PDA

View Full Version : Texture problem with VBO



Sarah22
04-26-2009, 10:32 AM
This code works properly


glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);

glBegin(GL_TRIANGLES);
for(int i=0; i<header.num_tris*3;i++)
{
glTexCoord2f(stCoor[i*2], stCoor[i*2+1]);
glVertex3f( vertexList[m_indices[i]][0], vertexList[m_indices[i]][1], vertexList[m_indices[i]][2] );
}
glEnd();

Result:

http://img525.imageshack.us/img525/8838/works.jpg

but when I try to use this.


glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertextSize );
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexList), vertexList, GL_STATIC_DRAW);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorSize);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(colorAll)*header.num_tris*3, colorAll, GL_STATIC_DRAW);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, textureSize);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(stCoor)*header.num_tris*3, stCoor, GL_STATIC_DRAW);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, nomalSize);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(normalsAll), normalsAll, GL_STATIC_DRAW);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER_ARB, nomalSize);
glNormalPointer(GL_FLOAT, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER_ARB, colorSize);
glColorPointer(3, GL_FLOAT, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER_ARB, textureSize);
glTexCoordPointer(2, GL_FLOAT, 0, 0);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertextSize);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawElements(GL_TRIANGLES, header.num_tris*3, GL_UNSIGNED_INT, indices );

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState( GL_VERTEX_ARRAY );

Result:

http://img525.imageshack.us/img525/4845/wtfjyo.jpg


Can anyone please check my codes.

Thanks
Sarah22

dletozeun
04-26-2009, 12:00 PM
Right now, I do not see any error in your code. Does that happen using vertex arrays instead? If it does, check the texture coordinates array content and remember that this one is indexed the same way as all arrays are (vertex, color, normal,...) So you may have to duplicate some data.

Sarah22
04-26-2009, 12:13 PM
Yes, only in vertex array. I'm lost on this vbo, really. I don't know what the heck is wrong. I already checked the content of my array by using the immediate mode just like what I posted on my first post but when I try to use use the vbo on my engine. it doesn't work correctly.

Texture array
S T S T S T S T ....

Vertex Array
X Y Z X Y Z X Y Z ...

LogicalError
04-26-2009, 12:33 PM
Although you didn't supply the definition of your data, I have a gut feeling the following pieces of code are the cause of your troubles:
"sizeof(stCoor)*header.num_tris*3" and "sizeof(colorAll)*header.num_tris*3"

after all, you're using "stCoor[i*2]" in your first statement.. which makes me think stCoor is the size of a float?

(my c++ is a bit rusty though, been using C# for the last couple of years now, so I might be wrong)

Sarah22
04-26-2009, 02:00 PM
after all, you're using "stCoor[i*2]" in your first statement.. which makes me think stCoor is the size of a float?

Yes stCoor is a float. That's sizeof(stCoor)*header.num_tris*2, by the way. It's a typo because there are only 2 floats in stCoor which is s and t. But that didn't fix the problem. Maybe opengl wants me to be stuck in immediate mode. lol

dletozeun
04-26-2009, 02:58 PM
And it should be:



glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertextSize );
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexList)**header.num_tris*3, vertexList, GL_STATIC_DRAW);


instead of



glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertextSize );
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexList), vertexList, GL_STATIC_DRAW);


Anyway I think all sizes you give here are wrong since you don't seem to understand the operator sizeof.

I assume the data you give here are arrays of float, so you are applying sizeof on a pointer in most of the code here. A pointer is no more than an integer that stores a memory address, so its is usually 4 bytes (at least, on 32 bits machines).

What we should see someting like sizeof(float), if the data type in your arrays is float.

For example if you have 4 vertices in your vertex array, its size is:

4 * 3 * sizeof( float ) bytes.

-> 4 vertices
-> 3 coordinates per vertex
-> each coordinate is a float.

Nordic
04-26-2009, 07:43 PM
I have this problem too. Works fine in immediate mode, but when I switch to VBO, my texture goes crazy.

Here's some of my code:



glGenBuffersARB (1,&amp;m_Mesh.texcoordId);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, m_Mesh.texcoordId );

glBufferDataARB (GL_ARRAY_BUFFER_ARB,
m_Mesh.numTexCoords * 2 * sizeof(GLfloat),
m_Mesh.TexCoordArray,
GL_STATIC_DRAW_ARB);


And then here's my draw function:



void CMesh::Draw()
{
glEnableClientState ( GL_VERTEX_ARRAY );
glEnableClientState ( GL_INDEX_ARRAY );

glBindBufferARB ( GL_ARRAY_BUFFER_ARB,
m_Mesh.vertexId );

glVertexPointer ( 3, GL_FLOAT, 0, (char *) NULL );
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, m_Mesh.indexId );
glIndexPointer ( GL_INT, 0, (char *) NULL );

if (m_Mesh.numNormals > 0)
{
glEnableClientState ( GL_NORMAL_ARRAY );
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, m_Mesh.normalId );
glNormalPointer ( GL_FLOAT, 0, (char *) NULL );
}

if (m_Mesh.numTexCoords > 0)
{
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, m_Mesh.texcoordId );
glTexCoordPointer ( 2, GL_FLOAT, 0, (char *) NULL );

}

glDrawElements (GL_TRIANGLES,
m_Mesh.numTriangles * 3,
GL_UNSIGNED_INT,
m_Mesh.IndexArray );

glDisableClientState (GL_TEXTURE_COORD_ARRAY );
glDisableClientState (GL_NORMAL_ARRAY );
glDisableClientState (GL_INDEX_ARRAY );
glDisableClientState (GL_VERTEX_ARRAY );
}

Sarah22
04-27-2009, 02:56 AM
Ok, I've fixed the problem on my own.

Nordic
04-27-2009, 03:52 AM
That's great. What was it? Maybe I'm failing on the same thing :p
Thanks

dletozeun
04-27-2009, 04:49 AM
Nordic, don't hijack this thread and open a new one. Maybe your problem is completely different.

Sarah22, what was the problem?? Was it related to the sizeof calls?

Nordic
04-27-2009, 05:13 AM
I'm sorry, I did not try and hijack anything. I'm new to this forum, and all I know is that moderators can get pretty angry when people open upp new threads asking for the same things as another currently open thread.

Sarah22
04-27-2009, 05:17 AM
Nope. The problem is, I didn't sort the texture correctly. I'm using indices(glDrawElements) so it means the first vertex to be drawn is not the vertex[0] but depending on the index, vertex[index](vertex[index], texture[index]). To make it work properly with the index, you must sort the texture's coordinate by the index order so it will work fine.

Nordic
04-27-2009, 05:42 AM
Sarah22... You may have saved my day! I'll try it out. thanks!

dletozeun
04-27-2009, 06:04 AM
I'm sorry, I did not try and hijack anything. I'm new to this forum, and all I know is that moderators can get pretty angry when people open upp new threads asking for the same things as another currently open thread.


Don't be sorry, this is an help forum, there are already tons of similar threads and there will always be. Moderators won't be angry :) .



Nope. The problem is, I didn't sort the texture correctly. I'm using indices(glDrawElements) so it means the first vertex to be drawn is not the vertex[0] but depending on the index, vertex[index](vertex[index], texture[index]). To make it work properly with the index, you must sort the texture's coordinate by the index order so it will work fine.


Ok, thanks for the precision. But I think my suggestion is still valid. it may work for now because the size of a pointer is the same as the size of a float.

Sarah22
05-01-2009, 12:56 AM
And it should be:



glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertextSize );
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexList)**header.num_tris*3, vertexList, GL_STATIC_DRAW);


I try doing those but it just give me an error.


Unhandled exception at 0x697da4d0 in 3D Engine.exe: 0xC0000005: Access violation reading location 0x00d16000.

Here's what I do on my class. I know that sizeof() will just return the size of the datatype in bytes. So multiplying 2048 * 3 * sizeof(float) = 24576.


#define MAX_MD2_VERTS 2048
typedef float vec3_t[3];

vec3_t vertlist[ MAX_MD2_VERTS ];

Did I do something wrong? Thanks for the help, dletozeun. :)