MMBC

3D Engine Soft Lib

Nov 29th, 2017
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.07 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <SDL/SDL.h>
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <math.h>
  8. #include <ctime>
  9. #include <ratio>
  10. #include <chrono>
  11.  
  12. #include "Mat3.h"
  13. #include "Vec2.h"
  14.  
  15. #undef main
  16.  
  17. #define VX_INIT_FLAGS SDL_HWSURFACE | SDL_HWACCEL | SDL_DOUBLEBUF
  18. #define VX_DEFAULT 0
  19. #define VX_HD 1
  20. #define VX_MEDIUM 2
  21.  
  22. #define BLACK   0x000000
  23. #define RED     0xFF0000
  24. #define GREEN   0x00FF00
  25. #define BLUE    0x0000FF
  26. #define WHITE   0xFFFFFF
  27. #define GRAY    0x808080
  28. #define MAGENTA 0xFF00FF
  29. #define CYAN    0x00FFFF
  30. #define YELLOW  0xFFFF00
  31.  
  32. constexpr float PI = 3.14159265f;
  33.  
  34. typedef struct {
  35.     Vec3 v1, v2, v3;
  36.     Uint32 c;
  37. } Triangle;
  38.  
  39. typedef struct {
  40.     Vei3 index;
  41.     Uint32 c;
  42. } Index_Triangle;
  43.  
  44. typedef struct {
  45.     Vec3 v1, v2;
  46.     Uint32 c;
  47. } Edge;
  48.  
  49. typedef struct {
  50.     Vei2 index;
  51.     Uint32 c;
  52. } Index_Edge;
  53.  
  54. typedef struct {
  55.     float x, y, z;
  56.     uint32_t c;
  57. } VX_Vertex;
  58.  
  59. typedef struct {
  60.     float x, y;
  61.     Uint8 code[4];
  62. } Vep2;
  63.  
  64. typedef struct {
  65.     float x, y, u, v, z;
  66. } TexVertex;
  67.  
  68. SDL_Surface* screen;
  69. Uint32 clearColor;
  70. char* app_name;
  71. char* app_icon;
  72. float camplane = 1;
  73.  
  74. int W, H;
  75.  
  76. int CLIP_LEFT;
  77. int CLIP_RIGHT;
  78. int CLIP_TOP;
  79. int CLIP_BOTTOM;
  80.  
  81. Vec3 translationMatrix;
  82. Vec3 rotationMatrix;
  83. Vec3 scalingMatrix;
  84.  
  85. void VXupdateCamplane(float fov)
  86. {
  87.     camplane = tan(fov);
  88. }
  89.  
  90. void VXsetFov(float fov)
  91. {
  92.     camplane = tan(fov);
  93. }
  94.  
  95. #ifdef BOTTOM_ORIGIN
  96. void VXsetPixelNoClip(int x, int y, Uint32 c)
  97. {
  98.     Uint32* p_s = (Uint32*)screen->pixels;
  99.     p_s += (H-y-1)*W+x;
  100.     *p_s = c;
  101. }
  102. #else
  103. void VXsetPixelNoClip(int x, int y, Uint32 c)
  104. {
  105.     Uint32* p_s = (Uint32*)screen->pixels;
  106.     p_s += y*W+x;
  107.     *p_s = c+0x101010;
  108. #ifdef VX_PAUSE_AT_PIXEL
  109.     SDL_Flip(screen);
  110.     SDL_Event ev;
  111.     SDL_PollEvent(&ev);
  112. #endif
  113. }
  114. #endif
  115.  
  116. void VXsetPixel(int x, int y, Uint32 c)
  117. {
  118.     if (x >= CLIP_LEFT && x <= CLIP_RIGHT && y >= CLIP_TOP && y <= CLIP_BOTTOM) VXsetPixelNoClip(x, y, c);
  119. }
  120.  
  121. SDL_Surface* VXgetBuffer()
  122. {
  123.     return screen;
  124. }
  125.  
  126. void VXsetClearColor(Uint32 color)
  127. {
  128.     clearColor = color;
  129. }
  130.  
  131. void VXlineNoClip(int x0, int y0, int x1, int y1, Uint32 c)
  132. {
  133.     int dx =  abs(x1-x0), sx = (x0 < x1) ? 1 : -1;
  134.     int dy = -abs(y1-y0), sy = (y0 < y1) ? 1 : -1;
  135.     int err = dx+dy, e2;
  136.  
  137.     for (;;)
  138.     {
  139.         VXsetPixelNoClip(x0, y0, c);
  140.         if (x0==x1 && y0==y1) break;
  141.         e2 = 2*err;
  142.         if (e2 >= dy) { err += dy; x0 += sx; }
  143.         if (e2 <= dx) { err += dx; y0 += sy; }
  144.     }
  145. }
  146.  
  147. void VXlineNoClip(Vei2 v0, Vei2 v1, Uint32 c)
  148. {
  149.     VXlineNoClip(v0.x, v0.y, v1.x, v1.y, c);
  150. }
  151.  
  152. Vep2 VXresetEndPt(Vep2 p1, Vep2 p2)
  153. {
  154.     Vep2 temp;
  155.     int x,y,i;
  156.     float m,k;
  157.  
  158.     if(p1.code[3]=='1')
  159.         x=CLIP_LEFT;
  160.  
  161.     if(p1.code[2]=='1')
  162.         x=CLIP_RIGHT;
  163.  
  164.     if((p1.code[3]=='1') || (p1.code[2]=='1'))
  165.     {
  166.         m=(float)(p2.y-p1.y)/(p2.x-p1.x);
  167.         k=(p1.y+(m*(x-p1.x)));
  168.         temp.y=k;
  169.         temp.x=x;
  170.  
  171.         for(i=0;i<4;i++)
  172.             temp.code[i]=p1.code[i];
  173.  
  174.         if(temp.y<=CLIP_BOTTOM && temp.y>=CLIP_TOP)
  175.             return (temp);
  176.     }
  177.  
  178.     if(p1.code[0]=='1')
  179.         y=CLIP_TOP;
  180.  
  181.     if(p1.code[1]=='1')
  182.         y=CLIP_BOTTOM;
  183.  
  184.     if((p1.code[0]=='1') || (p1.code[1]=='1'))
  185.     {
  186.         m=(float)(p2.y-p1.y)/(p2.x-p1.x);
  187.         k=(float)p1.x+(float)(y-p1.y)/m;
  188.         temp.x=k;
  189.         temp.y=y;
  190.  
  191.         for(i=0;i<4;i++)
  192.             temp.code[i]=p1.code[i];
  193.  
  194.         return(temp);
  195.     }
  196.     else
  197.         return(p1);
  198. }
  199.  
  200. int VXlineVisibility(Vep2 p1,Vep2 p2)
  201. {
  202.     int i,flag=0;
  203.  
  204.     for(i=0;i<4;i++)
  205.     {
  206.         if((p1.code[i]!='0') || (p2.code[i]!='0'))
  207.             flag=1;
  208.     }
  209.  
  210.     if(flag==0)
  211.         return(0);
  212.  
  213.     for(i=0;i<4;i++)
  214.     {
  215.         if((p1.code[i]==p2.code[i]) && (p1.code[i]=='1'))
  216.             flag='0';
  217.     }
  218.  
  219.     if(flag==0)
  220.         return(1);
  221.  
  222.     return(2);
  223. }
  224.  
  225. Vep2 setcode(Vep2 p)    //for setting the 4 bit code
  226. {
  227.     Vep2 ptemp;
  228.  
  229.     if(p.y<CLIP_TOP)
  230.         ptemp.code[0]='1';    //Top
  231.     else
  232.         ptemp.code[0]='0';
  233.  
  234.     if(p.y>CLIP_BOTTOM)
  235.         ptemp.code[1]='1';    //Bottom
  236.     else
  237.         ptemp.code[1]='0';
  238.  
  239.     if(p.x>CLIP_RIGHT)
  240.         ptemp.code[2]='1';    //Right
  241.     else
  242.         ptemp.code[2]='0';
  243.  
  244.     if(p.x<CLIP_LEFT)
  245.         ptemp.code[3]='1';    //Left
  246.     else
  247.         ptemp.code[3]='0';
  248.  
  249.     ptemp.x=p.x;
  250.     ptemp.y=p.y;
  251.  
  252.     return(ptemp);
  253. }
  254.  
  255. void VXline(int x0, int y0, int x1, int y1, Uint32 c)
  256. {
  257.     Vep2 vp1, vp2, vp3, vp4;
  258.     vp1.x = (float)x0;
  259.     vp1.y = (float)y0;
  260.     vp2.x = (float)x1;
  261.     vp2.y = (float)y1;
  262.  
  263.     vp1 = setcode(vp1);
  264.     vp2 = setcode(vp2);
  265.  
  266.     Uint8 v = VXlineVisibility(vp1, vp2);
  267.  
  268.     switch (v)
  269.     {
  270.     case 0:
  271.         VXlineNoClip(x0, y0, x1, y1, c);
  272.         break;
  273.     case 2:
  274.         vp3 = VXresetEndPt(vp1, vp2);
  275.         vp4 = VXresetEndPt(vp2, vp1);
  276.         VXlineNoClip((int)vp3.x, (int)vp3.y, (int)vp4.x, (int)vp4.y, c);
  277.         break;
  278.     default:
  279.         break;
  280.     }
  281. }
  282.  
  283. void VXline(Vei2 v0, Vei2 v1, Uint32 c)
  284. {
  285.     VXline(v0.x, v0.y, v1.x, v1.y, c);
  286. }
  287.  
  288. void VXdrawFlatBottomTriangleNoClip(const Vec2& v0, const Vec2& v1, const Vec2& v2, Uint32 c) {
  289.     float m0 = (float)(v1.x - v0.x) / (v1.y - v0.y);
  290.     float m1 = (float)(v2.x - v0.x) / (v2.y - v0.y);
  291.  
  292.     const int yStart = (int)ceil(v0.y-0.5f);
  293.     const int yEnd = (int)ceil(v2.y-0.5f);
  294.  
  295.     for (int y = yStart; y < yEnd; y++) {
  296.         const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
  297.         const float px1 = m1 * (float(y) + 0.5f - v0.y) + v0.x;
  298.  
  299.         const int xStart = (int)ceil(px0-0.5f);
  300.         const int xEnd = (int)ceil(px1-0.5f);
  301.  
  302.         for (int x = xStart; x < xEnd; x++) {
  303.             VXsetPixel(x, y, c);
  304.         }
  305.     }
  306. }
  307. void VXdrawFlatTopTriangleNoClip(const Vec2& v0, const Vec2& v1, const Vec2& v2, Uint32 c) {
  308.     float m0 = (v2.x - v0.x) / (v2.y - v0.y);
  309.     float m1 = (v2.x - v1.x) / (v2.y - v1.y);
  310.  
  311.     const int yStart = (int)ceil(v0.y-0.5f);
  312.     const int yEnd = (int)ceil(v2.y-0.5f);
  313.  
  314.     for (int y = yStart; y < yEnd; y++) {
  315.         const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
  316.         const float px1 = m1 * (float(y) + 0.5f - v1.y) + v1.x;
  317.  
  318.         const int xStart = (int)ceil(px0-0.5f);
  319.         const int xEnd = (int)ceil(px1-0.5f);
  320.  
  321.         for (int x = xStart; x < xEnd; x++) {
  322.             VXsetPixel(x, y, c);
  323.         }
  324.     }
  325. }
  326.  
  327. void VXdrawTriangleNoClip(const Vei2& v0, const Vei2& v1, const Vei2& v2, Uint32 c) {
  328.     const Vec2 ppv0 = {(float)v0.x,(float)v0.y};
  329.     const Vec2 ppv1 = {(float)v1.x,(float)v1.y};
  330.     const Vec2 ppv2 = {(float)v2.x,(float)v2.y};
  331.     const Vec2* pv0 = &ppv0;
  332.     const Vec2* pv1 = &ppv1;
  333.     const Vec2* pv2 = &ppv2;
  334.  
  335.     if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
  336.     if( pv2->y < pv1->y ) std::swap( pv1,pv2 );
  337.     if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
  338.  
  339.     if( pv0->y == pv1->y ) {
  340.         if( pv1->x < pv0->x ) std::swap( pv0,pv1 );
  341.         VXdrawFlatTopTriangleNoClip(*pv0, *pv1, *pv2, c);
  342.     } else
  343.     if (pv1->y == pv2->y) {
  344.         if (pv2->x < pv1->x) std::swap(pv1, pv2);
  345.         VXdrawFlatBottomTriangleNoClip(*pv0, *pv1, *pv2, c);
  346.     } else {
  347.         const float alphaSplit =
  348.             (pv1->y - pv0->y) /
  349.             (pv2->y - pv0->y);
  350.         const Vec2 vi = {pv0->x + (pv2->x - pv0->x) * alphaSplit,pv0->y + (pv2->y - pv0->y) * alphaSplit};
  351.  
  352.         if (pv1->x < vi.x) {
  353.             VXdrawFlatBottomTriangleNoClip(*pv0, *pv1, vi, c);
  354.             VXdrawFlatTopTriangleNoClip(*pv1, vi, *pv2, c);
  355.         } else {
  356.             VXdrawFlatBottomTriangleNoClip(*pv0, vi, *pv1, c);
  357.             VXdrawFlatTopTriangleNoClip(vi, *pv1, *pv2, c);
  358.         }
  359.     }
  360. }
  361.  
  362. void VXdrawTexturedFlatBottomTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
  363.     float m0 = (float)(v1.x - v0.x) / (v1.y - v0.y);
  364.     float m1 = (float)(v2.x - v0.x) / (v2.y - v0.y);
  365.  
  366.     const int yStart = (int)ceil(v0.y-0.5f);
  367.     const int yEnd = (int)ceil(v2.y-0.5f);
  368.  
  369.     for (int y = yStart; y < yEnd; y++) {
  370.         const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
  371.         const float px1 = m1 * (float(y) + 0.5f - v0.y) + v0.x;
  372.  
  373.         const int xStart = (int)ceil(px0-0.5f);
  374.         const int xEnd = (int)ceil(px1-0.5f);
  375.  
  376.         /*float w1, w2;
  377.  
  378.         w1 = 1/( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) );
  379.         if ( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) == 0) w1 = 1;
  380.         w2 = 1/( sqrt( (y - yEnd)*(y - yEnd)+(xStart-v1.x)*(xStart-v1.x) ) );
  381.         if ( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) == 0) w2 = 1;
  382.         float ule = (w1*v0.u+w2*v1.u)/(w1+w2);
  383.         float vle = (w1*v0.v+w2*v1.v)/(w1+w2);
  384.  
  385.         w1 = 1/( sqrt( (y-yStart)*(y-yStart)+(xEnd - v0.x)*(xEnd - v0.x) ) );
  386.         if ( sqrt( (y-yStart)*(y-yStart)+(xEnd - v0.x)*(xEnd - v0.x) ) == 0) w1 = 1;
  387.         w2 = 1/( sqrt( (y - yEnd)*(y - yEnd)+(xEnd - v2.x)*(xEnd - v2.x) ) );
  388.         if ( sqrt( (y - yEnd)*(y - yEnd)+(xEnd - v2.x)*(xEnd - v2.x) ) == 0) w2 = 1;
  389.         float ure = (w1*v0.u+w2*v2.u)/(w1+w2);
  390.         float vre = (w1*v0.v+w2*v2.v)/(w1+w2);*/
  391.  
  392.  
  393.         float alpha = sqrt((y-yStart)*(y-yStart))/sqrt((yEnd-yStart)*(yEnd-yStart));
  394.  
  395.         float ule = ((1-alpha)*(v0.u/v0.z)+alpha*(v1.u/v1.z))/((1-alpha)*(1/v0.z)+alpha*(1/v1.z));
  396.         float vle = ((1-alpha)*(v0.v/v0.z)+alpha*(v1.v/v1.z))/((1-alpha)*(1/v0.z)+alpha*(1/v1.z));
  397.  
  398.         float ure = ((1-alpha)*(v0.u/v0.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
  399.         float vre = ((1-alpha)*(v0.v/v0.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
  400.  
  401.         float zle = 1/((1-alpha)*(1/v0.z)+(alpha/v1.z));
  402.         float zre = 1/((1-alpha)*(1/v0.z)+(alpha/v2.z));
  403.  
  404.         for (int x = xStart; x < xEnd; x++) {
  405.             /*w1 = 1/( sqrt( (x - xStart)*(x - xStart) ) );
  406.             if ( sqrt( (x - xStart)*(x - xStart) ) == 0) w1 = 1;
  407.             w2 = 1/( sqrt( (x-(xEnd-1))*(x-(xEnd-1)) ) );
  408.             if ( sqrt( (x-(xEnd-1))*(x-(xEnd-1)) ) == 0) w2 = 1;
  409.             float upx = (w1*ule+w2*ure)/(w1+w2);
  410.             float vpx = (w1*vle+w2*vre)/(w1+w2);*/
  411.             alpha = sqrt((x-xStart)*(x-xStart))/sqrt((xEnd-xStart)*(xEnd-xStart));
  412.             float upx = ((1-alpha)*(ule/zle)+alpha*(ure/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
  413.             float vpx = ((1-alpha)*(vle/zle)+alpha*(vre/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
  414.             Uint32 c = tex[(int)((THEIGHT-1)*vpx)*TWIDTH+(int)((TWIDTH-1)*upx)];
  415.             VXsetPixel(x, y, c);
  416.         }
  417.     }
  418. }
  419. void VXdrawTexturedFlatTopTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
  420.     float m0 = (v2.x - v0.x) / (v2.y - v0.y);
  421.     float m1 = (v2.x - v1.x) / (v2.y - v1.y);
  422.  
  423.     const int yStart = (int)ceil(v0.y-0.5f);
  424.     const int yEnd = (int)ceil(v2.y-0.5f);
  425.  
  426.     for (int y = yStart; y < yEnd; y++) {
  427.         const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
  428.         const float px1 = m1 * (float(y) + 0.5f - v1.y) + v1.x;
  429.  
  430.         const int xStart = (int)ceil(px0-0.5f);
  431.         const int xEnd = (int)ceil(px1-0.5f);
  432.  
  433.         float alpha = sqrt((y-yStart)*(y-yStart))/sqrt((yEnd-yStart)*(yEnd-yStart));
  434.  
  435.         float ule = ((1-alpha)*(v0.u/v0.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
  436.         float vle = ((1-alpha)*(v0.v/v0.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
  437.  
  438.         float ure = ((1-alpha)*(v1.u/v1.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v1.z)+alpha*(1/v2.z));
  439.         float vre = ((1-alpha)*(v1.v/v1.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v1.z)+alpha*(1/v2.z));
  440.  
  441.         float zle = 1/((1-alpha)*(1/v0.z)+(alpha/v2.z));
  442.         float zre = 1/((1-alpha)*(1/v1.z)+(alpha/v2.z));
  443.  
  444.         for (int x = xStart; x < xEnd; x++) {
  445.             alpha = sqrt((x-xStart)*(x-xStart))/sqrt((xEnd-xStart)*(xEnd-xStart));
  446.             float upx = ((1-alpha)*(ule/zle)+alpha*(ure/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
  447.             float vpx = ((1-alpha)*(vle/zle)+alpha*(vre/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
  448.             Uint32 c = tex[(int)((THEIGHT-1)*vpx)*TWIDTH+(int)((TWIDTH-1)*upx)];
  449.             VXsetPixel(x, y, c);
  450.         }
  451.     }
  452. }
  453.  
  454. void VXdrawTexturedTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
  455.     const TexVertex* pv0 = &v0;
  456.     const TexVertex* pv1 = &v1;
  457.     const TexVertex* pv2 = &v2;
  458.  
  459.     if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
  460.     if( pv2->y < pv1->y ) std::swap( pv1,pv2 );
  461.     if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
  462.  
  463.     if( pv0->y == pv1->y ) {
  464.         if( pv1->x < pv0->x ) std::swap( pv0,pv1 );
  465.         VXdrawTexturedFlatTopTriangleNoClip(*pv0, *pv1, *pv2, tex);
  466.     } else
  467.     if (pv1->y == pv2->y) {
  468.         if (pv2->x < pv1->x) std::swap(pv1, pv2);
  469.         VXdrawTexturedFlatBottomTriangleNoClip(*pv0, *pv1, *pv2, tex);
  470.     } else {
  471.         const float alpha =
  472.             (pv1->y - pv0->y) /
  473.             (pv2->y - pv0->y);
  474.         TexVertex vi;
  475.         // = {pv0->x + (pv2->x - pv0->x) * alphaSplit,pv0->y + (pv2->y - pv0->y) * alphaSplit, pv0->u + (pv2->u - pv0->u) * alphaSplit, pv0->v + (pv2->v - pv0->v) * alphaSplit};
  476.         vi.x = (1-alpha)*pv0->x + alpha*pv2->x;
  477.         vi.y = pv1->y;
  478.         vi.u = ((1-alpha)*(pv0->u/pv0->z)+alpha*(pv2->u/pv2->z))/((1-alpha)*(1/pv0->z)+alpha*(1/pv2->z));
  479.         //vi.u = (1-alpha)*pv0->u + alpha*pv2->u;
  480.         vi.v = ((1-alpha)*(pv0->v/pv0->z)+alpha*(pv2->v/pv2->z))/((1-alpha)*(1/pv0->z)+alpha*(1/pv2->z));
  481.         //vi.v = (1-alpha)*pv0->v + alpha*pv2->v;
  482.         vi.z = 1/((1-alpha)/pv0->z+alpha/pv2->z);
  483.  
  484.         if (pv1->x < vi.x) {
  485.             VXdrawTexturedFlatBottomTriangleNoClip(*pv0, *pv1, vi, tex);
  486.             VXdrawTexturedFlatTopTriangleNoClip(*pv1, vi, *pv2, tex);
  487.         } else {
  488.             VXdrawTexturedFlatBottomTriangleNoClip(*pv0, vi, *pv1, tex);
  489.             VXdrawTexturedFlatTopTriangleNoClip(vi, *pv1, *pv2, tex);
  490.         }
  491.     }
  492. }
  493.  
  494. void VXupdateCaption()
  495. {
  496.     SDL_WM_SetCaption(app_name, app_icon);
  497. }
  498.  
  499. void VXsetName(const char* title)
  500. {
  501.     app_name = (char*)title;
  502.     VXupdateCaption();
  503. }
  504.  
  505. void VXsetIcon(const char* icon)
  506. {
  507.     app_icon = (char*)icon;
  508.     VXupdateCaption();
  509. }
  510.  
  511. void VXsetCaption(const char* title, const char* icon)
  512. {
  513.     app_name = (char*)title;
  514.     app_icon = (char*)icon;
  515.     VXupdateCaption();
  516. }
  517.  
  518. void VXTranslate(Vec3 tm)
  519. {
  520.     translationMatrix = tm;
  521. }
  522.  
  523. void VXTranslate(float x, float y, float z)
  524. {
  525.     translationMatrix = {x, y, z};
  526. }
  527.  
  528. void VXRotate(Vec3 rm)
  529. {
  530.     rotationMatrix = rm;
  531. }
  532.  
  533. void VXRotate(float xr, float yr, float zr)
  534. {
  535.     rotationMatrix = {xr, yr, zr};
  536. }
  537.  
  538. void VXScale(Vec3 sm)
  539. {
  540.     scalingMatrix = sm;
  541. }
  542.  
  543. void VXScale(float x, float y, float z)
  544. {
  545.     scalingMatrix = {x, y, z};
  546. }
  547.  
  548. int VXcrossP(Vei2 v1, Vei2 v2)
  549. {
  550.     return v1.y * v2.x - v1.x * v2.y;
  551. }
  552.  
  553. void VXinitEngine(int width, int height, int bpp, Uint32 flags)
  554. {
  555.     if (SDL_Init(SDL_INIT_VIDEO) < 0)
  556.     {
  557.         std::cout << "Error: could not initialize SDL : " << SDL_GetError() << std::endl;
  558.         exit(EXIT_FAILURE);
  559.     }
  560.     W = width;
  561.     H = height;
  562.     CLIP_LEFT = 0;
  563.     CLIP_TOP = 0;
  564.     CLIP_RIGHT = W-1;
  565.     CLIP_BOTTOM = H-1;
  566.     screen = SDL_SetVideoMode(width, height, bpp, flags);
  567.     if (screen == NULL)
  568.     {
  569.         std::cout << "Error: could not set video mode : " << SDL_GetError() << std::endl;
  570.         SDL_Quit();
  571.         exit(EXIT_FAILURE);
  572.     }
  573.     VXsetClearColor(BLACK);
  574.     VXScale(1,1,1);
  575.     VXRotate(0,0,0);
  576.     VXTranslate(0,0,0);
  577.     srand(time(0));
  578. }
  579.  
  580. void VXinitEngine(int default_config)
  581. {
  582.     if (default_config == VX_DEFAULT)
  583.         VXinitEngine(640, 480, 32, VX_INIT_FLAGS);
  584.     else if (default_config == VX_HD)
  585.         VXinitEngine(1320, 768, 32, VX_INIT_FLAGS | SDL_NOFRAME | SDL_FULLSCREEN);
  586.     else if (default_config == VX_MEDIUM)
  587.         VXinitEngine(1100, 600, 32, VX_INIT_FLAGS);
  588. }
  589.  
  590. void VXsetClipRegion(int left, int right, int top, int bottom)
  591. {
  592.     CLIP_BOTTOM = bottom;
  593.     CLIP_LEFT = left;
  594.     CLIP_RIGHT = right;
  595.     CLIP_TOP = top;
  596. }
  597.  
  598. void VXdrawClipRegion(Uint32 c)
  599. {
  600.     VXline(CLIP_LEFT, CLIP_TOP, CLIP_RIGHT, CLIP_TOP, c);
  601.     VXline(CLIP_LEFT, CLIP_BOTTOM, CLIP_RIGHT, CLIP_BOTTOM, c);
  602.     VXline(CLIP_LEFT, CLIP_TOP, CLIP_LEFT, CLIP_BOTTOM, c);
  603.     VXline(CLIP_RIGHT, CLIP_TOP, CLIP_RIGHT, CLIP_BOTTOM, c);
  604. }
  605.  
  606. void VXclearBuf()
  607. {
  608.     SDL_FillRect(screen, NULL, clearColor);
  609. }
  610.  
  611. void VXdisplay()
  612. {
  613.     SDL_Flip(screen);
  614. }
  615.  
  616. bool VXrunning()
  617. {
  618.     SDL_Event ev;
  619.     SDL_PollEvent(&ev);
  620.     switch(ev.type)
  621.     {
  622.     case SDL_QUIT:
  623.         return false;
  624.         break;
  625.     case SDL_KEYDOWN:
  626.         switch(ev.key.keysym.sym)
  627.         {
  628.         case SDLK_ESCAPE:
  629.             return false;
  630.             break;
  631.         default:
  632.             break;
  633.         }
  634.         break;
  635.     default:
  636.         break;
  637.     }
  638.     return true;
  639. }
  640.  
  641. bool VXkeyPressed(SDLKey k)
  642. {
  643.     SDL_Event ev;
  644.     SDL_PollEvent(&ev);
  645.     if (ev.type != SDL_KEYDOWN) return false;
  646.     if (ev.key.keysym.sym == k) return true;
  647.     return false;
  648. }
  649.  
  650. Vec3 VXM2W(Vec3 vertex, Mat3 XRot, Mat3 YRot, Mat3 ZRot, Vec3 tm, Vec3 sm)
  651. {
  652.     vertex = vertex*sm;
  653.     vertex = vertex*ZRot;
  654.     vertex = vertex*YRot;
  655.     vertex = vertex*XRot;
  656.     vertex += tm;
  657.     return vertex;
  658. }
  659.  
  660. Vei2 VXProject(Vec3 vertex)
  661. {
  662.     Vei2 projected_vertex;
  663.     vertex.x = (W/2) + (vertex.x * (W/2) / (vertex.z*camplane));
  664.     vertex.y = (H/2) - (vertex.y * (W/2) / (vertex.z*camplane));
  665.     projected_vertex.x = (int)vertex.x;
  666.     projected_vertex.y = (int)vertex.y;
  667.     return projected_vertex;
  668. }
  669.  
  670. #ifdef WIREFRAME_MODE
  671.  
  672. void VXrenderEdges(Edge* edges, Uint32 edge_count)
  673. {
  674.     Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
  675.     Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
  676.     Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
  677.  
  678.     std::vector<Vec3> VXVertexCache;
  679.     std::vector<Vei2> VXVertexScreenCache;
  680.     std::vector<Index_Edge> VXEdgeIndexCache;
  681.     for (Uint32 edge_iterator = 0; edge_iterator < edge_count; edge_iterator++)
  682.     {
  683.         Vec3 v1 = edges[edge_iterator].v1;
  684.         Vec3 v2 = edges[edge_iterator].v2;
  685.         Index_Edge edge_index;
  686.         if ((std::find(VXVertexCache.begin(), VXVertexCache.end(), v1)) != VXVertexCache.end())
  687.         {
  688.             for (uint32_t it = 0; it < VXVertexCache.size(); it++)
  689.                 if (VXVertexCache.at(it) == v1) edge_index.index.x = it;
  690.         }
  691.         else
  692.         {
  693.             VXVertexCache.push_back(v1);
  694.             // TO CHANGE !
  695.             //Vei2 pv = VXProject(v1, XRot, YRot, ZRot, translationMatrix, scalingMatrix);
  696.             //VXVertexScreenCache.push_back(pv);
  697.             edge_index.index.x = VXVertexCache.size()-1;
  698.         }
  699.         if ((std::find(VXVertexCache.begin(), VXVertexCache.end(), v2)) != VXVertexCache.end())
  700.         {
  701.             for (uint32_t it = 0; it < VXVertexCache.size(); it++)
  702.                 if (VXVertexCache.at(it) == v2) edge_index.index.y = it;
  703.         }
  704.         else
  705.         {
  706.             VXVertexCache.push_back(v2);
  707.             // TO CHANGE
  708.             //Vei2 pv = VXProject(v2, XRot, YRot, ZRot, translationMatrix, scalingMatrix);
  709.             //VXVertexScreenCache.push_back(pv);
  710.             edge_index.index.y = VXVertexCache.size()-1;
  711.         }
  712.         edge_index.c = edges[edge_iterator].c;
  713.         VXEdgeIndexCache.push_back(edge_index);
  714.     }
  715.     for (uint32_t ii = 0; ii < VXEdgeIndexCache.size(); ii++)
  716.         VXline(VXVertexScreenCache.at(VXEdgeIndexCache.at(ii).index.x), VXVertexScreenCache.at(VXEdgeIndexCache.at(ii).index.y), VXEdgeIndexCache.at(ii).c);
  717. }
  718.  
  719. void VXRenderWireframeNGLObject(const Vec3* verts, uint32_t vertexNum, const Vei2* trs, uint32_t facesNum)
  720. {
  721.  
  722.     Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
  723.     Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
  724.     Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
  725.  
  726.     std::vector<Vei2> VXScreenVertexCache;
  727.     std::vector<Vec3> VXViewVertexCache;
  728.  
  729.     for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
  730.     {
  731.         VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
  732.         VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
  733.     }
  734.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
  735.     {
  736.         VXline(VXScreenVertexCache.at(trs[3*tr_iterator+0].x), VXScreenVertexCache.at(trs[3*tr_iterator+1].x), trs[3*tr_iterator+0].y);
  737.         VXline(VXScreenVertexCache.at(trs[3*tr_iterator+1].x), VXScreenVertexCache.at(trs[3*tr_iterator+2].x), trs[3*tr_iterator+1].y);
  738.         VXline(VXScreenVertexCache.at(trs[3*tr_iterator+2].x), VXScreenVertexCache.at(trs[3*tr_iterator+0].x), trs[3*tr_iterator+2].y);
  739.     }
  740. }
  741.  
  742. #endif
  743.  
  744. void VXRenderNGLObject(const Vec3* verts, uint32_t vertexNum, Vei2* trs, uint32_t facesNum)
  745. {
  746. #ifdef PRINT_TIME
  747.     std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
  748. #endif // PRINT_TIME
  749.  
  750.     Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
  751.     Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
  752.     Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
  753.  
  754.     std::vector<Vei2> VXScreenVertexCache;
  755.     std::vector<Vec3> VXViewVertexCache;
  756.  
  757.     //std::vector<float> VXTrisDepth;
  758.     float VXTrisDepth[facesNum];
  759.  
  760.     std::vector<bool> VXBackFaceCache;
  761.  
  762. #ifdef PRINT_TIME
  763.     std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
  764.     std::chrono::duration<double, std::milli> init_time_span = t2 - t1;
  765. #endif // PRINT_TIME
  766.  
  767.     for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
  768.     {
  769.         VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
  770.         VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
  771.     }
  772.  
  773. #ifdef PRINT_TIME
  774.     std::chrono::high_resolution_clock::time_point t3 = std::chrono::high_resolution_clock::now();
  775.     std::chrono::duration<double, std::milli> m2v_time_span = t3 - t2;
  776. #endif // PRINT_TIME
  777.  
  778.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
  779.     {
  780.         VXTrisDepth[tr_iterator] = (VXViewVertexCache.at(trs[3*tr_iterator+0].x).z +
  781.                                VXViewVertexCache.at(trs[3*tr_iterator+1].x).z +
  782.                                VXViewVertexCache.at(trs[3*tr_iterator+2].x).z)
  783.                               /3.0f;
  784.     }
  785.  
  786. #ifdef PRINT_TIME
  787.     std::chrono::high_resolution_clock::time_point t4 = std::chrono::high_resolution_clock::now();
  788.     std::chrono::duration<double, std::milli> trsd_time_span = t4 - t3;
  789. #endif // PRINT_TIME
  790.  
  791.     float maxdepth;
  792.     uint32_t faceindex;
  793.  
  794.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++)
  795.     {
  796.         maxdepth = VXTrisDepth[tr_iterator];
  797.         faceindex = tr_iterator;
  798.         uint32_t tr_literator = 3*tr_iterator;
  799.         uint32_t facelindex = 3*faceindex;
  800.         for (uint32_t tr_titerator = tr_iterator+1; tr_titerator < facesNum; tr_titerator++)
  801.         {
  802.             float depth = VXTrisDepth[tr_titerator];
  803.             if (depth > maxdepth)
  804.             {
  805.                 maxdepth = depth;
  806.                 faceindex = tr_titerator;
  807.             }
  808.         }
  809.         Vei2 itmpx = trs[tr_literator+0];
  810.         trs[tr_literator+0] = trs[facelindex+0];
  811.         trs[facelindex+0] = itmpx;
  812.              itmpx = trs[tr_literator+1];
  813.         trs[tr_literator+1] = trs[facelindex+1];
  814.         trs[facelindex+1] = itmpx;
  815.              itmpx = trs[tr_literator+2];
  816.         trs[tr_literator+2] = trs[facelindex+2];
  817.         trs[facelindex+2] = itmpx;
  818.         float id   = VXTrisDepth[tr_iterator];
  819.         VXTrisDepth[tr_iterator] = VXTrisDepth[faceindex];
  820.         VXTrisDepth[faceindex] = id;
  821.     }
  822. #ifdef PRINT_TIME
  823.     std::chrono::high_resolution_clock::time_point t5 = std::chrono::high_resolution_clock::now();
  824.     std::chrono::duration<double, std::milli> dps_time_span = t5 - t4;
  825.     std::cout << "Init time :                      " << init_time_span.count() << "ms" << std::endl;
  826.     std::cout << "M2V time :                       " <<  m2v_time_span.count() << "ms" << std::endl;
  827.     std::cout << "Triangle depth computing time :  " << trsd_time_span.count() << "ms" << std::endl;
  828.     std::cout << "Depth sorting time :             " <<  dps_time_span.count() << "ms" << std::endl;
  829. #endif // PRINT_TIME
  830.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
  831.     {
  832.         Vei2 v1v2 = {VXScreenVertexCache.at(trs[3*tr_iterator+1].x).x - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x, VXScreenVertexCache.at(trs[3*tr_iterator+1].x).y - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y};
  833.         Vei2 v1v3 = {VXScreenVertexCache.at(trs[3*tr_iterator+2].x).x - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x, VXScreenVertexCache.at(trs[3*tr_iterator+2].x).y - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y};
  834.         if (VXcrossP(v1v2, v1v3) < 0)
  835.             VXdrawTriangleNoClip(VXScreenVertexCache.at(trs[3*tr_iterator+0].x), VXScreenVertexCache.at(trs[3*tr_iterator+1].x), VXScreenVertexCache.at(trs[3*tr_iterator+2].x), /*0xFFAA00+tr_iterator*/ /*rand() % 0x777777 + 0x777777*/ trs[3*tr_iterator+0].y);
  836.     }
  837. }
  838.  
  839. void VXRenderNGLTObject(const Vec3* verts, uint32_t vertexNum, Vei2* trs, uint32_t facesNum, Vec2* uvs, Uint32* tex)
  840. {
  841. #ifdef PRINT_TIME
  842.     std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
  843. #endif // PRINT_TIME
  844.  
  845.     Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
  846.     Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
  847.     Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
  848.  
  849.     std::vector<Vei2> VXScreenVertexCache;
  850.     std::vector<float> VXZScreenCache;
  851.     std::vector<Vec3> VXViewVertexCache;
  852.  
  853.     //std::vector<float> VXTrisDepth;
  854.     float VXTrisDepth[facesNum];
  855.  
  856.     std::vector<bool> VXBackFaceCache;
  857.  
  858. #ifdef PRINT_TIME
  859.     std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
  860.     std::chrono::duration<double, std::milli> init_time_span = t2 - t1;
  861. #endif // PRINT_TIME
  862.  
  863.     for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
  864.     {
  865.         VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
  866.         VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
  867.         VXZScreenCache.push_back(VXViewVertexCache[vertex_iterator].z);
  868.     }
  869.  
  870. #ifdef PRINT_TIME
  871.     std::chrono::high_resolution_clock::time_point t3 = std::chrono::high_resolution_clock::now();
  872.     std::chrono::duration<double, std::milli> m2v_time_span = t3 - t2;
  873. #endif // PRINT_TIME
  874.  
  875.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
  876.     {
  877.         VXTrisDepth[tr_iterator] = (VXViewVertexCache.at(trs[3*tr_iterator+0].x).z +
  878.                                VXViewVertexCache.at(trs[3*tr_iterator+1].x).z +
  879.                                VXViewVertexCache.at(trs[3*tr_iterator+2].x).z)
  880.                               /3.0f;
  881.     }
  882.  
  883. #ifdef PRINT_TIME
  884.     std::chrono::high_resolution_clock::time_point t4 = std::chrono::high_resolution_clock::now();
  885.     std::chrono::duration<double, std::milli> trsd_time_span = t4 - t3;
  886. #endif // PRINT_TIME
  887.  
  888.     /*float maxdepth;
  889.     uint32_t faceindex;
  890.  
  891.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++)
  892.     {
  893.         maxdepth = VXTrisDepth[tr_iterator];
  894.         faceindex = tr_iterator;
  895.         uint32_t tr_literator = 3*tr_iterator;
  896.         uint32_t facelindex = 3*faceindex;
  897.         for (uint32_t tr_titerator = tr_iterator+1; tr_titerator < facesNum; tr_titerator++)
  898.         {
  899.             float depth = VXTrisDepth[tr_titerator];
  900.             if (depth > maxdepth)
  901.             {
  902.                 maxdepth = depth;
  903.                 faceindex = tr_titerator;
  904.             }
  905.         }
  906.         Vei2 itmpx = trs[tr_literator+0];
  907.         trs[tr_literator+0] = trs[facelindex+0];
  908.         trs[facelindex+0] = itmpx;
  909.              itmpx = trs[tr_literator+1];
  910.         trs[tr_literator+1] = trs[facelindex+1];
  911.         trs[facelindex+1] = itmpx;
  912.              itmpx = trs[tr_literator+2];
  913.         trs[tr_literator+2] = trs[facelindex+2];
  914.         trs[facelindex+2] = itmpx;
  915.         Vec2 tmpuv = uvs[tr_literator+0];
  916.         uvs[tr_literator+0] = uvs[facelindex+0];
  917.         uvs[facelindex+0] = tmpuv;
  918.              tmpuv = uvs[tr_literator+1];
  919.         uvs[tr_literator+1] = uvs[facelindex+1];
  920.         uvs[facelindex+1] = tmpuv;
  921.              tmpuv = uvs[tr_literator+2];
  922.         uvs[tr_literator+2] = uvs[facelindex+2];
  923.         uvs[facelindex+2] = tmpuv;
  924.         float id   = VXTrisDepth[tr_iterator];
  925.         VXTrisDepth[tr_iterator] = VXTrisDepth[faceindex];
  926.         VXTrisDepth[faceindex] = id;
  927.     }*/
  928. #ifdef PRINT_TIME
  929.     std::chrono::high_resolution_clock::time_point t5 = std::chrono::high_resolution_clock::now();
  930.     std::chrono::duration<double, std::milli> dps_time_span = t5 - t4;
  931.     std::cout << "Init time :                      " << init_time_span.count() << "ms" << std::endl;
  932.     std::cout << "M2V time :                       " <<  m2v_time_span.count() << "ms" << std::endl;
  933.     std::cout << "Triangle depth computing time :  " << trsd_time_span.count() << "ms" << std::endl;
  934.     std::cout << "Depth sorting time :             " <<  dps_time_span.count() << "ms" << std::endl;
  935. #endif // PRINT_TIME
  936.     for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
  937.     {
  938.         Vei2 v1v2 = {VXScreenVertexCache.at(trs[3*tr_iterator+1].x).x - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x, VXScreenVertexCache.at(trs[3*tr_iterator+1].x).y - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y};
  939.         Vei2 v1v3 = {VXScreenVertexCache.at(trs[3*tr_iterator+2].x).x - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x, VXScreenVertexCache.at(trs[3*tr_iterator+2].x).y - VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y};
  940.         if (VXcrossP(v1v2, v1v3) < 0)
  941.         {
  942.             TexVertex tv0, tv1, tv2;
  943.             tv0.x = VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x;
  944.             tv0.y = VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y;
  945.             tv0.u = uvs[3*tr_iterator+0].x;
  946.             tv0.v = uvs[3*tr_iterator+0].y;
  947.             tv0.z = VXZScreenCache.at(trs[3*tr_iterator+0].x);
  948.             tv1.x = VXScreenVertexCache.at(trs[3*tr_iterator+1].x).x;
  949.             tv1.y = VXScreenVertexCache.at(trs[3*tr_iterator+1].x).y;
  950.             tv1.u = uvs[3*tr_iterator+1].x;
  951.             tv1.v = uvs[3*tr_iterator+1].y;
  952.             tv1.z = VXZScreenCache.at(trs[3*tr_iterator+1].x);
  953.             tv2.x = VXScreenVertexCache.at(trs[3*tr_iterator+2].x).x;
  954.             tv2.y = VXScreenVertexCache.at(trs[3*tr_iterator+2].x).y;
  955.             tv2.u = uvs[3*tr_iterator+2].x;
  956.             tv2.v = uvs[3*tr_iterator+2].y;
  957.             tv2.z = VXZScreenCache.at(trs[3*tr_iterator+2].x);
  958.             VXdrawTexturedTriangleNoClip(tv0, tv1, tv2, /*0xFFAA00+tr_iterator*/ /*rand() % 0x777777 + 0x777777*/ tex);
  959.         }
  960.     }
  961. }
  962.  
  963. void VXQuit()
  964. {
  965.     SDL_FreeSurface(screen);
  966.     SDL_Quit();
  967. }
  968.  
  969. template <typename T>
  970. T sq( const T& x )
  971. {
  972.     return x * x;
  973. }
Advertisement
Add Comment
Please, Sign In to add comment