Recent

Author Topic: Raytracing: FPC vs Java  (Read 14318 times)

argb32

  • Jr. Member
  • **
  • Posts: 89
    • Pascal IDE based on IntelliJ platform
Raytracing: FPC vs Java
« on: February 04, 2017, 05:30:34 pm »
I took raytracing demo from this topic and tried to make a compiler comparison.
Initial results on my PC (64bit Linux target): FPC 11 fps, Java 24 fps. Seems too bad for FPC.
First of all I modified the demos and now they output identical picture.
Java version:
Code: Java  [Select][+][-]
  1. import java.applet.Applet;
  2. import java.awt.Frame;
  3. import java.awt.image.BufferedImage;
  4. import java.awt.image.DataBufferInt;
  5.  
  6. public class Minecraft4k extends Applet implements Runnable {
  7.  
  8.     private static final long serialVersionUID = 1L;
  9.     private static final String version = "0.0.1";
  10.  
  11.     private static final int WIDTH = 640;
  12.     private static final int HEIGHT = 400;
  13.     private static final int SCALE = 1;
  14.  
  15.     // the block world map is stored in a cube of sides 64 in length;
  16.     // each map entry determines the colour of the corresponding block
  17.     private static final int MAPDIM = 64; // map dimensions
  18.     private static final int MAPCUBE = MAPDIM * MAPDIM * MAPDIM; // value 262144
  19.     private static final long TIME_SCALE = 100000;
  20.     private int[] map = new int[MAPCUBE];
  21.  
  22.     public static void main(String[] args) {
  23.         Frame f = new Frame("Minecraft4k Java Demo " + version);
  24.         f.addWindowListener(new java.awt.event.WindowAdapter() {
  25.             @Override
  26.             public void windowClosing(java.awt.event.WindowEvent e) {
  27.                 System.exit(0);
  28.             };
  29.         });
  30.  
  31.         Minecraft4k mc = new Minecraft4k();
  32.         mc.setSize(WIDTH * SCALE + 8, HEIGHT * SCALE + 24);
  33.         f.add(mc);
  34.         f.pack();
  35.         mc.start();
  36.         f.setSize(WIDTH * SCALE + 8, HEIGHT * SCALE + 24);
  37.         f.setVisible(true);
  38.     }
  39.  
  40.     @Override
  41.     public void start() {
  42.         new Thread(this).start(); // triggers the run() method
  43.     }
  44.  
  45.         /*
  46.          * The following textures are generated
  47.          * 0 Air
  48.          * 1 Grass + Dirt
  49.          * 2 Dirt
  50.          * 3 Dirt
  51.          * 4 Stone (gray)
  52.          * 5 Brick
  53.          * 6 Dirt
  54.          * 7 Wood
  55.          * 8 Tree leaves
  56.          * 9 Water
  57.          * 10 .. 13 Dirt
  58.          * 14 Stone with moss
  59.          * 15 Red Brick with moss
  60.          */
  61.     private int[] generate_textures() {
  62.         // Algorithmically generate textures...
  63.         int[] texmap = new int[12288]; // 16 * 16 * 16 * 3 = 12288
  64.         int j = 1;
  65.  
  66.         while (j < 16) {
  67.             int lBrightness = 255 - nextInt(96);
  68.             int y = 0;
  69.             while (y < (16 * 3)) { // 3 texture images (top, side and bottom),
  70.                 // stored one below the other
  71.                 int x = 0;
  72.                 while (x < 16) {
  73.                     int lBrightness2;
  74.                     int lColor;
  75.                     int color = 0x966C4A; // ground
  76.                     if (j == 4) {
  77.                         color = 0x7F7F7F; // stone
  78.                     }
  79.                     if (j != 4 || nextInt(3) == 0) {
  80.                         lBrightness = 255 - nextInt(96);
  81.                     }
  82.                     if (j == 1 && y < (x * x * 3 + x * 81 >> 2 & 3) + 18) {
  83.                         color = 0x6AAA40; // grass
  84.                     } else if (j == 1 && y < (x * x * 3 + x * 81 >> 2 & 3) + 19) {
  85.                         lBrightness = lBrightness * 2 / 3;
  86.                     }
  87.                     if (j == 7) {
  88.                         color = 0x675231; // wood
  89.                         if (x > 0 && x < 15 && (y > 0 && y < 15 || y > 32 && y < 47)) {
  90.                             color = 0xBC9862; // wood
  91.                             // This is WRONG - see the JavaScript version for
  92.                             // details
  93.                             lBrightness2 = x - 7;
  94.                             lColor = (y & 15) - 7;
  95.                             if (lBrightness2 < 0) {
  96.                                 lBrightness2 = 1 - lBrightness2;
  97.                             }
  98.                             if (lColor < 0) {
  99.                                 lColor = 1 - lColor;
  100.                             }
  101.                             if (lColor > lBrightness2) {
  102.                                 lBrightness2 = lColor;
  103.                             }
  104.                             lBrightness = 196 - nextInt(32) + lBrightness2 % 3 * 32;
  105.                         } else if (nextInt(2) == 0) {
  106.                             lBrightness = lBrightness * (150 - (x & 1) * 100) / 100;
  107.                         }
  108.                     }
  109.                     if (j == 5) {
  110.                         color = 0xB53A15; // brick
  111.                         if ((x + y / 4 * 4) % 8 == 0 || y % 4 == 0) {
  112.                             color = 0xBCAFA5;
  113.                         }
  114.                     }
  115.                     if (j == 9) {
  116.                         color = 0x4040ff; // water
  117.                     }
  118.                     if (j == 14) {
  119.                         color = 0x7F7F7F; // stone with moss
  120.                         if (nextInt(3) == 0) {
  121.                             color = 0x6AAA40;
  122.                         } else if ((x + y / 4 * 4) % 8 == 0 || y % 4 == 0) {
  123.                             color = 0x6AAA60;
  124.                         }
  125.                     }
  126.                     if (j == 15) {
  127.                         color = 0xB53A15; // red bricks with moss
  128.                         if (nextInt(3) == 0) {
  129.                             color = 0x6AAA40;
  130.                         } else if ((x + y / 4 * 4) % 8 == 0 || y % 4 == 0) {
  131.                             color = 0x6AAA60;
  132.                         }
  133.                     }
  134.  
  135.                     lBrightness2 = lBrightness;
  136.                     if (y >= 32) {
  137.                         lBrightness2 /= 2;
  138.                     }
  139.                     if (j == 8) {
  140.                         color = 0x50D937; // leaves
  141.                         if (nextInt(2) == 0) {
  142.                             color = 0;
  143.                             lBrightness2 = 255;
  144.                         }
  145.                     }
  146.                     lColor = (color >> 16 & 0xFF) * lBrightness2 / 0xFF << 16 //
  147.                             | (color >> 8 & 0xFF) * lBrightness2 / 0xFF << 8 //
  148.                             | (color & 0xFF) * lBrightness2 / 0xFF;
  149.                     texmap[x + y * 16 + j * 256 * 3] = lColor;
  150.                     ++x;
  151.                 }
  152.                 ++y;
  153.             }
  154.             ++j;
  155.  
  156.         }
  157.  
  158.         return texmap;
  159.     }
  160.  
  161.     private int curr = 1254543;
  162.     private int rndCnt = 0;
  163.     private int nextInt(int bound) {
  164.         rndCnt++;
  165.         curr = (curr * bound + 476611) % 455345;
  166.         return curr % bound;
  167.     }
  168.  
  169.     private void generateMap() {
  170.         for (int x = 0; x < MAPDIM; x++) {
  171.             for (int y = 0; y < MAPDIM; y++) {
  172.                 for (int z = 0; z < MAPDIM; z++) {
  173.                     int i = (z << 12) | (y << 6) | x;
  174.                     float yd = (y - 32.5f) * 0.4f;
  175.                     float zd = (z - 32.5f) * 0.4f;
  176.                     map[i] = nextInt(16);
  177.                     float th = nextInt(256) / 256.0f;
  178.                     if ((th > (Math.sqrt(Math.sqrt(yd * yd + zd * zd)) - 0.8f)) || (th < 0.5f)) {
  179.                         map[i] = 0;
  180.                     }
  181.                 }
  182.             }
  183.         }
  184.     }
  185.  
  186.     @Override
  187.     public void run() {
  188.         try {
  189.             long startTime = System.currentTimeMillis();
  190.             long lastTime = startTime;
  191.             int frames = 0;
  192.  
  193.             BufferedImage localBufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
  194.             int[] imgBufferData = ((DataBufferInt) localBufferedImage.getRaster().getDataBuffer()).getData();
  195.  
  196.             int[] texmap = generate_textures();
  197.             System.out.println("Rnd cnt1: " + rndCnt);
  198.             generateMap();
  199.             System.out.println("Rnd cnt1: " + rndCnt);
  200.  
  201.             do {
  202.                 float now = (System.currentTimeMillis() - startTime) % TIME_SCALE / (float)TIME_SCALE;
  203.  
  204.                 float ox = 32.5f + now * 64;
  205.                 final float oy = 32.5f;
  206.                 final float oz = 32.5f;
  207.  
  208.                 float xRot = (float) ((float) Math.sin(now * Math.PI * 2f) * 0.4f + Math.PI / 2f);
  209.                 float yRot = (float) Math.cos(now * Math.PI * 2f) * 0.4f;
  210.  
  211.                 float xSin = (float) Math.sin(xRot);
  212.                 float xCos = (float) Math.cos(xRot);
  213.                 float ySin = (float) Math.sin(yRot);
  214.                 float yCos = (float) Math.cos(yRot);
  215.  
  216.                 int x = 0;
  217.                 // raycaster: for each column
  218.                 while (x < WIDTH) {
  219.                     float ___xd = (x - WIDTH / 2) / (float) HEIGHT;
  220.                     int y = 0;
  221.                     while (y < HEIGHT) {
  222.                         float __yd = (y - HEIGHT / 2) / (float) HEIGHT;
  223.                         float __zd = 1.0f;
  224.                         float ___zd = __zd * yCos + __yd * ySin;
  225.                         float _yd = __yd * yCos - __zd * ySin;
  226.                         float _xd = ___xd * xCos + ___zd * xSin;
  227.                         float _zd = ___zd * xCos - ___xd * xSin;
  228.  
  229.                         int col = 0; // black sky colour
  230.                         int br = 255; // brightness
  231.                         float closest = 32.0f; // how far can we see
  232.  
  233.                         int d = 0;
  234.                         while (d < 3) {
  235.                             float dimLength = _xd;
  236.                             if (d == 1) {
  237.                                 dimLength = _yd;
  238.                             } else if (d == 2) {
  239.                                 dimLength = _zd;
  240.                             }
  241.                             float ll = 1.0f / Math.abs(dimLength);
  242.                             float xd = _xd * ll;
  243.                             float yd = _yd * ll;
  244.                             float zd = _zd * ll;
  245.                             float initial = ox - ((int) ox);
  246.                             if (d == 1) {
  247.                                 initial = oy - ((int) oy);
  248.                             } else if (d == 2) {
  249.                                 initial = oz - ((int) oz);
  250.                             }
  251.                             if (dimLength >= 0.0f) {
  252.                                 initial = 1.0f - initial;
  253.                             }
  254.  
  255.                             float dist = ll * initial;
  256.                             float xp = ox + xd * initial;
  257.                             float yp = oy + yd * initial;
  258.                             float zp = oz + zd * initial;
  259.  
  260.                             if (dimLength < 0.0f) {
  261.                                 if (d == 0) {
  262.                                     xp--;
  263.                                 } else if (d == 1) {
  264.                                     yp--;
  265.                                 } else if (d == 2) {
  266.                                     zp--;
  267.                                 }
  268.  
  269.                             }
  270.  
  271.                             // while we are considering a ray that is still closer then the best so far
  272.                             while (dist < closest) {
  273.  
  274.                                 // quantize to the map grid
  275.                                 int mapOffset = (((int) zp & 63) << 12) | (((int) yp & 63) << 6) | ((int) xp & 63);
  276.                                 int tex = map[mapOffset];
  277.  
  278.                                 // if this voxel has a texture applied
  279.                                 if (tex > 0) {
  280.  
  281.                                     // find the uv coordinates of the intersection point
  282.                                     int u;
  283.                                     int v;
  284.  
  285.                                     // fix uv's for alternate directions?
  286.                                     if (d == 1) {
  287.                                         u = (int) (xp * 16.0f) & 15;
  288.                                         v = (int) (zp * 16.0f) & 15;
  289.                                         if (yd < 0.0f) {
  290.                                             v += 32;
  291.                                         }
  292.                                     } else {
  293.                                         u = (int) ((xp + zp) * 16.0f) & 15;
  294.                                         v = ((int) (yp * 16.0f) & 15) + 16;
  295.                                     }
  296.  
  297.                                     // find the colour at the intersection point
  298.                                     int cc = texmap[u + v * 16 + tex * 256 * 3];
  299.  
  300.                                     // if the colour is not transparent
  301.                                     if (cc > 0) {
  302.                                         col = cc;
  303.                                         br = 255 - (int) (dist * (255.0f / 32.0f));
  304.                                         br = br * (255 - (d + 2) % 3 * 50) / 255;
  305.                                         // we now have the closest hit point (also terminates this ray)
  306.                                         closest = dist;
  307.                                     }
  308.                                 }
  309.                                 // advance the ray
  310.                                 xp += xd;
  311.                                 yp += yd;
  312.                                 zp += zd;
  313.                                 dist += ll;
  314.                             }
  315.                             ++d;
  316.                         }
  317.                         int r = (col >> 16 & 0xFF) * br / 0xFF;
  318.                         int g = (col >> 8 & 0xFF) * br / 0xFF;
  319.                         int b = (col & 0xFF) * br / 0xFF;
  320.                         imgBufferData[x + y * WIDTH] = r << 16 | g << 8 | b;
  321.                         ++y;
  322.                     }
  323.                     ++x;
  324.                 }
  325.  
  326.                 frames++;
  327.  
  328.                 this.getGraphics().drawImage(localBufferedImage, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
  329.  
  330.                 // FPS counter printed every 1 second.
  331.                 if (System.currentTimeMillis() - lastTime > 1000) {
  332.                     System.out.println(frames + " fps");
  333.                     lastTime = System.currentTimeMillis();
  334.                     frames = 0;
  335.                 }
  336.  
  337.             } while (true);
  338.         } catch (Exception e) {
  339.             e.printStackTrace();
  340.             return;
  341.         }
  342.     }
  343.  
  344. }
  345.  
As Java's (int) typecast equivalent in Pascal is Trunc(), not Round() or Floor(). The latter is slow btw.
After replacing with Trunc() fps become 18.
More 3 fps gave unrolling 3-rd loop.

It's weird that optimization settings (via {$OPTIMIZATION}) seems to have no effect.
As well as changing
Code: Pascal  [Select][+][-]
  1. type map : array[0..MAPDIM * MAPDIM * MAPDIM] of Integer;
  2.  
to
Code: Pascal  [Select][+][-]
  1. map : array[0..MAPDIM-1, 0..MAPDIM-1, 0..MAPDIM-1] of Integer;
  2.  
So final results: FPC 21 fps, Java 24 fps.
That's much better. ;)

argb32

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

argb32

  • Jr. Member
  • **
  • Posts: 89
    • Pascal IDE based on IntelliJ platform
Re: Raytracing: FPC vs Java
« Reply #2 on: February 04, 2017, 05:32:38 pm »
Version with unrolled loop:
Code: Pascal  [Select][+][-]
  1. program mc4k;
  2.         {$mode objfpc}{$h+}
  3.         {$ifdef mswindows}
  4.         {$apptype gui}
  5.         {$endif}
  6.         {$RANGECHECKS OFF}
  7. {$FPUTYPE SSE3}
  8. {$INLINE ON}
  9. {$A 32}
  10. {$OPTIMIZATION LOOPUNROLL,LEVEL3,UNCERTAIN,PEEPHOLE,ASMCSE,ORDERFIELDS,FASTMATH,CSE,DFA}
  11. uses
  12.     cmem,
  13.     sdl,
  14.     math;
  15.  
  16. type
  17.     p32Array = ^u32Array;
  18.     u32Array = array[0..$FFFFFF] of int32;
  19.  
  20. const
  21.     WIDTH = 640;
  22.     HEIGHT = 400;
  23.     math_pi = 3.141592;
  24.     MAPDIM = 64;
  25.     TIME_SCALE = 100000;
  26.  
  27. var
  28.     event : TSDL_Event;
  29.     done : boolean = false;
  30.     screen : PSDL_Surface;
  31.     texmap : array[0..12287] of Integer;
  32.     map : array[0..MAPDIM * MAPDIM * MAPDIM-1] of Integer;
  33.     tickStart: LongWord;
  34.  
  35. function inttostr(v : integer): ansistring;
  36. begin
  37.     str(v,result);
  38. end;
  39.  
  40. var curr: Integer = 1254543;
  41. var rndCnt: Integer = 0;
  42. function nextInt(bound: Integer): Integer;
  43. begin
  44.     rndCnt := rndCnt + 1;
  45.     curr := (curr * bound + 476611) mod 455345;
  46.     Result := curr mod bound;
  47. end;
  48.  
  49. procedure makeTextures();
  50. var
  51.     j, y, lBrightness, color, lBrightness2, lColor, x : int32;
  52. begin
  53.     // each texture
  54.     for j:=1 to 15 do begin
  55.  
  56.         lBrightness := 255 - nextInt(96);
  57.  
  58.         // each pixel in the texture
  59.         for y:=0  to (16 * 3)-1 do
  60.             for x :=0 to 15 do begin
  61.  
  62.                 color := $966C4A;
  63.                 lBrightness2 := 0;
  64.                 lColor := 0;
  65.  
  66.                 if (j = 4) then
  67.                     color := $7F7F7F;
  68.                 if ((j <> 4) or (nextInt(3) = 0)) then
  69.                     lBrightness := 255 - nextInt(96);
  70.                 if (j = 1) and (y < (((x * x * 3 + x * 81) >> 2) and $3) + 18) then
  71.                     color := $6AAA40
  72.                 else if (j = 1) and (y < (((x * x * 3 + x * 81) >> 2) and $3) + 19) then
  73.                     lBrightness := lBrightness * 2 div 3;
  74.                 if (j = 7) then
  75.                 begin
  76.                     color := $675231;
  77.                     if ((x > 0) and (x < 15) and (((y > 0) and (y < 15)) or ((y > 32) and (y < 47)))) then
  78.                     begin
  79.                         color := $BC9862;
  80.                         lBrightness2 := x - 7;
  81.                         lColor := (y and $F) - 7;
  82.                         if (lBrightness2 < 0) then
  83.                             lBrightness2 := 1 - lBrightness2;
  84.  
  85.                         if (lColor < 0.0) then
  86.                             lColor := 1 - lColor;
  87.  
  88.                         if (lColor > lBrightness2) then
  89.                             lBrightness2 := lColor;
  90.  
  91.                         lBrightness := 196 - nextInt(32) + lBrightness2 mod 3 * 32;
  92.                     end
  93.                     else if (nextInt(2) = 0) then
  94.                         lBrightness := lBrightness * (150 - (x and $1) * 100) div 100;
  95.                 end;
  96.                 if (j = 5) then
  97.                 begin
  98.                     color := $B53A15;
  99.                     if (((x + y div 4 * 4) mod 8 = 0) or (y mod 4 = 0)) then
  100.                         color := $BCAFA5;
  101.                 end;
  102.                 if (j = 9) then
  103.                     color := $4040ff; // water
  104.                 if (j = 14) then begin
  105.                     color := $7F7F7F; // stone with moss
  106.                     if nextInt(3) = 0 then
  107.                         color := $6AAA40
  108.                     else if ((x + y div 4 * 4) mod 8 = 0) or (y mod 4 = 0) then
  109.                         color := $6AAA60;
  110.                 end;
  111.                 if (j = 15) then begin
  112.                     color := $B53A15; // red bricks with moss
  113.                     if nextInt(3) = 0 then
  114.                         color := $6AAA40
  115.                     else if ((x + y div 4 * 4) mod 8 = 0) or (y mod 4 = 0) then
  116.                         color := $6AAA60;
  117.                 end;
  118.  
  119.                 lBrightness2 := lBrightness;
  120.                 if (y >= 32) then
  121.                     lBrightness2 := lBrightness2 div 2;
  122.                 if (j = 8) then
  123.                 begin
  124.                     color := $50D937; // leaves
  125.                     if (nextInt(2) = 0) then
  126.                     begin
  127.                         color := 0;
  128.                         lBrightness2 := 255;
  129.                     end;
  130.                 end;
  131.  
  132.                 // fixed point colour multiply between i1 and i2
  133.                 lColor :=
  134.                 ((((color >> 16) and $FF) * lBrightness2 div 255) << 16) or
  135.                 ((((color >>  8) and $FF) * lBrightness2 div 255) <<  8) or
  136.                 ((color        and $FF) * lBrightness2 div 255);
  137.                 // pack the colour away
  138.                 texmap[ x + y * 16 + j * 256 * 3 ] := lColor;
  139.             end;
  140.     end;
  141. end;
  142.  
  143. procedure makeMap();
  144. var
  145.     x, y, z, i : Integer;
  146.     yd, zd, th : single;
  147. begin
  148.     // add random blocks to the map
  149.     for x := 0 to MAPDIM-1 do begin
  150.         for y := 0 to MAPDIM-1 do begin
  151.             for z := 0 to MAPDIM-1 do begin
  152.                 i := (z shl 12) or (y shl 6) or x;
  153.                 yd := (y - 32.5) * 0.4;
  154.                 zd := (z - 32.5) * 0.4;
  155.                 map[i] := nextInt( 16 );
  156.                 th := nextInt( 256 ) / 256.0;
  157.                 if (th > sqrt( sqrt( sqr((y - 32.5) * 0.4) + sqr(zd) ) ) - 0.8) or (th < 0.5) then
  158.                     map[i] := 0;
  159.             end;
  160.         end;
  161.     end;
  162. end;
  163.  
  164. procedure init( );
  165. begin
  166.     makeTextures( );
  167.     makeMap( );
  168. end;
  169.  
  170. procedure render();
  171. const
  172.     __zd = 1.0;
  173.     oy = 32.5;
  174.     oz = 32.5;
  175. var
  176.     now,xRot,yRot,yCos,
  177.     ySin,xCos,xSin,
  178.     ox,
  179.     ___xd,__yd,___zd,_yd,
  180.     _xd,_zd,closest,
  181.     dimLength,ll,
  182.     xd,yd,zd,initial,dist,
  183.     xp,yp,zp: single;
  184.     x,y ,col,br: Integer;
  185.  
  186. procedure InnerLoop(d: Integer); inline;
  187. var
  188.     cc,tex,u,v:Integer;
  189. begin
  190.     // while we are concidering a ray that is still closer then the best so far
  191.     while (dist < closest) do begin
  192.         // quantize to the map grid
  193.         tex := map[ ((trunc(zp) and 63) << 12) or ((trunc(yp) and 63) << 6) or (trunc(xp) and 63) ];
  194.  
  195.         // if this voxel has a texture applied
  196.         if (tex > 0) then begin
  197.             // find the uv coordinates of the intersection point
  198.             if (d <> 0) then begin
  199.                 // fix uvs for alternate directions?
  200.                 u := (trunc((xp + zp) * 16)) and 15;
  201.                 v := (trunc(yp        * 16)  and 15) + 16;
  202.             end else begin
  203.                 u :=  (trunc(xp * 16)) and 15;
  204.                 v := ((trunc(zp * 16)) and 15);
  205.                 if (yd < 0.0) then
  206.                     v += 32;
  207.             end;
  208.  
  209.             //find the colour at the intersection point
  210.             cc := texmap[ u + v * 16 + tex * 256 * 3 ];
  211.             // if the colour is not transparent
  212.             if (cc > 0) then begin
  213.                 col := cc;
  214.                 br := 255 - trunc(dist * (255.0 / 32.0));
  215.                 br := br * (255 - d) div 255;
  216.                 //we now have the closest hit point (also terminates this ray)
  217.                 closest := dist;
  218.             end;
  219.         end;
  220.         // advance the ray
  221.         xp += xd;
  222.         yp += yd;
  223.         zp += zd;
  224.         dist += ll;
  225.     end;
  226. end;
  227.  
  228. procedure UnrolledLoop(); inline;
  229. var t: Single;
  230. begin
  231.     // d = 0
  232.     if (_xd > 0.0) then
  233.     begin
  234.         ll := 1.0 / (_xd);
  235.         xd := _xd * ll;
  236.         yd := _yd * ll;
  237.         zd := _zd * ll;
  238.         t := 1-(ox - Trunc(ox));
  239.         xp := ox + xd * t;
  240.     end else begin
  241.         ll := 1.0 / (-_xd);
  242.         xd := _xd * ll;
  243.         yd := _yd * ll;
  244.         zd := _zd * ll;
  245.         t := ox - Trunc(ox);
  246.         xp := ox + xd * t - 1;
  247.     end;
  248.     dist := ll * t;
  249.     yp := oy + yd * t;
  250.     zp := oz + zd * t;
  251.     InnerLoop(((0 + 2) mod 3) * 50);
  252.  
  253.     // d = 1
  254.     if (_yd > 0.0) then
  255.     begin
  256.         ll := 1.0 / (_yd);
  257.         xd := _xd * ll;
  258.         yd := _yd * ll;
  259.         zd := _zd * ll;
  260.         t := 1-(oy - Trunc(oy));
  261.         yp := oy + yd * t;
  262.     end else begin
  263.         ll := 1.0 / (-_yd);
  264.         xd := _xd * ll;
  265.         yd := _yd * ll;
  266.         zd := _zd * ll;
  267.         t := oy - Trunc(oy);
  268.         yp := oy + yd * t - 1;
  269.     end;
  270.     dist := ll * t;
  271.     xp := ox + xd * t;
  272.     zp := oz + zd * t;
  273.     InnerLoop(((1 + 2) mod 3) * 50);
  274.  
  275.     // d = 2
  276.     if (_zd > 0.0) then
  277.     begin
  278.         ll := 1.0 / _zd;
  279.         xd := _xd * ll;
  280.         yd := _yd * ll;
  281.         zd := _zd * ll;
  282.         t := 1 - oz + Trunc(oz);
  283.         zp := oz + zd * t;
  284.     end else begin
  285.         ll := 1.0 / -_zd;
  286.         xd := _xd * ll;
  287.         yd := _yd * ll;
  288.         zd := _zd * ll;
  289.         t := oz - Trunc(oz);
  290.         zp := oz + zd * t - 1;
  291.     end;
  292.     dist := ll * t;
  293.     xp := ox + xd * t;
  294.     yp := oy + yd * t;
  295.     InnerLoop(((2 + 2) mod 3) * 50);
  296. end;
  297.  
  298. begin
  299.     now := ((SDL_GetTicks() - tickStart) mod TIME_SCALE) / TIME_SCALE;
  300.  
  301.     xRot := sin(now * math_pi * 2) * 0.4 + math_pi / 2;
  302.     yRot := cos(now * math_pi * 2) * 0.4;
  303.     yCos := cos(yRot);
  304.     ySin := sin(yRot);
  305.     xCos := cos(xRot);
  306.     xSin := sin(xRot);
  307.  
  308.     ox := 32.5 + now * 64.0;
  309.  
  310.     // for each column
  311.     for x :=0 to WIDTH -1 do begin
  312.         // get the x axis delta
  313.         ___xd := (x - WIDTH div 2) / HEIGHT;
  314.         // for each row
  315.         for y :=0 to HEIGHT-1 do begin
  316.             // get the y axis delta
  317.             __yd := (y - HEIGHT div 2) / HEIGHT;
  318.             ___zd :=  __zd * yCos +  __yd * ySin;
  319.             _yd :=  __yd * yCos -  __zd * ySin;
  320.             _xd := ___xd * xCos + ___zd * xSin;
  321.             _zd := ___zd * xCos - ___xd * xSin;
  322.  
  323.             col := 0;
  324.             br := 255;
  325.             closest := 32.0;
  326.  
  327.             UnrolledLoop();
  328.  
  329.             p32Array(screen^.pixels)^[y * WIDTH + x] := ((br * ((col shr 16) and 255) div 255) shl 16
  330.                                                        + (br * ((col shr 8 ) and 255) div 255) shl 8
  331.                                                        +  br * (col and 255) div 255);
  332.         end;
  333.     end;
  334. end;
  335.  
  336. var
  337.     tickf: longword;
  338.     frames : longword = 0;
  339. begin
  340.     SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
  341.     SDL_putenv('SDL_VIDEO_CENTERED=1');
  342.     SDL_Init(SDL_INIT_VIDEO);
  343.  
  344.     screen := SDL_SetVideoMode( WIDTH, HEIGHT, 32 , SDL_SWSURFACE );
  345.     init();
  346.     tickStart := SDL_GetTicks();
  347.     tickf := tickStart;
  348.     while not done  do
  349.     begin
  350.         while  SDL_PollEvent( @event ) > 0  do
  351.             case event.type_  of
  352.                 SDL_KEYDOWN:
  353.                     if ( event.key.keysym.sym = SDLK_ESCAPE ) then
  354.                     begin
  355.                         done := true;
  356.                     end;
  357.                 SDL_QUITEV:
  358.                 begin
  359.                     done := true;
  360.                 end;
  361.             end;
  362.         render( );
  363.         inc(frames);
  364.         SDL_Flip(screen);
  365.         if SDL_GetTicks() - tickf > 1000  then begin
  366.             tickf := SDL_GetTicks();
  367.             SDL_WM_SetCaption(pchar('FPS='+inttostr(frames)), nil);
  368.             frames := 0;
  369.         end;
  370.     end;
  371. end.
  372.  

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Raytracing: FPC vs Java
« Reply #3 on: February 04, 2017, 05:42:35 pm »
level3 is a collection of optimizations. Set it first, or it may erase earlier switches?

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Raytracing: FPC vs Java
« Reply #4 on: February 04, 2017, 06:30:11 pm »
So final results: FPC 21 fps, Java 24 fps.
That's much better. ;)
That's all good and well... :)  But now start optimising the Java version too. ;-)  The gap between the two compilers increase again.

There is simply no way FPC can beat Java. As I mentioned in the original thread... we all know FPC was developed with "ease of maintenance" and "easy of portability" in mind. Performance was never on the table. Contrary to what many may think, in recent years, Java (even with badly written code) does an amazing job with optimisations. It's a damn good language and JVM these days.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Raytracing: FPC vs Java
« Reply #5 on: February 04, 2017, 06:50:43 pm »
There is simply no way FPC can beat Java. As I mentioned in the original thread... we all know FPC was developed with "ease of maintenance" and "easy of portability" in mind. Performance was never on the table. Contrary to what many may think, in recent years, Java (even with badly written code) does an amazing job with optimisations. It's a damn good language and JVM these days.

That is a pretty bad generalization. These benchmarks are totally atypical, don't use objects or dynamic memory management in the core loop, and map 1:1 on C.

Then it amounts to what you can buy wrt compiler technology, but that doesn't say really that much about Java the language and the performance of larger Java programs.

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Raytracing: FPC vs Java
« Reply #6 on: February 04, 2017, 07:37:44 pm »
@Marco: You are forgetting the fact that the original code (JavaScript version) was written based on Java code (original code was never released) which was submitted to a 4K (4000 bytes maximum) competition. So it was by design ugly (as Notch clearly stated) and was all about how much functionality he could achieved with a mere 4K executable. The C, Object Pascal and my Java version are all based on the "ugly code". So all of them are written on the same "level playing field" - you are welcome to disagree. None of them taking real advantage of each language [features] per se. So I personally think it's a good comparison, to see what a compiler can do with "ugly written code". Some compilers are clearly way better at that than others.

What I didn't mention in my previous post (and probably should have), is that FPC does have some advantages over Java too. eg: a all-in-one executable that doesn't require a 80MB runtime environment.

Saying all this, it is still possible writing games with FPC. If they are graphics intensive, simply make sure the game isn't based on software rendering, but rather hardware accelerated. Then you have nothing to worry about. My FPC+SDL2+OpenGL port of this demo so far reaches 450 fps - way more speed than I really need.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Raytracing: FPC vs Java
« Reply #7 on: February 04, 2017, 08:55:29 pm »
@Marco: You are forgetting the fact that the original code (JavaScript version) was written based on Java code (original code was never released) which was submitted to a 4K (4000 bytes maximum) competition. So it was by design ugly (as Notch clearly stated) and was all about how much functionality he could achieved with a mere 4K executable. The C, Object Pascal and my Java version are all based on the "ugly code". So all of them are written on the same "level playing field" - you are welcome to disagree. None of them taking real advantage of each language [features] per se. So I personally think it's a good comparison, to see what a compiler can do with "ugly written code". Some compilers are clearly way better at that than others.

All true, and all an open door if you are going to write e.g. codecs. Or vision apps (though even those are quite of more memory bandwidth than CPU limited).

But it has absolutely, absolutely nothing to do with the language, and your statement

Quote
It's a damn good language and JVM these days.

is very (and TOO) general. Specially since it has nought to do with language, just compiler technology.

argb32

  • Jr. Member
  • **
  • Posts: 89
    • Pascal IDE based on IntelliJ platform
Re: Raytracing: FPC vs Java
« Reply #8 on: February 04, 2017, 09:53:06 pm »
level3 is a collection of optimizations. Set it first, or it may erase earlier switches?

I've tried different combinations. Presence of level3 seems to give about 1 fps. Others (with or without level3) seems to have no effect.

That's all good and well... :)  But now start optimising the Java version too. ;-)  The gap between the two compilers increase again.

I've applied some optimizations but didn't managed to get any performance gain in java version.
Although I didn't apply loop unrolling.;)

It's a damn good language and JVM these days.

Agree. JVM (Oracle HotSpot) is very polished platform and JIT compiler does impressive job.
Java as language is not as good IMHO but there are many languages which can use JVM.

If they are graphics intensive, simply make sure the game isn't based on software rendering, but rather hardware accelerated. Then you have nothing to worry about.

Unfortunately there is still reason to worry as usually algorithms computing which data should be passed to graphics hardware (e.g. which portion is potentially visible) require CPU power.;)

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Raytracing: FPC vs Java
« Reply #9 on: February 04, 2017, 10:47:32 pm »
(e.g. which portion is potentially visible) require CPU power.;)
Nope, that is done by OpenGL (GPU) as well. Depth calculations, perspective views, translation matrix etc.... all done via OpenGL on the GPU. It's actually brilliant! At the moment the only thing Object Pascal does in my SDL2+OpenGL application is setting up the graphics system, input handling and game logic. All graphics stuff is done on the GPU via OpenGL, hence I can get up to 4000+ fps.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Raytracing: FPC vs Java
« Reply #10 on: February 05, 2017, 01:52:28 am »
(e.g. which portion is potentially visible) require CPU power.;)
Nope, that is done by OpenGL (GPU) as well. Depth calculations, perspective views, translation matrix etc.... all done via OpenGL on the GPU. It's actually brilliant! At the moment the only thing Object Pascal does in my SDL2+OpenGL application is setting up the graphics system, input handling and game logic. All graphics stuff is done on the GPU via OpenGL, hence I can get up to 4000+ fps.

You've said recently that you're new to OpenGL, so just to be sure you're not starting off on the wrong foot: are you, then, doing all of the things you just described within a GLSL shader? Because if not, you're still using the CPU. All of the fixed-function-pipeline matrix and viewport-related methods (as in glRotate, glScale, glTranslate, gluPerspective, glPushMatrix, glPopMatrix, glLoadMatrix, e.t.c) are executed strictly on the CPU, and upload their results to the GPU afterwards. To oversimplify it: anything that isn't being executed within a compiled shader (or a display list, although they're as deprecated as the fixed-function pipeline) is not using your GPU. Also, doing all of your matrix math inside a shader is not even really a good idea, as it means you'll be repeating the calculations for every single vertex. A better way to do it is to do the calculations once per "draw call" on the CPU, and send them to your shader via a uniform.
« Last Edit: February 05, 2017, 02:07:58 am by Akira1364 »

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Raytracing: FPC vs Java
« Reply #11 on: February 05, 2017, 02:49:27 am »
You've said recently that you're new to OpenGL,
:)

Quote
so just to be sure you're not starting off on the wrong foot: are you, then, doing all of the things you just described within a GLSL shader?
Correct, I set up a translation matrix (including some other matrix's too) and they are all executed by the shader. I'm not using any deprecated OpenGL calls. So I only support OpenGL 3.3 and up in my application and do things according to the "modern OpenGL way".

Quote
Also, doing all of your matrix math inside a shader is not even really a good idea, as it means you'll be repeating the calculations for every single vertex.
I'll see how it goes, but the GPU with its many many cores were design to do such things, and do them 1000's of times faster than the "general" CPU can. I'm just giving them what they were designed to do. ;-)
« Last Edit: February 05, 2017, 02:57:02 am by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Raytracing: FPC vs Java
« Reply #12 on: February 05, 2017, 03:38:02 am »
did anyone make LLVM version for comparison?

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Raytracing: FPC vs Java
« Reply #13 on: February 05, 2017, 04:49:30 am »
Like, Clang, you mean? Would likely be very similar to the GCC results.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Raytracing: FPC vs Java
« Reply #14 on: February 05, 2017, 01:39:54 pm »
Also try out ppcjvm. FPC is a jvm language too.. With sometimes indeed much faster results compared to true native code.
Specialize a type, not a var.

 

TinyPortal © 2005-2018