LearnOpenGL.com笔记

* 本文用作学习learnOpenGL.com的备忘

1. Hello Triangle

  1. Rendering pipeline(蓝色部分可编写shader程序):
  2. some primitives:
    • GL_LINES: Vertices 0 和1 是一条线,Vertices 2 and 3 是一条线,依次类推。
    • GL_LINE_STRIP: 所有相邻点组成一条线。
    • GL_LINE_LOOP: 相邻点连线,最后一个点和第一个点也连线。
    • GL_TRIANGLES: Vertices 0, 1, and 2 成三角形,Vertices 3, 4, and 5成三角形,以此类推。
    • GL_TRIANGLE_STRIP: 所有相邻三个点组成三角形,举例:(0,1,2)(1,2,3) … - GL_TRIANGLE_FAN: 第一个点和剩余任意两个相邻点组成三角形,举例:(0, 1, 2) (0, 2, 3), (0, 3, 4)…
  3. Vertex buffer objects (VBO) 存储GPU上的vertices。使用VBO可以实现向GPU批量传送数据。
  4. OpenGL中每个buffer都有一个唯一ID,使用glGenBuffers给一个buffer生成一个ID。之后需要使用glBindBuffer绑定该buffer的类型。最后使用glBufferData向buffer传送数据:
unsigned int VBO;
glGenBuffers(1, &VBO); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  1. glBufferData的最后一个参数:
    • GL_STATIC_DRAW: 数据不经常变化
    • GL_DYNAMIC_DRAW: 数据经常变化
    • GL_STREAM_DRAW: 每次render数据都变化
  2. 要使用shader,需要创建shader对象并赋予一个ID,声明其源码字符串并编译:
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
  1. 将多个shader链接到一个shader program对象。首先创建该对象,然后链接:
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
  1. 每次需要render时,使用glUseProgram执行shader program:
glUseProgram(shaderProgram);
  1. 使用glVertexAttribPointer声明解析vertices数据的方式,然后使用glEnableVertexAttribArray启用vertices数据:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  

其中:
- glVertexAttribPointerglEnableVertexAttribArray的第一个参数指明shader中layoutlocation
- glVertexAttribPointer的第二个参数指明vertex attribute元素个数,比如此处vertex attribute是个vec3(代表x,y,z坐标),那么填3
- 第三个参数为数据类型;第四个不解释;第五个为数据量;第六个为offset

10. OpenGL中强制使用vertex array object (also known as VAO) 来存储解析方式(也就是必须要有VAO)。假设没有不这样做,每次render都需要一大坨代码:

// 0. copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 1. then set the vertex attributes pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  
// 2. use our shader program when we want to render an object
glUseProgram(shaderProgram);
// 3. now draw the object 
someOpenGLFunctionThatDrawsOurTriangle();   

有了VAO,可以配置一次,以后每次render之前绑定VAO即可。
生成VAO方法如下:

unsigned int VAO;
glGenVertexArrays(1, &VAO);  

配置VAO方法如下:

// ..:: Initialization code (done once (unless your object frequently changes)) :: ..
// 1. bind Vertex Array Object
glBindVertexArray(VAO);
// 2. copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. then set our vertex attributes pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

以后每次需要render时,只需要:

// ..:: Drawing code (in render loop) :: ..
// 4. draw the object
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();   
  1. element buffer object(EBO)用于使用数据的索引来render。
    生成EBO方法,并绑定数据方法如下:
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 
  1. 在绑定VAO之后绑定的VBO和EBO被认为是该VAO的VBO和EBO,所以现在render的代码如下:
// ..:: Initialization code :: ..
// 1. bind Vertex Array Object
glBindVertexArray(VAO);
// 2. copy our vertices array in a vertex buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. copy our index array in a element buffer for OpenGL to use
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 4. then set the vertex attributes pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  

[...]

// ..:: Drawing code (in render loop) :: ..
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glBindVertexArray(0);

猜你喜欢

转载自blog.csdn.net/gdymind/article/details/80666188
今日推荐