我想旋转一个球体。并且灯应该在房间的固定位置。 但似乎光线不在固定位置,而是与球体一起旋转。 我试图把所有东西放在push / popmatrix中。没有帮助。 我读到了关于正常情况的内容,但我也读到了过度使用球体的自动过滤。
如何修复灯光位置?
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
float angletest = 1;
float winwidth, winheight;
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case'\033':
exit(0);
break;
}
}
void reshape(w, h)
GLsizei w;
GLsizei h;
{
int size;
winwidth = w;
winheight = h;
size = w>h ? h : w;
glViewport(0, 0, size, size);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, 1.0, 1.0f, 20.0f);
glutPostRedisplay();
}
void display(void)
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
GLUquadricObj *quadric;
quadric = gluNewQuadric();
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(0.5, 0, 0);
glRotatef(angletest, 0, 0, 1);
gluSphere(quadric, 0.2, 50, 50);
glPopMatrix();
glPushMatrix();
glColor3f(0, 1, 0);
glRotatef(angletest, 0, 0, 1);
glTranslatef(0, 0.5, 0);
glutSolidSphere(0.2, 50, 50);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void init()
{
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glClearColor(0, 0, 0, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 0, 0.5, 0, 1.0f };
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
}
void idle(void)
{
angletest = angletest + 0.05;
glutPostRedisplay();
}
void main(int argc, char** argv)
{
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("test");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
init();
glutMainLoop();
}
试图像下面提到的那样做,并把
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glRotatef之间的(angletest,0,0,1);和gluSphere(quadric,0.2,50,50); 但那并没有这样做。
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(0.5, 0, 0);
glRotatef(angletest, 0, 0, 1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
gluSphere(quadric, 0.2, 50, 50);
glPopMatrix();
实际上,我希望光源位于中间位置。但是,如果我把它放在0,0,0的位置,根本就没有光。 为了说明移动光线的意思,我在这里有三张照片。
light is in the left down corner
所以你可以看到它似乎与物体一起移动。 但我想要的是光线留在中间并为物体照明,就像它是太阳一样。
答案 0 :(得分:0)
抱歉,我的评论错了。我刚刚意识到你不使用矩阵堆栈来转换相机(模型视图中的视图部分),而是使用对象空间(模型部分)。在更改视图部件之后和更改模型部件之前,应调用glLightfv()
。但是你永远不会改变代码中的视图部分,所以设置一次光就足够了。
您的代码中还有另一个微妙的问题,这会导致此行为。看看你的reshape()
功能。您将矩阵模式更改为投影,并且永远不会将其更改回模型视图。因此,您应用的所有矩阵变换都将应用于投影矩阵。照明在视图空间中计算。由于您不更改模型视图矩阵,因此所有光照都在对象的坐标系中完成(假设此系统中的光位置)。然后投影矩阵旋转已经照明的物体,可能远离光线。
所以解决方案很简单:将矩阵模式切换回reshape()
函数中的模型视图。