OpenGL / GLUT - 在对象上绘图

时间:2011-12-28 12:03:10

标签: opengl glut

我正在导入一个目标文件,比方说它是一架飞机。我希望能够在飞机上画画,我似乎无法弄清楚它是如何完成的。知道鼠标点击的x和y坐标是非常简单的,但是z坐标怎么样?我需要能够进行某种射线追踪,射出射线并告诉我一旦它到达物体。我想知道的是对象上的点击的z坐标。我空间中没有其他物体是一个很好的假设。

2 个答案:

答案 0 :(得分:1)

谷歌搜索给了我这些好建议:

前段时间我使用它们(几乎所有这些)来创建我的应用程序。由于某些原因,我现在还没有得到这个应用程序,但我可以告诉你我的代码在2 ... 3小时内获得拾取点的3D矢量=)

如果你想实现“在对象上绘图”,我建议你需要找到拾取点的UV(纹理)坐标,然后对对象纹理执行一些绘制操作。

UPADTE:我的拣货功能实施

sf::Vector3f ScreenToSpace(int x, int y)
{
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetIntegerv(GL_VIEWPORT, viewport);

    winX = (float) x;
    winY = (float) viewport[3] - (float) y;
    glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

    return sf::Vector3f((float) posX, (float) posY, (float) posZ);
}

这里,sf :: Vector3f只是一个SFML Vector类。

答案 1 :(得分:1)

在鼠标下检索点的XYZ很简单。您不需要光线投射,只需要从光标下的帧缓冲区中检索深度值,然后执行gluUnProject

如果要在对象上绘画,可能需要修改纹理而不是几何体,因此您需要的主要是UV坐标,而不是XYZ。如果您的对象使用单个纹理绘制,那么我建议使用MRT(多个渲染目标)并在渲染场景期间将每像素UV坐标写入屏幕外缓冲区,以便您可以轻松阅读它们。 p>


回答您的进一步询问:

  

我想在对象上画一条线,所以我想得到多个XYZ并将它们连接在一起。我想在对象前面绘制线条,但非常非常接近它,就好像它在它上面一样(或实际上在它上面,无论哪种可能。)

如果你想在对象上“绘制”,那么你可能会遇到z-fighting(两个片段具有相同的深度值,导致不酷的伪像。

在前面画一点点就可以了。 (为了获得最佳效果,您可以将法线保存到屏幕外缓冲区,就像我之前提到过的UV一样,这样您就可以沿着曲面法线方向偏移线条,而不仅仅是朝向相机。) EM>

  

如何从帧缓冲区中检索深度值?

使用format = GL_DEPTH_COMPONENT尝试glReadPixels

  

2-如何修改纹理?

只需glTexImage*glTexSubImage*

  

此外,MRT渲染技术听起来非常复杂,我不是任何一个真正的专家。

你真的不需要成为专家:),MRT本身并不复杂(它分解为在屏幕缓冲区输出颜色值,同时将任何其他值输出到屏幕外缓冲区)。到目前为止我还没有实现它,但是一旦你掌握了着色器和帧缓冲对象(你应该尽快做到这一点,你应该非常容易,因为这就是你如何充分利用OpenGL!如果我进行OpenGL课程,着色器将是第二课) )。