OpenGL编程指南第版本学习笔记 --- OpenGL程序实现过程(win32 + OpenGL)
1. 先上代码
头文件glCommon.h
#include <GL/glew.h>
#include <GL/GL.h>
#include <GL/GLU.h>
#define MAX_LEN 2048
void GLLog(const char *pszFormat, ...);
void SetupPixelFomat( HWND hWnd, HDC &hDC );
bool InitGL(HDC hDC, HGLRC &hRC);
void DestroyGL(HDC hDC, HGLRC hRC);
源文件
#include <stdio.h>
#include "glCommon.h"
void SetupPixelFomat( HWND hWnd, HDC &hDC )
{
hDC = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size
1, // version
PFD_SUPPORT_OPENGL | // OpenGL window
PFD_DRAW_TO_WINDOW | // render to window
PFD_DOUBLEBUFFER, // support double-buffering
PFD_TYPE_RGBA, // color type
32, // preferred color depth
0, 0, 0, 0, 0, 0, // color bits (ignored)
0, // no alpha buffer
0, // alpha bits (ignored)
0, // no accumulation buffer
0, 0, 0, 0, // accum bits (ignored)
24, // depth buffer
8, // no stencil buffer
0, // no auxiliary buffers
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0, // no layer, visible, damage masks
};
int pixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelFormat, &pfd);
}
bool InitGL( HDC hDC, HGLRC &hRC )
{
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
const GLubyte *glVersion = glGetString(GL_VERSION);
GLLog("OpenGL version = %s", glVersion);
if (atof((const char *)glVersion) < 1.5)
{
char strComplain[256] = {0};
sprintf_s(strComplain, 256,"OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card.",
glVersion);
MessageBox(NULL,(LPCWSTR)strComplain, _T("OpenGL version too old"),MB_OK);
return false;
}
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
MessageBox(NULL,(LPCWSTR)glewGetErrorString(GlewInitResult), _T("OpenGL version too old"),MB_OK);
return false;
}
return true;
}
void GLLog( const char *pszFormat, ... )
{
char szBuf[MAX_LEN];
va_list ap;
va_start(ap, pszFormat);
vsnprintf_s(szBuf, MAX_LEN, MAX_LEN, pszFormat, ap);
va_end(ap);
WCHAR wszBuf[MAX_LEN] = {0};
MultiByteToWideChar(CP_UTF8, 0, szBuf, -1, wszBuf, sizeof(wszBuf));
OutputDebugStringW(wszBuf);
OutputDebugStringA("\n");
WideCharToMultiByte(CP_ACP, 0, wszBuf, sizeof(wszBuf), szBuf, sizeof(szBuf), NULL, FALSE);
printf("%s\n", szBuf);
}
void DestroyGL( HDC hDC, HGLRC hRC )
{
if (hDC != NULL && hRC != NULL)
{
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
}
}
#include "glCommon.h"
HACCEL g_hAccelTable = NULL;
HGLRC g_hRC;
HDC g_hDC;
static GLuint VAOs[1];
static GLuint Buffers[1];
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void DrawScene();
void SceneInit();
void ReSizeScene(int w, int h);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
bool bRet = false;
static TCHAR szAppName[] = TEXT ("triangles");
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WndProc;
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance;
wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclassex.lpszMenuName = NULL;
wndclassex.lpszClassName = szAppName;
wndclassex.hIconSm = wndclassex.hIcon;
if (!RegisterClassEx (&wndclassex))
{
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
szAppName,
TEXT ("WindowTitle"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
500,
NULL,
NULL,
hInstance,
NULL);
SetupPixelFomat(hwnd, g_hDC);
bRet = InitGL(g_hDC, g_hRC);
if(!bRet)
DestroyGL(g_hDC, g_hRC);
ShowWindow (hwnd, iCmdShow);
SceneInit();
while (true)
{
if(!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE ))
{
DrawScene();
::SwapBuffers(g_hDC);
continue;
}
if (msg.message == WM_QUIT)
break;
// Deal with windows message.
if (! g_hAccelTable || ! TranslateAccelerator(msg.hwnd, g_hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
return (0);
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
EndPaint (hwnd, &ps);
return (0);
case WM_SIZE:
{
int w = LOWORD(wParam);
int h = HIWORD(wParam);
//ReSizeScene(w, h);
}
return (0);
case WM_DESTROY:
DestroyGL(g_hDC, g_hRC);
ReleaseDC(hwnd,g_hDC);
PostQuitMessage (0);
return (0);
case WM_CLOSE:
PostQuitMessage(0);
return (0);
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
void DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
void SceneInit()
{
glGenVertexArrays(1 ,VAOs);
glBindVertexArray(VAOs[0]);
GLfloat vertices[6][2] = {
{-0.9f, -0.9f},
{0.85f, -0.9f},
{-0.9f, 0.85f},
{0.9f, -0.85f},
{0.9f, 0.9f},
{-0.85f, 0.9f},
};
glGenBuffers(1, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
}
void ReSizeScene( int w, int h )
{
SceneInit();
}