QB64.org Forum

Samples Gallery & Reference => Samples => SUB _GL => Topic started by: Qwerkey on March 14, 2020, 08:56:11 am

Title: 3D : Sierpinski Cube by Ashish
Post by: Qwerkey on March 14, 2020, 08:56:11 am
3D : Sierpinski Cube

Author: @Ashish
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2251.msg114913#msg114913 (https://www.qb64.org/forum/index.php?topic=2251.msg114913#msg114913)
Version: 1
Tags: [3D], [Graphics], [Open_GL]

Description:
This fractal is popularly known as Menger Sponge. It looks beautiful.

Controls:
Move mouse for rotation.

Source Code:
Code: QB64: [Select]
  1. '@Author:Ashish Kushwaha
  2. '28 Feb, 2020s
  3. _TITLE "Menger Sponge"
  4. SCREEN _NEWIMAGE(600, 600, 32)
  5.  
  6. TYPE vec3
  7.     x AS SINGLE
  8.     y AS SINGLE
  9.     z AS SINGLE
  10.  
  11.     SUB glutSolidCube (BYVAL dsize AS DOUBLE) 'use to draw a solid cube by taking the side length as its arguement
  12.  
  13. 'Algorithm
  14. '1. We take a cube.
  15. '2. We divide it into 27 equal cubical parts.
  16. '3. Out of this 27 cubes, 7 cubes are removed.
  17. '4. In the remaining 20 cubes, Step-1 is repeated for each cube.
  18. iteration = 3 'no. of iteration. At each iteration, 7 cubes are removed from parent cube.
  19. size = 0.5 'the size of our first cube
  20. n = (20 ^ iteration) - 1
  21.  
  22. DIM SHARED glAllow, cubeLoc(n) AS vec3, fundamentalCubeSize 'cubeLoc array store the location of cubes to be rendered. They are the smallest cube which are formed in the last iteration
  23. fundamentalCubeSize = size / (3 ^ iteration) 'the size the smallest cube which is formed in the last iteration
  24. initFractal 0, 0, 0, size, iteration 'this sub done all calculation for cube location & other stuff.
  25.  
  26. PRINT (n + 1); " Cubes will rendered with total of "; 8 * (n + 1); " vertices"
  27. PRINT "Hit a Key"
  28. glAllow = 1 'to start rendering in the SUB _GL
  29.     _LIMIT 40
  30.  
  31. SUB _GL () STATIC
  32.     DIM clr(3)
  33.     IF glAllow = 0 THEN EXIT SUB 'So that rendering will start as soon as initialization is done.
  34.     IF glInit = 0 THEN
  35.         _glViewport 0, 0, _WIDTH, _HEIGHT 'this defines the area in the screen where GL rendering will occur
  36.         aspect# = _WIDTH / _HEIGHT
  37.  
  38.         glInit = 1
  39.     END IF
  40.  
  41.     _glEnable _GL_DEPTH_TEST 'this enable Z-buffer. So that we can do 3D things.
  42.     _glClear _GL_DEPTH_BUFFER_BIT OR _GL_COLOR_BUFFER_BIT 'Not required unless we do softwre rendering as well.
  43.  
  44.     'LIGHTS CONFIG
  45.     _glEnable _GL_LIGHTING 'this enable us to use light. There are max of 8 lights in GL
  46.     _glEnable _GL_LIGHT0
  47.     clr(0) = 0.2: clr(1) = 0.2: clr(2) = 0.2: clr(3) = 1
  48.     _glLightfv _GL_LIGHT0, _GL_AMBIENT, _OFFSET(clr()) 'this define the color of the material where light can hardly reach.
  49.     clr(0) = 0.8: clr(1) = 0.8: clr(2) = 0.8: clr(3) = 1
  50.     _glLightfv _GL_LIGHT0, _GL_SPECULAR, _OFFSET(clr()) 'this define the color of the material where light is directly reflected & reach your eye.
  51.     _glLightfv _GL_LIGHT0, _GL_DIFFUSE, _OFFSET(clr()) 'this define the default/usual color of the light on the material.
  52.     clr(0) = 0: clr(1) = 0: clr(2) = 0: clr(3) = 1
  53.     _glLightfv _GL_LIGHT0, _GL_POSITION, _OFFSET(clr()) 'use to define the direction of light when 4th component is 0. When 4th component is 1, it defines the position of light. In this case, the light looses its intensity as distance increases.
  54.  
  55.     _glMatrixMode _GL_PROJECTION 'usually used for setting up perspective etc.
  56.     _gluPerspective 60, aspect#, 0.1, 10 'first arguement tell angle for FOV (Field of View, for human it is round 70degree for one eye.LOL) next one aspect ratio, next 2 are near & far distance. Objects which are not between these distance are clipped. (or are not rendered.)
  57.  
  58.     _glMatrixMode _GL_MODELVIEW 'rendering takes place here
  59.  
  60.     _glTranslatef 0, 0, -1 'move the origin forward by 1 unit
  61.     _glRotatef _MOUSEX, 0, 1, 0 'these are for rotation by the movement of mouse.
  62.     _glRotatef _MOUSEY, 1, 0, 0
  63.  
  64.     drawFractal 'draws the fractal
  65.     _glFlush 'force all the GL command to complete in finite amount of time
  66.  
  67. SUB initFractal (x, y, z, s, N) 'x-position, y-position, z-position, size, N-> iteration
  68.     STATIC i
  69.     'As we divide the cube, value of N decreases.
  70.     IF N = 0 THEN 'when the division is done N times (no. of iteration)
  71.         cubeLoc(i).x = x 'store the coordinates of cube
  72.         cubeLoc(i).y = y
  73.         cubeLoc(i).z = z
  74.         i = i + 1
  75.         ' ? "Added #",i
  76.         ' sleep
  77.         EXIT SUB
  78.     END IF
  79.     'top section
  80.     'front row, left to right
  81.     initFractal (x - s / 3), (y + s / 3), (z + s / 3), s / 3, N - 1
  82.     initFractal (x), (y + s / 3), (z + s / 3), s / 3, N - 1
  83.     initFractal (x + s / 3), (y + s / 3), (z + s / 3), s / 3, N - 1
  84.     'behind the previous row, left to right
  85.     initFractal (x - s / 3), (y + s / 3), (z), s / 3, N - 1
  86.     initFractal (x + s / 3), (y + s / 3), (z), s / 3, N - 1
  87.     'behind the previous row, left to right
  88.     initFractal (x - s / 3), (y + s / 3), (z - s / 3), s / 3, N - 1
  89.     initFractal (x), (y + s / 3), (z - s / 3), s / 3, N - 1
  90.     initFractal (x + s / 3), (y + s / 3), (z - s / 3), s / 3, N - 1
  91.     'middle section
  92.     'front row, left to right
  93.     initFractal (x - s / 3), (y), (z + s / 3), s / 3, N - 1
  94.     initFractal (x + s / 3), (y), (z + s / 3), s / 3, N - 1
  95.     'behind the previous row (last one as middle one contain no cube ;) ), left to right
  96.     initFractal (x - s / 3), (y), (z - s / 3), s / 3, N - 1
  97.     initFractal (x + s / 3), (y), (z - s / 3), s / 3, N - 1
  98.     'bottom section
  99.     'front row, left to right
  100.     initFractal (x - s / 3), (y - s / 3), (z + s / 3), s / 3, N - 1
  101.     initFractal (x), (y - s / 3), (z + s / 3), s / 3, N - 1
  102.     initFractal (x + s / 3), (y - s / 3), (z + s / 3), s / 3, N - 1
  103.     'behind the previous row, left to right
  104.     initFractal (x - s / 3), (y - s / 3), (z), s / 3, N - 1
  105.     initFractal (x + s / 3), (y - s / 3), (z), s / 3, N - 1
  106.     'behind the previous row, left to right
  107.     initFractal (x - s / 3), (y - s / 3), (z - s / 3), s / 3, N - 1
  108.     initFractal (x), (y - s / 3), (z - s / 3), s / 3, N - 1
  109.     initFractal (x + s / 3), (y - s / 3), (z - s / 3), s / 3, N - 1 '20
  110.  
  111.  
  112. SUB drawFractal ()
  113.     FOR i = 0 TO UBOUND(cubeLoc)
  114.         _glPushMatrix 'save the previous transformation configuration
  115.         _glTranslatef cubeLoc(i).x, cubeLoc(i).y, cubeLoc(i).z 'move at given location
  116.         glutSolidCube fundamentalCubeSize 'draws the solid cube of smallest size which is formed in the last iteration
  117.         _glPopMatrix 'restore the original transformation configuration
  118.     NEXT
  119.