fps drop when activating textures (opengl + GLUT)

Hi, i’m new to this forum. The main reason is that i need help solving a problem i have in my app, but i hope i can help other people too with their probs.
Here is mine:
I have coded an app in windows that uses glut for window managing. The app has the option to (de)activate textures at runtime pressing a button. There are only 4 textures im using:

  • grass : a 512x512 bitmap image
  • water: a 256x256 bitmap image
  • shark skin: 2 TGA images at 64x64
    The problem as the title states is that textures deactivated i have 64 fps but whenever i activate textures fps drops to 7-9 fps!!
    A friend of mine told me it might have to be related to doing several texture bindings in the rendering function. But i can’t believe that the use of so low number (4) of separate textures (not in an atlas) isnt supported!!
    I’ll post some code, ive followed the example that comes in the red book:

void IniciarWaterRunning(TTextura *tex)
{
	TexturaBMPCargar("res/texturas/water.bmp", tex);
	glGenTextures( 1 , &tex->tex_Id);  
	glBindTexture(GL_TEXTURE_2D, tex->tex_Id);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, tex->formato, 
					tex->ancho, tex->largo, 0, 
					tex->formato, GL_UNSIGNED_BYTE, 
					tex->img_data);
					
}


void FinalizarWaterRunning(TTextura *tex)
{
	free(tex->img_data);
	glDeleteTextures(1, &tex->tex_Id);
}


void main(int argc, char** argv) {

	
	glutInit(&argc, argv);
	alutInit(&argc, argv);

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("myapp");
	
	inicializar();
	
	IniciarWaterRunning(&tex_agua);	/
	IniciarRocas(&tex_suelo);

	glutReshapeFunc(visualReshape);
	glutDisplayFunc(visualRendering);
	glutFullScreen();
	glutSpecialFunc(teclasEspeciales);
	glutKeyboardFunc(teclado);
	glutMouseFunc(raton);
	glutMotionFunc(motion);

    glutMainLoop();

	//finaliza el contexto de dispositivo de Audio
	alutExit();
	FinalizarWaterRunning(&tex_agua);
	FinalizarRocas(&tex_suelo);
	FinalizarAudioModelo(audio);

	finalizar(); 
}

Following here are several rendering functions that are called in the main rendering function.


void DrawWaterRunning(/*some parameters here*/)
{
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	if(control->texturas == VERDADERO)
	{	
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);

		glBindTexture(GL_TEXTURE_2D, tex_agua.tex_Id);

		.
		glDepthMask(GL_FALSE);
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		glBegin(GL_POLYGON);//plano Zmax
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Xmax
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Zmin
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Xmin
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
		glDepthMask(GL_TRUE);
	}
	glPopMatrix();
}


In the next function i do several bindings for the same model.
DrawModel(/**/)
{
(.....)
        if (activar_texturas == VERDADERO)
	{
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, loco->stexturas.texturas[0].tex_Id);
	}
	glBegin(GL_POLYGON);
		glNormal3f( 0,-1, 1);	glTexCoord2f(0.5, 0);	glVertex3f( 0.5,-1.5, 1.5);	//0
		glNormal3f( 0,-1, 1);	glTexCoord2f( 0, 0);	glVertex3f(-0.5,-1.5, 1.5);	//1
		glNormal3f( 0, 1, 1);	glTexCoord2f( 0,0.5);	glVertex3f(-0.5, 1.5, 1.5);	//3
		glNormal3f( 0, 1, 1);	glTexCoord2f(0.5, 0.5);	glVertex3f( 0.5, 1.5, 1.5);	//2
	glEnd();
	glBegin(GL_POLYGON);
		glNormal3f( 0, 1,-1);	glTexCoord2f( 0,0.5);	glVertex3f(-0.5, 1.5,-1.5);	//5
		glNormal3f( 0, 1,-1);	glTexCoord2f(0.5, 0.5);	glVertex3f( 0.5, 1.5,-1.5);	//4
		glNormal3f( 0,-1,-1);	glTexCoord2f(0.5, 0);	glVertex3f( 0.5,-1.5,-1.5);	//6
		glNormal3f( 0,-1,-1);	glTexCoord2f( 0, 0);	glVertex3f(-0.5,-1.5,-1.5);	//7
	glEnd();

	if (activar_texturas == VERDADERO)
		glBindTexture(GL_TEXTURE_2D, loco->stexturas.texturas[1].tex_Id);

	glBegin(GL_POLYGON);
		glNormal3f( 0, 1, 1);	glTexCoord2f( 0.2F, 0);	glVertex3f( 0.5, 1.5, 1.5);	//2
		glNormal3f( 0, 1, 1);	glTexCoord2f( 0, 0);	glVertex3f(-0.5, 1.5, 1.5);	//3
		glNormal3f( 0, 1,-1);	glTexCoord2f( 0, 1);	glVertex3f(-0.5, 1.5,-1.5);	//5
		glNormal3f( 0, 1,-1);	glTexCoord2f( 0.2F, 1);	glVertex3f( 0.5, 1.5,-1.5);	//4
	glEnd();
(.........)
}

You can see that i do the binding once when i load the texture in the init function and i bind again each time i need to draw the polygon with the texture. I thought this was the right way to do it.
If someone can shed a light over here i d appreciate it very much!! T
Thanks in advance.

hi,

basicly the code looks right.
About binding just one thing:
when possible try to bind a texture one and draw all stuff that uses it - than bind the next one … and so on .
so you only bind every texture only once per frame - or use a texture atlas.

what is happeining on your example is propperbly the difference between
per vertex calculations AND per fragment calculations.

that means:
if you have a cube and one side of it is gray - than its the same gray for every pixel of this cube side - 1 calculation for the complete cupe side. ( unless you do per vertex lights )
so now if you have a texture the cube side has many different colours - so for every pixel an other color may need to be calculated - many calulations take time.

this may be a reason for your fps prob.
but maybe giva us a screenshot and a hardware description - this would help !

cu
uwi

Ive narrowed the problem to be only with the water texture.

I mean, all other three textures dont cause severe fps drop but this one does. Ill provide code to show what im doing, I can’t upload some screenshots because i dont know how to do it :S, can someone tell me?

This is the function that renders the 4 sides of a cube with water. The Texture is a blue BMP image. I use blending for transparency. (Maybe this is the problem?).
Ive deactivated the variable “offset_agua” which is an offset i give the texture to simulate water flow but It has no influence in the fps drop anyway.


void DrawWaterWalls(/*some parameters*/)
{
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	if(control->texturas == VERDADERO)
	{	
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);

		//indicamos la textura que vamos a utilizar
		glBindTexture(GL_TEXTURE_2D, tex_agua.tex_Id);

		//Para utilizar correctamente el blending, deben pintarse siempre antes
		//los objetos más lejos y terminar con los más cercanos al observador.
		//Esto no se cumple aqui porque los agentes están más lejanos y se pintan
		//después que estas cortinas de agua. Por lo que debo deshabilitar
		//el depth buffer para que no elimine lo que hay detrás de las cortinas.
		//Los agentes entonces no se verán afectados por el blending y el suelo sí.
		glDepthMask(GL_FALSE);
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		glBegin(GL_POLYGON);//plano Zmax
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Xmax
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Zmin
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glBegin(GL_POLYGON); //plano Xmin
			glColor4f(1,1,1,0.4f);
			glTexCoord2f( 0,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]);
			glTexCoord2f( 5,	0 + offset_agua);
			glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]);
			glTexCoord2f( 5,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]);
			glTexCoord2f( 0,	2 + offset_agua);
			glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
		glDepthMask(GL_TRUE);
	}
	glPopMatrix();
}

By the way, i have an XPS 17 dell laptop i7 4GB RAM with GPU NVIDIA GT555m 3GB VRAM.

Thanks

UPDATE: ive disabled GL_BLEND so there is no transparency now for the water walls and i still have the same very low fps… so it might not be a transparency problem!!