• OpenGL+VS2019代码搭建 安静点


     状态机

    OpenGL自身是一个巨大的状态机,变量(描述该如何操作)的大集合

    OpenGL的状态通常被称为上下文(Context)。

    状态设置函数(State-changing Function)

    状态应用的函数(State-using Function)

    通过改变一些上下文变量来改变 OpenGL状态,从而告诉OpenGL如何去绘图

    对象

    一个对象是指一些选项的集合,代表OpenGL状态的一个子集

    例如:可以用一个子集来代表绘图窗口的设置:设置它的大小、支持的颜色位数等等。可以把对象看做一个C风格的结构体:

     结构如下:

    struct object_name

    { GLfloat option1;

    GLuint option2;

    GLchar[] name;

    };

    通常把OpenGL上下文比作一个大的结构体,包含很多子集:

    // OpenGL的状态

    struct OpenGL_Context

    { ...

    object* object_Window_Target;

    ...

    };

     但是需要注意的是:

    当前状态只有一份,如果每次显示不同的效果,都重新配置会很麻烦。

    这时候我们就需要一些小助理(对象),帮忙记录某些状态信息。以便复用。

    如果有10种子集,每个子集有10种不同的状态集合,那么我们将需要100个小助理(对象)

    // 创建对象 
    GLuint objectId = 0; 
    //给小助理(对象)一个编号
    glGenObject(1, &objectId); 
    // 绑定对象至上下文 
    glBindObject(GL_WINDOW_TARGET, objectId);
     
    // 设置GL_WINDOW_TARGET对象的一些选项 下面这些设置都是给对象objectId 做的设置
    glSetObjectOption(GL_WINDOW_TARGET,GL_OPTION_WINDOW_WIDTH, 800); 
    glSetObjectOption(GL_WINDOW_TARGET,GL_OPTION_WINDOW_HEIGHT, 600); 
    
    // 将上下文的GL_WINDOW_TARGET对象设回默认 ,此时已经将objectId 对象解绑了,但是这个对象已经存在这个状态机(就是这个大对象集合)中了,
    // 所以再次调用glBindObject方法重新绑定的时候,这些选项就会再次生效。还要注意的是我们最好习惯性的使用这个解绑方法,防止未解绑导致出现上一个对象设置的状态出现在了当前对象上。
    glBindObject(GL_WINDOW_TARGET, 0);

     所以如果我们一开始就需要多个对象,并且对于一些选项有想法的情况,可以直接创建多对象,遍历多次分别设置一些默认的状态。在这个遍历中,以绑定对象和解绑对象分别为开始和结束。

     GLFW+GLAD

     不同操作系统上,创建支持OpenGL的窗口接口不同。需要我们自己处理创建窗口,定义OpenGL上下文以及处理用户输入。不同操作系统,不同显卡获取OpenGL函数的接口也有差异。

     GLFW解决操作系统层面的不同

    •     创建窗口
    •     定义上下文
    •     处理用户输入

    GLAD使得代码可以用于不同的OpenGL驱动

    • OpenGL本身只是标准/规范
    • 各个厂家具体实现方式可以不同

    VS2019代码搭建

    GLFW 第三方库(帮助你支持OpenGL上下文的窗口)

    下载地址:https://www.glfw.org/

     

     下载解压之后包含了这些文件:

     下面使用vs2019创建一个空项目:

     

     然后我们需要配置GLFW,我们在包含目录中将提前下好的GLFW中的图中的文件夹包含进去:

     

     还要将和VS2019相关的.lib文件也包含到项目的库目录中:

     

     还要注意的是在Windows上,还需使用OpenGL库opengl32.lib(随Microsoft SDK一起提供,在安装Visual Studio时默认安装)和glfw3.lib。

     

    GLAD使用了一个web服务器,通过输入想要为使用的OpenGL版本和相关信息生成库文件。 转到GLAD服务网站(https://glad.dav1d.de),具体设置如下:

     

    点击网站右下方的“GENERATE”,进入下载界面,下载glad.zip文件,解压缩即可使用。

     

    下载解压之后有下面2个文件夹:

     

    首先,配置包含目录:

    然后将src文件中的glad.c文件添加到项目中:

     验证是否配置正确

     代码如下:

    // GLAD的include文件包含所需的OpenGL头文件(如GL/GL.h),因此确保在其他需要OpenGL的头文件(如GLFW)之前包含GLAD。就是#include <glad/glad.h> 放在最前面
    #include <glad/glad.h> 
    #include <GLFW/glfw3.h>
    #include <iostream>
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    
    int main() {
        // 初始化GLFW,只有初始化完成之后才能够使用GLFW的函数
        glfwInit();
        // GLFW配置设置
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        // 如果是苹果系统的话使用下面代码
    #ifdef __APPLE__ 
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    #endif
        // 创建窗口 大小和名称
        GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
        if (window == NULL) {
            std::cout << "Failed to create GLFW window" << std::endl;
            // 此函数销毁所有剩余的窗口和光标
            glfwTerminate();
            return -1;
        }
        //GLFW将窗口的上下文设置为当前线程的上下文
        glfwMakeContextCurrent(window);
        // 告诉GLFW我们希望每当窗口调整大小的时候调用这个函数
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
        //GLAD
        // glad: 加载所有OpenGL函数指针
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
        // 渲染循环 一个循环就是一帧 只要是窗体不关闭,就会一直循环
        while (!glfwWindowShouldClose(window)) {
            processInput(window);
    
            // 在这里,我们将屏幕设置为了类似黑板的深蓝绿色
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //状态设置
            // 调用glClear函数,清除颜色缓冲之后,整个颜色缓冲都会被填充为glClearColor里所设置的颜色。
            glClear(GL_COLOR_BUFFER_BIT); //状态使用
            // glfw: 交换缓冲区 该函数在指定窗口的前后缓冲区交换
            // 前缓冲区:屏幕上显示的图像
            // 后缓冲区:正在渲染的图像
            // glfwSwapBuffers函数会交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),
            // 它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上
            glfwSwapBuffers(window);
            // 轮询IO事件(按键按下 / 释放、鼠标移动等)通过下面方法就可以是得窗体对鼠标做出的动作做出反应,比如关闭,移动窗体等
            glfwPollEvents();
        }
        // glfw: 回收前面分配的GLFW先关资源. 一定要注意,只有关闭窗体之后才会跳出while循环走到这一步!!!
        glfwTerminate();
        return 0;
    }
    // glfwGetKey函数:需要一个窗口以及一个按键作为输入;函数将会返回这个按键是否正在被按下
    void processInput(GLFWwindow* window)
    {
        // 如果按下了ESC键,设置窗体的关闭标志为true,代表窗体可以退出
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
    }
    
    // 当改变窗口的大小的时候,视口也应该被调整。我们可以对窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        // 设置窗口维度
        // glViewport(前两参数为窗口左下角位置,3.宽度,4.高度)
        glViewport(0, 0, width, height);
    }

     结果:

  • 相关阅读:
    Leetcode 40. Combination Sum II
    Leetcode** 39. Combination Sum
    Leetcode** 210. Course Schedule II
    Leetcode** 207. Course Schedule
    Leetcode 257. Binary Tree Paths
    Leetcode** 131. Palindrome Partitioning
    Leetcode** 20. Valid Parentheses
    Leetcode 14. Longest Common Prefix
    dfs序 二进制优化 Codeforces Round #316 (Div. 2)D. Tree Requests
    Codeforces Round #318 D. Bear and Blocks
  • 原文地址:https://www.cnblogs.com/anjingdian/p/16631048.html
Copyright © 2020-2023  润新知