Jump to content
  • Advertisement
Sign in to follow this  
Bobboau

vertex buffers

This topic is 3814 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok, I am working on a model editor with another person and I'm trying to upgrade our renderer to use VBOs whenever possible. now due to some bad design decisions I'm not going to be able to use index buffers for the moment, so I'm just trying to use a triangle list of interleaved verticese. I think I have most of it in place, I make VBOs of the geometry for each texture on model load, then when drawing I go thropugh each texture, set the VBO for it, go through and set the texture and some associated material effects then draw. now the reason I'm posting, is when I draw I get an access violation, now I'm somewhat inexperienced with OGL so I have likely made some super simple noob mistake like forgetting to enable something. so would someone please do me the favor of looking over this code and tell me if they see any glaring errors?
struct ogl_vertex_buffer
{
	unsigned int n_verts;
	unsigned int vertex_size;
	GLenum format;
	GLuint buffer;
};

//sets up all vertex buffers for this model
void PCS_Model::make_vertex_buffers(){
//	return;
	for(unsigned int i = 0; i<subobjects.size(); i++){
		subobjects.vertex_buffer.resize(textures.size());
		for(unsigned int j = 0; j <textures.size(); j++){
			subobjects.make_vertex_buffer(j);
		}
	}
}

//set's up a specific vertex buffer
void pcs_sobj::make_vertex_buffer(int tid){
	struct OGL_vert{
		float u,v;
		vector3d norm;
		vector3d pos;
	};

	kaz_vector<OGL_vert> tri;
	kaz_vector<OGL_vert> poly;

	for(unsigned int i = 0; i<polygons.size(); i++){
		if(polygons.texture_id != tid)continue;

		OGL_vert vert;

		poly.resize(polygons.verts.size());

		for(unsigned int v = 0; v<polygons.verts.size(); v++){
			vert.pos = polygons.verts[v].point;
			vert.norm = polygons.verts[v].norm;
			vert.u = polygons.verts[v].u;
			vert.v = polygons.verts[v].v;
			poly[v] = vert;
		}
		for(unsigned int t = 1; t<polygons.verts.size()-1; t++){
			tri.push_back(poly[0]);
			tri.push_back(poly[t]);
			tri.push_back(poly[t+1]);
		}
	}
	vertex_buffer[tid].n_verts = tri.size();
	if(tri.size() <1)return;

	glGenBuffers(1,&vertex_buffer[tid].buffer);
	vertex_buffer[tid].format = GL_T2F_N3F_V3F;
	vertex_buffer[tid].vertex_size = sizeof(OGL_vert);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer[tid].buffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, tri.size()*sizeof(OGL_vert), &tri[0], GL_STATIC_DRAW_ARB );

}


void pcs_sobj::destroy_vertex_buffer(){
	for(unsigned int i = 0; i<vertex_buffer.size(); i++){
		glDeleteBuffers(1, &vertex_buffer.buffer);
	}
}

//replaces all the rendering code in our current model rendering code
void pcs_sobj::set_vertex_buffer(int tid){
	ogl_vertex_buffer&buffer = vertex_buffer[tid];

	glInterleavedArrays(buffer.format, buffer.vertex_size, (void*)NULL);
	glTexCoordPointer( 2, GL_FLOAT, buffer.vertex_size, (void*)NULL );
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer.buffer);
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void pcs_sobj::draw_vertex_buffer(int tid){
	ogl_vertex_buffer&buffer = vertex_buffer[tid];
	glDrawArrays(GL_TRIANGLES, 0, buffer.n_verts/3);
}

and the actual drawing code edited for clarity (removed a bunch of material effect code that would do nothing but obfuscate what I was doing)
void PCS_Model::RenderGeometry_vertex_buffers(int sobj, TextureControl &tc){
	// Prep for rendering the geometry
	float light_one[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
	float light_zero[4] = { 0.0f, 0.0f, 0.0f, 1.0f };

	glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, light_one );
	glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, light_zero );

	// render geometry
	int tex_id = -1, glow_tex_id = -1, shine_tex_id = -1;
	glColor4f(1.0, 1.0, 1.0, 1.0); // clear any color

		glEnable(GL_LIGHTING);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GREATER, 0.01f);

	ERROR_CHECK;
	for(unsigned int t = 0; t<textures.size(); t++){
		if(subobjects[sobj].vertex_buffer.size() <1)
			continue;
		if(subobjects[sobj].vertex_buffer[t].n_verts <1)
			continue;

		tex_id = tc.TextureTranslate(t, TC_TEXTURE);

		subobjects[sobj].set_vertex_buffer(t);

		if (tex_id != -1 && !Textureless){
			glActiveTexture(GL_TEXTURE0);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, tex_id);
		//for completness, set the first stage to multiply the base texture with light
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
			glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0f);

				glActiveTexture(GL_TEXTURE1);
				glDisable(GL_TEXTURE_2D);
				glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
				glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
				glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
			
		}else{
			glActiveTexture(GL_TEXTURE0);
			glDisable(GL_TEXTURE_2D);

		}
	ERROR_CHECK;
		subobjects[sobj].draw_vertex_buffer(t);
		


	}
}

Share this post


Link to post
Share on other sites
Advertisement
I have interleaved formated data, I would basically have to redo everything, and I simply don't like haveing all of my geometry data in nineteen different locations, and that probably still wouldn't solve my problem.

Share this post


Link to post
Share on other sites
that seems to cover how it's suposed to work but I can't see anything I'm missing.

ok, hows this, is this the right sequence to draw a VBO full of triangles without an index buffer assuming all the textures and there states have been set properly beforehand?

glBindBufferARB (passing the VBO handle)
glInterleavedArrays (passing the format flag and a NULL pointer for the array cause it's suposed to be useing the VBO)
glDrawArrays (passing gl_triangles obviusly)

assuming the vbo was formed correctly, am I missing a step?

Share this post


Link to post
Share on other sites
Quote:
Original post by Bobboau
I have interleaved formated data, I would basically have to redo everything, and I simply don't like haveing all of my geometry data in nineteen different locations, and that probably still wouldn't solve my problem.


glInterleavedArrays() just uses gl*Pointer() under the hood anyways, it's a short cut function, nothing more; gl*Pointer() functions can point to the same VBO as each other, you just provide offsets.

Anyway, in the code above, unless I'm going blind, I can't see where you bind the VBO to draw from, only the bind for the index buffer.

Also, I'm not sure why you are setting the TexCoordPointer() after using glInterleavedArrays, more so when you don't even give an offset to the data?

Share this post


Link to post
Share on other sites
I figured that out just recently, I was misunderstanding how they worked somewhat.

the TexCoordPointer call was put there because I was looking at someone elses working code and that was the only difference I could find between theres and mine, I have no idea why they did it.

"Anyway, in the code above, unless I'm going blind, I can't see where you bind the VBO to draw from, only the bind for the index buffer."
from set_vertex_buffer()
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer.buffer);
I see now that probably should have been the first line, but same as above I was trying to emulate someone else's code that was somehow working
I have sense removed those two functions cause they are basicly one liners and only serve to complicate and obfuscate.

anyway, I just now got it to work, I'm still not quite sure how I did that, but I did find a big part of my problem was I was makeing the VBOs in a separate thread than I was rendering them in and apparently this was causing problems big enough that they were not getting formed but small enough that it, somehow, didn't crash with an access violation.

Share this post


Link to post
Share on other sites
This explains all the technical details

http://www.opengl.org/wiki/index.php/GL_ARB_vertex_buffer_object

I think you are interested in this part, but read the all the document as well


glNormalPointer(GL_FLOAT, 64, BUFFER_OFFSET(12));
glTexCoordPointer(2, GL_FLOAT, 64, BUFFER_OFFSET(24));
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, 64, BUFFER_OFFSET(32));
glClientActiveTexture(GL_TEXTURE2);
glTexCoordPointer(2, GL_FLOAT, 64, BUFFER_OFFSET(40));

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!