Fastest way to display a static model
#1
Posted 05 August 2012 - 04:48 AM
I want to make an obj viewer, but some of them are big (600k triangles) that when I rotate the scene, it takes more than a few seconds to update! Especialy when there are transparencies because I sort them by z.
I don't know if I should use shaders or not, glDrawArrays or not etc. I don't need textures, only vertex, normals and colors.
What I do right now is so slow, I cull the back and draw the front, then cull the front and draw the back, then draw the front transparencies, then the back transparencies (after sorting them!).
Thanks!
#2
Posted 06 August 2012 - 09:18 AM
Is the camera close enough to the object to allow you to do some quad tree or something?
#3
Posted 06 August 2012 - 05:10 PM
IIRC, in OpenGL for static geometry you should create a vertex buffer object and copy the vertices into it once at load time, then re-use the same VBO for rendering each frame. This should be quite fast. If you don't have access to VBOs, at least use glDrawArrays.
#4
Posted 06 August 2012 - 08:17 PM
From what I understand, glDrawArrays can not be used to draw front and back textures all at once, is that right?
Why can't OpenGL provide array pair for all this? I mean, a struct of vertex and front/back colors and textures...
struct gl_Vertex_Data {
vert1,vert2,vert3: vec4;
frontTexUV, backTexUV: vec2;
frontColor, backColor: vec4;
frontTexID, backTexID: uint
}
Bind all our texture to one unit and just use the texture ID. The way I understabd it now is only the active texture is used, and if you want 50 of them, you need to combine them all in a single giant texture! makes no sense, not with the technology we have now!
Then all we have to worry about is rotate, panning and stuff, and, if we pass the data as a pointer instead of uploading it to the card, it can become dynamic instead of static. Why are they making it so hard and complicated? c++ is easier to understand~!
#5
Posted 06 August 2012 - 08:33 PM
#6
Posted 06 August 2012 - 09:56 PM
If I were you I would look at the models and decide which triangles absolutely need to have different textures each side, and in your 3d editor duplicate those polygons.
Also extract all the transparent polygons and put them in a separate object.
Then render all the solid polygons with culling enabled,
Sort your transparent polygons
Draw them with culling off with a painters algorithm
It depends on the number of polygons that need to be duped, and the number of transparent ones, but it should be a lot quicker
#7
Posted 07 August 2012 - 12:57 AM
Reedbeta, how am I suppose to draw both sides on a single call? Say, one poly with a carpet texture on the front and a brick texture on the back. How can I do that with a single call without a shader? Or am I suppose to draw only onr face since only one face can be visible at any one time, and if so, how does this work without a shader?
#8
Posted 07 August 2012 - 01:10 AM
I was just saying that it's possible to write a shader that takes two textures, and based on whether you're looking at the front or back of a particular pixel, samples one texture or the other. That's not necessarily the best way to do this though. I'm just saying it's possible.
Anyway, all this yadda yadda about front/back and different textures etc. may be a red herring. Have you been able to narrow down your performance problem at all? For instance, if you turn off transparencies, or if you only render front faces, does it improve the speed? By how much? If it's still really slow when just drawing the opaque front faces, you have some other problem that may be totally unrelated to the whole front/back business.
#9
Posted 07 August 2012 - 01:51 AM
I use the glBegin(GL_TRIANGLES); glEnd; to set the texture, UV, normal and vertex for each poly. And it's not bad at all, not that slow on 600k poly doing the front and back, without transparencies. But the more transparencies I have, the bigger the list to sort, and again with the front then the back, so it get's very slow.
I wrote a shader that I pass everything to and use glDrawArrays, and the shader uses gl_FrontFacing to know which side, but it only works fine with colors since from what I can tell, you can't pass textures as well.
So I'm back to glBegin(GL_TRIANGLES); glEnd; and I can pass one texture using glBindTexture(GL_TEXTURE_2D...); but how do I pass a 2nd one, and not just that, how do I also pass the 2nd color, and the 2nd UV???
#10
Posted 07 August 2012 - 02:00 AM
For multiple textures, use glActiveTexture to switch which texture unit is the "current" one, then glBindTexture to assign a texture to the current texture unit. Like wise use glClientActiveTexture and glTexcoordPointer to set up multiple sets of UVs. So you'd set up all your vertices, UVs, textures, etc. and then do glDrawArrays to send everything off.
#11
Posted 07 August 2012 - 02:57 AM
ok Reedbeta, you really got me puzled here because I seached and search the net for days and nowhere have I found a way to do what you've explained.
Can you please enlighten more Reedbeta?
Here's what I do to setup the vertex...
glGenBuffers(1, &vboVertex); glBindBuffer(GL_ARRAY_BUFFER, vboVertex); glBufferData(GL_ARRAY_BUFFER, SizeOfTheArrayInByte, PointerTotheArray, GL_STATIC_DRAW); vboAtribVertex = glGetAttribLocation(ProgramID, "inVertex"); // in the vertex shader I have layout(location = 0) in vec4 inVertex; glEnableVertexAttribArray(vboAtribVertex); glBindBuffer(GL_ARRAY_BUFFER, vboVertex); glVertexAttribPointer(vboAtribVertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
Then i do the same for the normals, the colors and UVs, but I have no clue how to add textures to all this?
#12
Posted 07 August 2012 - 04:30 AM
glActiveTexture(0); glBindTexture(GL_TEXTURE_2D, aTexture); glActiveTexture(1); glBindTexture(GL_TEXTURE_2D, anotherTexture); glActiveTexture(2); glBindTexture(GL_TEXTURE_2D, yetAnotherTexture); // etc.
That's all there is to it. The numbers passed to glActiveTexture are the numbers of the texture units. They run from 0 up to however many simultaneous textures your card can support. You can probably get the texture unit numbers from glGetAttribLocation, too, to match up with specific textures declared in the shader.
To provide multiple UVs, just have the vertex shader declare multiple texcoord inputs and use glVertexAttribPointer multiple times, once for each set of UVs.
#13
Posted 07 August 2012 - 04:38 AM
#14
Posted 07 August 2012 - 05:15 AM
#15
Posted 07 August 2012 - 04:22 PM
#17
Posted 07 August 2012 - 06:18 PM
Any other work around that can work on more than 32 sampler?
Thanks guys, I appreciate the help.
#18
Posted 07 August 2012 - 06:28 PM
#19
Posted 07 August 2012 - 06:38 PM
For using different textures on the front and back sides, you would indeed use an if-statement. There's a pixel shader semantic, I forget what it's called, that tells you whether you're on the front or back side (i.e. it has a value of 1 for front-facing pixels and -1 for back-facing pixels, or some such). You could use that in an if-statement to determine which texture to sample.
As I mentioned earlier in the thread, this isn't necessarily the best way to do it. I think it's totally reasonable to draw the front faces in one call, and then switch textures and culling modes and do another call to get the back faces. Then the shader would only look at one texture. All of the stuff I posted was by way of if you want multiple textures in one shader, here's how you'd do it.
#20
Posted 07 August 2012 - 06:41 PM
2 user(s) are reading this topic
0 members, 2 guests, 0 anonymous users












