#include "math.h" #include "options33.h" #include "types33.h" #include "display33.h" #include "scene33.h" #include "strings33.h" #include "logger33.h" #define _FOV_HALF (0.78539816339744830962/2.0) #define _NEAR 1.0 #define _FAR 24.0 static Mat4 _projectionMatrix = {0,}; static Mat4 _viewMatrix; static Mat4 _worldMatrix; static f64 _preXformedModelVertices[ E33_VERTICES_PER_MODEL_MAX ][4]; static void _draw_line( Vec2 v0, Vec2 v1, u32 colour ); Error graphics33_init( void ) { f64 ar, cot; f64 displayW = (f64)__display.surface.w; f64 displayH = (f64)__display.surface.h; ar = displayW / displayH; cot = 1.0 / tan( _FOV_HALF ); _projectionMatrix[ 0] = cot / ar; _projectionMatrix[ 5] = cot; _projectionMatrix[10] = _FAR / (_FAR - _NEAR); _projectionMatrix[11] = 1.0; _projectionMatrix[14] = -_NEAR * (_FAR / (_FAR - _NEAR)); return E33_EXIT_SUCCESS; } Error graphics33_term( void ) { return E33_EXIT_SUCCESS; } void graphics33_update( void ) { math33_create_view_matrix(__scene.camera.t, __scene.camera.r, _viewMatrix ); VxP( _viewMatrix, _projectionMatrix ); } void graphics33_decompose_scene( void ) { extern Scene33 __scene; Size i, j; Size displayW = __display.surface.w; Size displayH = __display.surface.h; Model33 *model = &__scene.cube; ModelEdge33 *medges = model->medges; Size *sedges = model->sedges; Size modelVertexCount = model->vertexCount; Size modelSurfaceCount = model->surfaceCount; math33_create_world_matrix( model->t, model->r, model->s, _worldMatrix ); MxM4( _worldMatrix, _viewMatrix ); #define pV _preXformedModelVertices for( i = 0; i < modelVertexCount; ++i ) { f64 iw; V4xMt( pV[i], model->vertices[i], _worldMatrix ); iw = 1.0 / pV[i][3]; pV[i][0] = ( ((pV[i][0] * iw) + 1.0) * 0.5 ); pV[i][1] = ( ((pV[i][1] * iw) + 1.0) * 0.5 ); } for( i = 0; i < modelSurfaceCount; ++i ) { Vec4 v[16]; Size a[2], b[2], c[2]; Boolean needsClippage = 0; a[0] = medges[ sedges[i*3 ] ].vertices[0]; a[1] = medges[ sedges[i*3 ] ].vertices[1]; b[0] = medges[ sedges[i*3+1] ].vertices[0]; b[1] = medges[ sedges[i*3+1] ].vertices[1]; c[0] = medges[ sedges[i*3+2] ].vertices[0]; c[1] = medges[ sedges[i*3+2] ].vertices[1]; if( a[0] == b[0] ) { Size tmp = a[0]; a[0] = a[1]; a[1] = tmp; } else if( a[1] == b[1] ) { Size tmp = b[0]; b[0] = b[1]; b[1] = tmp; } if( c[1] != a[0] ) { Size tmp = c[0]; c[0] = c[1]; c[1] = tmp; } if( ( (pV[a[0]][0] - pV[b[0]][0]) * (pV[c[0]][1] - pV[b[0]][1]) - (pV[a[0]][1] - pV[b[0]][1]) * (pV[c[0]][0] - pV[b[0]][0]) ) <= 0 ) { continue; } v[0][3] = pV[a[0]][3]; if( v[0][3] <= _NEAR ) continue; if( v[0][3] > _FAR ) continue; v[0][0] = pV[a[0]][0]; v[0][1] = pV[a[0]][1]; v[0][2] = pV[a[0]][2]; v[1][3] = pV[b[0]][3]; if( v[1][3] <= _NEAR ) continue; if( v[1][3] > _FAR ) continue; v[1][0] = pV[b[0]][0]; v[1][1] = pV[b[0]][1]; v[1][2] = pV[b[0]][2]; v[2][3] = pV[c[0]][3]; if( v[2][3] <= _NEAR ) continue; if( v[2][3] > _FAR ) continue; v[2][0] = pV[c[0]][0]; v[2][1] = pV[c[0]][1]; v[2][2] = pV[c[0]][2]; v[0][0] *= (f64)(displayW - 1); v[0][1] *= (f64)(displayH - 1); v[1][0] *= (f64)(displayW - 1); v[1][1] *= (f64)(displayH - 1); v[2][0] *= (f64)(displayW - 1); v[2][1] *= (f64)(displayH - 1); _draw_line( v[0], v[1], CYAN ); _draw_line( v[1], v[2], CYAN ); _draw_line( v[2], v[0], CYAN ); } #undef pV } static void _draw_line( Vec2 v0, Vec2 v1, u32 colour ) { u32 *dest = __display.surface.data; Size w = __display.surface.w; Size h = __display.surface.h; Size x0 = (Size)(v0[0] + 0.5 ); Size y0 = (Size)(v0[1] + 0.5 ); Size x1 = (Size)(v1[0] + 0.5 ); Size y1 = (Size)(v1[1] + 0.5 ); Size sx, sy; Size dx, dy, error; dx = (x1 - x0); if( dx < 0 ) { dx = -dx; } sx = -1; if( x0 < x1 ) sx = 1; dy = -(y1 - y0); if( dy > 0 ) { dy = -dy; } sy = -1; if( y0 < y1 ) sy = 1; error = dx + dy; while( 1 ) { Size e2; dest[ x0 + y0 * w ] = colour; if( (x0 == x1) && (y0 == y1) ) { break; } e2 = error << 1; if( e2 >= dy ) { if( x0 == x1 ) { break; } error += dy; x0 += sx; } if( e2 <= dx ) { if( y0 == y1 ) { break; } error += dx; y0 += sy; } } }