LWJGL Forum

Programming => OpenGL => Topic started by: monsieurdozier on June 16, 2012, 01:32:36

Title: [SOLVED] VBO Not Rendering
Post by: monsieurdozier on June 16, 2012, 01:32:36
I'm working on switching my game over from Immediate Mode to using Vertex Buffer Objects.  But for some reason I can't get even the most basic of VBO's to render.

Here's the Code:

Code: [Select]
public static void generateVertexData(){

colorVertexHandle = glGenBuffers();
vboVertexHandle = glGenBuffers();

float[] vertexArray = new float[]{0, 1f, 0, 1f, 1f, 0f, 1f, 0f, 0f, 0f, 0f, 0f};
float[] colorArray = new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f};

amountOfVertices = 4;

        FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertexArray.length);
        vertexData.put(vertexArray);
        vertexData.flip();
                
        FloatBuffer colorData = BufferUtils.createFloatBuffer(colorArray.length);
        colorData.put(colorArray);
        colorData.flip();
                
        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        
        glBindBuffer(GL_ARRAY_BUFFER, colorVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, colorData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Code: [Select]
public static void drawLevelVBO(){
int vertexSize = 3;
int colorSize = 3;

glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);
        
        glBindBuffer(GL_ARRAY_BUFFER, colorVertexHandle);
        glColorPointer(colorSize, GL_FLOAT, 0, 0L);
        
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glDrawArrays(GL_QUADS, 0, amountOfVertices);
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
}

generateVertexData() is called during setup, and drawLevelVBO() is called during the main game loop.  glClear is called from the Main Game Loop.  Both colorVertexHandle and vboVertexHandle are static fields.  When I run the game, I should see a white square, instead I see nothing.  I'm still rendering the player quad with Immediate Mode, and using gluLookAt for the camera, all with gluPerspective, but I don't think any of those affect VBOs.

I've been staring at the code for a couple hours now and nothing.  Did I miss something?  Thanks.
Title: Re: VBO Not Rendering
Post by: MattCa on June 16, 2012, 05:40:38
I haven't got much time, but what you're doing is binding the vertex array to GL_ARRAY_BUFFER, but then binding the color array to the same - which overrides the vertex array, and thus doesn't draw.

What I suggest is appending the colorArray data to the end of the vertexData buffer instead of creating a seperate VBO and buffer for the colors. Then, when you come to use glColorPointer, set the index value to the position of the first color value (13, I think) in the combined-buffer.

Even better, you could do what is called 'interleaving', where you store the data in a pattern like so: <vertex (3 floats)><color (4 floats)><vertex(3 floats)>etc, etc.

Sorry about not providing any code, I'm in a bit of a rush!
Matt.
Title: Re: VBO Not Rendering
Post by: monsieurdozier on June 19, 2012, 23:35:52
I tried interleaving the vertex array, but to no avail.

Here's my new interleaved code:
Code: [Select]
public static void generateVertexData(){

levelVertexHandle = glGenBuffers();

float[] vertexArray = new float[]{
//Point One
//Vertex
0f, 1f, 0f,
//Color
1f, 1f, 1f,
//Point Two
//Vertex
1f, 1f, 0f,
//Color
1f, 1f, 1f,
//Point Three
//Vertex
1f, 0f, 0f,
//Color
1f, 1f, 1f,
//Point Four
//Vertex
0f, 0f, 0f,
//Color
1f, 1f, 1f};

amountOfVertices = 4;

        FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertexArray.length);
        vertexData.put(vertexArray);
        vertexData.flip();
               
        glBindBuffer(GL_ARRAY_BUFFER, levelVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

}


//TODO
public static void drawLevelVBO(){
int vertexSize = 3;
int colorSize = 3;

int stride = (vertexSize + colorSize) * 4;

glBindBuffer(GL_ARRAY_BUFFER, levelVertexHandle);
        glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
        glColorPointer(colorSize,GL_FLOAT,stride, (3 * 4));
       
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glDrawArrays(GL_QUADS, 0, amountOfVertices);
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
}

And here's my "practice code" that works like a champ:
Code: [Select]
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

public class VertexBufferObjectDemo {

    public VertexBufferObjectDemo() {
        try {
            Display.setDisplayMode(new DisplayMode(640, 480));
            Display.setTitle("Vertex Buffer Object Demo");
            Display.create();
        } catch (LWJGLException e) {
            e.printStackTrace();
        }

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(1, 1, 1, 1, 1, -1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
       
        int amountOfVertices = 4;
        int vertexSize = 3;
        int colorSize = 3;
       
        int stride = (vertexSize + colorSize) * 4;
       
        float[] vertexArray = new float[]{-0.5f, -0.5f, 0, 1,0,0, 0.5f, -0.5f, 0, 0,1,0, 0.5f, 0.5f, 0, 0,0,1, -0.5f, 0.5f, 0, 1,1,1};
       
        FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertexArray.length);
        vertexData.put(vertexArray);
        vertexData.flip();
       
        int vboVertexHandle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
       
        int offset = 12;
       
        while (!Display.isCloseRequested()) {
            glClear(GL_COLOR_BUFFER_BIT);

            glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
            glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
           
            glColorPointer(colorSize,GL_FLOAT,stride,offset);
           
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_COLOR_ARRAY);
            glDrawArrays(GL_QUADS, 0, amountOfVertices);
            glDisableClientState(GL_COLOR_ARRAY);
            glDisableClientState(GL_VERTEX_ARRAY);

            Display.update();
            Display.sync(60);
        }

        glDeleteBuffers(vboVertexHandle);

        Display.destroy();
        System.exit(0);
    }

    public static void main(String[] args) {
        new VertexBufferObjectDemo();
    }
}

I don't understand why the practice code works perfectly fine (Both interleaved and not), but the actual code doesn't.
Title: Re: VBO Not Rendering
Post by: monsieurdozier on June 20, 2012, 21:44:21
Well, I feel silly.  After tweaking my OpenGL Initialization Code, I discovered I had GL_BLEND Enabled.  It was basically blending all of the quads I created into the background.  So, problem solved.  Thanks for all of your help!