Guest User

3d scene

a guest
Aug 23rd, 2012
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.84 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include <sys/time.h>
  6. #include <SDL.h>
  7. #include <SDL_ttf.h>
  8.  
  9. //#define DEBUG_PRINT(A) printf A
  10. #define DEBUG_PRINT(A) ;
  11.  
  12. #ifndef max
  13.     #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
  14. #endif
  15.  
  16. #ifndef min
  17.     #define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
  18. #endif
  19.  
  20. int bsize = 2;
  21.  
  22. int scw = 1280;
  23. int sch = 1024;
  24.  
  25. int mapa = 32;
  26. int mapb = 32;
  27. int mapc = 128;
  28.  
  29. char* my_itoa(unsigned int val)
  30. {
  31.     static char buf[11];
  32.     short i=10;
  33.     for(;val&&i;--i,val/=10)buf[i]="0123456789"[val%10];
  34.     return &buf[i+1];
  35. }
  36.  
  37. double mygettime()
  38. {
  39.   struct timeval tv;
  40.   if(gettimeofday(&tv, 0) < 0)
  41.   {
  42.     perror("oops");
  43.   }
  44.   return (double)tv.tv_sec + (0.000001 * (double)tv.tv_usec);
  45. }
  46.  
  47. void filldata (int *hei, int *col)
  48. {
  49.     int idx,startidx;
  50.     int x,y,z;
  51.     for (y=0; y<mapb; y++)
  52.     {
  53.         for (x=0; x<mapa; x++)
  54.         {
  55.             if ((x>10)&&(x<30)&&(y>10)&&(y<30))
  56.             {
  57.                 startidx = y*mapa*mapb + x*mapa;
  58.                 hei[startidx] = 4;
  59.                 hei[startidx+1] = 25;
  60.             }
  61.  
  62.             int dist = (x-20)*(x-20)+(y-20)*(y-20);
  63.             if (dist<=81)
  64.             {
  65.                 hei[startidx+4] = 40;
  66.                 hei[startidx+5] = 41+x;
  67.  
  68.                 hei [startidx+2] = 80;
  69.                 hei [startidx+3] = 100;
  70.             }
  71.            
  72.             for (z=0; z<mapc; z++)
  73.             {
  74.                 idx = y*mapa*mapb + x*mapa + z;
  75.                 col[idx] = 3*sqrt(x*x+y*y+z*z);
  76.             }
  77.         }
  78.     }
  79. }
  80.  
  81. void fillpalette (SDL_Surface *screen)
  82. {
  83.     SDL_Color colors[256];
  84.     int i;
  85.  
  86.     for(i=0;i<=256;i++)
  87.     {
  88.         colors[i].r=i;
  89.         colors[i].g=i/3;
  90.         colors[i].b=i/3;
  91.     }
  92.     SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
  93. }
  94.  
  95. void blacken_screen (SDL_Surface *screen)
  96. {
  97.     SDL_Rect rect;
  98.     rect.x = 0;
  99.     rect.y = 0;
  100.     rect.w = scw;
  101.     rect.h = sch;
  102.  
  103.     SDL_FillRect (screen, &rect, 0);
  104. }
  105.  
  106. void checkevents(double *ang, int *x, int *y, int *z, int *k)
  107. {
  108.     SDL_Event event;
  109.     if (SDL_PollEvent(&event))
  110.     {
  111.         switch (event.type) {
  112.         case SDL_KEYDOWN:
  113.             if (event.key.keysym.sym == 'q')
  114.             {
  115.                 TTF_Quit();
  116.                 exit(0);
  117.             }
  118.         }
  119.     }
  120.     Uint8 *keystate = SDL_GetKeyState (NULL);
  121.     if (keystate[SDLK_LEFT]) *ang += 0.02;
  122.     if (keystate[SDLK_RIGHT]) *ang -= 0.02;
  123.     if (keystate[SDLK_UP]) *k -= 1;
  124.     if (keystate[SDLK_DOWN]) *k += 1;
  125.  
  126.     if (keystate[SDLK_k]) *z -= 1;
  127.     if (keystate[SDLK_j]) *z += 1;
  128.    
  129.     if (keystate[SDLK_a] || keystate[SDLK_d] || keystate[SDLK_w] || keystate[SDLK_s])
  130.     {
  131.         int xd, yd;
  132.         xd = 0;
  133.         yd = 0;
  134.         if (keystate[SDLK_a]) xd = -3;
  135.         if (keystate[SDLK_d]) xd = 3;
  136.         if (keystate[SDLK_w]) yd = 3;
  137.         if (keystate[SDLK_s]) yd = -3;
  138.        
  139.         *x += yd*cos(*ang) + xd*sin(*ang);
  140.         *y += -yd*sin(*ang) + xd*cos(*ang);
  141.     }
  142. }
  143.  
  144. int main ()
  145. {
  146.     int hei[mapa*mapb*mapc-1];
  147.     int col[mapa*mapb*mapc-1];
  148.  
  149.     memset (hei, -1, sizeof(int)*mapa*mapb*mapc);
  150.     filldata (hei, col);
  151.  
  152.     if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
  153.     {
  154.         fprintf(stderr, "Cannot initialize SDL: %s\n", SDL_GetError());
  155.         exit(1);
  156.     }
  157.  
  158.     if (TTF_Init()==-1)
  159.     {
  160.         printf ("Error Init TTF\n");
  161.         exit(1);
  162.     }
  163.     TTF_Font *font = TTF_OpenFont ("tahoma.ttf", 24);
  164.     SDL_Color fontcolor;
  165.     fontcolor.r = 255;
  166.     fontcolor.g = 255;
  167.     fontcolor.b = 255;
  168.  
  169.     SDL_Rect dest;
  170.     dest.x = 20;
  171.     dest.y = 20;
  172.     SDL_Surface *textrend = TTF_RenderText_Solid (font, "FPS: ", fontcolor);
  173.  
  174.     SDL_Surface *screen;
  175.     screen = SDL_SetVideoMode(scw, sch, 8, SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
  176.     if ( screen == NULL )
  177.     {
  178.         fprintf(stderr, "Cannot set resolution %ix%i: %s\n", scw, sch, SDL_GetError());
  179.         exit(1);
  180.     }
  181.  
  182.     fillpalette (screen);
  183.  
  184.     int posx = 0;
  185.     int posy = 0;
  186.     int posz = 80;
  187.  
  188.     double ang = 0;
  189.     int k = 1;
  190.  
  191.     double dd = 1;
  192.     double de = dd * 228; // 128 is the max "distance"
  193.     int x,y,z;
  194.  
  195.     double amax = M_PI/3.4; // FOV
  196.     double a;
  197.  
  198.     int bin1 = mapb*mapb*mapb-mapa*mapa;
  199.     int bin2 = mapa*mapa-mapa;
  200.     int bin3 = mapc-1;
  201.  
  202.     int sx;
  203.  
  204.     int minsytop[scw-1];
  205.     int maxsybottom[scw-1];
  206.     int areas;
  207.  
  208.     double time1 = mygettime();
  209.     double time2;
  210.     int frames = 0;
  211.    
  212.     while (1)
  213.     {
  214.         SDL_LockSurface(screen);
  215.        
  216.         blacken_screen (screen);
  217.  
  218.         double sinang = sin(ang);
  219.         double cosang = cos(ang);
  220.  
  221.         for (sx=0;sx<scw;sx++)
  222.         {
  223.             memset (minsytop, -1, sizeof(int)*scw);
  224.             memset (maxsybottom, -1, sizeof(int)*scw);
  225.             minsytop[0] = 0;
  226.             maxsybottom[0] = sch-1;
  227.             areas = 1;
  228.            
  229.             double d;
  230.             a = -amax + 2*amax*sx/scw;
  231.             for (d=0;d<=de;d+=dd)
  232.             {
  233.                 double y1 = d*/*cos(amax)**/tan(a);
  234.                 double x1 = d;//*cos(amax);
  235.  
  236.                 x = posx + x1*cosang+y1*sinang;
  237.                 y = posy - x1*sinang+y1*cosang;
  238.                 z = posz - k*d;//*sin(amax);
  239.  
  240.                 int idx = ((y*mapa*mapb)&bin1) + ((x*mapa)&bin2);
  241.                 int zi;
  242.  
  243.                 DEBUG_PRINT (("Inside d\n"));
  244.                
  245.                 for (zi=0; zi<mapc/2; zi++)
  246.                 {
  247.                     int idxstart = idx + zi*2;
  248.                     int hstart = hei[idxstart];
  249.  
  250.                     int idxend = idx + zi*2 + 1;
  251.                     int hend = hei[idxend];
  252.  
  253.                     if (hstart==-1) break;
  254.  
  255.                     DEBUG_PRINT (("gstart = %i, hend = %i\n", hstart, hend));
  256.                    
  257.                     int sy = sch/2 + 150*(z-hstart)/(d+1);
  258.                     int sy2 = sch/2 + 150*(z-hend)/(d+1);
  259.  
  260.                     int area;
  261.                     for (area=0; area<areas; area++)
  262.                     {
  263.                         DEBUG_PRINT (("Area = %i\n", area));
  264.                         int top = minsytop[area];
  265.                         int bottom = maxsybottom[area];
  266.                         if (top==-1) break;
  267.  
  268.                         int ovsy2 = max (top, sy2);
  269.                         int ovsy = min (bottom, sy);
  270.  
  271.                         DEBUG_PRINT (("sy = %i, sy2 = %i\n", sy, sy2));
  272.                         DEBUG_PRINT (("bottom = %i, top = %i\n", bottom, top));
  273.                        
  274.                         if (ovsy2<sch)
  275.                         {
  276.                             if (ovsy>=sch) ovsy = sch-1;
  277.                             if (ovsy2<0) ovsy2 = 0;
  278.                             int syi;
  279.                             for (syi=ovsy; syi>=ovsy2; syi--)
  280.                             {
  281.                                 *((Uint8*)screen->pixels+sx+scw*syi) = col[idx];
  282.                             }
  283.                         }
  284.  
  285.                         // Adjust minsytop and maxsybottom
  286.                         if ((sy2>top)&&(sy<bottom)) //Split
  287.                         {
  288.                             maxsybottom[area] = sy2;
  289.                             minsytop[areas] = sy;
  290.                             maxsybottom[areas] = bottom;
  291.                            
  292.                             areas++;
  293.                             break;
  294.                         }
  295.                         //if (top==ovsy2) minsytop[area] = sy; // Correct top
  296.                         //if (bottom==ovsy) maxsybottom[area] = sy2; // Correct bottom
  297.                         else if ((sy2<top)&&(sy>top)&&(sy<bottom)) minsytop[area] = sy;
  298.                         else if ((sy>bottom)&&(sy2<bottom)&&(sy2>top)) maxsybottom[area] = sy2;
  299.                         else if ((sy2<top)&&(sy>bottom)) // Destroy area
  300.                         {
  301.                             memmove (maxsybottom+area, maxsybottom+area+1, sizeof(int)*(areas-area));
  302.                             memmove (minsytop+area, minsytop+area+1, sizeof(int)*(areas-area));
  303.                             areas--;
  304.                         }
  305.                     }
  306.                     DEBUG_PRINT (("Areas %i\n", areas));
  307.                 }
  308.             }
  309.         }
  310.  
  311.         SDL_UnlockSurface (screen);
  312.         SDL_BlitSurface (textrend, NULL, screen, &dest);
  313.         SDL_Flip (screen);
  314.         checkevents (&ang, &posx, &posy, &posz, &k);
  315.         frames++;
  316.  
  317.         time2 = mygettime() - time1;
  318.         if (time2 > 1.0)
  319.         {
  320.             SDL_FreeSurface (textrend);
  321.             char fpsstring[30] = "FPS: ";
  322.             strcat (fpsstring, my_itoa (frames));
  323.             textrend = TTF_RenderText_Solid (font, fpsstring, fontcolor);
  324.             frames = 0;
  325.             time1 = mygettime();
  326.         }
  327.     }
  328.    
  329.     return atexit(SDL_Quit);
  330. }
Add Comment
Please, Sign In to add comment