Send two triangles to a Vertex Shader. Opengl, C++, GLSL

Asked

Viewed 306 times

4

I am learning in college graphic processing with Opengl at C++. We are using the GLFW and GLEW libraries. My program consists of creating two triangles in different parts of the window. I created an array with the coordinates of the triangle, and two VBO and a VAO for it. Then I want to apply a translation to this triangle to print it in another part of the screen, using the second VBO and the same VAO.

My problem here is this: I addressed the two triangles in the VAO, one in the 0(Location) position and the other in the 1.:

//4- Cria os vértices e seu VBO e VAO. Define a cor a partir de um Uniform
void SceneManager::setupScene()
{
// Set up vertex data (and buffer(s)) and attribute pointers
    GLfloat vertices[] = {
        // Positions                    
        -0.25f,  0.0f, 0.0f,
        0.25f,  0.0f, 0.0f,
        0.0f, 0.5f, 0.0f,
    };



    GLuint VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);


    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);



    glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)

                                                            GLint colorLoc = glGetUniformLocation(shader->Program, "color");
    assert(colorLoc > -1);
    glUseProgram(shader->Program);
    glUniform4f(colorLoc, 0.1f, 1.0f, 0.2f, 1.0f);

    triangulo2(*vertices);

}

Triangle 2:

 void SceneManager::triangulo2(GLfloat arrayVertices) {

        //Variável que via armazenar o VBO do triangulo2
       GLuint VBO2;
            glGenBuffers(1, &VBO2);

            //Vincula o VAO único
            glBindVertexArray(VAO);

            //Inicializa o VBO2 e gera seus atributos
            glBindBuffer(GL_ARRAY_BUFFER, VBO2);
            glBufferData(GL_ARRAY_BUFFER, sizeof(arrayVertices), &arrayVertices, GL_STATIC_DRAW);

            //Ponteiro de atributo de posição desse triângulo. VAO
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
            glEnableVertexAttribArray(1);


    glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)


    GLint colorLoc = glGetUniformLocation(shader->Program, "color");
    assert(colorLoc > -1);
    glUseProgram(shader->Program);
    glUniform4f(colorLoc, 0.1f, 1.0f, 0.2f, 1.0f);

}

Section where I send VAO to Vertex Shader:

void SceneManager::render()
{
    // Clear the colorbuffer
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    posicionaTriangulo2();

    if (resized) //se houve redimensionamento na janela, redefine a projection matrix
    {
        setupCamera2D();
        resized = false;
    }
    //Busca o VAO e desenha na tela.
    // Draw container
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    //drawElements é quando estou usando o EBO.
    glBindVertexArray(0);
}





   Só que eu não sei como passar corretamente os dois locations para o meu programa vertex shader. Sei que o objeto gl_Position da GLSL pode ser usado no meu vertex shader para processar as posições dos vértices de um objeteo passado ao shader, mas não sei como fazer quando eu passo mais de um objeto à esse shader. 

I tried to use two gl_Position, but when doing this, instead of appearing only a triangle as before, nothing appeared on the screen.

Can someone shed some light? There is no quality material on it, no decent tutorials...

This is my Vertex Shader file:

version 440 core

//Posições do primeiro triângulo
layout (location = 0) in vec3 position;

//Posições do segundo triângulo:
layout (location = 1) in vec3 posicao2;

uniform vec4 color;  

out vec4 ourColor;

uniform mat4 model1;
uniform mat4 projection;

void main()
{
    gl_Position = projection * model1 * vec4(position, 1.0f);

//Quando eu adicionei este gl_Position, nada mais aparece na tela.
    gl_Position = projection * vec4(posicao2, 1.0f);

    ourColor = color;
}

This is the function "positionTriângulo2()", where I look for the model matrix in Vertex Shader (this is the matrix where I put the transformations, in this case), and put in it some transformations to be added in Vertex Shader to my triangle set in VAO.

void SceneManager::posicionaTriangulo2() {
    // Render scene
        shader->Use();

    // Create transformations 
    //Esse método cria uma matriz4, mas não tem parâmetros... ONDE ELES SÃO DEFINIDOS? É a glm que o define?
    //A MATRIZ É PASSADA PARA O VERTEX SHADER
    model = glm::mat4();
    //model = glm::rotate(model, (GLfloat)glfwGetTime()*5, glm::vec3(0.0f, 0.0f, 0.1f));
    //model = glm::scale(model, glm::vec3(0.5, 1.0, 2.0));
    model = glm::translate(model, glm::vec3(1.0f, 0.3f, 0.0f));


    //Aplicar no rotate para uma rotação específica de 90 graus: glm::radians(90.0f)


    //EXEMPLO DO OPENGL:
    //trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
    //trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));

    // Get their uniform location
    GLint modelLoc = glGetUniformLocation(shader->Program, "model");

    // Pass them to the shaders
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

}
  • VAO stores the status of a buffer for drawing. You probably won’t be able to draw the 2 triangles defined in different buffers in the same VAO. Either you store all vertices in the same buffer or you use 2 Vaos (one for each object). The variable gl_Position is a predefined variable in Shader and using it more than once will not produce the result you expect

1 answer

4

There is a function there called positionTriangulo2(...), it does not have its implementation there but it seems to me that you still do not understand the concept of modern Opengl.

The idea of Opengl is to put all the information of what will be drawn in a linear array, vertices, colors, normal, etc. With this array in hand you upload this information to the GPU, On the Vertex Hader side you basically adjust the vertices and on the Fragment Hader side you adjust the colors of each pixel. Think CPU / GPU as client / server.

Once you have uploaded the information to the GPU, you will use the client to ask the server to render the information, basically you say: draw starting at position X of the array, each polygon will use Y array spaces and then you will skip N array positions and continue until the array is finished.

To draw 2 separate triangles you have some different options:

  • save 2 separate arrays for each triangle and upload individually (it is the weakest in performance)
  • use glDrawElements, in it you will upload the vertices where no matter the order in the array, pq when you request it to be drawn it is necessary to inform precisely this order (the indexes) that will be drawn
  • use a stop called "Primitive Restart", do not recommend using it pq is something much more recent and consequently is not available in any version of Opengl, being much more restrictive on the platform

If you’re saying there’s no quality material it’s because you don’t know these two sites:

These two sites are simply fantastic to help anyone who wants to learn Opengl, whether beginner level or even advanced.

  • Includes implementation of position functionTriângulo2()'.

  • Have you noticed that I ask GPU to draw the two triangles (one with the transformation model and the other without), in my Vertex Shader? But it only draws the last gl_position, which is the transformed triangle

  • Your theoretical explanation has cleared up a lot of things. I’m already paying more attention to learnopenGl as well. I’ll do the tutorial calmly. I already knew, but I found it confusing at first. In fact it is well didactic, it only requires patience.

  • But could you give me an example of how I would use the drawElements in this case?

  • I thought that way: glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_INT, VAO); The second parameter being the number of elements (what is defined by element here?). But the fourth parameter can’t be a VAO... It’s a pointer, but I don’t know what to put there.

  • 1
    1. vc got this part wrong, gl_position, in Vertex Shader, will only save one value, this main function of VS is called once for each vertex
  • 1
    1. I recommend starting with https://open.gl/ it is simpler
  • 1
    1. It’s been a while since I wrote code in opengl, but if you access this page here you will be able to understand well: https://open.gl/drawing
  • 1
    1. The fact that you understood the wrong Hader changes a lot of things
Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.