Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // include Simple Direct-media Layer
- #include <SDL/SDL.h>
- #pragma comment( lib, "SDL.lib" )
- #include <math.h>
- // setup some basic data types
- typedef signed long long s64;
- typedef unsigned long long u64;
- typedef unsigned int u32;
- typedef signed int s32;
- typedef signed short s16;
- typedef unsigned char byte;
- typedef signed long long fp64;
- // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK SPECIFICS
- namespace framework
- {
- // the title name for this application
- const char *app_name = "Raytrace Demo";
- // size of the video buffer
- const int vidSize = 512;
- // pixel size
- const int vidScale = 1;
- // video buffer
- u32 *video = NULL;
- // number of pixels in the video buffer
- const int nPixels = vidSize * vidSize;
- // calculated real SDL video buffer size
- const int scrRes = vidSize * vidScale;
- // the real SDL video buffer
- SDL_Surface *screen = NULL;
- // rate onTick is called in FPS
- const int tickFPS = 45;
- // mouse position
- int mousex = 0;
- int mousey = 0;
- }; // namespace framework
- using namespace framework;
- // ---- ----- ---- ---- ---- ---- ---- ---- MATH HELPER FUNCTIONS
- namespace mathHelper
- {
- static u32 randSeed = 0xBABEFACE;
- static s64 absi( s64 a )
- {
- if ( a < 0 ) return -a;
- else return a;
- }
- static s64 maxi( s64 a, s64 b )
- {
- if ( a > b ) return a;
- else return b;
- }
- static s64 mini( s64 a, s64 b )
- {
- if ( a < b ) return a;
- else return b;
- }
- inline u32 randi( void )
- {
- randSeed *= 1103515245;
- randSeed += 12345;
- return (randSeed >> 15) & 0xFFFF;
- }
- inline u32 scale( u32 a, byte scale )
- {
- return (a * scale) >> 8;
- }
- }; // namespace mathHelper
- using namespace mathHelper;
- // ---- ----- ---- ---- ---- ---- ---- ---- FIXED POINT HELPER FUNCTIONS
- namespace fixedPointHelper
- {
- const fp64 fp_1 = 0x10000;
- fp64 fp_mul( fp64 a, fp64 b )
- {
- return (a * b) >> 16;
- }
- fp64 fp_div( fp64 a, fp64 b )
- {
- return (a << 16) / b;
- }
- fp64 fp_ceil( fp64 a )
- {
- return (a | 0xFFFF) + 1;
- }
- fp64 fp_floor( fp64 a )
- {
- return a & (~0xFFFF);
- }
- fp64 fp_fract( fp64 a )
- {
- return a & 0xFFFF;
- }
- fp64 fp_ifract( fp64 a )
- {
- return 0xFFFF - (a & 0xFFFF);
- }
- int fp_to_int( fp64 a )
- {
- return (int) (a >> 16);
- }
- fp64 int_to_fp( int a )
- {
- return (a << 16);
- }
- fp64 fp_rand( int max )
- {
- return ((randi() % max) << 16) | (randi() & 0xFFFF);
- }
- }; // namespace fixedPointHelper
- using namespace fixedPointHelper;
- // ---- ----- ---- ---- ---- ---- ---- ---- DRAWING HELPER FUNCTIONS
- namespace videoHelper
- {
- static u32 drawColour = 0xFFFFFF;
- inline void plot( int x, int y )
- {
- bool out = x < 0;
- out |= y < 0;
- out |= x >= vidSize;
- out |= y >= vidSize;
- if ( out ) return;
- video[ x + y * vidSize ] = drawColour;
- }
- inline u32 readPixel( int x, int y )
- {
- bool out = x < 0;
- out |= y < 0;
- out |= x >= vidSize;
- out |= y >= vidSize;
- if ( out ) return 0;
- return video[ x + y * vidSize ];
- }
- void circle( s32 x0, s32 y0, s32 radius )
- {
- s32 error = 1 - radius;
- s32 errorY = 1;
- s32 errorX = -2 * radius;
- s32 x = radius, y = 0;
- plot(x0, y0 + radius);
- plot(x0, y0 - radius);
- plot(x0 + radius, y0);
- plot(x0 - radius, y0);
- while(y < x)
- {
- if (error > 0)
- { x--; errorX += 2; error += errorX; }
- { y++; errorY += 2; error += errorY; }
- plot(x0 + x, y0 + y);
- plot(x0 - x, y0 + y);
- plot(x0 + x, y0 - y);
- plot(x0 - x, y0 - y);
- plot(x0 + y, y0 + x);
- plot(x0 - y, y0 + x);
- plot(x0 + y, y0 - x);
- plot(x0 - y, y0 - x);
- }
- }
- void line( s32 X0, s32 Y0, s32 X1, s32 Y1 )
- {
- s32 incrementVal = 0;
- s32 shortLen = Y1 - Y0;
- s32 longLen = X1 - X0;
- bool yLonger = false;
- s32 decInc = 0;
- s32 endVal = 0;
- s32 j = 0;
- if ( absi( shortLen ) > absi( longLen ) )
- {
- int swap = shortLen;
- shortLen = longLen;
- longLen = swap;
- yLonger = true;
- }
- endVal = longLen;
- if ( longLen < 0 )
- {
- incrementVal = -1;
- longLen = -longLen;
- }
- else
- incrementVal = 1;
- if ( longLen == 0 )
- decInc = 0;
- else
- decInc = (shortLen << 16) / longLen;
- if ( yLonger )
- {
- for ( s32 i=0; i!=endVal; i+=incrementVal )
- {
- plot( X0 + (j >> 16), Y0 + i );
- j += decInc;
- }
- }
- else
- {
- for ( s32 i=0; i!=endVal; i+=incrementVal )
- {
- plot( X0 + i, Y0 + (j >> 16) );
- j += decInc;
- }
- }
- }
- }; // namesapce videoHelper
- using namespace videoHelper;
- // ---- ----- ---- ---- ---- ---- ---- ---- DEMO CODE ( the good stuff )
- namespace demo
- {
- struct vec3
- {
- float x, y, z;
- vec3( )
- : x( 0 ), y( 0 ), z( 0 )
- {
- }
- vec3( float _tx, float _ty, float _tz )
- : x( _tx ), y( _ty ), z( _tz )
- {
- }
- void normalize( void )
- {
- float d = 1.0f / sqrtf( x*x + y*y + z*z );
- x *= d;
- y *= d;
- z *= d;
- }
- vec3 operator - ( const vec3 &a )
- {
- return vec3( x - a.x, y - a.y, z - a.z );
- }
- vec3 operator + ( const vec3 &a )
- {
- return vec3( x + a.x, y + a.y, z + a.z );
- }
- float operator * ( const vec3 &a )
- {
- return x*a.x + y*a.y + z*a.z;
- }
- vec3 operator * ( const float s )
- {
- return vec3( x*s, y*s, z*s );
- }
- float lengthSqr( void )
- {
- return x*x + y*y + z*z;
- }
- };
- struct sSphere
- {
- sSphere( )
- : origin( 0, 0, 0 ), radius( 0 )
- {
- }
- sSphere( float x, float y, float z, float r )
- : origin( x, y, z ), radius( r )
- {
- }
- sSphere( float x, float y, float z, float r, u32 c )
- : origin( x, y, z ), radius( r ), colour( c )
- {
- }
- vec3 origin;
- float radius;
- u32 colour;
- };
- struct sRay
- {
- vec3 origin;
- vec3 normal;
- };
- u32 randColour( void )
- {
- return ((randi()&0xFF) << 16 ) | ((randi()&0xFF) << 8 ) | ((randi()&0xFF) );
- }
- bool intersect( sRay &ray, sSphere &sphere, vec3 &ipoint )
- {
- vec3 EO = sphere.origin - ray.origin;
- float v = EO * ray.normal;
- float disc = sphere.radius * sphere.radius;
- disc -= (EO*EO) - (v*v);
- if ( disc < 0.0 )
- return false;
- float d = sqrtf( disc );
- ipoint = ray.origin + ray.normal * (v-d);
- return true;
- }
- const int nSpheres = 3;
- sSphere spheres[ nSpheres ] =
- {
- sSphere( 0, 32, 315, 96, randColour( ) ),
- sSphere( -128, -32, 512, 48, randColour( ) ),
- sSphere( 0, -64, 256, 64, randColour( ) )
- };
- void onInit( void )
- {
- /*
- for ( int i=0; i<nSpheres; i++ )
- {
- sSphere &s = spheres[i];
- s.origin.x = (float) ( randi() % 256) - 128;
- s.origin.y = (float) ( randi() % 256) - 128;
- s.origin.z = (float) ( randi() % 256) + 128;
- s.radius = (float) ( randi() % 5) + 8;
- s.colour = randColour( );
- }
- */
- }
- void onKeyHit( SDLKey key )
- {
- switch ( key )
- {
- case ( SDLK_SPACE ):
- onInit( );
- }
- }
- u32 rayShoot( sRay &ray )
- {
- //
- float min = -1.0f;
- u32 colour = 0;
- //
- for ( int i=0; i<nSpheres; i++ )
- {
- vec3 ipoint( 0, 0, 0 );
- if ( intersect( ray, spheres[i], ipoint ) )
- {
- float dst = ipoint.lengthSqr( );
- if ( dst < min || min < 0.0f )
- {
- min = dst;
- vec3 normal = (ipoint - spheres[i].origin);
- float irad = 1.0f / spheres[i].radius;
- normal.x *= irad;
- normal.y *= irad;
- normal.z *= irad;
- int r = (int)(127.0 + 127.0 * normal.x);
- int g = (int)(127.0 + 127.0 * normal.y);
- int b = (int)(127.0 - 127.0 * normal.z);
- // colour = spheres[i].colour;
- colour = (r<<16) | (g<<8) | b;
- }
- }
- }
- return colour;
- }
- void incWrap( float &x, float y )
- {
- const float _2PI = 6.28318530718f;
- if ( (x+=y) > _2PI ) x -= _2PI;
- }
- float t = 0.0;
- void onTick( void )
- {
- float hvs = vidSize / 2.0;
- for ( int y=0; y<vidSize; y++ )
- {
- for ( int x=0; x<vidSize; x++ )
- {
- sRay ray = { vec3( ), vec3( x-hvs, y-hvs, hvs*2 ) };
- ray.normal.normalize( );
- drawColour = rayShoot( ray );
- plot( x, y );
- }
- }
- incWrap( t, 0.01f );
- spheres[0].origin.x = sin( (float)t ) * 256.0f;
- }
- }; // namespace demo
- using namespace demo;
- // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK FUNCIONS
- namespace framework
- {
- static bool app_init( void )
- {
- if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
- return false;
- SDL_WM_SetCaption( app_name, NULL );
- screen = SDL_SetVideoMode( scrRes, scrRes, 32, 0 );
- if ( screen == NULL )
- return false;
- if ( vidScale == 1 ) video = (u32*)screen->pixels;
- else video = new u32[ nPixels ];
- return true;
- }
- static void blit_2x( void )
- {
- //
- const int stride = screen->w;
- u32 *dst = (u32*) screen->pixels;
- int a = 0;
- for ( int i=0; i<nPixels; i++ )
- {
- u32 colour = video[ i ];
- // x4 pixel write
- dst[0 ] = colour;
- dst[1 ] = colour;
- dst[ stride] = colour;
- dst[1+stride] = colour;
- dst += 2;
- if ( a++ >= vidSize )
- {
- a = 0;
- // add on ONE stride not two since one length
- // has already been walked
- dst += stride;
- }
- }
- }
- static void app_draw( void )
- {
- if ( vidScale <= 1 )
- return;
- if ( vidScale == 2 )
- {
- blit_2x( );
- return;
- }
- for ( int i=0; i<nPixels; i++ )
- {
- SDL_Rect rect =
- {
- (i % vidSize) * vidScale,
- (i / vidSize) * vidScale,
- vidScale,
- vidScale
- };
- SDL_FillRect( screen, &rect, video[ i ] );
- }
- }
- static bool app_tick( void )
- {
- static bool active = true;
- SDL_Event event;
- while ( SDL_PollEvent( &event ) )
- {
- switch ( event.type )
- {
- case ( SDL_QUIT ):
- active = false;
- break;
- case ( SDL_KEYUP ):
- {
- if ( event.key.keysym.sym == SDLK_ESCAPE )
- active = false;
- else
- onKeyHit( event.key.keysym.sym );
- }
- break;
- }
- }
- return active;
- }
- static void app_quit( void )
- {
- //
- if ( video != NULL )
- if ( video != screen->pixels )
- delete [] video;
- video = NULL;
- //
- if ( screen != NULL )
- SDL_FreeSurface( screen );
- //
- SDL_Quit( );
- }
- }; // namespace framework
- // windows entry point
- int __stdcall WinMain( int, int, int, int )
- {
- // start up SDL
- atexit( app_quit );
- if (! app_init( ) )
- return 1;
- // get keyboard access
- u32 keyCount = 0;
- byte *keys = SDL_GetKeyState( (int*) &keyCount );
- // seed the random
- randSeed ^= SDL_GetTicks( );
- // call the on initialize function
- onInit( );
- //
- int oldTicks = SDL_GetTicks( );
- // work out the tick threshold in milliseconds
- const int tickThresh = 1000 / tickFPS;
- //
- while ( app_tick( ) )
- {
- int diff = SDL_GetTicks() - oldTicks;
- if ( diff < 10 )
- SDL_Delay( 10 );
- if ( diff > 500 )
- {
- oldTicks += diff;
- continue;
- }
- while ( diff > tickThresh )
- {
- // grab the mouse state
- SDL_GetMouseState( &mousex, &mousey );
- // tick the application
- onTick( );
- app_draw( );
- SDL_Flip( screen );
- // progress the tick count
- oldTicks += tickThresh;
- diff -= tickThresh;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement