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

calculating the frustum

Started by cherryyosh Mar 2, 2009 at 2:13 PM 8 replies 2.2k views
Original Post
cherryyosh
cherryyosh
hey guys, I have started to create a visual debugger for my lighting system but am currently stuck on how to calculate the light's view frustum. anyone have any ideas or links?? (my google'ing skills fail me )
zedz
zedz
do a box from (-1,-1,-1)->(1,1,1) with the inverse of the lights projectionmodelview matrix ( I think thats correct )
cherryyosh
cherryyosh
Quote:
Original post by zedz
do a box from (-1,-1,-1)->(1,1,1) with the inverse of the lights projectionmodelview matrix ( I think thats correct )


I think I might be getting the wrong inverse of the pmv..
Right now after rendering the shadowmap from the light I get the light's modelview then I mul the light's projection and store that as the pmv.

glTranslatef( l->center[0], l->center[1], l->center[2] );                                glGetFloatv( GL_MODELVIEW_MATRIX, modelView_shadow );                                DrawScene();                                glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );                                glDisable( GL_POLYGON_OFFSET_FILL );                        glPopAttrib();                glPopMatrix();        glMatrixMode( GL_PROJECTION );        //here we get the matrix needed later to draw the shadows correctly        glMultMatrixf( modelView_shadow );        glGetFloatv( GL_PROJECTION_MATRIX, l->shadow_pmv );


from there I inverse that and load it into the current matrix before drawing a unti cube. this does not work..
cherryyosh
cherryyosh
can anyone help me get the correct inverse??

EDIT:
I think I got it right, using the inverse modelView matrix, however this does not draw the correct frustum using a unit cube. Any ideas?

[Edited by - cherryyosh on March 2, 2009 8:05:52 PM]
cherryyosh
cherryyosh
any help please?? so annoyed by this.. should be easy! -_-
zedz
zedz
I just had a look


first mult current matrix by inverse_modelview_matrix(light)
the multiply that by
inverse_projection_matrix(light)

draw a cube
cherryyosh
cherryyosh
Quote:
Original post by zedz
I just had a look


first mult current matrix by inverse_modelview_matrix(light)
the multiply that by
inverse_projection_matrix(light)

draw a cube


Im doing that now, and its still moving with the camera, even tried glLoadIdentity() before...

heres the full code where I get the matrices

         //for( int i = 0; i < NUMLIGHTS; i++ ){        //      if( !light.isEnabled )         //              break; //no need to do anything        Light* l = light;        //set set and pop the matrixes so nothing is saved        //NOTE: NOT OGL3.0, needs to be changed, how I dont know        glMatrixMode( GL_PROJECTION );        glPushMatrix();                glMatrixMode( GL_MODELVIEW );                glPushMatrix();                        //set the viewport so we only draw what the map can haddel                        //dont belive this is OGL3.0 either                        //also very similar to sissors test, speed test??                        glPushAttrib( GL_VIEWPORT_BIT );                        glViewport( 0, 0, l->width, l->height );                                //prevent z-fighting                                glPolygonOffset( 1.0, 4096.0 );                                glEnable( GL_POLYGON_OFFSET_FILL );                                glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, shadow1FBO );                                glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );                                glTranslatef( l->center[0], l->center[1], l->center[2] );                                glGetFloatv( GL_MODELVIEW_MATRIX, tmp );                                Inverse( mvInv, tmp );                                DrawScene();                                glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );                                glDisable( GL_POLYGON_OFFSET_FILL );                        glPopAttrib();                glPopMatrix();        glMatrixMode( GL_PROJECTION );                glGetFloatv( GL_PROJECTION_MATRIX, tmp );                Inverse( projInv, tmp );        glPopMatrix();        glMatrixMode( GL_MODELVIEW );


and the code to draw the frustum

        glPushMatrix();                glMultMatrixf( mvInv );                glMultMatrixf( projInv );                glColor3f( 1.0, 0.0, 0.0 );                DrawUnitCube();        glPopMatrix();


and, thought I am sure this is correct, here is how I inverse the matrix

void Inverse(float dst[16], float src[16]){        dst[0] = src[0];        dst[1] = src[4];        dst[2] = src[8];        dst[3] = 0.0f;        dst[4] = src[1];        dst[5] = src[5];        dst[6]  = src[9];        dst[7] = 0.0f;        dst[8] = src[2];        dst[9] = src[6];        dst[10] = src[10];        dst[11] = 0.0f;        dst[12] = -(src[12] * src[0]) - (src[13] * src[1]) - (src[14] * src[2]);        dst[13] = -(src[12] * src[4]) - (src[13] * src[5]) - (src[14] * src[6]);        dst[14] = -(src[12] * src[8]) - (src[13] * src[9]) - (src[14] * src[10]);        dst[15] = 1.0f;}
zedz
zedz
thats not an inverse of a 4x4 matrix (that looks like a transpose, which is a lot easier, though it could be the inverse of a 3x3 matrix I think)

anyways have a look at an existing math library for an example of the inverse,

heres code in the matrix FAQ

http://web.archive.org/web/20041029003853/http:/www.j3d.org/matrix_faq/matrfaq_latest.html#Q24
cherryyosh
cherryyosh
Quote:
Original post by zedz
thats not an inverse of a 4x4 matrix (that looks like a transpose, which is a lot easier, though it could be the inverse of a 3x3 matrix I think)

anyways have a look at an existing math library for an example of the inverse,

heres code in the matrix FAQ

http://web.archive.org/web/20041029003853/http:/www.j3d.org/matrix_faq/matrfaq_latest.html#Q24


Really, ill check it out.. Thats really odd that the inverse isnt right thought as I got the code from a nvidia demo.. thanks for the info ill report back when I get a working inverse.

EDIT: desided it might be best if I use a preexisting libary for speed / full function.. But having a problem finding a good one. Anyone have any ideas on a good libary ( want cross platform, as if it wont be hah)?

[Edited by - cherryyosh on March 3, 2009 9:57:13 PM]
cherryyosh
cherryyosh
Ok so I got a matrix class, the one nvidia supply. It seems like I copyed the cameraInverse function that I guess was simply a transpose, believe I read somewhere that for camera functions that works.. but might be wrong.. Anyways the unit cube is now always draw behind the camera, and can only been seen when moving the camera backwards. Just incase this is doing the wrong inverse I will post the code. (NOTE: T is float )

    friend matrix4 inverse( const matrix4 & m) {        matrix4 minv;        T r1[8], r2[8], r3[8], r4[8];        T *s[4], *tmprow;        s[0] = &r1[0];        s[1] = &r2[0];        s[2] = &r3[0];        s[3] = &r4[0];        register int i,j,p,jj;        for(i=0;i<4;i++) {            for(j=0;j<4;j++) {                s[j] = m.element(i,j);                if(i==j) s[j+4] = 1.0;                else     s[j+4] = 0.0;            }        }        T scp[4];        for(i=0;i<4;i++) {            scp = T(fabs(s[0]));            for(j=1;j<4;j++)                if(T(fabs(s[j])) > scp) scp = T(fabs(s[j]));            if(scp == 0.0) return minv; // singular matrix!        }        int pivot_to;        T scp_max;        for(i=0;i<4;i++) {            // select pivot row            pivot_to = i;            scp_max = T(fabs(s/scp));            // find out which row should be on top            for(p=i+1;p<4;p++)                if (T(fabs(s/scp)) > scp_max) {                    scp_max = T(fabs(s/scp));                    pivot_to = p;                }            // Pivot if necessary            if(pivot_to != i) {                tmprow = s;                s = s[pivot_to];                s[pivot_to] = tmprow;                T tmpscp;                tmpscp = scp;                scp = scp[pivot_to];                scp[pivot_to] = tmpscp;            }            T mji;            // perform gaussian elimination            for(j=i+1;j<4;j++) {                mji = s[j]/s;                s[j] = 0.0;                for(jj=i+1;jj<8;jj++)                    s[j][jj] -= mji*s[jj];            }        }        if(s[3][3] == 0.0) return minv; // singular matrix!  //        // Now we have an upper triangular matrix.        //        //  x x x x | y y y y        //  0 x x x | y y y y         //  0 0 x x | y y y y        //  0 0 0 x | y y y y        //        //  we'll back substitute to get the inverse        //        //  1 0 0 0 | z z z z        //  0 1 0 0 | z z z z        //  0 0 1 0 | z z z z        //  0 0 0 1 | z z z z         //        T mij;        for(i=3;i>0;i--) {            for(j=i-1;j > -1; j--) {                mij = s[j]/s;                for(jj=j+1;jj<8;jj++)                    s[j][jj] -= mij*s[jj];            }        }        for(i=0;i<4;i++)            for(j=0;j<4;j++)                minv(i,j) = s[j+4] / s;        return minv;    }

Topic Locked

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

Sign in to reply to this topic.