Reputation: 1117
I'm trying to run my first OpenGL program. In the main() function I have infinity loop:
do {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programID);
_collection[0].draw();
_collection[1].draw();
glfwSwapBuffers(window);
glfwPollEvents();
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0)
The function _collection[].draw() should draw rectangles:
static const GLfloat g_vertex_buffer_data[] = {
x, y, 0.0f, // lewy górny
x, y - 0.4f, 0.0f, // lewy dolny
x + 0.4f, y - 0.4f, 0.0f, // prawy dolny
x + 0.4f, y, 0.0f, // lewy górny
x + 0.02f, y - 0.02f, 0.0f, // lewy górny
x + 0.02f, y - 0.4f + 0.02f, 0.0f, // lewy dolny
x + 0.4f - 0.02f, y - 0.4f + 0.02f, 0.0f, // prawy dolny
x + 0.4f - 0.02f, y - 0.02f, 0.0f, // lewy górny
};
static const GLfloat g_color_buffer_data[] = {
1.0f, 1.0f, 1.0f, // lewy górny
1.0f, 1.0f, 1.0f, // lewy dolny
1.0f, 1.0f, 1.0f, // prawy dolny
1.0f, 1.0f, 1.0f, // lewy górny
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(vertexPosition_modelspaceID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// przekazuję kolory wierzchołków
glEnableVertexAttribArray(vertexColorID);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
vertexColorID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// rysuję wszystko
glDrawArrays(GL_QUADS, 0, 8);
glDisableVertexAttribArray(vertexPosition_modelspaceID);
glDisableVertexAttribArray(vertexColorID);
My problem is that: When I run the program I see only the effect of a run the first function draw() - this with index 0. Then I change places these functions:
_collection[1].draw();
_collection[0].draw();
I still see the effect of the first function - in this case with index number 1.
It looks like there is something blocking the code from the second draw() function to run.
What is the problem? How can I fix it?
Upvotes: 0
Views: 158
Reputation: 1111
The second draw function isn't being blocked from executing. Since your vertice and color information is defined as static inside the body of your draw()
function, those values won't change regardless of which element of _collection
you are drawing. That's why drawing the two collections yields the same result -- you are drawing your vertices in the same location, and with the same colors.
To fix the problem, you only want to store vertex and color information once. Each of your collections should only contain x
and y
values, indicating their position. You don't want multiple collections of vertices and colors, you want a single collection of vertices and colors which you draw in several different locations.
You should create your vertex and color arrays in your main function before you enter your main loop. You should also use glGenBuffers
and glBindBuffer
followed by glBufferData
to tell OpenGL about your vertex and color arrays in your main program before your main loop as well. Then you can take the calls to glGenBuffers
and glBufferData
out of your draw function. You should also call glVertexAttribPointer
for both the vertex and color arrays in your main function and remove them from your draw()
function.
// Note that your vertex data isn't contingent on 'x' and 'y' positions.
// You will use the vertex shader to move your boxes around later.
GLfloat g_vertex_buffer_data[] = {
0.0f, 0, 0.0f, // lewy górny
0.0f, 0.4f, 0.0f, // lewy dolny
0.4f, 0.4f, 0.0f, // prawy dolny
0.4f, 0.0f, 0.0f, // lewy górny
0.02f, 0.02f, 0.0f, // lewy górny
0.02f, 0.4f + 0.02f, 0.0f, // lewy dolny
0.4f - 0.02f, 0.4f + 0.02f, 0.0f, // prawy dolny
0.4f - 0.02f, 0.02f, 0.0f, // lewy górny
};
GLfloat g_color_buffer_data[] = {
1.0f, 1.0f, 1.0f, // lewy górny
1.0f, 1.0f, 1.0f, // lewy dolny
1.0f, 1.0f, 1.0f, // prawy dolny
1.0f, 1.0f, 1.0f, // lewy górny
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(
vertexColorID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// All of the above information you only need to specify to openGL once, not every time you draw a frame!
You need to change your shader so that it accepts the x and y offset from each of your collections:
#version 150
uniform float collectionX;
uniform float collectionY;
in vec3 vertexPosition_modelspaceID; // This is the vertex attribute which the name 'vertexPosition_modelspaceID' corresponds to.
// Remember that your shader will also accept a color and give it to the fragment shader, include that code as well.
void main()
{
gl_Position = vec4(vertexPosition_modelspaceID.x + collectionX, vertexPosition_modelspaceID.y + collectionY, vertexPosition_modelspaceID.z, 1.0);
}
And you need to get the locations of the uniform variables you just added to your shader in your main program before the loop:
// Call these functions after you compile and link your shaders. programID should be your compiled and linked shader program.
GLuint collectionXID = glGetUniformLocation(programID, "collectionX");
GLuint collectionYID = glGetUniformLocation(programID, "collectionY");
Your draw function will be very simple now:
void draw()
{
glDrawArrays(GL_QUADS, 0, 8);
}
Finally, your main loop will look something like this:
do
{
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(vertexPosition_modelspaceID);
glEnableVertexAttribArray(vertexColorID);
glUniform1f(collectionXID, _collection[0].x);
glUniform1f(collectionYID, _collection[0].y);
_collection[0].draw();
glUniform1f(collectionXID, _collection[1].x);
glUniform1f(collectionYID, _collection[1].y);
_collection[1].draw();
glfwSwapBuffers(window);
glDisableVertexAttribArray(vertexPosition_modelspaceID);
glDisableVertexAttribArray(vertexColorID);
glfwPollEvents();
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0)
Note that you are now specifying the location at which to draw the vertices to your shader program by passing your individual collection's x
and y
position with the glUniform1f function. It is more common to move your vertices around with a transformation matrix, but that is a rather complicated topic itself.
Assuming the collections have different x
and y
positions, they will now draw in different locations.
Upvotes: 1