0
\$\begingroup\$

I have a MAT4 structure.

struct MAT4 {
    MAT4() {
        int c = 0;
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                this->matrix[x][y] = 0.0;
                this->pointer[c] = this->matrix[x][y];
                c++;
            }
        }
    }

    double matrix[4][4];
    double pointer[16]; // for opengl

    void LoadIdentity() {
        this->matrix[0][0] = 1.0;
        this->matrix[1][1] = 1.0;
        this->matrix[2][2] = 1.0;
        this->matrix[3][3] = 1.0;
    }

    void RotateX(double x, bool rads = false) {
        if (rads) x *= drx::rad;
        this->matrix[1][1] = cos(x);
        this->matrix[2][1] = -sin(x);
        this->matrix[2][2] = cos(x);
        this->matrix[1][2] = sin(x);
    }
    void RotateY(double y, bool rads = false) {
        if (rads) y *= drx::rad;
        this->matrix[0][0] = cos(y);
        this->matrix[2][0] = sin(y);
        this->matrix[2][2] = cos(y);
        this->matrix[0][2] = -sin(y);
    }
    void RotateZ(double z, bool rads = false) {
        if (rads) z *= drx::rad;
        this->matrix[0][0] = cos(z);
        this->matrix[1][0] = -sin(z);
        this->matrix[1][1] = cos(z);
        this->matrix[0][1] = sin(z);
    }

    void Translate(double x, double y, double z) {
        this->matrix[3][0] = x;
        this->matrix[3][1] = y;
        this->matrix[3][2] = z;
    }

    void Scale(double x, double y, double z) {
        this->matrix[0][0] = x;
        this->matrix[1][1] = y;
        this->matrix[2][2] = z;
    }

    double* Pointer() {
        int c = 0;
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                this->pointer[c] = this->matrix[x][y];
                c++;
            }
        }

        return this->pointer;
    }

    void Dump() {
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                std::cout << "\n [" << x << ", " << y << "]: " << this->matrix[x][y];
            }
        }
    }
};

Which I'm then trying to pass onto OpenGL:

drx::util::MAT4 trans;
trans.LoadIdentity();
trans.RotateY(45.0, true);
trans.Dump(); // outputs values as should
glUseProgram(this->P);
glUniformMatrix4dv(glGetUniformLocation(this->P, "transform"), 1, GL_FALSE, trans.Pointer());
glUseProgram(0);

My shader looks like:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 inColor;

out vec3 ourColor;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(aPos, 1.0);
    ourColor = inColor;
} 

If I take out the transforms from shaders, my triangle draws fine. But if I use the transforms my triangle disappears, is it offscreen or what could be happening?

Trying to follow this tutorial on Youtube.

Update: glGetError() gives 1282

std::cout << "\n " << glGetError(); // 0
int loc = glGetUniformLocation(this->P, "transform");
std::cout << "\n " << glGetError(); // 0
glUniformMatrix4dv(loc, 1, GL_FALSE, trans.Pointer());
std::cout << "\n " << glGetError(); // 1282

Update 2: Tried with glm, same result, no drawing.

Update 3: location for uniform variable returns -1

int loc = glGetUniformLocation(this->P, "transform"); // -1

/* defs */
extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");  
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Alright, so I managed to boil it down to types, the MAT4 (double) didn't work, so I made another structure MAT4F for floats and instantly it seems to work.

With some quick googling and noticing errors (from shaders), from what I can guess/tell, doubles weren't introduced until OpenGL 4.+, my version is:

#version 330 core // 3.3

But I could be wrong.

Anyway, I made the structure for float values (identical) and with the following code, it works:

glUseProgram(this->f.P);
drx::util::MAT4F trans, rotZ;
trans.LoadIdentity();
trans.Translate(-1, 0.0, 0.0);
rotZ.RotateZ(45.0, true);
trans = trans.Add(rotZ);
this->f.vertex.SetMat4f("transform", trans);
glUseProgram(0);

And I get the following result, which looks like a rotated rectangle, tranlasted in the negative X direction:

result

\$\endgroup\$
0
\$\begingroup\$

One thing that can cause problems with C++ vs. shader transform matrices is that there are two possible ways to lay out a matrix in memory - row major and column major. When going between shaders and C++ code, you may need to convert between the two layouts.

You can use the boolean parameter to glUniformMatrix4dv() to convert between the two layouts. Try passing GL_TRUE instead of GL_FALSE to transpose the matrix into the other layout:

glUniformMatrix4dv(loc, 1, GL_TRUE, trans.Pointer());
\$\endgroup\$
1
  • \$\begingroup\$ Unfortunately, in my case, it didn't work. \$\endgroup\$
    – Valtsuh
    Commented May 12 at 5:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .