Author Topic: "Real" 3D Rendering  (Read 7995 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: "Real" 3D Rendering
« Reply #15 on: November 21, 2019, 08:01:46 am »
Ah crap, I misled you a little yesterday.

I stupidly said that vec(i,j) holds the original position info. Not true.

Now look here, STxAxTIC.  I claim sole rights at this site for stupidity.  Stop treading on my territory this moment!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: "Real" 3D Rendering
« Reply #16 on: November 21, 2019, 10:23:31 am »
Hi STxAxTIC,

Are your replies #14, and #15 getting to the cube stretching problem in a round about way? or are we to make it an elephant in the room :D

Does Z have to be scaled because it is not naturally clipped from view as X and Y axis are?

I am thinking space clipping is setting up an arena, an aquarium, a finite block of space to put limits on what to calculate and show.

I am thinking my z stretching problem might be solved by setting back limit and then logarithmic scaling.

Oh the finite block of space is a pyramid with the pointy end cut off where the camera lens would go. Ha! this gives new meaning to that image on back of one dollar bill.


Still the z units going from front to back have to be diminishing in length.

« Last Edit: November 21, 2019, 10:35:34 am by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: "Real" 3D Rendering
« Reply #17 on: November 21, 2019, 11:05:55 am »
I don't know if  write another code with MAPTRIANGLE (3D) when the thread is mostly about how to create 3D using 2D commands?
I was doing a Z-axis survey today (how else than with Maptriangle 3D) and found out that, what for mathematical brains must be obvious long ago. The displacement of the points in the X, Y coordinates in relation to the Z axis is not linear.
It is rather a quadratic shift, at a lower distance the difference X, Y is large (100 pixels to the center), at a long distance the difference X, Y is small (about 5 pixels to the center compared to the previous position)

Otherwise - as STxAxTIC writes that it uses a rectangular viewport to limit the displayed points, I used the pythagoran theorem and by comparing the camera rotation I restricted the displayed elements to a semicircle (in a program that reads  maps, which can you do yourself  here: https://www.qb64.org/forum/index.php?topic=300.msg109293#msg109293)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: "Real" 3D Rendering
« Reply #18 on: November 21, 2019, 09:54:09 pm »
Hi guys, long day. I'll try to bite back into this slowly.

So bplus - are you getting stretching? If that's still true when you read this, I'll be happy to see what you've got. (By this point, the posts here are a few hours old and god only knows what's been learned since then.)

You can get distortions if the field-of-view constant isn't calibrated right. It's supposed to obey a similar triangle relation that would take more effort to write out (for me right now at least) then it would be for you just fudge the field-of-view constant until things look right. Again I point to Sanctum for an example of working numbers. Let me know m8.
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: "Real" 3D Rendering
« Reply #19 on: November 21, 2019, 10:41:24 pm »
Hi STxAxTIC,

Before posting my 3D rendering code I did fool with FOVD everything was magnified or shrunk with no effect at all on Z lengths except in being proportion of the magnifications.

I have been thinking camera x, y, z  is 0, 0, 0 on the real map and deciding whether a real x, y, z is in view should be covered with this very simple check:

Code: QB64: [Select]
  1. 'this code decides if x,y,z on real map is in square cone of vision
  2. 'DIM SHARED zmin, zmax, xmin, xmax, ymin, ymax   'move to top
  3. 'zmin = -50: zmax = -1
  4. 'xmin = -50: xmax = 50
  5. 'ymin = -50: ymax = 50
  6. FUNCTION xyzInView (test AS xyzType)
  7.     IF test.z >= zmin AND test.z <= zmax THEN
  8.         IF ABS(test.x) <= ABS(test.z) THEN
  9.             IF ABS(test.y) <= ABS(test.z) THEN xyzInView = -1
  10.         END IF
  11.     END IF

It's a simple model your eye is at 0,0,0 you have a peep hole 1x1 -1 unit in and looking at backscreen -50 units in from eye focal point, 45 degrees port and star-port gives full angle of 90 degrees, maybe you've seen this triangle before? ;-))
« Last Edit: November 21, 2019, 11:33:09 pm by bplus »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: "Real" 3D Rendering
« Reply #20 on: November 21, 2019, 11:49:53 pm »
So I thought about this a minute bplus - and thanks, I just tweaked the numbers for Sanctum as a result and it looks a lot better... Because I ran it, made a few blocks and shapes, saw the distortion, and totally saw what to do. The field of view constant was way too low. When I cranked up the "fovd" variable and re-ran the test, all the distortion went away. I always knew I was fudging those numbers but your question compelled me. There are reasons for this that I'd rather explain in a coherent bundle instead of all piecewise on a forum and start some kind of dumpster fire argument or whatever, haha. But yeah - just mess with the numbers. Here's a quicky screenshot of Sanctum getting a glancing angle of a sphere correct. That used to not look very circular. (Oh, and make sure you alt+enter your way into a screen mode that's truly square, that'll get ya each time.)

EDIT: When I dig into this and write this so-called tutorial or whatever it'll be one day, I may even find reason to revise the formula. I understand it better now than when I wrote it and could possibly improve it.

EDIT 2: I did a bad job with the purple ring there but you get the point: the sun is not an oval.
« Last Edit: November 22, 2019, 12:26:55 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: "Real" 3D Rendering
« Reply #21 on: November 22, 2019, 02:26:03 am »
OK STxAxTIC, I cranked up the FOVD and found cube like cubes! Didn't expect to have to go to 200!

Then I started testing my range and the new sub to see if it was predicting correctly what was in-view or not. Found out I had to make my FOVD negative for the points numbers to match drawn quadrants, for some reason they were reversed both x and y. Then I found x and y (cube centers) could only be .5 * z or less to be seen = 1/2 or more of cube visible. I found no -z limit if you don't mind pixel smudges but I did not try beyond -250 or so, expecting -50 was limit.

Here is revised code and testing:
Code: QB64: [Select]
  1. _TITLE "3D Render 2" ' B+ started 2019-10-20 (as Vector Math)
  2. ' Based on notes provided to QB64 forum by William F Barnes, on 2019-10-19
  3. ' https://www.qb64.org/forum/index.php?topic=1782.0
  4. ' A vector's dimension is the number of components it has.
  5. ' Here is code for processing 2 and 3 dimension vectors.
  6.  
  7. '2019-11-20 add STxAxTIC's conversion code for new sub screenXY
  8. ' Nice cube corners maker and nice wireframe cube
  9.  
  10. '2019-11-22 3D render 2, Upon STxAxTIC's advice crank up the FOVD,
  11. ' I did and found a nice range of cube like cubes, I also have a check
  12. ' for xyz to see if it is viewable, which we will test with FOVD.
  13. ' Oddly I had to make FOVD negative in order to get the numbers in the
  14. ' correct quadrants. When the cube center crosses into positive,
  15. ' the quadrants will flip-flop, but still a nice cube is drawn.
  16. ' When the cube center is at z=0  you will see a big X across screen!
  17.  
  18.  
  19. CONST sxmax = 700, symax = 700
  20. CONST tlx = -100, tly = 100, brx = 100, bry = -100 ' Cartesian Coordinate System corners for WINDOW command
  21. ' to convert mouse coordinates to WINDOW after call look up PMAP
  22.  
  23. TYPE xyType
  24.     x AS SINGLE
  25.     y AS SINGLE
  26.  
  27. TYPE xyzType
  28.     x AS SINGLE
  29.     y AS SINGLE
  30.     z AS SINGLE
  31.  
  32.  
  33. ' notation 0 w/arrowHat  (no way of telling if 2, 3 or more dimensions)
  34. DIM SHARED v2zero AS xyType, v3zero AS xyzType
  35. v2zero.x = 0: v2zero.y = 0
  36. v3zero.x = 0: v3zero.y = 0: v3zero.z = 0
  37.  
  38. 'Basis Vectors, isolate components e sub x Dot V w/arrowHat = V sub x
  39. DIM SHARED v2e(1 TO 2) AS xyType, v3e(1 TO 3) AS xyzType
  40. v2e(1).x = 1: v2e(1).y = 0
  41. v2e(2).x = 0: v2e(2).y = 1
  42. v3e(1).x = 1: v3e(1).y = 0: v3e(1).z = 0
  43. v3e(2).x = 0: v3e(2).y = 1: v3e(2).z = 0
  44. v3e(3).x = 0: v3e(3).y = 0: v3e(3).z = 1
  45.  
  46. DIM SHARED fovd AS DOUBLE 'for screenXY of (x, y, z) point in real space
  47. fovd = -200 '???
  48.  
  49.  
  50. DIM SHARED zmin, zmax, xmin, xmax, ymin, ymax
  51. zmin = -250: zmax = -1
  52. xmin = -50: xmax = 50
  53. ymin = -50: ymax = 50
  54.  
  55.  
  56. '==================================================================================== test area 2019-11-20
  57.  
  58. SCREEN _NEWIMAGE(sxmax, symax, 32) 'square screen
  59. _SCREENMOVE 300, 40
  60. WINDOW (tlx, tly)-(brx, bry) ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< get a Cartesian Coordinate System started
  61. ' >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   to convert mouse coordinates to WINDOW after call look up PMAP
  62.  
  63. REDIM testCube(0) AS xyzType
  64. DIM testPt AS xyzType
  65.  
  66. 'all z's must be negative!!!! there seems a flip flop mirror upside down image passing zero top pos hit inf at 0!!!!!!!!!
  67. FOR pushBack = 0 TO 9
  68.     FOR y = -2 TO 2 STEP 1
  69.         FOR x = -2 TO 2 STEP 2
  70.             FOR z = -6 TO -9 STEP -1
  71.                 newCube x, y, z - pushBack, 1, testCube()
  72.                 'FOR i = 0 TO 7
  73.                 '    PRINT v3$(testCube(i))
  74.                 'NEXT
  75.                 'good!  now convert these to screen projection points
  76.                 REDIM screenTest(0 TO 7) AS xyType
  77.                 FOR i = 0 TO 7
  78.                     screenXY testCube(i), screenTest(i)
  79.                     'PRINT screenTest(i).x, screenTest(i).y
  80.                 NEXT
  81.                 drawWireCube screenTest()
  82.             NEXT
  83.         NEXT
  84.     NEXT
  85.     _DELAY 2
  86.     CLS
  87.  
  88.  
  89. _TITLE "Testing only cubes with sides = 1 whatever units. Predicting what is viewable and what is not = BEEP with new function."
  90.  
  91. WHILE _KEYDOWN(27) = 0
  92.     CLS
  93.     PRINT "Press any to wakeup from sleep, esc to quit..."
  94.     z = irnd(-10, 5) 'ok now testing in and outside view numbers
  95.     x = irnd(.5 * z, -.5 * z)
  96.     y = irnd(.5 * z, -.5 * z)
  97.     setV3 x, y, z, testPt
  98.     IF xyzInView(testPt) THEN
  99.         newCube x, y, z, 1, testCube()
  100.         FOR i = 0 TO 7
  101.             PRINT v3$(testCube(i))
  102.         NEXT
  103.         'good!  now convert these to screen projection points
  104.         REDIM screenTest(0 TO 7) AS xyType
  105.         FOR i = 0 TO 7
  106.             screenXY testCube(i), screenTest(i)
  107.             PRINT screenTest(i).x, screenTest(i).y
  108.         NEXT
  109.         drawWireCube screenTest()
  110.         SLEEP
  111.     ELSE
  112.         BEEP
  113.         newCube x, y, z, 1, testCube()
  114.         FOR i = 0 TO 7
  115.             PRINT v3$(testCube(i))
  116.         NEXT
  117.         'good!  now convert these to screen projection points
  118.         REDIM screenTest(0 TO 7) AS xyType
  119.         FOR i = 0 TO 7
  120.             screenXY testCube(i), screenTest(i)
  121.             PRINT screenTest(i).x, screenTest(i).y
  122.         NEXT
  123.         drawWireCube screenTest()
  124.         SLEEP
  125.     END IF
  126.  
  127. 'this code decides if x,y,z on real map is in square cone of vision
  128. 'DIM SHARED zmin, zmax, xmin, xmax, ymin, ymax   'move to top
  129. 'zmin = -50: zmax = -1
  130. 'xmin = -50: xmax = 50
  131. 'ymin = -50: ymax = 50
  132. FUNCTION xyzInView (test AS xyzType)
  133.     IF test.z >= zmin AND test.z <= zmax THEN
  134.         IF ABS(test.x) <= .5 * ABS(test.z) THEN
  135.             IF ABS(test.y) <= .5 * ABS(test.z) THEN xyzInView = -1
  136.         END IF
  137.     END IF
  138.  
  139. 'bring this in for testing xyzInView
  140. FUNCTION irnd% (n1, n2) 'return an integer between 2 numbers
  141.     DIM l%, h%
  142.     IF n1 > n2 THEN l% = n2: h% = n1 ELSE l% = n1: h% = n2
  143.     irnd% = INT(RND * (h% - l% + 1)) + l%
  144.  
  145. ' ========================================================================= 2019-11-20 code
  146. SUB drawWireCube (corners() AS xyType)
  147.     'front face
  148.     LINE (corners(0).x, corners(0).y)-(corners(1).x, corners(1).y)
  149.     LINE -(corners(2).x, corners(2).y)
  150.     LINE -(corners(3).x, corners(3).y)
  151.     LINE -(corners(0).x, corners(0).y)
  152.     'back face
  153.     LINE (corners(4).x, corners(4).y)-(corners(5).x, corners(5).y)
  154.     LINE -(corners(6).x, corners(6).y)
  155.     LINE -(corners(7).x, corners(7).y)
  156.     LINE -(corners(4).x, corners(4).y)
  157.     'connect from to back
  158.     LINE (corners(0).x, corners(0).y)-(corners(4).x, corners(4).y)
  159.     LINE (corners(1).x, corners(1).y)-(corners(5).x, corners(5).y)
  160.     LINE (corners(2).x, corners(2).y)-(corners(6).x, corners(6).y)
  161.     LINE (corners(3).x, corners(3).y)-(corners(7).x, corners(7).y)
  162.  
  163. SUB newCube (cx, cy, cz, side, cubeCorners() AS xyzType)
  164.     DIM sd2, lx, rx, ty, by, fz, bz
  165.     REDIM cubeCorners(0 TO 7) AS xyzType
  166.     sd2 = side / 2
  167.     rx = cx + sd2: lx = cx - sd2
  168.     ty = cy + sd2: by = cy - sd2
  169.     fz = cz + sd2: bz = cz - sd2
  170.     cubeCorners(0).x = lx: cubeCorners(0).y = ty: cubeCorners(0).z = fz
  171.     cubeCorners(1).x = rx: cubeCorners(1).y = ty: cubeCorners(1).z = fz
  172.     cubeCorners(2).x = rx: cubeCorners(2).y = by: cubeCorners(2).z = fz
  173.     cubeCorners(3).x = lx: cubeCorners(3).y = by: cubeCorners(3).z = fz
  174.     cubeCorners(4).x = lx: cubeCorners(4).y = ty: cubeCorners(4).z = bz
  175.     cubeCorners(5).x = rx: cubeCorners(5).y = ty: cubeCorners(5).z = bz
  176.     cubeCorners(6).x = rx: cubeCorners(6).y = by: cubeCorners(6).z = bz
  177.     cubeCorners(7).x = lx: cubeCorners(7).y = by: cubeCorners(7).z = bz
  178.  
  179. ' project (x, y, z) point in real space to screenXY of user's eye-line
  180. SUB screenXY (xyzReal AS xyzType, xyScreen AS xyType)
  181.     'convert STxAxTIC's code to my code here
  182.     ' https://www.qb64.org/forum/index.php?topic=1904.msg111304#msg111304
  183.  
  184.     ' vec3Ddotnhat = vec(i, 1) * nhat(1) + vec(i, 2) * nhat(2) + vec(i, 3) * nhat(3)
  185.     ' vec2D(i, 1) = (vec(i, 1) * uhat(1) + vec(i, 2) * uhat(2) + vec(i, 3) * uhat(3)) * fovd / vec3Ddotnhat
  186.     ' vec2D(i, 2) = (vec(i, 1) * vhat(1) + vec(i, 2) * vhat(2) + vec(i, 3) * vhat(3)) * fovd / vec3Ddotnhat
  187.  
  188.     'my comments and conversion
  189.     'fovd seems like a variable that should be globally shared, maybe constant?
  190.     DIM vec3Ddotnhat
  191.     vec3Ddotnhat = v3DotProduct(xyzReal, v3e(3))
  192.     xyScreen.x = v3DotProduct(xyzReal, v3e(1)) * fovd / vec3Ddotnhat
  193.     xyScreen.y = v3DotProduct(xyzReal, v3e(2)) * fovd / vec3Ddotnhat
  194.  
  195. '================================================= subs and fuctions  from Vector Math.bas 2019-10-20
  196. SUB setV3 (x, y, z, setMe AS xyzType)
  197.     setMe.x = x: setMe.y = y: setMe.z = z
  198.  
  199. FUNCTION v3$ (showMeInnards AS xyzType)
  200.     v3$ = "[" + ts$(showMeInnards.x) + ", " + ts$(showMeInnards.y) + ", " + ts$(showMeInnards.z) + "]"
  201.  
  202. FUNCTION ts$ (number)
  203.     ts$ = _TRIM$(STR$(number))
  204.  
  205. 'notation UppercaseLetter w/arrowhat + uppercase Letter w/arrowHat
  206. SUB v2Add (A AS xyType, B AS xyType, Sum AS xyType)
  207.     Sum.x = A.x + B.x
  208.     Sum.y = A.y + B.y
  209. SUB v3Add (A AS xyzType, B AS xyzType, Sum AS xyzType)
  210.     Sum.x = A.x + B.x
  211.     Sum.y = A.y + B.y
  212.     Sum.z = A.z + B.z
  213.  
  214. 'notation UppercaseLetter w/arrowHat - UppercaseLetter w/arrowHat
  215. SUB v2Subtr (A AS xyType, B AS xyType, Sum AS xyType)
  216.     Sum.x = A.x - B.x
  217.     Sum.y = A.y - B.y
  218. SUB v3Subtr (A AS xyzType, B AS xyzType, Sum AS xyzType)
  219.     Sum.x = A.x - B.x
  220.     Sum.y = A.y - B.y
  221.     Sum.z = A.z - B.z
  222.  
  223. 'notation lowercaseletter (for a number next to (times)) UppercaseLetter w/arrowHat
  224. SUB v2Scale (mult AS SINGLE, A AS xyType, Scale AS xyType) 'parallels
  225.     Scale.x = mult * A.x
  226.     Scale.y = mult * A.y
  227. SUB v3Scale (mult AS SINGLE, A AS xyzType, Scale AS xyzType) 'parallels
  228.     Scale.x = mult * A.x
  229.     Scale.y = mult * A.y
  230.     Scale.z = mult * A.z
  231.  
  232. 'notation the inverse of A w/arrowHat is -A w/arrowHat
  233. SUB v2Inverse (A AS xyType, Inverse AS xyType) ' A + InverseOfA = 0
  234.     Inverse.x = -A.x
  235.     Inverse.y = -A.y
  236. SUB v3Inverse (A AS xyzType, Inverse AS xyzType) ' A + InverseOfA = 0
  237.     Inverse.x = -A.x
  238.     Inverse.y = -A.y
  239.     Inverse.z = -A.z
  240.  
  241. 'notation: A w/arrowHat Dot B w/arrowHat v2 Dot Product is a number, v3 Dot Product is a vector
  242. FUNCTION v2DotProduct (A AS xyType, B AS xyType) 'shadow or projection  if A Dot B = 0 then A , B are perpendicular
  243.     v2DotProduct = A.x * B.x + A.y * B.y
  244. FUNCTION v3DotProduct (A AS xyzType, B AS xyzType) 'shadow or projection  if A Dot B = 0 then A , B are perpendicular
  245.     v3DotProduct = A.x * B.x + A.y * B.y + A.z * B.z
  246.  
  247. 'notation absolute value bars about A w/arrowHat OR just an UppercaseLetter (with no hat), its just a number
  248. FUNCTION v2Magnitude (A AS xyType) 'hypotenuse of right triangle
  249.     v2Magnitude = SQR(v2DotProduct(A, A))
  250. FUNCTION v3Magnitude (A AS xyzType) 'hypotenuse of cube
  251.     v3Magnitude = SQR(v3DotProduct(A, A))
  252.  
  253. 'notation: A w/arrowHat X B w/arrowHat, X is a Cross get it?
  254. FUNCTION v2CrossProduct (A AS xyType, B AS xyType) ' a vector perpendicular to both A and B, v2 is a magnitude
  255.     v2CrossProduct = A.x * B.y - A.y * B.x
  256. SUB v3CrossProduct (A AS xyzType, B AS xyzType, Cross AS xyzType) ' v3 cross product is a 3d vector perpendicular to A and B
  257.     'notice x has no x components, y no y componets, z no z components
  258.     Cross.x = A.y * B.z - A.z * B.y
  259.     Cross.y = A.z * B.x - A.x * B.z
  260.     Cross.z = A.x * B.y - A.y * B.x
  261.  
  262. 'notation: A w/caratHat = A w/arrowHat divided by A (UppercaseLetter) or scaled by 1/A magnitude (no hats)
  263. SUB v2Unit (A AS xyType, Unit AS xyType)
  264.     DIM m AS SINGLE
  265.     m = v2Magnitude(A)
  266.     v2Scale 1 / m, A, Unit
  267. SUB v3Unit (A AS xyzType, Unit AS xyzType)
  268.     DIM m AS SINGLE
  269.     m = v3Magnitude(A)
  270.     v3Scale 1 / m, A, Unit
  271.  

I left off testing cubes around z=0 both positive and negative and 0 for centers.
Oh, the xmax, and xmin, ymax, ymin were never needed, z only has to be negative and both x and y <= 1/2 z's abs value.

So thanks, I have got the 1 unit cubes going!

Hey NO sign of SIN, COS or _PI, what do ya know!
« Last Edit: November 22, 2019, 12:54:22 pm by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: "Real" 3D Rendering
« Reply #22 on: November 25, 2019, 12:16:20 am »
I have a totally different solution for this....
Code: QB64: [Select]
  1. 'Example 3D Printing but using OpenGL
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3.  
  4.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  5.     SUB glutSolidCube (BYVAL dsize AS DOUBLE)
  6.  
  7. DIM SHARED glAllow, textImage AS LONG
  8.  
  9. text$ = "3D Printing in QB64!!"
  10. textImage = _NEWIMAGE(10 + LEN(text$) * _FONTWIDTH, 120) 'this image will be used by OpenGL for creating a 3D Text
  11. _DEST textImage
  12. CLS , _RGB(255, 0, 0)
  13. COLOR _RGB(255, 255, 255), _RGB(255, 0, 0)
  14. _PRINTSTRING (5, 60 - _FONTHEIGHT / 2), text$
  15. _SOURCE textImage
  16. glAllow = -1
  17.  
  18.     _LIMIT 40
  19.  
  20. SUB _GL () STATIC
  21.     IF NOT glAllow THEN EXIT SUB
  22.  
  23.     _glEnable _GL_DEPTH_TEST
  24.     _glEnable _GL_LIGHTING
  25.     _glEnable _GL_LIGHT0
  26.  
  27.  
  28.     _glMatrixMode _GL_PROJECTION
  29.     _gluPerspective 45.0, _WIDTH / _HEIGHT, 1, 1000
  30.  
  31.     _glMatrixMode _GL_MODELVIEW
  32.     gluLookAt 0, 0, 2, 0, 0, 0, 0, 1, 0
  33.     _glColor3f 1, 1, 1
  34.  
  35.     _glRotatef clock# * 60, .2, 1, 0
  36.     'reading source image
  37.     FOR y = 0 TO _HEIGHT(textImage) - 1
  38.         FOR x = 0 TO _WIDTH(textImage) - 1
  39.             c~& = POINT(x, y) 'reading the pixels
  40.             IF c~& = _RGB(255, 255, 255) THEN 'if color is white
  41.                 xx = map(map(x, 0, 160, 0, 800), 0, 800, -1, 1) 'mapping QB64 coordinate to OpenGL coordinate
  42.                 yy = map(map(y, 0, 120, 0, 600), 0, 600, 1, -1)
  43.                 _glPushMatrix
  44.                 _glTranslatef xx, yy, 0 'moving to x,y coordinate, z is 0
  45.                 glutSolidCube .018 'drawing a cube at that point of size 0.018
  46.                 _glPopMatrix
  47.             END IF
  48.         NEXT
  49.     NEXT
  50.  
  51.     _glFlush
  52.     clock# = clock# + .01
  53. 'functions which are below are taken from p5js.bas
  54. 'https://bit.ly/p5jsbas
  55.  
  56. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  57.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  58.  
  59.  
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: "Real" 3D Rendering
« Reply #23 on: November 25, 2019, 09:28:23 am »
;-) yeah GL, thanks Ashish but I was looking for math foundations of 3D specially use of vectors.

I am wondering if STxAxTIC has ideas for clothing our bare wire frame cube or if _MAPTRIANGLE is good enough?

I am thinking it should be worked back to front so back work doesn't cover front work through our peep hole, a sort of points by Z?

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: "Real" 3D Rendering
« Reply #24 on: November 25, 2019, 09:51:13 pm »
Hi all,

Nice as usual Ashish. I think if we were, like, 100% serious about just getting 3D on screen and asking no further questions, _GL would be on everyone's tongue. I do wonder if sometimes I'm leading people like a dark pied piper down the road of doing things the "hard way", but I digress. Nice work.

So bplus... great question, you're always a step ahead, and in this case, a few steps ahead of what I've got written on this... But i'll say what I can real quick.

It suffices to make everything in a 3D world out of 2D triangular panels that sew together to make coherent skins and textures - its an absolutely perfect application for maptriangle. There's some subtlety though in how you define the triangles in the first place. It's all about having the data right, and then the algorithm will be easy.

Are you familiar with the vector cross product and the right hand rule? 'Cuz it matters... To define a triangle one needs just a basepoint and two vectors that define the extent and orientation of the triangle, correct? So when it comes time to define the triangle in an array or whatever, which side do you define first? Does that even matter? Yup. Keep on hanging on...

Consider two vectors X and Y as shown in the plane of your screen:

Y
|
|
|______X

... And pretend that's one of your triangles that's part of a 3D scene. Now calculate the cross product between the two vectors. If I calculate X cross Y, the result will be a vector Z that points out of my screen. On the other hand, Y cross X results in a vector pointing into the screen.

Now pretend you've created a simple-enough 3D object out of triangles (like a car). There is absolutely no need to Z-sort in order to make sure the front faces cover the back faces at rendering time. Instead, you can calculate which triangles are facing the camera, vs which triangles are facing away. For the ones facing away, skip them entirely and don't draw them. You'd never see them anyway.

So *how* does one tell whether a triangle is facing toward or away? You *should* define all of your 3D objects using triangles whose sides, when you take the cross product, results in a vector that points away from the object. (Read this all twice if you must, I wish I had the time to explain this with pictures.) Then, at render time, you compute that so-called Z vector, and take its dot product with the screen normal vector. That'll give you a number, and depending on whether its positive or negative, tells you whether the triangle is visible.

So far so good?

Z (a whole different use of the letter Z in this context) sorting finally comes in once you have the list of visible triangles. We don't want to sort the invisible ones though.

I haven't implemented this since rewriting Sanctum and will probably convert that demo into a textured one at some point. I do have working examples of this on request, but the code embarrasses me, haha.
« Last Edit: November 25, 2019, 10:03:38 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: "Real" 3D Rendering
« Reply #25 on: November 25, 2019, 11:23:58 pm »
Hi STxAxTIC,

Ewh! That will take a couple of rereads but glad we don't have to sort by z points, finding which faces in which direction is interesting. sides, vectors, points, triangle that "point out" from object? Oh, you must mean the plane, so we want the perpendicular to the triangle plane, yeah those point inward or outward. OK?

Oh, I was curious, any comments on needing to use negative FOVD to get the points into the correct quadrants? I know there is a flip flop like what a lens does to light rays in the eye and assume something similar with our peep hole.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: "Real" 3D Rendering
« Reply #26 on: November 25, 2019, 11:54:05 pm »
Oh man, sorry about the negative fovd thing.

In my sketch, the observer's eye (like your actual eye) is behind the screen, making that distance negative. It's really just a convention. If you want that positive, flip all other z's somewhere else, or something similar. Not a big deal in the end.
You're not done when it works, you're done when it's right.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: "Real" 3D Rendering
« Reply #27 on: November 26, 2019, 12:03:41 am »
I totally agree with you guys... I know how to make things in 3D using OpenGL but I almost don't know the math behind it. Knowing such thing will be helpful for collision detection of 3D things on 2D screen with cursor (which are used in 3D shooting games). :)
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: "Real" 3D Rendering
« Reply #28 on: November 30, 2019, 12:06:42 pm »
Hi STxAxTIC,

I had to watch some vector tutorial videos in my native language to understand what you're talking about. So the problem of rendering outlying areas solves vector multiplication by the vector, and the result is a new, perpendicular vector in the Z axis. I will continue to study it. Then with thumb of right hand shows direction this new vector! And speaking of it. STxAxTIC, do you remember my function using a scalar product that returns an angle between 2 vectors? You argued that this function was wrong, because the result is a maximum of 180 degrees. I was looking for a my bug. Then I learned that only the smallest possible angle is always used, so COS fi is always the smaller angle. This means that its value can actually be up to 180 degrees (never more than 180 degrees)!
You didn't know? :)