OpenGL学习(2)——绘制三角形(补)

上一篇的补充,通过绘制三角形来完成矩形的绘制。此外,完成章节后练习。

绘制矩形

一个矩形由两个三角形组成,因此绘制矩形需要绘制两个三角形,一共6个顶点,其中2个顶点重复画了两次。
为了减小开销,仅储存矩形的4个顶点来完成绘制,需要使用Element Buffer Object按照绘制顺序存储顶点索引。
举例说明:矩形四个顶点(a, b, c, d),EBO中存储的索引为(0, 1, 2, 0, 2, 3),表示矩形由三角形abc和acd组成。
创建和配置EBO的方法与VBO类似:

初始化顶点和索引数组

float vertices[] = {0.5f, 0.5f, 0.0f,
                    0.5f, -0.5f, 0.0f,
                    -0.5f, 0.5f, 0.0f,
                    -0.5f, -0.5f, 0.0f};
unsigned int indices[] = {0, 1, 2,
                          1, 2, 3};

创建EBO

unsigned int EBO;
glGenBuffers(1, &EBO);

配置EBO

同样可以通过绑定VAO来保存EBO的配置。

但要注意,和VBO不同的是,在解绑VAO之前,不可以解绑EBO。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

渲染循环

在使用EBO时,调用glDrawElements函数代替glDrawArrays函数。
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

练习

1. Try to draw 2 triangles next to each other using glDrawArrays by adding more vertices.

float vertices[] = {0.5f, 0.5f, 0.0f,
                    0.5f, -0.5f, 0.0f,
                    -0.5f, 0.5f, 0.0f,

                    0.5f, 0.5f, 0.0f,
                    -0.5f, 0.5f, 0.0f,
                    0.0f, 1.0f, 0.0f};
while(!glfwWindowShouldClose(window)){

    processInput(window);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glfwSwapBuffers(window);
    glfwPollEvents();
}

2. Create the same 2 triangles using two different VAOs and VBOs for their data.

float vertices1[] = {0.5f, 0.5f, 0.0f,
                     0.5f, -0.5f, 0.0f,
                     -0.5f, 0.5f, 0.0f};

float vertices2[] = {0.5f, 0.5f, 0.0f,
                     -0.5f, 0.5f, 0.0f,
                     0.0f, 1.0f, 0.0f};
unsigned int VBO[2];
unsigned int VAO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);

glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window)){

    processInput(window);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO[0]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(VAO[1]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glfwSwapBuffers(window);
    glfwPollEvents();
}

*3.Create two shader programs where the second program uses a different fragment shader that outputs the color yellow; draw both triangles again where one outputs the color yellow. *

int fragmentShader[2];
const char *fragmentShaderSource1 = "#version 330 core
"
                                   "out vec4 fragColor;"
                                   "void main()"
                                   "{fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);}";
const char *fragmentShaderSource2 = "#version 330 core
"
                                   "out vec4 fragColor;"
                                   "void main()"
                                   "{fragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);}";
fragmentShader[0] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[0], 1, &fragmentShaderSource1, NULL);
glCompileShader(fragmentShader[0]);

fragmentShader[1] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[1], 1, &fragmentShaderSource2, NULL);
glCompileShader(fragmentShader[1]);

shaderProgram[0] = glCreateProgram();
glAttachShader(shaderProgram[0], vertexShader);
glAttachShader(shaderProgram[0], fragmentShader[0]);
glLinkProgram(shaderProgram[0]);
shaderProgram[1] = glCreateProgram();
glAttachShader(shaderProgram[1], vertexShader);
glAttachShader(shaderProgram[1], fragmentShader[1]);
glLinkProgram(shaderProgram[1]);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader[0]);
glDeleteShader(fragmentShader[1]);
while(!glfwWindowShouldClose(window)){

    processInput(window);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderProgram[0]);
    glBindVertexArray(VAO[0]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glUseProgram(shaderProgram[1]);
    glBindVertexArray(VAO[1]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glfwSwapBuffers(window);
    glfwPollEvents();
}
原文地址:https://www.cnblogs.com/yiqian/p/10759358.html