FreshRSS

Zobrazení pro čtení

Jsou dostupné nové články, klikněte pro obnovení stránky.

How to set matrices for different objects, in OpenGL?

Not sure how to do it, since I'm only seeing one instance of matrix-use drawn (only one of the objects has an energy bar):

image

glDrawElementsInstanced(GL_TRIANGLES, this->energy.indices, GL_UNSIGNED_INT, this->energy.indiceArray, this->energy.instances);

Works fine for same type of objects, but on the image they are just place-holders.

I'm creating the matrix instance buffer object, along with VBO:

float* matrices = new float[this->energy.instances * 16];

for (int j = 0; j < this->energy.instances; j++) {
    drx::util::MAT4F mat;
    mat.LoadIdentity();
    for (int y = 0, c = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++, c++) {
            matrices[j * 16 + c] = mat.matrix[x][y];
        }
    }
}

glGenBuffers(1, &this->energy.IBO);
glBindBuffer(GL_ARRAY_BUFFER, this->energy.IBO);
glBufferData(GL_ARRAY_BUFFER, this->energy.instances * 16 * sizeof(float), matrices, GL_DYNAMIC_DRAW);
delete[] matrices;
for (int i = 0; i < 4; i++) {
    glEnableVertexAttribArray(2 + i);
    glVertexAttribPointer(2 + i, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void*)(i * 4 * sizeof(float)));
    glVertexAttribDivisor(2 + i, 1);
}

Updating:

glBindBuffer(GL_ARRAY_BUFFER, this->energy.IBO);
for (int i = 0; i < this->energy.instances; i++) {
    drx::util::MAT4F mat;
    mat.LoadIdentity();
    mat.Translate(this->lab->dob[i].pos.x, this->lab->dob[i].pos.y - 7.5f, 0.0f);
    for (int y = 0, c = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++, c++) {
            this->matrix[c] = mat.matrix[x][y];
        }
    }
    glBufferSubData(GL_ARRAY_BUFFER, 16 * i * sizeof(float), 16 * sizeof(float), this->matrix);
}

And drawing:

glUseProgram(this->energy.Program);
this->energy.vertex.SetMVP(ortho);
glBindVertexArray(this->energy.VAO);
glDrawElements(GL_TRIANGLES, this->energy.indices, GL_UNSIGNED_INT, this->energy.indiceArray);

2D Zoom to mouse point

So I'm trying to create a zoom function for my 2D camera.

The best result I've got so far is:

zooming

But something still feels off, and I just can't seem to pinpoint it.

My code currently, which simply takes the substraction between before and after zoom:

void Zoom(float value, float mx, float my, float w, float h) {
    float bmwx = (w - (w - mx)) * this->zoom, bmwy = (h - (h - my)) * this->zoom; // before
    if (value < 0.0f) this->zoom *= 0.9f;
    if (value > 0.0f) this->zoom *= 1.1f;
    float amwx = (w - (w - mx)) * this->zoom, amwy = (h - (h - my)) * this->zoom; // after
    
    this->center.x += amwx - bmwx;
    this->center.y += amwy - bmwy;
}

My other function, for matrix construction:

void Update(float mx, float my, float w, float h) {
    float hw = w * 0.5f, hh = h * 0.5f;
    float left = -hw + this->center.x;
    float right = hw + this->center.x;
    float top = -hh + this->center.y;
    float bottom = hh + this->center.y;

    this->ortho.InitOrthographic(drx::gfx::ogl::n, drx::gfx::ogl::f, left, right, top, bottom);
    this->mZoom.LoadIdentity();
    this->mZoom.Scale(this->zoom, this->zoom, this->zoom);
    this->matrix = this->ortho * this->mZoom;
}

Update, to current code (Update: which also fails if I move the central point):

void Zoom(float value, float mx, float my, float w, float h) {
    this->os.x += mx * this->zoom;
    this->os.y += my * this->zoom;
    if (value < 0.0f) this->zoom *= 0.75f;
    if (value > 0.0f) this->zoom *= 1.25f;
    this->os.x -= mx * this->zoom;
    this->os.y -= my * this->zoom;

}

void Update(float mx, float my, float w, float h) {
    float hw = w * 0.5f, hh = h * 0.5f;
    float left = -hw + this->center.x;
    float right = hw + this->center.x;
    float top = -hh + this->center.y;
    float bottom = hh + this->center.y;

    this->ortho.InitOrthographic(drx::gfx::ogl::n, drx::gfx::ogl::f, left, right, top, bottom);
    this->mZoom.LoadIdentity();
    this->mZoom.Scale(this->zoom, this->zoom, this->zoom);
    this->mZoom.Translate(this->os.x, this->os.y, 0.0f);
    this->matrix = this->ortho * this->mZoom;
}

more zooming

Mouse coordinates to world space offsetting?

so i'm trying to make a mouse to world space function, and I seem to always end up with the rays cast offsetting.

I've looked at numerous tutorials, tried numerous examples. Tried with glm, gluUnProject, but what ever I try I always seem to get similar results to what my function gets. Which looks like something below: offset

Not sure which part of code to paste, so,

The function itself:

drx::util::V3 MTW(double z) {
    double w = drx::gfx::canvas.w; // 640.0;
    double h = drx::gfx::canvas.h; // 480.0;
    double mx = drx::view::window.mouse.x;
    double my = drx::view::window.mouse.y;
    double x = (2.0 * mx) / w - 1.0;
    double y = 1.0 - (2.0 * my) / h;
    drx::util::V4 clip = {x, y, z, 1};
    drx::util::MAT4F viewInv = this->GetView().Inve(); // inverted view matrix
    drx::util::MAT4F projectionInv = this->projection.Inve(); // inverted projection matrix
    drx::util::V4 wld = viewInv * projectionInv * clip;
    wld = wld.Divide(wld.w);
    drx::util::V3 ray = { wld.x, wld.y, wld.z };
    return ray;
}

With given z value set to 1.0, I get what was displayed in the gif, but if I set z to -1.0, I get a tiny line:

tiny line

View matrix:

this->view.matrix[0][0] = this->right.x;
this->view.matrix[0][1] = this->right.y;
this->view.matrix[0][2] = this->right.z;
this->view.matrix[1][0] = this->up.x;
this->view.matrix[1][1] = this->up.y;
this->view.matrix[1][2] = this->up.z;
this->view.matrix[2][0] = this->front.x;
this->view.matrix[2][1] = this->front.y;
this->view.matrix[2][2] = this->front.z;
this->view.matrix[0][3] = -this->position.Dot(this->right);
this->view.matrix[1][3] = -this->position.Dot(this->up);
this->view.matrix[2][3] = -this->position.Dot(this->front);
this->view.matrix[3][3] = 1.0f;

Projection matrix:

float sf = tanf(fov * 0.5);
this->matrix[0][0] = 1.0f / (ar * sf);
this->matrix[1][1] = 1.0f / sf;
this->matrix[2][2] = -((f + n) / (f - n));
this->matrix[3][2] = -1.0f;
this->matrix[2][3] = -((2.0f * f * n) / (f - n));

The lines in the image and gif, mean, red == camera.front, blue == camera.up and green == camera.right vectors.

I'm not too sure what sort of lines I should be seeing, so if anyone can shed some light into all that, I'd be very grateful. Will provide more info, if asked.

Matrices for OpenGL shaders

So I'm trying to figure out the model, view and projection matrices. I can, with some effort, find my drawings (3x3x3 structure of cubes) in 3D space and it looks like:

result

The problem is, the cubes seem to be offset from the center (where the lines meet at 0, 0, 0), which is where around they're initially positioned, and don't really seem to be sticking to it when moving camera. All around while moving camera the cube movement is off, seems off and inverted.

The green area is the far end of the view frustum, and the near end is where the black lines meet.

So far, from what I've gathered, I'm passing to the shaders:

// The model matrix
model.position = { x * scale, y * scale, z * scale }; // 3 x 3 x 3, scale = 50.0
drx::util::MAT4F mModel;
drx::util::MAT4F mSize;
mModel.LoadIdentity();
mModel.Translate(model.position.x, model.position.y, model.position.z);
mSize.Scale(scale, scale, scale);
mModel = mModel.Add(mSize);

// from the MAT4F structure
void Translate(float x, float y, float z) {
    this->matrix[3][0] = x;
    this->matrix[3][1] = y;
    this->matrix[3][2] = z;
}

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

// The view matrix
m.LoadIdentity();
m.matrix[0][0] = this->right.x;
m.matrix[1][0] = this->right.y;
m.matrix[2][0] = this->right.z;
m.matrix[0][1] = this->up.x;
m.matrix[1][1] = this->up.y;
m.matrix[2][1] = this->up.z;
m.matrix[0][2] = this->front.x; //
m.matrix[1][2] = this->front.y; // Direction vector
m.matrix[2][2] = this->front.z; //
m.matrix[3][0] = this->position.x; //
m.matrix[3][1] = this->position.y; // Eye or camera position vector
m.matrix[3][2] = this->position.z; //
// The projection matrix
float sf = tanf(fov / 2.0f);
this->matrix[0][0] = 1.0f / (ar * sf);
this->matrix[1][1] = 1.0f / sf;
this->matrix[2][2] = -((f + n) / (f - n));
this->matrix[2][3] = -1.0f;
this->matrix[3][2] = -((2.0f * f * n) / (f - n));
this->matrix[3][3] = 1.0f;

And on vertex shader, I have:

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

out vec4 ourColor;
out vec2 texCoords;

uniform vec4 myColor;
uniform float scale;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;

uniform vec3 myOtherColor;

void main()
{
    vec4 myPos = vec4(aPos, 1.0);
    gl_Position = projection * view * model * myPos;
    ourColor = vec4(inColor, 1.0);
    texCoords = texCoord;
} 

Custom matrix structure with OpenGL shaders

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");  

OpenGL strange depth testing

Depth testing isn't working (hopefully the images below describe, I'll gladly describe more when asked) for me, and I can't seem to figure out why.

GL initialization:

glEnable(GL_CULL_FACE);
//glFrontFace(GL_CW);               
glDisable(GL_LIGHTING);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
glDepthFunc(GL_LESS);
//glDepthRange(-100.0, 100.0);

Pre-drawing:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(this->camera.zoom, drx::gfx::ogl::ar, -100.0, 100.0);
this->camera.CameraLookAt();

/* Camera function */
drx::util::SPOT center = this->position.Add(this->front);
gluLookAt(this->position.x, this->position.y, this->position.z, center.x, center.y, center.z, this->up.x, this->up.y, this->up.z);

Some drawing:

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tx.id);
glBegin(GL_TRIANGLE_FAN);
//glColor3ub(tri.color.red, tri.color.green, tri.color.blue);

glTexCoord2f(u[0], v[0]);
glVertex3d(a.x, a.y, a.z);
glTexCoord2f(u[1], v[1]);
glVertex3d(b.x, b.y, b.z);
glTexCoord2f(u[2], v[2]);
glVertex3d(c.x, c.y, c.z);

glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);

Which then result to:

result1

result2

If I disable depth testing and look at from just the right angle, I get:

result3

Update 1: Tried to set glClearDepth, still same.

glClearDepth(200.0);
❌