代码之家  ›  专栏  ›  技术社区  ›  SparkyNZ

OpenGL:为什么对象旋转时照明会改变?

  •  3
  • SparkyNZ  · 技术社区  · 11 年前

    下面的代码围绕它们的局部轴旋转一个金字塔和一个立方体(我相信)。为什么这两个物体都会随着代码变亮变暗?光肯定会从一个固定的位置(比如太阳)发出,物体本身不会全部变暗变亮?

    是什么导致了这种行为?这是旧的即时模式。我是一个OpenGL新手。

    光源似乎“粘”在每个对象的一个面上。当每个对象旋转时,它会随之旋转其光源。

    #include <windows.h>                            // Header File For Windows
    #include <gl\gl.h>                              // Header File For The OpenGL32 Library
    #include <gl\glu.h>                             // Header File For The GLu32 Library
    #include <GL\glut.h>
    
    static void resize(int width, int height)
    {
        const float ar = (float) width / (float) height;
    
        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity() ;
    }
    
    GLfloat     rtri  = 0.0;                          // Angle For The Triangle 
    GLfloat     rquad = 0.0;                        // Angle For The Quad     
    GLfloat     xPosCube = 0.0;
    
    //--------------------------------------------------------------------------------------------
    // DrawPyramid
    //--------------------------------------------------------------------------------------------
    void DrawPyramid( void )
    {
        glLoadIdentity();
      glTranslatef( -1.5f, 0.0f, -6.0f );                   // Move Left 1.5 Units And Into The Screen 6.0
    
      glRotatef( rtri, 0.0f, 1.0f, 0.0f );              // Rotate The Triangle On The Y axis
    
        glBegin( GL_TRIANGLES );                    // Start Drawing The Pyramid
    
        // Face 1
          glVertex3f( 0.0f, 1.0f, 0.0f );           // Top Of Triangle (Front)
          glVertex3f( -1.0f, -1.0f, 1.0f );         // Left Of Triangle (Front)
          glVertex3f( 1.0f, -1.0f, 1.0f );          // Right Of Triangle (Front)
    
        // Face 2
          glVertex3f( 0.0f, 1.0f, 0.0f);            // Top Of Triangle (Right)
          glVertex3f( 1.0f,-1.0f, 1.0f);            // Left Of Triangle (Right)
          glVertex3f( 1.0f,-1.0f, -1.0f);           // Right Of Triangle (Right)
    
        // Face 3
          glVertex3f( 0.0f, 1.0f, 0.0f);            // Top Of Triangle (Back)
          glVertex3f( 1.0f,-1.0f, -1.0f);           // Left Of Triangle (Back)
          glVertex3f(-1.0f,-1.0f, -1.0f);           // Right Of Triangle (Back)
    
        // Face 4
          glVertex3f( 0.0f, 1.0f, 0.0f);            // Top Of Triangle (Left)
          glVertex3f(-1.0f,-1.0f,-1.0f);            // Left Of Triangle (Left)
          glVertex3f(-1.0f,-1.0f, 1.0f);            // Right Of Triangle (Left)
        glEnd();
    }
    
    //--------------------------------------------------------------------------------------------
    // DrawCube
    //--------------------------------------------------------------------------------------------
    void DrawCube( void )
    {
      glLoadIdentity();
        glTranslatef( 1.75f /* + xPosCube*/ ,0.0f,-7.0f + xPosCube);                // Move Right And Into The Screen
    
      glRotatef(rquad,1.0f,1.0f,1.0f);          // Rotate The Cube On X, Y & Z
    
        glBegin(GL_QUADS);
    
            glVertex3f( 1.0f, 1.0f,-1.0f);          // Top Right Of The Quad (Top)
            glVertex3f(-1.0f, 1.0f,-1.0f);          // Top Left Of The Quad (Top)
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Bottom Left Of The Quad (Top)
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Bottom Right Of The Quad (Top)
    
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Top Right Of The Quad (Bottom)
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Top Left Of The Quad (Bottom)
            glVertex3f(-1.0f,-1.0f,-1.0f);          // Bottom Left Of The Quad (Bottom)
            glVertex3f( 1.0f,-1.0f,-1.0f);          // Bottom Right Of The Quad (Bottom)
    
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Top Right Of The Quad (Front)
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Top Left Of The Quad (Front)
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Bottom Left Of The Quad (Front)
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Bottom Right Of The Quad (Front)
    
            glVertex3f( 1.0f,-1.0f,-1.0f);          // Bottom Left Of The Quad (Back)
            glVertex3f(-1.0f,-1.0f,-1.0f);          // Bottom Right Of The Quad (Back)
            glVertex3f(-1.0f, 1.0f,-1.0f);          // Top Right Of The Quad (Back)
            glVertex3f( 1.0f, 1.0f,-1.0f);          // Top Left Of The Quad (Back)
    
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Top Right Of The Quad (Left)
            glVertex3f(-1.0f, 1.0f,-1.0f);          // Top Left Of The Quad (Left)
            glVertex3f(-1.0f,-1.0f,-1.0f);          // Bottom Left Of The Quad (Left)
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Bottom Right Of The Quad (Left)
    
            glVertex3f( 1.0f, 1.0f,-1.0f);          // Top Right Of The Quad (Right)
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Top Left Of The Quad (Right)
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Bottom Left Of The Quad (Right)
            glVertex3f( 1.0f,-1.0f,-1.0f);          // Bottom Right Of The Quad (Right)
    
        glEnd();                        // Done Drawing The Quad
    }
    
    //--------------------------------------------------------------------------------------------
    // DrawPyramidHiddenLinesPolygonOffset()
    //--------------------------------------------------------------------------------------------
    void DrawPyramidHiddenLinesPolygonOffset( void )
    {
      // Draw cube - Hidden Line Removal with Polygon Offset.. 
      glEnable(GL_DEPTH_TEST);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glColor4f(1.0f,0.0f,0.0f, 1.0f);          // Set The Color To Violet
    
      DrawPyramid();
    
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      glEnable(GL_POLYGON_OFFSET_FILL);
      glPolygonOffset(1.0, 1.0);
      glColor4f(0.5f,0.0f,0.0f, 0.1f);          // Set The Color To Violet
    
      DrawPyramid();
    
      glDisable(GL_POLYGON_OFFSET_FILL);
    }
    
    //--------------------------------------------------------------------------------------------
    // DrawCubeHiddenLinesPolygonOffset()
    //--------------------------------------------------------------------------------------------
    void DrawCubeHiddenLinesPolygonOffset( void )
    {
      // Draw cube - Hidden Line Removal with Polygon Offset.. 
      glEnable(GL_DEPTH_TEST);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glColor4f(1.0f,0.0f,1.0f, 1.0f);          // Set The Color To Violet
    
      DrawCube( FALSE );
    
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      glEnable(GL_POLYGON_OFFSET_FILL);
      glPolygonOffset(1.0, 1.0);
      glColor4f(0.5f,0.0f,0.5f, 0.1f);          // Set The Color To Violet
    
      DrawCube( FALSE );
    
      glDisable(GL_POLYGON_OFFSET_FILL);
    }
    
    //--------------------------------------------------------------------------------------------
    // DrawGLScene()
    //--------------------------------------------------------------------------------------------
    void DrawGLScene(void)
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
      // Do camera rotation first..
    
      // Now draw and rotate objects..
      DrawCubeHiddenLinesPolygonOffset();
      DrawPyramidHiddenLinesPolygonOffset();
    
    
        rtri  += 0.022f;                        // Increase The Rotation Variable For The Triangle 
        rquad -= 0.045f;                        // Decrease The Rotation Variable For The Quad     
      //xPosCube -= 0.0005f;
    
      glutSwapBuffers();
    }
    
    const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
    const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
    
    const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
    const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
    const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat high_shininess[] = { 100.0f };
    
    
    
    void IdleFunc()
    {
      glutPostRedisplay();
    }
    
    
    void KeyboardFunc( BYTE key, int x, int y )
    {
      switch (key)
      {
         case 27: // Escape key
          //glutDestroyWindow( Win.id );
          exit (0);
          break;
      }
    }
    
    
    /* Program entry point */
    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitWindowSize(640,480);
        glutInitWindowPosition(10,10);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    
        glutCreateWindow("Programming Techniques - 3D Spheres");
    
        glutKeyboardFunc( KeyboardFunc );
        glutReshapeFunc(resize);
        glutDisplayFunc( DrawGLScene );
        glutIdleFunc( IdleFunc );
    
        glClearColor(1,1,1,1);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
    
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
    
        glEnable(GL_LIGHT0);
        glEnable(GL_NORMALIZE);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_LIGHTING);
    
        glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    
        glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
    
        glutMainLoop();
    
        return EXIT_SUCCESS;
    }
    
    1 回复  |  直到 11 年前
        1
  •  3
  •   derhass    11 年前

    您没有提供任何曲面法线,但照明取决于它。因此,所有顶点和面都具有相同的法线(GL的初始默认值为(0,1,0),iirc), 这意味着每一张脸都被照亮,好像它们都与光源成相同的角度。当您应用旋转时,该法线会发生变换。

    推荐文章