Recent

Author Topic: SDL vs OpenGL  (Read 55826 times)

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: SDL vs OpenGL
« Reply #15 on: January 24, 2017, 10:58:42 pm »
Quote
I looked at an SDL sample that renders a 320x200 animation...

Who one does a so small demo window that can be hardware accelerated BTW  :D

According to this website http://lazyfoo.net/tutorials/SDL/index.php

There's as I said software and hardware in SDL. Hardware is 'new'

"A big new feature in SDL 2.0 is hardware accelerated texture based 2D rendering. Here we'll be loading an image to render it using textures."

Issues with the drivers can be as said, I have these kind of problems with nvidia cards in the past.

« Last Edit: January 24, 2017, 11:22:02 pm by lainz »

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #16 on: January 25, 2017, 10:11:08 am »
Maybe you don't have proper drivers?
or it might be a conflict in Windows, where you need to have (or instead not to have) the manifest.
No, it's not the drivers. I have OpenGL 4.5 support (via proprietary NVIDIA drivers) on my FreeBSD system, and other OpenGL applications and demos run fine.

Having a better understanding of SDL+OpenGL now, after all these discussions, I realised the SDL box tunnel demo was implemented in pure software rendering. Hence it doesn't scale well to higher resolutions. Just goes to show what an amazing job GPU's do! Other complex demos run on my system at 2560x1440 resolution without skipping a beat.
« Last Edit: January 25, 2017, 10:24:05 am by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #17 on: January 25, 2017, 10:13:57 am »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #18 on: January 25, 2017, 10:22:30 am »
I seriously doubt that OpenGL functions called are declared in SDL headers.
Whenever an opengl routine is called, they are executed by the system.
Like I mentioned 2 or 3 replies ago... now that I know a bit more about SDL and OpenGL and how they work together, I can clearly see that the demo I was trying out, is implemented as a pure software renderer. No OpenGL is used at all.

Here is the code if you wanted to see.
  http://pastebin.com/jfjqAas8

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #19 on: January 25, 2017, 10:33:28 am »
Quote
I looked at an SDL sample that renders a 320x200 animation...

Who one does a so small demo window that can be hardware accelerated BTW  :D

That's true. That should have been a dead give away. :)

ps:
  I managed to create a 3D looking first person shooter type game engine, using software raycasting and low fidelity graphics. Internally it is low res, and then scaled 4x to 856x480. Amazingly I get  about 120fps on average. But as soon as I enable higher fidelity graphics and scale 2x or no scaling at all, but still running it at 856x480, then my frame rate drops to about 20fps.  To take this project further, I guess its time I look into hardware acceleration. :)
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

airpas

  • Full Member
  • ***
  • Posts: 179
Re: SDL vs OpenGL
« Reply #20 on: January 28, 2017, 08:56:45 am »
by curiosity i translated the c example to pascal just to see the difference of speed between fpc and gcc , well the difference is so big , gcc is 6x faster than fpc . or maybe my translation needs some tweaking ;)

my translation 
Code: Pascal  [Select][+][-]
  1. program test;
  2. {$ifdef FPC}{$mode objfpc}{$h+}{$endif}
  3. {$ifdef mswindows}{$apptype gui}{$endif}
  4. uses  sdl, math;
  5. type
  6.         p32Array = ^u32Array;
  7.         u32Array = array[0..0] of int32;
  8.  
  9. const
  10.   s_w = 640;
  11.   s_h = 400;
  12.   math_pi = 3.14159265359;
  13.  
  14. var
  15.   event : TSDL_Event;
  16.   done : boolean = false;
  17.   screen : PSDL_Surface;
  18.   texmap : array[0..12287] of int32;
  19.   map : array[0..262143] of smallint;
  20.  
  21. procedure  plot(x,y,c : int32)inline;
  22. begin
  23.   p32Array(screen^.pixels)^[y*s_w+x] := c;
  24. end;
  25.  
  26. function inttostr(v : integer): ansistring;
  27. begin
  28.   str(v,result);
  29. end;
  30.  
  31. procedure makeTextures();
  32. var
  33.    j,m,k,i1,i2,i3,n : int32;
  34. begin
  35.  
  36.     // each texture
  37.     for j:=0 to 15 do begin
  38.  
  39.         k := 255 - random(96);
  40.  
  41.         // each pixel in the texture
  42.         for m:=0  to (16 * 3)-1 do
  43.             for n :=0 to 15 do begin
  44.  
  45.                 i1 := $966C4A;
  46.                 i2 := 0;
  47.                 i3 := 0;
  48.  
  49.                 if (j = 4) then
  50.                     i1 := $7F7F7F;
  51.                 if ((j <> 4) or (random(3) = 0)) then
  52.                     k := 255 - random(96);
  53.                 if ( j = 1 ) then
  54.                 begin
  55.                     if (m < (((n * n * 3 + n * 81) >> 2) and $3) + 18) then
  56.                         i1 := $6AAA40
  57.                     else if (m < (((n * n * 3 + n * 81) >> 2) and $3) + 19) then
  58.                         k := k * 2 div 3;
  59.                 end;
  60.                 if (j = 7) then
  61.                 begin
  62.                     i1 := $675231;
  63.                     if ((n > 0) and (n < 15) and (((m > 0) and (m < 15)) or ((m > 32) and (m < 47)))) then
  64.                     begin
  65.                         i1 := $BC9862;
  66.                         i2 := n - 7;
  67.                         i3 := (m and $F) - 7;
  68.                         if (i2 < 0.0) then
  69.                             i2 := 1 - i2;
  70.  
  71.                         if (i3 < 0.0) then
  72.                             i3 := 1 - i3;
  73.  
  74.                         if (i3 > i2) then
  75.                             i2 := i3;
  76.  
  77.                         k := 196 - random(32) + i2 mod 3 * 32;
  78.                     end
  79.                     else if (random(2) = 0) then
  80.                         k := k * (150 - (n and $1) * 100) div 100;
  81.                 end;
  82.                 if (j = 5) then
  83.                 begin
  84.                     i1 := $B53A15;
  85.                     if (((n + m div 4 * 4) mod 8 = 0) or (m mod 4 = 0)) then
  86.                         i1 := $BCAFA5;
  87.                 end;
  88.                 i2 := k;
  89.                 if (m >= 32) then
  90.                     i2 := i2 div 2;
  91.                 if (j = 8) then
  92.                 begin
  93.                     i1 := 5298487;
  94.                     if (random(2) = 0) then
  95.                     begin
  96.                         i1 := 0;
  97.                         i2 := 255;
  98.                     end;
  99.                 end;
  100.  
  101.                 // fixed point colour multiply between i1 and i2
  102.                 i3 :=
  103.                     ((((i1 >> 16) and $FF) * i2 div 255) << 16) or
  104.                     ((((i1 >>  8) and $FF) * i2 div 255) <<  8) or
  105.                       ((i1        and $FF) * i2 div 255);
  106.                 // pack the colour away
  107.                 texmap[ n + m * 16 + j * 256 * 3 ] := i3;
  108.             end;
  109.     end;
  110. end;
  111.  
  112. procedure makeMap( ) ;
  113. var x,y,z,i : longword;
  114.     yd,zd,th : single;
  115. begin
  116.     // add random blocks to the map
  117.     for x := 0 to 63 do begin
  118.         for y := 0 to 63 do begin
  119.              for z := 0 to 63 do begin
  120.                 i := (z << 12) or (y << 6) or x;
  121.                yd := (y - 32.5) * 0.4;
  122.                zd := (z - 32.5) * 0.4;
  123.                map[i] := random( 16 );
  124.                th := random( 256 ) / 256.0;
  125.  
  126.               if (th > sqrt( sqrt( yd * yd + zd * zd ) ) - 0.8) then
  127.                  map[i] := 0;
  128.               end;
  129.         end;
  130.     end;
  131. end;
  132.  
  133. procedure init( );
  134. begin
  135.     makeTextures( );
  136.     makeMap( );
  137. end;
  138.  
  139. // fixed point byte byte multiply
  140. function fxmul( a,b : int32 ):int32 ; inline;
  141. begin
  142.     result := (a*b)>>8;
  143. end;
  144.  
  145. // fixed point 8bit packed colour multiply
  146. function  rgbmul(a,b : int32 ):int32;
  147. var _r,_g,_b : int32;
  148. begin
  149.     _r := (((a>>16) and $ff) * b) >> 8;
  150.     _g := (((a>> 8) and $ff) * b) >> 8;
  151.     _b := (((a    ) and $ff) * b) >> 8;
  152.     result := (_r<<16) or (_g<<8) or _b;
  153. end;
  154.  
  155.  
  156. procedure render(  );
  157. var
  158.    now,xRot,yRot,yCos,
  159.    ySin,xCos,xSin,___xd,
  160.    __yd,__zd,___zd,_yd,
  161.     _xd,_zd,ddist,closest,
  162.     ox,oy,oz,dimLength,ll,
  163.     xd,yd,zd,initial,dist,
  164.     xp,yp,zp: single;
  165.    x,y ,col,br,d,tex,u,v,cc: longword;
  166. begin
  167.         now := (SDL_GetTicks( ) mod 10000) / 10000;
  168.  
  169.         xRot := sin(now * math_pi * 2) * 0.4 + math_pi / 2;
  170.         yRot := cos(now * math_pi * 2) * 0.4;
  171.         yCos := cos(yRot);
  172.         ySin := sin(yRot);
  173.         xCos := cos(xRot);
  174.         xSin := sin(xRot);
  175.  
  176.         ox := 32.5 + now * 64.0;
  177.         oy := 32.5;
  178.         oz := 32.5;
  179.  
  180.         // for each column
  181.         for x :=0 to s_w -1 do begin
  182.                 // get the x axis delta
  183.                 ___xd := (x - s_w / 2) / s_h;
  184.                 // for each row
  185.                 for y :=0 to s_h-1 do begin
  186.                         // get the y axis delta
  187.                         __yd := (y - s_h / 2) / s_h;
  188.                         __zd := 1;
  189.                         ___zd :=  __zd * yCos +  __yd * ySin;
  190.                         _yd :=  __yd * yCos -  __zd * ySin;
  191.                         _xd := ___xd * xCos + ___zd * xSin;
  192.                         _zd := ___zd * xCos - ___xd * xSin;
  193.  
  194.                         col := 0;
  195.                         br := 255;
  196.                         ddist := 0;
  197.  
  198.                         closest := 32.0;
  199.  
  200.                         // for each principle axis  x,y,z
  201.                         for d :=0 to 2 do begin
  202.                           dimLength := _xd;
  203.                           if (d = 1) then
  204.                             dimLength := _yd;
  205.                           if (d = 2) then
  206.                             dimLength := _zd;
  207.                           if dimLength < 0.0 then
  208.                             dimLength := -dimLength;
  209.                           ll := 1.0 / dimLength;
  210.                           xd := _xd * ll;
  211.                           yd := _yd * ll;
  212.                           zd := _zd * ll;
  213.  
  214.                           initial := ox - floor(ox);
  215.                           if (d = 1) then initial := oy - floor(oy);
  216.                           if (d = 2) then initial := oz - floor(oz);
  217.  
  218.                           if (dimLength > 0.0) then initial := 1 - initial;
  219.  
  220.                           dist := ll * initial;
  221.  
  222.                           xp := ox + xd * initial;
  223.                           yp := oy + yd * initial;
  224.                           zp := oz + zd * initial;
  225.  
  226.                           if (dimLength < 0.0) then begin
  227.                            if (d = 0)then xp-=1;
  228.                            if (d = 1)then yp-=1;
  229.                            if (d = 2)then zp-=1;
  230.                           end;
  231.  
  232.                           // while we are concidering a ray that is still closer then the best so far
  233.                           while (dist < closest) do begin
  234.                           // quantize to the map grid
  235.                             tex := map[ ((trunc(zp) and 63) << 12) or ((trunc(yp) and 63) << 6) or (trunc(xp) and 63) ];
  236.  
  237.                             // if this voxel has a texture applied
  238.                             if (tex > 0) then begin
  239.                             // find the uv coordinates of the intersection point
  240.                               u := (round((xp + zp) * 16)) and 15;
  241.                               v := (round(yp        * 16)  and 15) + 16;
  242.  
  243.                             // fix uvs for alternate directions?
  244.                             if (d = 1) then begin
  245.                               u :=  (round(xp * 16)) and 15;
  246.                               v := ((round(zp * 16)) and 15);
  247.                               if (yd < 0.0) then
  248.                                 v += 32;
  249.                             end;
  250.  
  251.                             //find the colour at the intersection point
  252.                             cc := texmap[ u + v * 16 + tex * 256 * 3 ];
  253.                             // if the colour is not transparent
  254.                             if (cc > 0) then begin
  255.                               col := cc;
  256.                               ddist := 255 - ((dist / 32 * 255));
  257.                               br := 255 * (255 - ((d + 2) mod 3) * 50) div 255;
  258.                               //we now have the closest hit point (also terminates this ray)
  259.                               closest := dist;
  260.                             end;
  261.                           end;
  262.                          // advance the ray
  263.                         xp += xd;
  264.                         yp += yd;
  265.                         zp += zd;
  266.                         dist += ll;
  267.                     end;
  268.                 end;
  269.  
  270.             plot( x, y, rgbmul( col, fxmul( br, round(ddist) ) ) );
  271.         end;
  272.     end;
  273. end;
  274.  
  275. var
  276.     tickf,tickl,fps : longword;
  277.     dif : single;
  278.     count : longword = 0;
  279. begin
  280.     SDL_putenv('SDL_VIDEO_CENTERED=1');
  281.     SDL_Init(SDL_INIT_VIDEO);
  282.  
  283.     screen := SDL_SetVideoMode( s_w, s_h, 32 , SDL_SWSURFACE );
  284.     init();
  285.     tickf := SDL_GetTicks();
  286.     while not done  do
  287.     begin
  288.      dif := (tickl-tickf) / 1000;
  289.      if dif >= 1.0  then begin
  290.           tickf := tickl;
  291.           fps := count;
  292.           count := 0;
  293.           SDL_WM_SetCaption(pchar('fps='+inttostr(fps)),nil);
  294.      end else begin
  295.           inc(count);
  296.          end;
  297.          while  SDL_PollEvent( @event ) > 0  do
  298.             case event.type_  of
  299.             SDL_KEYDOWN:
  300.                 if ( event.key.keysym.sym = SDLK_ESCAPE ) then
  301.                 begin
  302.                   done := true;
  303.                 end;
  304.                 SDL_QUITEV:
  305.                 begin
  306.                   done := true;
  307.                 end;
  308.              end;
  309.            render( );
  310.            SDL_Flip(screen);
  311.            tickl := SDL_GetTicks();
  312.      end;
  313. end.
  314.  
  315.  

c version with fps cout
Code: C  [Select][+][-]
  1. // C++ port of Minecraft 4k JS (http://jsdo.it/notch/dB1E)
  2. // By The8BitPimp
  3. // See: the8bitpimp.wordpress.com
  4.  
  5. #define _SDL_main_h
  6. #include <SDL.h>
  7.  
  8. #include <math.h>
  9.  
  10. const int w = 640;
  11. const int h = 400;
  12.  
  13. SDL_Surface *screen ;
  14.  
  15. const float math_pi = 3.14159265359f;
  16.  
  17. static inline float math_sin( float x ) {
  18.     return sinf( x );
  19. }
  20.  
  21. static inline float math_cos( float x ) {
  22.     return cosf( x );
  23. }
  24.  
  25. // the texture map
  26. int texmap[ 16 * 16 * 16 * 3 ];
  27.  
  28. // the voxel map
  29. char map[ 64 * 64 * 64 ];
  30.  
  31. static inline int random( int max ) {
  32.     return (rand()^(rand()<<16)) % max;
  33. }
  34.  
  35. static inline void plot( int x, int y, int c ) {
  36.     int *p = (int*) screen->pixels;
  37.     p[ y * w + x ] = c;
  38. }
  39.  
  40. static void makeTextures( void ) {
  41.  
  42.     // each texture
  43.     for ( int j=0; j<16; j++ ) {
  44.  
  45.         int k = 255 - random(96);
  46.  
  47.         // each pixel in the texture
  48.         for ( int m=0; m<16 * 3; m++ )
  49.             for ( int n = 0; n<16; n++ ) {
  50.  
  51.                 int i1 = 0x966C4A;
  52.                 int i2 = 0;
  53.                 int i3 = 0;
  54.  
  55.                 if (j == 4)
  56.                     i1 = 0x7F7F7F;
  57.                 if ((j != 4) || (random(3) == 0))
  58.                     k = 255 - random(96);
  59.                 if ( j == 1 )
  60.                 {
  61.                     if (m < (((n * n * 3 + n * 81) >> 2) & 0x3) + 18)
  62.                         i1 = 0x6AAA40;
  63.                     else if (m < (((n * n * 3 + n * 81) >> 2) & 0x3) + 19)
  64.                         k = k * 2 / 3;
  65.                 }
  66.                 if (j == 7)
  67.                 {
  68.                     i1 = 0x675231;
  69.                     if ((n > 0) && (n < 15) && (((m > 0) && (m < 15)) || ((m > 32) && (m < 47))))
  70.                     {
  71.                         i1 = 0xBC9862;
  72.                         i2 = n - 7;
  73.                         i3 = (m & 0xF) - 7;
  74.                         if (i2 < 0)
  75.                             i2 = 1 - i2;
  76.  
  77.                         if (i3 < 0)
  78.                             i3 = 1 - i3;
  79.  
  80.                         if (i3 > i2)
  81.                             i2 = i3;
  82.  
  83.                         k = 196 - random(32) + i2 % 3 * 32;
  84.                     }
  85.                     else if (random(2) == 0)
  86.                         k = k * (150 - (n & 0x1) * 100) / 100;
  87.                 }
  88.                 if (j == 5)
  89.                 {
  90.                     i1 = 0xB53A15;
  91.                     if (((n + m / 4 * 4) % 8 == 0) || (m % 4 == 0))
  92.                         i1 = 0xBCAFA5;
  93.                 }
  94.                 i2 = k;
  95.                 if (m >= 32)
  96.                     i2 /= 2;
  97.                 if (j == 8)
  98.                 {
  99.                     i1 = 5298487;
  100.                     if (random(2) == 0)
  101.                     {
  102.                         i1 = 0;
  103.                         i2 = 255;
  104.                     }
  105.                 }
  106.  
  107.                 // fixed point colour multiply between i1 and i2
  108.                 i3 =
  109.                     ((((i1 >> 16) & 0xFF) * i2 / 255) << 16) |
  110.                     ((((i1 >>  8) & 0xFF) * i2 / 255) <<  8) |
  111.                       ((i1        & 0xFF) * i2 / 255);
  112.                 // pack the colour away
  113.                 texmap[ n + m * 16 + j * 256 * 3 ] = i3;
  114.             }
  115.     }
  116. }
  117.  
  118. static void makeMap( void ) {
  119.     // add random blocks to the map
  120.         for ( int x = 0; x < 64; x++) {
  121.                 for ( int y = 0; y < 64; y++) {
  122.                         for ( int z = 0; z < 64; z++) {
  123.                                 int i = (z << 12) | (y << 6) | x;
  124.                                 float yd = (y - 32.5) * 0.4;
  125.                                 float zd = (z - 32.5) * 0.4;
  126.                                 map[i] = random( 16 );
  127.  
  128.                 float th = random( 256 ) / 256.0f;
  129.  
  130.                                 if (th > sqrtf( sqrtf( yd * yd + zd * zd ) ) - 0.8f)
  131.                                         map[i] = 0;
  132.                         }
  133.                 }
  134.         }
  135. }
  136.  
  137. static void init( void ) {
  138.     makeTextures( );
  139.     makeMap( );
  140. }
  141.  
  142. // fixed point byte byte multiply
  143. static inline int fxmul( int a, int b ) {
  144.     return (a*b)>>8;
  145. }
  146.  
  147. // fixed point 8bit packed colour multiply
  148. static inline int rgbmul( int a, int b ) {
  149.     int _r = (((a>>16) & 0xff) * b) >> 8;
  150.     int _g = (((a>> 8) & 0xff) * b) >> 8;
  151.     int _b = (((a    ) & 0xff) * b) >> 8;
  152.     return (_r<<16) | (_g<<8) | _b;
  153. }
  154.  
  155. static void render( void ) {
  156.  
  157.  
  158.     float now = (float)(SDL_GetTicks( ) % 10000) / 10000.f;
  159.  
  160.         float xRot = math_sin(now * math_pi * 2) * 0.4 + math_pi / 2;
  161.         float yRot = math_cos(now * math_pi * 2) * 0.4;
  162.         float yCos = math_cos(yRot);
  163.         float ySin = math_sin(yRot);
  164.         float xCos = math_cos(xRot);
  165.         float xSin = math_sin(xRot);
  166.  
  167.         float ox = 32.5 + now * 64.0;
  168.         float oy = 32.5;
  169.         float oz = 32.5;
  170.  
  171.         // for each column
  172.         for ( int x = 0; x < w; x++) {
  173.                 // get the x axis delta
  174.                 float ___xd = ((float)x - (float)w / 2.f) / (float)h;
  175.                 // for each row
  176.                 for ( int y = 0; y < h; y++) {
  177.                         // get the y axis delta
  178.                         float  __yd = ((float)y - (float)h / 2.f) / (float)h;
  179.                         float  __zd = 1;
  180.                         float ___zd =  __zd * yCos +  __yd * ySin;
  181.                         float   _yd =  __yd * yCos -  __zd * ySin;
  182.                         float   _xd = ___xd * xCos + ___zd * xSin;
  183.                         float   _zd = ___zd * xCos - ___xd * xSin;
  184.  
  185.                         int col = 0;
  186.                         int br = 255;
  187.                         float ddist = 0;
  188.  
  189.                         float closest = 32.f;
  190.  
  191.                         // for each principle axis  x,y,z
  192.                         for ( int d = 0; d < 3; d++) {
  193.                                 float dimLength = _xd;
  194.                                 if (d == 1)
  195.                                         dimLength = _yd;
  196.                                 if (d == 2)
  197.                                         dimLength = _zd;
  198.  
  199.                                 float ll = 1.0f / (dimLength < 0.f ? -dimLength : dimLength);
  200.                                 float xd = (_xd) * ll;
  201.                                 float yd = (_yd) * ll;
  202.                                 float zd = (_zd) * ll;
  203.  
  204.                                 float       initial = ox - floor(ox);
  205.                                 if (d == 1) initial = oy - floor(oy);
  206.                                 if (d == 2) initial = oz - floor(oz);
  207.  
  208.                                 if (dimLength > 0) initial = 1 - initial;
  209.  
  210.                                 float dist = ll * initial;
  211.  
  212.                                 float xp = ox + xd * initial;
  213.                                 float yp = oy + yd * initial;
  214.                                 float zp = oz + zd * initial;
  215.  
  216.                                 if (dimLength < 0) {
  217.                                         if (d == 0)     xp--;
  218.                                         if (d == 1)     yp--;
  219.                                         if (d == 2)     zp--;
  220.                                 }
  221.  
  222.                                 // while we are concidering a ray that is still closer then the best so far
  223.                                 while (dist < closest) {
  224.  
  225.                                         // quantize to the map grid
  226.                                         int tex = map[ (((int)zp & 63) << 12) | (((int)yp & 63) << 6) | ((int)xp & 63) ];
  227.  
  228.                                         // if this voxel has a texture applied
  229.                                         if (tex > 0) {
  230.  
  231.                                                 // find the uv coordinates of the intersection point
  232.                                                 int u = ((int)((xp + zp) * 16.f)) & 15;
  233.                                                 int v = ((int) (yp       * 16.f)  & 15) + 16;
  234.  
  235.                                                 // fix uvs for alternate directions?
  236.                                                 if (d == 1) {
  237.                                                         u =  ((int)(xp * 16.f)) & 15;
  238.                                                         v = (((int)(zp * 16.f)) & 15);
  239.                                                         if (yd < 0)
  240.                                                                 v += 32;
  241.                                                 }
  242.  
  243.                                                 // find the colour at the intersection point
  244.                                                 int cc = texmap[ u + v * 16 + tex * 256 * 3 ];
  245.  
  246.                                                 // if the colour is not transparent
  247.                                                 if (cc > 0) {
  248.                                                         col = cc;
  249.                                                         ddist = 255 - ((dist / 32 * 255));
  250.                                                         br = 255 * (255 - ((d + 2) % 3) * 50) / 255;
  251.  
  252.                                                         // we now have the closest hit point (also terminates this ray)
  253.                                                         closest = dist;
  254.                                                 }
  255.                                         }
  256.  
  257.                                         // advance the ray
  258.                                         xp += xd;
  259.                                         yp += yd;
  260.                                         zp += zd;
  261.                                         dist += ll;
  262.                                 }
  263.                         }
  264.  
  265.             plot( x, y, rgbmul( col, fxmul( br, ddist ) ) );
  266.         }
  267.     }
  268. }
  269.  
  270. int main( void ) {
  271.     unsigned int tickf =0 ,tickl = 0,fps = 0;
  272.     float dif;
  273.     unsigned int count = 0;
  274.     char buf[32];
  275.  
  276.     SDL_Init( SDL_INIT_VIDEO );
  277.     screen = SDL_SetVideoMode( w, h, 32, 0 );
  278.     if ( screen == NULL )
  279.         return -1;
  280.     init( );
  281.     bool running = true;
  282.     tickf = SDL_GetTicks();
  283.     while ( running ) {
  284.      dif = (tickl-tickf) / 1000;
  285.       if (dif >= 1.0f ){
  286.         tickf = tickl;
  287.         fps = count;
  288.         count = 0;
  289.         sprintf(buf,"fps=%d",fps);
  290.         SDL_WM_SetCaption(buf,NULL);
  291.       } else {
  292.         count++;
  293.       };
  294.         SDL_Event event;
  295.         while ( SDL_PollEvent( &event ) ) {
  296.             running &= (event.type != SDL_QUIT);
  297.         }
  298.         render( );
  299.         SDL_Flip( screen );
  300.         tickl = SDL_GetTicks();
  301.     }
  302.     return 0;
  303. }
  304.  
  305.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: SDL vs OpenGL
« Reply #21 on: January 28, 2017, 09:12:02 am »
- use the cmem memory manager. (faster - in this case -)
- When C uses pointer access, do the same in pascal :$pointermath on
- use sincos, not sin and cos. (that also goes for the idiot that wrote the C code: he's fired as well... >:D >:D )
- pascal is slow with string output other than shortstring. use shortstring or use PChars.

It should be possible to have about parity in speed with this code (the compiler is in THIS case certainly capable of generating similar code to a C compiler) but you rely on too many high level pascal constructs compared to C. Use low level Pascal constructs: they are all there....
So the comparison is not fair at all.
« Last Edit: January 28, 2017, 09:35:54 am by Thaddy »
Specialize a type, not a var.

airpas

  • Full Member
  • ***
  • Posts: 179
Re: SDL vs OpenGL
« Reply #22 on: January 28, 2017, 11:12:54 am »
if you mean high level pascal is the string addition in the line 293 , this code is executed every 1 second , i don't think this would slow down the fps .
the speed is still the same , maybe because fpc is still weak on vectorization  ,gcc is stronger in this area .
the options used is  fpc(-O4 -Cfsse2) gcc(-O3 -msse -mfpmath=sse) , compiler versions fpc trunk , gcc 6.2 

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: SDL vs OpenGL
« Reply #23 on: January 28, 2017, 02:21:00 pm »
by curiosity i translated the c example to pascal just to see the difference of speed between fpc and gcc , well the difference is so big , gcc is 6x faster than fpc . or maybe my translation needs some tweaking ;)
Never benchmark code with "random()" in it. It is known slow (but good quality) in FPC.

Fill a block of memory with random values, and use that block within the loop.

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: SDL vs OpenGL
« Reply #24 on: January 28, 2017, 05:38:25 pm »
Please if you have time try again with the suggestions given. If FPC is still slower well there's always something to improve.

What I like of this is that the comparison is between two working projects (not tested but it seems). Not only testing a specific function or procedure.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: SDL vs OpenGL
« Reply #25 on: January 28, 2017, 06:20:43 pm »
maybe because fpc is still weak on vectorization 

Non existent is a better word. But maybe you can disable vectorization in gcc to get an idea?

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #26 on: January 31, 2017, 01:45:46 am »
by curiosity i translated the c example to pascal just to see the difference of speed between fpc and gcc , well the difference is so big , gcc is 6x faster than fpc . or maybe my translation needs some tweaking ;)
On my Intel i7 I get 10 fps which is pretty sad indeed. :)  Then a few seconds later I get a core dump (due to floating point exception).
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: SDL vs OpenGL
« Reply #27 on: January 31, 2017, 11:02:01 am »
Attached are slightly tweaked versions of the code airpas posted. This gives both a better "tunnel" effect.
Sad thing is, this kills the Pascal+SDL version even more. On my i7 3770K @ 3.5GHz the Pascal version gives avg 8 fps and the C version gives avg 30 fps.

Using the cmem memory manager with the Pascal version, simply gained 2 fps (from 6 fps before to 8 fps afterwards).

As for the comment regarding the usage of Random() and it being slow in Free Pascal. That has no bearing on the fps because Random() is only used while generating the textures and the voxel map. Random() is not used during the gameloop and the raycasting.

The comment regarding string functionality being slow. Again, that has no bearing on the performance, as the only string functionality is generating the window title that contains the FPS count, and that is only executed once per second - unlike the raycasting code that is many times per second.

I also tried FPC 2.6.4 ,3.0.0 and 3.0.1 and they all yielded the same result.

Clearly Free Pascal is a bad choice for game development. We all know (as fact - mentioned many times is the mailing lists over the years) that FPC's goal is code maintainability and portability. Performance has always been a distant 3rd and a "nice to have" if anybody with skills has the time. Maybe Delphi will be a better fit as it is tweaking for performance too, but then you obviously loose portability.

[EDIT]
  On a side note: For those that still think Java is slow.... how wrong you are. The exact
  same tunnel demo in Java runs at 32-36 fps on my system. That's more than double the
  speed of the C+SDL version!!

[EDIT #2]
  Applied the if..else minor optimisation change for the d =1 and d=2 test. The code samples below
  reflect that change.

The Pascal version:
Code: Pascal  [Select][+][-]
  1. {
  2.   Compile with:
  3.       fpc -O3 -Cfsse3 -Xs -ominecraft4k_sdl_fpc Minecraft4k_SDL.pas
  4. }
  5. program test;
  6.   {$mode objfpc}{$h+}
  7.   {$ifdef mswindows}
  8.     {$apptype gui}
  9.   {$endif}
  10. uses
  11.   cmem,
  12.   sdl,
  13.   math;
  14.  
  15.   type
  16.         p32Array = ^u32Array;
  17.         u32Array = array[0..0] of int32;
  18.  
  19. const
  20.   s_w = 640;
  21.   s_h = 400;
  22.   math_pi = 3.14159265359;
  23.  
  24. var
  25.   event : TSDL_Event;
  26.   done : boolean = false;
  27.   screen : PSDL_Surface;
  28.   texmap : array[0..12287] of int32;
  29.   map : array[0..262143] of smallint;
  30.  
  31. procedure  plot(x,y,c : int32)inline;
  32. begin
  33.   p32Array(screen^.pixels)^[y*s_w+x] := c;
  34. end;
  35.  
  36. function inttostr(v : integer): ansistring;
  37. begin
  38.   str(v,result);
  39. end;
  40.  
  41. procedure makeTextures();
  42. var
  43.    j,m,k,i1,i2,i3,n : int32;
  44. begin
  45.  
  46.     // each texture
  47.     for j:=0 to 15 do begin
  48.  
  49.         k := 255 - random(96);
  50.  
  51.         // each pixel in the texture
  52.         for m:=0  to (16 * 3)-1 do
  53.             for n :=0 to 15 do begin
  54.  
  55.                 i1 := $966C4A;
  56.                 i2 := 0;
  57.                 i3 := 0;
  58.  
  59.                 if (j = 4) then
  60.                     i1 := $7F7F7F;
  61.                 if ((j <> 4) or (random(3) = 0)) then
  62.                     k := 255 - random(96);
  63.                 if ( j = 1 ) then
  64.                 begin
  65.                     if (m < (((n * n * 3 + n * 81) >> 2) and $3) + 18) then
  66.                         i1 := $6AAA40
  67.                     else if (m < (((n * n * 3 + n * 81) >> 2) and $3) + 19) then
  68.                         k := k * 2 div 3;
  69.                 end;
  70.                 if (j = 7) then
  71.                 begin
  72.                     i1 := $675231;
  73.                     if ((n > 0) and (n < 15) and (((m > 0) and (m < 15)) or ((m > 32) and (m < 47)))) then
  74.                     begin
  75.                         i1 := $BC9862;
  76.                         i2 := n - 7;
  77.                         i3 := (m and $F) - 7;
  78.                         if (i2 < 0.0) then
  79.                             i2 := 1 - i2;
  80.  
  81.                         if (i3 < 0.0) then
  82.                             i3 := 1 - i3;
  83.  
  84.                         if (i3 > i2) then
  85.                             i2 := i3;
  86.  
  87.                         k := 196 - random(32) + i2 mod 3 * 32;
  88.                     end
  89.                     else if (random(2) = 0) then
  90.                         k := k * (150 - (n and $1) * 100) div 100;
  91.                 end;
  92.                 if (j = 5) then
  93.                 begin
  94.                     i1 := $B53A15;
  95.                     if (((n + m div 4 * 4) mod 8 = 0) or (m mod 4 = 0)) then
  96.                         i1 := $BCAFA5;
  97.                 end;
  98.                 i2 := k;
  99.                 if (m >= 32) then
  100.                     i2 := i2 div 2;
  101.                 if (j = 8) then
  102.                 begin
  103.                     i1 := 5298487;
  104.                     if (random(2) = 0) then
  105.                     begin
  106.                         i1 := 0;
  107.                         i2 := 255;
  108.                     end;
  109.                 end;
  110.  
  111.                 // fixed point colour multiply between i1 and i2
  112.                 i3 :=
  113.                     ((((i1 >> 16) and $FF) * i2 div 255) << 16) or
  114.                     ((((i1 >>  8) and $FF) * i2 div 255) <<  8) or
  115.                       ((i1        and $FF) * i2 div 255);
  116.                 // pack the colour away
  117.                 texmap[ n + m * 16 + j * 256 * 3 ] := i3;
  118.             end;
  119.     end;
  120. end;
  121.  
  122. procedure makeMap( ) ;
  123. var x,y,z,i : longword;
  124.     yd,zd,th : single;
  125. begin
  126.     // add random blocks to the map
  127.     for x := 0 to 63 do begin
  128.         for y := 0 to 63 do begin
  129.              for z := 0 to 63 do begin
  130.                 i := (z << 12) or (y << 6) or x;
  131.                yd := (y - 32.5) * 0.4;
  132.                zd := (z - 32.5) * 0.4;
  133.                map[i] := random( 16 );
  134.                th := random( 256 ) / 256.0;
  135.  
  136.               if (th > sqrt( sqrt( yd * yd + zd * zd ) ) - 0.8) or (th < 0.5) then
  137.                  map[i] := 0;
  138.               end;
  139.         end;
  140.     end;
  141. end;
  142.  
  143. procedure init( );
  144. begin
  145.     makeTextures( );
  146.     makeMap( );
  147. end;
  148.  
  149. // fixed point byte byte multiply
  150. function fxmul( a,b : int32 ):int32 ; inline;
  151. begin
  152.     result := (a*b)>>8;
  153. end;
  154.  
  155. // fixed point 8bit packed colour multiply
  156. function  rgbmul(a,b : int32 ):int32;
  157. var _r,_g,_b : int32;
  158. begin
  159.     _r := (((a>>16) and $ff) * b) >> 8;
  160.     _g := (((a>> 8) and $ff) * b) >> 8;
  161.     _b := (((a    ) and $ff) * b) >> 8;
  162.     result := (_r<<16) or (_g<<8) or _b;
  163. end;
  164.  
  165.  
  166. procedure render(  );
  167. var
  168.    now,xRot,yRot,yCos,
  169.    ySin,xCos,xSin,___xd,
  170.    __yd,__zd,___zd,_yd,
  171.     _xd,_zd,ddist,closest,
  172.     ox,oy,oz,dimLength,ll,
  173.     xd,yd,zd,initial,dist,
  174.     xp,yp,zp: single;
  175.    x,y ,col,br,d,tex,u,v,cc: longword;
  176. begin
  177.         now := (SDL_GetTicks( ) mod 10000) / 10000;
  178.  
  179.         xRot := sin(now * math_pi * 2) * 0.4 + math_pi / 2;
  180.         yRot := cos(now * math_pi * 2) * 0.4;
  181.         yCos := cos(yRot);
  182.         ySin := sin(yRot);
  183.         xCos := cos(xRot);
  184.         xSin := sin(xRot);
  185.  
  186.         ox := 32.5 + now * 64.0;
  187.         oy := 32.5;
  188.         oz := 32.5;
  189.  
  190.         // for each column
  191.         for x :=0 to s_w -1 do begin
  192.                 // get the x axis delta
  193.                 ___xd := (x - s_w / 2) / s_h;
  194.                 // for each row
  195.                 for y :=0 to s_h-1 do begin
  196.                         // get the y axis delta
  197.                         __yd := (y - s_h / 2) / s_h;
  198.                         __zd := 1;
  199.                         ___zd :=  __zd * yCos +  __yd * ySin;
  200.                         _yd :=  __yd * yCos -  __zd * ySin;
  201.                         _xd := ___xd * xCos + ___zd * xSin;
  202.                         _zd := ___zd * xCos - ___xd * xSin;
  203.  
  204.                         col := 0;
  205.                         br := 255;
  206.                         ddist := 0;
  207.  
  208.                         closest := 32.0;
  209.  
  210.                         // for each principle axis  x,y,z
  211.                         for d :=0 to 2 do begin
  212.                           dimLength := _xd;
  213.                           if (d = 1) then
  214.                             dimLength := _yd
  215.                           else if (d = 2) then
  216.                             dimLength := _zd;
  217.                           if dimLength < 0.0 then
  218.                             dimLength := -dimLength;
  219.                           ll := 1.0 / dimLength;
  220.                           xd := _xd * ll;
  221.                           yd := _yd * ll;
  222.                           zd := _zd * ll;
  223.  
  224.                           initial := ox - floor(ox);
  225.                           if (d = 1) then initial := oy - floor(oy);
  226.                           if (d = 2) then initial := oz - floor(oz);
  227.  
  228.                           if (dimLength > 0.0) then initial := 1 - initial;
  229.  
  230.                           dist := ll * initial;
  231.  
  232.                           xp := ox + xd * initial;
  233.                           yp := oy + yd * initial;
  234.                           zp := oz + zd * initial;
  235.  
  236.                           if (dimLength < 0.0) then begin
  237.                            if (d = 0)then xp-=1;
  238.                            if (d = 1)then yp-=1;
  239.                            if (d = 2)then zp-=1;
  240.                           end;
  241.  
  242.                           // while we are concidering a ray that is still closer then the best so far
  243.                           while (dist < closest) do begin
  244.                           // quantize to the map grid
  245.                             tex := map[ ((trunc(zp) and 63) << 12) or ((trunc(yp) and 63) << 6) or (trunc(xp) and 63) ];
  246.  
  247.                             // if this voxel has a texture applied
  248.                             if (tex > 0) then begin
  249.                             // find the uv coordinates of the intersection point
  250.                               u := (round((xp + zp) * 16)) and 15;
  251.                               v := (round(yp        * 16)  and 15) + 16;
  252.  
  253.                             // fix uvs for alternate directions?
  254.                             if (d = 1) then begin
  255.                               u :=  (round(xp * 16)) and 15;
  256.                               v := ((round(zp * 16)) and 15);
  257.                               if (yd < 0.0) then
  258.                                 v += 32;
  259.                             end;
  260.  
  261.                             //find the colour at the intersection point
  262.                             cc := texmap[ u + v * 16 + tex * 256 * 3 ];
  263.                             // if the colour is not transparent
  264.                             if (cc > 0) then begin
  265.                               col := cc;
  266.                               ddist := 255 - ((dist / 32 * 255));
  267.                               br := 255 * (255 - ((d + 2) mod 3) * 50) div 255;
  268.                               //we now have the closest hit point (also terminates this ray)
  269.                               closest := dist;
  270.                             end;
  271.                           end;
  272.                          // advance the ray
  273.                         xp += xd;
  274.                         yp += yd;
  275.                         zp += zd;
  276.                         dist += ll;
  277.                     end;
  278.                 end;
  279.  
  280.             plot( x, y, rgbmul( col, fxmul( br, round(ddist) ) ) );
  281.         end;
  282.     end;
  283. end;
  284.  
  285. var
  286.     tickf,tickl,fps : longword;
  287.     dif : single;
  288.     count : longword = 0;
  289. begin
  290.     SDL_putenv('SDL_VIDEO_CENTERED=1');
  291.     SDL_Init(SDL_INIT_VIDEO);
  292.  
  293.     screen := SDL_SetVideoMode( s_w, s_h, 32 , SDL_SWSURFACE );
  294.     init();
  295.     tickf := SDL_GetTicks();
  296.     while not done  do
  297.     begin
  298.      dif := (tickl-tickf) / 1000;
  299.      if dif >= 1.0  then begin
  300.           tickf := tickl;
  301.           fps := count;
  302.           count := 0;
  303.           SDL_WM_SetCaption(pchar('fps='+inttostr(fps)),nil);
  304.      end else begin
  305.           inc(count);
  306.          end;
  307.          while  SDL_PollEvent( @event ) > 0  do
  308.             case event.type_  of
  309.             SDL_KEYDOWN:
  310.                 if ( event.key.keysym.sym = SDLK_ESCAPE ) then
  311.                 begin
  312.                   done := true;
  313.                 end;
  314.                 SDL_QUITEV:
  315.                 begin
  316.                   done := true;
  317.                 end;
  318.              end;
  319.            render( );
  320.            SDL_Flip(screen);
  321.            tickl := SDL_GetTicks();
  322.      end;
  323. end.
  324.  

And the C version:
Code: C  [Select][+][-]
  1. // C++ port of Minecraft 4k JS (http://jsdo.it/notch/dB1E)
  2. // By The8BitPimp
  3. // See: the8bitpimp.wordpress.com
  4.  
  5. // Compile as follows:
  6. //   $ gcc -I/usr/include -I/usr/local/include/SDL -L/usr/local/lib -L/usr/lib -lm -lSDL -O3 -msse -mfpmath=sse -o minecraft4k_sdl_with_fps Minecraft4k_SDL.cpp
  7.  
  8.  
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include "SDL/SDL.h" // All SDL apps need this
  12.  
  13. const int w = 640;
  14. const int h = 400;
  15.  
  16. SDL_Surface *screen = NULL;
  17.  
  18. const float math_pi = 3.14159265359f;
  19.  
  20. static inline float math_sin( float x ) {
  21.   return sinf( x );
  22. }
  23.  
  24. static inline float math_cos( float x ) {
  25.   return cosf( x );
  26. }
  27.  
  28. // the texture map
  29. int texmap[ 16 * 16 * 16 * 3 ];
  30.  
  31. // the voxel map
  32. char map[ 64 * 64 * 64 ];
  33.  
  34. static inline int random( int max ) {
  35.   return (rand()^(rand()<<16)) % max;
  36. }
  37.  
  38. static inline void plot( int x, int y, int c ) {
  39.   int *p = (int*) screen->pixels;
  40.   p[ y * w + x ] = c;
  41. }
  42.  
  43. static void makeTextures( void ) {
  44.  
  45.   // each texture
  46.   for ( int j=0; j<16; j++ ) {
  47.  
  48.         int k = 255 - random(96);
  49.  
  50.         // each pixel in the texture
  51.         for ( int m=0; m<16 * 3; m++ )
  52.             for ( int n = 0; n<16; n++ ) {
  53.  
  54.                   int i1 = 0x966C4A;
  55.                   int i2 = 0;
  56.                   int i3 = 0;
  57.  
  58.                   if (j == 4)
  59.                         i1 = 0x7F7F7F;
  60.                   if ((j != 4) || (random(3) == 0))
  61.                         k = 255 - random(96);
  62.                   if ( j == 1 )
  63.                   {
  64.                         if (m < (((n * n * 3 + n * 81) >> 2) & 0x3) + 18)
  65.                             i1 = 0x6AAA40;
  66.                         else if (m < (((n * n * 3 + n * 81) >> 2) & 0x3) + 19)
  67.                             k = k * 2 / 3;
  68.                   }
  69.                   if (j == 7)
  70.                   {
  71.                         i1 = 0x675231;
  72.                         if ((n > 0) && (n < 15) && (((m > 0) && (m < 15)) || ((m > 32) && (m < 47))))
  73.                         {
  74.                             i1 = 0xBC9862;
  75.                             i2 = n - 7;
  76.                             i3 = (m & 0xF) - 7;
  77.                             if (i2 < 0)
  78.                                   i2 = 1 - i2;
  79.  
  80.                             if (i3 < 0)
  81.                                   i3 = 1 - i3;
  82.  
  83.                             if (i3 > i2)
  84.                                   i2 = i3;
  85.  
  86.                             k = 196 - random(32) + i2 % 3 * 32;
  87.                         }
  88.                         else if (random(2) == 0)
  89.                             k = k * (150 - (n & 0x1) * 100) / 100;
  90.                   }
  91.                   if (j == 5)
  92.                   {
  93.                         i1 = 0xB53A15;
  94.                         if (((n + m / 4 * 4) % 8 == 0) || (m % 4 == 0))
  95.                             i1 = 0xBCAFA5;
  96.                   }
  97.                   i2 = k;
  98.                   if (m >= 32)
  99.                         i2 /= 2;
  100.                   if (j == 8)
  101.                   {
  102.                         i1 = 5298487;
  103.                         if (random(2) == 0)
  104.                         {
  105.                             i1 = 0;
  106.                             i2 = 255;
  107.                         }
  108.                   }
  109.  
  110.                   // fixed point colour multiply between i1 and i2
  111.                   i3 =
  112.                         ((((i1 >> 16) & 0xFF) * i2 / 255) << 16) |
  113.                         ((((i1 >>  8) & 0xFF) * i2 / 255) <<  8) |
  114.                           ((i1        & 0xFF) * i2 / 255);
  115.                   // pack the colour away
  116.                   texmap[ n + m * 16 + j * 256 * 3 ] = i3;
  117.             }
  118.   }
  119. }
  120.  
  121. static void makeMap( void ) {
  122.   // add random blocks to the map
  123.         for ( int x = 0; x < 64; x++) {
  124.                   for ( int y = 0; y < 64; y++) {
  125.                             for ( int z = 0; z < 64; z++) {
  126.                                         int i = (z << 12) | (y << 6) | x;
  127.                                 float yd = (y - 32.5) * 0.4f;
  128.                                 float zd = (z - 32.5) * 0.4f;
  129.                                         map[i] = random( 16 );
  130.  
  131.                   float th = random( 256 ) / 256.0f;
  132.  
  133.                                 if (th > sqrtf( sqrtf( yd * yd + zd * zd ) ) - 0.8f || th < 0.5f)
  134.                                                   map[i] = 0;
  135.                             }
  136.                   }
  137.         }
  138. }
  139.  
  140. static void init( void ) {
  141.   makeTextures( );
  142.   makeMap( );
  143. }
  144.  
  145. // fixed point byte byte multiply
  146. static inline int fxmul( int a, int b ) {
  147.   return (a*b)>>8;
  148. }
  149.  
  150. // fixed point 8bit packed colour multiply
  151. static inline int rgbmul( int a, int b ) {
  152.   int _r = (((a>>16) & 0xff) * b) >> 8;
  153.   int _g = (((a>> 8) & 0xff) * b) >> 8;
  154.   int _b = (((a    ) & 0xff) * b) >> 8;
  155.   return (_r<<16) | (_g<<8) | _b;
  156. }
  157.  
  158. static void render( void ) {
  159.  
  160.  
  161.   float now = (float)(SDL_GetTicks( ) % 10000) / 10000.f;
  162.   //printf("now = %f", now);
  163.  
  164.         float xRot = math_sin(now * math_pi * 2) * 0.4 + math_pi / 2;
  165.         float yRot = math_cos(now * math_pi * 2) * 0.4;
  166.         float yCos = math_cos(yRot);
  167.         float ySin = math_sin(yRot);
  168.         float xCos = math_cos(xRot);
  169.         float xSin = math_sin(xRot);
  170.  
  171.         float ox = 32.5 + now * 64.0;
  172.         float oy = 32.5;
  173.         float oz = 32.5;
  174.  
  175.         // for each column
  176.         for ( int x = 0; x < w; x++) {
  177.                   // get the x axis delta
  178.                   float ___xd = ((float)x - (float)w / 2.f) / (float)h;
  179.                   // for each row
  180.                   for ( int y = 0; y < h; y++) {
  181.                             // get the y axis delta
  182.                             float  __yd = ((float)y - (float)h / 2.f) / (float)h;
  183.                             float  __zd = 1;
  184.                             float ___zd =  __zd * yCos +  __yd * ySin;
  185.                             float   _yd =  __yd * yCos -  __zd * ySin;
  186.                             float   _xd = ___xd * xCos + ___zd * xSin;
  187.                             float   _zd = ___zd * xCos - ___xd * xSin;
  188.  
  189.                             int col = 0;
  190.                             int br = 255;
  191.                             float ddist = 0;
  192.  
  193.                             float closest = 32.f;
  194.  
  195.                             // for each principle axis  x,y,z
  196.                             for ( int d = 0; d < 3; d++) {
  197.                                         float dimLength = _xd;
  198.                                         if (d == 1) {
  199.                                                   dimLength = _yd;
  200.                                         }
  201.                                         else if (d == 2) {
  202.                                                   dimLength = _zd;
  203.                                         }
  204.  
  205.                                         float ll = 1.0f / (dimLength < 0.f ? -dimLength : dimLength);
  206.                                         float xd = (_xd) * ll;
  207.                                         float yd = (_yd) * ll;
  208.                                         float zd = (_zd) * ll;
  209.  
  210.                                         float       initial = ox - floor(ox);
  211.                                         if (d == 1) {
  212.                                                 initial = oy - floor(oy);
  213.                                         } else if (d == 2) {
  214.                                                 initial = oz - floor(oz);
  215.                                         }
  216.  
  217.                                         if (dimLength > 0) initial = 1 - initial;
  218.  
  219.                                         float dist = ll * initial;
  220.  
  221.                                         float xp = ox + xd * initial;
  222.                                         float yp = oy + yd * initial;
  223.                                         float zp = oz + zd * initial;
  224.  
  225.                                         if (dimLength < 0) {
  226.                                                 if (d == 0) {
  227.                                                         xp--;
  228.                                                 }
  229.                                                 else if (d == 1) {
  230.                                                         yp--;
  231.                                                 }
  232.                                                 else if (d == 2) {
  233.                                                         zp--;
  234.                                                 }
  235.                                         }
  236.  
  237.                                         // while we are considering a ray that is still closer then the best so far
  238.                                         while (dist < closest) {
  239.  
  240.                                                   // quantize to the map grid
  241.                                                   int tex = map[ (((int)zp & 63) << 12) | (((int)yp & 63) << 6) | ((int)xp & 63) ];
  242.  
  243.                                                   // if this voxel has a texture applied
  244.                                                   if (tex > 0) {
  245.  
  246.                                                             // find the uv coordinates of the intersection point
  247.                                                             int u = ((int)((xp + zp) * 16.f)) & 15;
  248.                                                             int v = ((int) (yp       * 16.f)  & 15) + 16;
  249.  
  250.                                                             // fix uvs for alternate directions?
  251.                                                             if (d == 1) {
  252.                                                                         u =  ((int)(xp * 16.f)) & 15;
  253.                                                                         v = (((int)(zp * 16.f)) & 15);
  254.                                                                         if (yd < 0)
  255.                                                                                   v += 32;
  256.                                                             }
  257.  
  258.                                                             // find the colour at the intersection point
  259.                                                             int cc = texmap[ u + v * 16 + tex * 256 * 3 ];
  260.  
  261.                                                             // if the colour is not transparent
  262.                                                             if (cc > 0) {
  263.                                                                         col = cc;
  264.                                                                         ddist = 255 - ((dist / 32 * 255));
  265.                                                                         br = 255 * (255 - ((d + 2) % 3) * 50) / 255;
  266.  
  267.                                                                         // we now have the closest hit point (also terminates this ray)
  268.                                                                         closest = dist;
  269.                                                             }
  270.                                                   }
  271.  
  272.                                                   // advance the ray
  273.                                                   xp += xd;
  274.                                                   yp += yd;
  275.                                                   zp += zd;
  276.                                                   dist += ll;
  277.                                         }
  278.                             }
  279.  
  280.             plot( x, y, rgbmul( col, fxmul( br, ddist ) ) );
  281.         }
  282.   }
  283. }
  284.  
  285. int main( void ) {
  286.   unsigned int tickf =0 ,tickl = 0,fps = 0;
  287.   float dif;
  288.   unsigned int count = 0;
  289.   char buf[32];
  290.  
  291.   SDL_Init( SDL_INIT_VIDEO );
  292.   screen = SDL_SetVideoMode( w, h, 32, 0 );
  293.   if ( screen == NULL )
  294.         return -1;
  295.   init( );
  296.   bool running = true;
  297.   tickf = SDL_GetTicks();
  298.   while ( running ) {
  299.    dif = (tickl-tickf) / 1000;
  300.     if (dif >= 1.0f ){
  301.         tickf = tickl;
  302.         fps = count;
  303.         count = 0;
  304.         sprintf(buf,"fps=%d",fps);
  305.         SDL_WM_SetCaption(buf,NULL);
  306.     } else {
  307.         count++;
  308.     };
  309.         SDL_Event event;
  310.         while ( SDL_PollEvent( &event ) ) {
  311.             running &= (event.type != SDL_QUIT);
  312.         }
  313.         render( );
  314.         SDL_Flip( screen );
  315.         tickl = SDL_GetTicks();
  316.   }
  317.     // Shutdown all subsystems
  318.     SDL_Quit();    
  319.   return 0;
  320. }
  321.  
  322.  
« Last Edit: January 31, 2017, 12:55:55 pm by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Re: SDL vs OpenGL
« Reply #28 on: January 31, 2017, 11:35:00 am »
The code has simply been translated from C, and is typical C style. C compilers are probably better to optimize poorly written code, so the programmer does not need to worry a lot. But when looking at the inner loop "for d := 0 to 2...", there are a few obvious things that could be done better, for instance the repeated comparison "if d = 1 then", "if d =2 then" which does not even use the most obvious manual optimization, using an else statement (which gives me a 30% performance gain straightaway). I guess that disentangling the C-style loop further could improve performance significantly.
Another bad thing is the use of floor(); the math unit is per default compiled for extended precision, so each call will involve two conversions from single to extended and back.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: SDL vs OpenGL
« Reply #29 on: January 31, 2017, 11:42:50 am »
Attached are slightly tweaked versions of the code airpas posted. This gives both a better "tunnel" effect.

Sad thing is, this kills the Pascal+SDL version even more. On my i7 3770K @ 3.5GHz the Pascal version gives avg 8 fps and the C version gives avg 30 fps.

Read my earlier post, first remove random from all tight loops, it is known slow on FPC, but that is not related to the current subject.

 

TinyPortal © 2005-2018