zoukankan      html  css  js  c++  java
  • OpenGL学习笔记(二)

    1. 状态机

    OpenGL自身就是一个大型状态机(State Machine),它使用了一种状态模型来追踪所有的OpenGL状态变量。当一个状态值被设置之后,它就一直保持这个状态,直到其他函数对它进行修改为止。

    当我们使用glGenBuffer声明buffer并使用glBufferData创建初始化buffer的时候,这个buffer其实是在显存中的,接下来是由GPU而非CPU访问。

    而我们调用的OpenGL API,以及以后的shader,其实就是改变OpenGL状态机的状态,通过draw call告诉GPU如何从buffer取数据来进行绘制。
    在我看来,这是一种数据-控制模型。

    2. 顶点数组与顶点属性

    通过声明、创建并初始化vertex array buffer,可以把数据存到到GPU中。

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions) * sizeof(float), positions, GL_STATIC_DRAW);

    开启并定义顶点属性

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, NULL);

    在OpenGL中,vertex顶点和vertex position顶点位置是两种概念(因为顶点的位置会随着物体的变化而变化)
    顶点还包含

    • 纹理
    • 坐标
    • 法线
    • 颜色
    • 按法线切线

    3. 绘制

    最后再在循环中调用glDrawArrays()进行draw call绘制

    glDrawArrays(GL_TRIANGLES, 0, 3);

    贴上完整代码

    #include <GLFW/glfw3.h>
    
    int main(void)
    {
        GLFWwindow* window;
    
        // 初始化GLFW库,对应的需要在退出时候调用glfwTerminate()销毁资源
        if (!glfwInit())
            return -1;
    
        // 创建window和OpenGL context,该window的context需要手动设置成current context
        window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
        if (!window)
        {
            glfwTerminate();
            return -1;
        }
    
        // 把window的context设置成current context
        glfwMakeContextCurrent(window);
    
        // 设置顶点的位置
        GLfloat positions[] = {
            -0.5f, -0.5f,
             0.0f,  0.5f,
             0.5f, -0.5f
        };
    
        // 用来存储缓冲对象名称
        unsigned int VBO;
        // 生成1个缓冲对象名称,并写到bufferObject
        glGenBuffers(1, &VBO);
        // 绑定顶点缓冲到bufferObject
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        // 创建并初始化缓冲对象的数据
        glBufferData(GL_ARRAY_BUFFER, sizeof(positions) * sizeof(float), positions, GL_STATIC_DRAW);
    
        // 开启顶点着色器的属性,不然无法显示绘制
        glEnableVertexAttribArray(0);
        // 定义顶点数据的属性,其中一个位置有2个浮点数,不需要normalized,步进为sizeof(float)*2字节
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, NULL);
    
        // 检查window的关闭标志
        while (!glfwWindowShouldClose(window))
        {
            // 清除屏幕颜色
            glClear(GL_COLOR_BUFFER_BIT);
    
            // draw call,从0开始渲染3个索引
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            // 交换window的前后buffer
            glfwSwapBuffers(window);
    
            // 处理事件
            glfwPollEvents();
        }
    
        glfwTerminate();
        return 0;
    }
  • 相关阅读:
    作业 20181030-3互评Alpha版本
    Alpha阶段事后诸葛亮会议记录
    Alpha发布用户使用报告
    20181023-2 贡献分配
    作业 20181016-1 Alpha阶段贡献分配规则
    Scrum立会报告+燃尽图(十月三十日总第二十一次)
    OC中时间函数的使用
    OC中的集合详解
    面向对象的概念详解(转)
    集中类
  • 原文地址:https://www.cnblogs.com/jacobchen/p/14756055.html
Copyright © 2011-2022 走看看