• Create Account

# neo187

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

### 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]);

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 )

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?

```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 )

}

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);
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);
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