带显示列表的 OpenGL 光照
OpenGL Lighting with Display Lists
我正在使用 JOGL 库开发一些 OpenGL 游戏。
当我经常画物体时,例如在显示方法中直接使用GL_QUADS,场景光照出现在物体上。
但是,当我在 init 方法中准备对象并在显示列表中使用 glCallList 加载时,这些对象似乎不受光照的影响。
准确地说,它们在某些方面受到影响:改变 materialfv 函数参数或环境参数使场景变亮或变暗,但我试图漫射的颜色不起作用(仅在常规绘制的对象上没有列表)。
代码
这里是灯光代码:
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glShadeModel(GL2.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL2.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL2.GL_LEQUAL); // The Type Of Depth Testing To Do
glu = new GLU();
// Really Nice Perspective Calculations
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
// Light
float ambient[] = {0.1f,0.1f,0.1f,1.0f};
float diffuse0[] = {1f,0f,0f,1.0f};
float diffuse1[] = {0f,0f,1f,1.0f};
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, 0);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse0, 0);
gl.glEnable(GL2.GL_LIGHT0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_AMBIENT, ambient, 0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, diffuse1, 0);
gl.glEnable(GL2.GL_LIGHT1);
gl.glEnable(GL2.GL_LIGHTING);
// make display lists here...
显示屏灯光部分:
// display method...
// apply light
float position0[] = {500, 300, 3500,1.0f};
float position1[] = {500, 300, 500,1.0f};
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, position0, 0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, position1, 0);
// draw objects directly
// draw objects using glCallLists
下面是我如何在显示方法中绘制常规对象的示例:
gl.glPushMatrix();
gl.glTranslatef(1000, 500, 2000);
gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
float material[] = {0.8f,0.8f,0.8f,1.0f};
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE, material, 0);
gl.glBegin(GL2.GL_QUADS);
// Front Face
gl.glNormal3f(0,0,1);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
gl.glNormal3f(0,0,-1);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
// Top Face
gl.glNormal3f(0,1,0);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
// Bottom Face
gl.glNormal3f(0,-1,0);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
gl.glNormal3f(1,0,0);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
// Left Face
gl.glNormal3f(-1,0,0);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glEnd();
gl.glPopMatrix();
Here's the class I use to load obj files.
我使用 loadWavefrontObjectAsDisplayList 方法,它接受 obj 文件的路径,然后 returns 列表整数。
另一个编辑:
场景(lamp正在点亮,板条箱没有):
板条箱模型的 WaveFront OBJ 文件中可能缺少法线。
然后,您使用的 OBJ 导入器生成坐标为 (0, 0, 0) 的完全错误的法线,它无法处理闪电。
我正在使用 JOGL 库开发一些 OpenGL 游戏。
当我经常画物体时,例如在显示方法中直接使用GL_QUADS,场景光照出现在物体上。
但是,当我在 init 方法中准备对象并在显示列表中使用 glCallList 加载时,这些对象似乎不受光照的影响。
准确地说,它们在某些方面受到影响:改变 materialfv 函数参数或环境参数使场景变亮或变暗,但我试图漫射的颜色不起作用(仅在常规绘制的对象上没有列表)。
代码
这里是灯光代码:
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glShadeModel(GL2.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL2.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL2.GL_LEQUAL); // The Type Of Depth Testing To Do
glu = new GLU();
// Really Nice Perspective Calculations
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
// Light
float ambient[] = {0.1f,0.1f,0.1f,1.0f};
float diffuse0[] = {1f,0f,0f,1.0f};
float diffuse1[] = {0f,0f,1f,1.0f};
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, 0);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse0, 0);
gl.glEnable(GL2.GL_LIGHT0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_AMBIENT, ambient, 0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, diffuse1, 0);
gl.glEnable(GL2.GL_LIGHT1);
gl.glEnable(GL2.GL_LIGHTING);
// make display lists here...
显示屏灯光部分:
// display method...
// apply light
float position0[] = {500, 300, 3500,1.0f};
float position1[] = {500, 300, 500,1.0f};
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, position0, 0);
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, position1, 0);
// draw objects directly
// draw objects using glCallLists
下面是我如何在显示方法中绘制常规对象的示例:
gl.glPushMatrix();
gl.glTranslatef(1000, 500, 2000);
gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
float material[] = {0.8f,0.8f,0.8f,1.0f};
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE, material, 0);
gl.glBegin(GL2.GL_QUADS);
// Front Face
gl.glNormal3f(0,0,1);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
gl.glNormal3f(0,0,-1);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
// Top Face
gl.glNormal3f(0,1,0);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
// Bottom Face
gl.glNormal3f(0,-1,0);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
gl.glNormal3f(1,0,0);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
// Left Face
gl.glNormal3f(-1,0,0);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glEnd();
gl.glPopMatrix();
Here's the class I use to load obj files.
我使用 loadWavefrontObjectAsDisplayList 方法,它接受 obj 文件的路径,然后 returns 列表整数。
另一个编辑:
场景(lamp正在点亮,板条箱没有):
板条箱模型的 WaveFront OBJ 文件中可能缺少法线。
然后,您使用的 OBJ 导入器生成坐标为 (0, 0, 0) 的完全错误的法线,它无法处理闪电。