• 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程序了,非常的方便。

  • 相关阅读:
    DDD:管理“工作单元实例”的两种模式
    DDD:DDD+CQRS+高伸缩性的分布式架构
    ExtJS4.2:快捷键支持(没有你想象的那么简单)
    DDD:用 “四色原型” 进行 “职责分配”
    .NET:处理数据库事务中的并发
    Javascript:必须知道的Javascript知识点之“单线程事件驱动”
    技术交流:20130413线下交流总结,不再做苦逼的程序员
    Javascript:必须知道的Javascript知识点之“原型链”
    DDD:主键映射,你一直在使用的企业应用模式
    设计原则:重复的方式以及如何消除重复
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/5375676.html
Copyright © 2020-2023  润新知