Sign in to follow this  
CRACK123

Calculating normal arrays for rendering

Recommended Posts

Hi, I am loading a 3DS Model and rendered it in immediate mode. However in this case I didn't calculate the normals but let lib3ds do it for me. After rendering this is how it was lit. This is how the rendering of triangle is being done in this case
for(int j = 0 ; j < size; j++)
			{
				std::string name(g->faceList[j].material.m_materialName);
				MaterialInfo mat = CMaterialManager::GetInstance().GetMaterial(name);
				
				glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&mat.m_ambient);
				glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&mat.m_diffuse);
				glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&mat.m_specular);
				glMaterialfv(GL_FRONT, GL_SHININESS, (float *)&mat.m_shininess);

				std::string texName(g->faceList[j].material.m_textureMapName);
				CTextureManager::GetInstance().Bind(texName);
				glEnable(GL_TEXTURE_2D);
						
				glBegin(GL_TRIANGLES);
				for(int k = 0; k < 3; k++)
				{
					
						glTexCoord2fv( (float *)&m_TexCoords[g->faceList[j].face[k]]);
						glNormal3fv((float *)&g->normals[3 * j + k]);
						glVertex3fv((float *)&m_Vertices[g->faceList[j].face[k]]);							
				}
				glEnd();
			}	





Now I am trying to use Vertex arrays to do the same. But instead I am calculating the normals myself. But now the render comes out like this This is how I am calcuating the normals and doing the rendering
// Recalculate normals
void CModel::RecalculateNormals()
{
	m_Model.isNormalRecalculated = true;
	
	for(int i = 0; i < m_Model.m_numGroups; i++)
	{
		
		Groups *g = &m_Model.pGroups[i];
		g->m_NormalVBO.reserve(g->m_Faces.size());
		
		for(int j = 0; j < g->m_Faces.size(); j += 2)
		{
			vector3 v1 = m_Vertices[g->m_Faces[j + 0]];
			vector3 v2 = m_Vertices[g->m_Faces[j + 1]];
			vector3 v3 = m_Vertices[g->m_Faces[ j + 2]];
			
			vector3 cross1 = v3 - v1;
			vector3 cross2 = v2 - v1;
			
			vector3 normal = CrossProduct(cross1, cross2);
			normal.normalize();
			
			g->m_NormalVBO[g->m_Faces[j + 0]] = normal;
			g->m_NormalVBO[g->m_Faces[j + 1]] = normal;
			g->m_NormalVBO[g->m_Faces[j + 2]] = normal;
			
		}	
	}
}


// render using vertex arrays
void CModel::Render()
{
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, sizeof(vector3), (float *)&m_Vertices[0]);
	
	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, sizeof(vector3), (float *)&m_Normals);
	
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glTexCoordPointer(2, GL_FLOAT, sizeof(vector2), (float *)&m_TexCoords[0]);
	
	for(int i = 0; i < m_Model.m_numGroups; i++)
	{
		Groups *g = &m_Model.pGroups[i];
		std::string name = g->m_Materials.m_materialName;
		MaterialInfo mat = CMaterialManager::GetInstance().GetMaterial(name);
		
		glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&mat.m_ambient);
		glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&mat.m_diffuse);
		glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&mat.m_specular);
		glMaterialfv(GL_FRONT, GL_SHININESS, (float *)&mat.m_shininess);

		std::string texture = g->m_Materials.m_textureMapName;
		CTextureManager::GetInstance().Bind(texture);
		
		if(m_Model.isNormalRecalculated)
		{
			glNormalPointer(GL_FLOAT, sizeof(vector3), (float *)&g->m_NormalVBO[0]);
		}
		
		glDrawElements(GL_TRIANGLES, g->m_Faces.size(), GL_UNSIGNED_INT, &g->m_Faces[0]);
	}
}





Anyone have any idea what I am doing wrong? Can anyone confirm if the normal calculations are correct ? Thanks

Share this post


Link to post
Share on other sites
I'm assuming you are doing this as a learning exercise, because it would be sooo much easier just to ask lib3ds for the normals [wink]

anyways, it looks right, I'm guessing you are being tripped up on the winding order of the verts. try swapping v1 with v2 in the sum to get the two vectors for the cross product.

Share this post


Link to post
Share on other sites
I changed it to v2 in the sum. Now it goes like this


vector3 cross1 = v3 - v2;
vector3 cross2 = v1 - v2;

vector3 normal = CrossProduct(cross1, cross2);
normal.normalize();




I am doing partly as a learning exercise and partly as because I dont know how exactly to map the normal on a per vertex basis. Plus I think having the option to calculate the normals will be good in my opinion even if do manage to get the copying of normals on a index list basis from lib3ds normal array. Whatever maths I can think of and try seems to be going wrong when I try to copy the vertex normals generated from lib3ds.

What I am doing is - batching everything up per material and rendering on a per material basis. Right now I am rendering everything and I am not using any special culling techniques to cull anything except GL_CULL_FACE.

This is a screenshot of wthe render -




Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this