PDA

View Full Version : VBO Trouble



PropPutty
08-14-2010, 07:59 AM
I've been trying to implement a 20 * 20 grid of quads (using two triangle strips) using VBO's. But it seems like when I go to draw it, it's only drawing up to the 64th spot and then repeating. So the grid is incomplete.

A little example of what I mean:
|7|8|9|
|4|5|6|
|1|2|3|

Say you want draw this 3 * 3 grid, it draws squares 1 - 4 correctly, but then instead of drawing square number 5 in the middle it draws it back at square 1 and just repeats.
|4, 8|
|1, 5, 9|2, 6|3, 7|

Hope that makes you a little bit clearer on what's happening, anyways here's my code.

#define NUMBER_OF_TILES 400
#define BLUE 0.0, 0.0, 1.0
#define GREEN 0.0, 1.0, 0.0
#define RED 1.0, 0.0, 0.0
#define WHITE 1.0, 1.0, 1.0

GLuint MapVBO, MapIBO;

//Drawing snippet start
glBindBuffer(GL_ARRAY_BUFFER, MapVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, MapIBO);

glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

//To draw my grid properly I'm actually using DrawElements in a loop, drawing only 1 square each time using GL_TRIANGLE_STRIPS instead.
glDrawElements(GL_TRIANGLES, NUMBER_OF_TILES * 4, GL_UNSIGNED_BYTE, (void*)((char*)NULL));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
//Drawing snippet end


//VBO creation function
void CreateVBO()
{
glGenBuffers(1, &MapVBO);
glBindBuffer(GL_ARRAY_BUFFER, MapVBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20 * NUMBER_OF_TILES, 0, GL_STATIC_DRAW);

void *VBOBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

int Loop, OldY;
float Tile[20] = {
RED, 40.0, 40.0,
GREEN, 56.0, 40.0,
BLUE, 40.0, 56.0,
WHITE, 56.0, 56.0
};

for (Loop = 0, OldY = 0; Loop < NUMBER_OF_TILES; Loop++)
{
memcpy(VBOBuffer + sizeof(float) * 20 * Loop, Tile, sizeof(float) * 20);

if (OldY < ((Loop + 1) / 20))
{
Tile[4] += 16.0;
Tile[9] += 16.0;
Tile[14] += 16.0;
Tile[19] += 16.0;

Tile[3] = 40.0;
Tile[8] = 56.0;
Tile[13] = 40.0;
Tile[18] = 56.0;

OldY++;
}

else
{
Tile[3] += 16.0;
Tile[8] += 16.0;
Tile[13] += 16.0;
Tile[18] += 16.0;
}
}

glUnmapBuffer(GL_ARRAY_BUFFER);

glColorPointer(3, GL_FLOAT, sizeof(float) * 5, (void*)((char*)NULL));
glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, (void*)((char*)NULL + sizeof(float) * 3));

glGenBuffers(1, &amp;MapIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, MapIBO);

unsigned char *Indices = (unsigned char*)malloc(sizeof(unsigned char) * (NUMBER_OF_TILES * 4));
for (Loop = 0; Loop < (NUMBER_OF_TILES * 4); Loop++)
{
Indices[Loop] = Loop;
}

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned char) * (NUMBER_OF_TILES * 4), Indices, GL_STATIC_DRAW);
free(Indices);
}




edit: Just thought I should say, I've checked to see if there were any errors using glGetError() and there were none.

I tried writing to the buffer with glBufferData() instead of mapping the buffer and using memcpy() to copy over the vertex and colour. And it was the same result.

I tried changing the last argument in glDrawElements() so it is pointing to the last four indices (so it draws the last square). And the last square is still drawn where it shouldn't be.

mhagain
08-14-2010, 09:57 AM
GL_UNSIGNED_BYTE in your glDrawElements I reckon. Change it to GL_UNSIGNED_SHORT instead and it should work.

You shouldn't be using GL_UNSIGNED_BYTE anyway as most hardware only supports 16-bit or 32-bit indexes, with 16-bit having the more widespread support.

PropPutty
08-14-2010, 10:43 AM
That worked, thanks a lot :).