所以我决定学习OpenGL,我要做的第一件事就是深入了解基础知识。在这种情况下,我想熟悉OpenGL坐标系和摄像机定位。
以下是关于OpenGL的两个相关事实:我知道这一点:
其坐标轴形成右手坐标系
默认情况下,摄像机位于原点,并指向z轴的负方向:
首先,一个概念性问题:假设相机后面的物体不可见(意味着物体坐标必须至少满足z <0),我是对的吗?
第二次,关于我在标题中提到的奇怪相机行为的问题。我写了一个简单的OpenGL程序,绘制一个中心位于(0,0,0)的立方体,并允许我实时翻译相机。这就是我所拥有的:
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
函数中与OpenGL相关的代码:
<...>
HGLRC openGLContext = wglCreateContext(hDC);
wglMakeCurrent(hDC, openGLContext);
if (Win32LoadOpenGLFunctions())//fragment-related additon
initOpenGL();
<...>
initOpenGL()
函数中的代码:
static void initOpenGL()
{
glEnable(GL_DEPTH_TEST);
}
draw()
函数中的代码:
void draw()
{
glViewport(0, 0, width, height);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, 5, -5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, test);//translate the camera along the z-axis
glBegin(GL_TRIANGLES);
Cube(1);
glEnd();
glFlush();
}
test
函数中的参数draw()
被绑定到按键,因此我可以测试当我沿z轴平移相机时屏幕输出的变化。
Cube()
函数如下所示:
void Cube(float a)
{
float A = a * 0.5f;
//red face
glColor3f(1, 0, 0);
glVertex3f(A, A, A);
glVertex3f(-A, -A, A);
glVertex3f(A, -A, A);
glVertex3f(A, A, A);
glVertex3f(-A, A, A);
glVertex3f(-A, -A, A);
//blue face
glColor3f(0, 0, 1);
glVertex3f(A, A, -A);
glVertex3f(-A, -A, -A);
glVertex3f(A, -A, -A);
glVertex3f(A, A, -A);
glVertex3f(-A, A, -A);
glVertex3f(-A, -A, -A);
//yellow face
glColor3f(1, 1, 0);
glVertex3f(A, A, A);
glVertex3f(A, A, -A);
glVertex3f(-A, A, A);
glVertex3f(-A, A, A);
glVertex3f(A, A, -A);
glVertex3f(-A, A, -A);
//cyan face
glColor3f(0, 1, 1);
glVertex3f(A, -A, A);
glVertex3f(A, -A, -A);
glVertex3f(-A, -A, A);
glVertex3f(-A, -A, A);
glVertex3f(A, -A, -A);
glVertex3f(-A, -A, -A);
//green face
glColor3f(0, 1, 0);
glVertex3f(A, A, A);
glVertex3f(A, -A, A);
glVertex3f(A, -A, -A);
glVertex3f(A, A, A);
glVertex3f(A, -A, -A);
glVertex3f(A, A, -A);
//orange face
glColor3f(1, 0.67, 0);
glVertex3f(-A, A, A);
glVertex3f(-A, -A, A);
glVertex3f(-A, -A, -A);
glVertex3f(-A, A, A);
glVertex3f(-A, -A, -A);
glVertex3f(-A, A, -A);
}
这张照片显示了我假设发生的事情:
在这张照片中,我们正在俯视立方体。由于我指定了具有5和-5的正交投影作为近和远裁剪值,因此观看体积是从z = 5延伸到z = -5的框。立方体在z = 0.5处具有“红色”面,在z = -0.5处具有“蓝色”面。相机最初位于(0,0,0),这意味着保持立方体。因为它看着“蓝色”的脸,我应该看到一个蓝色的方块。
如果我将相机转向“蓝色”脸部(test
&lt; 0),我预计test
&lt; test
时,“蓝色”脸会消失。 -0.5因为它落后于相机。当翻译成“红色”面(test
&gt; 0)时,我希望DEPTH_TEST
&gt;时屏幕上的蓝色方块变为红色。 0.5(因为相机位于“红色”面前,阻挡了“蓝色”面并且test
打开了)。当test
&gt; 5.0屏幕应该变黑,因为相机在观看体积之外。
但事实并非如此。当test
从0变为5.5时,“蓝色”面部可见,此时它会消失。将{{1}}从0减少到约-4.5会显示“蓝色”面,然后它会切换到“红色”,在约-5.5时消失。
有什么想法吗?
-
相关问题 - 为什么它看起来像一个矩形而不是一个正方形?我没有看到我在代码中引入这样的透视图。正交不应使正方形看起来像矩形afaik。
答案 0 :(得分:0)
(完全披露,我不是OpenGL专家,我只是玩了一下)
第一个问题:你的直觉是正确的,相机背后的物体将不可见。因此,对于默认相机,位于z的对象> 0将不可见。
第二个问题:您对相机相对于正交观看体积的位置的解释是不正确的。通过定义观看音量,您可以有效地移动相机。相机位于观看体积的后面,在这种情况下,z = 5.0。
通过更改测试值,您将沿z轴移动查看体积。当测试&lt; -4.5,您已将观察体积移动到红色表面之外,因此蓝色表面变得可见。当测试&lt; 5.5,您已将观察体积移动到蓝色表面之外,因此两个表面都不再可见。
相关问题:相机所在的观看体积的背面是正方形。但是,显示相机所看到的内容的窗口是一个矩形,因此它会从相机中拉伸图像。如果更改查看体积的大小或窗口的大小以使宽度和高度匹配,则表面将显示为完美的正方形。