openGl1

项目里很少用到渲染相关的东西,openGl都忘差不多了,复习一下
长期不用的东西很容易忘,对人来说,这也就是重复的意义
顺便记录一下上次看的时候忽略的

扩展

当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现
当一个扩展非常流行或者非常有用的时候,它将最终成为未来的OpenGL规范的一部分

多数图形渲染api都是一个状态机,不管是openGl还是vulkan,提供参数不同而已

类型

使用OpenGL的类型的好处是保证了在各平台中每一种类型的大小都是统一的

其他跳过了,直接开始吧
按照vulkan之前教程直接配置,不过发现c/c++没有这个项,得加个cpp才有这个选项
glad。驱动program控制显卡,而驱动版本多,函数位置不固定,所以调用函数常缓存指针,glad用于简化这个过程
配置好了,直接跑一下

#include <glad/glad.h>
int main() {
	return 0;
}

双缓冲

文中提到:
双缓冲(Double Buffer)

应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。 这是因为生成的图像不是一下子被绘制出来的,而是按照从左到右,由上而下逐像素地绘制而成的。最终图像不是在瞬间显示给用户,而是通过一步一步生成的,这会导致渲染的结果很不真实。为了规避这些问题,我们应用双缓冲渲染窗口应用程序。前缓冲保存着最终输出的图像,它会在屏幕上显示;而所有的的渲染指令都会在后缓冲上绘制。当所有的渲染指令执行完毕后,我们交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来,之前提到的不真实感就消除了。

这段话里面有一点,说单缓冲导致图像闪烁,因为图像是逐步生成的。这句话问题很多,为什么逐步生成会导致闪烁、不真实呢。难道双缓冲的图像就不是“逐步”生成的了吗。他像表达的意思可能是,“逐步”是使用双缓冲的原因。我理解的话,闪烁是因为反差过大,就像我先放一张黑图,再切成白图,频率除非快到我能直接看成一张灰色图,不然他就是“闪烁”的。也就是说逐步导致了速度不够快,可能IO原因,可能其他原因,不过不管什么原因,双缓冲这种时空置换的方式肯定比单缓冲快。从逻辑来看,双缓冲逻辑更简单,单缓冲如果渲染的时候有新的写入要怎么处理呢,可能这是更快的原因之一

成功开启黑窗

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include<iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}
class Tool {
public:
    static void InitGlfw() {
        glfwInit();//glfw初始化
    //oenGl主版本号
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        //oenGl次版本号
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        //oenGl 核心模式
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    }
    static auto CreateWindow() {
        GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
        if (window == NULL)
        {
            std::cout << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
            return window;
        }
        glfwMakeContextCurrent(window);//将我们窗口的上下文设置为当前线程的主上下文
        return window;
    }
    static int InitGlad() {
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
        {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
        return 0;
    }
    static void InitGlView() {
        glViewport(0, 0, 800, 600);//窗口左下角的坐标、窗口大小
    }
    static void BindAutoAdaptSize(GLFWwindow* window) {
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    }
    static void RenderLoop(GLFWwindow* window) {

        while (!glfwWindowShouldClose(window))//检查一次GLFW是否被要求退出
        {
            glfwSwapBuffers(window);//交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲)
            glfwPollEvents();//触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)
        }
    }
    static void Free() {
        glfwTerminate();
    }
private:
    
};
class MyWindow
{
public:
    MyWindow();
    ~MyWindow();
    bool IsSuccess();
private:
    GLFWwindow* window;
    bool succFlag = true;
};

MyWindow::MyWindow()
{
    Tool::InitGlfw();
    window = Tool::CreateWindow();
    if (window == NULL) {
        succFlag = false;
        return;
    }
     int gFlag= Tool::InitGlad();
    if (gFlag == -1) {
        succFlag = false;
        return ;
    }
    Tool::BindAutoAdaptSize(window);
    Tool::RenderLoop(window);
    Tool::Free();
}

MyWindow::~MyWindow()
{
}
bool MyWindow::IsSuccess()
{
    return succFlag;
}

int main()
{   
    auto myWindow = MyWindow();
    if (myWindow.IsSuccess()==false) {
        return -1;
    }

    return 0;
}
posted @ 2025-03-10 18:22  vil4  阅读(37)  评论(0)    收藏  举报