gluLook在绘制形状后无法正常工作

Dia*_*ame 0 c++ opengl

我真的很困惑如何gluLookAtglOrthogluPersective一起工作.这是问题所在.

我在-5轴的z轴上绘制了一个2D三角形和一个2D五边形.

//pentagon
glVertex3f(0.5f, 0.5f, -5.0f);
glVertex3f(1.5f, 0.5f, -5.0f);
glVertex3f(0.5f, 1.0f, -5.0f);

glVertex3f(0.5f, 1.0f, -5.0f);
glVertex3f(1.5f, 0.5f, -5.0f);
glVertex3f(1.5f, 1.0f, -5.0f);

glVertex3f(0.5f, 1.0f, -5.0f);
glVertex3f(1.5f, 1.0f, -5.0f);
glVertex3f(1.0f, 1.5f, -5.0f);

//Triangle
glVertex3f(-0.5f, 0.5f, -5.0f);
glVertex3f(-1.0f, 1.5f, -5.0f);
glVertex3f(-1.5f, 0.5f, -5.0f);
Run Code Online (Sandbox Code Playgroud)

然后我定义我的相机位置(0,0,-10)和透视

//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
gluLookAt(0, 0, -10, 0, 0, -200, 0, 1, 0);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective

//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(45.0,                  //The camera angle
    (double)w / (double)h, //The width-to-height ratio
    1.0,                   //The near z clipping coordinate
    5.2);                //The far z clipping coordinate
Run Code Online (Sandbox Code Playgroud)

根据我的理解,我在场景中什么都看不到.但是,由于对象是在-5 z轴中定义的,因此摄像机位于-10 z轴,并且它看起来是负z轴.因此,物体应该在相机后面.但为什么我仍然能看到场景中的物体? 在此输入图像描述

同样地,当我在正面z轴上定义我的相机时,我仍然可以看到物体.为什么?

另一个问题是为什么我将远z剪裁坐标设置为5后可以看到对象?

有谁能解释一下?

我的完整代码:

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

using namespace std;

//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
  int x, int y) {    //The current mouse coordinates
  switch (key) {
  case 27: //Escape key
    exit(0); //Exit the program
  }
}

//Initializes 3D rendering
void initRendering() {
  //Makes 3D drawing work when something is in front of something else
  glEnable(GL_DEPTH_TEST);
}

//Called when the window is resized
void handleResize(int w, int h) {
  //Tell OpenGL how to convert from coordinates to pixel values
  glViewport(0, 0, w, h);

  gluLookAt(0, 0, -10, 0, 0, -200, 0, 1, 0);

  glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective

  //Set the camera perspective
  glLoadIdentity(); //Reset the camera
  gluPerspective(45.0,                  //The camera angle
    (double)w / (double)h, //The width-to-height ratio
    1.0,                   //The near z clipping coordinate
    5.2);                //The far z clipping coordinate
}

//Draws the 3D scene
void drawScene() {
  //Clear information from last draw
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


  glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
  glLoadIdentity(); //Reset the drawing perspective

  glBegin(GL_QUADS); //Begin quadrilateral coordinates

  //Trapezoid
  glVertex3f(-0.7f, -1.5f, -5.0f);
  glVertex3f(0.7f, -1.5f, -5.0f);
  glVertex3f(0.4f, -0.5f, -5.0f);
  glVertex3f(-0.4f, -0.5f, -5.0f);

  glEnd(); //End quadrilateral coordinates

  glBegin(GL_TRIANGLES); //Begin triangle coordinates

  //Pentagon
  glVertex3f(0.5f, 0.5f, -5.0f);
  glVertex3f(1.5f, 0.5f, -5.0f);
  glVertex3f(0.5f, 1.0f, -5.0f);

  glVertex3f(0.5f, 1.0f, -5.0f);
  glVertex3f(1.5f, 0.5f, -5.0f);
  glVertex3f(1.5f, 1.0f, -5.0f);

  glVertex3f(0.5f, 1.0f, -5.0f);
  glVertex3f(1.5f, 1.0f, -5.0f);
  glVertex3f(1.0f, 1.5f, -5.0f);

  //Triangle
  glVertex3f(-0.5f, 0.5f, -5.0f);
  glVertex3f(-1.0f, 1.5f, -5.0f);
  glVertex3f(-1.5f, 0.5f, -5.0f);

  glEnd(); //End triangle coordinates

  glutSwapBuffers(); //Send the 3D scene to the screen
}

int main(int argc, char** argv) {
  //Initialize GLUT
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(400, 400); //Set the window size

  //Create the window
  glutCreateWindow("Basic Shapes - videotutorialsrock.com");
  initRendering(); //Initialize rendering

  //Set handler functions for drawing, keypresses, and window resizes
  glutDisplayFunc(drawScene);
  glutKeyboardFunc(handleKeypress);
  glutReshapeFunc(handleResize);

  glutMainLoop(); //Start the main loop.  glutMainLoop doesn't return.
  return 0; //This line is never reached
}
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 5

你说的是:

我画了一个2D三角形和一个二维五边形在z轴-5
...
然后我定义我的相机位置(0,0,-10)和透视

如果那真的是你正在进行操作的顺序,那那就是罪魁祸首.OpenGL是基于命令的API,而不是场景图.调用glVertex(x, y, z)并不意味着" x, y, z场景中有一个带坐标的顶点".这意味着" 现在去坐标绘制一个verex x, y, z." 这意味着顶点由模型视图和投影矩阵调用激活.glVertex()

换句话说,您使用默认的模型视图和投影矩阵发出顶点,因此它们会在屏幕上正常绘制.然后你改变模型视图和投影; 如果你继续发出更多顶点,它们将被这些新的模型视图和投影值转换.但之前发布的已经在屏幕上并且不受影响.

换句话说,从绘图函数中删除这两行:

glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
Run Code Online (Sandbox Code Playgroud)

评论似乎很好地表明了这个问题.


最常见的设置是发出任何渲染命令之前,在调整大小挂钩中定义投影矩阵(因为它取决于宽高比),以及绘制函数中的视图矩阵(=摄像机位置和方向).

正如@datenwolf在评论中正确指出的那样,这是单视图渲染的常见设置.如果您有多个视口,则每个视口可能需要不同的投影矩阵,在这种情况下,您需要在发布基元之前在渲染代码中设置投影矩阵和视图矩阵.