欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

openGL基础概念复习

程序员文章站 2022-07-04 11:10:29
...

重读LearnOpenGL CN,巩固下基础知识.
感谢Joey de Vries的LearnOpenGL,也感谢LearnOpenGL CN上各位大佬的翻译.

概念:

  • OpenGL本身并不是一个API,仅仅是一个规范,由Khronos组织制定并维护。 实际的OpenGL库的开发者通常是显卡的生产商。
  • 扩展(Extension): windows下opengl32.dll(opengl32.lib是导入库)中只包含openGL1.1以前的实现,新版本功能由显卡驱动实现,要想使用新版本功能,必须使用扩展机制,查找到相应的函数地址.
  • 立即渲染模式 (Immediate mode): 固定管线;核心模式(Core-profile): 可编程管线.前者慢慢废弃,后者更加灵活高效.
  • 状态机: OpenGL自身是一个巨大的状态机,OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL 状态:设置一些选项,操作一些缓冲。最后,我们使用当前OpenGL上下文来渲染。
  • 对象(Object): vbo是最常用的对象,但除了vbo还有很多对象,例如下面的例子:
// 创建对象 
GLuint objectId = 0; 
glGenObject(1, &objectId); 
// 绑定对象至上下文 
glBindObject(GL_WINDOW_TARGET, objectId); 
// 设置GL_WINDOW_TARGET对象的一些选项 
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800); 
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600); 
// 将上下文的GL_WINDOW_TARGET对象设回默认 
glBindObject(GL_WINDOW_TARGET, 0);

窗口系统:
最流行的几 个库有GLUT,SDL,SFML和GLFW。学习建议使用GLFW。

函数寻址:
openGL的函数及扩展中的函数,使用动态调用dll的方式使用,因此函数寻址比较麻烦,如下:

// 定义函数类型 
typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*); 
// 找到正确的函数并赋值给函数指针 
GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress("glGenBuffers"); 
// 现在函数可以被正常调用了 
GLuint buffer; 
glGenBuffers(1, &buffer);

glew和glad都可以帮助方便的使用openGL及其扩展的函数,现在glad比较流行.
glad.h必须在glfw3.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);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    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

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }    

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        // input
        // -----
        processInput(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}