PDA

View Full Version : VBO with multi texture



shin88
02-24-2011, 12:01 AM
Hi all,
I just wan to know is there any problem in my programming on OS 10.5 Mac

I have loaded a 3ds file with 3dsloader
I put all the vertices, texcoord, and indices in 3 separate array which is big enough.

As I know, the 3ds file have 33 object.
Each object, having it vertices, texcoord, & indices list.

After all of that, I bind the 3 separate array into VBO.
and now i need to draw the VBO with 33 different texture. (means 1 texture per object)

How should I do it..?
The immediate mode is working.. but slow
now i using glArrayElement, but i think thats not VBO.



for(int o_index = 0; o_index<33; o_index++){
glBindTexture(GL_TEXTURE_2D, object.objects_type[o_index].id_texture);
glBegin(GL_TRIANGLES);
for(GLint i = p_count[o_index]*3; i< p_count[o_index+1]*3; i++)
//if(indices_VBO[i] >= v_count[0] &amp;&amp; indices_VBO[i] <= v_count[33])
glArrayElement(indices_VBO[i]);
glEnd();
}

.. If you look closely, the code is actually "glDrawRangeElements"

_arts_
02-24-2011, 04:08 AM
Don't use glArrayElement with VBO, use glDrawElement, glDrawRangeElement or glDrawArrays.

For how to do separate drawing regarding the texture change, use indices, or know where in the array there are texture changes.

shin88
02-24-2011, 05:50 AM
Ya, I know bout it.. but when I look into the documentation..

GLvoid glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid* indices)
{
glBegin(mode);
for(GLint i = 0; i < count; ++i)
glArrayElement(indices[i]);
glEnd();
}


GLvoid glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type, GLvoid* indices)
{
glBegin(mode);
for(GLint i = 0; i < count; ++i)
if(indices[i] >= start &amp;&amp; indices[i] <= end)
glArrayElement(indices[i]);
glEnd();
}


GLvoid glMultiDrawElements(GLenum mode, GLsizei* count, GLenum type,
GLvoid** indices, GLsizei primcount)
{
for(GLint i = 0; i < primcount; ++i)
{
if(count[i]) > 0)
glDrawElements(mode, count[i], type, indices[i]);
}
}


If i use "glDrawElements", "glDrawRangeElements", "glMultiDrawElements",
In the "for loop", it always start with "zero" (GLint i = 0)
which mean the indices always start from the first.

If this is the case, when i bind texture, It will look terrible wrong..

Any suggestion to solve my problem? If not using VBO, what can be use.?

I have 33 Objects:
Each objects:
> Vertices list
> Texcoord list
> Polygon/Indices list

For now I loop the whole 33 objects.. store all the data side by side (without stride) in vertex array, texcoord array, ... As for the Indices, i will add offset to it each loop..so that it point to the correct vertices.

_arts_
02-24-2011, 05:58 AM
This documentation should come with an "old OpenGL reference book", I have it with the OpenGL 1.2 reference book. This is just an example (and bad !)

For GL 3.x and above, immediate mode (ie glBegin...) doesn't exist anymore.

For your example, look at the if statements. It doesn't start from 0.



GLvoid glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type, GLvoid* indices)


It doesn't start at 0.

So really, these functions (mainly glDrawRangeElements and glDrawArrays) will solve your problem.

If you really don't want to do so, then split your meshes regarding the textures.

shin88
02-24-2011, 06:31 AM
Thanks for the guide..
I think i'm a little rush at this.. that's y comment out the start n end..

But, anyway I will try it again tomorrow. Hopefully it works.
I'm working on old iMac Core Duo, ATi X1600 , opengl 2.0....Cocoa Objective-C... I know is old..

Here's the idea:


for(int i = 0; i<33; i++){
glBindTexture(GL_TEXTURE_2D, object.objects_type[i].id_texture);
glDrawRangeElements(GL_TRIANGLES, start[i], end[i], count[i], GL_UNSIGNED_SHORT, 0)
}


start[33] (eg: 0, 33, 99, 1290, 3560, ...)
end[33] (eg: 33, 99, 1290, 3560, 4500, ...)
count[33] (eg: 33, 66, 1191, 2270, 940, ...)

Do you think this idea is correct??
What if after all this the FPS is still low??
The texture resolution is 1024x1024 TIF format..
Is actually a map, with detail picture, like u see in google map, so i can't really lower the resolution.

mhagain
02-24-2011, 07:59 AM
I think the intent behind that documentation is to demonstrate how each of the glDraw* functions works when compared to immediate mode, rather than saying "this is what they do behind the scenes".

Wait until after you make the switch to glDrawRangeElements before you worry about whether or not it's still slow. At that point you'll know that your drawing code is basically correct, so you'll have narrowed down the list of places where performance problems could be coming from.

shin88
02-24-2011, 07:49 PM
Hey guys,

apparently, i figure somethg out.
I just try out the idea.. and is not working..

But the below i'm gonna show u guys is working for me.


for(GLint o_index=0; o_index< 33; o_index++){
glBindTexture(GL_TEXTURE_2D, object.objects_type[o_index].id_texture);
glDrawRangeElements(GL_TRIANGLES,
0,
1,
object.objects_type[o_index].polygons_qty*3,
GL_UNSIGNED_SHORT,
BUFFER_OFFSET(p_count[o_index]*3*2));
}


I got to use the BUFFER_OFFSET to offset my "start" reading indices.. the BUFFER_OFFSET is in byte, but my incides is UShort, so I just have to multiply by 2.

The 2nd & 3rd parameter which is "GLuint start & GLuint end" is not working for me.. so i just put zero & one there..

The map can be drawn with multi-texture now..

Here's the comparison..
By using Immediate mode : 5 FPS
By using glDrawRangeElements : 8 FPS

Any idea how to make it render faster?
TQ

--------
Ok.. i run some experiment by myself
As i mention, i got 33 objects to render..
o_index -> limit
render from 0 -> 23 :: I get 60 FPS & above
render from 0 -> 24 :: I get 10 FPS & below
render from 1 -> 25 :: I get 60 FPS & above
render from 2 -> 26 :: I get 60 FPS & above
render from 3 -> 27 :: I get 60 FPS & above
.
.
.
render from 12 -> 33 :: I get 10 FPS & below
render from 13 -> 33 :: I get 60 FPS & above

shin88
02-25-2011, 02:19 AM
Hi again,

I think the old iMac jz stress out with loading too much texture in it.. Is just X1600..

Just now i try it on the latest iMac 27" which come with HD5750 i7 Core, It just work perfectly nice and fast..