[SOLVED] VBO Not Rendering

Started by monsieurdozier, June 16, 2012, 01:32:36

Previous topic - Next topic

monsieurdozier

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:

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);
	}
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.

MattCa

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.

monsieurdozier

I tried interleaving the vertex array, but to no avail.

Here's my new interleaved code:
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:
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.

monsieurdozier

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!