如何在旋转对象时在OpenGL中固定光源?

Att*_*Kun 5 opengl lighting

我有一个glutSolidTeapot(根据opengl.org自动生成表面法线)和一个发射漫射光的光源.当我尝试旋转茶壶时出现问题:似乎光源也在进行旋转,而不是保持在我定义的相同位置(它基本上跟随茶壶).正如你在我的代码中看到的那样,我只在初始化时修改了光照位置,所以它不受glRotatef()的影响,因为它设置光位置后被调用.

尽管花了很多时间试图解决这个问题,我真的不知道这种行为可归因于什么.

粘贴glEnable(GL_NORMALIZE); 在初始化中也没有解决问题.

我认为所需的输出应该是一个带有光泽右侧的茶壶(因为光线来自那个方向),无论茶壶旋转的角度是多少.

如果要测试我的代码,请按空格键旋转茶壶.

#include <math.h>
#include <stdlib.h>

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#include <windows.h>     
#endif

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>     

void onInitialization( ) { //creating the light source
 glEnable(GL_LIGHTING);
 glEnable(GL_DEPTH_TEST); 

 GLfloat diffuse[]={0.8, 0.8, 0.8, 1.0};
 GLfloat pos[]={0.5, 0.0, 0.8, 0.0};

 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
 glLightfv(GL_LIGHT0, GL_POSITION, pos);

 glEnable(GL_LIGHT0);

 glRotatef(-90, 1, 0, 0); //we want to see the top of the teapot
}

void onDisplay( ) {
    glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 //rotating on every frame (for testing purposes only)
 glRotatef(5, 0,1,0);
 glutSolidTeapot(0.4);

    glFinish();
    glutSwapBuffers();
}


void onKeyboard(unsigned char key, int x, int y) {
 if (key==32){ //do rotation upon hitting the Space key
  glutPostRedisplay();
 }
}

int main(int argc, char **argv) {
    glutInit(&argc, argv); 
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(100, 100);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("Teapot");

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    onInitialization();

    glutDisplayFunc(onDisplay);
    glutKeyboardFunc(onKeyboard);

    glutMainLoop();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

MaR*_*MaR 2

我认为改变

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
Run Code Online (Sandbox Code Playgroud)

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Run Code Online (Sandbox Code Playgroud)

是一个很好的起点。