2015-08-12 5 views
1

Приведенный ниже код поворачивает пирамиду и куб вокруг их локальной оси (я считаю). Почему оба объекта становятся светлыми и темными с помощью этого кода? Разумеется, свет исходил из одного фиксированного положения (например, солнца), и сами объекты не могли бы стать темными и светлыми во всей полноте?OpenGL: Почему освещение меняется, когда объект вращается?

В чем причина этого поведения? Это старый немедленный режим. Я новичок 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

Вы не производите никаких нормалей поверхности, но от этого зависит освещение. В результате все ваши вершины и грани имеют одинаковую нормаль (начальное значение по умолчанию GL (0,1,0), iirc), , что означает, что каждая грань освещена, как если бы все они имели одинаковый угол к свету , Эта норма просто трансформируется, когда вы применяете свое вращение.

+0

Спасибо, что-то я еще не узнал. Поэтому для каждой поверхности необходимо определить нормальную. – SparkyNZ