|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| Terrain rendering and VBO |
|
![]() Saya Member since: 1/2/2008 From: Marly-le-roi, France |
||||
|
|
||||
| I am wondering, i am currently rendering a terrain. At first i did brute force rendering, then display lists, then vertex arrays, then now indexed vertex arrays :p! ( as i learn the new concepts i apply them ) and now VBOs with an indexed vertex array. I read that VBOs are better than displaylists so i used them even though i dont have any notable FPS gain they have the advantage of being flexible. So what i was wondering, is it better to use Indexed Vertex arrays or simple Vertex Arrays? Also is it good to render my terrain with a single vertex array? (its an rts like terrain). Also how would i apply several textures on my terrain using the texture array? ( each 'tile' of the terrain has a texture that can be different like sand grass etc... ). I didnt find any good tutorials on the subject since i probably dont even know the words to use for the search. Thanks in advance! |
||||
|
||||
![]() Arex Member since: 7/1/2004 From: Helsinki, Finland |
||||
|
|
||||
| If you can do indexing for vertices then do it. :) Using one vertex array for the whole terrain probably isn't the best solution if you have loads of data in it. I suggest you split it in 'tiles' of some size. Sincerely, Arto Ruotsalainen Dawn Bringer 3D - Tips & Tricks |
||||
|
||||
![]() Krohm Member since: 8/27/2002 From: Italy |
|||||
|
|
|||||
Quote:Uhm... sort of. Static VBOs are just as fast as DL (there may be sort of 2% difference but that's nothing). Dynamic VBOs aren't directly comparable to DLs. Saying that they're faster is a gross simplification... but the result is that they're way better for dynamic data. Dynamic data means the VBO data changes, not that the mesh itself changes. Quote:Obviously indexed. I don't see the connection here. Why do you think this may be a problem? Quote:Yes, less VBOs/streams are better. Just make sure they don't grow too big. I am pretty happy at 4MB (my dataset is generally about tens of megs of geometry data) but I plan to move to higher numbers in the near future. Do not try the impossible. Merging similar stuff in a single VBO is easy. Mixing two "very far" resources in the same VBO may be more difficult. Take it easy for now. Using a VBO per tile (or a VBO per draw call in general) is likely to be far from optimal. Quote:I'm unsure this makes sense. Supposing you want to tile them, then you'll have to place each tile in the right spot. Then, since you're already batching another call it just takes a simple Bind. If you somehow manage to draw multiple tiles then using a support texcoord may help, but it's unclear if your "texture array" is the new fourth-gen shading pipe functionality. |
|||||
|
|||||
![]() Saya Member since: 1/2/2008 From: Marly-le-roi, France |
||||
|
|
||||
| Well do i have to build a different vertex array for each texture type? I dont understand how to do it since my texture array only defines the texture position and not the texture itself. Im having problems with using VBOs instead of simple vertex arrays. My indexed array code works but my VBO only displays like one fourth of the map and some rubbish. Heres my code for the Vertex array and then the VBO (i use exactly the same arrays for both): using an indexed vertex array: void Map::renderTerrain(void) { /**vertex arrays*/ glEnable(GL_TEXTURE_2D); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white_color); glBindTexture(GL_TEXTURE_2D, texture); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertexarray); glNormalPointer(GL_FLOAT, 0, vnormalarray); glTexCoordPointer(2, GL_FLOAT, 0, texarray); glDrawElements(GL_TRIANGLES, 6*(size_x-1)*(size_y-1), GL_UNSIGNED_INT, indexarray); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } using VBO with an indexed vertex array: void Map::constructVBO(void) { // Create the buffer objects glGenBuffersARB(4, bufferObjects); // Copy data to video memory // Vertex data glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[VERTEX_DATA]); glBufferDataARB(GL_ARRAY_BUFFER_ARB, 3*4*(size_x-1)*(size_y-1)*sizeof(GLfloat), vertexarray, GL_STATIC_DRAW_ARB); // Normal data glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[NORMAL_DATA]); glBufferDataARB(GL_ARRAY_BUFFER_ARB, 3*4*(size_x-1)*(size_y-1)*sizeof(GLfloat), vnormalarray, GL_STATIC_DRAW_ARB); // Texture coordinates glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[TEXTURE_DATA]); glBufferDataARB(GL_ARRAY_BUFFER_ARB, 2*4*(size_x-1)*(size_y-1)*sizeof(GLfloat), texarray, GL_STATIC_DRAW_ARB); // Indexes glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, 6*(size_x-1)*(size_y-1), indexarray, GL_STATIC_DRAW_ARB); } void Map::renderVBO(void) { glEnable(GL_TEXTURE_2D); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white_color); glBindTexture(GL_TEXTURE_2D, texture_grass); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Here’s where the data is now glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[VERTEX_DATA]); glVertexPointer(3, GL_FLOAT,0, 0); // Normal data glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[NORMAL_DATA]); glNormalPointer(GL_FLOAT, 0, 0); // Texture coordinates glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferObjects[TEXTURE_DATA]); glTexCoordPointer(2, GL_FLOAT, 0, 0); // Indexes glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]); glDrawElements(GL_TRIANGLES, 6*(size_x-1)*(size_y-1), GL_UNSIGNED_INT, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } [Edited by - Saya on January 10, 2008 10:02:41 AM] |
||||
|
||||
![]() Saya Member since: 1/2/2008 From: Marly-le-roi, France |
||||
|
|
||||
Nevermind, by looking at the source posted here i realised i had forgotten to multiply the size of the index array by the size of GLfloat... However im having a slight compilation problem with VBOs i get these warnings (i use gcc on ubuntu linux): g++ -Wall -g -lSDL -lSDL_image -lSDL_ttf -lGL -lGLU camera.cpp entity.cpp game.cpp main.cpp map.cpp sdlglutils.cpp vector3d.cpp -o test_opengl /usr/bin/ld: Warning: type of symbol `glGenBuffersARB' changed from 2 to 1 in /tmp/cc5HsBFb.o /usr/bin/ld: Warning: type of symbol `glBindBufferARB' changed from 2 to 1 in /tmp/cc5HsBFb.o /usr/bin/ld: Warning: type of symbol `glBufferDataARB' changed from 2 to 1 in /tmp/cc5HsBFb.o /usr/bin/ld: Warning: type of symbol `glDeleteBuffersARB' changed from 2 to 1 in /tmp/cc5HsBFb.o Here is how i implement the extensions: typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage); // VBO Extension Function Pointers PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure std::cout<<"VBO supported..."<<std::endl; glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB"); glBindBufferARB = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB"); glBufferDataARB = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB"); glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB"); Any ideas on what the problem could be? |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|