3D Starfield SDL

Torak 28.09.03 00:56

3D Starfield SDL

 Tekstiversio  Arvo: 4 (5 ääntä)  Äänestä: +  -
//========================================================================
// 3D Starfield - Klassikko efekti. Toimii ainakin VC 7:lla.
//========================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <SDL.h>

//========================================================================
// SDL lib
//========================================================================
// Automatic LIB addon for VC
#ifdef WIN32
#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDLmain.lib")
#endif

//========================================================================
// Defines
//========================================================================
// Intro configuration
#define NUMSTARS 2000    // Number of stars
#define VIDEOX 640              // Screen x resolution
#define VIDEOY 480              // Screen y resolution
#define TICKS 30  // Minimum screen update time
#define SCALE 900                // Perspective value
#define RAND(max) (rand() % max)

//========================================================================
// Data types
//========================================================================
typedef struct
{
        int x,y,z;
} star_type;

//========================================================================
// Global variables
//========================================================================
star_type stars[NUMSTARS];

//========================================================================
// Function prototypes
//========================================================================
void Stars_Init(void);
void Stars_Draw(SDL_Surface *S);
void Stars_Move(void);
void putpixel32(SDL_Surface *S, int x, int y, int r, int g, int  b);

//========================================================================
// Main loop
//========================================================================
int main(int argc, char *argv[])
{
    SDL_Surface* screen;
    Uint32 ticks;
        Uint32 t_flip, t_diff;
        int i;
   
    // Initialize the SDL library
    if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
        SDL_Quit();
        return 1;
    }
    else
    {
                // Register SLD_Quit() to exit-processing function
        atexit(SDL_Quit);
    }

    // Try and set the video mode
    screen = SDL_SetVideoMode(VIDEOX, VIDEOY, 32,
                SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);
    if ( screen == NULL  )
    {
        fprintf(stderr, "Couldn't initialize video mode: %s\n",  SDL_GetError());
        return 1;
    }

        // Hide cursor
        SDL_ShowCursor(SDL_DISABLE);   

        // Ignore all other events except keyboard and quit
        for(i=0; i<SDL_NUMEVENTS; ++i )
        {
                if (i != SDL_KEYDOWN && i != SDL_QUIT)
                        SDL_EventState(i, SDL_IGNORE);
        }

        Stars_Init();

    while (SDL_PollEvent(NULL)==0)
    {      
                t_flip = SDL_GetTicks();                        // Save the time  
                SDL_FillRect(screen, NULL,                  // Make       black screen
                        SDL_MapRGB(screen->format, 0,0,0));          
                Stars_Move();                  // Zoom    space              
        SDL_LockSurface(screen);                        // Start drawing               
                Stars_Draw(screen);                         // Actual draw operation          
        SDL_UnlockSurface(screen);                  // Drawing end                               
        SDL_Flip(screen);                                   // Show        the new picture   
                t_diff = SDL_GetTicks() - t_flip;        // Slow down
                if(t_diff < TICKS) SDL_Delay(TICKS-t_diff);
    }

    return 0;
}

//========================================================================
// Initialise stars they random position.
//========================================================================
void Stars_Init(void)
{
        int loop;

        for(loop=0; loop<NUMSTARS; loop++)
        {
                stars[loop].x = RAND(VIDEOX) - VIDEOX/2;
                stars[loop].y = RAND(VIDEOY) - VIDEOY/2;
                stars[loop].z = loop+1;
        }
}

//========================================================================
// Draw stars in surface
//========================================================================
void Stars_Draw(SDL_Surface *S)
{
        int loop;
        int xpos;
        int ypos;

        for(loop=0; loop<NUMSTARS; loop++)
        {
                // 3D -> 2D
                xpos =(int)((stars[loop].x*SCALE)/stars[loop].z)+(VIDEOX/2);
                ypos =(int)((stars[loop].y*SCALE)/stars[loop].z)+(VIDEOY/2);

                if(xpos < VIDEOX && ypos < VIDEOY && xpos>0 && ypos>0)      
                        putpixel32(S, xpos, ypos, 255, 255, 255);
        }
}

//========================================================================
// Plot pixel to surface. Surface format need to be 32bit.
//========================================================================
void Stars_Move(void)
{
        int loop;
        for(loop=0;loop<NUMSTARS;loop++)
        {
                stars[loop].z-=5;
                if(stars[loop].z<1 || stars[loop].z == 0)
                        stars[loop].z+=NUMSTARS;
        }
}

//========================================================================
// Plot pixel to surface. Surface format need to be 32bit.
//========================================================================
void putpixel32(SDL_Surface *S, int x, int y, int r, int g, int  b)
{
        Uint32 color;
        Uint32 *pixels;

        color = SDL_MapRGB(S->format, r, g, b);
        pixels = (Uint32 *) S->pixels;

        pixels[S->pitch*y/4 + x] = color;
}

Akheron 15:02 1.10.03 
Toimii myös gcc:llä käännettynä Linuxissa. Hyvä esimerkki, tosin joitain kohtia olisi voinut kommentoida vähän enemmän.
phadej 20:57 27.3.05 
jos muuttaa piirtofunktion:
//========================================================================
// Draw stars in surface
//========================================================================
void Stars_Draw(SDL_Surface *S)
{
        int loop;
        int xpos;
        int ypos;
        int color;

        for(loop=0; loop<NUMSTARS; loop++)
        {
                // 3D -> 2D
                xpos =(int)((stars[loop].x*SCALE)/stars[loop].z)+(VIDEOX/2);
                ypos =(int)((stars[loop].y*SCALE)/stars[loop].z)+(VIDEOY/2);

                color = (NUMSTARS-stars[loop].z)*255/NUMSTARS;

                if(xpos < VIDEOX && ypos < VIDEOY && xpos>0 && ypos>0)
                putpixel32(S, xpos, ypos, color, color, color);
        }
}


tulee hienompaa jälkeä :)