QB64.org Forum

Samples Gallery & Reference => Samples => 2D/3D Graphics => Topic started by: Qwerkey on March 26, 2020, 05:52:12 am

Title: MAPTRIANGLE in 3D by Petr
Post by: Qwerkey on March 26, 2020, 05:52:12 am
MAPTRIANGLE in 3D - ROTATION

Author: @Petr
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=300.msg101478#msg101478 (https://www.qb64.org/forum/index.php?topic=300.msg101478#msg101478)
Version: 3D Rotation
Tags: [3D], [Graphics]

Description:
A demo to show rotation in 3D using MAPTRIANGLE 3D, without direct OpenGL statements.

Librarian's Note:  The sample given here is just one of a number of _MAPTRIANGLE(3D) examples which appear in Petr's post.  That post is a good learning resource for anyone wanting to learn 3D graphics using _MAPTRIANGLE(3D).

Source Code:
Code: QB64: [Select]
  1. 'Program details:
  2.  
  3. 'ad 1:  SUB init - read text "Petr", which is writed to virtual screen and write every pixel position to array T.
  4. '       array T contains pixels positions data, recalculated to 3D in the same way as OpenGL (X = minus values to left, plus values to right, zero is middle,
  5. '       Y = minus values down, plus values up, zero in middle, Z values - visible from -1 to lower values)
  6. '
  7. ' I see such a small reproach to myself in the definition of the T array. Next time I would write also new function, that would return a number
  8. ' indicating the real number used pixels, because is an unnecessary waste of memory and performance to write  DIM T (16*8) for one character, if this
  9. ' character use just 20 pixels.
  10.  
  11. 'ad 2: (row 73 in source code): Program read array T. If in T is some record ( T().x >0 ) then is called SUB kostka. SUB kostka create cube in
  12. '      coordinates X, Y, Z and use OpenGL coordinate system.
  13.  
  14.  
  15.  
  16.  
  17. _TITLE "Next MAPTRIANGLE 3D demo"
  18.  
  19. k = _PI(2) / 4 'k is angle 360 / 4 in radians, for 4 cube corners (cube is double quad)
  20.  
  21.     x AS INTEGER
  22.     y AS INTEGER
  23.  
  24. '------------
  25. DIM SHARED texture AS LONG, rot
  26.  
  27.     x AS SINGLE
  28.     y AS SINGLE
  29.     z AS SINGLE
  30.  
  31. DIM SHARED T(14 * 110) AS T
  32.  
  33. init '                          SEE ad 1
  34. '---------------------
  35.  
  36.  
  37.  
  38. SCREEN _NEWIMAGE(800, 600, 32)
  39. CLS , _RGB32(127, 127, 188)
  40.  
  41.  
  42. DIM B(3) AS b
  43.  
  44.  
  45. B(0).x = -1: B(0).y = -1
  46. B(1).x = 1: B(1).y = -1
  47. B(2).x = -1: B(2).y = -1
  48. B(3).x = 1: B(3).y = -1 '            B() are starting coordinates for cube in middle screen
  49.  
  50. w = _WIDTH(i)
  51. h = _HEIGHT(i)
  52.  
  53.     IF i THEN _FREEIMAGE i '         if exists hardware image (which contains clock), then free it from memory
  54.     j = _NEWIMAGE(150, 100, 32) '    create software image (handle j)
  55.     _DEST j
  56.     CLS , _RGBA32(0, 50, 127, 100)
  57.     clock 0, 0 '                    draw new clock image, which contains current system time to software image (handle j)
  58.     _DEST 0
  59.     '                               copy software image j as hardware image i and then delete software image j
  60.     i = _COPYIMAGE(j, 33)
  61.     _FREEIMAGE j
  62.  
  63.     clock 0, 0 '                    as you see, here you are in DEST 0. Clocks is now paint to screen to left corner (coordinates 0,0)
  64.  
  65.     texture& = i '                  set i handle as texture& handle
  66.     '--------------------
  67.  
  68.     FOR Ys = 0 TO 17 '                            SEE ad 2
  69.         zz2 = zz2 + .01
  70.         FOR Xs = 0 TO 50
  71.             IF T(i4).x > 0 THEN
  72.                 X = T(i4).x + 70
  73.                 Y = T(i4).y
  74.                 z = T(i4).z - 70
  75.                 kostka X - zz2, Y, z - 15 + zz2
  76.             END IF
  77.             i4 = i4 + 1
  78.     NEXT Xs, Ys
  79.     i4 = 0
  80.     IF zz2 > 140 THEN zz2 = -50
  81.     '-----------------------------
  82.  
  83.     Sx = 0
  84.     Sz = -2.5
  85.     Sy = -1
  86.  
  87.  
  88.     Rx = 1
  89.     Ry = -1
  90.     Rz = 1
  91.     ' info for rotation. To rotate the bodies, you must have all the points that are rotating in the same center. For this demo, it is easy to specify the radius of rotation,
  92.     ' because all the points are just as far from the center as the cube is a symmetrical body. But if you want to write a 3D game, then if you want to write with MAPTRIANGLE,
  93.     ' you need to map the floor using 4 triangles and calculate the radius for the points on the edges using the Pythagoras theorem:
  94.     '
  95.     '       A--------------------------B     x is your position, as you see, all points use different radius
  96.     '       I\\\                   Y / I     Y is your triangle side 1, next is floor height - Y
  97.     '       I   \\\\\\             Y/  I     X is your triangle side 2, next is floor width - X
  98.     '       I          \\\\\\\\/// xXXXI     third sides calculate using Pythagoras.
  99.     '       I       ////////////    \  I
  100.     '       I //////                 \ I
  101.     '       C--------------------------D
  102.     '
  103.     x1 = Sx + SIN(rot) * Rx: z1 = Sz + COS(rot) * Rz: y1R = Sy + SIN(rot) * Ry
  104.     x2 = Sx + SIN(rot + k) * Rx: z2 = Sz + COS(rot + k) * Rz: y2R = Sy + SIN(rot + k) * Ry
  105.  
  106.     x4 = Sx + SIN((2 * k) + rot) * Rx: z4 = Sz + COS((2 * k) + rot) * Rz: y3R = Sy + SIN((3 * k) + rot) * Ry
  107.     x3 = Sx + SIN((3 * k) + rot) * Rx: z3 = Sz + COS((3 * k) + rot) * Rz: y4R = Sy + SIN((4 * k) + rot) * Ry
  108.  
  109.     y1 = B(0).y
  110.     y2 = B(1).y
  111.     y4 = B(2).y
  112.     y3 = B(3).y
  113.  
  114.  
  115.  
  116.  
  117.     y5 = y1 + 1.5
  118.     y6 = y2 + 1.5
  119.     y7 = y3 + 1.5
  120.     y8 = y4 + 1.5
  121.  
  122.  
  123.     _MAPTRIANGLE (0, h)-(w, h)-(0, 0), i TO(x1, y1, z1)-(x2, y2, z2)-(x3, y3, z3) 'podlaha                 floor
  124.     _MAPTRIANGLE (w, h)-(0, 0)-(w, 0), i TO(x2, y2, z2)-(x3, y3, z3)-(x4, y4, z4) 'podlaha
  125.  
  126.  
  127.     _MAPTRIANGLE (0, h)-(w, h)-(0, 0), i TO(x1, y5, z1)-(x2, y6, z2)-(x3, y7, z3) 'strop                   roof
  128.     _MAPTRIANGLE (w, h)-(0, 0)-(w, 0), i TO(x2, y6, z2)-(x3, y7, z3)-(x4, y8, z4) 'strop
  129.  
  130.     _MAPTRIANGLE (0, h)-(w, h)-(0, 0), i TO(x1, y1, z1)-(x2, y2, z2)-(x1, y5, z1) 'prava stena             right wall
  131.     _MAPTRIANGLE (w, h)-(0, 0)-(w, 0), i TO(x2, y2, z2)-(x1, y5, z1)-(x2, y6, z2) 'prava stena
  132.  
  133.  
  134.     _MAPTRIANGLE (w, h)-(0, h)-(w, 0), i TO(x3, y3, z3)-(x4, y4, z4)-(x3, y7, z3) 'leva stena              left wall
  135.     _MAPTRIANGLE (0, h)-(w, 0)-(0, 0), i TO(x4, y4, z4)-(x3, y7, z3)-(x4, y8, z4) 'leva stena
  136.  
  137.  
  138.     _MAPTRIANGLE (w, h)-(0, h)-(w, 0), i TO(x1, y1, z1)-(x3, y3, z3)-(x1, y5, z1) 'zadni stena             back wall
  139.     _MAPTRIANGLE (0, h)-(w, 0)-(0, 0), i TO(x3, y3, z3)-(x1, y5, z1)-(x3, y7, z3) 'zadni stena
  140.  
  141.  
  142.     _MAPTRIANGLE (0, h)-(w, h)-(0, 0), i TO(x2, y2, z2)-(x4, y4, z4)-(x2, y6, z2) 'predni stena            front wall
  143.     _MAPTRIANGLE (w, h)-(0, 0)-(w, 0), i TO(x4, y4, z4)-(x2, y6, z2)-(x4, y8, z4) 'zadni stena
  144.  
  145.  
  146.     _DISPLAY
  147.     _LIMIT 50
  148.  
  149.     rot = rot + .01
  150.  
  151. SUB kostka (x, y, z) 'zadavas levy horni predni roh ,udela kostku v zadane x,y,z                         x y z are coordinates for left upper corner, do cube on this place
  152.  
  153.  
  154.     W = _WIDTH(texture&)
  155.     H = _HEIGHT(texture&)
  156.  
  157.     '                g                       h                                e                  f
  158.     MAPQUAD x + -1.5, y + 1.5, z + -1.5, x + .5, y + 1.5, z + -1.5, x + -1.5, y + -.5, z + -1.5, x + .5, y + -.5, z - 1.5, texture&
  159.     MAPQUAD x + -1, y + 1, z + -1, x + 1, y + 1, z + -1, x + -1.5, y + 1.5, z + -1.5, x + .5, y + 1.5, z + -1.5, texture&
  160.     MAPQUAD x + -1.5, y + -.5, z + -1.5, x + .5, y + -.5, z - 1.5, x + -1, y + -1, z + -1, x + 1, y - 1, z - 1, texture& '
  161.     MAPQUAD x + -1, y + 1, z + -1, x + -1.5, y + 1.5, z + -1.5, x + -1, y + -1, z + -1, x + -1.5, y + -.5, z + -1.5, texture&
  162.     MAPQUAD x + .5, y + 1.5, z + -1.5, x + .5, y + -.5, z - 1.5, x + 1, y - 1, z - 1, x + 1, y + 1, z + -1, texture&
  163.     '                a                     b                    c                       d
  164.     MAPQUAD x + -1, y + 1, z + -1, x + 1, y + 1, z + -1, x + -1, y + -1, z + -1, x + 1, y - 1, z - 1, texture&
  165.  
  166.  
  167.  
  168.  
  169.  
  170. SUB MAPQUAD (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, texture AS LONG)
  171.     W = _WIDTH(texture&)
  172.     H = _HEIGHT(texture&)
  173.  
  174.     _MAPTRIANGLE (0, 0)-(W, 0)-(0, H), texture& TO(x1, y1, z1)-(x2, y2, z2)-(x3, y3, z3)
  175.     _MAPTRIANGLE (W, 0)-(0, H)-(W, H), texture& TO(x2, y2, z2)-(x3, y3, z3)-(x4, y4, z4)
  176.  
  177. SUB init
  178.     text$ = " Petr" 'width = 32 pixels (records)
  179.  
  180.     virtual& = _NEWIMAGE(100, 100, 256)
  181.     _DEST virtual&
  182.     PRINT text$
  183.     _SOURCE virtual&
  184.     i = 0
  185.     FOR Y = 17 TO 0 STEP -1
  186.         FOR X = 0 TO 50
  187.             IF POINT(X, Y) <> 0 THEN
  188.                 T(i).x = (-8.5 + X)
  189.                 T(i).y = -18 + (16 - Y) * 2
  190.                 T(i).z = -5 - X '                      this shift cubes in space consecutively. One pixel = One cube.
  191.             END IF
  192.             i = i + 1
  193.     NEXT X, Y
  194.     _DEST 0: _SOURCE 0: _FREEIMAGE virtual&
  195.     i = 0
  196.  
  197.  
  198. SUB clock (x, y) '                                     This sub draw software image contains clock
  199.     de = _DEST
  200.     clocka& = _NEWIMAGE(100, 100, 32)
  201.     _DEST clocka&
  202.     vterina = VAL(RIGHT$(TIME$, 2))
  203.     hodina = VAL(LEFT$(TIME$, 2))
  204.     minuta = VAL(MID$(TIME$, 4, 2))
  205.  
  206.     IF hodina > 12 THEN hodina = hodina - 12
  207.     hodina = hodina + (1 / 59) * minuta
  208.  
  209.  
  210.     vt = vterina + 45
  211.     ho = hodina + 45
  212.     mi = minuta + 45
  213.  
  214.     pozicevterina = _PI(2) / 60 * vt
  215.     poziceminuta = _PI(2) / 60 * ho * 5
  216.     pozicehodina = _PI(2) / 60 * mi
  217.  
  218.     xs = 50 + COS(pozicevterina) * 30
  219.     ys = 50 + SIN(pozicevterina) * 30
  220.  
  221.     xm = 50 + COS(poziceminuta) * 35
  222.     ym = 50 + SIN(poziceminuta) * 35
  223.  
  224.     xh = 50 + COS(pozicehodina) * 40
  225.     yh = 50 + SIN(pozicehodina) * 40
  226.  
  227.     FOR n = 1 TO 100
  228.         LINE (n, 0)-(n, 99), _RGB32(127 - n, n, 27 + n), BF
  229.     NEXT n
  230.     LINE (0, 0)-(99, 99), _RGB32(255, 255, 255), B
  231.  
  232.     COLOR _RGBA32(127, 127, 127, 150)
  233.     _PRINTSTRING (35, 45), "QB64"
  234.     COLOR _RGB32(255, 255, 255)
  235.  
  236.  
  237.     LINE (50, 50)-(xh, yh), _RGB32(255, 255, 0)
  238.     LINE (50, 50)-(xm, ym), _RGB32(255, 255, 0)
  239.     LINE (50, 50)-(xs, ys), _RGB32(0, 255, 255)
  240.     m = 0
  241.     FOR kruh = 0 TO _PI(2) STEP _PI(2) / 60
  242.         PSET (50 + COS(kruh) * 47, 50 + SIN(kruh) * 47)
  243.         IF m MOD 5 = 0 THEN LINE (50 + COS(kruh) * 47, 50 + SIN(kruh) * 47)-(50 + COS(kruh) * 44, 50 + SIN(kruh) * 44), , BF
  244.         m = m + 1
  245.     NEXT kruh
  246.     _DEST de
  247.     _SETALPHA 100, , clocka&
  248.     _PUTIMAGE (x, y), clocka&, de
  249.     _FREEIMAGE clocka&
  250.