Home » Community » Forums » OpenGL » Terrain rendering and VBO
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic


 Last Thread Next Thread 
 Terrain rendering and VBO
Post New Topic  Post Reply 
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!

 User Rating: 1008   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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


 User Rating: 1069   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by Saya
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.
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:
Original post by Saya
So what i was wondering, is it better to use Indexed Vertex arrays or simple Vertex Arrays?
Obviously indexed. I don't see the connection here. Why do you think this may be a problem?
Quote:
Original post by Saya
Also is it good to render my terrain with a single vertex array? (its an rts like terrain).
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:
Original post by Saya
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'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.

 User Rating: 1149   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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]

 User Rating: 1008   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link


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?

 User Rating: 1008   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: