Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎯 Unreal

Vertex lighting issue

Started by Dynx Dec 31, 2008 at 2:03 AM 0 replies 450+ views
Original Post
Dynx
Dynx
Hello everyone, I was wrote a simple glsl diffuse vertex lighting to test my rendering framework and for some reason either the light position transforms to object space or the glMultMatrixf affects the normals in a weird way because, well the entire lighting is always in object space. So if I put the point light at ( 10, 0, 0 ), no matter where the object is, it always receives the light from its +x axis. Again, if the light is at ( 0,0,0 ) the light is treated as if its in the origin of the object therefore the dot product is always negative even though the object may be at say 0,10,0 and should be receiving the light from the bottom. I tested it with a glut sphere to see if my normal calculations were off but same problem. I'd appreciate if anyone can help me out here. Thanks. Vertex Program ============== varying float Diffuse; uniform vec3 lightPosition; void main(void) { gl_Position = ftransform(); vec3 Normal = gl_NormalMatrix * gl_Normal; vec3 vPosition = ( gl_ModelViewMatrix * gl_Vertex ).xyz; vec3 Light = normalize( lightPosition - vPosition ); Diffuse = max( dot(Normal, Light), 0.0 ); } Fragment Program ================ varying float Diffuse; void main(void) { gl_FragColor = Diffuse * vec4(0,0,1,1); } =================

void
Renderer::_drawEntity( Entity* entity )
{
	//Apply transformation
	glPushMatrix();
	glMultMatrixf( reinterpret_cast<float*>( entity->getTransform() ) );

		//Apply shader
		uInt shader = entity->getShader();
		if( shader != NO_SHADER )
		{
			//Don't bother calling OpenGL if we're gonna use the previous shader
			if( shader != activeShader_ )
			{
				glUseProgram( shader );
				activeShader_ = shader;
			}

			Map<String, ParameterInfo> parameters = entity->getShaderParameters();
			Map<String, ParameterInfo>::iterator iter;

			for( iter = parameters.begin(); iter != parameters.end(); iter++ )
			{
				switch( iter->second.type )
				{
				case PT_3FV:
					{
					float values[3] = { iter->second.value[0], 
										iter->second.value[1], 
										iter->second.value[2] };

					glUniform3fv( glGetUniformLocation( shader, 
														iter->first.c_str() ), 
														1, 
														values );
					}
					break;
				case PT_F:
					{
					float values[1] = {iter->second.value[0]};
					glUniform1fv( glGetUniformLocation( shader,
														iter->first.c_str() ),
														1,
														values );
					}
					break;
				}
			}
		}

		else
		{
			if( activeShader_ != 0 )
			{
				activeShader_ = 0;
				glUseProgram(0);
			}
		}

		//Clear and apply texture
		uInt diffuse = entity->getDiffuseMap();
		glBindTexture( GL_TEXTURE_2D, diffuse );
		if(  diffuse != NO_TEXTURE && shader != NO_SHADER )
		{
			int dUniformLocation = glGetUniformLocation( shader, "texture0");
			glUniform1i( dUniformLocation, 0);
		}

	if( entity->isGLUTSphere() )
	{
		glutSolidSphere( 1, 10, 10 );
	}

	else
	{
		//For each mesh...
		Mesh* mesh = entity->getMesh();
		Vector<Polygon>* polygons = mesh->getPolygonList();
		Vector<Vertex>*  vertices = mesh->getVertexList();

		//For each polygon of the mesh...
		for( uInt j = 0; j < polygons->size(); j++ )
		{
			Polygon polygon		 = (*polygons)[j];
			Vector<int>* indices = polygon.getIndices();
			Vec4D faceNormal = polygon.getNormal();

			glBegin( GL_QUADS );

			//For each vertex in each polygon of the mesh...
			for( unsigned int k = 0; k < indices->size(); k++ )
			{
				Vertex v = (*vertices)[(*indices)[k]];

				outline ? 0 : glColor3f( v.color.x, v.color.y, v.color.z );
				outline ? 0 : glTexCoord2f( v.texCoord.x, v.texCoord.y );
				glVertex3f( v.position.x, v.position.y, v.position.z );
				glNormal3f( v.normal.x, v.normal.y, v.normal.z );
			}

			glEnd();
		}
	}
	glPopMatrix();
}

Dynx
Dynx
Thanks for all the help, the attention was overwhelming.

Anyway, for future reference, the reason of light calculation being in the object space was because I forgot to convert the light to eye space as modelview matrix xforms vertex position into eye space.

The transformation can be done using glLight() to specify the light position instead sending the light position as a uniform variable or you can multiply the world coordinates by gl_NormalMatrix which is inverse-transpose of the upper 3x3 of ModelView matrix to convert to eye space.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.