zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    pandas Dataframe filter
    process xlsx with pandas
    data manipulate in excel with easyExcel class
    modify registry in user environment
    add number line in vim
    java import webservice
    ctypes MessageBoxA
    music 163 lyrics
    【python实例】自动贩卖机
    【python基础】sys模块(库)方法汇总
  • 原文地址:https://www.cnblogs.com/zjzyh/p/4174639.html
Copyright © 2011-2022 走看看