将图像从屏幕坐标转换为世界坐标

问题描述 投票:1回答:1

我正在尝试编写一个在给定屏幕坐标的情况下绘制图像的函数,并将其放置在OpenGL中的世界坐标中。

glm::vec3 CImage::showImage(float x, float y)
{
    float screenW = 1920.0f;
    float screenH = 1080.0f;
    float xPosition = x;
    float yPosition = y;
    xPosition = xPosition * 2 / screenW - 1;
    yPosition = yPosition * (-2 / screenH) + 1;

    glm::vec4 viewport = glm::vec4(0.0f, 0.0f, screenW, screenH);
    glm::mat4 projectionMatrix = glm::ortho(0.0f, screenW, screenH, 0.0f, -1.0f, 1.0f);
    glm::mat4 model = glm::mat4(1.0f);
    glm::vec2 pixel_pos = glm::vec2(xPosition, screenH - yPosition);
    glm::vec3 world = glm::unProject(glm::vec3(pixel_pos, 0), model, projectionMatrix, viewport);

    return world;
}

被:呼叫

glm::mat4 transform = glm::mat4(1.0f);
transform = glm::translate(transform, showImage(100, 150));//screen coordinates
glUseProgram(shaderProgram);
unsigned int transformLoc = glGetUniformLocation(shaderProgram, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

这是顶点着色器:

#version 330

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 transform;
void main() 
{
   gl_Position = transform * vec4(aPos, 1.0);
   TexCoord = vec2(aTexCoord.x, aTexCoord.y);
};

这是片段着色器:

#version 330

out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D texture_sampler;
void main() 
{
   FragColor = texture(texture_sampler, TexCoord);
};

根据图像大小,结果永远不会相同,如果将其放在中间(960、540),则可以工作,但是当尝试在左/上角或右/下角显示时,是一个烂摊子。我知道(glm::unproject)中有几个这样的问题,但是已经尝试了好几天解决它。

c++ opengl shader glm-math
1个回答
0
投票

回答我自己的问题:

glm::vec3 CImage::showImage(float x, float y)
{
    float screenW = 1920;
    float screenH = 1080;
    float xPosition = x;
    float yPosition = y;
    float sxImage = 100; 
    float syImage = 100; 

    xPosition = xPosition * 2 / screenW - 1;
    yPosition = yPosition * (-2 / screenH) + 1;
    glm::vec4 viewport = glm::vec4(0.0f, 0.0f, screenW, screenH);
    glm::mat4 projectionMatrix = glm::ortho(0.0f, screenW, screenH, 0.0f, -1.0f, 1.0f);
    glm::mat4 model = glm::mat4(1.0f);
    glm::vec2 pixel_pos = glm::vec2(xPosition, screenH - yPosition);
    pixel_pos = pixel_pos + glm::vec2(sxImage / screenW, syImage / screenH);
    glm::vec3 world = glm::unProject(glm::vec3(pixel_pos, 0), model, projectionMatrix, viewport);

    return world;
}
© www.soinside.com 2019 - 2024. All rights reserved.