Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <SDL/SDL.h>
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <math.h>
- #include <ctime>
- #include <ratio>
- #include <chrono>
- #include "Mat3.h"
- #include "Vec2.h"
- #undef main
- #define VX_INIT_FLAGS SDL_HWSURFACE | SDL_HWACCEL | SDL_DOUBLEBUF
- #define VX_DEFAULT 0
- #define VX_HD 1
- #define VX_MEDIUM 2
- #define BLACK 0x000000
- #define RED 0xFF0000
- #define GREEN 0x00FF00
- #define BLUE 0x0000FF
- #define WHITE 0xFFFFFF
- #define GRAY 0x808080
- #define MAGENTA 0xFF00FF
- #define CYAN 0x00FFFF
- #define YELLOW 0xFFFF00
- constexpr float PI = 3.14159265f;
- typedef struct {
- Vec3 v1, v2, v3;
- Uint32 c;
- } Triangle;
- typedef struct {
- Vei3 index;
- Uint32 c;
- } Index_Triangle;
- typedef struct {
- Vec3 v1, v2;
- Uint32 c;
- } Edge;
- typedef struct {
- Vei2 index;
- Uint32 c;
- } Index_Edge;
- typedef struct {
- float x, y, z;
- uint32_t c;
- } VX_Vertex;
- typedef struct {
- float x, y;
- Uint8 code[4];
- } Vep2;
- typedef struct {
- float x, y, u, v, z;
- } TexVertex;
- SDL_Surface* screen;
- Uint32 clearColor;
- char* app_name;
- char* app_icon;
- float camplane = 1;
- int W, H;
- int CLIP_LEFT;
- int CLIP_RIGHT;
- int CLIP_TOP;
- int CLIP_BOTTOM;
- Vec3 translationMatrix;
- Vec3 rotationMatrix;
- Vec3 scalingMatrix;
- void VXupdateCamplane(float fov)
- {
- camplane = tan(fov);
- }
- void VXsetFov(float fov)
- {
- camplane = tan(fov);
- }
- #ifdef BOTTOM_ORIGIN
- void VXsetPixelNoClip(int x, int y, Uint32 c)
- {
- Uint32* p_s = (Uint32*)screen->pixels;
- p_s += (H-y-1)*W+x;
- *p_s = c;
- }
- #else
- void VXsetPixelNoClip(int x, int y, Uint32 c)
- {
- Uint32* p_s = (Uint32*)screen->pixels;
- p_s += y*W+x;
- *p_s = c+0x101010;
- #ifdef VX_PAUSE_AT_PIXEL
- SDL_Flip(screen);
- SDL_Event ev;
- SDL_PollEvent(&ev);
- #endif
- }
- #endif
- void VXsetPixel(int x, int y, Uint32 c)
- {
- if (x >= CLIP_LEFT && x <= CLIP_RIGHT && y >= CLIP_TOP && y <= CLIP_BOTTOM) VXsetPixelNoClip(x, y, c);
- }
- SDL_Surface* VXgetBuffer()
- {
- return screen;
- }
- void VXsetClearColor(Uint32 color)
- {
- clearColor = color;
- }
- void VXlineNoClip(int x0, int y0, int x1, int y1, Uint32 c)
- {
- int dx = abs(x1-x0), sx = (x0 < x1) ? 1 : -1;
- int dy = -abs(y1-y0), sy = (y0 < y1) ? 1 : -1;
- int err = dx+dy, e2;
- for (;;)
- {
- VXsetPixelNoClip(x0, y0, c);
- if (x0==x1 && y0==y1) break;
- e2 = 2*err;
- if (e2 >= dy) { err += dy; x0 += sx; }
- if (e2 <= dx) { err += dx; y0 += sy; }
- }
- }
- void VXlineNoClip(Vei2 v0, Vei2 v1, Uint32 c)
- {
- VXlineNoClip(v0.x, v0.y, v1.x, v1.y, c);
- }
- Vep2 VXresetEndPt(Vep2 p1, Vep2 p2)
- {
- Vep2 temp;
- int x,y,i;
- float m,k;
- if(p1.code[3]=='1')
- x=CLIP_LEFT;
- if(p1.code[2]=='1')
- x=CLIP_RIGHT;
- if((p1.code[3]=='1') || (p1.code[2]=='1'))
- {
- m=(float)(p2.y-p1.y)/(p2.x-p1.x);
- k=(p1.y+(m*(x-p1.x)));
- temp.y=k;
- temp.x=x;
- for(i=0;i<4;i++)
- temp.code[i]=p1.code[i];
- if(temp.y<=CLIP_BOTTOM && temp.y>=CLIP_TOP)
- return (temp);
- }
- if(p1.code[0]=='1')
- y=CLIP_TOP;
- if(p1.code[1]=='1')
- y=CLIP_BOTTOM;
- if((p1.code[0]=='1') || (p1.code[1]=='1'))
- {
- m=(float)(p2.y-p1.y)/(p2.x-p1.x);
- k=(float)p1.x+(float)(y-p1.y)/m;
- temp.x=k;
- temp.y=y;
- for(i=0;i<4;i++)
- temp.code[i]=p1.code[i];
- return(temp);
- }
- else
- return(p1);
- }
- int VXlineVisibility(Vep2 p1,Vep2 p2)
- {
- int i,flag=0;
- for(i=0;i<4;i++)
- {
- if((p1.code[i]!='0') || (p2.code[i]!='0'))
- flag=1;
- }
- if(flag==0)
- return(0);
- for(i=0;i<4;i++)
- {
- if((p1.code[i]==p2.code[i]) && (p1.code[i]=='1'))
- flag='0';
- }
- if(flag==0)
- return(1);
- return(2);
- }
- Vep2 setcode(Vep2 p) //for setting the 4 bit code
- {
- Vep2 ptemp;
- if(p.y<CLIP_TOP)
- ptemp.code[0]='1'; //Top
- else
- ptemp.code[0]='0';
- if(p.y>CLIP_BOTTOM)
- ptemp.code[1]='1'; //Bottom
- else
- ptemp.code[1]='0';
- if(p.x>CLIP_RIGHT)
- ptemp.code[2]='1'; //Right
- else
- ptemp.code[2]='0';
- if(p.x<CLIP_LEFT)
- ptemp.code[3]='1'; //Left
- else
- ptemp.code[3]='0';
- ptemp.x=p.x;
- ptemp.y=p.y;
- return(ptemp);
- }
- void VXline(int x0, int y0, int x1, int y1, Uint32 c)
- {
- Vep2 vp1, vp2, vp3, vp4;
- vp1.x = (float)x0;
- vp1.y = (float)y0;
- vp2.x = (float)x1;
- vp2.y = (float)y1;
- vp1 = setcode(vp1);
- vp2 = setcode(vp2);
- Uint8 v = VXlineVisibility(vp1, vp2);
- switch (v)
- {
- case 0:
- VXlineNoClip(x0, y0, x1, y1, c);
- break;
- case 2:
- vp3 = VXresetEndPt(vp1, vp2);
- vp4 = VXresetEndPt(vp2, vp1);
- VXlineNoClip((int)vp3.x, (int)vp3.y, (int)vp4.x, (int)vp4.y, c);
- break;
- default:
- break;
- }
- }
- void VXline(Vei2 v0, Vei2 v1, Uint32 c)
- {
- VXline(v0.x, v0.y, v1.x, v1.y, c);
- }
- void VXdrawFlatBottomTriangleNoClip(const Vec2& v0, const Vec2& v1, const Vec2& v2, Uint32 c) {
- float m0 = (float)(v1.x - v0.x) / (v1.y - v0.y);
- float m1 = (float)(v2.x - v0.x) / (v2.y - v0.y);
- const int yStart = (int)ceil(v0.y-0.5f);
- const int yEnd = (int)ceil(v2.y-0.5f);
- for (int y = yStart; y < yEnd; y++) {
- const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
- const float px1 = m1 * (float(y) + 0.5f - v0.y) + v0.x;
- const int xStart = (int)ceil(px0-0.5f);
- const int xEnd = (int)ceil(px1-0.5f);
- for (int x = xStart; x < xEnd; x++) {
- VXsetPixel(x, y, c);
- }
- }
- }
- void VXdrawFlatTopTriangleNoClip(const Vec2& v0, const Vec2& v1, const Vec2& v2, Uint32 c) {
- float m0 = (v2.x - v0.x) / (v2.y - v0.y);
- float m1 = (v2.x - v1.x) / (v2.y - v1.y);
- const int yStart = (int)ceil(v0.y-0.5f);
- const int yEnd = (int)ceil(v2.y-0.5f);
- for (int y = yStart; y < yEnd; y++) {
- const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
- const float px1 = m1 * (float(y) + 0.5f - v1.y) + v1.x;
- const int xStart = (int)ceil(px0-0.5f);
- const int xEnd = (int)ceil(px1-0.5f);
- for (int x = xStart; x < xEnd; x++) {
- VXsetPixel(x, y, c);
- }
- }
- }
- void VXdrawTriangleNoClip(const Vei2& v0, const Vei2& v1, const Vei2& v2, Uint32 c) {
- const Vec2 ppv0 = {(float)v0.x,(float)v0.y};
- const Vec2 ppv1 = {(float)v1.x,(float)v1.y};
- const Vec2 ppv2 = {(float)v2.x,(float)v2.y};
- const Vec2* pv0 = &ppv0;
- const Vec2* pv1 = &ppv1;
- const Vec2* pv2 = &ppv2;
- if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
- if( pv2->y < pv1->y ) std::swap( pv1,pv2 );
- if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
- if( pv0->y == pv1->y ) {
- if( pv1->x < pv0->x ) std::swap( pv0,pv1 );
- VXdrawFlatTopTriangleNoClip(*pv0, *pv1, *pv2, c);
- } else
- if (pv1->y == pv2->y) {
- if (pv2->x < pv1->x) std::swap(pv1, pv2);
- VXdrawFlatBottomTriangleNoClip(*pv0, *pv1, *pv2, c);
- } else {
- const float alphaSplit =
- (pv1->y - pv0->y) /
- (pv2->y - pv0->y);
- const Vec2 vi = {pv0->x + (pv2->x - pv0->x) * alphaSplit,pv0->y + (pv2->y - pv0->y) * alphaSplit};
- if (pv1->x < vi.x) {
- VXdrawFlatBottomTriangleNoClip(*pv0, *pv1, vi, c);
- VXdrawFlatTopTriangleNoClip(*pv1, vi, *pv2, c);
- } else {
- VXdrawFlatBottomTriangleNoClip(*pv0, vi, *pv1, c);
- VXdrawFlatTopTriangleNoClip(vi, *pv1, *pv2, c);
- }
- }
- }
- void VXdrawTexturedFlatBottomTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
- float m0 = (float)(v1.x - v0.x) / (v1.y - v0.y);
- float m1 = (float)(v2.x - v0.x) / (v2.y - v0.y);
- const int yStart = (int)ceil(v0.y-0.5f);
- const int yEnd = (int)ceil(v2.y-0.5f);
- for (int y = yStart; y < yEnd; y++) {
- const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
- const float px1 = m1 * (float(y) + 0.5f - v0.y) + v0.x;
- const int xStart = (int)ceil(px0-0.5f);
- const int xEnd = (int)ceil(px1-0.5f);
- /*float w1, w2;
- w1 = 1/( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) );
- if ( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) == 0) w1 = 1;
- w2 = 1/( sqrt( (y - yEnd)*(y - yEnd)+(xStart-v1.x)*(xStart-v1.x) ) );
- if ( sqrt( (y-yStart)*(y-yStart)+(xStart-v0.x)*(xStart-v0.x) ) == 0) w2 = 1;
- float ule = (w1*v0.u+w2*v1.u)/(w1+w2);
- float vle = (w1*v0.v+w2*v1.v)/(w1+w2);
- w1 = 1/( sqrt( (y-yStart)*(y-yStart)+(xEnd - v0.x)*(xEnd - v0.x) ) );
- if ( sqrt( (y-yStart)*(y-yStart)+(xEnd - v0.x)*(xEnd - v0.x) ) == 0) w1 = 1;
- w2 = 1/( sqrt( (y - yEnd)*(y - yEnd)+(xEnd - v2.x)*(xEnd - v2.x) ) );
- if ( sqrt( (y - yEnd)*(y - yEnd)+(xEnd - v2.x)*(xEnd - v2.x) ) == 0) w2 = 1;
- float ure = (w1*v0.u+w2*v2.u)/(w1+w2);
- float vre = (w1*v0.v+w2*v2.v)/(w1+w2);*/
- float alpha = sqrt((y-yStart)*(y-yStart))/sqrt((yEnd-yStart)*(yEnd-yStart));
- float ule = ((1-alpha)*(v0.u/v0.z)+alpha*(v1.u/v1.z))/((1-alpha)*(1/v0.z)+alpha*(1/v1.z));
- float vle = ((1-alpha)*(v0.v/v0.z)+alpha*(v1.v/v1.z))/((1-alpha)*(1/v0.z)+alpha*(1/v1.z));
- float ure = ((1-alpha)*(v0.u/v0.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
- float vre = ((1-alpha)*(v0.v/v0.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
- float zle = 1/((1-alpha)*(1/v0.z)+(alpha/v1.z));
- float zre = 1/((1-alpha)*(1/v0.z)+(alpha/v2.z));
- for (int x = xStart; x < xEnd; x++) {
- /*w1 = 1/( sqrt( (x - xStart)*(x - xStart) ) );
- if ( sqrt( (x - xStart)*(x - xStart) ) == 0) w1 = 1;
- w2 = 1/( sqrt( (x-(xEnd-1))*(x-(xEnd-1)) ) );
- if ( sqrt( (x-(xEnd-1))*(x-(xEnd-1)) ) == 0) w2 = 1;
- float upx = (w1*ule+w2*ure)/(w1+w2);
- float vpx = (w1*vle+w2*vre)/(w1+w2);*/
- alpha = sqrt((x-xStart)*(x-xStart))/sqrt((xEnd-xStart)*(xEnd-xStart));
- float upx = ((1-alpha)*(ule/zle)+alpha*(ure/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
- float vpx = ((1-alpha)*(vle/zle)+alpha*(vre/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
- Uint32 c = tex[(int)((THEIGHT-1)*vpx)*TWIDTH+(int)((TWIDTH-1)*upx)];
- VXsetPixel(x, y, c);
- }
- }
- }
- void VXdrawTexturedFlatTopTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
- float m0 = (v2.x - v0.x) / (v2.y - v0.y);
- float m1 = (v2.x - v1.x) / (v2.y - v1.y);
- const int yStart = (int)ceil(v0.y-0.5f);
- const int yEnd = (int)ceil(v2.y-0.5f);
- for (int y = yStart; y < yEnd; y++) {
- const float px0 = m0 * (float(y) + 0.5f - v0.y) + v0.x;
- const float px1 = m1 * (float(y) + 0.5f - v1.y) + v1.x;
- const int xStart = (int)ceil(px0-0.5f);
- const int xEnd = (int)ceil(px1-0.5f);
- float alpha = sqrt((y-yStart)*(y-yStart))/sqrt((yEnd-yStart)*(yEnd-yStart));
- float ule = ((1-alpha)*(v0.u/v0.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
- float vle = ((1-alpha)*(v0.v/v0.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v0.z)+alpha*(1/v2.z));
- float ure = ((1-alpha)*(v1.u/v1.z)+alpha*(v2.u/v2.z))/((1-alpha)*(1/v1.z)+alpha*(1/v2.z));
- float vre = ((1-alpha)*(v1.v/v1.z)+alpha*(v2.v/v2.z))/((1-alpha)*(1/v1.z)+alpha*(1/v2.z));
- float zle = 1/((1-alpha)*(1/v0.z)+(alpha/v2.z));
- float zre = 1/((1-alpha)*(1/v1.z)+(alpha/v2.z));
- for (int x = xStart; x < xEnd; x++) {
- alpha = sqrt((x-xStart)*(x-xStart))/sqrt((xEnd-xStart)*(xEnd-xStart));
- float upx = ((1-alpha)*(ule/zle)+alpha*(ure/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
- float vpx = ((1-alpha)*(vle/zle)+alpha*(vre/zre))/((1-alpha)*(1/zle)+alpha*(1/zre));
- Uint32 c = tex[(int)((THEIGHT-1)*vpx)*TWIDTH+(int)((TWIDTH-1)*upx)];
- VXsetPixel(x, y, c);
- }
- }
- }
- void VXdrawTexturedTriangleNoClip(const TexVertex& v0, const TexVertex& v1, const TexVertex& v2, Uint32* tex) {
- const TexVertex* pv0 = &v0;
- const TexVertex* pv1 = &v1;
- const TexVertex* pv2 = &v2;
- if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
- if( pv2->y < pv1->y ) std::swap( pv1,pv2 );
- if( pv1->y < pv0->y ) std::swap( pv0,pv1 );
- if( pv0->y == pv1->y ) {
- if( pv1->x < pv0->x ) std::swap( pv0,pv1 );
- VXdrawTexturedFlatTopTriangleNoClip(*pv0, *pv1, *pv2, tex);
- } else
- if (pv1->y == pv2->y) {
- if (pv2->x < pv1->x) std::swap(pv1, pv2);
- VXdrawTexturedFlatBottomTriangleNoClip(*pv0, *pv1, *pv2, tex);
- } else {
- const float alpha =
- (pv1->y - pv0->y) /
- (pv2->y - pv0->y);
- TexVertex vi;
- // = {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};
- vi.x = (1-alpha)*pv0->x + alpha*pv2->x;
- vi.y = pv1->y;
- vi.u = ((1-alpha)*(pv0->u/pv0->z)+alpha*(pv2->u/pv2->z))/((1-alpha)*(1/pv0->z)+alpha*(1/pv2->z));
- //vi.u = (1-alpha)*pv0->u + alpha*pv2->u;
- vi.v = ((1-alpha)*(pv0->v/pv0->z)+alpha*(pv2->v/pv2->z))/((1-alpha)*(1/pv0->z)+alpha*(1/pv2->z));
- //vi.v = (1-alpha)*pv0->v + alpha*pv2->v;
- vi.z = 1/((1-alpha)/pv0->z+alpha/pv2->z);
- if (pv1->x < vi.x) {
- VXdrawTexturedFlatBottomTriangleNoClip(*pv0, *pv1, vi, tex);
- VXdrawTexturedFlatTopTriangleNoClip(*pv1, vi, *pv2, tex);
- } else {
- VXdrawTexturedFlatBottomTriangleNoClip(*pv0, vi, *pv1, tex);
- VXdrawTexturedFlatTopTriangleNoClip(vi, *pv1, *pv2, tex);
- }
- }
- }
- void VXupdateCaption()
- {
- SDL_WM_SetCaption(app_name, app_icon);
- }
- void VXsetName(const char* title)
- {
- app_name = (char*)title;
- VXupdateCaption();
- }
- void VXsetIcon(const char* icon)
- {
- app_icon = (char*)icon;
- VXupdateCaption();
- }
- void VXsetCaption(const char* title, const char* icon)
- {
- app_name = (char*)title;
- app_icon = (char*)icon;
- VXupdateCaption();
- }
- void VXTranslate(Vec3 tm)
- {
- translationMatrix = tm;
- }
- void VXTranslate(float x, float y, float z)
- {
- translationMatrix = {x, y, z};
- }
- void VXRotate(Vec3 rm)
- {
- rotationMatrix = rm;
- }
- void VXRotate(float xr, float yr, float zr)
- {
- rotationMatrix = {xr, yr, zr};
- }
- void VXScale(Vec3 sm)
- {
- scalingMatrix = sm;
- }
- void VXScale(float x, float y, float z)
- {
- scalingMatrix = {x, y, z};
- }
- int VXcrossP(Vei2 v1, Vei2 v2)
- {
- return v1.y * v2.x - v1.x * v2.y;
- }
- void VXinitEngine(int width, int height, int bpp, Uint32 flags)
- {
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
- std::cout << "Error: could not initialize SDL : " << SDL_GetError() << std::endl;
- exit(EXIT_FAILURE);
- }
- W = width;
- H = height;
- CLIP_LEFT = 0;
- CLIP_TOP = 0;
- CLIP_RIGHT = W-1;
- CLIP_BOTTOM = H-1;
- screen = SDL_SetVideoMode(width, height, bpp, flags);
- if (screen == NULL)
- {
- std::cout << "Error: could not set video mode : " << SDL_GetError() << std::endl;
- SDL_Quit();
- exit(EXIT_FAILURE);
- }
- VXsetClearColor(BLACK);
- VXScale(1,1,1);
- VXRotate(0,0,0);
- VXTranslate(0,0,0);
- srand(time(0));
- }
- void VXinitEngine(int default_config)
- {
- if (default_config == VX_DEFAULT)
- VXinitEngine(640, 480, 32, VX_INIT_FLAGS);
- else if (default_config == VX_HD)
- VXinitEngine(1320, 768, 32, VX_INIT_FLAGS | SDL_NOFRAME | SDL_FULLSCREEN);
- else if (default_config == VX_MEDIUM)
- VXinitEngine(1100, 600, 32, VX_INIT_FLAGS);
- }
- void VXsetClipRegion(int left, int right, int top, int bottom)
- {
- CLIP_BOTTOM = bottom;
- CLIP_LEFT = left;
- CLIP_RIGHT = right;
- CLIP_TOP = top;
- }
- void VXdrawClipRegion(Uint32 c)
- {
- VXline(CLIP_LEFT, CLIP_TOP, CLIP_RIGHT, CLIP_TOP, c);
- VXline(CLIP_LEFT, CLIP_BOTTOM, CLIP_RIGHT, CLIP_BOTTOM, c);
- VXline(CLIP_LEFT, CLIP_TOP, CLIP_LEFT, CLIP_BOTTOM, c);
- VXline(CLIP_RIGHT, CLIP_TOP, CLIP_RIGHT, CLIP_BOTTOM, c);
- }
- void VXclearBuf()
- {
- SDL_FillRect(screen, NULL, clearColor);
- }
- void VXdisplay()
- {
- SDL_Flip(screen);
- }
- bool VXrunning()
- {
- SDL_Event ev;
- SDL_PollEvent(&ev);
- switch(ev.type)
- {
- case SDL_QUIT:
- return false;
- break;
- case SDL_KEYDOWN:
- switch(ev.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- return false;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return true;
- }
- bool VXkeyPressed(SDLKey k)
- {
- SDL_Event ev;
- SDL_PollEvent(&ev);
- if (ev.type != SDL_KEYDOWN) return false;
- if (ev.key.keysym.sym == k) return true;
- return false;
- }
- Vec3 VXM2W(Vec3 vertex, Mat3 XRot, Mat3 YRot, Mat3 ZRot, Vec3 tm, Vec3 sm)
- {
- vertex = vertex*sm;
- vertex = vertex*ZRot;
- vertex = vertex*YRot;
- vertex = vertex*XRot;
- vertex += tm;
- return vertex;
- }
- Vei2 VXProject(Vec3 vertex)
- {
- Vei2 projected_vertex;
- vertex.x = (W/2) + (vertex.x * (W/2) / (vertex.z*camplane));
- vertex.y = (H/2) - (vertex.y * (W/2) / (vertex.z*camplane));
- projected_vertex.x = (int)vertex.x;
- projected_vertex.y = (int)vertex.y;
- return projected_vertex;
- }
- #ifdef WIREFRAME_MODE
- void VXrenderEdges(Edge* edges, Uint32 edge_count)
- {
- Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
- Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
- Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
- std::vector<Vec3> VXVertexCache;
- std::vector<Vei2> VXVertexScreenCache;
- std::vector<Index_Edge> VXEdgeIndexCache;
- for (Uint32 edge_iterator = 0; edge_iterator < edge_count; edge_iterator++)
- {
- Vec3 v1 = edges[edge_iterator].v1;
- Vec3 v2 = edges[edge_iterator].v2;
- Index_Edge edge_index;
- if ((std::find(VXVertexCache.begin(), VXVertexCache.end(), v1)) != VXVertexCache.end())
- {
- for (uint32_t it = 0; it < VXVertexCache.size(); it++)
- if (VXVertexCache.at(it) == v1) edge_index.index.x = it;
- }
- else
- {
- VXVertexCache.push_back(v1);
- // TO CHANGE !
- //Vei2 pv = VXProject(v1, XRot, YRot, ZRot, translationMatrix, scalingMatrix);
- //VXVertexScreenCache.push_back(pv);
- edge_index.index.x = VXVertexCache.size()-1;
- }
- if ((std::find(VXVertexCache.begin(), VXVertexCache.end(), v2)) != VXVertexCache.end())
- {
- for (uint32_t it = 0; it < VXVertexCache.size(); it++)
- if (VXVertexCache.at(it) == v2) edge_index.index.y = it;
- }
- else
- {
- VXVertexCache.push_back(v2);
- // TO CHANGE
- //Vei2 pv = VXProject(v2, XRot, YRot, ZRot, translationMatrix, scalingMatrix);
- //VXVertexScreenCache.push_back(pv);
- edge_index.index.y = VXVertexCache.size()-1;
- }
- edge_index.c = edges[edge_iterator].c;
- VXEdgeIndexCache.push_back(edge_index);
- }
- for (uint32_t ii = 0; ii < VXEdgeIndexCache.size(); ii++)
- VXline(VXVertexScreenCache.at(VXEdgeIndexCache.at(ii).index.x), VXVertexScreenCache.at(VXEdgeIndexCache.at(ii).index.y), VXEdgeIndexCache.at(ii).c);
- }
- void VXRenderWireframeNGLObject(const Vec3* verts, uint32_t vertexNum, const Vei2* trs, uint32_t facesNum)
- {
- Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
- Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
- Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
- std::vector<Vei2> VXScreenVertexCache;
- std::vector<Vec3> VXViewVertexCache;
- for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
- {
- VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
- VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
- }
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
- {
- VXline(VXScreenVertexCache.at(trs[3*tr_iterator+0].x), VXScreenVertexCache.at(trs[3*tr_iterator+1].x), trs[3*tr_iterator+0].y);
- VXline(VXScreenVertexCache.at(trs[3*tr_iterator+1].x), VXScreenVertexCache.at(trs[3*tr_iterator+2].x), trs[3*tr_iterator+1].y);
- VXline(VXScreenVertexCache.at(trs[3*tr_iterator+2].x), VXScreenVertexCache.at(trs[3*tr_iterator+0].x), trs[3*tr_iterator+2].y);
- }
- }
- #endif
- void VXRenderNGLObject(const Vec3* verts, uint32_t vertexNum, Vei2* trs, uint32_t facesNum)
- {
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
- #endif // PRINT_TIME
- Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
- Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
- Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
- std::vector<Vei2> VXScreenVertexCache;
- std::vector<Vec3> VXViewVertexCache;
- //std::vector<float> VXTrisDepth;
- float VXTrisDepth[facesNum];
- std::vector<bool> VXBackFaceCache;
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> init_time_span = t2 - t1;
- #endif // PRINT_TIME
- for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
- {
- VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
- VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
- }
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t3 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> m2v_time_span = t3 - t2;
- #endif // PRINT_TIME
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
- {
- VXTrisDepth[tr_iterator] = (VXViewVertexCache.at(trs[3*tr_iterator+0].x).z +
- VXViewVertexCache.at(trs[3*tr_iterator+1].x).z +
- VXViewVertexCache.at(trs[3*tr_iterator+2].x).z)
- /3.0f;
- }
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t4 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> trsd_time_span = t4 - t3;
- #endif // PRINT_TIME
- float maxdepth;
- uint32_t faceindex;
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++)
- {
- maxdepth = VXTrisDepth[tr_iterator];
- faceindex = tr_iterator;
- uint32_t tr_literator = 3*tr_iterator;
- uint32_t facelindex = 3*faceindex;
- for (uint32_t tr_titerator = tr_iterator+1; tr_titerator < facesNum; tr_titerator++)
- {
- float depth = VXTrisDepth[tr_titerator];
- if (depth > maxdepth)
- {
- maxdepth = depth;
- faceindex = tr_titerator;
- }
- }
- Vei2 itmpx = trs[tr_literator+0];
- trs[tr_literator+0] = trs[facelindex+0];
- trs[facelindex+0] = itmpx;
- itmpx = trs[tr_literator+1];
- trs[tr_literator+1] = trs[facelindex+1];
- trs[facelindex+1] = itmpx;
- itmpx = trs[tr_literator+2];
- trs[tr_literator+2] = trs[facelindex+2];
- trs[facelindex+2] = itmpx;
- float id = VXTrisDepth[tr_iterator];
- VXTrisDepth[tr_iterator] = VXTrisDepth[faceindex];
- VXTrisDepth[faceindex] = id;
- }
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t5 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> dps_time_span = t5 - t4;
- std::cout << "Init time : " << init_time_span.count() << "ms" << std::endl;
- std::cout << "M2V time : " << m2v_time_span.count() << "ms" << std::endl;
- std::cout << "Triangle depth computing time : " << trsd_time_span.count() << "ms" << std::endl;
- std::cout << "Depth sorting time : " << dps_time_span.count() << "ms" << std::endl;
- #endif // PRINT_TIME
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
- {
- 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};
- 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};
- if (VXcrossP(v1v2, v1v3) < 0)
- 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);
- }
- }
- void VXRenderNGLTObject(const Vec3* verts, uint32_t vertexNum, Vei2* trs, uint32_t facesNum, Vec2* uvs, Uint32* tex)
- {
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
- #endif // PRINT_TIME
- Mat3 XRot = Mat3::XRotation(rotationMatrix.x);
- Mat3 YRot = Mat3::YRotation(rotationMatrix.y);
- Mat3 ZRot = Mat3::ZRotation(rotationMatrix.z);
- std::vector<Vei2> VXScreenVertexCache;
- std::vector<float> VXZScreenCache;
- std::vector<Vec3> VXViewVertexCache;
- //std::vector<float> VXTrisDepth;
- float VXTrisDepth[facesNum];
- std::vector<bool> VXBackFaceCache;
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> init_time_span = t2 - t1;
- #endif // PRINT_TIME
- for (uint32_t vertex_iterator = 0; vertex_iterator < vertexNum; vertex_iterator++)
- {
- VXViewVertexCache.push_back(VXM2W(verts[vertex_iterator], XRot, YRot, ZRot, translationMatrix, scalingMatrix));
- VXScreenVertexCache.push_back(VXProject(VXViewVertexCache[vertex_iterator]));
- VXZScreenCache.push_back(VXViewVertexCache[vertex_iterator].z);
- }
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t3 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> m2v_time_span = t3 - t2;
- #endif // PRINT_TIME
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
- {
- VXTrisDepth[tr_iterator] = (VXViewVertexCache.at(trs[3*tr_iterator+0].x).z +
- VXViewVertexCache.at(trs[3*tr_iterator+1].x).z +
- VXViewVertexCache.at(trs[3*tr_iterator+2].x).z)
- /3.0f;
- }
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t4 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> trsd_time_span = t4 - t3;
- #endif // PRINT_TIME
- /*float maxdepth;
- uint32_t faceindex;
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum-1; tr_iterator++)
- {
- maxdepth = VXTrisDepth[tr_iterator];
- faceindex = tr_iterator;
- uint32_t tr_literator = 3*tr_iterator;
- uint32_t facelindex = 3*faceindex;
- for (uint32_t tr_titerator = tr_iterator+1; tr_titerator < facesNum; tr_titerator++)
- {
- float depth = VXTrisDepth[tr_titerator];
- if (depth > maxdepth)
- {
- maxdepth = depth;
- faceindex = tr_titerator;
- }
- }
- Vei2 itmpx = trs[tr_literator+0];
- trs[tr_literator+0] = trs[facelindex+0];
- trs[facelindex+0] = itmpx;
- itmpx = trs[tr_literator+1];
- trs[tr_literator+1] = trs[facelindex+1];
- trs[facelindex+1] = itmpx;
- itmpx = trs[tr_literator+2];
- trs[tr_literator+2] = trs[facelindex+2];
- trs[facelindex+2] = itmpx;
- Vec2 tmpuv = uvs[tr_literator+0];
- uvs[tr_literator+0] = uvs[facelindex+0];
- uvs[facelindex+0] = tmpuv;
- tmpuv = uvs[tr_literator+1];
- uvs[tr_literator+1] = uvs[facelindex+1];
- uvs[facelindex+1] = tmpuv;
- tmpuv = uvs[tr_literator+2];
- uvs[tr_literator+2] = uvs[facelindex+2];
- uvs[facelindex+2] = tmpuv;
- float id = VXTrisDepth[tr_iterator];
- VXTrisDepth[tr_iterator] = VXTrisDepth[faceindex];
- VXTrisDepth[faceindex] = id;
- }*/
- #ifdef PRINT_TIME
- std::chrono::high_resolution_clock::time_point t5 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::milli> dps_time_span = t5 - t4;
- std::cout << "Init time : " << init_time_span.count() << "ms" << std::endl;
- std::cout << "M2V time : " << m2v_time_span.count() << "ms" << std::endl;
- std::cout << "Triangle depth computing time : " << trsd_time_span.count() << "ms" << std::endl;
- std::cout << "Depth sorting time : " << dps_time_span.count() << "ms" << std::endl;
- #endif // PRINT_TIME
- for (uint32_t tr_iterator = 0; tr_iterator < facesNum; tr_iterator++)
- {
- 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};
- 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};
- if (VXcrossP(v1v2, v1v3) < 0)
- {
- TexVertex tv0, tv1, tv2;
- tv0.x = VXScreenVertexCache.at(trs[3*tr_iterator+0].x).x;
- tv0.y = VXScreenVertexCache.at(trs[3*tr_iterator+0].x).y;
- tv0.u = uvs[3*tr_iterator+0].x;
- tv0.v = uvs[3*tr_iterator+0].y;
- tv0.z = VXZScreenCache.at(trs[3*tr_iterator+0].x);
- tv1.x = VXScreenVertexCache.at(trs[3*tr_iterator+1].x).x;
- tv1.y = VXScreenVertexCache.at(trs[3*tr_iterator+1].x).y;
- tv1.u = uvs[3*tr_iterator+1].x;
- tv1.v = uvs[3*tr_iterator+1].y;
- tv1.z = VXZScreenCache.at(trs[3*tr_iterator+1].x);
- tv2.x = VXScreenVertexCache.at(trs[3*tr_iterator+2].x).x;
- tv2.y = VXScreenVertexCache.at(trs[3*tr_iterator+2].x).y;
- tv2.u = uvs[3*tr_iterator+2].x;
- tv2.v = uvs[3*tr_iterator+2].y;
- tv2.z = VXZScreenCache.at(trs[3*tr_iterator+2].x);
- VXdrawTexturedTriangleNoClip(tv0, tv1, tv2, /*0xFFAA00+tr_iterator*/ /*rand() % 0x777777 + 0x777777*/ tex);
- }
- }
- }
- void VXQuit()
- {
- SDL_FreeSurface(screen);
- SDL_Quit();
- }
- template <typename T>
- T sq( const T& x )
- {
- return x * x;
- }
Advertisement
Add Comment
Please, Sign In to add comment