OpenGL超級寶典筆記----框架搭建


  自從工作后,總是或多或少的會接觸到客戶端3d圖形渲染,正好自己對於3d圖形的渲染也很感興趣,所以最近打算從學習OpenGL的圖形API出發,進而了解3d圖形的渲染技術。到網上查了一些資料,OpenGL的入門學習通常是用《OpenGL開發指南》和《OpenGL超級寶典》這兩本書。博主最近在看《OpenGL超級寶典》,在這里分享一些自己的理解,希望和園子里的人一起學習和探討。

 1、 創建工程

《OpenGL超級寶典》的作者為了避免每個例子都重復寫一些窗口創建,捕獲消息,專門寫了一個應用程序的框架。程序框架的代碼在github上,先把里面的sb7code代碼下載下來,然后解壓縮,可以看到有下面這些文件:

  從上面的CMakeLists.txt可以發現,這個工程是用cmake來生成的。所以需要下載cmake,至於怎樣使用cmake,可以參考使用cmake自動構建工程。除了cmake外,工程中使用了glfw庫來創建窗口和捕獲鍵盤和鼠標的消息。為了使用glfw,需要先把它編譯成庫文件,glfw的源文件在extern目錄中,它的工程也是通過cmake來建立的,所以如果會使用cmake的話就可以先通過cmake建立一個vs工程,然后編譯工程就可以生成對應的庫文件了。把在debug模式下生成的glfw3.lib(重命名為glfw3_d.lib)和release模式下生成的庫文件glfw3.lib拷貝到lib目錄中。最后運行cmake生成vs工程,生成的工程可以在build中找到,打開build下面的superbible7.sln工程文件,就可以發現很多書本上介紹的例子項目了。其中sb7就是整個工程的框架,在sb7里面實現了類application,新的程序只需要繼承這個類,然后根據需要重寫里面的一些方法,最后用DECLARE_MAIN宏創建這個程序就可以了。創建程序的大致代碼如下:

#include <sb7.h>

class simpleclear_app : public sb7::application
{
       //重載一些方法
     virtual void render(double currentTime)
    {
        static const GLfloat white[] = { 1.0f, 0.0f, 0.0f, 1.0f };
        glClearBufferfv(GL_COLOR, 0, white);
     }
};

DECLARE_MAIN(test_app)

然后編譯就可以直接運行了,這樣我們就可以完全不用關心窗口的創建,只需要關心怎樣用opengl進行渲染就行了。

2、application

   現在來看下類application和宏DECLARE_MAIN怎樣為我們創建應用程序的。application類中有個run方法,主要的代碼如下:

 1  virtual void run(sb7::application* the_app)
 2     {
 3         bool running = true;
 4         app = the_app;
 5 
 6         glfwInit()
 7         init();
 8         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, info.majorVersion);
 9         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, info.minorVersion);
10         glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
11         glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
12         glfwWindowHint(GLFW_SAMPLES, info.samples);
13         glfwWindowHint(GLFW_STEREO, info.flags.stereo ? GL_TRUE : GL_FALSE);
14 
15         window = glfwCreateWindow(info.windowWidth, info.windowHeight, info.title, NULL, NULL);
16         glfwMakeContextCurrent(window);
17         glfwSetWindowSizeCallback(window, glfw_onResize);
18         glfwSetKeyCallback(window, glfw_onKey);
19         glfwSetMouseButtonCallback(window, glfw_onMouseButton);
20         glfwSetCursorPosCallback(window, glfw_onMouseMove);
21         glfwSetScrollCallback(window, glfw_onMouseWheel);
22         gl3wInit();
23         startup();
24 
25         do
26         {
27             render(glfwGetTime());
28             glfwSwapBuffers(window);
29             glfwPollEvents();
30             running &= (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_RELEASE);
31             running &= (glfwWindowShouldClose(window) != GL_TRUE);
32         } while (running);
33 
34         shutdown();
35         glfwDestroyWindow(window);
36         glfwTerminate();
37     }

  run方法先調用glfwInit來初始化glfw,然后調用glfwCreateWindow來創建窗口,隨后調用glfwSetXXXCallback來設置消息處理的回調函數,最后通過while循環來執行render函數,獲取消息等。run中還有init和setup函數,這些函數只有是用來給子類設置一些自己的參數。

  DECLARE_MAIN宏的定義如下:

 1 #define DECLARE_MAIN(a)                             \
 2 sb7::application *app = 0;                          \
 3 int CALLBACK WinMain(HINSTANCE hInstance,           \
 4                      HINSTANCE hPrevInstance,       \
 5                      LPSTR lpCmdLine,               \
 6                      int nCmdShow)                  \
 7 {                                                   \
 8     a *app = new a;                                 \
 9     app->run(app);                                  \
10     delete app;                                     \
11     return 0;                                       \
12 }

  這個宏定義了WinMain函數,它是win32窗口程序的入口,相當於控制台程序的main函數。然后在這個函數里面new了我們自己定義的application子類對象,最后調用對象的run方法來創建窗口和調用render函數。

  有了這個框架,基本上我們只需要繼承下application類,重寫下render函數就可以跑我們的opengl程序了,非常的方便。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM