zoukankan      html  css  js  c++  java
  • 机械版CG 实验6 简单光照明模型实现

    CG实验指导八 简单光照明模型实现

    1.实验目的:

    了解简单光照明模型的基本原理,实现物体的真实感图形显示效果。

    2.实验内容:

    (1)       结合示范代码了解简单光照明模型的基本原理与实现;

    (2)       调试、编译、修改示范程序,给出不同光照系数,观察验证显示效果。

    3.实验原理:

    Phong光照明模型是由物体表面上一点P反射到视点的光强I为环境光的反射光强Ie、理想漫反射光强Id、和镜面反射光Is的总和,即
     

    其中RVN为单位矢量;Ip为点光源发出的入射光强;Ia为环境光的漫反射光强;Ka环境光的漫反射系数;Kd漫反射系数取决于表面的材料;Ks镜面反射系数n幂次,用以模拟反射光的空间分布,表面越光滑,n越大。

    在用Phong模型进行真实感图形计算时,对物体表面上的每个点P,均需计算光线的反射方向R,再由V计算。为减少计算量,我们可以作如下假设:a)光源在无穷远处,即光线方向L为常数;b)视点在无穷远处,即视线方向V为常数;c)近似。这里HLV的角平分向量,。在这种简化下,由于对所有的点总共只需计算一次H的值,节省了计算时间。结合RGB颜色模型,Phong光照明模型最终有如下的形式:

             

    本次实验中,光源在无穷远处,光线方向为单位向量L0.5, 0.5, 0.707,视点在无穷远处,视线方向V为(0 0 1)。

    4.实验代码:

    #include <GL/glut.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <math.h>

    struct Vector

    {

           float fx, fy, fz;

    };

    struct Color

    {

           float Ir, Ig, Ib;

    };

    float KaIa;//环境光强度

    float Kd, n;

    Vector H,light;

    Color mLight, mColor;

    GLboolean bLight = false;

    //利用圆的八向对称性生成圆上的点

    void CirclePt(int x0, int y0, int x, int y, Color mColor)

    {

           glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);

           glBegin(GL_POINTS);

           glVertex2i ( x+x0, y+y0);//x,y

           glVertex2i ( -x+x0, y+y0);//-x,y

           glVertex2i ( x+x0, -y+y0);//x, -y

           glVertex2i ( -x+x0, -y+y0);//-x, -y

           glVertex2i ( y+x0, x+y0);//y, x

           glVertex2i ( y+x0, -x+y0);//y, -x

           glVertex2i ( -y+x0, x+y0);//-y, x

           glVertex2i ( -y+x0,-x+y0);//-y, -x

           glEnd();

    }

    //中点圆生成算法

    void MidCircle(int x0, int y0, int r, Color mColor)

    {

           int x,y,deltax,deltay,d;

           x = 0;

           y = r;

           deltax = 3;

           deltay = 5-r-r;

           d = 1-r;

           CirclePt( x0, y0, x, y, mColor);

           while(x<y)

           {

                  if(d<0)

                  {

                         d += deltax;

                         deltax += 2;

                         deltay += 2;

                         x++;

                  }

                  else

                  {

                         d += deltay;

                         deltax += 2;

                         deltay += 4;

                         x++;

                         y--;

                  }

                  CirclePt( x0, y0, x, y, mColor);

           }

    }

    //根据中点圆算法填充圆域

    void FlatCircle(int x0, int y0, int r, Color mColor)

    {

           int x,y,deltax,deltay,d;

           x = 0;

           y = r;

           deltax = 3;

           deltay = 5-r-r;

           d = 1-r;

           glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);

           glBegin(GL_POINTS);

           {

                  for(int i=-x;i<=x;i++)

                  {

                         glVertex2i (i+x0,y+y0);

                         glVertex2i (i+x0,-y+y0);

                  }

                  for(i=-y;i<=y;i++)

                  {

                         glVertex2i (i+x0,x+y0);

                         glVertex2i (i+x0,-x+y0);

                  }

                  while(x<y)

                  {

                         if(d<0)

                         {

                                d += deltax;

                                deltax += 2;

                                deltay += 2;

                                x++;

                         }

                         else

                         {

                                d += deltay;

                                deltax += 2;

                                deltay += 4;

                                x++;

                                y--;

                         }

                         for(i=-x;i<=x;i++)

                         {

                                glVertex2i (i+x0,y+y0);

                                glVertex2i (i+x0,-y+y0);

                         }

                         for(i=-y;i<=y;i++)

                         {

                                glVertex2i (i+x0,x+y0);

                                glVertex2i (i+x0,-x+y0);

                         }

                  }

           }

           glEnd();

    }

    //初始化设定

    void Init()

    {

           float mo;

           Vector eye;

           mLight.Ir = 0;

           mLight.Ig = 175;

           mLight.Ib = 0;

           KaIa=80;

           Kd = 1;

           n = 10;

           light.fx=0.50;light.fy=0.50;

           light.fz = sqrt(1-(light.fx*light.fx)-(light.fy*light.fy));

           eye.fx=0;eye.fy=0;eye.fz=1;

           H.fx=light.fx+eye.fx;

           H.fy=light.fy+eye.fy;

           H.fz=light.fz+eye.fz;

           mo=sqrt(H.fx*H.fx+H.fy*H.fy+H.fz*H.fz);

           H.fx=(H.fx/mo);H.fy=(H.fy/mo);H.fz=(H.fz/mo);

           H.fx=(H.fx/mo);H.fy=(H.fy/mo);H.fz=(H.fz/mo);

           glClearColor(0.0, 0.0, 0.0, 0.0);

           glShadeModel(GL_SMOOTH);

    }

    //根据Phong模型计算光强

    Color Phong(int x0, int y0, int r, int x, int y)

    {

           Vector N;

           float z,alpha,theta,Ks;

           Ks=1.0-Kd;

           z=sqrt((float)(r*r-(x-x0)*(x-x0)-(y-y0)*(y-y0)));

           N.fx=(x-x0)*1.0/r;

           N.fy=(y-y0)*1.0/r;

           N.fz = z*1.0/r;

           theta = N.fx * light.fx + N.fy * light.fy + N.fz * light.fz;

           if(theta<0)

                  theta=0;

           alpha=H.fx*N.fx+H.fy*N.fy+H.fx*N.fz;

           if(alpha<0)

                  alpha=0;

           mColor.Ir=KaIa+mLight.Ir*Kd*theta+mLight.Ir*Ks*pow(alpha,n);

           mColor.Ig=KaIa+mLight.Ig*Kd*theta+mLight.Ig*Ks*pow(alpha,n);

           mColor.Ib=KaIa+mLight.Ib*Kd*theta+mLight.Ib*Ks*pow(alpha,n);

           return mColor;

    }

    //根据计算的光强按球体的结果着色

    void Sphere(int x0, int y0, int r)

    {

           int x,y,deltax,deltay,d;

           x = 0;

           y = r;

           deltax = 3;

           deltay = 5-r-r;

           d = 1-r;

           glBegin(GL_POINTS);

           {

                  for(int i=-x;i<=x;i++)

                  {

                         mColor=Phong(x0,y0,r,i+x0,y+y0);

                         glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,y+y0);

                         glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,-y+y0);

                  }

                  for(i=-y;i<=y;i++)

                  {

                         mColor=Phong(x0,y0,r,i+x0,x+y0);

                         glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,x+y0);

                         glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,-x+y0);

                  }

                  while(x<y)

                  {

                         if(d<0)

                         {

                                d += deltax;

                                deltax += 2;

                                deltay += 2;

                                x++;

                         }

                         else

                         {

                                d += deltay;

                                deltax += 2;

                                deltay += 4;

                                x++;

                                y--;

                         }

                         for(i=-x;i<=x;i++)

                         {

                                mColor=Phong(x0,y0,r,i+x0,y+y0);

                                glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,y+y0);

                                glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,-y+y0);

                         }

                         for(i=-y;i<=y;i++)

                         {

                                mColor=Phong(x0,y0,r,i+x0,x+y0);

                                glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,x+y0);

                                glColor3ub (mColor.Ir, mColor.Ig, mColor.Ib);   glVertex2i (i+x0,-x+y0);

                         }

                  }

           }

           glEnd();

    }

    void myDisplay()

    {

           glClear(GL_COLOR_BUFFER_BIT);

           glColor3f (1.0f, 1.0f, 1.0f);

           Color clr;

           clr.Ir = 180, clr.Ig = 180, clr.Ib = 180;

           MidCircle(80, 240, 70, clr);

           FlatCircle(280, 240, 70, clr);

           Sphere(540, 240, 70);

           glFlush();

    }

    void Reshape(int w, int h)

    {

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

           glMatrixMode(GL_PROJECTION);

           glLoadIdentity();

           gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);

    }

    int main(int argc, char *argv[])

    {

           glutInit(&argc, argv);

           glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

           glutInitWindowPosition(100, 100);

           glutInitWindowSize(640, 480);

           glutCreateWindow("Hello World!");

           Init();

           glutDisplayFunc(myDisplay);

           glutReshapeFunc(Reshape);

           glutMainLoop();

           return 0;

    }

    5.实验思考题

    尝试绘制一个平面或正方体的简单光照效果。

  • 相关阅读:
    CSS中常用中文字体转Unicode编码表
    CSS自定义字体(@font-face选择符)
    ie7 动态改变select option时,宽度自动变短解决方法
    面试题
    HTML DOM Document 对象
    测试
    复习代码
    Android 极光推送集成
    Android 事件分发
    Android View
  • 原文地址:https://www.cnblogs.com/opengl/p/961787.html
Copyright © 2011-2022 走看看