Jump to content

  • Log In with Google      Sign In   
  • Create Account


neo187

Member Since 02 Nov 2010
Offline Last Active Dec 05 2011 09:16 AM
-----

Posts I've Made

In Topic: glDrawArrays efficiency issue for a keyframing function

24 November 2011 - 09:44 AM

Ok, have yet again refactored the function, this time using one interleaved dynamic array GLfloat displayList that I initialize onLoad according to the mesh vertex count. I get a fairly good boost, from15 FPS frames to roughly 25 FPS. So thanks for the hint! This is the new function, including the two passes that I do for recreating Nehe's toon shade effect:


// ... calculate frame position....


int vCount = 0;

	for(int i = 0; i < numTriangles; i++) {

        //Calculate vertices interpolation
		MD2Triangle* triangle = triangles + i;
		for(int j = 0; j < 3; j++) {
			MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
			MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
			Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
			Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
			if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
				normal = Vec3f(0, 0, 1);
			}
			
			displayList[vCount] = normal[0];
			displayList[vCount+1] = normal[1];
			displayList[vCount+2] = normal[2];
			vCount+=3;

			MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
			displayList[vCount] = texCoord->texCoordX;
			displayList[vCount+1] = texCoord->texCoordY;
			vCount+=2;

			displayList[vCount] = pos[0];
			displayList[vCount+1] = pos[1];
			displayList[vCount+2] = pos[2];
			vCount +=3;
		}

	}


	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);

        glNormalPointer(GL_FLOAT, 8*sizeof(float), &displayList[0]);
        glTexCoordPointer(2, GL_FLOAT, 8*sizeof(float), &displayList[3]); 
        glVertexPointer(3, GL_FLOAT, 8*sizeof(float), &displayList[5]);

	// Cel-Shading Code  = Shade
	glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);				// Use The Good Calculations ( NEW )
	glEnable (GL_LINE_SMOOTH);
	glEnable (GL_TEXTURE_1D);									// Enable 1D Texturing ( NEW )
	glBindTexture (GL_TEXTURE_1D, shaderTexture[0]);			// Bind Our Texture ( NEW )
	glColor3f (1.0f, 1.0f, 1.0f);								// Set The Color Of The Model ( NEW )

	//PASS 1
	glDrawArrays(GL_TRIANGLES, 0, numTriangles * 3);


	glDisable (GL_TEXTURE_1D);									// Disable 1D Textures ( NEW )
	

        //Cel-Shading Code = Outline
	glEnable (GL_BLEND);									// Enable Blending ( NEW )
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);		// Set The Blend Mode ( NEW )

	glPolygonMode (GL_BACK, GL_LINE);						// Draw Backfacing Polygons As Wireframes ( NEW )
	glLineWidth (outlineWidth);								// Set The Line Width ( NEW )
	glCullFace (GL_FRONT);									// Don't Draw Any Front-Facing Polygons ( NEW )
	glDepthFunc (GL_LEQUAL);								// Change The Depth Mode ( NEW )
	glColor3fv (&outlineColor[0]);							// Set The Outline Color ( NEW )

	//PASS 2
	glDrawArrays(GL_TRIANGLES, 0, numTriangles * 3);


	glDepthFunc (GL_LESS);									// Reset The Depth-Testing Mode ( NEW )
	glCullFace (GL_BACK);									// Reset The Face To Be Culled ( NEW )
	glPolygonMode (GL_BACK, GL_FILL);						// Reset Back-Facing Polygon Drawing Mode ( NEW )
	glDisable (GL_BLEND);	

	glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);


Does this look as efficient as I can get without using vertex shaders?

Thanks a lot for your directions!

In Topic: glDrawArrays efficiency issue for a keyframing function

24 November 2011 - 07:19 AM

Also consider interleaving your arrays; non-interleaved arrays are slower with hardware T&L.


Thank you very much.... I actually do know the maximum number of vertices upfront since the MD2 format has that for its limit, it's 2048.... So if I instead use a Glfloat vertices[2048] array and insert those data in the array at each pass then that should be faster? How can I interleave the data in one array? I understand that I'd have tio use the same array reference in VertexPointer, TextCoordPointer and NormalPointer, but how do I work out the other two members?

Thanks a lot for your help!

In Topic: glDrawArrays efficiency issue for a keyframing function

23 November 2011 - 05:43 PM

Have updated my original question as I got past the optimization problems I was facing, can anyone have a look at the way I am using glDrawArrays here as check whether I am using it correctly? As it is currently giving me a worse performance than the original function with immediate drawing mode....

Thanks a lot

In Topic: Cel-Shading effect on BMP model textures?

22 November 2011 - 07:52 AM

I have actually (somehow) managed to merge a BMP texture rendering into the effect, the result is actually quite nice and pleasing but it is havling the speed of the program, it's quite very slow even with just 3 models on screen...
Since the result was kind of hacked together, I am thinking that maybe I am performing some extra steps or extra rendering tasks that maybe are not needed, and are slowing down the game?
Something unnecessary that maybe you guys could spot?

Both MD2 and 3DS loader have an InitToon() function called upon creation to load the shader
initToon(){

	int i;														// Looping Variable ( NEW )
	char Line[255];												// Storage For 255 Characters ( NEW )
	float shaderData[32][3];									// Storate For The 96 Shader Values ( NEW )
	FILE *In = fopen ("Shader.txt", "r");						// Open The Shader File ( NEW )

	if (In)														// Check To See If The File Opened ( NEW )
	{
		for (i = 0; i < 32; i++)								// Loop Though The 32 Greyscale Values ( NEW )
		{
			if (feof (In))										// Check For The End Of The File ( NEW )
				break;

			fgets (Line, 255, In);								// Get The Current Line ( NEW )

			shaderData[i][0] = shaderData[i][1] = shaderData[i][2] = float(atof (Line)); // Copy Over The Value ( NEW )
		}

		fclose (In);											// Close The File ( NEW )
	}

	else
		return false;											// It Went Horribly Horribly Wrong ( NEW )

	glGenTextures (1, &shaderTexture[0]);						// Get A Free Texture ID ( NEW )

	glBindTexture (GL_TEXTURE_1D, shaderTexture[0]);			// Bind This Texture. From Now On It Will Be 1D ( NEW )

	// For Crying Out Loud Don't Let OpenGL Use Bi/Trilinear Filtering! ( NEW )
	glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);    
	glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexImage1D (GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGB , GL_FLOAT, shaderData);	// Upload ( NEW )


}

This is the drawing for the animated MD2 model:

void MD2Model::drawToon() {
	float		outlineWidth	= 3.0f;								// Width Of The Lines ( NEW )
	float		outlineColor[3]	= { 0.0f, 0.0f, 0.0f };				// Color Of The Lines ( NEW )
    

// ORIGINAL PART OF THE FUNCTION


	//Figure out the two frames between which we are interpolating
	int frameIndex1 = (int)(time * (endFrame - startFrame + 1)) + startFrame;
	if (frameIndex1 > endFrame) {
		frameIndex1 = startFrame;
	}
    
	int frameIndex2;
	if (frameIndex1 < endFrame) {
		frameIndex2 = frameIndex1 + 1;
	}
	else {
		frameIndex2 = startFrame;
	}
    
	MD2Frame* frame1 = frames + frameIndex1;
	MD2Frame* frame2 = frames + frameIndex2;
    
	//Figure out the fraction that we are between the two frames
	float frac =
		(time - (float)(frameIndex1 - startFrame) /
     	(float)(endFrame - startFrame + 1)) * (endFrame - startFrame + 1);
    

// I ADDED THESE FROM NEHE'S TUTORIAL FOR FIRST PASS (TOON SHADE)

	glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);				// Use The Good Calculations ( NEW )
	glEnable (GL_LINE_SMOOTH);
	// Cel-Shading Code //
	glEnable (GL_TEXTURE_1D);									// Enable 1D Texturing ( NEW )
	glBindTexture (GL_TEXTURE_1D, shaderTexture[0]);			// Bind Our Texture ( NEW )

	glColor3f (1.0f, 1.0f, 1.0f);								// Set The Color Of The Model ( NEW )

// ORIGINAL DRAWING CODE

	//Draw the model as an interpolation between the two frames
	glBegin(GL_TRIANGLES);
	for(int i = 0; i < numTriangles; i++) {
		MD2Triangle* triangle = triangles + i;
		for(int j = 0; j < 3; j++) {
			MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
			MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
			Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
			Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
			if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
				normal = Vec3f(0, 0, 1);
			}
			glNormal3f(normal[0], normal[1], normal[2]);
		    
			MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
			glTexCoord2f(texCoord->texCoordX, texCoord->texCoordY);
			glVertex3f(pos[0], pos[1], pos[2]);
		}
	}
	glEnd();

// ADDED THESE FROM NEHE'S FOR SECOND PASS (OUTLINE)

	glDisable (GL_TEXTURE_1D);									// Disable 1D Textures ( NEW )


	glEnable (GL_BLEND);									// Enable Blending ( NEW )
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);		// Set The Blend Mode ( NEW )

		glPolygonMode (GL_BACK, GL_LINE);						// Draw Backfacing Polygons As Wireframes ( NEW )
		glLineWidth (outlineWidth);								// Set The Line Width ( NEW )

		glCullFace (GL_FRONT);									// Don't Draw Any Front-Facing Polygons ( NEW )

		glDepthFunc (GL_LEQUAL);								// Change The Depth Mode ( NEW )

		glColor3fv (&outlineColor[0]);							// Set The Outline Color ( NEW )


// HERE I AM PARSING THE VERTICES AGAIN (NOT IN THE ORIGINAL FUNCTION) FOR THE OUTLINE AS PER NEHE'S TUT

		glBegin (GL_TRIANGLES);									// Tell OpenGL What We Want To Draw
		for(int i = 0; i < numTriangles; i++) {
		MD2Triangle* triangle = triangles + i;
		for(int j = 0; j < 3; j++) {
			MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
			MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
			Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
			Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
			if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
				normal = Vec3f(0, 0, 1);
			}
			glNormal3f(normal[0], normal[1], normal[2]);
		    
			MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
			glTexCoord2f(texCoord->texCoordX, texCoord->texCoordY);
			glVertex3f(pos[0], pos[1], pos[2]);
		}
	}
		glEnd ();												// Tell OpenGL We've Finished

		glDepthFunc (GL_LESS);									// Reset The Depth-Testing Mode ( NEW )

		glCullFace (GL_BACK);									// Reset The Face To Be Culled ( NEW )

		glPolygonMode (GL_BACK, GL_FILL);						// Reset Back-Facing Polygon Drawing Mode ( NEW )

		glDisable (GL_BLEND);    
}



Whereas this is the drawToon function in the 3DS loader

void Model_3DS::drawToon()
{

	float		outlineWidth	= 3.0f;								// Width Of The Lines ( NEW )
	float		outlineColor[3]	= { 0.0f, 0.0f, 0.0f };				// Color Of The Lines ( NEW )

//ORIGINAL CODE

	if (visible)
	{
	glPushMatrix();

		// Move the model
		glTranslatef(pos.x, pos.y, pos.z);

		// Rotate the model
		glRotatef(rot.x, 1.0f, 0.0f, 0.0f);
		glRotatef(rot.y, 0.0f, 1.0f, 0.0f);
		glRotatef(rot.z, 0.0f, 0.0f, 1.0f);

		glScalef(scale, scale, scale);

		// Loop through the objects
		for (int i = 0; i < numObjects; i++)
		{
			// Enable texture coordiantes, normals, and vertices arrays
			if (Objects[i].textured)
				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			if (lit)
				glEnableClientState(GL_NORMAL_ARRAY);
			glEnableClientState(GL_VERTEX_ARRAY);

			// Point them to the objects arrays
			if (Objects[i].textured)
				glTexCoordPointer(2, GL_FLOAT, 0, Objects[i].TexCoords);
			if (lit)
				glNormalPointer(GL_FLOAT, 0, Objects[i].Normals);
			glVertexPointer(3, GL_FLOAT, 0, Objects[i].Vertexes);

			// Loop through the faces as sorted by material and draw them
			for (int j = 0; j < Objects[i].numMatFaces; j ++)
			{
				// Use the material's texture
				Materials[Objects[i].MatFaces[j].MatIndex].tex.Use();


// AFTER THE TEXTURE IS APPLIED I INSERT THE TOON FUNCTIONS HERE (FIRST PASS)



					glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);				// Use The Good Calculations ( NEW )
					glEnable (GL_LINE_SMOOTH);
					// Cel-Shading Code //
					glEnable (GL_TEXTURE_1D);									// Enable 1D Texturing ( NEW )
					glBindTexture (GL_TEXTURE_1D, shaderTexture[0]);			// Bind Our Texture ( NEW )

						glColor3f (1.0f, 1.0f, 1.0f);								// Set The Color Of The Model ( NEW )



				glPushMatrix();

					// Move the model
					glTranslatef(Objects[i].pos.x, Objects[i].pos.y, Objects[i].pos.z);

					// Rotate the model
							    
					glRotatef(Objects[i].rot.z, 0.0f, 0.0f, 1.0f);
					glRotatef(Objects[i].rot.y, 0.0f, 1.0f, 0.0f);
					glRotatef(Objects[i].rot.x, 1.0f, 0.0f, 0.0f);

					// Draw the faces using an index to the vertex array
					glDrawElements(GL_TRIANGLES, Objects[i].MatFaces[j].numSubFaces, GL_UNSIGNED_SHORT, Objects[i].MatFaces[j].subFaces);

				glPopMatrix();
			}



				glDisable (GL_TEXTURE_1D);									// Disable 1D Textures ( NEW )


// THIS IS AN ADDED SECOND PASS AT THE VERTICES FOR THE OUTLINE


	glEnable (GL_BLEND);									// Enable Blending ( NEW )
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);		// Set The Blend Mode ( NEW )

		glPolygonMode (GL_BACK, GL_LINE);						// Draw Backfacing Polygons As Wireframes ( NEW )
		glLineWidth (outlineWidth);								// Set The Line Width ( NEW )

		glCullFace (GL_FRONT);									// Don't Draw Any Front-Facing Polygons ( NEW )

		glDepthFunc (GL_LEQUAL);								// Change The Depth Mode ( NEW )

		glColor3fv (&outlineColor[0]);							// Set The Outline Color ( NEW )

		for (int j = 0; j < Objects[i].numMatFaces; j ++)
			{
		glPushMatrix();

					// Move the model
					glTranslatef(Objects[i].pos.x, Objects[i].pos.y, Objects[i].pos.z);

					// Rotate the model
									glRotatef(Objects[i].rot.z, 0.0f, 0.0f, 1.0f);
					glRotatef(Objects[i].rot.y, 0.0f, 1.0f, 0.0f);
					glRotatef(Objects[i].rot.x, 1.0f, 0.0f, 0.0f);

					// Draw the faces using an index to the vertex array
					glDrawElements(GL_TRIANGLES, Objects[i].MatFaces[j].numSubFaces, GL_UNSIGNED_SHORT, Objects[i].MatFaces[j].subFaces);

				glPopMatrix();


		}

				glDepthFunc (GL_LESS);									// Reset The Depth-Testing Mode ( NEW )

		glCullFace (GL_BACK);									// Reset The Face To Be Culled ( NEW )

		glPolygonMode (GL_BACK, GL_FILL);						// Reset Back-Facing Polygon Drawing Mode ( NEW )

		glDisable (GL_BLEND);

glPopMatrix();
}

Finally this is the tex.Use() function that loads a BMP texture and somehow gets blended perfectly with the Toon shading
void GLTexture::Use()
{
	glEnable(GL_TEXTURE_2D);								// Enable texture mapping
	glBindTexture(GL_TEXTURE_2D, texture[0]);				// Bind the texture as the current one

}

In Topic: c++ linker problem - unable to link FMOD library to VS2010 project

21 November 2011 - 05:53 PM

Right so I eventually fixed it by removing the Additional Dependency in the Input section of the Linker and instead adding Include and Library directories in in Configuration Properties\VC++ directories.... Most articles I found advise to use the actual full path to the FMOD installation folder, but since I want this project to be portable and self contained, i created a "lib" and "include" folder in my project and put those files in them... (used the directories "\lib" and "\include" in the project properties which I am assuming links to the project folder, have never done this before but am hoping it won't cause dependency issues if I compile this on a different machine)... And on top of this I've added the .dll to the project root folder and now it compiles ok!

PARTNERS