Projective Texturing

Started by
8 comments, last by Deliverance 17 years, 9 months ago
I'm trying to implement projective texturing using multitexturing but I'm experimenting some artefacts here's the code

	StoreLightMatrices();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	
	gluLookAt(camera.vPosition.x, camera.vPosition.y, camera.vPosition.z,
			  camera.vView.x, camera.vView.y, camera.vView.z,
			  camera.vUpVector.x, camera.vUpVector.y, camera.vUpVector.z); 
							
	glActiveTextureARB(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);

	glActiveTextureARB(GL_TEXTURE1);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, projTexID);

	// Specify the projector's properties
	glMatrixMode(GL_TEXTURE);
		
		glLoadIdentity();
	
		glTranslatef(0.5f, 0.5f, 1.0f);
		glScalef(0.5f, 0.5f, 1.0f);
	
		glMultMatrixf(projectorProjection);
		glMultMatrixf(projectorModelView);
	
	glMatrixMode(GL_MODELVIEW);

	double Splane[] = {1.0f, 0.0f, 0.0f, 0.0f};	
	double Tplane[] = {0.0f, 1.0f, 0.0f, 0.0f};
	double Rplane[] = {0.0f, 0.0f, 1.0f, 0.0f};
	double Qplane[] = {0.0f, 0.0f, 0.0f, 1.0f};
		
	glTexGendv(GL_S, GL_EYE_PLANE, Splane);
	glTexGendv(GL_T, GL_EYE_PLANE, Tplane);
	glTexGendv(GL_R, GL_EYE_PLANE, Rplane);
	glTexGendv(GL_Q, GL_EYE_PLANE, Qplane);
	
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);
	glEnable(GL_TEXTURE_GEN_Q);

	glEnable(GL_TEXTURE_2D);	
	glActiveTextureARB(GL_TEXTURE0);

        // Draw world here 

the projectorProjection and projectorModelView are computed like this:

float projectorModelView[16], projectorProjection[16];
float g_LightPosition[3] = {0.0f, 5.0f, 6.0f};
float g_LightView[3] = {0.0f, 5.0f, 0.0f};

void StoreLightMatrices()
{
	memset(projectorModelView, 0, sizeof(float)*16);
	memset(projectorProjection, 0, sizeof(float)*16);

	glPushMatrix();

		glPushMatrix();

			glLoadIdentity();		

			gluLookAt(g_LightPosition[0],  g_LightPosition[1],  g_LightPosition[2], 
					  g_LightView[0],	   g_LightView[1],	    g_LightView[2],		0, 1, 0);

			glGetFloatv(GL_MODELVIEW_MATRIX, projectorModelView);

		glPopMatrix();
		
		glLoadIdentity();
		
		gluPerspective(150.0f, 1.0f, 1.0f, 2.0f);

		glGetFloatv(GL_MODELVIEW_MATRIX, projectorProjection);

	glPopMatrix();
}
So do you see something wrong at first glance, somethjing that might cause artefacts? I'm not refering to artefacts as the reverse projection.
Advertisement
You could tell a little more about what the artefacts.

You could get artefacts between front and rear projection if you do not set the edge pixels in the texture properly - for all mipmap levels.
Okay here's the link with the problem

http://i11.photobucket.com/albums/a156/Keenox/projectivetexturing.jpg
Yes it does look like you do not process the edge pixels properly. You will need to set the edgemost pixels in the texture to black (or sometimes white), for all mipmap levels.
so how do I do that? can you be more specific?
Quote:Original post by Deliverance
so how do I do that? can you be more specific?


for all mipmap levels    h = mipmap.h    w = mipmap.w    for y = 0; y < h; ++y        for x = 0; x < w; ++x            bool edge = (x == 0) || (y == 0) || (x == w - 1) || (y == h - 1)            texel(x,y).rgb = (image.black_edge && edge) ? black : proper rgb


You already have the for loops somewhere where you load (or a library you use) the textures and compute mipmaps, before optionally compressing textures, either in the application or your content path. Just add test: If the pixel is on the edge and if the texture in question should have black edges - Then set the pixel color to black instead of the proper rgb from the source (the original image or mipmap).
The texture I use already has black borders and this doesn't seem to solve the problem
try using

GLfloat borderColour[4] = {0.0, 0.0, 0.0, 0.0};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);

when you set up your texture object.

Also... it looks from your screenshot that the blue square is dead centre. Does the square move with the shadow or with the viewport?
Quote:Original post by Deliverance
The texture I use already has black borders and this doesn't seem to solve the problem


Do you have black borders on all mipmap levels? Having 1 texel black border on the base texture does not ensure black border on further mipmap levels.
Thank you guys for all the interest I solved the problem mainly thanks to coordz ! Thank you!!!!

This topic is closed to new replies.

Advertisement