zoukankan      html  css  js  c++  java
  • OpenGL------光照+染色

    这次做的真是搓,whatever~

      1 /*****
      2     Computer Graphics: HW4
      3     Shading, Lighting, Hidden Surface Removal 
      4 ****/
      5 
      6 /****
      7     Shading:                    Flat Shading in function shading();
      8     Hidden Surface Removal:        Z-Buffer and remove the back face also in shading(); Get Z-value by interpolation;
      9     Light Illumiantion:            for every end point in polygons in function lighting();
     10     Normal Vector:                for a point, it's normal vector is the average normal vector of the surface it belongs to, in funtion cal_normal();
     11     Coloring:                    coloring the whole screen in C-Buffer in function coloring();                    
     12 ****/
     13 
     14 /***
     15     notice: 
     16             To run, you should change the name of test file to HW4.in;
     17             In HW4.in, the first line should be "b 600 600"(add a letter 'b');
     18             Other useless function in hw4 written before is removed;
     19 ***/
     20 
     21 #include <iostream>
     22 #include <string>
     23 #include <cstdlib>
     24 #include <cmath>
     25 #include <cstdio>
     26 #include <vector>
     27 #include <gl/glut.h>
     28 #include <iomanip>
     29 #include <fstream>
     30 #include <algorithm>
     31 
     32 using namespace std;
     33 
     34 const int dimension = 4;
     35 const float PI = acos(-1);
     36 const float eps = 1e-6;
     37 const float INF = 1000000;
     38 const char* filename = "HW4.in";
     39 
     40 struct object {         //object
     41     float r, g, b;
     42     float Kd, Ks;
     43     int N;
     44 }obj[10];
     45 
     46 struct vec {            // vector
     47     float x, y, z;
     48     float r, g, b;
     49     vec(float _x=0, float _y=0, float _z=0, float _r=0, float _g=0, float _b=0):x(_x), y(_y), z(_z), r(_r), g(_g), b(_b){}
     50 };
     51 
     52 vec unit(vec a)            //get unit vector
     53 {
     54     vec res;
     55     float l = sqrt(a.x*a.x+a.y*a.y+a.z*a.z); 
     56     res.x = a.x / l;
     57     res.y = a.y / l;
     58     res.z = a.z / l;
     59     return res;
     60 }
     61 
     62 float dot(vec a, vec b)            //dot
     63 {
     64     return a.x * b.x + a.y * b.y + a.z * b.z;
     65 }
     66 
     67 vec vec_add(vec a, vec b)            // vector addition
     68 {
     69     vec res;
     70     res.x = a.x+b.x;
     71     res.y = a.y+b.y;
     72     res.z = a.z+b.z;
     73     return res;
     74 }
     75 
     76 vec cross(vec a, vec b, int i=0)        //cross
     77 {
     78     vec res;
     79     res.x = a.y * b.z - b.y * a.z;
     80     res.y = -(a.x * b.z - b.x * a.z);
     81     res.z = a.x * b.y - b.x * a.y;
     82     float l = sqrt(res.x*res.x+res.y*res.y+res.z*res.z);
     83     if(i == 0)
     84         res = unit(res);
     85     return res;
     86 }
     87 
     88 struct poly_point {                //end points of polygons
     89     float x, y, z, w;
     90     float r, g, b;
     91     vec Nv;
     92     poly_point(float _x=0, float _y=0, float _z=0, float _w=1, float _r=0, float _g=0, float _b=0, float xx=0, float yy=0, float zz=0)
     93     { x=_x; y=_y; z=_z; w=_w; r=_r; g=_g; b=_b; Nv.x=xx; Nv.y=yy; Nv.z=zz;}
     94 };
     95 
     96 struct mat {                    //matrix 
     97     float m[4][4];
     98     mat()
     99     {
    100         memset(m,0,sizeof(m));
    101         m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;        
    102     }
    103     void reset_mat()
    104     {
    105         memset(m,0,sizeof(m));
    106         m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;
    107     }
    108 };
    109 
    110 mat T,S,R,Rx,Ry,Rz,Sh,TM, M,GRM,EM,Mirrorx, PM, WTVM;
    111 
    112 mat operator * (mat a, mat b)        // re-write * to matrix multiplication 
    113 {
    114     mat c;
    115     memset(c.m,0,sizeof(c.m));
    116     for(int i=0; i<dimension; i++)
    117         for(int j=0; j<dimension; j++)
    118             for(int k=0; k<dimension; k++)
    119                 c.m[i][j] += (a.m[i][k]*b.m[k][j]);        
    120     return c;
    121 }
    122 
    123 // vector multipled by matrix
    124 poly_point mat_mul_vec(mat t, poly_point pp)
    125 {
    126     poly_point res;
    127     res.x = t.m[0][0]*pp.x+t.m[0][1]*pp.y+t.m[0][2]*pp.z+t.m[0][3]*pp.w;
    128     res.y = t.m[1][0]*pp.x+t.m[1][1]*pp.y+t.m[1][2]*pp.z+t.m[1][3]*pp.w;
    129     res.z = t.m[2][0]*pp.x+t.m[2][1]*pp.y+t.m[2][2]*pp.z+t.m[2][3]*pp.w;
    130     res.w = t.m[3][0]*pp.x+t.m[3][1]*pp.y+t.m[3][2]*pp.z+t.m[3][3]*pp.w;
    131     res.r = pp.r;
    132     res.g = pp.g;
    133     res.b = pp.b;
    134     res.Nv.x = pp.Nv.x;
    135     res.Nv.y = pp.Nv.y;
    136     res.Nv.z = pp.Nv.z;
    137     return res;
    138 }
    139 
    140 // print matrix for debug
    141 void print_mat(mat M)
    142 {
    143     for(int i=0; i<dimension; i++)
    144     {
    145         for(int j=0; j<dimension; j++)
    146             printf("%.2lf ", M.m[i][j]);
    147         printf("
    ");
    148     }
    149     printf("
    ");
    150 }
    151 
    152 int num_tm=0;
    153 poly_point poly_vertex[10][2000], observe[10][2000];
    154 int poly_face[10][4000][4];
    155 string file_name;
    156 float Near, Far, FOV;
    157 
    158 //hw4
    159 float r_obj, g_obj, b_obj, Kd, Ks, N; 
    160 float r_back, g_back, b_back, Ka;    
    161 float IP, X, Y, Z;
    162 float sx,sy,sz, tx,ty,tz, rx,ry,rz;
    163 float PX, PY, PZ, CX, CY, CZ, Tilt; 
    164 int ID;
    165 vec light[10];
    166 int face_num[4000];
    167 int ver_nums[10];
    168 int fac_nums[10];
    169 float ZBuffer[1000][1000];
    170 vec CBuffer[1000][1000];
    171 poly_point xx[10];
    172 
    173 int height, width;
    174 int num_vertex, num_face;
    175 void displayFunc(void);
    176 void ReadInput(bool& IsExit);
    177 
    178 //hw4
    179 vec Normal_Vec(poly_point v1, poly_point v2, poly_point v3);    //获得平面法向量 
    180 void WS_TO_SS();                                                //World Space to Screen Space 
    181 void Shading();                                                    //Shading(ZBuffer, CBuffer)
    182 void Coloring();                                                //染色 
    183 void lighting();                                                //给多边形顶点加光照 
    184 void cal_normal();                                                //计算每个多边形顶点的法向量 
    185 
    186 
    187 //hw3
    188 void scale(float sx, float sy, float sz);            
    189 void rotate(float rx, float ry, float rz, int i=0);            
    190 void translate(float tx, float ty, float tz);        
    191 void reset(); 
    192 void observer(float PX, float PY, float PZ, float CX, float CY, float CZ, float Tilt, float Near, float Far, float FOV);
    193 void view(float VL, float VR, float VB, float VT);
    194 void display();
    195 void read_asc_file();
    196 void transform(mat t);
    197 void projection(float AR, float Near, float Far, float FOV);
    198 void per_div();
    199 void transform_observe(mat t);
    200 void DrawWindow(float vl, float vr, float vb, float vt, float r, float g, float b);
    201 void print_mat(mat t);
    202 void print();
    203 
    204 //hw1中已经实现的函数 
    205 void drawDot(int x, int y, float r, float g, float b);    
    206 
    207 void myKeyboard(unsigned char key, int x, int y) 
    208 {
    209     cout << "KEYYYY" << endl;
    210     switch(key) {
    211     // Draw dots with 'd' or 'D'
    212     case 'q':
    213     case 'Q':
    214         //glutMouseFunc(Mymouse);
    215           exit(0);
    216           break;
    217     }
    218 }
    219 
    220 // Read Input
    221 void ReadInput(bool& IsExit)
    222 {
    223     //float sx,sy,sz, tx,ty,tz, rx,ry,rz;
    224     //float PX, PY, PZ, CX, CY, CZ, Tilt;
    225     //ifstream ffin(filename);
    226     //ffin >> width >> height;
    227     //cout << width << " " << height << endl;
    228     string command,comment;
    229     cin >> command;
    230     //cin >> width >> height;
    231     //cout << width << " " << height << endl;
    232     //while(ffin>>command) {
    233     if(command=="b")
    234     {
    235         cout<<command<<endl;
    236         cin >> width >> height;
    237         cout << width << " " << height << endl;
    238     }
    239     //while(cin >> command) {
    240         if (command=="scale")
    241         {
    242             cout<<command<<endl;
    243             cin>>sx>>sy>>sz;
    244             scale(sx,sy,sz);    
    245         }
    246         else if (command=="rotate")
    247         {
    248             cout<<command<<endl;
    249             cin>>rx>>ry>>rz;
    250             rotate(rx,ry,rz,0);    
    251         }
    252         else if (command=="translate")
    253         {
    254             cout<<command<<endl;
    255             cin>>tx>>ty>>tz;
    256             translate(tx,ty,tz);    
    257         }
    258         else if (command=="reset")
    259         {
    260             cout<<command<<endl;
    261             //reset();
    262         }
    263         else if (command=="observer")
    264         {
    265             cout<<command<<endl;
    266             cin>>PX>>PY>>PZ>>CX>>CY>>CZ>>Tilt>>Near>>Far>>FOV;
    267             observer(PX,PY,PZ,CX,CY,CZ,Tilt,Near,Far,FOV);
    268         }
    269         else if (command=="background")
    270         {
    271             cout<<command<<endl;
    272             cin >> r_back >> g_back >> b_back;
    273             DrawWindow(0, width, 0, height, r_back, g_back, b_back);
    274         }
    275         else if (command=="end")
    276         {
    277             cout<<command<<endl;
    278             IsExit=true;
    279             //exit(0);
    280         }
    281         else if (command=="#")
    282         {
    283             getline(cin, comment);
    284         }
    285         else if (command=="display")
    286         {
    287             cout<<command<<endl;
    288             display();
    289         }
    290         else if (command=="object")
    291         {
    292             cout<<command<<endl;
    293             cin >> file_name;
    294             cin >> r_obj >> g_obj >> b_obj >> Kd >> Ks >> N;
    295             read_asc_file();
    296         }
    297         else if (command=="ambient")
    298         {
    299             cout<<command<<endl;
    300             cin >> Ka;
    301         }
    302         else if (command=="light")
    303         {
    304             cout<<command<<endl;
    305             cin >> ID >> IP >> X >> Y >> Z;
    306             light[ID].r = IP;
    307             light[ID].g = IP;
    308             light[ID].b = IP;
    309             light[ID].x = X;
    310             light[ID].y = Y;
    311             light[ID].z = Z;
    312         }
    313     //}
    314     //ffin.close();
    315 }
    316 
    317 
    318 // Display function
    319 void displayFunc(void){
    320   
    321   freopen(filename, "r", stdin);
    322   bool IsExit;
    323   IsExit=false;
    324   // clear the entire window to the background color
    325   glClear(GL_COLOR_BUFFER_BIT);
    326   while (!IsExit)
    327   {
    328     glClearColor(0.0, 0.0, 0.0, 0.0); 
    329 //    redraw();
    330   // draw the contents!!! Iterate your object's data structure!
    331   // flush the queue to actually paint the dots on the opengl window
    332     glFlush();
    333     ReadInput(IsExit);
    334   }
    335  // infile.close();
    336   //exit(0);
    337 }
    338 
    339 
    340 // Main
    341 void main(int ac, char** av) {
    342   //initial();
    343   
    344   int winSizeX, winSizeY;
    345   string name;
    346   if(ac == 3) {
    347     winSizeX = atoi(av[1]);
    348     winSizeY = atoi(av[2]);
    349 //        cout<<"Done";
    350   }
    351   else { // default window size
    352     winSizeX = 600;
    353     winSizeY = 600;
    354 
    355   }
    356  // freopen("test.in", "r", stdin);
    357 //  cout<<"Please input file name:"<<endl;
    358 //  cin>>name;
    359 //  infile.open(name.c_str());
    360  // exit(0);
    361  // infile.open("inp3.txt");
    362 // infile.open(av[1]);
    363   //width  = winSizeX;
    364   //height = winSizeY;
    365 
    366   // initialize OpenGL utility toolkit (glut)
    367   glutInit(&ac, av);
    368 
    369   // single disply and RGB color mapping
    370   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
    371   glutInitWindowSize(winSizeX, winSizeY);      // set window size
    372   glutInitWindowPosition(0, 0);                // set window position on screen
    373   glutCreateWindow("HW4 Window");       // set window title
    374   
    375   // set up the mouse and keyboard callback functions
    376    // register the keyboard action function
    377   glutKeyboardFunc(myKeyboard);
    378   // displayFunc is called whenever there is a need to redisplay the window,
    379   // e.g., when the window is exposed from under another window or when the window is de-iconified
    380   glutDisplayFunc(displayFunc); // register the redraw function
    381   
    382   // set background color
    383   glClearColor(0.0, 0.0, 0.0, 0.0);     // set the background to black
    384   glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
    385 
    386   // misc setup
    387   glMatrixMode(GL_PROJECTION);  // setup coordinate system
    388   glLoadIdentity();
    389   gluOrtho2D(0, winSizeX, 0, winSizeY);
    390   glShadeModel(GL_FLAT);
    391   glFlush();
    392   glutMainLoop();
    393 }
    394 
    395 // 3 transformations
    396 void scale(float sx, float sy, float sz)
    397 {
    398     S.m[0][0]=sx;    S.m[1][1]=sy;    S.m[2][2]=sz;
    399     TM=S*TM;
    400 }
    401 void rotate(float rx, float ry, float rz, int i)
    402 {
    403     if(i == 0)
    404     {
    405         rx = rx * PI / 180.0;    ry = ry * PI / 180.0;    rz = rz * PI / 180.0;
    406     }
    407     Rx.m[1][1]=cos(rx);    Rx.m[2][2]=cos(rx);    Rx.m[1][2]=-sin(rx);    Rx.m[2][1]=sin(rx);
    408     Ry.m[0][0]=cos(ry);    Ry.m[2][2]=cos(ry);    Ry.m[0][2]=sin(ry);        Ry.m[2][0]=-sin(ry);
    409     Rz.m[0][0]=cos(rz);    Rz.m[1][1]=cos(rz);    Rz.m[0][1]=-sin(rz);    Rz.m[1][0]=sin(rz);
    410     R = Rz*Ry*Rx;
    411     TM=R*TM;
    412 }
    413 void translate(float tx, float ty, float tz)
    414 {
    415     T.m[0][3]=tx;    T.m[1][3]=ty;    T.m[2][3]=tz;
    416     TM=T*TM;
    417 }
    418 
    419 // poly_vertex to observe
    420 void reset()
    421 {
    422     int j=num_tm-1;
    423     for(int i=1; i<=ver_nums[num_tm-1]; i++) 
    424     {
    425         observe[j][i].x = poly_vertex[j][i].x; 
    426         observe[j][i].y = poly_vertex[j][i].y;
    427         observe[j][i].z = poly_vertex[j][i].z;
    428     }
    429 }
    430 
    431 //get EM matrix and PM matrix
    432 void observer(float PX, float PY, float PZ, float CX, float CY, float CZ, float Tilt, float Near, float Far, float FOV)
    433 {
    434     //GRM
    435     translate(-PX,-PY,-PZ);
    436     //print_mat(T);
    437     float x = CX-PX;
    438     float y = CY-PY;
    439     float z = CZ-PZ;
    440     //Tilt=Tilt*PI/180.0;
    441     float l=sqrt(x*x+y*y+z*z);
    442     vec v(x,y,z);
    443     vec t(0,1,sin(Tilt*PI/180.0));
    444     vec v3;
    445     v3.x = v.x/l; v3.y = v.y/l; v3.z = v.z/l;
    446     vec v1=cross(v,t);
    447     vec v2=cross(v1,v3);
    448     GRM.m[0][0]=v1.x;    GRM.m[0][1]=v1.y;    GRM.m[0][2]=v1.z;
    449     GRM.m[1][0]=v2.x;    GRM.m[1][1]=v2.y;    GRM.m[1][2]=v2.z;
    450     GRM.m[2][0]=v3.x;    GRM.m[2][1]=v3.y;    GRM.m[2][2]=v3.z;
    451     printf("GRM
    ");
    452     print_mat(GRM);
    453     EM = Mirrorx*GRM*T;
    454     TM.reset_mat();
    455     //print_mat(EM);
    456 }
    457 
    458 //viewport
    459 void view(float VL, float VR, float VB, float VT)
    460 {
    461     float WL=-1, WR=1, WB=-1, WT=1;
    462     translate(-WL, -WB, 0);    
    463     WTVM = T * WTVM;    
    464     scale((VR-VL)/(WR-WL), (VT-VB)/(WT-WB), 1);
    465     WTVM = S * WTVM;    
    466     translate(VL, VB, 0);    
    467     WTVM = T * WTVM;
    468     printf("WTVM
    ");
    469     //print_mat(WTVM);
    470 }
    471 
    472 // display in screen
    473 void display()
    474 {
    475     DrawWindow(0, width, 0, height, r_back, g_back, b_back);
    476     lighting();
    477     view(0, width, 0, height);
    478     WS_TO_SS();
    479     //print();
    480     Shading();
    481     Coloring();
    482     //////////////////////////
    483     reset();
    484     EM.reset_mat();
    485     PM.reset_mat();
    486     WTVM.reset_mat();
    487 }
    488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    489 // read oject store the data in obj[]
    490 void read_asc_file()
    491 {
    492     num_tm++;
    493 
    494     cout << file_name << endl;
    495     ifstream fin(file_name);
    496     fin >> ver_nums[num_tm-1] >> fac_nums[num_tm-1];
    497     cout << ver_nums[num_tm-1] << " " << fac_nums[num_tm-1] << endl;
    498 
    499     // read vertex one by one
    500     for(int i=1; i<=ver_nums[num_tm-1]; i++) 
    501     {
    502         fin >> poly_vertex[num_tm-1][i].x >> poly_vertex[num_tm-1][i].y >> poly_vertex[num_tm-1][i].z;
    503     }
    504     // read face one by one
    505     for(int i=0; i<fac_nums[num_tm-1]; i++) 
    506     {
    507         fin >> face_num[num_tm-1];    //faces num 3 or 4
    508         for(int j=0; j<face_num[num_tm-1]; j++)
    509             fin >> poly_face[num_tm-1][i][j];
    510     }
    511     obj[num_tm-1].r =  r_obj;
    512     obj[num_tm-1].g =  g_obj;
    513     obj[num_tm-1].b =  b_obj;
    514     obj[num_tm-1].Kd = Kd;
    515     obj[num_tm-1].Ks = Ks;
    516     obj[num_tm-1].N = N;
    517     //cout << "objectcolor!!!" <<r_obj << " " << g_obj << " " << b_obj << endl;
    518     transform(TM);//
    519     reset();
    520     cal_normal();
    521     TM.reset_mat();
    522 }
    523 
    524 // calculate normal vector for every point
    525 void cal_normal()
    526 {
    527     //for(int k=0; k<num_tm; k++)
    528     {
    529         int k = num_tm-1;
    530         for(int i=0; i<fac_nums[k]; i++) 
    531         {
    532             vec Nvec = Normal_Vec(observe[k][poly_face[k][i][0]], observe[k][poly_face[k][i][1]], observe[k][poly_face[k][i][2]]);
    533             for(int j=0; j<face_num[k]; j++)
    534             {
    535                 observe[k][poly_face[k][i][j]].Nv.x += Nvec.x;
    536                 observe[k][poly_face[k][i][j]].Nv.y += Nvec.y;
    537                 observe[k][poly_face[k][i][j]].Nv.z += Nvec.z;
    538             }
    539         }
    540     }
    541 }
    542 
    543 //lighting the end points for every polygons
    544 void lighting()
    545 {    
    546     cout << "num_tm: " << num_tm << endl;
    547     for(int k=0; k<num_tm; k++)
    548     {
    549         //float fatt=1, diffuse=0, specular=0;
    550         for(int i=1; i<=ver_nums[k]; i++)
    551         {
    552             //for(int i=1; i<=ver_nums[k]; i++)
    553             float fatt=1, diffuse=0, specular=0;
    554             for(int j=1; j<=ID; j++)
    555             {
    556                 vec N, L, H, V;        //Normal, Lighting, H, View vector
    557                 L.x = observe[k][i].x - light[j].x;        L.y =  observe[k][i].y - light[j].y;        L.z = observe[k][i].z - light[j].z;
    558                 L = unit(L);
    559                 N.x = observe[k][i].Nv.x;    N.y = observe[k][i].Nv.y;    N.z = observe[k][i].Nv.z;
    560                 N = unit(N);
    561                 V.x = CX-PX;    V.y = CY-PY;    V.z = CZ-PZ;
    562                 V = unit(V);
    563                 H = vec_add(L, V);
    564                 H = unit(H);
    565                 float temp, temp1;
    566                 if(num_tm > 2 && (k == 0 || k == 1 || k == 2))        //notice that the r, g, b shuold be positive
    567                     temp = (pow(dot(H, N), obj[k].N));
    568                 else
    569                     temp = pow(abs(dot(H, N)), obj[k].N);
    570                 if(num_tm > 2 && (k == 0 || k == 1 || k == 2))
    571                     temp1 = (dot(N, L));
    572                 else
    573                     temp1 = abs(dot(N, L));
    574 
    575                 diffuse += obj[k].Kd * light[j].r * temp1;                
    576                 specular += obj[k].Ks * light[j].r * temp;            
    577             }
    578             //cout<<"color "<<obj[k].r<<" "<<obj[k].g<<" "<<obj[k].b<<endl;
    579             observe[k][i].r = Ka * obj[k].r + diffuse * obj[k].r + specular;
    580             observe[k][i].g = Ka * obj[k].g + diffuse * obj[k].g + specular;
    581             observe[k][i].b = Ka * obj[k].b + diffuse * obj[k].b + specular;
    582             
    583             if(observe[k][i].r > 1)        observe[k][i].r = 1;
    584             if(observe[k][i].g > 1)        observe[k][i].g = 1;
    585             if(observe[k][i].b > 1)        observe[k][i].b = 1;
    586             //cout << observe[k][i].r << " " << observe[k][i].g << " " << observe[k][i].b << " " << endl;
    587             //print();
    588         }
    589     }
    590     //print();
    591 }
    592 
    593 // transform points' coordinate in matrix transformation
    594 void transform(mat t)
    595 {
    596     for(int i=1; i<=ver_nums[num_tm-1]; i++) 
    597         poly_vertex[num_tm-1][i] = mat_mul_vec(t, poly_vertex[num_tm-1][i]);
    598 }
    599 void transform_observe(mat t)
    600 {
    601     for(int j=0; j<num_tm; j++)
    602     {
    603         for(int i=1; i<=ver_nums[j]; i++) 
    604             observe[j][i] = mat_mul_vec(t, observe[j][i]);
    605     }
    606 }    
    607 
    608 // projection
    609 void projection(float AR, float Near, float Far, float FOV)
    610 {
    611     //PM
    612     FOV=FOV*PI/180.0;
    613     float Y=Far*tan(FOV);
    614     float H=Near*tan(FOV);
    615     PM.m[1][1]=AR;
    616     PM.m[2][2]=Y/(Y-H)*tan(FOV);
    617     PM.m[2][3]=Y*H/(H-Y)*tan(FOV);
    618     PM.m[3][2]=tan(FOV);
    619     PM.m[3][3]=0;
    620     //print_mat(PM);
    621 }
    622 
    623 // perspective divide
    624 void per_div()
    625 {
    626     for(int j=0; j<num_tm; j++)
    627     {
    628         for(int i=1; i<=ver_nums[j]; i++) 
    629         {
    630             observe[j][i].x /= observe[j][i].w;
    631             observe[j][i].y /= observe[j][i].w;
    632             observe[j][i].z /= observe[j][i].w;
    633             observe[j][i].w /= observe[j][i].w;
    634         }
    635     }
    636     
    637 }
    638 
    639 //background: color the background and viewport
    640 void DrawWindow(float vl, float vr, float vb, float vt, float r, float g, float b)
    641 {
    642     cout << "Windows!!!" <<width << " " << height << endl;
    643     for(int y=0; y<width; y++)
    644         for(int x=0; x<height; x++)
    645         {
    646             ZBuffer[y][x]=INF;
    647             CBuffer[y][x].r = r;
    648             CBuffer[y][x].g = g;
    649             CBuffer[y][x].b = b;
    650             //drawDot(x, y, r, g, b);
    651         }    
    652 }
    653 
    654 // coloring the whole screen
    655 void Coloring()
    656 {
    657     cout << "Coloring!!!" << width << " " << height << endl;
    658     for(int y=0; y<width; y++)
    659         for(int x=0; x<height; x++)
    660             drawDot(x, height-y, CBuffer[y][x].r, CBuffer[y][x].g, CBuffer[y][x].b);
    661 }
    662 
    663 // world space to screen space
    664 void WS_TO_SS()
    665 {
    666     projection(width/height,Near,Far,FOV);
    667     //print();
    668     transform_observe(EM);
    669     //print();
    670     transform_observe(PM);
    671     //print();
    672     per_div();
    673     //print();
    674     transform_observe(WTVM);
    675     cout << "num_tm: " << num_tm << endl;
    676 }
    677 
    678 // find normal vector
    679 vec Normal_Vec(poly_point v1, poly_point v2, poly_point v3)
    680 {
    681     vec v1_v2, v2_v3, Nv;    //plan equation
    682     v1_v2.x = v2.x - v1.x;
    683     v1_v2.y = v2.y - v1.y;
    684     v1_v2.z = v2.z - v1.z;
    685     v2_v3.x = v3.x - v2.x;
    686     v2_v3.y = v3.y - v2.y;
    687     v2_v3.z = v3.z - v2.z;
    688     Nv = cross(v1_v2, v2_v3, 1);
    689     return Nv;
    690 }
    691 
    692 // cmp in sort
    693 bool cmp(poly_point a, poly_point b)
    694 {
    695     return a.x < (b.x+eps);
    696 }
    697 
    698 //shading function: Flat Shading
    699 void Shading()
    700 {        
    701     //print();
    702     const int max_num_tm=7;
    703     for(int k=0; k<num_tm; k++)
    704     {        
    705         int n = face_num[k];
    706         for(int i=0; i<fac_nums[k]; i++) 
    707         {        
    708             if(num_tm < max_num_tm)
    709             {
    710                 // Remove the back face
    711                 vec Nvec = Normal_Vec(poly_vertex[k][poly_face[k][i][0]], poly_vertex[k][poly_face[k][i][1]], poly_vertex[k][poly_face[k][i][2]]);
    712                 Nvec = unit(Nvec);
    713                 vec V;
    714                 V.x = CX-PX;    V.y = CY-PY;    V.z = CZ-PZ;
    715                 V = unit(V);
    716                 if(dot(Nvec, V)<0)
    717                     continue;
    718             }
    719             poly_point p1, p2, p0;
    720             float xmin=600, xmax=0, ymin=600, ymax=0;
    721             float r=0, g=0, blue=0;
    722             for(int j=0; j<n; j++)
    723             {
    724                 ymax = max(ymax, observe[k][poly_face[k][i][j]].y);
    725                 ymin = min(ymin, observe[k][poly_face[k][i][j]].y);
    726                 xmax = max(xmax, observe[k][poly_face[k][i][j]].x);
    727                 xmin = min(xmin, observe[k][poly_face[k][i][j]].x);
    728                 r += observe[k][poly_face[k][i][j]].r;
    729                 g += observe[k][poly_face[k][i][j]].g;
    730                 blue += observe[k][poly_face[k][i][j]].b;
    731             }
    732             r /= n;        g /= n;        blue /= n;                        //Get the average color
    733             //cout<<"average color: "<<r<<" "<<g<<" "<<blue<<endl;
    734 
    735             for(int y=ymin-1; y<=ymax+1; y++)        //y-scan_line
    736             {
    737                 //cout << "y: " << y << endl;
    738                 int cnt=0;
    739                 for(int j=0; j<n-1; j++)
    740                 {
    741                     p1=observe[k][poly_face[k][i][j]];
    742                     p2=observe[k][poly_face[k][i][j+1]];
    743                     p1.z=observe[k][poly_face[k][i][j]].z;
    744                     p2.z=observe[k][poly_face[k][i][j+1]].z;
    745                     
    746                     p0.x = (y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
    747                     p0.y = y;
    748                     p0.z = (p2.z-p1.z)/(p2.y-p1.y)*(p0.y-p1.y)+p1.z;     //Get Z-value by interpolation
    749                     if(p1.y > p2.y || p2.y > p1.y)
    750                     {
    751                         if(y <= max(p1.y, p2.y) && y >= min(p1.y, p2.y))
    752                             xx[cnt++] = p0;
    753                     }
    754                     if(abs(p0.x-xmax)<eps || abs(p0.x-xmin)<eps)
    755                     {
    756                         int minx = min(p1.x, p2.x);
    757                         int maxx = max(p1.x, p2.x);
    758                         for (int x = minx; x <= maxx; x++)
    759                         {
    760                             float z = (p2.z - p1.z) / (p2.x - p1.x)*(x - p1.x) + p1.z;
    761                             //cout << z << endl;
    762                             if (z < ZBuffer[y][x] && (x < 265 || x > 335))            //Z-Buffer && CBuffer
    763                             {
    764                                 ZBuffer[y][x] = z;
    765                                 CBuffer[y][x].r = r;
    766                                 CBuffer[y][x].g = g;
    767                                 CBuffer[y][x].b = blue;
    768                             }
    769                         }
    770                     }
    771                 }
    772                 
    773                 p1=observe[k][poly_face[k][i][n-1]];
    774                 p2=observe[k][poly_face[k][i][0]];
    775                 p1.z=observe[k][poly_face[k][i][n-1]].z;
    776                 p2.z=observe[k][poly_face[k][i][0]].z;
    777                 if(p1.y > p2.y || p2.y > p1.y)
    778                 {
    779                     p0.x = (y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
    780                     p0.y = y;
    781                     p0.z = (p2.z-p1.z)/(p2.y-p1.y)*(p0.y-p1.y)+p1.z;
    782                     if(y <= max(p1.y, p2.y) && y >= min(p1.y, p2.y))
    783                         xx[cnt++] = p0;
    784                 }
    785                 if(abs(p0.x-xmax)<eps || abs(p0.x-xmin)<eps)
    786                 {
    787                     int minx = min(p1.x, p2.x);
    788                         int maxx = max(p1.x, p2.x);
    789                         for (int x = minx; x <= maxx; x++)
    790                         {
    791                             float z = (p2.z - p1.z) / (p2.x - p1.x)*(x - p1.x) + p1.z;
    792                             //cout << z << endl;
    793                             if (z < ZBuffer[y][x] && (x < 265 || x > 335))
    794                             {
    795                                 ZBuffer[y][x] = z;
    796                                 CBuffer[y][x].r = r;
    797                                 CBuffer[y][x].g = g;
    798                                 CBuffer[y][x].b = blue;
    799                             }
    800                         }
    801                 }
    802                 if(cnt==2)        // find two intersect points
    803                 {        
    804                     //cout << "intersect" << endl;
    805                     sort(xx, xx+cnt, cmp);
    806                     for(int x=xx[0].x; x<xx[1].x; x++)
    807                     {
    808                         poly_point a = xx[0];
    809                         poly_point b = xx[1];
    810                         float z = (b.z-a.z)/(b.x-a.x)*(x-a.x)+a.z;                    
    811                         if(y >= 0 && y <= width && x >= 0 && x <= height && z < ZBuffer[(int)y][(int)x])
    812                         {
    813                             ZBuffer[y][x] = z;
    814                             CBuffer[y][x].r = r;
    815                             CBuffer[y][x].g = g;
    816                             CBuffer[y][x].b = blue;
    817                         }
    818                     }        
    819                 }
    820             }
    821         }
    822     }
    823 }
    824 
    825 //print r, g, b for debug
    826 void print()
    827 {
    828     for(int k=0; k<num_tm; k++)
    829     {
    830         int n=face_num[num_tm-1];
    831         for(int i=0; i<fac_nums[k]; i++) 
    832         {
    833             for(int j=0; j<n; j++)
    834                 cout << observe[k][poly_face[k][i][j]].r << " " << observe[k][poly_face[k][i][j]].g << " " << observe[k][poly_face[k][i][j]].b << endl;
    835             
    836         }
    837     }
    838 }
    839 /////////////////////////////////////////////////////////////////////////hw1/////////////////////////////////////////////////
    840 // draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
    841 void drawDot(int x, int y, float r, float g, float b) 
    842 {
    843     glBegin(GL_POINTS);
    844   
    845     // set the color of dot
    846     glColor3f(r, g, b);
    847   
    848     // invert height because the opengl origin is at top-left instead of bottom-left
    849     glVertex2i(x ,  height-y);
    850   
    851     glEnd();
    852 }
  • 相关阅读:
    【react】---react中使用装饰器
    【react】---react中key值的作用
    【react】---react项目中如何使用iconfont
    【react】---redux-actions的基本使用---【巷子】
    linux查看硬件配置
    ssh实现内网穿透
    base_convert()函数探秘及小bug记录
    【转】ASCII码表
    【转载】在C语言中,double、long、unsigned、int、char类型数据所占字节数
    xdebug及phpstorm、vim+dbgpy远程调试配置以及xdebug profile+webgrind笔记
  • 原文地址:https://www.cnblogs.com/dominjune/p/4602627.html
Copyright © 2011-2022 走看看