C++ 如何从 3D 点获取屏幕坐标?OpenGL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3792481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:45:08  来源:igfitidea点击:

How to get Screen coordinates from a 3D Point? Opengl

c++opengl

提问by Aero

I've seen alot of Screen-Coordinate to world coordinate posts, but have not seen the opposite. Is there an easy way of getting screen coordinates from a 3d point, from any angle I view it from? I'm using C++ and opengl

我已经看到很多屏幕坐标到世界坐标帖子,但还没有看到相反的内容。有没有一种简单的方法可以从我查看的任何角度从 3d 点获取屏幕坐标?我正在使用 C++ 和 opengl

回答by Bahbar

erjot's answer is incomplete.

erjot 的回答是不完整的。

There are 2 additional things to take into account.

还有 2 件额外的事情需要考虑。

  1. with homogeneous = P . M . world, the homogeneousvector is a 4-d vector in homogeneous space. In particular, to bring it back to the [-1:1]^3 cube, you need to divide its first 3 coordinates by homogeneous.w. cube.x = homogeneous.x / homogeneous.w(what some people call the projection divide).
  2. You then need to transform the [-1:1]^3 cube to window coordinates by applying the Viewport transformation to it. window.x = viewport.x + viewport.width * (cube.x+1)/2
  1. homogeneous = P . M . world,所述homogeneous载体是在均相空间中的4-d载体。特别是,要将其带回 [-1:1]^3 立方体,您需要将其前 3 个坐标除以homogeneous.wcube.x = homogeneous.x / homogeneous.w(有些人称之为投影鸿沟)。
  2. 然后,您需要通过对其应用视口转换将 [-1:1]^3 立方体转换为窗口坐标。 window.x = viewport.x + viewport.width * (cube.x+1)/2

In case you care about the final Z, the transformation is not going through viewport, but DepthRange instead.

如果您关心最终的 Z,转换不是通过视口,而是通过 DepthRange。

回答by erjot

Screen-coordinates for a vertex is just a result of multiplication such vertex by its projection and modelview matrix:

顶点的屏幕坐标只是该顶点与其投影和模型视图矩阵相乘的结果:

screen_coordinates = projection_matrix * modelview_matrix * world_coordinates

screen_coordinates = projection_matrix * modelview_matrix * world_coordinates

You can do it by hand (especially if you're using some maths library for doing operations on matrices) or use gluProject, for example:

您可以手动完成(尤其是当您使用一些数学库对矩阵进行运算时)或使用 gluProject,例如:

std::array<GLfloat, 16> projection;
std::array<GLfloat, 16> modelview;
std::array<GLfloat, 3>  screen_coords;

glGetFloatv(GL_PROJECTION_MATRIX, projection.data());
glGetFloatv(GL_MODELVIEW_MATRIX, modelview.data());

gluProject(world_coords[0], world_coords[1], world_coords[2],
    modelview.data(), projection.data(),
    screen_coords.data(), screen_coords.data() + 1, screen_coords.data() + 2);

回答by Kaz

One another thing. Remember, gluProject gives coordinates where the beginning of coordinate system begins at the left bottom corner. Screen coordinates begin at the left top corner. To obtain proper values of screen coordinates value of y must be subtracted from height of the OpenGL device.

另一件事。请记住,gluProject 给出坐标系的起点从左下角开始的坐标。屏幕坐标从左上角开始。要获得适当的屏幕坐标值,必须从 OpenGL 设备的高度中减去 y 值。

For example in Qt GLWidget to draw a text in (0,1,2) world coordinates it goes:

例如,在 Qt GLWidget 中,在 (0,1,2) 世界坐标中绘制文本:

gluProject(0,1,2,modelMatrix,projMatrix,sc.x,sc.y,sc.z); renderText(sc.x,height()-sc.y,"(0,1,2)");

gluProject(0,1,2,modelMatrix,projMatrix,sc.x,sc.y,sc.z); renderText(sc.x,height()-sc.y,"(0,1,2)");