Advertisement
Guest User

Untitled

a guest
Nov 24th, 2017
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.65 KB | None | 0 0
  1. /**
  2.  * minigl.cpp
  3.  * -------------------------------
  4.  * Implement miniGL here.
  5.  *
  6.  * You may include minigl.h and any of the standard C++ libraries.
  7.  * No other includes are permitted.  Other preprocessing directives
  8.  * are also not permitted.  These requirements are strictly
  9.  * enforced.  Be sure to run a test grading to make sure your file
  10.  * passes the sanity tests.
  11.  *
  12.  * The behavior of the routines your are implenting is documented here:
  13.  * https://www.opengl.org/sdk/docs/man2/
  14.  * Note that you will only be implementing a subset of this.  In particular,
  15.  * you only need to implement enough to pass the tests in the suite.
  16.  */
  17.  
  18. #include "minigl.h"
  19. #include "vec.h"
  20. #include "mat.h"
  21. #include <algorithm>
  22. #include <cassert>
  23. #include <cmath>
  24. #include <vector>
  25. #include <cstdio>
  26. #include <stack>
  27.  
  28. using namespace std;
  29.  
  30. /**
  31.  * Useful data types
  32.  */
  33. typedef mat<MGLfloat,4,4> mat4; //data structure storing a 4x4 matrix, see mat.h
  34. typedef mat<MGLfloat,3,3> mat3; //data structure storing a 3x3 matrix, see mat.h
  35. typedef vec<MGLfloat,4> vec4;   //data structure storing a 4 dimensional vector, see vec.h
  36. typedef vec<MGLfloat,3> vec3;   //data structure storing a 3 dimensional vector, see vec.h
  37. typedef vec<MGLfloat,2> vec2;   //data structure storing a 2 dimensional vector, see vec.h
  38.  
  39. class Pixel;
  40. class Matrix;
  41. struct vertex;
  42. class BoundingBox;
  43. struct triangle;
  44.  
  45. MGLpoly_mode draw_mode;
  46. vector<vertex> vectorlist;
  47. vec3 current_color;
  48. vector<triangle> trianglelist;
  49. vector<Pixel> frameBuffer;
  50. vector<Pixel> zBuffer;
  51. bool failure = false;
  52. MGLmatrix_mode matrix_mode;
  53. stack <Matrix> modelMatrixS;
  54. stack <Matrix> projMatrixS;
  55.  
  56. class Pixel
  57. {
  58.     public:
  59.     int x,y;
  60.     MGLpixel pColor;
  61.     MGLfloat z;
  62.    
  63.     Pixel(int X, int Y, MGLpixel c, MGLfloat Z) : x(X), y(Y), pColor(c), z(Z) {}
  64. };
  65.  
  66. class Matrix
  67. {
  68.     // variables
  69.     public:
  70.     MGLfloat matrix[4][4];
  71.    
  72.     Matrix()
  73.     {
  74.         clearMatrix();
  75.         initMatrix (0, 0, 0);
  76.     }
  77.    
  78.     Matrix(MGLfloat X, MGLfloat Y, MGLfloat Z)
  79.     {
  80.         clearMatrix();
  81.         initMatrix (X, Y, Z);
  82.     }
  83.    
  84.     Matrix& operator= (const Matrix& rhs)
  85.     {
  86.         if (this != &rhs)
  87.         {
  88.             for (int row = 0; row < 4; ++row)
  89.                 for (int col = 0; col < 4; ++col)
  90.                     matrix[row][col] = rhs.matrix[row][col];
  91.         }
  92.        
  93.         return *this;
  94.     }
  95.    
  96.     // Currently unused. mglMultMatrix is used instead.
  97.     Matrix operator* (const Matrix& rhs)
  98.     {
  99.         Matrix result;
  100.         result.clearMatrix();
  101.        
  102.         MGLfloat sum = 0;
  103.        
  104.         for (int i = 0; i < 4; ++i)
  105.         {
  106.             for (int j = 0; j < 4; ++j)
  107.             {
  108.                 sum = 0;
  109.                 for (int k = 0; k < 4; ++k)
  110.                     sum += matrix[i][k] * rhs.matrix[k][j];
  111.                 result.matrix[i][j] = sum;
  112.             }
  113.         }
  114.            
  115.         return result;
  116.     }
  117.    
  118.     friend ostream& operator<< (ostream& os, const Matrix& m)
  119.     {
  120.         for (int row = 0; row < 4; ++row)
  121.         {
  122.             for (int col = 0; col < 4; ++col)
  123.                 os << m.matrix[row][col] << " ";
  124.             os << "\n";
  125.         }
  126.         return os;
  127.        
  128.     }
  129.    
  130.     void clearMatrix()
  131.     {
  132.         for (int row = 0; row < 4; ++row)
  133.             for (int col = 0; col < 4; ++col)
  134.                 matrix[row][col] = 0;
  135.     }
  136.    
  137.     void createScaler(float x, float y, float z)
  138.     {
  139.         clearMatrix();
  140.         matrix[0][0] = x;
  141.         matrix[1][1] = y;
  142.         matrix[2][2] = z;
  143.         matrix[3][3] = 1;
  144.     }
  145.    
  146.     void createTranslater(MGLfloat X, MGLfloat Y, MGLfloat Z)
  147.     {
  148.         matrix[0][0] = 1;
  149.         matrix[1][1] = 1;
  150.         matrix[2][2] = 1;
  151.         matrix[3][3] = 1;
  152.        
  153.         matrix[0][3] = X;
  154.         matrix[1][3] = Y;
  155.         matrix[2][3] = Z;
  156.     }  
  157.    
  158.     private:
  159.     void initMatrix (MGLfloat X, MGLfloat Y, MGLfloat Z)
  160.     {  
  161.         // set w
  162.         matrix[3][3] = 1;
  163.        
  164.         // set the x, y, z coordinate
  165.         matrix[0][3] = X;
  166.         matrix[1][3] = Y;
  167.         matrix[2][3] = Z;
  168.     }
  169. };
  170.  
  171. struct vertex {
  172.   vec3 color;
  173.   vec4 pos;
  174.   vec4 xyzw_Screen;
  175.   MGLpixel vColor[3];
  176.  
  177.   friend ostream& operator<< (ostream& os, const vertex& v)
  178.     {
  179.         os << "( " << v.pos[0] << ", " << v.pos[1] << ", " << v.pos[2] << ", " << v.pos[3] << " ) " << endl;
  180.         return os;
  181.        
  182.     }
  183.    
  184.     vertex& operator= (const vertex& rhs)
  185.     {
  186.         if (this != &rhs)
  187.         {
  188.             pos[0] = rhs.pos[0];
  189.             pos[1] = rhs.pos[1];
  190.             pos[2] = rhs.pos[2];
  191.             pos[3] = rhs.pos[3];
  192.             color[0] = rhs.color[0];
  193.             color[1] = rhs.color[1];
  194.             color[2] = rhs.color[2];
  195.            
  196.             xyzw_Screen[0] = rhs.xyzw_Screen[0];
  197.             xyzw_Screen[1] = rhs.xyzw_Screen[1];
  198.             xyzw_Screen[2] = rhs.xyzw_Screen[2];
  199.             xyzw_Screen[3] = rhs.xyzw_Screen[3];
  200.         }
  201.        
  202.         return *this;
  203.     }
  204.    
  205.     /* This operation performs matrix and vector multiplication.
  206.      * The vector must be on the left of *, and the matrix must be on
  207.      * the right.
  208.      *
  209.      * It follows the matrix * vector order of multiplication.
  210.      */
  211.     vertex operator* (const Matrix& rhs)
  212.     {
  213.         MGLfloat currVertex[4] = {pos[0], pos[1], pos[2], pos[3]};
  214.         MGLfloat newVertex[4] = {0, 0, 0, 0};
  215.        
  216.         MGLfloat sum, val = 0;
  217.        
  218.         // [ Vertex ] [ Matrix ]
  219.         for (int row = 0; row < 4; ++row)
  220.         {
  221.             sum = 0;
  222.             for (int col = 0; col < 4; ++col)
  223.             {
  224.                 val = currVertex[col];
  225.                 sum += rhs.matrix[row][col] * val; 
  226.             }
  227.            
  228.             newVertex[row] = sum;
  229.             //cout << "row: " << row << " sum: " << sum << endl;
  230.         }
  231.        
  232.         vertex v;
  233.         v.pos =  vec4(newVertex[0], newVertex[1], newVertex[2], newVertex[3]);
  234.         return v;
  235. }
  236.  
  237.   void vscaletoscreen(MGLsize width, MGLsize height)
  238.  
  239.   {
  240.       pos[0] = pos[0]/pos[3];
  241.       pos[1] = pos[1]/pos[3];
  242.       pos[2] = pos[2]/pos[3];
  243. //    pos[3] = pos[3]/pos[3];
  244.  
  245.      MGLfloat  i = ((pos[0] + 1) * width) /2 -0.5;
  246.      MGLfloat  j = ((pos[1] + 1) * height) /2 - 0.5;
  247.  
  248.       if (i > width)
  249.         i = width;
  250.  
  251.       xyzw_Screen[0] = i;
  252.       xyzw_Screen[1] = j;
  253.       xyzw_Screen[2] = pos[2];
  254.       xyzw_Screen[3] = pos[3];
  255. //    cout << "TESTS:    " << xyzw_Screen[0] << " " << xyzw_Screen[1] << " " << xyzw_Screen[2] << " " << xyzw_Screen[3] << endl;
  256.   }
  257.  
  258.     void applyTransformations()
  259.     {
  260.         Matrix model = modelMatrixS.top();
  261.         Matrix proj = projMatrixS.top();
  262.         Matrix trans;
  263.         trans.createTranslater(1, 1, 1);
  264.  
  265.         vertex v;
  266.         v.pos = pos;       
  267.         v = v * model;
  268.         v = v * proj;  
  269.         //v = v * trans;   
  270.        
  271.            
  272.         // update the x, y, z, w values.
  273.         pos[0] = v.pos[0];
  274.         pos[1] = v.pos[1];
  275.         pos[2] = v.pos[2];
  276.         pos[3] = v.pos[3];
  277. }      
  278. };
  279.  
  280. struct triangle {
  281.   vertex a,b,c;
  282.  
  283.   void scaletoscreen(MGLsize width, MGLsize height)
  284.   {
  285.       a.vscaletoscreen(width, height);
  286.       b.vscaletoscreen(width, height);
  287.       c.vscaletoscreen(width, height);
  288.      
  289.   }
  290. };
  291.  
  292. class BoundingBox
  293. {
  294. public:
  295.     float min_x, max_x, min_y, max_y;
  296.  
  297.     BoundingBox()
  298.         : min_x(0), max_x(0), min_y(0), max_y(0)
  299.     {}
  300.  
  301.     void initBB(const triangle& t)
  302.     {
  303.         min_x = getMin_X(t);
  304.         min_y = getMin_Y(t);
  305.         max_x = getMax_X(t);
  306.         max_y = getMax_Y(t);
  307.     }
  308.    
  309.     void initBB(const triangle& t1, const triangle& t2)
  310.     {
  311.         min_x = getMin_X(t1, t2.c);
  312.         min_y = getMin_Y(t1, t2.c);
  313.         max_x = getMax_X(t1, t2.c);
  314.         max_y = getMax_Y(t1, t2.c);
  315.     }
  316.  
  317. private:
  318.     // returns the minimum value
  319.     float getMin_X(const triangle& t)
  320.     {
  321.         float min = t.a.xyzw_Screen[0];
  322.  
  323.         if (t.b.xyzw_Screen[0] < min) min = t.b.xyzw_Screen[0];
  324.         if (t.c.xyzw_Screen[0] < min) min = t.c.xyzw_Screen[0];
  325.         return min;
  326.     }
  327.  
  328.     float getMin_Y(const triangle& t)
  329.     {
  330.         float min = t.a.xyzw_Screen[1];
  331.  
  332.         if (t.b.xyzw_Screen[1] < min) min = t.b.xyzw_Screen[1];
  333.         if (t.c.xyzw_Screen[1] < min) min = t.c.xyzw_Screen[1];
  334.  
  335.         return min;
  336.     }
  337.  
  338.     float getMax_X(const triangle& t)
  339.     {
  340.         float max = t.a.xyzw_Screen[0];
  341.  
  342.         if (t.b.xyzw_Screen[0] > max) max = t.b.xyzw_Screen[0];
  343.         if (t.c.xyzw_Screen[0] > max) max = t.c.xyzw_Screen[0];
  344.  
  345.         return max;
  346.     }
  347.  
  348.     float getMax_Y(const triangle& t)
  349.     {
  350.         float max = t.a.xyzw_Screen[1];
  351.  
  352.         if (t.b.xyzw_Screen[1] > max) max = t.b.xyzw_Screen[1];
  353.         if (t.c.xyzw_Screen[1] > max) max = t.c.xyzw_Screen[1];
  354.  
  355.         return max;
  356.     }
  357.    
  358.     float getMin_X(const triangle& t, const vertex& v)
  359.     {
  360.         float min = t.a.xyzw_Screen[0];
  361.  
  362.         if (t.b.xyzw_Screen[0] < min) min = t.b.xyzw_Screen[0];
  363.         if (t.c.xyzw_Screen[0] < min) min = t.c.xyzw_Screen[0];
  364.         if (v.xyzw_Screen[0] < min) min = v.xyzw_Screen[0];
  365.        
  366.         return min;
  367.     }
  368.  
  369.     float getMin_Y(const triangle& t, const vertex& v)
  370.     {
  371.         float min = t.a.xyzw_Screen[1];
  372.  
  373.         if (t.b.xyzw_Screen[1] < min) min = t.b.xyzw_Screen[1];
  374.         if (t.c.xyzw_Screen[1] < min) min = t.c.xyzw_Screen[1];
  375.         if (v.xyzw_Screen[1] < min) min = v.xyzw_Screen[1];
  376.  
  377.         return min;
  378.     }
  379.  
  380.     float getMax_X(const triangle& t, const vertex& v)
  381.     {
  382.         float max = t.a.xyzw_Screen[0];
  383.  
  384.         if (t.b.xyzw_Screen[0] > max) max = t.b.xyzw_Screen[0];
  385.         if (t.c.xyzw_Screen[0] > max) max = t.c.xyzw_Screen[0];
  386.         if (v.xyzw_Screen[0] > max) max = v.xyzw_Screen[0];
  387.  
  388.         return max;
  389.     }
  390.  
  391.     float getMax_Y(const triangle& t , const vertex& v)
  392.     {
  393.         float max = t.a.xyzw_Screen[1];
  394.  
  395.         if (t.b.xyzw_Screen[1] > max) max = t.b.xyzw_Screen[1];
  396.         if (t.c.xyzw_Screen[1] > max) max = t.c.xyzw_Screen[1];
  397.         if (v.xyzw_Screen[1] > max) max = v.xyzw_Screen[1];
  398.  
  399.         return max;
  400.     }
  401.  
  402. };
  403.  
  404.  
  405.  
  406. /**
  407.  * Standard macro to report errors
  408.  */
  409. inline void MGL_ERROR(const char* description) {
  410.     printf("%s\n", description);
  411.     exit(1);
  412. }
  413.  
  414. void set_pixel(int x, int y, MGLpixel c, MGLfloat z)
  415. {
  416.     Pixel pix(x,y,c,z);
  417.     frameBuffer.push_back(pix);
  418.     zBuffer.push_back(pix);
  419.    
  420. }
  421.  
  422. void conv2screencoord(MGLsize width, MGLsize height, triangle& t)
  423. {
  424.    
  425.         t.scaletoscreen(width, height);
  426.    
  427. }
  428.  
  429. float bary(float x, float y, float x_b, float y_b, float x_c, float y_c)
  430. {
  431.     return (y_b - y_c)*x + (x_c - x_b)*y + ((x_b*y_c) - (x_c*y_b));
  432. }
  433.  
  434. bool sortByZ(Pixel a, Pixel b) { return a.z > b.z; }
  435.  
  436. MGLpixel mixColors(float alpha, float beta, float gamma, const vec3 vColor1, const vec3 vColor2, const vec3 vColor3)
  437. {
  438.    
  439.         float newR = alpha*vColor1[0] + beta*vColor2[0] + gamma*vColor3[0];
  440.         float newG = alpha*vColor1[1] + beta*vColor2[1] + gamma*vColor3[1];
  441.         float newB = alpha*vColor1[2] + beta*vColor2[2] + gamma*vColor3[2];
  442.         MGLpixel newColor;
  443.         float r = 255* newR;
  444.         float g = 255* newG;
  445.         float b = 255* newB;
  446.         newColor = Make_Pixel(r,g,b);
  447. //      newColor = Make_Pixel(255, 255, 255);
  448.         return newColor;
  449. }
  450.  
  451. void drawTriangle(int x, int y, const vertex& a, const vertex& b, const vertex& c)
  452. {
  453.     // vertex A
  454.     float x_a = a.xyzw_Screen[0];
  455.     float y_a = a.xyzw_Screen[1];
  456.     // vertex B
  457.     float x_b = b.xyzw_Screen[0];
  458.     float y_b = b.xyzw_Screen[1];
  459.  
  460.     // vertex C
  461.     float x_c = c.xyzw_Screen[0];
  462.     float y_c = c.xyzw_Screen[1];
  463.    
  464.  
  465.    
  466. //  MGLfloat fabc = ((y_a - y_b)*x_c) + ((x_b - x_a)*y_c) + (x_a*y_b - x_b*y_a);
  467. //  MGLfloat facb = ((y_c - y_a)*x_b) + ((x_a - x_c)*y_c) + (x_c*y_a - x_a*y_c);
  468. //  MGLfloat fbca = ((y_b - y_c)*x_a) + ((x_c - x_b)*y_a) + (x_b*y_c - x_c*y_b);
  469.    
  470.    
  471. //  MGLfloat fcar = ((y_c - y_a)*(80)) + ((x_a - x_c)*(60)) + (x_c*y_a - x_a*y_c);
  472. //  MGLfloat fabr = ((y_a - y_b)*(80)) + ((x_b - x_a)*(60)) + (x_a*y_b - x_b*y_a);
  473. //  MGLfloat fbcr = ((y_b - y_c)*(80)) + ((x_c - x_b)*(60)) + (x_b*y_c - x_c*y_b);
  474.  
  475. //  float alpha = bary(x, y, x_b, y_b, x_c, y_c) / bary(x_a, y_a, x_b, y_b, x_c, y_c);
  476. //  float beta = bary(x, y, x_c, y_c, x_a, y_a) / bary(x_b, y_b, x_c, y_c, x_a, y_a);
  477. //  float gamma = bary(x, y, x_a, y_a, x_b, y_b) / bary(x_c, y_c, x_a, y_a, x_b, y_b);
  478.  
  479.  
  480.    
  481.     float alpha = bary(x, y, x_b, y_b, x_c, y_c) / bary(x_a, y_a, x_b, y_b, x_c, y_c);
  482.     float beta = bary(x_a, y_a, x, y, x_c, y_c) / bary(x_a, y_a, x_b, y_b, x_c, y_c);
  483.     float gamma = bary(x_a, y_a, x_b, y_b, x, y) / bary(x_a, y_a, x_b, y_b, x_c, y_c);
  484.    
  485. //  bool one = (0 < alpha);
  486. //    bool two = (0 < beta);
  487. //   bool three = (0 < gamma);
  488. //    bool four = (fbca*fbcr > 0);
  489. //   bool five = (facb*fcar > 0);
  490. //  bool six = (fabc*fabr > 0);
  491.  
  492. //  alpha = (alpha/a.xyzw_Screen[3])/((alpha/a.xyzw_Screen[3]) + (beta/b.xyzw_Screen[3]) + (gamma/c.xyzw_Screen[3]));
  493. //  beta = (beta/b.xyzw_Screen[3])/((alpha/a.xyzw_Screen[3]) + (beta/b.xyzw_Screen[3]) + (gamma/c.xyzw_Screen[3]));
  494. //  gamma = (gamma/c.xyzw_Screen[3])/((alpha/a.xyzw_Screen[3]) + (beta/b.xyzw_Screen[3]) + (gamma/c.xyzw_Screen[3]));
  495.    
  496.     // Inside the triangle
  497.     if (alpha >= 0 && beta >= 0 && gamma >= 0)
  498.     {
  499.  
  500.        
  501.         MGLpixel pixelColor = mixColors(alpha, beta, gamma, a.color, b.color, c.color);
  502.         MGLfloat newZ = alpha*a.xyzw_Screen[2] + beta*b.xyzw_Screen[2] + gamma*c.xyzw_Screen[2];
  503.  
  504.         set_pixel(x,y, pixelColor, newZ);
  505.     }
  506. }
  507.  
  508.  
  509. void rasterizeT(MGLsize width, MGLsize height, const triangle& t)
  510. {
  511.     BoundingBox MGL_BoundingBox;
  512.  
  513.     MGL_BoundingBox.initBB(t);
  514.  
  515.  
  516.     int x_min = static_cast<MGLpixel>(MGL_BoundingBox.min_x + 0.5);
  517.     int x_max = static_cast<MGLpixel>(MGL_BoundingBox.max_x + 0.5);
  518.     int y_min = static_cast<MGLpixel>(MGL_BoundingBox.min_y + 0.5);
  519.     int y_max = static_cast<MGLpixel>(MGL_BoundingBox.max_y + 0.5);
  520.     for (int i = x_min; i <= x_max; ++i)
  521.         for (int j = y_min; j <= y_max; ++j)
  522.             drawTriangle(i,j, t.a, t.b, t.c);
  523. }
  524.  
  525. void rasterizeQ(MGLsize width, MGLsize height, const triangle& t1, const triangle& t2)
  526. {
  527.     BoundingBox MGL_BoundingBox;
  528. //  cout << t1.a.pos[0] << " " << t1.a.pos[1] << t1.b.pos[0] << " " << t1.b.pos[1] << t1.c.pos[0] << " " << t1.c.pos[1] << t2.c.pos[0] << " " << t2.c.pos[1] << endl;
  529.  
  530.     MGL_BoundingBox.initBB(t1, t2);
  531.  
  532.  
  533.     int x_min = static_cast<MGLpixel>(MGL_BoundingBox.min_x + 0.5);
  534.     int x_max = static_cast<MGLpixel>(MGL_BoundingBox.max_x + 0.5);
  535.     int y_min = static_cast<MGLpixel>(MGL_BoundingBox.min_y + 0.5);
  536.     int y_max = static_cast<MGLpixel>(MGL_BoundingBox.max_y + 0.5);
  537.     for (int i = x_min; i <= x_max; ++i)
  538.     {
  539.             for (int j = y_min; j <= y_max; ++j)
  540.         {
  541.             drawTriangle(i,j, t1.a, t1.b, t1.c);
  542.             drawTriangle(i,j, t2.a, t2.b, t2.c);
  543.         }
  544.     }
  545. }
  546. /**
  547.  * Read pixel data starting with the pixel at coordinates
  548.  * (0, 0), up to (width,  height), into the array
  549.  * pointed to by data.  The boundaries are lower-inclusive,
  550.  * that is, a call with width = height = 1 would just read
  551.  * the pixel at (0, 0).
  552.  *
  553.  * Rasterization and z-buffering should be performed when
  554.  * this function is called, so that the data array is filled
  555.  * with the actual pixel values that should be displayed on
  556.  * the two-dimensional screen.
  557.  */
  558. void mglReadPixels(MGLsize width,
  559.                    MGLsize height,
  560.                    MGLpixel *data)
  561. {  
  562.     int numTriangles = trianglelist.size();
  563.     for (int i = 0; i < numTriangles; i++)
  564.     {
  565.         if (draw_mode == MGL_TRIANGLES)
  566.         {
  567.             conv2screencoord(width, height, trianglelist.at(i));
  568.             rasterizeT(width, height, trianglelist.at(i));
  569.         }
  570.         else if (draw_mode == MGL_QUADS)
  571.         {
  572.             conv2screencoord(width, height, trianglelist.at(i));
  573.             conv2screencoord(width, height, trianglelist.at(i+1));
  574.             rasterizeQ(width, height, trianglelist.at(i), trianglelist.at(i+1));
  575.             i+=2;
  576.         }
  577.     }
  578.    
  579.         // sort the zBuffer by descending order.
  580.     sort(zBuffer.begin(), zBuffer.end(), sortByZ);
  581.  
  582.     int size = zBuffer.size();
  583.      
  584.      for (int i = 0; i < size; ++i)
  585.      {
  586.         int x = zBuffer[i].x;
  587.         int y = zBuffer[i].y;
  588.        
  589.         MGLpixel color = zBuffer[i].pColor;
  590.         *(data + y*width + x) = color;
  591.        
  592.     }
  593.    
  594.  
  595.  
  596.  
  597.     trianglelist.clear();
  598. }
  599.  
  600. /**
  601.  * Start specifying the vertices for a group of primitives,
  602.  * whose type is specified by the given mode.
  603.  */
  604. void mglBegin(MGLpoly_mode mode)
  605. {
  606.   if (mode == MGL_TRIANGLES || mode == MGL_QUADS)
  607.         draw_mode = mode;
  608.   else
  609.     failure = true;
  610. }
  611.  
  612.  
  613. /**
  614.  * Stop specifying the vertices for a group of primitives.
  615.  */
  616. void mglEnd()
  617. {
  618.   if (draw_mode == MGL_TRIANGLES && vectorlist.size()%3 == 0)
  619.     {
  620.       triangle t;
  621.       for(unsigned int i = 0; i < vectorlist.size(); i = i + 3)
  622.     {
  623.      t.a = vectorlist.at(i);
  624.      t.b = vectorlist.at(i+1);
  625.      t.c = vectorlist.at(i+2);
  626.      trianglelist.push_back(t);
  627.     }
  628.  
  629.     }
  630.   if (draw_mode == MGL_QUADS && vectorlist.size()%4 == 0)
  631.     {
  632.       triangle t1;
  633.       triangle t2;
  634.     for (unsigned int i = 0; i < vectorlist.size(); i = i + 4)
  635.       {
  636.         t1.a = vectorlist.at(i);
  637.         t1.b = vectorlist.at(i+1);
  638.         t1.c = vectorlist.at(i+2);
  639.         t2.a = vectorlist.at(i);
  640.         t2.b = vectorlist.at(i+2);
  641.         t2.c = vectorlist.at(i+3);
  642.        
  643.         trianglelist.push_back(t1);
  644.         trianglelist.push_back(t2);
  645.       }
  646.     }
  647.   vectorlist.clear();
  648. }
  649.  
  650. /**
  651.  * Specify a two-dimensional vertex; the x- and y-coordinates
  652.  * are explicitly specified, while the z-coordinate is assumed
  653.  * to be zero.  Must appear between calls to mglBegin() and
  654.  * mglEnd().
  655.  */
  656. void mglVertex2(MGLfloat x, MGLfloat y)
  657. {
  658.   mglVertex3(x,y,0);
  659. }
  660.  
  661. /**
  662.  * Specify a three-dimensional vertex.  Must appear between
  663.  * calls to mglBegin() and mglEnd().
  664.  */
  665. void mglVertex3(MGLfloat x, MGLfloat y, MGLfloat z)
  666. {
  667.    
  668.     if (failure == true)
  669.     {
  670.         MGL_ERROR("Failure Aborting...Aborting! \n");
  671.     }
  672.     vertex v;
  673.     v.color = current_color;
  674.     v.pos = vec4(x,y,z,1);
  675.     cout << v.pos[0] << " " << v.pos[1] << " " << v.pos[2] << " " << v.pos[3] << endl;
  676.     v.applyTransformations();
  677.     cout << v.pos[0] << " " << v.pos[1] << " " << v.pos[2] << " " << v.pos[3] << endl;
  678.     vectorlist.push_back(v);
  679. }
  680.  
  681. /**
  682.  * Set the current matrix mode (modelview or projection).
  683.  */
  684. void mglMatrixMode(MGLmatrix_mode mode)
  685. {
  686.    
  687.     if (mode == MGL_MODELVIEW || mode == MGL_PROJECTION)
  688.         matrix_mode = mode;
  689.     else
  690.         failure = true;
  691.  
  692. }
  693.  
  694. /**
  695.  * Push a copy of the current matrix onto the stack for the
  696.  * current matrix mode.
  697.  */
  698. void mglPushMatrix()
  699. {
  700.     if (matrix_mode == MGL_MODELVIEW && !modelMatrixS.empty())
  701.         modelMatrixS.push(modelMatrixS.top());
  702.     else if (matrix_mode == MGL_PROJECTION && !projMatrixS.empty());
  703.         projMatrixS.push(projMatrixS.top());
  704. }
  705.  
  706. /**
  707.  * Pop the top matrix from the stack for the current matrix
  708.  * mode.
  709.  */
  710. void mglPopMatrix()
  711. {
  712.     if (matrix_mode == MGL_MODELVIEW && !modelMatrixS.empty())
  713.     {
  714.         if (!modelMatrixS.empty())
  715.             modelMatrixS.pop();
  716.     }
  717.    
  718.     else if (matrix_mode == MGL_PROJECTION && !projMatrixS.empty())
  719.     {
  720.         if (!projMatrixS.empty())
  721.             projMatrixS.pop();
  722.     }
  723. }
  724.  
  725. /**
  726.  * Replace the current matrix with the identity.
  727.  */
  728. void mglLoadIdentity()
  729. {
  730.        
  731.     Matrix Identity;
  732.     Identity.matrix[0][0] = 1;
  733.     Identity.matrix[1][1] = 1;
  734.     Identity.matrix[2][2] = 1;
  735.    
  736.    
  737.     if (matrix_mode == MGL_PROJECTION)
  738.     {
  739.  
  740.         if (!projMatrixS.empty())
  741.             projMatrixS.pop();
  742.            
  743.         projMatrixS.push(Identity);
  744.        
  745.     }
  746.     else if (matrix_mode == MGL_MODELVIEW)
  747.     {
  748.         if (!modelMatrixS.empty())
  749.             modelMatrixS.pop();
  750.            
  751.         modelMatrixS.push(Identity);
  752.     }
  753.  
  754. }
  755.  
  756. /**
  757.  * Replace the current matrix with an arbitrary 4x4 matrix,
  758.  * specified in column-major order.  That is, the matrix
  759.  * is stored as:
  760.  *
  761.  *   ( a0  a4  a8  a12 )
  762.  *   ( a1  a5  a9  a13 )
  763.  *   ( a2  a6  a10 a14 )
  764.  *   ( a3  a7  a11 a15 )
  765.  *
  766.  * where ai is the i'th entry of the array.
  767.  */
  768. void mglLoadMatrix(const MGLfloat *matrix)
  769. {
  770.     Matrix load;
  771.     for (int i = 0; i < 4; i++)
  772.     {
  773.         for(int j = 0; j < 4; j++)
  774.             {
  775.                 load.matrix[i][j] = matrix[i * 4 + j];
  776.             }
  777.     }
  778.    
  779.     if (matrix_mode == MGL_MODELVIEW)
  780.     {
  781.         if(!modelMatrixS.empty())
  782.             modelMatrixS.pop();
  783.         modelMatrixS.push(load);
  784.     }
  785.     else if (matrix_mode == MGL_PROJECTION)
  786.     {
  787.         if(!projMatrixS.empty())
  788.             projMatrixS.pop();
  789.         projMatrixS.push(load);
  790.     }
  791.    
  792. }
  793.  
  794. /**
  795.  * Multiply the current matrix by an arbitrary 4x4 matrix,
  796.  * specified in column-major order.  That is, the matrix
  797.  * is stored as:
  798.  *
  799.  *   ( a0  a4  a8  a12 )
  800.  *   ( a1  a5  a9  a13 )
  801.  *   ( a2  a6  a10 a14 )
  802.  *   ( a3  a7  a11 a15 )
  803.  *
  804.  * where ai is the i'th entry of the array.
  805.  */
  806. void mglMultMatrix(const MGLfloat *matrix)
  807. {
  808.     Matrix result;
  809.     Matrix left;
  810.     left.clearMatrix();
  811.     result.clearMatrix();
  812.    
  813.    
  814.     if (matrix_mode == MGL_MODELVIEW)
  815.     {
  816.         left = modelMatrixS.top();
  817.                
  818.         for (int i = 0; i < 4; ++i)
  819.         {
  820.             for (int j = 0; j < 4; ++j)
  821.             {
  822.        
  823.                 for (int k = 0; k < 4; ++k)
  824.                 {
  825.                 result.matrix[i][j] += left.matrix[i][k] * matrix[k * 4 + j];
  826.                
  827.                 }
  828.        
  829.             }
  830.         }
  831.         if (!modelMatrixS.empty())
  832.             modelMatrixS.pop();
  833.        
  834.         modelMatrixS.push(result);
  835.     }
  836.     else if (matrix_mode == MGL_PROJECTION)
  837.     {
  838.         left = projMatrixS.top();
  839.        
  840.         for (int i = 0; i < 4; ++i)
  841.         {
  842.             for (int j = 0; j < 4; ++j)
  843.             {
  844.        
  845.                 for (int k = 0; k < 4; ++k)
  846.                 {  
  847.                     result.matrix[i][j] += left.matrix[i][k] * matrix[k * 4 + j];
  848.                    
  849.                 }
  850.        
  851.             }
  852.         }
  853.         if(!projMatrixS.empty())
  854.             projMatrixS.pop();
  855.        
  856.         projMatrixS.push(result);
  857.     }
  858. }
  859.  
  860.  
  861. //void mglMultMatrix(Matrix& left, const Matrix& m)
  862. //{
  863.     //Matrix result;
  864.     //result.clearMatrix();
  865.    
  866.     //// [ currMatrix ] [ m ]
  867.     //for (int i = 0; i < 4; ++i)
  868.     //{
  869.         //for (int j = 0; j < 4; ++j)
  870.         //{
  871.        
  872.             //for (int k = 0; k < 4; ++k)
  873.             //{
  874.                 //result.matrix[i][j] += left.matrix[i][k] * m.matrix[k][j];
  875.                
  876.             //}
  877.        
  878.         //}
  879.     //}
  880.     //left = result;
  881. //}
  882.  
  883. /**
  884.  * Multiply the current matrix by the translation matrix
  885.  * for the translation vector given by (x, y, z).
  886.  */
  887. void mglTranslate(MGLfloat x, MGLfloat y, MGLfloat z)
  888. {
  889.     Matrix m;
  890.     m.createTranslater(x,y,z);
  891.    
  892.     mglMultMatrix(*m.matrix);
  893. }
  894.  
  895. void normalize(MGLfloat &x, MGLfloat &y, MGLfloat &z)
  896. {
  897.     MGLfloat magnitude = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2) );
  898.        
  899.     if (magnitude == 0)
  900.         return;
  901.        
  902.     x = x/magnitude;
  903.     y = y/magnitude;
  904.     z = z/magnitude;
  905. }
  906. /**
  907.  * Multiply the current matrix by the rotation matrix
  908.  * for a rotation of (angle) degrees about the vector
  909.  * from the origin to the point (x, y, z).
  910.  */
  911. void mglRotate(MGLfloat angle, MGLfloat x, MGLfloat y, MGLfloat z)
  912. {
  913.     angle = angle * (M_PI/180);
  914.     MGLfloat s = sin(angle);
  915.     MGLfloat c = cos(angle);   
  916.    
  917.     normalize(x, y, z);
  918.    
  919.     MGLfloat a = (x*x) * (1-c) + c;
  920.     MGLfloat b = (x*y) * (1-c) - z*s;
  921.     MGLfloat cr = (x*z) * (1-c) + y*s;
  922.    
  923.     MGLfloat d = (y*x) * (1-c) + z*s;
  924.     MGLfloat e = (y*y) * (1-c) + c;
  925.     MGLfloat f = (y*z) * (1-c) - x*s;
  926.    
  927.     MGLfloat g = (x*z) * (1-c) - y*s;
  928.     MGLfloat h = (y*z) * (1-c) + x*s;
  929.     MGLfloat i = (z*z) * (1-c) + c;
  930.    
  931.     Matrix r(0, 0, 0);
  932.    
  933.     r.matrix[0][0] = a;
  934.     r.matrix[0][1] = b;
  935.     r.matrix[0][2] = cr;
  936.    
  937.     r.matrix[1][0] = d;
  938.     r.matrix[1][1] = e;
  939.     r.matrix[1][2] = f;
  940.    
  941.     r.matrix[2][0] = g;
  942.     r.matrix[2][1] = h;
  943.     r.matrix[2][2] = i;
  944.  
  945.     mglMultMatrix(*r.matrix);
  946. }
  947.  
  948.  
  949. /**
  950.  * Multiply the current matrix by the scale matrix
  951.  * for the given scale factors.
  952.  */
  953. void mglScale(MGLfloat x, MGLfloat y, MGLfloat z)
  954. {
  955.     Matrix m;
  956.    
  957.     m.matrix[0][0] = x;
  958.     m.matrix[1][1] = y;
  959.     m.matrix[2][2] = z;
  960.    
  961.     mglMultMatrix(*m.matrix);
  962. }
  963.  
  964. /**
  965.  * Multiply the current matrix by the perspective matrix
  966.  * with the given clipping plane coordinates.
  967.  */
  968. void mglFrustum(MGLfloat left,
  969.                 MGLfloat right,
  970.                 MGLfloat bottom,
  971.                 MGLfloat top,
  972.                 MGLfloat near,
  973.                 MGLfloat far)
  974. {
  975.     MGLfloat x,y,A,B,C,D;
  976.    
  977.     x = (near * 2.0f)/(right - left);
  978.     y = (near * 2.0f)/(top - bottom);
  979.     A = (right + left)/(right - left);
  980.     B = (top + bottom)/(top - bottom);
  981.     C = -(far + near)/(far - near);
  982.     D = -(2.0f * far * near)/(far - near);
  983.    
  984.     Matrix frustrum(0, 0, D);
  985.    
  986.     frustrum.matrix[0][0] = x;
  987.     frustrum.matrix[1][1] = y;
  988.    
  989.     frustrum.matrix[0][2] = A;
  990.     frustrum.matrix[1][2] = B;
  991.     frustrum.matrix[2][2] = C;
  992.     frustrum.matrix[3][2] = -1;
  993.     frustrum.matrix[3][3] = 0;
  994.    
  995.     mglMultMatrix(*frustrum.matrix);
  996. }
  997.  
  998. /**
  999.  * Multiply the current matrix by the orthographic matrix
  1000.  * with the given clipping plane coordinates.
  1001.  */
  1002.  
  1003. void mglOrtho(MGLfloat left,
  1004.               MGLfloat right,
  1005.               MGLfloat bottom,
  1006.               MGLfloat top,
  1007.               MGLfloat near,
  1008.               MGLfloat far)
  1009. {
  1010.     MGLfloat t_x, t_y, t_z, x, y, z;
  1011.     x = 2/(right - left);
  1012.     y = 2/(top - bottom);
  1013.     z = -2/(far - near);
  1014.  
  1015.     t_x = -(right + left)/(right - left);
  1016.     t_y = -(top + bottom)/(top-bottom);
  1017.     t_z = -(far + near)/(far - near);
  1018.  
  1019.     Matrix ortho;
  1020.     ortho.matrix[0][0] = x;
  1021.     ortho.matrix[1][1] = y;
  1022.     ortho.matrix[2][2] = z;
  1023.    
  1024.     ortho.matrix[0][3] = t_x;
  1025.     ortho.matrix[1][3] = t_y;
  1026.     ortho.matrix[2][3] = t_z;
  1027.    
  1028.     mglMultMatrix(*ortho.matrix);
  1029.        
  1030. }
  1031.  
  1032. /**
  1033.  * Set the current color for drawn shapes.
  1034.  */
  1035. void mglColor(MGLfloat red,
  1036.               MGLfloat green,
  1037.               MGLfloat blue)
  1038. {
  1039.     current_color = vec3(red,green,blue);
  1040. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement