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)
Related
I have a problem about activating a single texture to multiple buffer objects. I am trying to draw two different graphical objects that using the same texture. However could not make it bind.
After searchs so far, I could find an answer that fits to my question in this (Re-using one texture for multiple OpenGL Quads) link. I tried this method in my code by using the glBindTexture() function before the main opengl render loop, and also inside of the render loop but it did not bind. Also it is said that, bind the texture before the draw call, in here (OpenGl all models are with the same texture). But this way also did not work for me.
How can I use the exact same texture which is named texture1 for second buffer object?
I use two buffer objects and two vertex array objects for different graphical objects. What I really want to accomplish to describe only one texture after the first buffer array and then use the exact same texture for the second object. But when I try to bind the texture after vertex array object it does not work.
By the way I do not load any images for the texture. The main purpose that I use texture in order to utilize the texture coordinates. I do necessary works in the fragment shader.
#shader vertex
#version 330 core
layout (location=0) in vec3 position;
layout (location=1) in vec2 TextureCoords;
out vec2 TexCoord;
void main()
{
TexCoord = vec2(TextureCoords.x, TextureCoords.y);
gl_Position = vec4(position, 1.0);
};
#shader fragment
#version 330 core
out vec4 fragColor;
in vec2 TexCoord;
void main()
{
vec2 xy = TexCoord.xy;
vec4 color = vec4(vec3(xy.x), 1.0);
fragColor = color;
};
float vertexArray1[] = {
// Vertex Position | Texture Coords
// x y z x y
0.9f, 0.9f, 0.0f, 1.0f, 1.0f,
0.9f, 0.2f, 0.0f, 1.0f, 0.0f,
0.2f, 0.2f, 0.0f, 0.0f, 0.0f,
0.2f, 0.9f, 0.0f, 0.0f, 1.0f,
0.9f, 0.9f, 0.0f, 1.0f, 1.0f,
0.2f, 0.2f, 0.0f, 0.0f, 0.0f,
};
float vertexArray2[] = {
-0.2f, 0.9f, 0.0f, 1.0f, 1.0f,
-0.2f, 0.2f, 0.0f, 1.0f, 0.0f,
-0.9f, 0.2f, 0.0f, 0.0f, 0.0f,
-0.9f, 0.9f, 0.0f, 0.0f, 1.0f,
-0.2f, 0.9f, 0.0f, 1.0f, 1.0f,
-0.9f, 0.2f, 0.0f, 0.0f, 0.0f,
};
unsigned int buffer;
unsigned int VAO;
glGenBuffers(1, &buffer);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray1), vertexArray1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
glEnableVertexAttribArray(0);
unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
unsigned int buffer2;
unsigned int VAO2;
glGenBuffers(1, &buffer2);
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, buffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray2), vertexArray2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
glEnableVertexAttribArray(0);
// I want to use the previously described texture1 in here, but it does not bind.
glBindTexture(GL_TEXTURE_2D, texture1);
while(!glfwWindowShouldClose(window)){
processInput(window);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(VAO);
glDrawArrays(GL_LINES, 0, 6*3*1);
glBindVertexArray(VAO2);
glDrawArrays(GL_LINES, 0, 6*3*1);
glfwSwapBuffers(window);
glfwPollEvents();
}
Note: When I create another different texture for the buffer2 object it works like a charm. I mean texture1 for buffer1, texture2 for buffer2... But I want to keep the number of the texture as possible as minimum. Maybe in future developments, I will have to create more than 50 buffer object, thus I do not want to create different textures for every single buffer object.
EDIT: I have changed my misunderstanding of "binding a texture to a vertex array" to "enabling attributes of a texture for other objects". I've also included my shader scripts for debugging purposes.
Textures are not bound to buffer objects. When you draw something, it uses the currently bound texture, not one from a buffer.
Textures are not bound to VAOs either so there's no need to worry about that.
To use a texture, you do need to have a sampler in your shader, bind the texture unit (not the texture) to the sampler with glUniform1i, and call the texture function in the shader and do something with the return value.
Since you say your shader isn't doing anything with your texture anyway, I wonder how you can tell whether it's bound or not.
In fact, there's no reason to have a texture if you don't have a shader that does something with it! There is no magical texture-shader interaction. A texture is something you have to specifically query (by calling texture) or else it doesn't do anything by itself.
You don't need to have a texture to have texture coordinates.
Since you haven't shown your shaders, it's impossible to debug them for you.
After I review my code again and search once more, I came across a solution for my question.
And I guess where I was wrong was trying to bind a texture which was already bound to the global context, as #ColonelThirtyTwo pointed out in the comment.
As I understood, instead of trying to bind the same texture I should have called the glVertexAttribPointer() and enable with glEnableVertexAttribArray() for bounded texture.
Since in the answer of this question (glVertexAttribPointer clarification), it is said that:
"A Vertex Array Object or VAO is used to store the state of all the glVertexAttribPointer calls and the VBOs that were targeted when each
of the glVertexAttribPointer calls were made."
So I came up to this solution and it worked:
unsigned int buffer;
unsigned int VAO;
glGenBuffers(1, &buffer);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray1), vertexArray1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
glEnableVertexAttribArray(0);
unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
unsigned int buffer2;
unsigned int VAO2;
glGenBuffers(1, &buffer2);
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, buffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray2), vertexArray2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
glEnableVertexAttribArray(0);
// Inseted of the bind call,
// I called the glVertexAttribPointer() and glEnableVertexAttribArray() here.
// And if I am not wrong these calls use the currently bounded texture which is texture1.
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
while(!glfwWindowShouldClose(window)){
processInput(window);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(VAO);
glDrawArrays(GL_LINES, 0, 6*3*1);
glBindVertexArray(VAO2);
glDrawArrays(GL_LINES, 0, 6*3*1);
glfwSwapBuffers(window);
glfwPollEvents();
}
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...
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/
I am new to modern OpenGL VBO/VAO and I struggle with one thing: I have coded a RectangleAsset based on this tutorial, but I am not sure how to move information about texture UVs to the RactangleAssetInstance (my rectangles can have different textures).
Do I have to create new VAO for it or can I just pass the UVs by some other means? Or add second VBO for UVs? And most imporantly: what would be best practice solving this?
struct RectangleAsset {
GLuint VBO;
GLuint VAO;
};
struct RectangleAssetInstance { //this is actually more complex class in my code
RectangleAsset rect; //but tried to extract the most imporatant code
glm::mat4 transform;
Texture * texture;
void UpdateTransform(int,int,int,int);
private:
int x,y,width,height;
};
and function loading the RectangleAsset:
void GUIRenderer::init()
{
image = new Program ("vs.glsl", "fs.glsl");
glGenVertexArrays(1, &rect.VAO);
glBindVertexArray(rect.VAO);
glGenBuffers(1, &rect.VBO);
glBindBuffer(GL_ARRAY_BUFFER, rect.VAO);
GLfloat vertexData[] = {
// X Y Z U V
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(image->attrib("vert"));
glVertexAttribPointer(image->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), NULL);
glEnableVertexAttribArray(image->attrib("vertTexCoord"));
glVertexAttribPointer(image->attrib("vertTexCoord"), 2, GL_FLOAT, GL_TRUE, 5*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
}
NOTE: I plan to use RectangleAssetInstances only at one place, in one std::vector for GUI rendering(non-static gui). Might it be good idea to merge all rectangles in one VBO and VAO (and re-create it whenever UIElement is added/removed)?
Any advices learning best practices with OpenGL are welcomed.
VAOs store both the format of input data and the location that that input data is sourced from. This is actually two separate concepts. If you want to change where the UVs come from you must call glVertexAttribPointer again. This call would look something like glVertexAttribPointer(uvLoc, GL_FLOAT, false, sizeof(float) * 5, (const GLvoid*)(sizeof(float) * 3)) Note that this will NOT change the VBO that your position information is coming from.
Now you mentioned that you wanted to do this because your rectangle instances may have different textures. You need not change the UVs in order to make this happen. In general positions, UVs, and normals are all part of the mesh and you only need one copy of them. To change the texture just call glActiveTexture(GL_TEXTURE0 + i) followed by glBindTexture(GL_TEXTURE_2D, tex) and then set the sampler uniform in your shader to use the correct image unit with glUniform1i(samplerLoc, i)
There is also the ARB_vertex_attrib_binding extension, which became core in OpenGL 4.3. This allows you to separate attribute layout from data location. The article at the OpenGL wiki provides information on how to do this, but again it is probably better to author all the textures for a given mesh using the same UVs.
In regards to your question about merging everything into one VAO and VBO: If you only want rectangles than this is not necessary, since you can get any kind of rectangle you would like using an affine transform with non-uniform scaling component. Thus you only need one VAO and one VBO in total, and there is no need to merge anything.
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.