// // FRAME5.CPP // // RomaNets Software 3D Tutorial, 2000 // #include #include #include #include #include #include #include "mytype.h" #include "frame5.h" // GLOBALS /////////////////////////////////////////////////////////////////// unsigned char far * double_bufferB; MATRIX world; int X0 = 160; int Y0 = 100; int g_point_color = 14; int g_line_color = 15; int g_flag_pause = 0; // PROTOTYPES //////////////////////////////////////////////////////////////// void App_InitObjects(); void App_Render(); void InitGraph(); void ClearDoubleBuffer(); void WaitForVsync(); void ShowDoubleBuffer(); void Line ( int x1, int y1, int x2, int y2 ); void SetPointColor( int color ); void SetLineColor( int color ); // code is in tri.cpp extern void Triangle8(BYTE *p, int next_scan, POINT P0, POINT P1, POINT P2, DWORD c); // ================================================================= void SetRotateZMatrix( MATRIX &m, float a) // ================================================================= { float COS = cos(a); float SIN = sin(a); m._11 = COS; m._12 = SIN; m._13 = 0; m._14 = 0; m._21 = -SIN; m._22 = COS; m._23 = 0; m._24 = 0; m._31 = 0; m._32 = 0; m._33 = 1; m._34 = 0; m._41 = 0; m._42 = 0; m._43 = 0; m._44 = 1; } // ================================================================= void SetRotateXMatrix( MATRIX &m, float a) // ================================================================= { float COS = cos(a); float SIN = sin(a); m._11 = 1; m._12 = 0; m._13 = 0; m._14 = 0; m._21 = 0; m._22 = COS; m._23 = SIN; m._24 = 0; m._31 = 0; m._32 = -SIN; m._33 = COS; m._34 = 0; m._41 = 0; m._42 = 0; m._43 = 0; m._44 = 1; } // ================================================================= void SetRotateYMatrix( MATRIX &m, float a) // ================================================================= { float COS = cos(a); float SIN = sin(a); m._11 = COS; m._12 = 0; m._13 = -SIN; m._14 = 0; m._21 = 0; m._22 = 1; m._23 = 0; m._24 = 0; m._31 = SIN; m._32 = 0; m._33 = COS; m._34 = 0; m._41 = 0; m._42 = 0; m._43 = 0; m._44 = 1; } // ================================================================= void SetTranslateMatrix( MATRIX &m, float x, float y, float z ) // ================================================================= { m._11 = 1; m._12 = 0; m._13 = 0; m._14 = 0; m._21 = 0; m._22 = 1; m._23 = 0; m._24 = 0; m._31 = 0; m._32 = 0; m._33 = 1; m._34 = 0; m._41 = x; m._42 = y; m._43 = z; m._44 = 1; } // ================================================================= void SetScaleMatrix( MATRIX &m, float x, float y, float z ) // ================================================================= { m._11 = x; m._12 = 0; m._13 = 0; m._14 = 0; m._21 = 0; m._22 = y; m._23 = 0; m._24 = 0; m._31 = 0; m._32 = 0; m._33 = z; m._34 = 0; m._41 = 0; m._42 = 0; m._43 = 0; m._44 = 1; } // // b11 b12 b13 b14 a11 a12 a13 a14 [Q] = [B]*[A] // b21 b22 b23 b24 a21 a22 a23 a24 // b31 b32 b33 b34 a31 a32 a33 a34 // b41 b42 b43 b44 a41 a42 a43 a44 // ================================================================= void MatrixMultiply( MATRIX &q, MATRIX &a, MATRIX &b ) // ================================================================= { q._11 = b._11*a._11 + b._12*a._21 + b._13*a._31 + b._14*a._41; q._12 = b._11*a._12 + b._12*a._22 + b._13*a._32 + b._14*a._42;; q._13 = b._11*a._13 + b._12*a._23 + b._13*a._33 + b._14*a._43; q._14 = b._11*a._14 + b._12*a._24 + b._13*a._34 + b._14*a._44; q._21 = b._21*a._11 + b._22*a._21 + b._23*a._31 + b._24*a._41; q._22 = b._21*a._12 + b._22*a._22 + b._23*a._32 + b._24*a._42; q._23 = b._21*a._13 + b._22*a._23 + b._23*a._33 + b._24*a._43; q._24 = b._21*a._14 + b._22*a._24 + b._23*a._34 + b._24*a._44; q._31 = b._31*a._11 + b._32*a._21 + b._33*a._31 + b._34*a._41; q._32 = b._31*a._12 + b._32*a._22 + b._33*a._32 + b._34*a._42; q._33 = b._31*a._13 + b._32*a._23 + b._33*a._33 + b._34*a._43; q._34 = b._31*a._14 + b._32*a._24 + b._33*a._34 + b._34*a._44; q._41 = b._41*a._11 + b._42*a._21 + b._43*a._31 + b._44*a._41; q._42 = b._41*a._12 + b._42*a._22 + b._43*a._32 + b._44*a._42; q._43 = b._41*a._13 + b._42*a._23 + b._43*a._33 + b._44*a._43; q._44 = b._41*a._14 + b._42*a._24 + b._43*a._34 + b._44*a._44; } // ================================================================= void _MatrixMultiply( MATRIX& q, MATRIX& a, MATRIX& b ) // ================================================================= { float* pA = (float*)&a; float* pB = (float*)&b; float pM[16]; memset( pM, 0, sizeof(MATRIX) ); for( int i=0; i<4; i++ ) for( int j=0; j<4; j++ ) for( int k=0; k<4; k++ ) pM[4*i+j] += pA[4*k+j] * pB[4*i+k]; memcpy( &q, pM, sizeof(MATRIX) ); } // ----------------------------------------------------------------- Point Point::operator*(MATRIX const &m) // ----------------------------------------------------------------- { float x1 = x*m._11 + y*m._21 + z*m._31 + m._41; float y1 = x*m._12 + y*m._22 + z*m._32 + m._42; float z1 = x*m._13 + y*m._23 + z*m._33 + m._43; // return Point(x1,y1,z1); float w = x*m._14 + y*m._24 + z*m._34 + m._44; // new for STEP_5 return Point(x1/w,y1/w,z1/w); } // ----------------------------------------------------------------- void Point::draw() // ----------------------------------------------------------------- { // projection // int x1 = X0 + (int)x; int y1 = Y0 - (int)y; long off = y1*320 + x1; double_bufferB[off] = g_point_color; } // ----------------------------------------------------------------- Point& Point::Normalize() // ----------------------------------------------------------------- { float length = sqrt(x*x + y*y + z*z); x = x/length; y = y/length; z = z/length; return *this; } // ================================================================= void DrawPointList( Point *p, int num) // ================================================================= { for ( int i=0; i 0 ) // culling back side // continue; // !!! IT'S BETTER DO IT AT SCREEN COORDINATES n.Normalize(); // !!! HERE WE CALC ONLY COLOR float shade = DotProduct( n, Light); shade += AmbientLight; if ( shade < 0 ) shade = 0; if ( shade > 1.0 ) shade = 1.0; color = 64 + 63*shade ; // VIEW MATRIX // MATRIX matView; // position and orientation of the camera matView._43 = 350.0f; // back along the z-axis by -350 units // matView._41 = -15.0f; // right along the x-axis by 15 units p0 = p0*matView; p1 = p1*matView; p2 = p2*matView; // PROJECT MATRIX // MATRIX matProj; // how the 3D scene is "projected" onto the matProj._11 = 400.0f; //w // 2D render target (the backbuffer surface) matProj._22 = 400.0f*0.8; //h matProj._34 = 1.0f; matProj._43 = -1.0f; matProj._44 = 0.0f; p0 = p0*matProj; p1 = p1*matProj; p2 = p2*matProj; POINT P0; // Screen coordinates POINT P1; POINT P2; P0.x = X0 + p0.x; P0.y = Y0 - p0.y; P1.x = X0 + p1.x; P1.y = Y0 - p1.y; P2.x = X0 + p2.x; P2.y = Y0 - p2.y; int v1 = P2.x - P1.x; // Culling operation int w1 = P1.x - P0.x; int v2 = P2.y - P1.y; int w2 = P1.y - P0.y; if ( v1*w2 - v2*w1 < 0 ) continue; Triangle8( (BYTE*)double_bufferB,320, P0, P1, P2, color ); } } // ================================================================= void InitGraph() // ================================================================= { asm { mov ax,0x13 int 0x10; } double_bufferB = new char[320*200L]; } // ================================================================= void ClearDoubleBuffer() // ================================================================= { //long color = 0x01010101; //long color = 0x0F0F0F0F; long color = 0; long far *dbDW=(long far*)double_bufferB; for ( long i=0; i<320*50L; i++ ) *dbDW++ = color; } // ================================================================= void ShowDoubleBuffer() // ================================================================= { long far *vb=(long far*)0xA0000000L; long far *dbDW=(long far*)double_bufferB; for ( long i=0; i<320*50L; i++ ) *vb++ = *dbDW++; } // ================================================================= void WaitForVsync() // ================================================================= { while(inp(0x3DA) & 0x08) { // do nothing, vga is in retrace } while(!(inp(0x3DA) & 0x08)) { // do nothing, wait for start of retrace } } // ================================================================= void SetPaletteRegister( int index, RGBCOLOR *color ) // ================================================================= { //outp( 0x3C6,0xff); // register mask outp( 0x3C8, index); // register write outp( 0x3C9, color->red); // register data outp( 0x3C9, color->green); outp( 0x3C9, color->blue); } // ================================================================= void Line ( int x1, int y1, int x2, int y2 ) // ================================================================= { //int color = 15; int color = g_line_color; // projection // x1 = X0 + x1; x2 = X0 + x2; y1 = Y0 - y1; y2 = Y0 - y2; long off; int dx = abs ( x2 - x1 ); int dy = abs ( y2 - y1 ); int sx = x2 >= x1 ? 1 : -1; int sy = y2 >= y1 ? 1 : -1; int d,d1,d2,x,y,i; if ( dy <= dx ) { d = ( dy << 1 ) - dx; d1 = dy << 1; d2 = ( dy - dx ) << 1; off = (y1<<8) + (y1<<6) + x1; double_bufferB[off] = color; for ( x = x1 + sx, y = y1, i = 1; i <= dx; i++, x += sx ) { if ( d > 0 ) { d += d2; y += sy; } else d += d1; off = (y<<8) + (y<<6) + x; double_bufferB[off] = color; } } else { d = ( dx << 1 ) - dy; d1 = dx << 1; d2 = ( dx - dy ) << 1; off = (y1<<8) + (y1<<6) + x1; double_bufferB[off] = color; for ( x = x1, y = y1 + sy, i = 1; i <= dy; i++, y += sy ) { if ( d > 0 ) { d += d2; x += sx; } else d += d1; off = (y<<8) + (y<<6) + x; double_bufferB[off] = color; } } } // Line // ================================================================= void SetPointColor( int color ) // ================================================================= { g_point_color = color; } // ================================================================= void SetLineColor( int color ) // ================================================================= { g_line_color = color; } //////////////////////////////////////////////////////////////////// void main() //////////////////////////////////////////////////////////////////// { InitGraph(); App_InitObjects(); int done = 0; while ( !done ) { if ( kbhit() ) { int ch = getch(); switch ( ch ) { case 27: // ESC done = 1; break; case 'p': case 'P': g_flag_pause = !g_flag_pause; break; } } if ( !g_flag_pause ) { ClearDoubleBuffer(); App_Render(); WaitForVsync(); ShowDoubleBuffer(); } } delete [] double_bufferB; textmode(3); }