gluLookAt() 在 OpenGL 中无效

Posted

技术标签:

【中文标题】gluLookAt() 在 OpenGL 中无效【英文标题】:gluLookAt() has no effect in OpenGL 【发布时间】:2019-07-12 12:26:11 【问题描述】:

我正在尝试使用 gluLookAt() 函数从另一侧查看正方形。 使用该功能后,没有任何变化,尽管我预计正方形的角会发生变化。 我将相机点设置在世界的最右边,并查看它的中心,即广场所在的位置。 他不得不向两边伸展。为什么没有任何变化?

代码:

#include "includes.h"

using namespace std;

constexpr auto FPS_RATE = 60;
int windowHeight = 600, windowWidth = 600, windowDepth = 600;

void init();
void idleFunction();
void displayFunction();
double getTime();

double getTime()

    using Duration = std::chrono::duration<double>;
    return std::chrono::duration_cast<Duration>(
        std::chrono::high_resolution_clock::now().time_since_epoch()
        ).count();


const double frame_delay = 1.0 / FPS_RATE;
double last_render = 0;

void init()

    glutDisplayFunc(displayFunction);
    glutIdleFunc(idleFunction);
    glViewport(0, 0, windowWidth, windowHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, -windowDepth / 2, windowDepth / 2);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);


void idleFunction()

    const double current_time = getTime();
    if ((current_time - last_render) > frame_delay)
    
        last_render = current_time;
        glutPostRedisplay();
    


void displayFunction()

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_POLYGON);
    gluLookAt(-300, 0, 0,
        0, 0, 0,
        0, 1, 0);
    glColor3f(1, 1, 1);
    glVertex3i(-150, 150, 0);
    glVertex3i(150, 150, 0);
    glVertex3i(150, -150, 0);
    glVertex3i(-150, -150, 0);
    glEnd();
    glutSwapBuffers();


int main(int argc, char* argv[])

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(windowWidth, windowHeight);
    glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight) / 2);
    glutCreateWindow("Window");
    init();
    glutMainLoop();
    return 0;

【问题讨论】:

【参考方案1】:

这个问题是因为gluLookAt() 是在glBegin/glEnd 序列中调用的。这是不允许的。您必须在 glBegin 之前致电 gluLookAt。 一旦由glBegin开始绘制图元,它只允许指定顶点坐标(glVertex)和更改属性(例如glColorglTexCoord ...),直到绘制结束(glEnd) . 所有其他指令将被忽略并导致 GL_INVALID_OPERATION 错误(错误代码 1282)。

进一步注意,glLookAt 没有设置当前矩阵。它定义了一个矩阵并将当前矩阵乘以新矩阵。设置矩阵模式(glMatrixMode)并在glLoadIdentity之前设置Identity matrixgluLookAt

带有视图矩阵

gluLookAt(-300, 0, 0, 0, 0, 0, 0, 1, 0);

您想“看到”任何东西,因为使用该矩阵,视线沿 x 轴设置,您从侧面看二维多边形。

注意,多边形是二维对象。如果您从正面、侧面(然后它是一条线且不可见)或从中间的方向看,物体的大小看起来会有所不同。 gluLookAt 的前 3 个参数定义了观察点,接下来的 3 个参数定义了您观察的点。从视点到您所看的点的矢量是视线。

可能你想沿着 z 轴看:

void displayFunction()

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, -300, 0, 0, 0, 0, 1, 0);    

    glBegin(GL_POLYGON);
    glColor3f(1, 1, 1);
    glVertex3i(-150, 150, 0);
    glVertex3i(150, 150, 0);
    glVertex3i(150, -150, 0);
    glVertex3i(-150, -150, 0);
    glEnd();

    glutSwapBuffers();

您使用Orthographic (parallel) projection。如果您使用Perspective projection,那么当到视点的距离增加时,对象的投影尺寸会减小。透视投影可以通过gluPerspective设置。例如:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, (double)windowWidth / windowHeight, 0.1, 600.0);

【讨论】:

我试过你的选项,但我只看到黑屏。 @是的,我扩展了答案。你必须gluLookAt(0, 0, -300, 0, 0, 0, 0, 1, 0); 我将glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, (double)window Width / window Height, 0.1, 600.0); 添加到我的init(); 函数中。在displayFunction(); 中,我在glClear(...) 之后和glEnable(...) 之前添加了glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, -300, 0, 0, 0, 0, 1, 0);。跑步时,我在中心呈正方形。 @Герман 阅读答案“...当到视点的距离增加时,物体的投影尺寸会减小...”。使用gluLookAt(0, 0, -50, 0, 0, 0, 0, 1, 0);,对象会增加。 感谢您的帮助。但是,在我看来,该程序的行为不正确。当您将相机至少向一侧移动一个像素时,正方形会过度拉伸。我在YouTube 上发布了一个关于这个问题的视频。如果您能看到它并向我解释为什么会发生这种情况,我会很高兴。谢谢。

以上是关于gluLookAt() 在 OpenGL 中无效的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 使用 gluLookat()

gluLookAt 似乎产生了错误的视图,OpenGL

两个Sphere和gluLookAt函数之间的OpenGL碰撞

OpenGL的gluLookAt和glOrtho的关系

OpenGL gluLookat 不适用于着色器

Opengl视点转换如何gluLookAt