PDA

View Full Version : Projective Textures, view only section



henniman2
05-13-2012, 03:15 AM
Hi all,

i use projective textures in my application. It works very well, the pseudo code is




//
// set up texture projection
// 1. switch to texture matrix
// 2. reset
// 2.1 go from -1..+1 space to 0..1 space: translate and scale by 0.5
// 3. set perspective using gui-selected FOV
// 4. set up view direction using gluLookAt. remember y/z switch and z inversion when importing from 3ds
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0.0);
glScalef(0.5, 0.5, 1.0);
gluPerspective( projector_fov, 1.0, 0.1, 100);
gluLookAt( projector_source[0], -projector_source[2], projector_source[1],
projector_target[0], -projector_target[2], projector_target[1], 0.0, 1.0, 0.0);


//
// set up projection
// 1. switch to projection matrix
// 2. reset
// 3. set perspective using gui-selected FOV
// 4. set up view direction using gluLookAt. remember y/z switch and z inversion
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( viewer_fov, 1.0, 0.1, 100);
gluLookAt(
viewer_source[0], viewer_source[2], -viewer_source[1],
viewer_target[0], viewer_target[2], -viewer_target[1], +0.0, +1.0, +0.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//
// draw a transparent line as a border around the texture
glBindTexture(GL_TEXTURE_2D, rm->getResultTextureBeforeCorrection());
GLfloat borderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

GLfloat sz = 0.5;
GLfloat eyePlaneS[] = {sz, 0.0, 0.0, 0.0};
GLfloat eyePlaneT[] = {0.0, sz, 0.0, 0.0};
GLfloat eyePlaneR[] = {0.0, 0.0, sz, 0.0};
GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, sz};

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
render_target();



This renders the whole source texture onto the target. What do
i have to do if i only want to render a part of the texture,
( eg. a lower left eighth, in tex coordinates 0.0,0.0,0.25,0.5)
do i have to change the matrix


GLfloat sz = 0.5;
GLfloat eyePlaneS[] = {sz, 0.0, 0.0, 0.0};
GLfloat eyePlaneT[] = {0.0, sz, 0.0, 0.0};
GLfloat eyePlaneR[] = {0.0, 0.0, sz, 0.0};
GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, sz};


or do i have to change the projection matrix


glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0.0);
glScalef(0.5, 0.5, 1.0);


Best,
Henniman

henniman2
05-17-2012, 01:23 PM
sorry, is the question too trivial or simply impossible to understand?

thokra
05-18-2012, 02:52 AM
It maybe due to the fact that few people remember how to do this stuff using legacy OpenGL. At least I don't. ;)

In a shader this wouldn't be a problem, you would simply check if the projected vertex is inside the desired range. Mathematically you get

Vproj= Mscale_bias * MVP * V

If Vproj.s > 0.25 or Vproj.t > 0.25 then you simply don't use the projected texture for the corresponding fragment.

Do you absolutely need to do this using fixed-function stuff?