In my engine, I'm ~trying~ to do per-pixel/normal mapped lighting with GLSL shaders. I'm using a modified shader from RenderMonkey. Everything compiles properly, but everything is illuminated at full-bright (as if there was no lighting).

First of all, the shaders:
ppl2.frag (fragment shader):
Code:
uniform float Kd;
uniform float Ka;
uniform vec4 diffuse;
uniform vec4 ambient;
uniform float Ks;
uniform vec4 specular;
uniform float specular_power;
uniform float bumpiness;
uniform mat4 view_matrix;

uniform sampler2D base_map;

varying vec2 vTexCoord;
varying vec3 vLightVector;
varying vec3 vHalfAngle;



float saturate( float inValue)
{
   return clamp(inValue, 0.0, 1.0);
}

//**---------------------------------------------------------
//** Function:    main
//** Description: Declare the main entry point for the shader
//** Input:       PS_INPUT_STRUCT, derived from the output of
//**              the associated vertex shader
//** Returns:     PS_OUTPUT_STRUCT
//**---------------------------------------------------------
void main(void)
{

   //**------------------------------------------------------
   //** Retreive the base color and bump components from the
   //** respective textures, based on the passed bump coords.
   //**------------------------------------------------------
   vec3 base = texture2D( base_map, vTexCoord ).xyz;
   vec3 blank = vec3(1.0,1.0,1.0);

   //**----------------------------------------------------
   //** Normalize the passed vectors from the vertex shader
   //**----------------------------------------------------
   vec3 normalized_light_vector = normalize( vLightVector );
   vec3 normalized_half_angle   = normalize( vHalfAngle );
  
   //**--------------------------------------------------------
   //** "Smooth out" the bumps based on the bumpiness parameter.
   //** This is simply a linear interpolation between a "flat"
   //** normal and a "bumped" normal.  Note that this "flat"
   //** normal is based on the texture space coordinate basis.
   //**--------------------------------------------------------
   vec3 smooth = vec3(0.5, 0.5, 1.0);
  
   //bump = mix( smooth, bump, bumpiness );
   //bump = normalize( ( bump * 2.0 ) - 1.0 );

   //**---------------------------------------------------------
   //** These dot products are used for the lighting model
   //** equations.  The surface normal dotted with the light
   //** vector is denoted by n_dot_l.  The normal vector
   //** dotted with the half angle vector is denoted by n_dot_h.
   //**---------------------------------------------------------
   vec3 n_dot_l = vec3(dot( blank, normalized_light_vector ));
   vec3 n_dot_h = vec3(dot( blank, normalized_half_angle ));

   //**--------------------------------------
   //** Calculate the resulting base color,
   //** based on our lighting model.
   //** Ambient + Diffuse + Specular
   //**--------------------------------------
   vec3 color0 = ( base * ambient.xyz * Ka ) +
                 ( base * diffuse.xyz * Kd * max( vec3(0.0), n_dot_l ) ) +
                 ( specular.xyz * Ks * pow( max( vec3(0.0), n_dot_h ), vec3(specular_power) ));

   //**------------------------------------
   //** Interpolate the resulting color
   //** based on the reflectance parameter.
   //**------------------------------------
   float color0_a = 1.0; //** Set the alpha component manually


   gl_FragColor = vec4(color0.xyz, color0_a); //** Return the resulting output struct
}
ppl2.vert (vertex shader):
Code:
uniform mat4 view_matrix;
uniform mat4 inv_view_matrix;
uniform vec4 eyepos;
uniform vec4 lightpos;

attribute vec3 rm_Tangent; 
attribute vec3 rm_Binormal;

varying vec2 vTexCoord;
varying vec3 vLightVector;
varying vec3 vHalfAngle;

varying vec3 vBasis1;
varying vec3 vBasis2;
varying vec3 vBasis3;

varying vec3 vNormal;
varying vec4 vTangent;

void main( void )
{
 
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   vec4 eye_position =  gl_ModelViewMatrix * gl_Vertex;

   //**----------------------------------------------
   //** Pass the bump and base texture coords through
   //**----------------------------------------------
   vTexCoord = vec2(gl_MultiTexCoord0);

   //**----------------------------------------------
   //** Create a local copy of tanspace.
   //**----------------------------------------------
   vec3 tangent  = vec3( rm_Tangent.x,  rm_Tangent.y,  rm_Tangent.z);
   vec3 normal   = vec3(  gl_Normal.x,   gl_Normal.y,   gl_Normal.z);
   vec3 binormal = vec3(rm_Binormal.x, rm_Binormal.y, rm_Binormal.z);

   //**--------------------------------------------
   //** Calculate the light vector in object space,
   //** and then transform it into texture space.
   //**--------------------------------------------
   vec3 temp_light_position =  vec3(  vec4(light_position.x, light_position.y, -light_position.z, light_position.w) * inv_view_matrix);
   vec3 temp_light_vector   = temp_light_position.xyz - gl_Vertex.xyz; 
   vLightVector.x = dot( temp_light_vector, tangent );
   vLightVector.y = dot( temp_light_vector, binormal );
   vLightVector.z = dot( temp_light_vector, normal );

   //**-------------------------------------------
   //** Calculate the view vector in object space,
   //** and then transform it into texture space.
   //**-------------------------------------------
   vec4 oglEyePos = eye_position;
   oglEyePos.z    = -oglEyePos.z;
   vec3 temp_eye_position = vec3( oglEyePos * inv_view_matrix) ;
   vec3 temp_view_vector  = temp_eye_position - gl_Vertex.xyz;
   vec3 temp_view_vector2;
   temp_view_vector2.x = dot( temp_view_vector, tangent );
   temp_view_vector2.y = dot( temp_view_vector, binormal );
   temp_view_vector2.z = dot( temp_view_vector, normal );

   //**-------------------------
   //** Calculate the half angle
   //**-------------------------
   vHalfAngle = vLightVector + temp_view_vector2;

}
My uniform variables are defined and passed to the shader as:
Code:
	float eyepos[4] = {pCam.m_vPosition.x, pCam.m_vPosition.y, pCam.m_vPosition.z, 1}; 									
	glGetFloatv( GL_PROJECTION_MATRIX, proj );
	glGetFloatv( GL_MODELVIEW_MATRIX, modl );
	float kd = 1.0f;
	float ka = 0.0f;
	float ks = 0.01f;
	float specular_power = 6.38780f;
	float bumpiness = 0.5f;
	float diffuse[4] = {1.5f, 1.5f, 1.5f, 1.0f};
	float ambient[4] = {0.0f, 0.0f, 0.0f, 1.0f};
	float specular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
	view_matrix == modl;
	inv_view_matrix[16] == -view_matrix[16];
Here is where I suspect some of the trouble. I calculate the tangent and bitangent vectors, and store them in an array:
Code:
vector3d computeTangentVector(vector3d pVtxA, vector3d pVtxB, vector3d pVtxC, vector3d normal, float tuA, float tvA, float tuB, float tvB, float tuC, float tvC)
{
	vector3d vProjAB;
	vector3d vProjAC;
	vector3d vTangent;
	
	vector3d vAB = pVtxB-pVtxA;
	vector3d vAC = pVtxC-pVtxA;
	vector3d nA  = normal;

    // Components of vectors to neighboring vertices that are orthogonal to the
    // vertex normal
    vProjAB.x = vAB.x - ( dot(nA, vAB) * nA.x );
	vProjAB.y = vAB.y - ( dot(nA, vAB) * nA.y );
	vProjAB.z = vAB.z - ( dot(nA, vAB) * nA.z );
    vProjAC.x = vAC.x - ( dot(nA, vAC) * nA.x );
	vProjAC.y = vAC.y - ( dot(nA, vAC) * nA.y );
	vProjAC.z = vAC.z - ( dot(nA, vAC) * nA.z );

    // tu texture coordinate differences
    float duAB = tuB - tuA;
    float duAC = tuC - tuA;

	// tv texture coordinate differences
    float dvAB = tvB - tvA;
    float dvAC = tvC - tvA;

    if( (duAC * dvAB) > (duAB * dvAC) )
    {
        duAC = -duAC;
        duAB = -duAB;
    }
    
    vTangent.x = (duAC * vProjAB.x) - (duAB * vProjAC.x);
	vTangent.y = (duAC * vProjAB.y) - (duAB * vProjAC.y);
	vTangent.z = (duAC * vProjAB.z) - (duAB * vProjAC.z);
    vTangent = normalize(vTangent);
    
	return vTangent;
}

extern int index[3];
void computeTangentsAndBinormals(obj objectP)
{
	vector3d v1, v2, v3;
	vector3d n1, n2, n3;

	vector3d tan1, tan2, tan3;
	vector3d bitan1, bitan2, bitan3;

	for (int i=0; i<objectP->m_numMeshes; i++)
	{
		for ( int j = 0; j < objectP->m_pMeshes[i].m_numTriangles; j++ )
		{
			int triangleIndex = objectP->m_pMeshes[i].m_pTriangleIndices[j];
			const Triangle *pTri = &objectP->m_pTriangles[triangleIndex];
			
			index[0] = pTri->m_vertexIndices[0];			
			index[1] = pTri->m_vertexIndices[1];
			index[2] = pTri->m_vertexIndices[2];

			v1.x = objectP->m_pVertices[index[0]].m_location[0];
			v1.y = objectP->m_pVertices[index[0]].m_location[1];
			v1.z = objectP->m_pVertices[index[0]].m_location[2];
			v2.x = objectP->m_pVertices[index[1]].m_location[0];
			v2.y = objectP->m_pVertices[index[1]].m_location[1];
			v2.z = objectP->m_pVertices[index[1]].m_location[2];
			v3.x = objectP->m_pVertices[index[2]].m_location[0];
			v3.y = objectP->m_pVertices[index[2]].m_location[1];
			v3.z = objectP->m_pVertices[index[2]].m_location[2];
			n1.x = pTri->m_vertexNormals[0][0];
			n1.y = pTri->m_vertexNormals[0][1];
			n1.z = pTri->m_vertexNormals[0][2];
			n2.x = pTri->m_vertexNormals[1][0];
			n2.y = pTri->m_vertexNormals[1][1];
			n2.z = pTri->m_vertexNormals[1][2];
			n3.x = pTri->m_vertexNormals[2][0];
			n3.y = pTri->m_vertexNormals[2][1];
			n3.z = pTri->m_vertexNormals[2][2];

			tan1 = computeTangentVector(v1, v2, v3, n1, 
				pTri->m_s[0], pTri->m_t[0], pTri->m_s[1], pTri->m_t[1], pTri->m_s[2], pTri->m_t[2]);
			tan2 = computeTangentVector(v1, v2, v3, n2, 
				pTri->m_s[0], pTri->m_t[0], pTri->m_s[1], pTri->m_t[1], pTri->m_s[2], pTri->m_t[2]); 
			tan3 = computeTangentVector(v1, v2, v3, n3, 
				pTri->m_s[0], pTri->m_t[0], pTri->m_s[1], pTri->m_t[1], pTri->m_s[2], pTri->m_t[2]);

			tan1 = normalize(tan1);
			tan2 = normalize(tan2);
			tan3 = normalize(tan3);

			objectP->m_pVertices[index[0]].m_tangent[0] == tan1.x;
			objectP->m_pVertices[index[0]].m_tangent[1] == tan1.y;
			objectP->m_pVertices[index[0]].m_tangent[2] == tan1.z;
			objectP->m_pVertices[index[1]].m_tangent[0] == tan2.x;
			objectP->m_pVertices[index[1]].m_tangent[1] == tan2.y;
			objectP->m_pVertices[index[1]].m_tangent[2] == tan2.z;
			objectP->m_pVertices[index[2]].m_tangent[0] == tan3.x;
			objectP->m_pVertices[index[2]].m_tangent[1] == tan3.y;
			objectP->m_pVertices[index[2]].m_tangent[2] == tan3.z;

			bitan1 = cross(n1, tan1);
			bitan2 = cross(n2, tan2);
			bitan3 = cross(n3, tan3);

			objectP->m_pVertices[index[0]].m_binormal[0] == bitan1.x;
			objectP->m_pVertices[index[0]].m_binormal[1] == bitan1.y;
			objectP->m_pVertices[index[0]].m_binormal[2] == bitan1.z;
			objectP->m_pVertices[index[1]].m_binormal[0] == bitan2.x;
			objectP->m_pVertices[index[1]].m_binormal[1] == bitan2.y;
			objectP->m_pVertices[index[1]].m_binormal[2] == bitan2.z;
			objectP->m_pVertices[index[2]].m_binormal[0] == bitan3.x;
			objectP->m_pVertices[index[2]].m_binormal[1] == bitan3.y;
			objectP->m_pVertices[index[2]].m_binormal[2] == bitan3.z;
		}
	}
}
And in the draw function, I pass them to the vertex shader as attribute variables:
Code:
	for(i=0; i<objectP->m_numVertices; i++)
	{
		_ceShader->attribute3fv(program[4], "rm_Tangent", objectP->m_pVertices[i].m_tangent);
		_ceShader->attribute3fv(program[4], "rm_Binormal", objectP->m_pVertices[i].m_binormal);
	}

Alot of code, I know, but I have no idea exactly where the problem is, so posting too much is probably better than posting too little.

Help will be very much appreciated. This has got me really fusturated!
Thanx.

-psychopath