• 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("
    ");
    
    	WideCharToMultiByte(CP_ACP, 0, wszBuf, sizeof(wszBuf), szBuf, sizeof(szBuf), NULL, FALSE);
    	printf("%s
    ", 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();
    }
    
    

    2. OpenGL的初始化过程

    2.1 初始化顶点数组对象 --> glGenVertexArrays, glBindVertexArrays,

    2.2 分配顶点缓存对象 ---> glGenBuffers, glBindBuffer

    2.3 将数据载入缓存对象 ---> glBufferData

    2.4 初始化顶点与片段着色器(之前的代码已把此部分删除)

    2.5 顶点着色器里面的数据关联到顶点属性数组 --> glVertexAttribPointer

    2.6 启动顶点属性数组 ---> glEnableVertexAttribArray

    3. OpenGL 渲染过程

    3.1 清除屏幕 ---> glClear

    3.2 激活顶点数组 ---> glBindVertexArrays

    3.3 使用OpenGL绘制函数 ---> glDrawArrays etc

  • 相关阅读:
    Python学习杂记_2_格式化字符串的一些操作
    Python学习杂记_1_PyCharm使用的一些收获
    autolayout sizeclass 资料集锦
    据说这个是获得当前的控制器方法,没试过
    Mac下搭建php开发环境【转】
    搜索栏会消失 uisearchbar 狂点消失的问题解决
    mac下XAMPP服务器配置多站点配置局域网配置 (转)
    在 Xcode 6 中使用矢量图( iPhone 6 置配 UI)
    收到远程通知,怎么区分是点击通知栏提醒进去的还是在foreground收到的通知?
    开发经验之状态机思想,分别使用了swift,OC,C,PHP语言实现
  • 原文地址:https://www.cnblogs.com/zjzyh/p/4174639.html
Copyright © 2020-2023  润新知