Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: Trying to render a frusum "shape" from a given orthographic projection matrix.

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    17

    Trying to render a frusum "shape" from a given orthographic projection matrix.

    Hi guys, in order to test my application, I want to render a shape which represents the volume of an orthographic projection.

    I have found this code, and when I pass a perspective projection matrix, it creates the frustum shape perfectly, but when I pass a matrix of a orthographic projection, all components ( x, y and z ) of the each generate vert are set with 0.0f.

    So two questions:

    1º) Why the frustum shape with a perspective matrix is built correctly, but not with an orthographic matrix?
    2º) How can I create a frustum shape from an orthograpic projection matrix?

    PD: The orthographic projection that I'm trying to render with that code, works well in my program.

    Thanks in advances,
    Alberto.
    Last edited by Alberto García; 01-01-2018 at 11:24 AM.

  2. #2
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,015
    The word "fustrum" describes a specific shape: it's a pyramid with the top chopped off. The volume of an orthographic projection is not a frustum. Therefore, you cannot render a frustum that represents a non-frustrum shape.

    The volume of an orthographic projection is a cuboid/rectangular prism.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    17
    Thanks for the clarification, Alfonse.

    Then the question is:

    How can I produce a shape in order to see the "view volume" of an orthographic projection, using my projection matrix?

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,421
    That code just doesn't know how to back-infer the frustum generation parameters correctly for an orthographic frustum. It only supports a perspective frustum.

    That said, updating it to detect an orthographic projection and allowing it to back-infer the frustum-generation parameters (l,r,b,t,n,f) from the orthographic projection matrix shouldn't be that hard. See the ortho and perspective projection matrices at the bottom of this page. To determine which type of transform you have, just look at the bottom row. And combinations of matrix elements will give you (l,r,b,t,n,f), similar to the logic already there for a perspective projection matrix.

    By the way, regardless of whether we're talking about an orthographic projection or a perspective projection, both are defined by a frustum (which is a region of a solid which lies between 2 parallel planes -- near and far in this case). A rectangular prism is just as much a frustum as a pyramid chopped by parallel planes. Both are easily defined by 6 planes, at least 2 of which are parallel.

    The only confusion is that legacy OpenGL provided separate APIs to specify an orthographic projection matrix (glOrtho) and perspective projection matrix (glFrustum), falsely implying that only the perspective projection is defined by a frustum.
    Last edited by Dark Photon; 01-02-2018 at 06:08 AM.

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,859
    Quote Originally Posted by Alberto García View Post
    How can I produce a shape in order to see the "view volume" of an orthographic projection, using my projection matrix?
    Transform the vertices of the signed unit cube by the inverse of the projection matrix.

    If the projection matrix has a known structure, it's possible to simplify the inverse (which is what that blog post tries to do, although I'm fairly sure it's wrong). But a generalised inverse isn't that difficult, and is something you should have available anyhow.

  6. #6
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    17
    Hi again, I come back with this issue,

    according the post of GClements I have multiplied a unit cube by the inverse of my projection matrix ( orthographic ), but the shape produced by this operations doesn't match what I expect.

    Here the source code:

    Code :
                void SetOrtho( Mat4 proj )
                {
                    Mat4 inv = proj.Inverse();
     
                    // NEAR corners
                    Vec3 bln = inv * Vec4( Vec3( -1.0f, -1.0f, -1.0f ), 1.0f );
                    Vec3 brn = inv * Vec4( Vec3( 1.0f, -1.0f, -1.0f ), 1.0f );
                    Vec3 tln = inv * Vec4( Vec3( -1.0f, 1.0f, -1.0f ), 1.0f );
                    Vec3 trn = inv * Vec4( Vec3( 1.0f, 1.0f, -1.0f ), 1.0f );
                    // FAR corners
                    Vec3 blf = inv * Vec4( Vec3( -1.0f, -1.0f, 1.0f ), 1.0f );
                    Vec3 brf = inv * Vec4( Vec3( 1.0f, -1.0f, 1.0f ), 1.0f );
                    Vec3 tlf = inv * Vec4( Vec3( -1.0f, 1.0f, 1.0f ), 1.0f );
                    Vec3 trf = inv * Vec4( Vec3( 1.0f, 1.0f, 1.0f ), 1.0f );
     
                    Vec3 verts[] =
                    {
                        Vec3( tln ),
                        Vec3( trn ),
                        Vec3( brn ),
                        Vec3( bln ),
                        Vec3( tlf ),
                        Vec3( trf ),
                        Vec3( brf ),
                        Vec3( blf )
                    };
     
                    GLuint indexes[] =
                    {
                        // front
                        0, 1,
                        1, 2,
                        2, 3,
                        3, 0,
                        // back
                        4, 5,
                        5, 6,
                        6, 7,
                        7, 4,
                        // union
                        0, 4,
                        1, 5,
                        2, 6,
                        3, 7
                    };
     
                    Prana::SurfaceData *data = this->GetData();
     
                    data->mIndices.SaveData( indexes, 24 );
                    data->GetVBO( Prana::VBO_ID::INDEXES ).SetUpdated( false );
                    data->mVerts.SaveData( verts, 8 );
                    data->GetVBO( Prana::VBO_ID::VERTS ).SetUpdated( false );
     
                    data->CreateGL_VAO();
                }

    Is it right?

    Thanks in advance,
    Alberto

  7. #7
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    17
    I'm sorry I have noticed that there was an error in the multiplication order, now it runs has expected.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •