opengl光照方程的计算验证

#include "stdafx.h"

#include <GL/glut.h>

#include <iostream>

using namespace std;

 

void Init(void)

{

    GLfloat mat_ambient[] = { 0.2, 0.2, 0.2, 1.0 };//光源环境光

    GLfloat mat_diffuse[] = { 0.0, 0.0, 0.0, 1.0 };//散射光

    GLfloat mat_emission[] = { 0.1, 0.1, 0.1, 1.0 };//镜面光

    GLfloat mat_specular[] = { 0.3, 0.3, 0.3, 1.0 };//物体自发光

    GLfloat mat_shininess[] = { 2.0 };

 

    GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };//点光源(位置性光源)

    GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0};

    GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};

    GLfloat light_specular[] ={1.0, 1.0, 1.0, 1.0};

    GLfloat lmodel_ambient[] = { 0.5, 0.5, 0.5, 1.0};

    glClearColor (0.0, 0.0, 0.0, 0.0);

    //GL_FLAT,绘制的三角形上的所有点都是最后一个点的颜色,而用GL_SMOOTH会线性插值

    glShadeModel (GL_SMOOTH /*GL_FLAT*/);

 

    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_EMISSION, mat_emission);

    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

 

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);//点光源相对视点的位置始终不变,此处是(1,1,1)

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);

    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

 

    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);//环境光

 

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glEnable(GL_DEPTH_TEST);

 

}

void Display(void)

{  

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

 

    glTranslatef( 0.0f, 0.0f, -2.0f);

    glBegin(GL_TRIANGLES);

       glNormal3f(0.0f, 0.0f, 1.0f);     

   

       //glColor3f( 1, 0, 0);//如此有glEnable(GL_LIGHTING);,则此处glColor3f()设置的颜色无效.

       glVertex3f( -1.0, 0.0, 0.0f);

       glVertex3f(  1.0, 0.0, 0.0f);  

       glVertex3f(  1.0, 1.0, 0.0f);

 

    glEnd();

 

    glutSwapBuffers(); //双缓冲

}

void Reshape(int w,int h)

{  

 

    //透视投影或者正交投影都可以

    /*glViewport(0,0  ,(GLsizei)w  ,(GLsizei)h  );

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluPerspective( 90.0f, (GLfloat)w/ (GLfloat)h, 0.1f, 1000.0f );

 

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();*/

 

    glViewport (0, 0, (GLsizei) w, (GLsizei) h);

   glMatrixMode (GL_PROJECTION);

   glLoadIdentity();

   if (w <= h)

      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,

         1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);

   else

      glOrtho (-1.5*(GLfloat)w/(GLfloat)h,

         1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

   glMatrixMode(GL_MODELVIEW);

   glLoadIdentity();

}

 

void OnTimer( int iTimerIndex)

{

    //更新

    glutPostRedisplay();//刷新显示

    glutTimerFunc( 50, OnTimer, 0);

}

 

 

void Keyboard(unsigned char key, int x, int y)

{

 

    switch (key)

    {

        case 'w':     //

        break;

        case 's':     //

            break;

        case 'a':     //

            break;

        case 'd':     //

            break;

        case 'q':    //

            break;

        case 27:

            exit(0);

            break;

    }

}

 

void MouseEvent(int button, int state, int x, int y)

{

    switch(button)

    {

        case GLUT_LEFT_BUTTON:

            cout<<"GLUT_LEFT_BUTTON"<<endl;

            break;

        case GLUT_RIGHT_BUTTON:

            cout<<"GLUT_RIGHT_BUTTON"<<endl;

            break;

        case GLUT_MIDDLE_BUTTON:

            cout<<"GLUT_MIDDLE_BUTTON"<<endl;

            break;

    }

}

void MotionMove(int x,int y)

{

 

}

   

int main(int argc, char** argv)

{

    glutInit(&argc,argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    glutInitWindowSize(450,450);

    glutInitWindowPosition(200,200);

    glutCreateWindow("Hello");

    Init();

    glutDisplayFunc( Display);

    glutReshapeFunc( Reshape);

 

    //定时器

    //glutTimerFunc( 50, OnTimer, 0 );

 

    glutKeyboardFunc( Keyboard);

    glutMouseFunc( MouseEvent);

    glutMotionFunc( MotionMove);

 

    glutMainLoop();

    return 0;

}

 

以上代码可以产生一个三角形,经计算验证,书上的光照计算方法是正确的.

程序运行后,可用QQ截图获取某个点的像素值(该程序中左顶点的像素是(130,130,130),因为本程序中每个像素的R,G,B都是一样的):

opengl光照方程的计算验证_第1张图片

由于没有用gluLookAt()来改变视点,所以视点坐标依然不变,为世界坐标系原点E(0,0,0,),光源位

(偷了下懒).

总的计算过程是C=(0.1, 0.1, 0.1)+( 0.5, 0.5, 0.5)*( 0.2, 0.2, 0.2)+[( 0.2, 0.2, 0.2)*( 0.2, 0.2, 0.2)+ 3/ *(1.0, 1.0, 1.0)*( 0.0, 0.0, 0.0)+ (s*n)平方*(1.0, 1.0, 1.0)*( 0.3, 0.3, 0.3)],然后再把C*255即可得到实际像素值(130),可以证明光照方程是正确的.

注意:s中的2个向量都必须先单位化后,再相加成为s,然后s还要单位化.我在计算时,由于粗心,没有把L单位化,导致一直得不到正确结果,后来找王辉问时,才突然发现s的2个向量一定要单位化.以后一定要细心,而且一般遇到问题,不要抱怨,以为是编译器错了,而事实上往往是由于自己的疏忽和不小心,应仔细debug,切记!

 

 

你可能感兴趣的:(opengl光照方程的计算验证)