OpenGL 4.0 Tutorials 第三章:初始化 OpenGL 4.0
原文地址:
?
http://www.rastertek.com/gl40tut03.html
?
Tutorial 3: Initializing OpenGL 4.0
第三章:初始化 OpenGL 4.0
?
This tutorial will be the first real introduction to working with OpenGL 4.0. We will address three main things which are initializing OpenGL 4.0, shutting it down, and basic rendering with it. This tutorial uses the same classes as the previous tutorial except that we will be adding more code to each to facilitate rendering with OpenGL 4.0.
這一章將正式介紹 OpenGL 4.0。我們將涉及3個部分,初始化 OpenGL 4.0、關閉、渲染。我們將在前面教程的基礎上添加 OpenGL 4.0 渲染。
?
We will start the tutorial by looking at the filled out OpenGLClass:
本章從填充OpenGLClass開始:
?
Openglclass.h
// Filename: openglclass.h#ifndef _OPENGLCLASS_H_ #define _OPENGLCLASS_H_OpenGL 4.0 requires that you link in the opengl32.lib library. You can do this in the IDE or directly in the code. I have put the linking in the code as this is my preference.
OpenGL 4.0 需要鏈接opengl32.lib庫文件。可以通過設置IDE或下面的代碼來實現。原作者使用了他喜歡的代碼方式。
/ // LINKING // / #pragma comment(lib, "opengl32.lib")OpenGL 4.0 also requires the windows.h and gl.h header files. I have also included math.h since we will need to write some math functions to assist in rendering with OpenGL.
OpenGL 4.0 需要包含windows.h和gl.h頭文件。這里也包含了math.h頭文件以便實現一些數學方法來輔助OpenGL渲染。
// // INCLUDES // // #include <windows.h> #include <gl\gl.h> #include <math.h>In Windows the gl.h header only contains the defines, functions, and function pointers for OpenGL 1.0 and OpenGL 1.1. All newer OpenGL functionality is actually implemented in the display driver for your video card in the form of extensions. You can find the names of all the extensions in the OpenGL 4.0 spec that the Khronos Group maintains on their website in the OpenGL 4.0 documentation. You can also download files such as wglext.h and glext.h which contain a large number of them as well. For these tutorials we only need a subset of all the functions so I have included the defines, typedefs, and function pointers that we will use in this header file.
在Windows系統中gl.h頭文件只包含了OpenGL 1.0 和 OpenGL 1.1 版本的定義、方法。全部的新的OpenGL實現都以擴展的方式實現在顯示設備驅動里。你可以在Khronos組織提供的OpenGL 4.0?在線文檔里查找全部OpenGL 4.0?擴展的名稱。你也可以下載包含了大量擴展的wglext.h和glext.h文件。本教程只用到了部分擴展,所以我在下面的頭文件里對它們進行了定義。
?
The following are the defines that we will be using:
下面是我們將要用到的定義:
/ // DEFINES // / #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_SWAP_METHOD_ARB 0x2007 #define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_DOUBLE_BUFFER_ARB 0x2011 #define WGL_PIXEL_TYPE_ARB 0x2013 #define WGL_COLOR_BITS_ARB 0x2014 #define WGL_DEPTH_BITS_ARB 0x2022 #define WGL_STENCIL_BITS_ARB 0x2023 #define WGL_FULL_ACCELERATION_ARB 0x2027 #define WGL_SWAP_EXCHANGE_ARB 0x2028 #define WGL_TYPE_RGBA_ARB 0x202B #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define GL_ARRAY_BUFFER 0x8892 #define GL_STATIC_DRAW 0x88E4 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_COMPILE_STATUS 0x8B81 #define GL_LINK_STATUS 0x8B82 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_TEXTURE0 0x84C0 #define GL_BGRA 0x80E1 #define GL_ELEMENT_ARRAY_BUFFER 0x8893The following are the typedefs that we need to access the OpenGL 4.0 functionality:
下面是我們將在OpenGL 4.0 方法中使用的類型定義。
// // TYPEDEFS // // typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats,int *piFormats, UINT *nNumFormats); typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); typedef void (APIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, ptrdiff_t size, const GLvoid *data, GLenum usage); typedef void (APIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRY * PFNGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRY * PFNGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef void (APIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef GLint (APIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const char *name); typedef void (APIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, char *infoLog); typedef void (APIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, char *infoLog); typedef void (APIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const char* *string, const GLint *length); typedef void (APIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,const GLvoid *pointer); typedef void (APIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const char *name); typedef GLint (APIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const char *name); typedef void (APIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); typedef void (APIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);The class definition for the OpenGLClass is kept as simple as possible here. It has the regular constructor, copy constructor, and destructor. Then more importantly it has the InitializeExtensions, InitializeOpenGL, and Shutdown function. This will be what we are mainly focused on in this tutorial. Other than that I have a number of helper functions which aren't important to this tutorial and a number of private member variables that will be looked at when we examine the openglclass.cpp file. For now just realize the initialization and shutdown functions are what concern us.
OpenGLClass的定義盡量保持簡潔。它包含規范的構造和析構函數。更重要的是它實現了InitializeExtensions、InitializeOpenGL、Shutdown方法。這是本章的重點。同時,類中也包含了一些不太重要的輔助方法和一些私有變量。目前我們只實現了初始化和關閉方法。
// Class name: OpenGLClassclass OpenGLClass { public:OpenGLClass();OpenGLClass(const OpenGLClass&);~OpenGLClass();bool InitializeExtensions(HWND);bool InitializeOpenGL(HWND, int, int, float, float, bool);void Shutdown(HWND);void BeginScene(float, float, float, float);void EndScene();void GetWorldMatrix(float*);void GetProjectionMatrix(float*);void GetVideoCardInfo(char*);void BuildIdentityMatrix(float*);void BuildPerspectiveFovLHMatrix(float*, float, float, float, float);void MatrixRotationY(float*, float);void MatrixTranslation(float*, float, float, float);void MatrixMultiply(float*, float*, float*);private:bool LoadExtensionList();private:HDC m_deviceContext;HGLRC m_renderingContext;The following three OpenGL function pointers are used for interfacing with windows:
下面3個窗口接口用的OpenGL函數指針:
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;float m_worldMatrix[16];float m_projectionMatrix[16];char m_videoCardDescription[128];These are the remainder of the function pointers that will be used for interfacing with OpenGL. I have made them public so we can call them easily using just a pointer to this class:
余下的是OpenGL接口函數指針。為了方便調用,在此定義為公有的:
public:PFNGLATTACHSHADERPROC glAttachShader;PFNGLBINDBUFFERPROC glBindBuffer;PFNGLBINDVERTEXARRAYPROC glBindVertexArray;PFNGLBUFFERDATAPROC glBufferData;PFNGLCOMPILESHADERPROC glCompileShader;PFNGLCREATEPROGRAMPROC glCreateProgram;PFNGLCREATESHADERPROC glCreateShader;PFNGLDELETEBUFFERSPROC glDeleteBuffers;PFNGLDELETEPROGRAMPROC glDeleteProgram;PFNGLDELETESHADERPROC glDeleteShader;PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;PFNGLDETACHSHADERPROC glDetachShader;PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;PFNGLGENBUFFERSPROC glGenBuffers;PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;PFNGLGETPROGRAMIVPROC glGetProgramiv;PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;PFNGLGETSHADERIVPROC glGetShaderiv;PFNGLLINKPROGRAMPROC glLinkProgram;PFNGLSHADERSOURCEPROC glShaderSource;PFNGLUSEPROGRAMPROC glUseProgram;PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;PFNGLACTIVETEXTUREPROC glActiveTexture;PFNGLUNIFORM1IPROC glUniform1i;PFNGLGENERATEMIPMAPPROC glGenerateMipmap;PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;PFNGLUNIFORM3FVPROC glUniform3fv;PFNGLUNIFORM4FVPROC glUniform4fv; };#endifFor those familiar with OpenGL already you may notice I don't have a view matrix variable in this class. The reason being is that I will be putting it in a camera class that we will be looking at in future tutorials.
熟悉OpenGL的同學會發現這里沒有定義視口矩陣。原因是我在后面的教程里將它放進攝像機類中。
Openglclass.cpp
// Filename: openglclass.cpp#include "openglclass.h"We begin by initializing the two member handles to null.
開始,將2個成員變量設置為null。
OpenGLClass::OpenGLClass() {m_deviceContext = 0;m_renderingContext = 0; }OpenGLClass::OpenGLClass(const OpenGLClass& other) { }OpenGLClass::~OpenGLClass() { }The InitializeExtensions function is what allows us to get pointers to all the OpenGL functions that are available from the video card driver. Note that this function cannot be called unless there is a window already created, hence the reason in the SystemClass::InitializeWindows function for creating a temporary window, calling this function to get the extensions, and then destroying that temporary window and creating a new one.
InitializeExtensions方法允許我們從顯卡驅動獲取全部可用的OpenGL函數指針。注意,在窗口創建前不能調用此方法。這就是SystemClass::InitializeWindows方法創建臨時窗口的原因,獲取OpenGL擴展后銷毀臨時窗口,然后再新建一個窗口。
?
In this function we will setup a temporary device context, pixel format, and rendering context so that we can call the LoadExtensionList function which then gets us all the function pointers we need. Once that is complete we release the temporary contexts.
這個方法里我創建了一個臨時設備上下文、像素格式和渲染上下文。然后我們可以通過調用LoadExtensionList方法獲得我們需要的函數指針。最后釋放他們。
bool OpenGLClass::InitializeExtensions(HWND hwnd) {HDC deviceContext;PIXELFORMATDESCRIPTOR pixelFormat;int error;HGLRC renderContext;bool result;// Get the device context for this window. // 獲得窗口設備上下文。deviceContext = GetDC(hwnd);if(!deviceContext){return false;}// Set a temporary default pixel format. // 設置默認的臨時像素格式。error = SetPixelFormat(deviceContext, 1, &pixelFormat);if(error != 1){return false;}// Create a temporary rendering context. // 創建臨時渲染上下文。renderContext = wglCreateContext(deviceContext);if(!renderContext){return false;}// Set the temporary rendering context as the current rendering context for this window. // 為窗口設置臨時渲染上下文。error = wglMakeCurrent(deviceContext, renderContext);if(error != 1){return false;}// Initialize the OpenGL extensions needed for this application. Note that a temporary rendering context was needed to do so. // 初始化程序需要的OpenGL擴展。result = LoadExtensionList();if(!result){return false;}// Release the temporary rendering context now that the extensions have been loaded. // 釋放臨時渲染上下文,現在擴展已經被加載。wglMakeCurrent(NULL, NULL);wglDeleteContext(renderContext);renderContext = NULL;// Release the device context for this window. // 釋放窗口設備上下文。ReleaseDC(hwnd, deviceContext);deviceContext = 0;return true; }InitializeOpenGL sets up OpenGL 4.0. Before this function is called the extensions must be loaded from the InitializeExtensions function. Also and the correct window needs to be created which is done in the SystemClass::InitializeWindows. Once those two things are in place this function can then be called.
InitializeOpenGL方法設置OpenGL 4.0。擴展必須要在InitializeExtensions方法加載和SystemClass::InitializeWindows方法創建了正確的窗口后才能在此方法中調用。
?
This function then creates an OpenGL 4.0 rendering context and appropriate pixel format. Once that is in place this function then sets up some extra things such as back face culling, vertical sync, depth buffer, and some matrices that we will need for rendering.
然后此方法創建OpenGL 4.0渲染上下文和適當的像素格式。完成后,此方法將完成渲染需要的背面剔除、垂直同步、深度緩沖和矩陣變換等操作。
bool OpenGLClass::InitializeOpenGL(HWND hwnd, int screenWidth, int screenHeight, float screenDepth, float screenNear, bool vsync) {int attributeListInt[19];int pixelFormat[1];unsigned int formatCount;int result;PIXELFORMATDESCRIPTOR pixelFormatDescriptor;int attributeList[5];float fieldOfView, screenAspect;char *vendorString, *rendererString;// Get the device context for this window.m_deviceContext = GetDC(hwnd);if(!m_deviceContext){return false;}// Support for OpenGL rendering.attributeListInt[0] = WGL_SUPPORT_OPENGL_ARB;attributeListInt[1] = TRUE;// Support for rendering to a window.attributeListInt[2] = WGL_DRAW_TO_WINDOW_ARB;attributeListInt[3] = TRUE;// Support for hardware acceleration.attributeListInt[4] = WGL_ACCELERATION_ARB;attributeListInt[5] = WGL_FULL_ACCELERATION_ARB;// Support for 24bit color.attributeListInt[6] = WGL_COLOR_BITS_ARB;attributeListInt[7] = 24;// Support for 24 bit depth buffer.attributeListInt[8] = WGL_DEPTH_BITS_ARB;attributeListInt[9] = 24;// Support for double buffer.attributeListInt[10] = WGL_DOUBLE_BUFFER_ARB;attributeListInt[11] = TRUE;// Support for swapping front and back buffer.attributeListInt[12] = WGL_SWAP_METHOD_ARB;attributeListInt[13] = WGL_SWAP_EXCHANGE_ARB;// Support for the RGBA pixel type.attributeListInt[14] = WGL_PIXEL_TYPE_ARB;attributeListInt[15] = WGL_TYPE_RGBA_ARB;// Support for a 8 bit stencil buffer.attributeListInt[16] = WGL_STENCIL_BITS_ARB;attributeListInt[17] = 8;// Null terminate the attribute list.attributeListInt[18] = 0;// Query for a pixel format that fits the attributes we want.result = wglChoosePixelFormatARB(m_deviceContext, attributeListInt, NULL, 1, pixelFormat, &formatCount);if(result != 1){return false;}// If the video card/display can handle our desired pixel format then we set it as the current one.result = SetPixelFormat(m_deviceContext, pixelFormat[0], &pixelFormatDescriptor);if(result != 1){return false;}// Set the 4.0 version of OpenGL in the attribute list.attributeList[0] = WGL_CONTEXT_MAJOR_VERSION_ARB;attributeList[1] = 4;attributeList[2] = WGL_CONTEXT_MINOR_VERSION_ARB;attributeList[3] = 0;// Null terminate the attribute list.attributeList[4] = 0;// Create a OpenGL 4.0 rendering context.m_renderingContext = wglCreateContextAttribsARB(m_deviceContext, 0, attributeList);if(m_renderingContext == NULL){return false;}// Set the rendering context to active.result = wglMakeCurrent(m_deviceContext, m_renderingContext);if(result != 1){return false;}// Set the depth buffer to be entirely cleared to 1.0 values.glClearDepth(1.0f);// Enable depth testing.glEnable(GL_DEPTH_TEST);// Set the polygon winding to front facing for the left handed system.glFrontFace(GL_CW);// Enable back face culling.glEnable(GL_CULL_FACE);glCullFace(GL_BACK);// Initialize the world/model matrix to the identity matrix.BuildIdentityMatrix(m_worldMatrix);// Set the field of view and screen aspect ratio.fieldOfView = 3.14159265358979323846f / 4.0f;screenAspect = (float)screenWidth / (float)screenHeight;// Build the perspective projection matrix.BuildPerspectiveFovLHMatrix(m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);// Get the name of the video card.vendorString = (char*)glGetString(GL_VENDOR);rendererString = (char*)glGetString(GL_RENDERER);// Store the video card name in a class member variable so it can be retrieved later.strcpy_s(m_videoCardDescription, vendorString);strcat_s(m_videoCardDescription, " - ");strcat_s(m_videoCardDescription, rendererString);// Turn on or off the vertical sync depending on the input bool value.if(vsync){result = wglSwapIntervalEXT(1);}else{result = wglSwapIntervalEXT(0);}// Check if vsync was set correctly.if(result != 1){return false;}return true; }The Shutdown function will release the two context handles that were used for rendering with OpenGL 4.0.
Shutdown方法用來釋放OpenGL渲染用到的兩個上下文句柄。
?
The next two helper functions are named BeginScene and EndScene. BeginScene will be called whenever we are going to draw a new 3D scene at the beginning of each frame. All it does is initializes the buffers so they are blank and ready to be drawn to. The other function is Endscene, it swaps the back buffer to the front buffer which displays our 3D scene once all the drawing has completed at the end of each frame.
下面是兩個輔助方法BeginScene和EndScene。BeginScene在每一幀開始繪制新的3D場景時被調用。EndScene在每一幀場景繪制完成后前后緩沖數據交換時被調用。
void OpenGLClass::BeginScene(float red, float green, float blue, float alpha) {// Set the color to clear the screen to.glClearColor(red, green, blue, alpha);// Clear the screen and depth buffer.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);return; }void OpenGLClass::EndScene() {// Present the back buffer to the screen since rendering is complete.SwapBuffers(m_deviceContext);return; }The LoadExtensionList function loads all the extensions we will be using for interfacing with OpenGL 4.0. Each function pointer gets the address to the function by calling the wglGetProcAddress function. If you wish to add even more OpenGL 4.0 support you can add your extra function pointer loading to this function.
LoadExtensionList方法加載了用來接口OpenGL 4.0的全部擴展。通過wglGetProcAddress?方法獲取每個OpenGL方法指針。你也可以在此方法中添加其他的OpenGL 4.0支持的函數指針。
bool OpenGLClass::LoadExtensionList() {// Load the OpenGL extensions that this application will be using.wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");if(!wglChoosePixelFormatARB){return false;}wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");if(!wglCreateContextAttribsARB){return false;}wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");if(!wglSwapIntervalEXT){return false;}glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");if(!glAttachShader){return false;}glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");if(!glBindBuffer){return false;}glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");if(!glBindVertexArray){return false;}glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");if(!glBufferData){return false;}glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");if(!glCompileShader){return false;}glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");if(!glCreateProgram){return false;}glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");if(!glCreateShader){return false;}glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");if(!glDeleteBuffers){return false;}glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");if(!glDeleteProgram){return false;}glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader");if(!glDeleteShader){return false;}glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glDeleteVertexArrays");if(!glDeleteVertexArrays){return false;}glDetachShader = (PFNGLDETACHSHADERPROC)wglGetProcAddress("glDetachShader");if(!glDetachShader){return false;}glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");if(!glEnableVertexAttribArray){return false;}glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");if(!glGenBuffers){return false;}glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");if(!glGenVertexArrays){return false;}glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");if(!glGetAttribLocation){return false;}glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog");if(!glGetProgramInfoLog){return false;}glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv");if(!glGetProgramiv){return false;}glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog");if(!glGetShaderInfoLog){return false;}glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");if(!glGetShaderiv){return false;}glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");if(!glLinkProgram){return false;}glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");if(!glShaderSource){return false;}glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");if(!glUseProgram){return false;}glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");if(!glVertexAttribPointer){return false;}glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)wglGetProcAddress("glBindAttribLocation");if(!glBindAttribLocation){return false;}glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");if(!glGetUniformLocation){return false;}glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");if(!glUniformMatrix4fv){return false;}glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");if(!glActiveTexture){return false;}glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");if(!glUniform1i){return false;}glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap");if(!glGenerateMipmap){return false;}glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray");if(!glDisableVertexAttribArray){return false;}glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");if(!glUniform3fv){return false;}glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");if(!glUniform4fv){return false;}return true; }The following functions just return the matrices that this class has built to calling functions. These matrices are important to rendering.
下面幾個方法用來處理本類用的矩陣。這些矩陣對渲染非常重要。
void OpenGLClass::GetWorldMatrix(float* matrix) {matrix[0] = m_worldMatrix[0];matrix[1] = m_worldMatrix[1];matrix[2] = m_worldMatrix[2];matrix[3] = m_worldMatrix[3];matrix[4] = m_worldMatrix[4];matrix[5] = m_worldMatrix[5];matrix[6] = m_worldMatrix[6];matrix[7] = m_worldMatrix[7];matrix[8] = m_worldMatrix[8];matrix[9] = m_worldMatrix[9];matrix[10] = m_worldMatrix[10];matrix[11] = m_worldMatrix[11];matrix[12] = m_worldMatrix[12];matrix[13] = m_worldMatrix[13];matrix[14] = m_worldMatrix[14];matrix[15] = m_worldMatrix[15];return; }void OpenGLClass::GetProjectionMatrix(float* matrix) {matrix[0] = m_projectionMatrix[0];matrix[1] = m_projectionMatrix[1];matrix[2] = m_projectionMatrix[2];matrix[3] = m_projectionMatrix[3];matrix[4] = m_projectionMatrix[4];matrix[5] = m_projectionMatrix[5];matrix[6] = m_projectionMatrix[6];matrix[7] = m_projectionMatrix[7];matrix[8] = m_projectionMatrix[8];matrix[9] = m_projectionMatrix[9];matrix[10] = m_projectionMatrix[10];matrix[11] = m_projectionMatrix[11];matrix[12] = m_projectionMatrix[12];matrix[13] = m_projectionMatrix[13];matrix[14] = m_projectionMatrix[14];matrix[15] = m_projectionMatrix[15];return; }The GetVideoCardInfo function returns the name and manufacturer of the video card in a string to the caller of this function.
GetVideoCardInfo?方法返回顯卡的名字和生產廠商。
void OpenGLClass::GetVideoCardInfo(char* cardName) {strcpy_s(cardName, 128, m_videoCardDescription);return; }This function builds a basic identity matrix.
下面方法構造基本單位矩陣。
void OpenGLClass::BuildIdentityMatrix(float* matrix) {matrix[0] = 1.0f;matrix[1] = 0.0f;matrix[2] = 0.0f;matrix[3] = 0.0f;matrix[4] = 0.0f;matrix[5] = 1.0f;matrix[6] = 0.0f;matrix[7] = 0.0f;matrix[8] = 0.0f;matrix[9] = 0.0f;matrix[10] = 1.0f;matrix[11] = 0.0f;matrix[12] = 0.0f;matrix[13] = 0.0f;matrix[14] = 0.0f;matrix[15] = 1.0f;return; }This function builds a left handed projection matrix.
下面方法構造基于左手坐標系的投影矩陣。
void OpenGLClass::BuildPerspectiveFovLHMatrix(float* matrix, float fieldOfView, float screenAspect, float screenNear, float screenDepth) {matrix[0] = 1.0f / (screenAspect * tan(fieldOfView * 0.5f));matrix[1] = 0.0f;matrix[2] = 0.0f;matrix[3] = 0.0f;matrix[4] = 0.0f;matrix[5] = 1.0f / tan(fieldOfView * 0.5f);matrix[6] = 0.0f;matrix[7] = 0.0f;matrix[8] = 0.0f;matrix[9] = 0.0f;matrix[10] = screenDepth / (screenDepth - screenNear);matrix[11] = 1.0f;matrix[12] = 0.0f;matrix[13] = 0.0f;matrix[14] = (-screenNear * screenDepth) / (screenDepth - screenNear);matrix[15] = 0.0f;return; }This function builds a rotation matrix based around the Y axis.
下面方法構造基于Y軸的旋轉矩陣。
void OpenGLClass::MatrixRotationY(float* matrix, float angle) {matrix[0] = cosf(angle);matrix[1] = 0.0f;matrix[2] = -sinf(angle);matrix[3] = 0.0f;matrix[4] = 0.0f;matrix[5] = 1.0f;matrix[6] = 0.0f;matrix[7] = 0.0f;matrix[8] = sinf(angle);matrix[9] = 0.0f;matrix[10] = cosf(angle);matrix[11] = 0.0f;matrix[12] = 0.0f;matrix[13] = 0.0f;matrix[14] = 0.0f;matrix[15] = 1.0f;return; }This function builds a basic translation matrix.
下面方法構造了基本位移矩陣。
void OpenGLClass::MatrixTranslation(float* matrix, float x, float y, float z) {matrix[0] = 1.0f;matrix[1] = 0.0f;matrix[2] = 0.0f;matrix[3] = 0.0f;matrix[4] = 0.0f;matrix[5] = 1.0f;matrix[6] = 0.0f;matrix[7] = 0.0f;matrix[8] = 0.0f;matrix[9] = 0.0f;matrix[10] = 1.0f;matrix[11] = 0.0f;matrix[12] = x;matrix[13] = y;matrix[14] = z;matrix[15] = 1.0f;return; }This function multiplies two 4x4 matrices and returns the result.
下面方法返回兩個4x4矩陣相乘的結果。
void OpenGLClass::MatrixMultiply(float* result, float* matrix1, float* matrix2) {result[0] = (matrix1[0] * matrix2[0]) + (matrix1[1] * matrix2[4]) + (matrix1[2] * matrix2[8]) + (matrix1[3] * matrix2[12]);result[1] = (matrix1[0] * matrix2[1]) + (matrix1[1] * matrix2[5]) + (matrix1[2] * matrix2[9]) + (matrix1[3] * matrix2[13]);result[2] = (matrix1[0] * matrix2[2]) + (matrix1[1] * matrix2[6]) + (matrix1[2] * matrix2[10]) + (matrix1[3] * matrix2[14]);result[3] = (matrix1[0] * matrix2[3]) + (matrix1[1] * matrix2[7]) + (matrix1[2] * matrix2[11]) + (matrix1[3] * matrix2[15]);result[4] = (matrix1[4] * matrix2[0]) + (matrix1[5] * matrix2[4]) + (matrix1[6] * matrix2[8]) + (matrix1[7] * matrix2[12]);result[5] = (matrix1[4] * matrix2[1]) + (matrix1[5] * matrix2[5]) + (matrix1[6] * matrix2[9]) + (matrix1[7] * matrix2[13]);result[6] = (matrix1[4] * matrix2[2]) + (matrix1[5] * matrix2[6]) + (matrix1[6] * matrix2[10]) + (matrix1[7] * matrix2[14]);result[7] = (matrix1[4] * matrix2[3]) + (matrix1[5] * matrix2[7]) + (matrix1[6] * matrix2[11]) + (matrix1[7] * matrix2[15]);result[8] = (matrix1[8] * matrix2[0]) + (matrix1[9] * matrix2[4]) + (matrix1[10] * matrix2[8]) + (matrix1[11] * matrix2[12]);result[9] = (matrix1[8] * matrix2[1]) + (matrix1[9] * matrix2[5]) + (matrix1[10] * matrix2[9]) + (matrix1[11] * matrix2[13]);result[10] = (matrix1[8] * matrix2[2]) + (matrix1[9] * matrix2[6]) + (matrix1[10] * matrix2[10]) + (matrix1[11] * matrix2[14]);result[11] = (matrix1[8] * matrix2[3]) + (matrix1[9] * matrix2[7]) + (matrix1[10] * matrix2[11]) + (matrix1[11] * matrix2[15]);result[12] = (matrix1[12] * matrix2[0]) + (matrix1[13] * matrix2[4]) + (matrix1[14] * matrix2[8]) + (matrix1[15] * matrix2[12]);result[13] = (matrix1[12] * matrix2[1]) + (matrix1[13] * matrix2[5]) + (matrix1[14] * matrix2[9]) + (matrix1[15] * matrix2[13]);result[14] = (matrix1[12] * matrix2[2]) + (matrix1[13] * matrix2[6]) + (matrix1[14] * matrix2[10]) + (matrix1[15] * matrix2[14]);result[15] = (matrix1[12] * matrix2[3]) + (matrix1[13] * matrix2[7]) + (matrix1[14] * matrix2[11]) + (matrix1[15] * matrix2[15]);return; }Systemclass.h
?
The SystemClass has been modified since the last tutorial to now include the OpenGL 4.0 initialization and shutdown. The header has not been modified but the source file has been.
SystemClass添加了OpenGL 4.0的初始化和關閉操作。
// Filename: systemclass.h#ifndef _SYSTEMCLASS_H_ #define _SYSTEMCLASS_H_/// // PRE-PROCESSING DIRECTIVES // /// #define WIN32_LEAN_AND_MEAN// // INCLUDES // // #include <windows.h>/// // MY CLASS INCLUDES // /// #include "openglclass.h" #include "inputclass.h" #include "graphicsclass.h"// Class name: SystemClassclass SystemClass { public:SystemClass();SystemClass(const SystemClass&);~SystemClass();bool Initialize();void Shutdown();void Run();LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);private:bool Frame();bool InitializeWindows(OpenGLClass*, int&, int&);void ShutdownWindows();private:LPCWSTR m_applicationName;HINSTANCE m_hinstance;HWND m_hwnd;OpenGLClass* m_OpenGL;InputClass* m_Input;GraphicsClass* m_Graphics; };/ // FUNCTION PROTOTYPES // / static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);/ // GLOBALS // / static SystemClass* ApplicationHandle = 0;#endifSystemclass.cpp
// Filename: systemclass.cpp#include "systemclass.h"SystemClass::SystemClass() {m_OpenGL = 0;m_Input = 0;m_Graphics = 0; }SystemClass::SystemClass(const SystemClass& other) { }SystemClass::~SystemClass() { }bool SystemClass::Initialize() {int screenWidth, screenHeight;bool result;// Initialize the width and height of the screen to zero.screenWidth = 0;screenHeight = 0;// Create the OpenGL object.m_OpenGL = new OpenGLClass;if(!m_OpenGL){return false;}// Create the window the application will be using and also initialize OpenGL.result = InitializeWindows(m_OpenGL, screenWidth, screenHeight);if(!result){MessageBox(m_hwnd, L"Could not initialize the window.", L"Error", MB_OK);return false;}// Create the input object. This object will be used to handle reading the input from the user.m_Input = new InputClass;if(!m_Input){return false;}// Initialize the input object.m_Input->Initialize();// Create the graphics object. This object will handle rendering all the graphics for this application.m_Graphics = new GraphicsClass;if(!m_Graphics){return false;}// Initialize the graphics object.result = m_Graphics->Initialize(m_OpenGL, m_hwnd);if(!result){return false;}return true; }void SystemClass::Shutdown() {// Release the graphics object.if(m_Graphics){m_Graphics->Shutdown();delete m_Graphics;m_Graphics = 0;}// Release the input object.if(m_Input){delete m_Input;m_Input = 0;}We now call the shutdown function for the OpenGL object.
這里調用OpenGL對象的關閉方法。
// Release the OpenGL object.if(m_OpenGL){m_OpenGL->Shutdown(m_hwnd);delete m_OpenGL;m_OpenGL = 0;}// Shutdown the window.ShutdownWindows();return; }void SystemClass::Run() {MSG msg;bool done, result;// Initialize the message structure.ZeroMemory(&msg, sizeof(MSG));// Loop until there is a quit message from the window or the user.done = false;while(!done){// Handle the windows messages.if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}// If windows signals to end the application then exit out.if(msg.message == WM_QUIT){done = true;}else{// Otherwise do the frame processing.result = Frame();if(!result){done = true;}}}return; }bool SystemClass::Frame() {bool result;// Check if the user pressed escape and wants to exit the application.if(m_Input->IsKeyDown(VK_ESCAPE)){return false;}// Do the frame processing for the graphics object.result = m_Graphics->Frame();if(!result){return false;}return true; }LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {switch(umsg){// Check if a key has been pressed on the keyboard.case WM_KEYDOWN:{// If a key is pressed send it to the input object so it can record that state.m_Input->KeyDown((unsigned int)wparam);return 0;}// Check if a key has been released on the keyboard.case WM_KEYUP:{// If a key is released then send it to the input object so it can unset the state for that key.m_Input->KeyUp((unsigned int)wparam);return 0;}// Any other messages send to the default message handler as our application won't make use of them.default:{return DefWindowProc(hwnd, umsg, wparam, lparam);}} }bool SystemClass::InitializeWindows(OpenGLClass* OpenGL, int& screenWidth, int& screenHeight) {WNDCLASSEX wc;DEVMODE dmScreenSettings;int posX, posY;bool result;// Get an external pointer to this object.ApplicationHandle = this;// Get the instance of this application.m_hinstance = GetModuleHandle(NULL);// Give the application a name.m_applicationName = L"Engine";// Setup the windows class with default settings.wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = m_hinstance;wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);wc.hIconSm = wc.hIcon;wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wc.lpszMenuName = NULL;wc.lpszClassName = m_applicationName;wc.cbSize = sizeof(WNDCLASSEX);// Register the window class.RegisterClassEx(&wc);// Create a temporary window for the OpenGL extension setup.m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_POPUP,0, 0, 640, 480, NULL, NULL, m_hinstance, NULL);if(m_hwnd == NULL){return false;}// Don't show the window.ShowWindow(m_hwnd, SW_HIDE);We now load the extensions using the OpenGL object.
// Initialize a temporary OpenGL window and load the OpenGL extensions.result = OpenGL->InitializeExtensions(m_hwnd);if(!result){MessageBox(m_hwnd, L"Could not initialize the OpenGL extensions.", L"Error", MB_OK);return false;}// Release the temporary window now that the extensions have been initialized.DestroyWindow(m_hwnd);m_hwnd = NULL;// Determine the resolution of the clients desktop screen.screenWidth = GetSystemMetrics(SM_CXSCREEN);screenHeight = GetSystemMetrics(SM_CYSCREEN);// Setup the screen settings depending on whether it is running in full screen or in windowed mode.if(FULL_SCREEN){// If full screen set the screen to maximum size of the users desktop and 32bit.memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));dmScreenSettings.dmSize = sizeof(dmScreenSettings);dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;dmScreenSettings.dmBitsPerPel = 32;dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;// Change the display settings to full screen.ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);// Set the position of the window to the top left corner.posX = posY = 0;}else{// If windowed then set it to 800x600 resolution.screenWidth = 800;screenHeight = 600;// Place the window in the middle of the screen.posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;}// Create the window with the screen settings and get the handle to it.m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_POPUP,posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);if(m_hwnd == NULL){return false;}With the extensions in place we can now properly initialize an OpenGL 4.0 rendering context.
使用擴展初始化OpenGL 4.0渲染上下文。
// Initialize OpenGL now that the window has been created.result = m_OpenGL->InitializeOpenGL(m_hwnd, screenWidth, screenHeight, SCREEN_DEPTH, SCREEN_NEAR, VSYNC_ENABLED);if(!result){MessageBox(m_hwnd, L"Could not initialize OpenGL, check if video card supports OpenGL 4.0.", L"Error", MB_OK);return false;}// Bring the window up on the screen and set it as main focus.ShowWindow(m_hwnd, SW_SHOW);SetForegroundWindow(m_hwnd);SetFocus(m_hwnd);// Hide the mouse cursor.ShowCursor(false);return true; }void SystemClass::ShutdownWindows() {// Show the mouse cursor.ShowCursor(true);// Fix the display settings if leaving full screen mode.if(FULL_SCREEN){ChangeDisplaySettings(NULL, 0);}// Remove the window.DestroyWindow(m_hwnd);m_hwnd = NULL;// Remove the application instance.UnregisterClass(m_applicationName, m_hinstance);m_hinstance = NULL;// Release the pointer to this class.ApplicationHandle = NULL;return; }LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) {switch(umessage){// Check if the window is being closed.case WM_CLOSE:{PostQuitMessage(0);return 0;}// All other messages pass to the message handler in the system class.default:{return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);}} }Graphicsclass.h
?
For this tutorial we have now also filled out the GraphicsClass so that it can perform some basic OpenGL rendering.
本章我們為GraphicsClass添加基本的OpenGL渲染。
// Filename: graphicsclass.h#ifndef _GRAPHICSCLASS_H_ #define _GRAPHICSCLASS_H_/// // MY CLASS INCLUDES // /// #include "openglclass.h"/ // GLOBALS // / const bool FULL_SCREEN = false; const bool VSYNC_ENABLED = true; const float SCREEN_DEPTH = 1000.0f; const float SCREEN_NEAR = 0.1f;// Class name: GraphicsClassclass GraphicsClass { public:GraphicsClass();GraphicsClass(const GraphicsClass&);~GraphicsClass();bool Initialize(OpenGLClass*, HWND);void Shutdown();bool Frame();private:bool Render();private: We now have an OpenGL class object.OpenGLClass* m_OpenGL; };#endifGraphicsclass.cpp
?
From the previous tutorial this class was entirely empty with no code in it at all. Now that we have a OpenGLClass member we will start to fill out some code inside the GraphicsClass to initialize and shutdown the OpenGLClass object. We will also add calls to BeginScene and EndScene in the Render function so that we are now drawing to the window using OpenGL.
本類在前面的教程沒有任何代碼。現在,我們有一個OpenGLClass成員,我們可以添加代碼來初始化和關閉OpenGLClass對象。為了讓OpenGL繪制窗口,在Render方法里我們添加了BeginScene和EndScene方法調用。
// Filename: graphicsclass.cpp#include "graphicsclass.h"So the very first change is in the class constructor. Here we initialize the OpenGLClass object pointer to null for safety reasons as we do with all class pointers.
此類的構造函數發生了變化。為了安全,在構造函數里將OpenGLClass對象指針設置為null。
GraphicsClass::GraphicsClass() {m_OpenGL = 0; }GraphicsClass::GraphicsClass(const GraphicsClass& other) { }GraphicsClass::~GraphicsClass() { }The second change is in the Initialize function inside the GraphicsClass Here we send in a pointer to the OpenGLClass object so that the GraphicsClass can make OpenGL system calls just using a single pointer.
在GraphicsClass的初始化方法里傳入OpenGLClass對象指針,這樣GraphicsClass使用同一個指針操作OpenGL系統。
bool GraphicsClass::Initialize(OpenGLClass* OpenGL, HWND hwnd) {// Store a pointer to the OpenGL class object.m_OpenGL = OpenGL;return true; }The next change is in the Shutdown function in the GraphicsClass. Here we release the pointer to the OpenGLClass object during shut down.
在Shutdown方法里釋放OpenGLClass對象指針。
void GraphicsClass::Shutdown() {// Release the pointer to the OpenGL class object.m_OpenGL = 0;return; }The Frame function has been updated so that it now calls the Render function each frame.
Frame方法每一幀都調用Render方法。
bool GraphicsClass::Frame() {bool result;// Render the graphics scene.result = Render();if(!result){return false;}return true; }The final change to this class is in the Render function. We call the OpenGL object to clear the screen to a grey color. After that we call EndScene so that the grey color is presented to the window.
Render方法里,我們使用OpenGL對象清楚屏幕為灰色。然后調用EndScene將灰色顯示到窗口中。
bool GraphicsClass::Render() {// Clear the buffers to begin the scene.m_OpenGL->BeginScene(0.5f, 0.5f, 0.5f, 1.0f);// Present the rendered scene to the screen.m_OpenGL->EndScene();return true; }Summary
總結
?
Now we are finally able to initialize and shut down OpenGL 4.0. Compiling and running the code will produce the same window as the last tutorial but OpenGL is initialized now and clear the window to grey for us. Compiling and running the code will also show if your video card driver can properly get all the OpenGL 4.0 extensions that we will be using.
本章講述了初始化和關閉OpenGL 4.0的內容。編譯并運行代碼,將看到被OpenGL清理為灰色的窗口。同時也能知道你的顯卡釋放支持我們用到的OpenGL 4.0的擴展。
?
To Do Exercises
練習
?
1. Re-compile the code and run the program to ensure OpenGL works. Press the escape key to quit after the window displays.
1. 重新編譯并運行代碼確保OpenGL可以正常工作,窗口顯示后按下ESC鍵退出。
?
2. Change the global in graphicsclass.h to full screen and re-compile/run.
2. 修改graphicsclass.h中全部變量的值為全屏,然后重新編譯并運行。
?
3. Change the clear color in GraphicsClass::Render to yellow.
3. 修改GraphicsClass::Render方法里清除顏色為黃色。
?
4. Write the video card name out to a text file.
4. 將顯卡名稱輸出到文本文件。
?
Source Code
源代碼
?
http://www.rastertek.com/gl40src03.zip
?
?
Openglclass.cpp
總結
以上是生活随笔為你收集整理的OpenGL 4.0 Tutorials 第三章:初始化 OpenGL 4.0的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中信白条联名卡申请/办卡条件
- 下一篇: spline 用法