OpenGL -- 光照实例 1

设置太阳光(平行光)
在设置不同材质的球体,观察光照效果

直接上图

OpenGL -- 光照实例 1_第1张图片

代码

#include     
#include 
#include 
#include 
#include 
#include 
#include 

#define PI 3.1415926     
#define WIDTH 500  
#define HEIGHT 500 

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲  

    // 定义太阳光源,它是一种白色的光源  
    {
        GLfloat sun_light_position[] = { 0.0f, 0.0f, 100.0f, 1.0f }; // 光源的位置
        GLfloat sun_light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
        GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
        GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

        glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position); //指定第0号光源的位置   
        glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient); //GL_AMBIENT表示各种光线照射到该材质上,  
        //经过很多次反射后最终遗留在环境中的光线强度(颜色)  
        glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse); //漫反射后~~  
        glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//镜面反射后~~~  

        glEnable(GL_LIGHT0); //使用第0号光照  
        glEnable(GL_LIGHTING); //在后面的渲染中使用光照  
        glEnable(GL_DEPTH_TEST); //这句是启用深度测试,这样,在后面的物体会被挡着,例如房子后面有棵树,如果不启用深度测试,  
        //你先画了房子再画树,树会覆盖房子的;但启用深度测试后无论你怎么画,树一定在房子后面(被房子挡着)   
    }

    glPushMatrix();
    // 定义一个球体 
    {
        GLfloat earth_mat_ambient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
        GLfloat earth_mat_diffuse[] = { 1.0f, 1.0f, 0.0f, 1.0f };  // 漫反射的颜色(也就是该对象的颜色) 定义了黄色的
        GLfloat earth_mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 材质的镜面反射颜色 定义了白色
        GLfloat earth_mat_emission[] = { 0.2f, 0.2f, 0.0f, 1.0f }; // 材质发射出的光的颜色,定义发出微微的黄色的光
        GLfloat earth_mat_shininess = 15.0f; // 球体比较的光滑

        glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
        glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
        glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);

        glTranslatef(5.0f, 0.0f, 0.0f);

        //如果使用glutSolidSphere函数来绘制球体,则该函数会自动的指定这些法线向量,  
        //不必再手工指出。如果是自己指定若干的顶点来绘制一个球体,则需要自己指定法线向量。  
        glutSolidSphere(2.3, 40, 32);
    }
    glPopMatrix();

    glPushMatrix();
    // 定义一个球体 
    {
        GLfloat earth_mat_ambient[] = { 0.0f, 0.5f, 0.0f, 1.0f };
        GLfloat earth_mat_diffuse[] = { 0.0f, 0.5f, 0.0f, 1.0f }; // 浅绿色的球
        GLfloat earth_mat_specular[] = { 0.0f, 1.0f, 0.0f, 1.0f };
        GLfloat earth_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };
        GLfloat earth_mat_shininess = 110.0f; // 球体比较粗糙

        // GL_AMBIENT 材质的环境颜色 
        glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
        // GL_DIFFUSE 材质的散射颜色
        glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
        // GL_SPECULAR 材质的镜面反射颜色
        glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
        // GL_EMISSION 材质的发射光颜色
        glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
        // GL_SHININESS 镜面反射指数
        glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);

        glTranslatef(-3.0f, 4.0f, 0.0f);   // 平移

        glutSolidSphere(2.3, 40, 32);
    }
    glPopMatrix();

    glPushMatrix();
    // 定义一个球体
    {
        GLfloat earth_mat_ambient[] = { 0.5f, 0.0f, 0.0f, 1.0f };
        GLfloat earth_mat_diffuse[] = { 1.0f, 0.0f, 0.0f, 1.0f }; // 深红色的球
        GLfloat earth_mat_specular[] = { 0.2f, 0.0f, 0.0f, 1.0f }; // 镜面反射出红光
        GLfloat earth_mat_emission[] = { 0.1f, 0.0f, 0.0f, 1.0f }; // 自己发出微微的红光
        GLfloat earth_mat_shininess = 60.0f; 

        // GL_AMBIENT 材质的环境颜色 
        glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
        // GL_DIFFUSE 材质的散射颜色
        glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
        // GL_SPECULAR 材质的镜面反射颜色
        glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
        // GL_EMISSION 材质的发射光颜色
        glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
        // GL_SHININESS 镜面反射指数
        glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);

        glTranslatef(-4.0f, -4.0f, 0.0f);   // 平移 

        glutSolidSphere(2.3, 40, 32);
    }
    glPopMatrix();

    glutSwapBuffers(); //交换缓冲区  
}

void Reshape(int w, int h)
{
    // //改变显示区域,起始位置为客户端窗口左下角(非坐标原点)
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //宽高比改为当前值,视线区域与屏幕大小一致;
    gluPerspective(45, 1.0*w / h, 1, 1000);
    // 开启更新深度缓冲区的功能
    glEnable(GL_DEPTH_TEST);
    // 摄像机视图观看
    gluLookAt(0.0, 0.0, 25.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1000.0);
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutCreateWindow("OpenGL光照演示");

    glutReshapeFunc(&Reshape);
    glutDisplayFunc(&myDisplay);

    glutMainLoop();
    return 0;
}

参考

光照学习
http://blog.csdn.net/timidsmile/article/details/7017197

光照材质
http://blog.csdn.net/wong_judy/article/details/6309667


你可能感兴趣的:(#,OpenGL)