• Advertisement
Sign in to follow this  

qglVertexAttribPointerARB question

This topic is 4172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to do lighting, which shouldn't be that difficult, but my problem is the lighting is all over the place and I can't decide whether is a bad TBN matrix, it being passed with glVertexAttribPointerARB or something else. This isn't effienct its just for testing this is the code that calls glDrawElements with all the gl parmetor setting above it, and in its parent calling function.
static void R_DrawElementsBumped( int numIndexes, const glIndex_t *indexes, shaderCommands_t *input ) {
	qglEnableVertexAttribArrayARB(tr.defaultCG.params[3]);
	qglEnableVertexAttribArrayARB(tr.defaultCG.params[4]);
	//qglEnableVertexAttribArrayARB(tr.defaultCG.params[5]);

	qglEnableClientState( GL_NORMAL_ARRAY );

	qglVertexAttribPointerARB(tr.defaultCG.params[3], 3, GL_FLOAT, 0, 16, input->tangent);
	qglVertexAttribPointerARB(tr.defaultCG.params[4], 3, GL_FLOAT, 0, 16, input->binormal);

	qglNormalPointer( GL_FLOAT, 16, input->normal2 );
	qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexes );

	qglDisableClientState( GL_NORMAL_ARRAY );
	qglDisableVertexAttribArrayARB(tr.defaultCG.params[3]);
	qglDisableVertexAttribArrayARB(tr.defaultCG.params[4]);
	//qglDisableVertexAttribArrayARB(tr.defaultCG.params[5]);
}

The values for the TBN array all correct, heres a condump of what vertex and its corresponding TBN Value(each three verts have the same TBN value odviouslly).
------ New Surface ---------
*For Vertex(0) -248.000000 -248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 -1.000000
*For Vertex(1) 248.000000 -248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 -1.000000
*For Vertex(2) 248.000000 248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 -1.000000
*For Vertex(3) -248.000000 248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 -1.000000
------ New Surface ---------
*For Vertex(4) -248.000000 -248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 1.000000
*For Vertex(5) -248.000000 248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 1.000000
*For Vertex(6) 248.000000 248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 1.000000
*For Vertex(7) 248.000000 -248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 -1.000000 0.000000
Normal2: 0.000000 0.000000 1.000000
Light 0 rendering at -8.000000 8.000000 128.000000
------ New Surface ---------
*For Vertex(0) 248.000000 -248.000000 8.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: -1.000000 0.000000 0.000000
*For Vertex(1) 248.000000 248.000000 8.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: -1.000000 0.000000 0.000000
*For Vertex(2) 248.000000 248.000000 248.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: -1.000000 0.000000 0.000000
*For Vertex(3) 248.000000 -248.000000 248.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: -1.000000 0.000000 0.000000
------ New Surface ---------
*For Vertex(4) -248.000000 -248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 1.000000 0.000000
*For Vertex(5) 248.000000 -248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 1.000000 0.000000
*For Vertex(6) 248.000000 -248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 1.000000 0.000000
*For Vertex(7) -248.000000 -248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 1.000000 0.000000
------ New Surface ---------
*For Vertex(8) -248.000000 248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 -1.000000 0.000000
*For Vertex(9) -248.000000 248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 -1.000000 0.000000
*For Vertex(10) 248.000000 248.000000 248.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 -1.000000 0.000000
*For Vertex(11) 248.000000 248.000000 8.000000*
Tangent: 1.000000 0.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 0.000000 -1.000000 0.000000
------ New Surface ---------
*For Vertex(12) -248.000000 -248.000000 8.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 1.000000 0.000000 0.000000
*For Vertex(13) -248.000000 -248.000000 248.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 1.000000 0.000000 0.000000
*For Vertex(14) -248.000000 248.000000 248.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 1.000000 0.000000 0.000000
*For Vertex(15) -248.000000 248.000000 8.000000*
Tangent: 0.000000 1.000000 0.000000
Binormal: 0.000000 0.000000 -1.000000
Normal2: 1.000000 0.000000 0.000000
Light 0 rendering at -8.000000 8.000000 128.000000

Vertex program:
// bumpMapSpecNv2.glslvert
//

varying vec3 lightDir;

uniform vec3 lightOrigin;

attribute vec3		attr_Tangent;
attribute vec3		attr_Binormal;
attribute vec3		attr_Normal;

void main()
{
	vec3 Tangent = attr_Tangent;
	vec3 Binormal = attr_Binormal;
	vec3 Normal = gl_Normal;

	vec4 glXyz  = gl_ModelViewProjectionMatrix * gl_Vertex;

	gl_Position    = glXyz;

	gl_TexCoord[0] = gl_MultiTexCoord0;

	// mat3 tbnMatrix = mat3(Tangent, Binormal, Normal);

	mat3 tbnMatrix = mat3(Tangent.x, Binormal.x, gl_Normal.x,
			      Tangent.y, Binormal.y, gl_Normal.y,
			      Tangent.z, Binormal.z, gl_Normal.z);				

	lightDir       = (lightOrigin - gl_Vertex.xyz) * tbnMatrix; 
//	lightDir       = normalize(lightDir);
}

Fragment program
// bumpMapSpecNv2.glslfrag
//

uniform sampler2D colorMapTex;
uniform sampler2D normalTex;
varying vec3 lightDir;

void main()
{
	// Diffuse Map
	vec3	color 		= texture2D(colorMapTex, gl_TexCoord[0].st).xyz;
	// Normal Map
	vec3	normalVec 	= 2.0 * (texture2D(normalTex, gl_TexCoord[0].st).xyz - 0.5);

	normalVec = normalize(normalVec);
	vec3 lightD = normalize(lightDir);

	// NdotL + ambient value.
	float   NdotL = clamp(dot(normalVec, lightD), 0.0, 1.0) + 0.3;

	// Attenuation Hack
	float   att = clamp(1.0 - dot(lightD/(300.0),lightD/(300.0)), 0.0, 1.0); 


	gl_FragColor = vec4(att * (NdotL * color), 1.0);
}

This lighting moves around, and looks completelly wrong, only part that is lit properlly is the ceiling on the box, the walls and floor are lit completelly wrong. I Was just hoping someone could see something I couldn't ; ).

Share this post


Link to post
Share on other sites
Advertisement
I may have missed it but it doesn't look like you're ever binding your vertex attributes. OpenGL state in general gives us a set number of spots or locations that we can bind our user-defined vertex attributes to (this number is implementation dependent but I think it's usually 16).

Before we can specify the attributes values we actually have to bind the attributes to one of these locations with a call to glBindAttribLocationARB(GLhandleARB ProgramObject, GLuint Index_to_bind_to, const GLcharARB *name_of_the_attribute);

Share this post


Link to post
Share on other sites
I did, just didn't post it.


/*
=============
R_GetGLSLParam
=============
*/

void R_GetGLSLParam( trProgType_t type, trCG_t *cg, const char *name ) {
switch( type ) {
case GLSL_PROG_UNIFORM:
cg->params[cg->numParams] = qglGetUniformLocationARB( cg->program, name );
break;

case GLSL_PROG_ATTR:
cg->params[cg->numParams] = qglGetAttribLocationARB( cg->program, name );
break;

default:
Com_Error(ERR_FATAL, "R_GetGLSLParam: Invalid type %d\n", type);
break;
}
if(cg->params[cg->numParams] < 0) {
Com_Printf("WARNING: %s variable does not exist\n", name);
R_CheckLastGPUError(name, cg->program);
// SHOULD NOT GET HERE.
#if 0
Com_Error(ERR_FATAL, "GLSL Internal Error\n");
#endif
}
cg->numParams++;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by eviltwigflipper
I Was just hoping someone could see something I couldn't ; ).


Apparently you're doing this for quake 3, right?

There's lotsa things that can go wrong here. First of all, in what system are the normalmaps generated and in which system are your tangents done? Y can go up or down, depending on who you ask for. And is the light defined in model's local coordinates?

The tangent matrix should be [ tangent, bitangent, normal ]

ch.

Share this post


Link to post
Share on other sites
Quote:

There's lotsa things that can go wrong here. First of all, in what system are the normalmaps generated and in which system are your tangents done? Y can go up or down, depending on who you ask for. And is the light defined in model's local coordinates?


The normal maps and diffusemaps are all from Doom 3, just to make sure none of my art assests were wrong. Yes i'm doing this in Quake 3. The light is just used from the standard dynamic lighting trap that gets used on the client side(I'm not at home atm to look at the code, to remember the actual trap name), then I pass it as a paremtor in DrawMultitexture. Horriblly ineffeciant, but again at first I'm not designing this for speed.

I thought the TBN was {tangent.x, binormal.x, normal.x,
tangent.y, binormal.y, normal.y
tangent.z, binormal.z, normal.z}.

I know theres a lot of things that can go wrong, I'm just trying to single them down. I just pass the TBN values to tess from a modifed srfSurface_t structure that holds vertex, and TBN info(TBN gets calculated in ParseFace). Then in RB_TessSurface or something like that I put it directlly into shaderCommand_t tess something liek this:

XYZ[0] = TBN[0]
etc.

I don't think I had to negate the Y, cord before the TBN matrix is calculated?

Share this post


Link to post
Share on other sites
Start debugging by using vec3(0,0,1) normal vector instead of normalmap. Compare this to shader that uses the real polygon normals. If that doesn't show up right, change the tbn calculation, I think I used one from nVidia SDK that worked correctly with normalmaps from doom3. Then there's the "ATI version" which has the Y upside down.

Just took a look at one of my demo that shows imp (exported as obj). Tangents are calculated in nvidias obj loader, so I'll bet its the same as in nvidias library. Here's the vertex shader:


uniform vec3 light_pos;

varying vec3 v_eyeVec;
varying vec3 v_lightVec;

void main ()
{
// light in local space..
// this is the first thing that comes to mind
// in local space eyeVec is not vec3(0,0,0) !!!!
// but gl_ModelViewMatrixInverse * vec4(0,0,0,1);

// or is this correct after all ??
vec3 eyeVec = ((gl_ModelViewMatrixInverse * vec4(0,0,0,1)) - gl_Vertex).xyz;
vec3 lightVec = light_pos - vec3(gl_Vertex);

// transform to tangent space
// with T, BT, N matrix
mat3 m = mat3 ( gl_MultiTexCoord1.xyz, gl_MultiTexCoord2.xyz, gl_Normal );

// v_eyeVec = normalize ( m * eyeVec );
// v_lightVec = normalize ( m * lightVec );

// the matrix is in freaking OTHER ORDER !!!!
v_eyeVec = normalize ( eyeVec * m);
v_lightVec = normalize ( lightVec * m);

gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}


I guess you were right on the matrix order, but you have to swap the multiplication on the vector.

ch.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement