Opengl视点转换如何gluLookAt
Posted
技术标签:
【中文标题】Opengl视点转换如何gluLookAt【英文标题】:Opengl viewpoint transformation how to gluLookAt 【发布时间】:2019-12-04 16:51:34 【问题描述】:我想通过我的键盘使用极坐标来操纵上、下、左和右相机点。
#include <stdlib.h>
#include <glut.h>
GLint TopLeftX, TopLeftY, BottomRightX, BottomRightY ;
static int HourOfDay = 0;
static int DayOfYear = 10;
void init(void)
glClearColor(0.0, 0.0, 0.0, 0.0);
void myDisplay(void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); // Origin
glClear(GL_DEPTH_BUFFER_BIT);
/* Sun */
glColor3f(1.0, 1.0, 0.0);
glutSolidSphere(1.0, 20, 10);
/* Mercury */
glPushMatrix();
glRotatef((GLfloat)DayOfYear, 0.0, 0.0, 1.0);
glTranslatef(3.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.87, 0.53, 0.25);
glutSolidSphere(0.3, 10, 2);
glPopMatrix();
/* Venus */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 195, 0.0, 0.0, 1.0);
glTranslatef(5.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.99, 0.91, 0.66);
glutSolidSphere(0.5, 10, 2);
glPopMatrix();
/* Earth */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 80, 0.0, 0.0, 1.0);
glTranslatef(7.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.47, 0.82, 0.98);
glutSolidSphere(0.5, 10, 2);
/* Earth's Moon 1*/
glPushMatrix();
glRotatef((GLfloat)DayOfYear, 0.0, 0.0, 1.0);
glTranslatef(0.7, 0.0, 0.0);
glColor3f(0.89, 0.93, 0.95);
glutSolidSphere(0.1, 5, 5);
glPopMatrix();
glPopMatrix();
/* Mars */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 275, 0.0, 0.0, 1.0);
glTranslatef(9.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.84, 0.16, 0.15);
glutSolidSphere(0.35, 10, 2);
glPopMatrix();
/* Jupiter */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 33, 0.0, 0.0, 1.0);
glTranslatef(11.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.93, 0.64, 0.27);
glutSolidSphere(1.0, 10, 2);
glPopMatrix();
/* Saturn */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 180, 0.0, 0.0, 1.0);
glTranslatef(15.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.92, 0.82, 0.45);
glutSolidSphere(0.9, 10, 2);
glPopMatrix();
/* Uranus */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 90, 0.0, 0.0, 1.0);
glTranslatef(17.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.64, 0.84, 0.78);
glutSolidSphere(0.8, 10, 2);
glPopMatrix();
/* Neptune */
glPushMatrix();
glRotatef((GLfloat)DayOfYear + 150, 0.0, 0.0, 1.0);
glTranslatef(20.0, 0.0, 0.0);
glRotatef((GLfloat)HourOfDay, 0.0, 0.0, 1.0);
glColor3f(0.29, 0.74, 0.95);
glutSolidSphere(0.25, 10, 2);
glPopMatrix();
glutSwapBuffers();
// Animation State
DayOfYear = (DayOfYear + 1) % 360;
HourOfDay = (HourOfDay + 5) % 360;
void Timer(int iUnused)
glutPostRedisplay();
glutTimerFunc(30, Timer, 0);
static float cam_axis_x = 0.0;
static float cam_axis_y = 0.0;
static float cam_axis_z = -50.0;
void reshape(int w, int h)
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.0, 90.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(cam_axis_x, cam_axis_y, cam_axis_z);
/*void reshape(int w, int h)
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLsizei)w / (GLsizei)h, 0.0, 90.0);
*/
void keyboard(unsigned char key, int x, int y)
switch (key)
case 'q': // Esc
exit(0);
break;
case '75': // left
break;
case '77': // right
break;
case '72': // up
break;
case '80': // down
break;
void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y)
if (Button == GLUT_LEFT_BUTTON && State == GLUT_DOWN)
TopLeftX = X;
TopLeftY = Y;
void MyMouseMove(GLint X, GLint Y)
BottomRightX = X;
BottomRightY = Y;
glutPostRedisplay();
int main(int argc, char** argv)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(reshape);
Timer(0);
glutKeyboardFunc(keyboard);
glutMouseFunc(MyMouseClick);
glutMotionFunc(MyMouseMove);
glutMainLoop();
return 0;
我想围绕太阳移动相机
你能告诉我gluLookAt
吗?
【问题讨论】:
myDisplay
末尾缺少一个glPopMatrix();
。 (与glPushMatrix(); // Origin
相反)
“你能告诉我关于 gluLookAt 的事吗?”听起来你需要一个教程而不是一个特定问题的答案。 *** 认为此类问题过于宽泛。
【参考方案1】:
我不知道你所说的极坐标是什么意思,通常是二维的。也许你的意思是球坐标。
方法完全相同:
假设您的太阳位于世界的起源处(目前确实如此)
你有两种方法
假设 Theta 是您希望相机绕太阳运行的角度 并且 Phi 是围绕您的 xAxis 框架的一些“俯仰”(您可能想要也可能不想要它)。
1) 使用基本公式计算相机的 x、y、z 位置: https://en.wikipedia.org/wiki/Spherical_coordinate_system
球坐标:
// r is the distance to the sun
cam_axis_x = r * sin(theta) * cos(phi);
cam_axis_y = r * r * cos(theta);
cam_axis_z = r * sin(theta) * sin(phi);
“极坐标”:
cam_axis_x = r * sin(theta);
cam_axis_z = r * cos(theta);
然后像以前一样应用翻译
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(cam_axis_x, cam_axis_y, cam_axis_z);
2) 将相机平移到原始位置后对其应用旋转:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(cam_axis_x, cam_axis_y, cam_axis_z);
glRotatef(0, theta, phi);
【讨论】:
以上是关于Opengl视点转换如何gluLookAt的主要内容,如果未能解决你的问题,请参考以下文章