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 9 of 9

Thread: Very odd results when drawing with an identity matrix

  1. #1
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45

    Very odd results when drawing with an identity matrix

    For some reason, a shape I'm attempting to draw a sphere without any transformations (other than a camera projection) won't draw correctly. This:
    Code :
    #version 330 core
     
    layout (location = 0) in vec4 InPosition;
    layout (location = 1) in vec4 InColor;
    uniform mat4 CameraMat;
    uniform mat4 ModelMat;
     
    smooth out vec4 FragColor;
     
    void main()
    {
        gl_Position = CameraMat * ModelMat * InPosition;
        FragColor = InColor;
    }
    Click image for larger version. 

Name:	Original.jpg 
Views:	35 
Size:	4.6 KB 
ID:	1205
    causes a blank screen when drawing with ModelMat set to an identity matrix, while when it is set to ANYTHING else, it draws fine (correctly transformed as well). When I use this vertex shader:
    Code :
    #version 330 core
     
    layout (location = 0) in vec4 InPosition;
    layout (location = 1) in vec4 InColor;
    uniform mat4 CameraMat;
    uniform mat4 ModelMat;
     
    smooth out vec4 FragColor;
     
    void main()
    {
        gl_Position = CameraMat * InPosition;
        FragColor = InColor;
    }
    Click image for larger version. 

Name:	Modified_1.jpg 
Views:	44 
Size:	5.0 KB 
ID:	1203
    It draws perfectly fine, in the center of my world. It's quite odd that when I remove the term it draws fine, but when I leave it, it doesn't work...even weirder is this:
    Code :
    #version 330 core
     
    layout (location = 0) in vec4 InPosition;
    layout (location = 1) in vec4 InColor;
    uniform mat4 CameraMat;
    uniform mat4 ModelMat;
     
    smooth out vec4 FragColor;
     
    void main()
    {
        mat4 TestMat(1.0f);
        gl_Position = CameraMat * TestMat * InPosition;
        FragColor = InColor;
    }
    Click image for larger version. 

Name:	Modified_2.jpg 
Views:	51 
Size:	5.6 KB 
ID:	1204
    It draws a big black sphere filling the whole window, when it is supposed to be green and not the size of the window. ??? I'm baffled. My C++ code remained exactly the same through all these samples, only the vertex shader changed. And, when I use the original shader (that gives no sphere with an identity ModelMat) with a translate, it draws it correctly.

    EDIT: Turns out this:
    Code :
    #version 330 core
     
    layout (location = 0) in vec4 InPosition;
    layout (location = 1) in vec4 InColor;
    uniform mat4 CameraMat;
    uniform mat4 ModelMat;
     
    smooth out vec4 FragColor;
     
    void main()
    {
        mat4 TestMat(1.0f);
        gl_Position = CameraMat * ModelMat * InPosition;
        FragColor = InColor;
    }
    causes the big black sphere as well...so it is just the declaration of TestMat (and not the use of it) that causes that issue. I'm even more confused now.
    Last edited by chbaker0; 12-22-2013 at 08:05 PM.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,104
    Does you input vertex have a 1 in w component? (AFAIK it will if you don't supply a w component).

  3. #3
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Yes, I made sure to set the w values to 1 before setting up the VBOs. Here is the code I used for loading the vertices and colors into arrays from a model importer:
    Code :
        auto *SphereMesh = SphereScene->mMeshes[0];
        float SphereVertices[SphereMesh->mNumVertices * 4];
        float SphereColors[SphereMesh->mNumVertices * 4];
        for(uint64_t i = 0; i < SphereMesh->mNumVertices; i++)
        {
            auto CurrentVertex = SphereMesh->mVertices[i];
            SphereVertices[i*4] = CurrentVertex.x;
            SphereVertices[i*4+1] = CurrentVertex.y;
            SphereVertices[i*4+2] = CurrentVertex.z;
            SphereVertices[i*4+3] = 1.0f;
     
            SphereColors[i*4] = 0.0f;
            SphereColors[i*4+1] = 1.0f;
            SphereColors[i*4+2] = 0.0f;
            SphereColors[i*4+3] = 1.0f;
        }

  4. #4
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Also, I just noticed that if I create my model matrix with
    Code :
    glm::dmat4(/* Any number other than 1 */);
    It also displays fine. It is ONLY identity matrices causing the problem, even though a matrix created as glm::dmat4() with any other number still in the end should be equivalent due to the perspective divide.

  5. #5
    Intern Contributor
    Join Date
    Sep 2013
    Posts
    70
    Maybe you want to read them to make sure the values are actually what you are expecting them to be.
    Maybe you "think" its the identity matrix but somewhere, in some hidden corner of the code, you change it without your own knowledge. (Happens to me all the time)

  6. #6
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    Quote Originally Posted by chbaker0 View Post
    Also, I just noticed that if I create my model matrix with
    Code :
    glm::dmat4(/* Any number other than 1 */);
    It also displays fine. It is ONLY identity matrices causing the problem, even though a matrix created as glm::dmat4() with any other number still in the end should be equivalent due to the perspective divide.
    you didn't supply the code, where you pass matrix as a uniform with glUniform* call. did you count the fact that you're using double-precision matrix in your c++ code? and also, do you use glm::value_ptr to pass matrix?

  7. #7
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Cornix: I actually did check that, I wrote it to output all the terms of the matrix just before sending it to the shader program, and it was correct...very odd.

    Nowhere-01:
    Here's the actual Uniform sending code:
    Here the wrapper class code
    Code :
    template <class T>
    class _UniformBase
    {
    protected:
        std::forward_list<std::pair<GLuint,GLint>> Uniforms;
        T Data;
     
        virtual void SetUniform(GLint) {/*Dummy*/};      // Must be implemented in child classes
     
    public:
     
        //..............other code...............
     
        void SetData(T Data_in)
        {
            if(Data_in != Data)
            {
                Data = Data_in;
                GLuint Initial;
                glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)(&Initial));
                GLuint Previous = Initial;
                for(auto &i : Uniforms)
                {
                    if(i.first != Previous)
                    {
                        glUseProgram(i.first);
                        Previous = i.first;
                    }
                    SetUniform(i.second);
                }
                if(Initial != Previous) glUseProgram(Initial);
            }
        }
    };
    Code :
    template <>
    class _Uniform<glm::mat4> : public _UniformBase<glm::mat4>
    {
    protected:
        void SetUniform(GLint Uniform_in)
        {
            glUniformMatrix4fv(Uniform_in, 1, GL_FALSE, glm::value_ptr(Data));
        }
    };
    for the mat4.
    Here's the actual drawing code for the sphere:
    Code :
        auto SphereDrawFunc =
        [&](const mat4 &Transform_in, const mat4 &NormalTranform_in)
        {
            SphereArray.Bind();
            Transform.SetData(Transform_in);
            glDrawElements(GL_TRIANGLES, ElementCount, GL_UNSIGNED_INT, 0);
        };
    Which gets called once per iteration of the main loop. Between setting the transform and sending it to the uniform, it simply gets casted from glm::dmat4 to glm::mat4.

  8. #8
    Intern Contributor
    Join Date
    Sep 2013
    Posts
    70
    You should print it out after sending it to the shader.
    Dont read the data that you put in, query the data directly from OpenGL and see what is inside.

  9. #9
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Oh, wow, I just found out what it was. For efficiency I set my Uniform class to update the uniform only if it is different from the last value it is set to. However, it is initialized to an identity matrix and the uniform isn't ever set before the first call. So, it ends up not ever setting it. Pretty stupid error haha.

    Also, it turned out that the big black sphere was simply because I initialized the TestMat incorrectly (should be mat4 TestMat = mat4(1.0f)) and I forgot to check the shader logs.
    Last edited by chbaker0; 12-23-2013 at 09:04 AM.

Posting Permissions

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