Raytracing

本程序是根据Raytracing的要求所写。

该题目要求根据其所给的框架程序来实现raytracing的功能。

该项目已迁移到我的个人github主页,请访问[bin2415]## 题目要求

具体实现

  • 环境是virual studio 2015和opengl
  • 具体代码及分析如下:

    /*
    CSCI 480
    Assignment 3 Raytracer
    
    Name: <binpang>
    */
    {% highlight c++ %}
    
    
    #define _CRT_SECURE_NO_WARNINGS
    
    
    #define GLUT_DISABLE_ATEXIT_HACK
    
    
    #include <pic.h>
    
    
    
    #include <windows.h>
    
    
    #include <GL/glu.h>
    
    
    #include <GL/glut.h>
    
    
    #include <stdlib.h>
    
    
    #include <stdio.h>
    
    
    #include <string>
    
    
    #include <math.h>
    
    
    #include <vector>
    
    
    #define MAX_TRIANGLES 2000
    
    
    #define MAX_SPHERES 10
    
    
    #define MAX_LIGHTS 10
    
    
    
    char *filename=0;
    
    
    #define MODE_DISPLAY 1
    
    
    #define MODE_JPEG 2
    
    int mode=MODE_DISPLAY;
    
    
    #define WIDTH 640
    
    
    #define HEIGHT 480
    
    
    
    #define fov 60.0
    
    
    #define PI 3.1415926
    
    
    
    int MaxStep = 10;
    int Steps = 0;
    //求出投射的屏幕的x和y的最大范围的坐标
    
    double yMax = tan((double)PI*fov / (2 * 180));
    double xMax = yMax*((double)WIDTH) / ((double)HEIGHT);
    
    unsigned char buffer[HEIGHT][WIDTH][3];
    
    struct Vertex
    {
      double position[3];
      double color_diffuse[3];//漫射
      double color_specular[3];   //反射
      double normal[3];
      double shininess;
    };
    
    typedef struct _Triangle
    {
      struct Vertex v[3];
    } Triangle;
    
    typedef struct _Sphere
    {
      double position[3];
      double color_diffuse[3];
      double color_specular[3];
      double shininess;
      double radius;
    } Sphere;
    
    typedef struct _Light
    {
      double position[3];
      double color[3];
    } Light;
    
    //表示点的结构
    struct point
    {
        double x;
        double y;
        double z;
    };
    //点在里面还是在外面
    struct isIn
    {
        bool in;        //当在三角形外面时为0,当在里面时为1
        double bary[3];
    };
    
    //交点的结构
    struct intexPoint
    {
        point p;
        double t;
        int tID;    //物体在数组中的标号
        int tObj;  //如果是1表示点在圆上,如果为2表示在三角形上
        isIn iO;    
    };
    Triangle triangles[MAX_TRIANGLES];
    Sphere spheres[MAX_SPHERES];
    Light lights[MAX_LIGHTS];
    double ambient_light[3];
    
    struct point cam;
    
    int num_triangles=0;
    int num_spheres=0;
    int num_lights=0;
    
    void plot_pixel_display(int x,int y,unsigned char r,unsigned char g,unsigned char b);
    
    void plot_pixel_jpeg(int x,int y,unsigned char r,unsigned char g,unsigned char b);
    
    void plot_pixel(int x,int y,unsigned char r,unsigned char g,unsigned char b);
    
    point reflect(intexPoint p, point dir);
    
    point Render(point p, point dir);
    //两个点进行相减
    point minusPoint(point A, point B)
    {
        point C;
        C.x = A.x - B.x;
        C.y = A.y - B.y;
        C.z = A.z - B.z;
    
        return C;
    }
    
    //向量除以一个数
    point DivConst(point A, double a)
    {
        point B;
    
        B.x = 0.0;
        B.y = 0.0;
        B.z = 0.0;
    
        if (abs(a) > 1e-10)
        {
            B.x = A.x / a;
            B.y = A.y / a;
            B.z = A.z / a;
        }
    
        return B;
    }
    //计算向量的大小
    double caculateSize(point A)
    {
        double size;
        size = sqrt(pow(A.x, 2) + pow(A.y, 2) + pow(A.z, 2));
        return size;
    }
    
    //单位化向量
    point unitize(point A)
    {
        point uni;
        double size;
        size = caculateSize(A);
        uni = DivConst(A, size);
    
        return uni;
    }
    //点乘
    double dot(point A, point B)
    {
        double C;
    
        C = (A.x*B.x + A.y*B.y + A.z*B.z);
        return C;
    }
    //叉乘
    point cross(point A, point B)
    {
        point C;
        C.x = (A.y*B.z - B.y*A.z);
        C.y = (B.x*A.z - A.x*B.z);
        C.z = (A.x*B.y - A.y*B.x);
    
        return C;
    
    }
    
    //求出距离src,方向为dir,长度为t的点
    point caluPoint(point src, point dir, double t)
    {
        point p;
    
        p.x = src.x + t*(dir.x);
        p.y = src.y + t*(dir.y);
        p.z = src.z + t*(dir.z);
    
        return p;
    }
    
    //与球的交点
    double intersectSphere(Sphere sphere, point src, point dir)
    {
        double b, c, t, t1, t2;
        t1 = 0;
        t2 = 0;
    
        c = pow((src.x - sphere.position[0]), 2) + pow((src.y - sphere.position[1]), 2)
            + pow((src.z - sphere.position[2]), 2) - pow(sphere.radius, 2);
        b = 2 * (dir.x*(src.x - sphere.position[0])
            + dir.y*(src.y - sphere.position[1])
            + dir.z*(src.z - sphere.position[2])
            );
    
        //检查判别式是否大于0
        if ((pow(b, 2) - 4 * c) > 0)
        {
            t1 = (((-1)*b) + sqrt(pow(b, 2) - 4 * c)) / 2;
            t2 = (((-1)*b) - sqrt(pow(b, 2) - 4 * c)) / 2;
    
            if (t1 <= t2)
                t = t1;
            else
                t = t2;
            if (t < 0)
                t = -1;
            else if (t<1e-10)
            {
                if (t1<1e-15 && t2>1e-15)
                    t = t2;
                else if (t2<1e-15 && t1>1e-15)
                    t = t1;
                else t = -1; 
            }
        }
        else t = -1; 
    
        return t;
    }
    
    //获得两个顶点之间的边
    point getSide(Vertex v1, Vertex v2)
    {
        point c;
        c.x = v1.position[0] - v2.position[0];
        c.y = v1.position[1] - v2.position[1];
        c.z = v1.position[2] - v2.position[2];
    
        return c;
    }
    //判断两个点是否相等
    bool checkEqual(point A, point B)
    {
        bool equ;
        if ((abs(A.x - B.x)<1e-10) && (abs(A.y - B.y)<1e-10) && (abs(A.z - B.z)<1e-10))
            equ = 1;
        else
            equ = 0;
        return equ;
    }
    
    double intersectTriangle(Triangle triangle, point src, point dir,isIn* iO)
    {
        point AB, AC, DirxAC;
        float u, v, t;
        //isIn iO;
        AB = getSide(triangle.v[1], triangle.v[0]);
        AC = getSide(triangle.v[2], triangle.v[0]);
        DirxAC = cross(dir, AC);
        float det = dot(AB, DirxAC);
        point T;
        point p1;
        p1.x = triangle.v[0].position[0];
        p1.y = triangle.v[0].position[1];
        p1.z = triangle.v[0].position[2];
        if (det >0)
       {
           T = minusPoint(src, p1);
    }
        else
        {
            T = minusPoint(p1, src);
        det = -det;
     }
        if (det < 1e-10)
        {
            iO->in = -1;
            return -1;
        }
    
        u = dot(T, DirxAC);
        if (u < 0.0f || u > det)
        {
            iO->in = -1;
            return -1;
    
        }
        point Q = cross(T, AB);
        v = dot(dir, Q);
        if (v < 0.0f || u + v > det)
        {
            iO->in = -1;
            return -1;
        }
    
        t = dot(AC, Q);
        //t = -t;
        float fInvDet = 1.0f / det;
        t *= fInvDet;
        u *= fInvDet;
        v *= fInvDet;
    
        iO->in = 1;
        iO->bary[0] = u;
        iO->bary[1] = v;
        iO->bary[2] = 1 - u - v;
        return t;
    }
    
    //找到p点在圆上的的法向量,tID为spheres数组中的标号
    point findSphereNormal(point p, int tID)
    {
        point n;
    
        // based on the equation
        n.x = (p.x - spheres[tID].position[0]) / spheres[tID].radius;
        n.y = (p.y - spheres[tID].position[1]) / spheres[tID].radius;
        n.z = (p.z - spheres[tID].position[2]) / spheres[tID].radius;
        return n;
    }
    
    //三角形的线性插值,如果ID为0则表示法线插值,如果ID为1则表示漫反射,如果为2则表示镜面反射
    point chazhi(Triangle triangle, isIn iO, int ID)
    {
        point P;
        if (ID == 0)
        {
            P.x = iO.bary[0] * triangle.v[0].normal[0]
                + iO.bary[1] * triangle.v[1].normal[1]
                + iO.bary[2] * triangle.v[2].normal[2];
    
            P.y = iO.bary[0] * triangle.v[0].normal[1]
                + iO.bary[1] * triangle.v[1].normal[1]
                + iO.bary[2] * triangle.v[2].normal[1];
    
            P.z = iO.bary[0] * triangle.v[0].normal[2]
                + iO.bary[1] * triangle.v[1].normal[2]
                + iO.bary[2] * triangle.v[2].normal[2];
        }
        else if (ID == 1)
        {
            P.x = iO.bary[0] * triangle.v[0].color_diffuse[0]
                + iO.bary[1] * triangle.v[1].color_diffuse[0]
                + iO.bary[2] * triangle.v[2].color_diffuse[0];
    
            P.y = iO.bary[0] * triangle.v[0].color_diffuse[1]
                + iO.bary[1] * triangle.v[1].color_diffuse[1]
                + iO.bary[2] * triangle.v[2].color_diffuse[1];
    
            P.z = iO.bary[0] * triangle.v[0].color_diffuse[2]
                + iO.bary[1] * triangle.v[1].color_diffuse[2]
                + iO.bary[2] * triangle.v[2].color_diffuse[2];
        }
    
        else if (ID == 2)
        {
            P.x = iO.bary[0] * triangle.v[0].color_specular[0]
                + iO.bary[1] * triangle.v[1].color_specular[0]
                + iO.bary[2] * triangle.v[2].color_specular[0];
    
            P.y = iO.bary[0] * triangle.v[0].color_specular[1]
                + iO.bary[1] * triangle.v[1].color_specular[1]
                + iO.bary[2] * triangle.v[2].color_specular[1];
    
            P.z = iO.bary[0] * triangle.v[0].color_specular[2]
                + iO.bary[1] * triangle.v[1].color_specular[2]
                + iO.bary[2] * triangle.v[2].color_specular[2];
        }
    
        return P;
    }
    
    //公式模型I_spec = k_z * I_l(V • ((2N • L)N - L))^n_s
    //其中R = (2N • L)N - L
    point phong(point p, int id, int Obj, isIn iO, Light light, point camera)
    {
        point n, l, v, r, kd, ks;
        point po;
        double lDotN, rDotV, n_s;
    
        //用point表示light的位置
        l.x = light.position[0];
        l.y = light.position[1];
        l.z = light.position[2];
    
        //l = l - p;
        //入射光线
        l = unitize(minusPoint(l, p));
    
        //v = camera - p;
        //观察者到p点的射线
        v = unitize(minusPoint(camera, p));
    
        if (Obj == 1)
        {
            n = findSphereNormal(p, id);
    
            kd.x = spheres[id].color_diffuse[0];
            kd.y = spheres[id].color_diffuse[1];
            kd.z = spheres[id].color_diffuse[2];
    
            ks.x = spheres[id].color_specular[0];
            ks.y = spheres[id].color_specular[1];
            ks.z = spheres[id].color_specular[2];
    
            n_s = spheres[id].shininess;
        }
    
        else
            if (Obj == 2)
            {
                n = unitize(chazhi(triangles[id], iO, 0));
                kd = chazhi(triangles[id], iO, 1);
                ks = chazhi(triangles[id], iO, 2);
    
                n_s = iO.bary[0] * triangles[id].v[0].shininess
                    + iO.bary[1] * triangles[id].v[1].shininess
                    + iO.bary[2] * triangles[id].v[2].shininess;
            }
    
    
        lDotN = dot(l, n);
        if (lDotN<0)
            lDotN = 0;
        else if (lDotN>1.f)
            lDotN = 1.f;
    
        //R = (2N • L)N - L
        r.x = 2 * lDotN*n.x - l.x;
        r.y = 2 * lDotN*n.y - l.y;
        r.z = 2 * lDotN*n.z - l.z;
    
    
        rDotV = dot(r, v);
        if (rDotV<0)
            rDotV = 0;
        else if (rDotV>1.f)
            rDotV = 1.f;
    
        //计算该点的颜色r,g,b
        po.x = light.color[0] * ((kd.x)*lDotN + ((ks.x)*pow((rDotV), (n_s)))); // r
        po.y = light.color[1] * ((kd.y)*lDotN + ((ks.y)*pow((rDotV), (n_s)))); // g 
        po.z = light.color[2] * ((kd.z)*lDotN + ((ks.z)*pow((rDotV), (n_s)))); // b
        return po;
    }
    
    /*
    与物体相交
    */
    intexPoint intersectObjects(point p1, point p2, point dir, int flag)
    {
        point p, q,raySrc, pixPoint;
        intexPoint intxObj;
        isIn iO;
        iO.in = -1;
        double t, t1, t2, tS, tT;
        int id, Obj;
    
        q = p1;
        t1 = 0;
        id = -1;
        Obj = -1;
    
    
        raySrc = p1;
    
    
        //找到最近的交点
        for (int i = 0; i < num_spheres; i++)
        {
            tS = intersectSphere(spheres[i], raySrc, dir);
            if (t1 == 0 && tS > 1e-10)
            {
                t1 = tS;
                id = i;
                Obj = 1;
            }
            else if (tS <= t1 && tS > 1e-10)
            {
                t1 = tS;
                id = i;
                Obj = 1;
            }
        }
    
        for (int i = 0; i < num_triangles; i++)
        {
            tT = intersectTriangle(triangles[i], raySrc, dir, &iO);
            p = caluPoint(raySrc, dir, tT); //找到交点
                                           //iO = isInTest(triangles[i], p); //判断p点是否在三角形内
    
            if (iO.in == 1)
            {
                if (t1 == 0 && tT > 1e-5)
                {
                    t1 = tT;
                    id = i;
                    Obj = 2;
                    if (flag == 0)
                        q = p;
                    intxObj.iO.bary[0] = iO.bary[0];
                    intxObj.iO.bary[1] = iO.bary[1];
                    intxObj.iO.bary[2] = iO.bary[2];
    
                }
                else if (tT<t1 && tT>1e-5)
                {
                    t1 = tT;
                    id = i;
                    Obj = 2;
                    if (flag == 0)
                        q = p;
                    intxObj.iO.bary[0] = iO.bary[0];
                    intxObj.iO.bary[1] = iO.bary[1];
                    intxObj.iO.bary[2] = iO.bary[2];
                }
            }
        }
    
        if (flag == 1)
        {
            //如果为1则计算从light到p点的距离t2
            if (dir.x != 0)
            {
                t2 = (p2.x - raySrc.x) / dir.x;
            }
            else if (dir.y != 0)
            {
                t2 = (p2.y - raySrc.y) / dir.y;
            }
            else if (dir.z != 0)
            {
                t2 = (p2.z - raySrc.z) / dir.z;
            }
            else t2 = 0;
    
            //t2和t1进行比较,如果t1小于t2则说明没有物体挡住光线 
            if (t1 >= t2)
            {
                Obj = -1;
                id = -1;
            }
        }
        else if ((t1 >= 0) && (Obj == 1))
            q = caluPoint(raySrc, dir, t1);
    
        intxObj.p = q;
        intxObj.t = t1;
        intxObj.tID = id;
        intxObj.tObj = Obj;
        return intxObj;
    }
    
    point findColor(int x, int y)
    {
        //point p, q, dir, light, lightS;
        //point black, pixColor, temp, tempN;
        //intexPoint intxObj, intxFlag;
    
        point black, pixColor, p;
        black.x = 0.0;
        black.y = 0.0;
        black.z = 0.0;
        pixColor = black;
    
        //将像素点转换为世界坐标
        p.x = (((double)x / (double)WIDTH) * 2 * xMax) - xMax;
        p.y = (((double)y / (double)HEIGHT) * 2 * yMax) - yMax;
        p.z = -1;
    
    
        point dir1, p1 = p;
        dir1 = minusPoint(p, cam);
        dir1 = unitize(dir1);
        pixColor = Render(p, dir1);
        if (pixColor.x > 1) pixColor.x = 1.f;
        if (pixColor.y > 1) pixColor.y = 1.f;
        if (pixColor.z > 1) pixColor.z = 1.f;
        return pixColor;
    }
    
    //迭代渲染
    point Render(point p, point dir)
    {
        Steps++;
        point blackColor, pixColor, q, light, dir1, temp, temp1;
        point reflect_ray;
        intexPoint intxObj, intxFlag;
        blackColor.x = 0.0;
        blackColor.y = 0.0;
        blackColor.z = 0.0;
        pixColor = blackColor;
        if (Steps > MaxStep)
        {
            Steps = 0;
            return blackColor;
        }
        point p1 = p;
        intxObj = intersectObjects(p, p1, dir, 0);
        //如果和一个物体有交点
            if (intxObj.tID != -1)
            {
                q = intxObj.p;
    
                reflect_ray = reflect(intxObj, dir);
                pixColor.x += ambient_light[0];
                pixColor.y += ambient_light[1];
                pixColor.z += ambient_light[2];
    
                for (int h = 0; h < num_lights; h++)
                {
                    light.x = lights[h].position[0];
                    light.y = lights[h].position[1];
                    light.z = lights[h].position[2];
    
                    dir1 = minusPoint(light, q);
                    dir1 = unitize(dir1);
                    intxFlag = intersectObjects(q, light, dir1, 1);
    
                    //如果没有物体遮挡
                    if (intxFlag.tID == -1)
                    {
                        //phong模型求出颜色
                        temp = phong(q, intxObj.tID, intxObj.tObj, intxObj.iO, lights[h], cam);
                        pixColor.x += temp.x;
                        pixColor.y += temp.y;
                        pixColor.z += temp.z;
                    }
                }
                temp1 = Render(q, reflect_ray);
                int id = intxObj.tID;
                if (intxObj.tObj == 1)
                {
                    pixColor.x += temp1.x * spheres[id].color_specular[0];
                    pixColor.y += temp1.y * spheres[id].color_specular[1];
                    pixColor.z += temp1.z * spheres[id].color_specular[2];
                }
                else
                {
                    point tp = chazhi(triangles[id], intxObj.iO, 2);
                    pixColor.x += temp1.x * tp.x;
                    pixColor.y += temp1.y * tp.y;
                    pixColor.z += temp1.z * tp.z;
                }
    
            }
            else
            {
                pixColor = blackColor;
                Steps = 0;
            }
            return pixColor;
    }
    //反射的光线的方向
    
    point reflect(intexPoint intx, point dir)
    {
        point result;
        point n;
        if (intx.tObj == 1)
        {
            n = findSphereNormal(intx.p, intx.tID);
        }
        else
        {
            n = unitize(chazhi(triangles[intx.tID], intx.iO, 0));
        }
    
        dir.x = -dir.x;
        dir.y = -dir.y;
        dir.z = -dir.z;
        double r1 = dot(n, dir);
        point n2;
        n2.x = n.x * 2 * r1;
        n2.y = n.y * 2 * r1;
        n2.z = n.z * 2 * r1;
    
        result = n2;
        return result;
    }
    void drawColor()
    {
        unsigned int x, y;
        point pixColor;
    
        for (x = 0; x < WIDTH; x++)
        {
            for (y = 0; y < HEIGHT; y++)
            {
                pixColor = findColor(x, y);
    
                plot_pixel_jpeg(x, y, abs(pixColor.x) * 255, abs(pixColor.y) * 255, abs(pixColor.z) * 255);
            }
        }
    }
    //MODIFY THIS FUNCTION
    void draw_scene()
    {
      unsigned int x,y;
    
      //glPointSize(2.0);
      //glBegin(GL_POINTS);
      //simple output
      for(x=0; x<WIDTH; x++)
      {
    glPointSize(2.0);  
    glBegin(GL_POINTS);
    for(y=0;y < HEIGHT;y++)
    {
     // plot_pixel(x,y,x%256,y%256,(x+y)%256);
            plot_pixel_display(x, y, buffer[HEIGHT - y - 1][x][0], buffer[HEIGHT - y - 1][x][1], buffer[HEIGHT - y - 1][x][2]);
    }
    glEnd();
    glFlush();
      }
      printf("Done!\n"); fflush(stdout);
    }
    
    void plot_pixel_display(int x,int y,unsigned char r,unsigned char g,unsigned char b)
    {
      glColor3f(((double)r)/256.f,((double)g)/256.f,((double)b)/256.f);
      glVertex2i(x,y);
    }
    
    void plot_pixel_jpeg(int x,int y,unsigned char r,unsigned char g,unsigned char b)
    {
      buffer[HEIGHT-y-1][x][0]=r;
      buffer[HEIGHT-y-1][x][1]=g;
      buffer[HEIGHT-y-1][x][2]=b;
    }
    
    void plot_pixel(int x,int y,unsigned char r,unsigned char g, unsigned char b)
    {
      plot_pixel_display(x,y,r,g,b);
      if(mode == MODE_JPEG)
      plot_pixel_jpeg(x,y,r,g,b);
    }
    
    
    
    /*void save_jpg()
    {
      Pic *in = NULL;
    
      in = pic_alloc(640, 480, 3, NULL);
      printf("Saving JPEG file: %s\n", filename);
    
      memcpy(in->pix,buffer,3*WIDTH*HEIGHT);
      if (jpeg_write(filename, in))
    printf("File saved Successfully\n");
      else
    printf("Error in Saving\n");
    
      pic_free(in);  
    
    }*/
    
    void parse_check(char *expected,char *found)
    {
      if(stricmp(expected,found))
    {
      char error[100];
      printf("Expected '%s ' found '%s '\n",expected,found);
      printf("Parse error, abnormal abortion\n");
      exit(0);
    }
    
    }
    
    void parse_doubles(FILE*file, char *check, double p[3])
    {
      char str[100];
      fscanf(file,"%s",str);
      parse_check(check,str);
      fscanf(file,"%lf %lf %lf",&p[0],&p[1],&p[2]);
      printf("%s %lf %lf %lf\n",check,p[0],p[1],p[2]);
    }
    
    void parse_rad(FILE*file,double *r)
    {
      char str[100];
      fscanf(file,"%s",str);
      parse_check("rad:",str);
      fscanf(file,"%lf",r);
      printf("rad: %f\n",*r);
    }
    
    void parse_shi(FILE*file,double *shi)
    {
      char s[100];
      fscanf(file,"%s",s);
      parse_check("shi:",s);
      fscanf(file,"%lf",shi);
      printf("shi: %f\n",*shi);
    }
    
    int loadScene(char *argv)
    {
      FILE *file = fopen(argv,"r");
      int number_of_objects;
      char type[50];
      int i;
      Triangle t;
      Sphere s;
      Light l;
      fscanf(file,"%i",&number_of_objects);
    
      printf("number of objects: %i\n",number_of_objects);
      char str[200];
    
      parse_doubles(file,"amb:",ambient_light);
    
      for(i=0;i < number_of_objects;i++)
    {
      fscanf(file,"%s\n",type);
      printf("%s\n",type);
      if(stricmp(type,"triangle")==0)
        {
    
          printf("found triangle\n");
          int j;
    
          for(j=0;j < 3;j++)
        {
          parse_doubles(file,"pos:",t.v[j].position);
          parse_doubles(file,"nor:",t.v[j].normal);
          parse_doubles(file,"dif:",t.v[j].color_diffuse);
          parse_doubles(file,"spe:",t.v[j].color_specular);
          parse_shi(file,&t.v[j].shininess);
        }
    
          if(num_triangles == MAX_TRIANGLES)
        {
          printf("too many triangles, you should increase MAX_TRIANGLES!\n");
          exit(0);
        }
          triangles[num_triangles++] = t;
        }
      else if(stricmp(type,"sphere")==0)
        {
          printf("found sphere\n");
    
          parse_doubles(file,"pos:",s.position);
          parse_rad(file,&s.radius);
          parse_doubles(file,"dif:",s.color_diffuse);
          parse_doubles(file,"spe:",s.color_specular);
          parse_shi(file,&s.shininess);
    
          if(num_spheres == MAX_SPHERES)
        {
          printf("too many spheres, you should increase MAX_SPHERES!\n");
          exit(0);
        }
          spheres[num_spheres++] = s;
        }
      else if(stricmp(type,"light")==0)
        {
          printf("found light\n");
          parse_doubles(file,"pos:",l.position);
          parse_doubles(file,"col:",l.color);
    
          if(num_lights == MAX_LIGHTS)
        {
          printf("too many lights, you should increase MAX_LIGHTS!\n");
          exit(0);
        }
          lights[num_lights++] = l;
        }
      else
        {
          printf("unknown type in scene description:\n%s\n",type);
          exit(0);
        }
    }
      return 0;
    }
    
    void display()
    {
        cam.x = 0.0;
        cam.y = 0.0;
        cam.z = 0.0;
        glLoadIdentity();
    
        drawColor();
        draw_scene();
    }
    
    void init()
    {
      glMatrixMode(GL_PROJECTION);
      glOrtho(0,WIDTH,0,HEIGHT,1,-1);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
    
      glClearColor(0,0,0,0);
      glClear(GL_COLOR_BUFFER_BIT);
    }
    
    void idle()
    {
      //hack to make it only draw once
      static int once=0;
      if (!once)
      {
          draw_scene();
    //    if (mode == MODE_JPEG)
    //        save_jpg();
      }
      once=1;
    }
    
    int main (int argc, char ** argv)
    {
      if (argc<2 || argc > 3)
      {  
    printf ("usage: %s <scenefile> [jpegname]\n", argv[0]);
    exit(0);
      }
      if(argc == 3)
    {
      mode = MODE_JPEG;
      filename = argv[2];
    }
      else if(argc == 2)
    mode = MODE_DISPLAY;
    
      glutInit(&argc,argv);
      loadScene(argv[1]);
    
      glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
      glutInitWindowPosition(0,0);
      glutInitWindowSize(WIDTH,HEIGHT);
      int window = glutCreateWindow("Ray Tracer");
      glutDisplayFunc(display);
      glutIdleFunc(idle);
      init();
      glutMainLoop();
    }
  • 运行结果如图所示

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值