openGL-使用不同的着色器渲染多个对象

时间:2018-09-17 14:48:15

标签: opengl

我正在尝试渲染许多橙色三角形,并在其上叠加一些黑线(以便形成一个漂亮的立方体)。我正在使用两个着色器来渲染不同的颜色:

橙色片段着色器( fragment.glsl ),我用来绘制三角形:

#version 120

void main() {
    gl_FragColor = vec4(0.8,0.4,0.1,1.0);
}

和我用来绘制线条的黑色着色器( fragment_lines.glsl ):

#version 120

void main() {
    gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}

我用于生成旋转立方体(橙色三角形+黑色线)的代码如下:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "matrix.h"
#include "shader.h"
#include "util.h"

int main(void) {
    if (!glfwInit()) {
        return -1;
    }

    GLFWwindow *window = glfwCreateWindow(800, 800, "HelloGL", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glEnable(GL_DEPTH_TEST);

    if (glewInit() != GLEW_OK) {
        glfwTerminate();
        return -1;
    }

    GLuint program = load_program("shaders/vertex.glsl", "shaders/fragment.glsl");
    GLuint program_lines = load_program("shaders/vertex.glsl", "shaders/fragment_lines.glsl");
    GLuint position = glGetAttribLocation(program, "position");
    GLuint position_lines = glGetAttribLocation(program_lines, "position");
    GLuint matrix = glGetUniformLocation(program, "matrix");
    GLuint matrix_lines = glGetUniformLocation(program_lines, "matrix");


    float data[] = {
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
    };

    GLuint buffer = gen_buffer(sizeof(data), data);
    GLuint buffer_lines = gen_buffer(sizeof(data), data);

    while (!glfwWindowShouldClose(window)) {

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        float mat[16];
        mat_identity(mat);
        mat_translate(mat, 0, -0.5, 0);
        mat_rotate(mat, 0.1, 0.3, 1, glfwGetTime());
        mat_ortho(mat, -2, 2, -2, 2, -2, 2);


        glUniformMatrix4fv(matrix, 1, GL_FALSE, mat);
        glUniformMatrix4fv(matrix_lines, 1, GL_FALSE, mat);

        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glEnableVertexAttribArray(position);
        glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, buffer_lines);
        glEnableVertexAttribArray(position_lines);
        glVertexAttribPointer(position_lines, 3, GL_FLOAT, GL_FALSE, 0, 0);


        glUseProgram(program);
        glDrawArrays(GL_TRIANGLES, 0, 12*3);

        glUseProgram(program_lines);
        glDrawArrays(GL_LINES, 0, 12*3);

        glDisableVertexAttribArray(position);
        glDisableVertexAttribArray(position_lines);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

但是,当我运行此代码时,我只能在屏幕上看到黑线。如果我交换

的顺序
glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 12*3);

glUseProgram(program_lines);
glDrawArrays(GL_LINES, 0, 12*3);

然后我只看到橙色三角形,没有黑线的迹象。

我该如何进行设置,以使两个立方体面(橙色三角形)和相应的边缘(黑线)都可见?

ps .:

我正在使用Ubuntu 18.04。

我知道我应该删除重复的点以提高效率,但这是一个简单的示例。

我知道线条坐标有点愚蠢,它们应该足够好,可以看到示例工作。

可以在https://github.com/fogleman/HelloGL

中找到矩阵代码

1 个答案:

答案 0 :(得分:1)

进行两个绘制功能,例如

DrawCube()
{
 glUniformMatrix4fv(matrix, 1, GL_FALSE, mat);
 glBindBuffer(GL_ARRAY_BUFFER, buffer);
 glEnableVertexAttribArray(position);
 glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

 glUseProgram(program);
 glDrawArrays(GL_TRIANGLES, 0, 12*3);

 glUseProgram(0);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
}

代码的问题是您要混合两次绘制的着色器状态。相同的 DrawLines()单独代码和编写代码,并且它们在render函数中只需将它们都调用。