Vertex Buffer Object not drawing in SDL window - opengl

I'm just using the opengl SDL template with Xcode, and everything runs fine. I removed the Atlantis code, and changed the main extension to .mm, then added some testing code to drawGL. Drawing a simple triangle (using immediate mode) at this point inside drawGL gives me a white triangle, but when I add the code to draw using a vertex buffer object, i just get a black window.
Here is my VBO drawing code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity();
GLuint buffer;
float vertices[] = {
0.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 0.0f,
1.0f,-1.0f, 0.0f
};
// VBO doesn't work :(
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9, vertices, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);

Your glVertexPointer() call looks suspect for VBO usage. I think you need a BUFFER_OFFSET construct instead of the vertices pointer.

Related

Draw 2D HUD elements over 3D rendered scene

I searched for this and only found a post from 2014 asking about a somewhat similar situation. However, as I couldn't understand what was done there, I'm asking again, specifically for my implementation, hoping this sheds some light on the topic in general as well. I am fairly new to c++ and openGL, so please be so kkind as to excuse stupid mistakes.
I'm trying to implement a simple 2D HUD for my 3D game. Now, my game is fully rendered, due to having a bloom effect in my game, I even rendered my game on a screen quad.
What I now want to do ist placing a HUD over this rendered scene, I, however, can't seem to do that.
My screen quad for the game is drawn like so:
unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
if (quadVAO == 0)
{
float quadVertices[] = {
// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// texCoords
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
// setup plane VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
What I tried to do, ist change my renderQuad method to a renderHUDquad one by basically just changing the dimensions of the quad to make it appear in the bottom left corner of the screen.
The code looks as follows:
unsigned int HUDquadVAO = 0;
unsigned int HUDquadVBO;
void renderHUDQuad()
{
if (HUDquadVAO == 0)
{
float HUDquadVertices[] = {
// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// texCoords
0.0f, 0.02f,
0.0f, 0.0f,
0.2f, 0.0f,
0.0f, 0.02f,
0.2f, 0.0f,
0.2f, 0.02f
};
// setup plane VAO
glGenVertexArrays(1, &HUDquadVAO);
glGenBuffers(1, &HUDquadVBO);
glBindVertexArray(HUDquadVAO);
glBindBuffer(GL_ARRAY_BUFFER, HUDquadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(HUDquadVertices), &HUDquadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
}
glBindVertexArray(HUDquadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
As this only needs to be a small green quad, i.e. a health bar for the player, I was thinking about just assigning it a green texture or sth..
However, when drawing my two quads like this:
// Third pass = Combined bloom pictures
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
bloomShader->use();
// Set uniform for multiple layout uniforms
bloomShader->setUniform("scene", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorAndLightBuffers[0]);
// Set uniform for multiple layout uniforms
bloomShader->setUniform("bloomBlur", 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, pingpongBuffer[horizontal == 0 ? 1 : 0]);
bloomShader->setUniform("bloom", bloom);
bloomShader->setUniform("exposure", exposure);
renderQuad();
renderHUDQuad();
// Swap buffers
glfwSwapBuffers(window);
I only get the HUD element without any of the stuff I drew before as if the rest of the screen was rendered black. I thought I could just add this to the old buffer, as there a way to do this?
You did screw up your GL state very badly:
void renderHUDQuad() {
if (HUDquadVAO == 0)
{
[...]
glGenVertexArrays(1, &quadVAO);
You actually use quadVAO in the rest of this function, so you overwrite your fullscreen quad by the smaller one, which means the rest of your scene will be scaled down to this quad from the next frame on...

glDrawArray not drawing the second time

Hi so i have been basically pulling my hair out trying to understand this OpenGL confusion
i have tried to find answers in books, in tutorials , and even experimenting around with it
SO basically i have a opengl program that draws the first time my two triangles, however when i try to redraw the first triangle again it doesnt seem to be working
i dont know what information i am missing , but its no t making any sense
as far as i understand once the VAO and VBO have been created and bounded and buffered to memory, and vertex attrib pointers set and enabled that once i bind the vao object that i want to draw as many times as i like, i just have to do that
after initialization which works for me, the problem is that once i rebind another vao object it doesnt seem to draw it
my code is quiet long , i can paste it here if you like, but i think that the drawing part of the code would be sufficient
here it is
GLfloat vec[] = {0.0f, 0.0f,
1.0f, -1.0f,
-1.0f, -1.0f};
GLfloat vec2[] = {0.0f, 1.0f,
1.0f, 0.0f,
-1.0f, 0.0f};
//next step is to upload data to graphics memory
//generating a buffer from openGL
GLuint vbo;
GLuint vbo2 ;
GLuint vao;
GLuint vao2;
glGenBuffers(1, &vbo);
glGenBuffers(1, &vbo2);
glGenVertexArrays(1, &vao);
glGenVertexArrays(1, &vao2);
//to upload the actual data must make the object active by binding it to a target
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//upload the data of active object to memory
glBufferData(GL_ARRAY_BUFFER, sizeof(vec), vec, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec2), vec2, GL_STATIC_DRAW);
//bind and draw
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
glClear(GL_COLOR_BUFFER_BIT);
//rendering second triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBindVertexArray(vao2);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
//rendering the first triangle again------where the problem lies!!!
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
You'll also need to clear the depth buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
If you follow a tutorial then you will probably have enabled depth testing in the openGL setup boilerplate it provided. This is because more people will want to use the depth buffer than not.
you can also not call glEnable(GL_DEPTH_TEST); during setup.

c++ Opengl, Win memory leak

I've created a simple opengl program on Windows 7 using WIN api.
I've setup the window by following the tutorial on MSDN win api website.
The window works perfectly, even with input logging it does not leak any memory and works alright stays at 1.7 MB of ram.
With opengl context it takes 11MB.
If i want to draw something like Rectangle it begins to leak by 200 kb.
(The rectangle draws perfectly fine....)
It starts at 14.5 MB and grows up to 50MB and continues.
There are no 'new' keywords in the whole program, it is very simple program. Only create window. Than while loop in which the rendering is done...
Here is the main.
int main()
{
Window wind(800,600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(!wind.isCloseRequested())
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
Vector3f Vertices[3];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
wind.update();
Sleep(16);
}
wind.Destroy();
return 0;
}
glGenBuffers(1, &VBO);
make memory leak. You need create buffer one time and using it or destroy buffer every time with glDeleteBuffers
By the way, before using any OpenGL function I recommended read docs. Many OpenGL function allocate some internal buffers in memory or resources in GPU and need call delete/destroy.

How to draw polygon with 3D points in modern openGL?

I know in 2.0- openGL we can draw a line simply like this.
glBegin(GL_LINES);
glVertex3f(20.0f,150.0f,0.0f);
glVertex3f(220.0f,150.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glEnd();
but how to do similar thing in modern openGL(3.0+)
I have read Drawing round points using modern OpenGL but the answer is not about certain point,since I want to draw polygon with points have certain coordinates,it's not quite helpful.
I use this code,but it shows nothing except a blue background.what do I missed?
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
static const GLfloat g_vertex_buffer_data[] = {
20.0f, 150.0f, 0.0f, 1.0f,
220.0f, 150.0f, 0.0f, 1.0f,
200.0f, 160.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);
do{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
4, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_LINES, 0, 2); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
1) You have to define an array of vertices, that contain the points of your polygon lines. Like in your example:
GLfloat vertices[] =
{
20.0f, 150.0f, 0.0f, 1.0f,
220.0f, 150.0f, 0.0f, 1.0f,
200.0f, 160.0f, 0.0f, 1.0f
};
2) You have to define and bind a Vertex Buffer Object (VBO) to be able to pass your vertices to the vertex shader. Like this:
// This is the identifier for your vertex buffer
GLuint vbo;
// This creates our identifier and puts it in vbo
glGenBuffers(1, &vbo);
// This binds our vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// This hands the vertices into the vbo and to the rendering pipeline
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
3) Now we are ready to draw. Doing this:
// "Enable a port" to the shader pipeline
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// pass information about how vertex array is composed
glVertexAttribPointer(0, // same as in glEnableVertexAttribArray(0)
4, // # of coordinates that build a vertex
GL_FLOAT, // data type
GL_FALSE, // normalized?
0, // stride
(void*)0);// vbo offset
glDrawArrays(GL_LINES, 0, 2);
glDisableVertexAttribArray(0);
Step 1) and 2) can be done before rendering as initialization. Step 3) is done in your rendering loop. Also you'll need a vertex shader and a fragment shader to visualize the line with color.
If you don't know anything about these things and like to start with OpenGL 3, I'd suggest to start over with a tutorial like this:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-1-opening-a-window/

cannot draw my triangle with OpenGL depth test enabled

I write a program to draw a simple triangle and I use VAO、VBO and GLSL shaders. The result is the following:
But if I enable depth test using:
glEnable(GL_DEPTH_TEST)
nothing appears in the window.
Now I post some code of my program:
float positionData[] = {
-0.8f, -0.8f, 0.0f,
0.8f, -0.8f, 0.0f,
0.0f, 0.8f, 0.0f };
float colorData[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
void initVBO()
{
// Create and populate the buffer objects
GLuint vboHandles[2];
glGenBuffers(2, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
glBindBuffer(GL_ARRAY_BUFFER,positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER,9 * sizeof(float),
positionData,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER,9 * sizeof(float),
colorData,GL_STATIC_DRAW);
glGenVertexArrays(1,&vaoHandle);
glBindVertexArray(vaoHandle);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vaoHandle);
glDrawArrays(GL_TRIANGLES,0,3);
glBindVertexArray(0);
glutSwapBuffers();
}
My question is : why I cannot draw the triangle after enabling depth test?
There are multiple (types of) buffers used when rendering, typically. One is the color buffer, which contains the pixel data in some pixel format (IE: RGB with 8 bits for each color channel). Another typical buffer used is the depth buffer. Depth testing and writing to the depth buffer are two different things. Depth testing checks the depth value from a pixel against the depth value of the associated pixel(s) in the depth buffer and decides whether to accept or reject the pixel/fragment. Depth writing actually writes that value to a buffer, such as the depth buffer.
Your program probably writes to the depth buffer and test the depth buffer, but you never clear out the depth buffer, so it believes that, even though the color buffer has been cleared, that there are already things written to it that are at/in front (or whatever is configured) of the pixels you're trying to write to, so it rejects them.
Clear your depth buffer each frame, typically. You do this by passing the GL_DEPTH_BUFFER_BIT flag to glClear.
You need to explicitly clear the depth buffer, too:
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT)