日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL 4.0 Tutorials 第三章:初始化 OpenGL 4.0

發布時間:2023/12/10 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 0x8893

The 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; };#endif

For 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渲染用到的兩個上下文句柄。

void OpenGLClass::Shutdown(HWND hwnd) {// Release the rendering context.if(m_renderingContext){wglMakeCurrent(NULL, NULL);wglDeleteContext(m_renderingContext);m_renderingContext = 0;}// Release the device context.if(m_deviceContext){ReleaseDC(hwnd, m_deviceContext);m_deviceContext = 0;}return; }

?

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;#endif

Systemclass.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; };#endif

Graphicsclass.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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产小视频在线观看 | 伊人射 | 成人黄大片视频在线观看 | 午夜久久久久久久久久影院 | 色999精品| 91免费高清观看 | 91在线免费看片 | 97免费在线观看视频 | 久久久黄视频 | 欧美看片 | 永久免费的啪啪网站免费观看浪潮 | 欧美一级视频免费看 | 一性一交视频 | 久久久久久97三级 | 婷婷色九月 | 欧美日韩国产一区 | 久久国产精品电影 | 国产精品久久久久久久免费观看 | 91看片看淫黄大片 | 在线看成人 | 久久精品99国产精品亚洲最刺激 | 高清av免费看 | 日韩精品不卡在线观看 | 欧美日韩性生活 | 久草电影在线观看 | 国产成人777777 | 国产黄网站在线观看 | 青草视频网 | 在线成人观看 | 最新在线你懂的 | 国产专区一 | 亚洲乱码中文字幕综合 | 视频99爱 | 综合婷婷 | 精品国产网址 | 国产精品一区二区久久国产 | 久久免费在线观看 | 亚洲1区在线 | 999久久国产精品免费观看网站 | 日夜夜精品视频 | 欧美a性 | 天天激情天天干 | 亚洲天堂va | 五月激情丁香图片 | 日韩中文字幕亚洲一区二区va在线 | 亚洲欧美日韩中文在线 | 亚洲欧美国产精品 | 久久综合网色—综合色88 | 亚洲国产精品电影 | 欧美精品久久久久久久久久白贞 | 国产精品一区免费在线观看 | 国产精品久久久久久69 | 久久久久久久综合色一本 | 欧美日韩中文视频 | 九色91av | 午夜91视频 | 黄色在线免费观看网站 | 欧美日韩视频在线观看一区二区 | 日日夜色 | a黄色| 97视频免费在线看 | av无限看| 91亚色免费视频 | 久久久免费少妇 | 久久精品国产亚洲精品2020 | 欧美精品一二三 | 中文在线天堂资源 | 亚州av网站大全 | 久久久999精品视频 国产美女免费观看 | 免费看久久 | 日韩黄色中文字幕 | 久久99精品国产 | 欧美日韩精品在线免费观看 | 蜜桃av久久久亚洲精品 | 91麻豆精品 | 六月天综合网 | 69成人在线 | 亚洲激情中文 | 日本论理电影 | 亚洲精品玖玖玖av在线看 | 91av手机在线 | 97成人在线观看 | 久 久久影院 | 国产亚洲成人网 | 中文字幕乱码电影 | av在线免费网站 | 亚洲一区二区91 | 免费视频三区 | 麻花豆传媒mv在线观看网站 | 二区三区精品 | 成人理论在线观看 | av一级片| 亚洲在线国产 | 欧美日韩在线观看不卡 | 成人影音在线 | bbbb操bbbb| 国产黄色av影视 | 久久久久影视 | 久久超级碰视频 | 午夜精品一区二区三区四区 | 亚洲日本中文字幕在线观看 | 亚洲欧美成人综合 | 天天草天天插 | 久久久久国产精品视频 | 国产精品视频全国免费观看 | 久久激情五月丁香伊人 | 97视频在线看 | 日韩久久久 | 国产精品wwwwww | 在线a视频免费观看 | 99精品国产成人一区二区 | 欧美,日韩| 一区 二区 精品 | 激情喷水 | 天天色天天操综合网 | 中文字幕人成一区 | 深爱激情综合网 | 久久婷婷丁香 | 日韩欧美高清在线 | 玖玖视频免费在线 | 精品国偷自产在线 | 最近中文字幕免费av | 午夜精品久久久久久 | 开心激情综合网 | 国产99中文字幕 | 天天干天天操天天爱 | 99成人在线视频 | 91网站观看| 欧美一级爽 | 在线观看黄色 | 欧美午夜视频在线 | 美女黄频在线观看 | 免费91在线 | 国产免费精彩视频 | 国产成人精品午夜在线播放 | 日韩免费电影网站 | 国产精品网红直播 | 波多野结衣网址 | 深爱五月激情五月 | 黄色小网站在线观看 | 免费日韩 | 亚洲精品午夜久久久久久久 | 久久久久国产精品一区 | 久久看片网| 狠狠狠色狠狠色综合 | 激情婷婷| 91丨九色丨蝌蚪丰满 | 精品视频在线免费 | 久色伊人 | 国产电影黄色av | 中文字幕在线免费看线人 | 久久人人爽人人爽人人片av免费 | 在线免费高清视频 | 成人免费视频视频在线观看 免费 | 国产一及片 | 亚洲区另类春色综合小说校园片 | 日本不卡一区二区 | 激情综合色播五月 | 狠狠躁日日躁夜夜躁av | 国产成人黄色网址 | 午夜黄色一级片 | 又黄又网站| 精品美女久久久久 | 久久国产一区 | 亚洲最新视频在线 | 久久久久亚洲国产精品 | 国产亚洲精品综合一区91 | 国产高清在线免费观看 | 岛国精品一区二区 | 久久久精品免费看 | 久久久久综合精品福利啪啪 | 亚洲午夜久久久久久久久电影网 | 在线免费中文字幕 | 夜夜操网站 | 亚洲国产成人在线 | 久久精品99国产精品酒店日本 | 久久久天天操 | 日本精品午夜 | 婷婷丁香视频 | 日韩三级视频在线观看 | 国产大尺度视频 | 激情狠狠干 | av专区在线 | 国内精品久久久久久久 | 成人久久精品视频 | 精品久久毛片 | 久久视频免费看 | 久久免费视频99 | 日韩免费在线观看视频 | 国产在线精品观看 | 亚洲国产精品女人久久久 | 久久国产精品久久国产精品 | 精品国产成人在线 | 久久免费电影网 | 亚洲aⅴ乱码精品成人区 | av午夜电影 | 国产视频资源在线观看 | 99久久精品免费看 | www.国产毛片 | 国产美女无遮挡永久免费 | 久久黄色影院 | 香蕉免费在线 | 免费在线观看av电影 | 成人黄色片免费 | 亚洲人成精品久久久久 | 久热色超碰 | 亚洲精品高清在线观看 | 超碰在线cao | 精品视频久久久 | 成人免费视频观看 | 99 久久久久 | 免费看黄电影 | 欧美资源| 久久久片 | www.天天操.com | 精品亚洲一区二区三区 | 国产免费不卡 | 超碰成人网 | www.夜夜爽| 欧美色噜噜噜 | 在线观看福利网站 | 久久免费视频在线观看 | 亚洲国产中文字幕在线视频综合 | 97在线视频免费看 | 国产五月天婷婷 | 99精品区| 色射色 | 久久99精品久久久久久秒播蜜臀 | 亚洲国产精品免费 | 欧美a级免费视频 | 国产精品久久久久永久免费 | 国产在线播放一区二区三区 | 天堂av在线免费 | 国产亚洲免费的视频看 | 综合网久久 | 欧美色噜噜 | 五月天婷亚洲天综合网鲁鲁鲁 | 欧美疯狂性受xxxxx另类 | 亚洲午夜av电影 | 日韩精品一区在线播放 | 人人爽久久久噜噜噜电影 | 三上悠亚一区二区在线观看 | 日本精品视频在线 | 国产高清视频免费最新在线 | 韩国av电影网 | 亚洲精品国产综合99久久夜夜嗨 | 色婷婷激婷婷情综天天 | 成人欧美一区二区三区黑人麻豆 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 日日插日日干 | 五月激情av | 91精品国产麻豆国产自产影视 | 香蕉97视频观看在线观看 | 夜夜躁日日躁 | 91专区在线观看 | 免费欧美精品 | 美女视频网站久久 | 国产日韩视频在线观看 | 国产剧在线观看片 | 日本久久综合网 | 亚洲视频电影在线 | 日韩在线色视频 | 国产精品久久久久久久免费观看 | 亚洲精品成人av在线 | 亚洲精品国产片 | 久久a v视频 | 国产精品中文字幕av | 国产专区视频 | 国产经典av| 欧美另类sm图片 | 日本性xxxxx 亚洲精品午夜久久久 | 亚洲精品欧美专区 | 91麻豆视频| 久久亚洲影院 | 国产原创av在线 | 亚洲第二色 | 久久伦理| 97国产大学生情侣酒店的特点 | 免费看一及片 | www.五月天| 成人小视频在线观看免费 | 狠狠激情中文字幕 | 国产91综合一区在线观看 | 日韩色av色资源 | 国产精品久久久777 成人手机在线视频 | 少妇bbw搡bbbb搡bbb | 人人插人人草 | 日韩精品中文字幕有码 | 免费av在线| 婷婷成人在线 | 国产美女免费 | 色资源二区在线视频 | 99免费在线播放99久久免费 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 99精品国产一区二区三区麻豆 | 久草观看视频 | 中文字幕第 | 中文字幕av电影下载 | 日韩中文字幕91 | 久草在线久草在线2 | 91夜夜夜 | 五月婷婷综合激情网 | 99久久er热在这里只有精品15 | 91片网 | 婷婷国产v亚洲v欧美久久 | 国产又粗又猛又黄 | 欧美国产大片 | 亚洲欧美日韩精品久久奇米一区 | 欧美亚洲国产日韩 | 黄色三级久久 | 国产免费亚洲高清 | 欧美在线视频一区二区 | 午夜性福利 | 久久精品视频免费观看 | 激情网婷婷| 国产美女免费 | 中文字幕在线观看一区二区 | 欧美性生爱 | 国产手机在线精品 | 久草久热 | 国产高清在线免费观看 | 久久国产二区 | 丰满少妇在线观看资源站 | 婷婷综合五月天 | 久久免费视频3 | 欧美日韩中文国产一区发布 | 特级毛片在线免费观看 | 国产一区二区免费 | 看国产黄色大片 | 91成人精品 | 国产一区二区三区高清播放 | 99免费精品 | 色91在线| 亚洲精品视频在线免费播放 | 91麻豆精品国产自产在线游戏 | 99在线观看视频网站 | 久久99久久99精品免费看小说 | 免费观看一区二区三区视频 | 国产精品18久久久久vr手机版特色 | 亚洲国产精彩中文乱码av | 欧美另类z0zx | 91视频-88av | 午夜国产成人 | 国产高清不卡一区二区三区 | 日本高清xxxx | 日韩3区 | 丁香激情婷婷 | 最新av在线网站 | 欧洲成人av | 婷婷色视频 | 97视频在线观看播放 | 日韩在线播放欧美字幕 | 欧美性生活久久 | 99精品免费视频 | 操操操日日 | 精品国产乱码久久久久久1区二区 | 免费麻豆网站 | 日本bbbb摸bbbb | 国产精品久久久久久av | 亚洲最新av网站 | av一本久道久久波多野结衣 | 六月激情婷婷 | 狠狠色丁香婷婷 | 日本少妇久久久 | 男女全黄一级一级高潮免费看 | 日韩中文字幕免费电影 | 亚洲国产偷 | 亚洲综合在线五月 | 最新日本中文字幕 | 黄色亚洲精品 | 国产色在线 | 久久精品99北条麻妃 | 色综合久久久久综合体 | 国产一级大片在线观看 | 久久综合九色综合久99 | 91高清一区 | 97精品久久人人爽人人爽 | 国产美女免费观看 | 欧美一级片免费播放 | 亚洲黄色大片 | 亚洲成人av在线播放 | 99久久婷婷 | 国产精品麻 | www毛片com| 91在线免费播放视频 | 欧美一区二区免费在线观看 | 天天爽天天射 | 毛片网在线 | 久久久久久久久久久久av | av免费看看| 狠狠操.com | 波多野结衣综合网 | 日韩欧美精品在线 | 91黄色免费网站 | 日韩av一区在线观看 | 欧美aⅴ在线观看 | 天天综合视频在线观看 | 久久综合九色欧美综合狠狠 | 97理论片 | 最新av免费在线 | 国产资源在线免费观看 | 91av九色 | 天天玩天天干天天操 | 欧美日韩在线观看不卡 | 国产欧美综合在线观看 | 在线视频免费观看 | 国产精品小视频网站 | 久久99精品国产91久久来源 | 免费国产黄线在线观看视频 | 九色视频网 | 久久精品99精品国产香蕉 | 精品一区二区三区电影 | 天天拍天天草 | 亚洲一区 影院 | 成人午夜网址 | 久久,天天综合 | 国产视频手机在线 | 国产日韩中文字幕在线 | 亚洲精品成人av在线 | 在线观看视频你懂的 | 黄色毛片视频 | 一区二区三区免费在线播放 | 国产精品福利视频 | 91传媒视频在线观看 | 中文字幕 在线看 | 日韩欧美在线视频一区二区三区 | 中文字幕在线久一本久 | 天天插视频 | 九九精品无码 | 国产精品久久久久久久久软件 | 免费a v在线 | 国产成人综合图片 | 国产精品一区二区免费看 | 一区二区不卡在线观看 | 久久观看免费视频 | 国产精品麻豆欧美日韩ww | 国产在线黄色 | 99免费| 亚洲作爱视频 | 久久久午夜精品理论片中文字幕 | 国产玖玖精品视频 | 久久精品视频网址 | 久福利 | 国产成人av | 亚洲人成人在线 | 免费看精品久久片 | 狂野欧美激情性xxxx欧美 | 天天摸天天舔天天操 | 波多野结衣视频一区二区三区 | 日韩资源在线 | 久草在线视频精品 | 久久毛片视频 | 一区二区精 | 国产色网 | 亚洲综合在| 久久亚洲区 | 在线a人片免费观看视频 | 日本久久中文字幕 | 国产精品久久久久一区二区三区共 | 国产三级国产精品国产专区50 | 在线播放日韩av | 日p视频 | 在线亚洲播放 | 婷婷伊人综合 | 91毛片在线| www.91成人| 成人免费在线视频观看 | 国产欧美精品一区二区三区四区 | 久久久国产精品视频 | 99性视频 | 51精品国自产在线 | 成人一级片在线观看 | 天天综合网久久综合网 | 极品久久久久久久 | 中文字幕 国产精品 | 99久久精品午夜一区二区小说 | 天天操狠狠操夜夜操 | 国产成人精品a | 国产精品免费久久久久影院仙踪林 | 色国产精品一区在线观看 | 美国av片在线观看 | 久久精品1区2区 | 在线观看黄a| av在线进入 | 中文字幕在线免费看线人 | 四虎影院在线观看av | 亚洲国产欧洲综合997久久, | 伊人天堂网 | 91精品视频一区二区三区 | 久久这里只有精品久久 | 日韩一区二区三免费高清在线观看 | 一区 在线观看 | 国产一卡久久电影永久 | 国产日韩视频在线观看 | 91入口在线观看 | 国产理论免费 | av一区二区三区在线 | 国产国语在线 | 日韩激情一二三区 | 超碰人在线 | 亚洲日韩欧美一区二区在线 | 中文字幕韩在线第一页 | 一级片观看 | 欧美精品资源 | 国产精品美女久久久久aⅴ 干干夜夜 | 麻豆精品视频 | 国模视频一区二区 | 久草免费福利在线观看 | 亚洲国产黄色片 | 精品1区2区| 日韩在线激情 | 亚洲a在线观看 | 国产精品人成电影在线观看 | 国产99久久99热这里精品5 | 国产精品18久久久久久久久 | 毛片一区二区 | 日韩欧美国产视频 | 黄网站色视频免费观看 | 中文字幕色网站 | 色成人亚洲 | 四虎在线影视 | www.夜夜干.com| 日韩小视频 | 手机成人在线电影 | 欧美日韩久 | 国产高清在线免费视频 | 免费高清在线一区 | 五月婷婷黄色网 | 久操视频在线播放 | 国产电影一区二区三区四区 | 国产三级视频在线 | 亚州中文av | 国产一区二三区好的 | 99久久激情 | 国产精品毛片 | 日韩欧美综合视频 | 日本久久免费电影 | 欧美精品久久久久久久久久久 | 伊人资源视频在线 | 久久天天躁夜夜躁狠狠躁2022 | 日韩在线网址 | 国产 欧美 日产久久 | 国产日韩在线一区 | 国产高清久久久久 | 久草视频观看 | 国产91影院 | 不卡精品视频 | 超碰97人人射妻 | 日韩精品视 | 超碰免费成人 | 精品国产aⅴ麻豆 | 7777精品伊人久久久大香线蕉 | 中文字幕日韩电影 | 丁香婷婷成人 | av看片网 | 九九热在线视频免费观看 | 99久久激情视频 | 激情深爱 | 亚洲国产免费看 | 国产伦精品一区二区三区免费 | 91视视频在线直接观看在线看网页在线看 | 日韩久久久久久久久久 | 91香蕉视频在线 | 国产精品一区二区三区久久 | 久久久久免费网 | www.com.黄| 免费网站污 | 97成人免费 | 在线视频观看你懂的 | 99久久久国产精品 | 丁香 婷婷 激情 | 91免费视频国产 | 午夜少妇av | 国产又粗又猛又爽又黄的视频免费 | 久久久综合香蕉尹人综合网 | 久久久影片 | 激情综合站 | 精品国产一区二区在线 | 中文字幕一区二区三区在线播放 | 69视频网站| 久久国产网站 | 操久| 亚洲影音先锋 | 精品久久一二三区 | 99久久婷婷国产 | 成人毛片在线观看视频 | 中午字幕在线 | 欧美五月婷婷 | 色婷婷视频在线 | 夜夜操天天 | 久草免费在线观看视频 | 91看片淫黄大片一级在线观看 | 国产在线免费 | 婷婷 综合 色 | 午夜视频在线观看欧美 | 亚洲高清视频在线观看免费 | 色视频成人在线观看免 | 亚洲另类人人澡 | 日韩精品中文字幕在线不卡尤物 | 亚洲理论在线观看电影 | 亚洲国产精品成人精品 | 2020天天干天天操 | 国产精品久久久久久久免费 | 日韩av一区二区在线影视 | 亚洲极色 | 精品一区久久 | 四虎永久免费在线观看 | 国产亚洲精品美女久久 | 国产成人一区二区三区久久精品 | 九色在线视频 | 91精品国自产在线观看 | 日韩福利在线观看 | 国产片免费在线观看视频 | 国产色 在线 | 亚洲精品一区二区三区在线观看 | 国产精选在线观看 | 在线视频日韩 | 99视频偷窥在线精品国自产拍 | 久久久久久久久免费视频 | 国产精品久久久久久久久久99 | 毛片网站观看 | av网站手机在线观看 | 国内精品一区二区 | 国产一区在线免费观看视频 | 永久中文字幕 | 免费男女网站 | 久久精品国产精品亚洲精品 | 日韩av手机在线看 | 91精品国产91久久久久 | 麻豆视频免费网站 | 亚洲色图美腿丝袜 | 天天精品视频 | av在线收看 | 免费国产视频 | 久久精品国产亚洲aⅴ | 四虎影视4hu4虎成人 | 91久久爱热色涩涩 | 精品国产乱码久久久久久久 | 色中文字幕在线观看 | 天天狠狠干| 欧洲精品码一区二区三区免费看 | 国产99久久久国产精品成人免费 | 国产精品久久久久免费a∨ 欧美一级性生活片 | 国产亚洲精品女人久久久久久 | 日本91在线 | 日韩两性视频 | 一区二区三区中文字幕在线 | 日韩精品免费一区二区三区 | 91精品国产麻豆 | 成人av教育 | 天堂中文在线视频 | 在线观看岛国av | av色综合网 | 九九热视频在线免费观看 | 久草在线视频免赞 | 国产日产欧美在线观看 | 久久看毛片 | 亚洲综合色网站 | 91刺激视频 | 免费欧美精品 | 天天曰 | 免费一级片在线观看 | 天天操夜夜操 | 免费成人av电影 | 国产精品精 | 亚洲激情五月 | 精品九九九九 | 久久综合九色九九 | 国产黄色观看 | 丁香九月婷婷 | 中文字幕一区二区三区四区视频 | 99草在线视频| 亚洲精品一区二区三区四区高清 | 久久精品中文 | 久久精品国产精品亚洲 | 久久久久久久免费观看 | 亚洲欧美在线综合 | 黄网av在线 | 鲁一鲁影院| 亚洲精品777 | 久久精品国产v日韩v亚洲 | 亚洲午夜久久久综合37日本 | 日韩国产精品久久久久久亚洲 | 亚洲午夜精品一区二区三区电影院 | 精品免费视频. | 久久99九九99精品 | 天天射射天天 | 九九九九九国产 | 天天拍天天操 | 亚洲高清在线精品 | 色综合久久中文综合久久牛 | 国产精品丝袜在线 | 婷婷在线色 | 美女黄频视频大全 | 天天亚洲综合 | 五月婷婷激情综合网 | 国产一区在线免费观看 | 国产美女网站在线观看 | 国产精品久久久久国产a级 激情综合中文娱乐网 | 69成人在线 | 欧美日本高清视频 | 黄色日视频 | 在线成人一区二区 | 在线观看视频 | 亚洲人成免费网站 | 免费观看国产精品 | 欧美日韩国产页 | 91中文字幕 | 色噜噜日韩精品欧美一区二区 | 国产一区二三区好的 | 日本三级大片 | 久久综合免费视频 | 免费在线观看黄 | 午夜 久久 tv | 在线影院中文字幕 | 最新精品视频在线 | 国产中文字幕在线播放 | 久草视频手机在线 | 日本不卡一区二区三区在线观看 | 亚洲成人精品久久 | 综合五月 | 97av色| 亚洲欧美日韩精品一区二区 | 黄色小说在线观看视频 | 91麻豆精品国产91久久久久久久久 | 最新av免费 | 九九一级片 | 69人人| av线上看 | 91在线观看欧美日韩 | 日韩av免费在线电影 | 欧美日韩高清在线一区 | 最新超碰在线 | 日韩精品一区二区三区免费观看视频 | 99c视频高清免费观看 | 亚洲va在线va天堂va偷拍 | 丁香六月婷婷开心 | 人人看黄色 | av在线超碰 | 精品欧美在线视频 | av解说在线 | 亚洲九九九在线观看 | 国产成人精品一区二区在线 | 超碰在线最新 | 99精品福利视频 | 亚洲视频在线观看网站 | 91av视频在线观看免费 | 国产涩涩在线观看 | 欧美国产日韩一区二区三区 | 国际精品网| 尤物97国产精品久久精品国产 | 亚洲黄网址 | 一区中文字幕在线观看 | 天天干天天干天天射 | 中文字幕乱码在线播放 | 91精品国产一区 | 天天激情综合网 | 99久久精品国 | 亚洲天堂网站视频 | 91专区在线观看 | 国产高清视频网 | 精品成人国产 | 欧美精品在线一区 | www好男人 | 国产日韩精品一区二区在线观看播放 | 中文字幕在线高清 | 天天舔天天搞 | 高清av免费看 | 中文字幕在线观看第二页 | 九九久久久久久久久激情 | 国产视频精品在线 | 少妇搡bbbb搡bbb搡aa | 久久久免费电影 | 久久人人爽人人爽人人 | 九九热只有精品 | 嫩模bbw搡bbbb搡bbbb | 日韩av看片 | 91色视频 | 亚洲精品国产欧美在线观看 | 天天综合狠狠精品 | 中文字幕永久 | 久久精品二区 | 久久免费大片 | 国产精品 9999 | 国产一级久久久 | av网站在线观看播放 | 久久久久久久久久网 | 99久久精品无免国产免费 | 成 人 黄 色 视频播放1 | 国产成人av电影在线观看 | 激情欧美一区二区三区免费看 | 99精品热视频只有精品10 | 狠狠狠狠狠狠 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 婷婷性综合 | 99九九99九九九视频精品 | 天天综合网天天 | 国产精品久久久久久久久久白浆 | 激情综合啪啪 | 色综合亚洲精品激情狠狠 | 久久国产精品免费视频 | 国产女人免费看a级丨片 | 国产中文| 精品国产一区二区三区男人吃奶 | 成人一级片免费看 | 久久久久久影视 | 亚洲久草在线视频 | 一区二区三区免费看 | 91桃色在线免费观看 | av专区在线 | 中文字幕av最新 | 欧美精品久久久久久久 | 国产福利91精品 | 97国产精品免费 | 国产精品久久久久久久久婷婷 | 五月婷丁香网 | 免费网站在线观看人 | 免费看一级黄色 | 国产综合激情 | 99久久精品免费看国产一区二区三区 | 精品99久久 | 色综合人人 | 成人免费ⅴa | 婷婷色在线资源 | 久久成熟 | 久精品在线 | 丰满少妇高潮在线观看 | 日本三级不卡视频 | 一区二区三区播放 | 国产中文字幕视频在线观看 | 麻豆国产精品永久免费视频 | 美女视频黄是免费的 | 欧美日韩三区二区 | 国产成人精品av在线观 | 97国产在线视频 | 亚洲欧美国产日韩在线观看 | 国产99精品在线观看 | 制服丝袜天堂 | 久久伊人精品一区二区三区 | 久久 精品一区 | 亚洲综合精品视频 | 蜜桃视频日本 | 丁香婷婷色 | 精品欧美在线视频 | 在线视频 影院 | 久久爱992xxoo | 天天色中文 | 激情五月婷婷综合 | 日本乱码在线 | 国产精品毛片一区二区在线 | 国产99久久九九精品 | 国产色秀视频 | 日韩av三区| 国产一级高清视频 | 在线免费性生活片 | 亚洲精品网址在线观看 | av久久久久久 | 天天操夜夜操夜夜操 | 麻豆av电影 | 国产精品免费视频一区二区 | av九九| 日韩特级片 | 美女视频黄的免费的 | 久久久网址 | 午夜电影av | 日韩激情第一页 | 色五丁香 | 在线探花 | 久久综合狠狠综合久久激情 | 日韩资源在线播放 | 美女视频网站久久 | 在线亚洲高清视频 | 日本爱爱片 | av免费看在线 | 日韩精品91偷拍在线观看 | 精品国产_亚洲人成在线 | 国产美女网站在线观看 | 日韩美视频 | 香蕉视频日本 | 亚洲精品黄色片 | 最新av电影网站 | 久草免费看| 亚洲va欧洲va国产va不卡 | 国产91精品高清一区二区三区 | 亚洲日韩中文字幕 | 欧美午夜精品久久久久久孕妇 | 久久久激情视频 | 久久久国产精品网站 | 国产午夜精品免费一区二区三区视频 | 婷婷激情五月综合 | 91试看| 天天狠狠操 | 在线亚洲免费视频 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 99热 精品在线 | 九色琪琪久久综合网天天 | 久久精品毛片基地 | 日韩3区 | 精品国产欧美一区二区三区不卡 | 五月婷婷六月丁香激情 | 91视频在线播放视频 | 久久人人精 | 亚洲涩涩一区 | 成人午夜性影院 | 中文字幕成人网 | 绯色av一区 | 香蕉精品视频在线观看 | 91久久久国产精品 | 天堂v中文 | 国产精品自产拍在线观看桃花 | 香蕉久草 | 午夜狠狠干| 亚洲免费在线观看视频 | 麻豆久久 | 国际精品久久久 | 免费看短 | 怡红院久久| 天天爱天天操天天爽 | 亚洲国产成人精品电影在线观看 | 精品国产一区二区三区av性色 | 久久久久久美女 | 天天干天天摸 | 五月婷婷久久丁香 | 国产九色在线播放九色 | 成年在线观看 | 天堂av网址 | 在线精品观看 | 色婷婷一区 | 亚洲一区二区视频在线播放 | 国产亚洲激情视频在线 | 午夜精品久久久久久久99水蜜桃 | 99在线观看 | 91av国产视频 | 欧美精品亚洲二区 | 一区二区三区免费网站 | 97超碰色偷偷 | 欧美一区二区在线刺激视频 | 精品欧美一区二区三区久久久 | 麻豆系列在线观看 | 中文字幕在线视频第一页 | 精品一区二区免费视频 | 在线国产一区二区三区 | 看v片| 九九热精品国产 | 久久免费高清视频 | 天天爽天天摸 | 欧美成人精品欧美一级乱黄 | 久久99精品国产麻豆婷婷 | 国产美女搞久久 | 伊人资源站 | 国内精品免费久久影院 | 亚洲高清久久久 | 国产精品色视频 | 国产精品成人自产拍在线观看 | 香蕉手机在线 | 午夜精品一区二区三区免费视频 | 中文字幕在线观看完整版 | 一级一片免费看 | 天天玩天天干天天操 | 欧美成人影音 | 中文字幕在线看 | 黄色小视频在线观看免费 | 九九有精品 | 精品uu | 在线看国产精品 | 亚洲成人一二三 | 久久福利小视频 | 日韩av一区二区在线影视 | 在线视频一二区 | 成人小视频在线免费观看 | 五月情婷婷 | 激情网在线视频 | 久久久精品福利视频 | 亚洲伊人av | 不卡视频在线 | 韩日三级在线 | 中文字幕在线观看播放 | 国产精品久久久av久久久 | 天天曰天天 | 国产四虎在线 | 激情网在线视频 | 夜夜躁狠狠躁日日躁视频黑人 | 美女网站黄在线观看 | 江苏妇搡bbbb搡bbbb | 国产精品无| 亚洲人人射 | 97香蕉超级碰碰久久免费软件 | 一本—道久久a久久精品蜜桃 | 欧美在线视频二区 | 在线观看中文字幕dvd播放 | 99综合电影在线视频 | 国产高清日韩欧美 | 国产亚洲高清视频 | 天天干天天天天 | 亚洲国产综合在线 | 中文字幕国内精品 | 国产成人av综合色 | 日韩精品一区二区三区中文字幕 |