0
\$\begingroup\$

Heyho :)

I'm trying to convert world coordinates to screen coordinates. I have available: fov, screen width, screen height, camera position, camera angle and obviously the position of the object in world space.

This is what I tried:

glm::vec3 world_to_screen(glm::vec3 pos,
                          glm::vec3 cam_angle,
                          glm::vec3 cam_pos) {
    glm::mat4 projection = glm::perspective(
        glm::radians(FOV), (float)SCREEN_W / (float)SCREEN_H, NEAR, FAR);

    glm::mat4 model(1.0);

    model = glm::translate(model, cam_pos);

    model = glm::rotate(model, cam_angle.x, glm::vec3(1.0f, 0.0f, 0.0f));
    model = glm::rotate(model, cam_angle.y, glm::vec3(0.0f, 1.0f, 0.0f));
    model = glm::rotate(model, cam_angle.z, glm::vec3(0.0f, 0.0f, 1.0f));

    glm::mat4 view = glm::inverse(model);

    glm::mat4 modelview = view * model;

    return glm::project(pos, modelview, projection,
                        glm::vec4(0, 0, SCREEN_W, SCREEN_H));
}

However it is not working, the output screen coords are over 30000 (I don't have a 30k monitor...) and I'm not sure what I did wrong. There is a correlation though, sometimes the screen coords happen to be in my screen (I draw an indicator at the position to see if I did it right) and if the object moves the indicator also moves with (kinda) the same speed etc.

Help is very much appreciated :) Thanks a lot in advance!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Here is a working code, for your reference -- I got it at https://www.gamedev.net/forums/topic/708406-opengl-screen-to-world-coordinates-varying-eye-position-and-look_at-position/5432692/

void WorldToScreen (float screen[3], float world[3])
    {
        float s[4];
        s[0] = ( world[0] * MVP[0][0] ) + ( world[1] * MVP[1][0] ) + ( world[2] * MVP[2][0]) + MVP[3][0];
        s[1] = ( world[0] * MVP[0][1] ) + ( world[1] * MVP[1][1] ) + ( world[2] * MVP[2][1]) + MVP[3][1];
        s[2] = ( world[0] * MVP[0][2] ) + ( world[1] * MVP[1][2] ) + ( world[2] * MVP[2][2]) + MVP[3][2];
        s[3] = ( world[0] * MVP[0][3] ) + ( world[1] * MVP[1][3] ) + ( world[2] * MVP[2][3]) + MVP[3][3];   

        screen[0] = s[0] / s[3] * viewportWidth/2 + viewportWidth/2;
        screen[1] = s[1] / s[3] * viewportHeight/2 + viewportHeight/2;
        screen[2] = s[2] / s[3];
    }
    
    void ScreenToWorld (float world[3], float screen[3])
    {
        float s[3];
        s[0] = 2 * screen[0] / viewportWidth - 1;
        s[1] = 2 * screen[1] / viewportHeight - 1;
        s[2] = screen[2];

        float p[4];
        p[0] = ( s[0] * MVPinv[0][0] ) + ( s[1] * MVPinv[1][0] ) + ( s[2] * MVPinv[2][0]) + MVPinv[3][0];
        p[1] = ( s[0] * MVPinv[0][1] ) + ( s[1] * MVPinv[1][1] ) + ( s[2] * MVPinv[2][1]) + MVPinv[3][1];
        p[2] = ( s[0] * MVPinv[0][2] ) + ( s[1] * MVPinv[1][2] ) + ( s[2] * MVPinv[2][2]) + MVPinv[3][2];
        p[3] = ( s[0] * MVPinv[0][3] ) + ( s[1] * MVPinv[1][3] ) + ( s[2] * MVPinv[2][3]) + MVPinv[3][3];   

        float w = 1 / p[3];
        world[0] = p[0] * w;
        world[1] = p[1] * w;
        world[2] = p[2] * w;
    }
\$\endgroup\$

You must log in to answer this question.

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