我一直在努力解决这个问题:
绘制彩色立方体的程序,允许用户适当移动相机以进行透视观察。立方体也应该旋转。
我已经完成了编码,就在这里。它似乎工作正常,除了一个简单的问题:
//Program to draw a color cube and allow the user to move the camera suitably to experiment with perspective viewing
#include <stdio.h>
#include <glut.h>
float v[][3] = {{-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1},{-1,1,-1},{1,1,-1},{1,-1,-1},{-1,-1,-1}};
void drawPolygon(float a[3],float b[3],float c[3],float d[3])
{
glBegin(GL_POLYGON);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glVertex3fv(d);
glEnd();
glFlush();
}
void drawCube(float v[8][3])
{
glColor3f(1,0,0);
drawPolygon(v[0],v[1],v[2],v[3]);
glColor3f(0,1,0);
drawPolygon(v[0],v[1],v[6],v[7]);
glColor3f(0,0,1);
drawPolygon(v[7],v[6],v[5],v[4]);
glColor3f(1,1,0);
drawPolygon(v[2],v[3],v[4],v[5]);
glColor3f(0,1,1);
drawPolygon(v[1],v[2],v[5],v[6]);
glColor3f(1,0,1);
drawPolygon(v[0],v[3],v[4],v[7]);
glFlush();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
//glRotatef(60,1,1,0);
drawCube(v);
glFlush();
}
void reshape(int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2,2,-2,2,-2,2);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void mouse(int btn,int state,int x,int y)
{
if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
glRotatef(2,1,0,0);
if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
glRotatef(2,0,1,0);
if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
glRotatef(2,0,0,1);
glutPostRedisplay();
}
float ex=0,ey=0,ez=-10,cx=0,cy=0,cz=0,ux=0,uy=1,uz=0;
void keyboard(unsigned char key,int x,int y)
{
if(key == 'x')
ex += 0.1;
if(key == 'X')
ex -= 0.1;
if(key == 'y')
ey += 0.1;
if(key == 'Y')
ey -= 0.1;
if(key == 'z')
ez += 0.1;
if(key == 'Z')
ez -= 0.1;
glMatrixMode(GL_PROJECTION);
gluLookAt(ex,ey,ez,cx,cy,cz,ux,uy,uz);
glutPostRedisplay();
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("spin cube");
glClearColor(1,1,1,0);
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
通过鼠标单击旋转立方体
相机移动x / X y / Y z / Z
但问题是,当我第一次按某个键时,显示屏会消失。然后第二次它正确移动相机。为什么?我希望相机只是移动而不是消失显示。有什么问题?
答案 0 :(得分:2)
您的计划中有两个错误:
两者都是根本错误的。这是您的代码的更正版本:
//Program to draw a color cube and allow the user to move the camera suitably to experiment with perspective viewing
#include <stdio.h>
#include <glut.h>
float v[][3] = {{-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1},{-1,1,-1},{1,1,-1},{1,-1,-1},{-1,-1,-1}};
void drawPolygon(float a[3],float b[3],float c[3],float d[3])
{
glBegin(GL_POLYGON);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glVertex3fv(d);
glEnd();
}
void drawCube(float v[8][3])
{
glColor3f(1,0,0);
drawPolygon(v[0],v[1],v[2],v[3]);
glColor3f(0,1,0);
drawPolygon(v[0],v[1],v[6],v[7]);
glColor3f(0,0,1);
drawPolygon(v[7],v[6],v[5],v[4]);
glColor3f(1,1,0);
drawPolygon(v[2],v[3],v[4],v[5]);
glColor3f(0,1,1);
drawPolygon(v[1],v[2],v[5],v[6]);
glColor3f(1,0,1);
drawPolygon(v[0],v[3],v[4],v[7]);
}
float ex=0,ey=0,ez=-10,cx=0,cy=0,cz=0,ux=0,uy=1,uz=0;
void display()
{
int win_width, win_height;
win_width = glutGet(GLUT_WINDOW_WIDTH);
win_height = glutGet(GLUT_WINDOW_HEIGHT);
glViewport(0,0,width,height);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2,2,-2,2,-2,2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(ex,ey,ez,cx,cy,cz,ux,uy,uz);
glRotatef(rot_x,1,0,0);
glRotatef(rot_y,0,1,0);
glRotatef(rot_z,0,0,1);
glColor3f(1,0,0);
//glRotatef(60,1,1,0);
drawCube(v);
glFinish();
}
void mouse(int btn,int state,int x,int y)
{
if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
rot_x += 2;
if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
rot_y += 2;
if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
rot_z += 2;
glutPostRedisplay();
}
void keyboard(unsigned char key,int x,int y)
{
if(key == 'x')
ex += 0.1;
if(key == 'X')
ex -= 0.1;
if(key == 'y')
ey += 0.1;
if(key == 'Y')
ey -= 0.1;
if(key == 'z')
ez += 0.1;
if(key == 'Z')
ez -= 0.1;
glutPostRedisplay();
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("spin cube");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
答案 1 :(得分:1)
gluLookAt
不应该进入投影矩阵,而应该进入模型视图。我还建议你跟踪你的立方体旋转和眼睛位置,并将它们应用到显示功能中:
//Program to draw a color cube and allow the user to move the camera suitably to experiment with perspective viewing
#include <stdio.h>
#include <glut.h>
float ex=0,ey=0,ez=-10,cx=0,cy=0,cz=0,ux=0,uy=1,uz=0;
float cubex=0,cubey=0,cubez=0;
float v[][3] = {{-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1},{-1,1,-1},{1,1,-1},{1,-1,-1},{-1,-1,-1}};
void drawPolygon(float a[3],float b[3],float c[3],float d[3])
{
glBegin(GL_POLYGON);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glVertex3fv(d);
glEnd();
}
void drawCube(float v[8][3])
{
glColor3f(1,0,0);
drawPolygon(v[0],v[1],v[2],v[3]);
glColor3f(0,1,0);
drawPolygon(v[0],v[1],v[6],v[7]);
glColor3f(0,0,1);
drawPolygon(v[7],v[6],v[5],v[4]);
glColor3f(1,1,0);
drawPolygon(v[2],v[3],v[4],v[5]);
glColor3f(0,1,1);
drawPolygon(v[1],v[2],v[5],v[6]);
glColor3f(1,0,1);
drawPolygon(v[0],v[3],v[4],v[7]);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(ex,ey,ez,cx,cy,cz,ux,uy,uz);
glRotatef(cubex, 1, 0, 0);
glRotatef(cubey, 0, 1, 0);
glRotatef(cubez, 0, 0, 1);
glColor3f(1,0,0);
//glRotatef(60,1,1,0);
drawCube(v);
glFinish();
}
void reshape(int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2,2,-2,2,-2,2);
glutPostRedisplay();
}
void mouse(int btn,int state,int x,int y)
{
if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
cubex += 2;
if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
cubey += 2;
if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
cubez += 2;
glutPostRedisplay();
}
void keyboard(unsigned char key,int x,int y)
{
if(key == 'x')
ex += 0.1;
if(key == 'X')
ex -= 0.1;
if(key == 'y')
ey += 0.1;
if(key == 'Y')
ey -= 0.1;
if(key == 'z')
ez += 0.1;
if(key == 'Z')
ez -= 0.1;
glutPostRedisplay();
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("spin cube");
glClearColor(1,1,1,0);
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
这并非100%等同于您最初尝试实现的目标,因为它分别在x,y和z轴周围应用了三个累积的连续旋转,而不是增量旋转。
此外,您不需要所有glFlush
次调用,在渲染结束时对glFinish
的单次调用应该足够,甚至更好;交换到双缓冲渲染并改为使用glutSwapBuffers
。