Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Helios_vmg

Member Since 26 Nov 2012
Offline Last Active Apr 20 2014 11:45 AM

Topics I've Started

glSwapBuffers() - odd performance pattern

26 November 2012 - 03:13 PM

Hi.
I'm working on my first big project using OpenGL, and I've encountered a problem that's left me stumped.
I wanted to see how many sprites I could handle without going below 60 fps on my computer. It seems like it would be able to handle 10k sprites just fine, but at regular inters (AFAICT, exactly every second regardless of framerate) my framerate drops by as much as 75%. I've narrowed it down to the call to glSwapBuffers() arbitrarily taking longer for no apparent reason. Even if all I do every frame is call my renderer, I still get lag.

I'll post my main rendering function, in the hope that someone can spot something I'm doing that's obviously wrong:
typedef GLuint texture_t;

struct Vertex{
	real_t x,y;
};

struct Color{
	real_t rgba[4];
};

struct ComplexVertex{
	Vertex screen_coordinate;
	Color color;
	Vertex texture_coordinate;
};

struct Quad{
	ComplexVertex vertices[4];
};

typedef Quad VertexArrayElement;

void Device::draw(){
	this->sprite_count=this->sprite_list.size();
	if (this->sprite_list.size()){
		size_t sprite_count=this->sprite_list.size();
		this->sorting_structure.resize(sprite_count);
		sprite *s_p=&this->sorting_structure[0];
		this->vertex_array.resize(sprite_count);
		OpenGL::VertexArrayElement *va_p=&this->vertex_array[0];
		boost::unordered_set<texture_t> textures_in_use;
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnableClientState(GL_COLOR_ARRAY);
	  
		// ... populate textures_in_use and sorting_structure ...
	  
		if (textures_in_use.size()>1){
			std::sort(this->sorting_structure.begin(),this->sorting_structure.end(),spritecmp());
			texture_t last_texture=0;
			size_t interval_count=0;
			this->intervals.resize(textures_in_use.size());
			this->copy_array.resize(this->vertex_array.size());
		  
			// ... populate intervals ...

			glVertexPointer(2,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->copy_array[0].vertices[0].screen_coordinate.x));
			glTexCoordPointer(2,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->copy_array[0].vertices[0].texture_coordinate.x));
			glColorPointer(4,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->copy_array[0].vertices[0].color.rgba[0]));
			for (size_t a=0;a<this->intervals.size();a++){
				glBindTexture(GL_TEXTURE_2D,this->intervals[a].texture);
				glDrawArrays(GL_QUADS,this->intervals[a].start*4,this->intervals[a].size*4);
			}
		}else{
			glVertexPointer(2,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->vertex_array[0].vertices[0].screen_coordinate.x));
			glTexCoordPointer(2,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->vertex_array[0].vertices[0].texture_coordinate.x));
			glColorPointer(4,GL_FLOAT,sizeof(OpenGL::ComplexVertex),&(this->vertex_array[0].vertices[0].color.rgba[0]));
			glBindTexture(GL_TEXTURE_2D,this->sorting_structure.front().texture);
			glDrawArrays(GL_QUADS,0,sprite_count*4);
		}
	}
	SDL_GL_SwapBuffers();
}
}

Any ideas?

PARTNERS