openGL使用固定灯光旋转球体

openGL使用固定灯光旋转球体,opengl,Opengl,我想旋转一个球体。灯应该在房间的固定位置。 但是,似乎光线不是在固定的位置,而是随着球体旋转。 我试着把所有的东西都放进推送矩阵。没用。 我读到了关于正常的,但我也读到了glut是用球体自动完成的 我怎样才能固定灯的位置 #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <gl\glut.h> #include <stdio.h> #include

我想旋转一个球体。灯应该在房间的固定位置。 但是,似乎光线不是在固定的位置,而是随着球体旋转。 我试着把所有的东西都放进推送矩阵。没用。 我读到了关于正常的,但我也读到了glut是用球体自动完成的

我怎样才能固定灯的位置

#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();

}
glRotatef(角度测试,0,0,1)之间;和胶球(二次曲面,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的位置,就没有光了。 为了弄清楚我所说的移动光是什么意思,我这里有三张图片

所以你可以看到,光线似乎在随着物体移动。
但我想要的是光线停留在中间,给物体以光,就像太阳一样。

<对不起,我的评论是错误的。我刚刚意识到,您没有使用矩阵堆栈来变换摄影机(模型视图中的视图部分),而是对象空间(模型部分)
glLightfv()
应在更改视图零件之后和更改模型零件之前调用。但您永远不会更改代码中的视图部分,因此只需设置一次灯光即可

代码中还有另一个微妙的问题,导致了这种行为。看看您的
重塑()函数。将“矩阵”模式更改为“投影”,而从不将其更改回“模型视图”。因此,应用的所有矩阵变换都将应用于投影矩阵。照明是在视图空间中计算的。由于不更改模型视图矩阵,因此所有照明都在对象的坐标系中完成(假定灯光在该系统中的位置)。然后,投影矩阵旋转已照亮的对象,可能远离灯光


因此,解决方案很简单:在
重塑()
函数中将矩阵模式切换回模型视图。

您使用的是传统的固定函数OpenGL管道,它已经被弃用了八年多。你应该切换到现代OpenGL的可编程管道。可能是@NicoSchertler的副本我以前读过这个线程。但是我不太确定我在哪里设置了模型视图矩阵,并且必须编写glLightfv(GL_LIGHT0,GL_POSITION,light_POSITION);再一次。走出车站,我试着把它放在任何可能的地方。但是没有变化。介于
glRotatef()
gluSphere()
之间;gl3f(0,0,1);glTranslatef(0.5,0,0);glRotatef(角度测试,0,0,1);glLightfv(GLU灯0、GLU位置、灯位置);胶球(二次曲面,0.2,50,50);glPopMatrix();但这并不意味着感谢你的回答。不幸的是,当我这样写的时候:glMatrixMode(GL_投影);glLoadIdentity();(40,1.0,1.0f,20.0f);glMatrixMode(GLU模型视图);glLoadIdentity();再发现();我再也看不到任何东西了,因为你现在有了一个以前没有的透视矩阵(你通过在
display()
中调用
glLoadIdentity()
删除了它)。删除透视变换,你应该会再次看到一些东西。谢谢。就是这样。我还需要删除glLightfv(GL_LIGHT0,GL_POSITION,light_POSITION);两次。但现在它起作用了。谢谢
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();