在OpenGL中设置相机

时间:2009-11-04 10:30:08

标签: c++ opengl sdl

我一直在研究游戏引擎。我刚开始只使用SDL的2D图形,但我已经慢慢地使用OpenGL转向3D功能。我见过的关于“如何完成工作”的大部分文档都使用了我没有使用的GLUT。

问题是如何在OpenGL中创建一个“相机”,我可以在3D环境中移动并正确显示3D模型以及精灵(例如,具有固定位置和旋转的精灵)。为了在OpenGL摄像机中设置摄像机以及调用它们的顺序,我应该关注哪些功能?

以下是一些背景信息,可以说明我想要一台真正的相机。

为了绘制一个简单的精灵,我从SDL表面创建一个GL纹理,然后将它绘制到(SpriteX-CameraX)和(SpriteY-CameraY)坐标的屏幕上。这样可以正常工作但是当朝着实际的3D模型移动时,它不能正常工作。摄像机位置是一个自定义矢量类(即不使用它的标准库),具有X,Y,Z整数分量。

我有一个由三角形组成的3D立方体,我自己可以绘制并旋转它,我可以通过在绘制模型时传入相机位置来实际移动立方体(尽管是以一种尴尬的方式)使用位置矢量的那些分量来计算模型位置。当我转动模型时,这种方法会出现问题。模型的起源不是模型本身,而是似乎是屏幕的起源。一些谷歌搜索告诉我,我需要保存模型的位置,围绕原点旋转,然后将模型恢复到其原始位置。

我没有通过计算新顶点来传递我的相机的位置并计算应该在视口中绘制的位置,而是想我会创建一个OpenGL“相机”来为我这样做,所以我需要做的一切是我的Camera对象的坐标传递到OpenGL相机,它会自动翻译视图。如果您使用GLUT,这个任务似乎非常简单,但我不确定如何使用OpenGL设置相机。

编辑#1(在评论之后): 根据一些建议,这是在我的程序中调用的更新方法。它已更新,以创建透视和视图矩阵。所有绘图都在调用之前发生。当OpenGL执行时(减去缓冲区交换),会执行一组类似的方法。 x,y,z坐标是相机及其位置矢量的直线实例。如果摄像机处于(256,32,0),那么256,32和0将被传递到Update方法。目前,z设置为0,因为此时无法更改该值。绘制的3D模型是位置X = 320,Y = 240,Z = -128的一组顶点/三角形+法线。当程序运行时,这是FILL模式,然后是LINE模式和FILL after movement中的另一个模式,当我将相机向右移动一点时。它喜欢Normal可能是原因,但我认为它还有更多与我失去一些非常重要的东西或者不完全理解glFrustum的NEAR和FAR参数实际上做了什么。

在我实现这些更改之前,我正在使用glOrtho并正确呈现了多维数据集。现在,如果我切换回glOrtho,一个面部呈现(绿色)并且旋转非常奇怪 - 可能是由于翻译。立方体有6种不同的颜色,每边一个。红色,蓝色,绿色,青色,白色和紫色。

int VideoWindow::Update(double x, double y, double z)
{
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glFrustum(0.0f, GetWidth(), GetHeight(), 0.0f, 32.0f, 192.0f);


    glMatrixMode( GL_MODELVIEW );

    SDL_GL_SwapBuffers();  
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glRotatef(0, 1.0f, 0.0f, 0.0f);
    glRotatef(0, 0.0f, 1.0f, 0.0f);
    glRotatef(0, 0.0f, 0.0f, 1.0f);
    glTranslated(-x, -y, 0);

    return 0;
}

编辑决赛: 问题结果是glFrustum的Near和Far参数以及glTranslated的Z值存在问题。虽然更改值已修复它,但我可能需要更多地了解这两个函数之间的关系。

3 个答案:

答案 0 :(得分:4)

您需要一个视图矩阵和一个投影矩阵。您可以采用以下两种方式之一:

  1. 使用自己的库计算矩阵后,使用glMatrixMode()glLoadMatrixf()自行加载矩阵。

  2. 使用glMatrixMode(GL_MODELVIEW)glTranslate() / glRotate()的组合来创建视图矩阵,并使用glMatrixMode(GL_PROJECTION)glFrustum()来创建投影矩阵。请记住 - 您的视图矩阵是相机位置的负向平移(因为它应该将世界移动到相对于相机原点的位置),以及应用的任何旋转(俯仰/偏航)。

  3. 希望这有帮助,如果我有更多时间,我会给你写一个正确的例子!

答案 1 :(得分:2)

你必须使用矩阵堆栈作为对象层次结构,

但摄像机位于层次结构中,因此您必须在绘制对象之前将逆变换放在堆栈上,因为openGL仅使用从3D到相机的矩阵。

答案 2 :(得分:1)

如果你还没有检查,那么可能会看下面的项目会详细解释“tsalter”在他的帖子中写的内容。

来自OGL SDK(CodeColony)的

Camera

另请参阅红皮书以获取有关观看的说明以及模型视图和投影矩阵如何帮助您创建相机。首先是实际相机与OpenGL API相对应的良好比较。 Chapter 3 - Viewing