《Learn OpenGL》https://learnopengl.com/Introduction 讲述 OpenGL 3.3 core profile 版本。

Getting Started

OpenGL

  1. OpenGL 3.0 引入 API 废弃机制;OpenGL 3.1 废弃了fixed-function pipeline相关的函数;OpenGL 3.2 开始划分 core profile 和 compatibility profile。

  2. OpenGL context 是一个大状态机,OpenGL object 是状态机里的一部分状态,使用模式如下:

    // An OpenGL object
    struct object_name {
        float  option1;
        int    option2;
        char[] name;
    };
    
    // The State of OpenGL
    struct OpenGL_Context {
      	...
      	object_name* object_Window_Target;
      	...
    };
    
    // create object
    unsigned int objectId = 0;
    glGenObject(1, &objectId);
    // bind/assign object to context
    glBindObject(GL_WINDOW_TARGET, objectId);
    // set options of object currently bound to GL_WINDOW_TARGET
    glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH,  800);
    glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
    // set context target back to default
    glBindObject(GL_WINDOW_TARGET, 0);
    // delete object
    glDeleteObject(objectId);
    

Hello Triangle

  1. OpenGL Pipeline

    1. Vertex puller
    2. Vertex Shader: 处理单个 vertex,变换坐标,改变属性
    3. Primitive Assembly: 处理构成一个基本图形的所有 vertex,输出基本图形(点,三角形、线段)
    4. Tessellation
      1. Tessellation Control Shader
      2. Primitive Assembly
      3. Tessellation Primitive Generator
      4. Tessellation Evaluation Shader
      5. Primitive Assembly
    5. Geometry Shader: 处理基本图形,输出额外 vertex
    6. Primitive Assembly
    7. Transform Feedback (optional)
    8. Flat shading
    9. Clipping
    10. Perpspective Divide
    11. Viewport Transform
    12. Front/Back Face Selection
    13. Rasterization:处理基本图形,输出像素点
    14. Fragment Shader:为像素点着色,处理光照、阴影等。Fragment 指 OpenGL 里为了渲染单个像素点所需要的所有数据。
    15. Per-Fragment Operation: scissor test, stencil test, depth test, blending, logical operation, write mask
    16. Framebuffer
  2. 只有 Vertex Shader 和 Fragment Shader 是没有默认值,必须自行提供的。

  3. Normalized Device Coordinates(NDC): 被 vertex shader 处理后,x、y、z坐标应该在 [-1.0, 1.0]之间,x 轴向右,y 轴向上(与 screen space coordinate 相反),且原点在坐标系中间(在屏幕坐标系中原点是左上角)。在 viewport transform 中会使用 glViewport() 指定的参数将 NDC 坐标转换到 SSC 坐标,转换后的坐标称为 fragment shader 的输入。

  4. 使用 shader

  5. 使用 Vertex Buffer Object

    unsigned int vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    // GL_STREAM_DRAW: 写一次,读几次
    // GL_STATIC_DRAW: 写一次,读多次
    // GL_DYNAMIC_DRAW: 多次写,多次读