PintoDoido
PintoDoido

Reputation: 1051

openGL - Render multiple objects using different shaders

I am trying to render a number of orange triangles and superimpose a few black lines on them (so to form a nice cube). I am using two shaders to render the different colors:

an orange fragment shader (fragment.glsl) the i use to draw the triangles:

#version 120

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

and a black shader that i use to draw the lines (fragment_lines.glsl):

#version 120

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

The code I am using to generate the rotating cube (orange triangles + black lines) is the following:

#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;
}

However, when I run this code I can only see the black lines on screen. If I swap the order of

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

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

Then I see only the orange triangles and no sign of the black lines.

How can i set this up so that both cube faces (orange triangles) and the corresponding edges (black lines) are visible?

ps.:

I am using Ubuntu 18.04.

I know I should remove duplicate points to improve efficiency, but this is a simple example.

I know the lines coords are a bit silly, they should be good enough to see the example working.

The matrix code can be found in https://github.com/fogleman/HelloGL

Upvotes: 2

Views: 1786

Answers (1)

Paritosh Kulkarni
Paritosh Kulkarni

Reputation: 862

Make two draw functions like

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);
}

The problem with your code is you are mixing shader states for two draws. Same separate and write code for DrawLines() and them in render function just call these both.

Upvotes: 1

Related Questions