Author Topic: 3D OpenWorld Mountains  (Read 664 times)

Offline Pete

  • Cuz I sez so, varmint!
Re: 3D OpenWorld Mountains
« Reply #15 on: March 10, 2019, 03:31:21 PM »
@Pete
why do you hate SpaceBalls?

Ha Ha, the Star Wars spoof. "My brains are rushing to my feeeeeeeeet!"

Why do I hate Star Wars? I'll explain it here..

https://www.tapatalk.com/groups/qbasic/viewtopic.php?f=183705&t=39457

Offline johnno56

  • Live long and prosper.
Re: 3D OpenWorld Mountains
« Reply #16 on: March 10, 2019, 11:15:14 PM »
You probably have already guessed that "I" am a Trekkie as well.... I do not hate Star Warts... I think of it like this... Star Trek is royalty; Star Warts is the court jester. It makes me laugh... and don't we ALL need to laugh? lol
Logic is the beginning of wisdom.

Offline Ashish

  • The joy of coding is endless.
Re: 3D OpenWorld Mountains
« Reply #17 on: March 14, 2019, 10:36:14 AM »
@Pete
Oh! I see... Starwars. I rarely watch Hollywood movies. Last time, I saw Spider-Man (I don't remember the part). I know that these movies might be good but they seem a bit unrealistic (to me). My all friends have watched it. They all say that I am "rare".
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories

Offline Jack002

  • Boss, l wanna talk about arrays
Re: 3D OpenWorld Mountains
« Reply #18 on: March 14, 2019, 02:49:48 PM »
Firefly is better than either
QB64 is the best!

Offline Petr

  • The best code is the DNA of the hops.
Re: 3D OpenWorld Mountains
« Reply #19 on: March 14, 2019, 03:51:57 PM »
The best movie of all time (for me) is definitely not Star Wars but a Back to the future (all 3 parts) :-D

Offline SMcNeill

  • QB64 Developer
Re: 3D OpenWorld Mountains
« Reply #20 on: March 14, 2019, 05:03:28 PM »
The best movie of all time (for me) is definitely not Star Wars but a Back to the future (all 3 parts) :-D

Best movie of all time, for me, would have to be “Unforgiven” by Clint Eastwood.  https://ffilms.org/unforgiven-1992/
« Last Edit: March 14, 2019, 05:04:49 PM by SMcNeill »

Re: 3D OpenWorld Mountains
« Reply #21 on: March 14, 2019, 05:38:01 PM »
Hi
I think that at this moment of my life this is one of the best movies that I have seen.
https://www.youtube.com/watch?v=QRl-LiF1VsU
https://www.youtube.com/watch?v=EBh_m9hx2bE
https://www.youtube.com/watch?v=wBi_W6euny0

Offline Pete

  • Cuz I sez so, varmint!
Re: 3D OpenWorld Mountains
« Reply #22 on: March 14, 2019, 06:04:23 PM »
Hi
I think that at this moment of my life this is one of the best movies that I have seen.
https://www.youtube.com/watch?v=QRl-LiF1VsU
https://www.youtube.com/watch?v=EBh_m9hx2bE
https://www.youtube.com/watch?v=wBi_W6euny0

You really need to get out more!

Hey, don't blame me, the rest of you guys took this waaaaay off-topic. I just provided a link. :D

Pete

Re: 3D OpenWorld Mountains
« Reply #23 on: March 14, 2019, 07:21:18 PM »
@Pete

Quote
You really need to get out more!
No I don't agree I need more time to make something to enjoy just like code in QB64 or type/talk in this community

PS
Quote

1. I told her all her friends were idiots.
2. She told me she told them that, and they told her that I was the idiot.
3.I told her all idiots think other people smarter than them, are idiots.

really did you this syllogism? :D
the idiot person calls idiot the person smarter than himself  :-)

Sorry for the thread

Offline Pete

  • Cuz I sez so, varmint!
Re: 3D OpenWorld Mountains
« Reply #24 on: March 14, 2019, 07:56:19 PM »
You left out the punchline, which goes... And that's why they're idiots!

Argh, some people just don't get convoluted logic. Here's a good example from a dialogue my wife, her friends, and I had in 1982. Wife says to me she is going out with her friends. I tell her, don't go, I'll miss you. She says, well then go with us! I said no. She asked why? I told her, because if I go, I'll miss me too!

Pete

- Sometimes the train goes off the tracks, but times like these, the tracks go with the train.

Offline Ashish

  • The joy of coding is endless.
Re: 3D OpenWorld Mountains
« Reply #25 on: March 17, 2019, 06:13:51 AM »
Hi everyone!

Here are the some changes done to the program -
  • There is a *surprise* in the world. Find it & try to go into that surprising object to get another surprise. If a red mark appears on the map, it means you are closer to the surprise.
  • You can give your feedback about the surprise. But please don't tell the surprise to everyone as it will reduce their excitement.
  • There is a new MOD in the world. It can only be unlocked by finding that mysterious object. Sorry for no tree/animal/alien.
  • Small static water bodies are added. Fixed a bug in map.
  • I will be happy if someone will help me to smooth out bumpiness done by the camera y-point.

Here's the code, enjoy!

Code: QB64 [Select]
  1. '3D OpenWorld Terrain Demo
  2. 'Using Perlin Noise
  3. 'By Ashish Kushwaha
  4.  
  5.  
  6. _TITLE "3D OpenWorld Terrain"
  7. SCREEN _NEWIMAGE(800, 600, 32)
  8.  
  9.  
  10.  
  11. CONST sqrt2 = 2 ^ 0.5
  12. CONST mountHeightMax = 4
  13.  
  14. TYPE vec3
  15.     x AS SINGLE
  16.     y AS SINGLE
  17.     z AS SINGLE
  18.  
  19. TYPE vec2
  20.     x AS SINGLE
  21.     y AS SINGLE
  22.  
  23. TYPE tree
  24.     h AS SINGLE
  25.     POS AS vec3
  26.     mpos AS vec2
  27.  
  28. TYPE camera
  29.     POS AS vec3
  30.     mpos AS vec3
  31.     target AS vec3
  32.  
  33. TYPE blowMIND
  34.     POS AS vec3
  35.     set AS _BYTE
  36.  
  37. DECLARE LIBRARY 'camera control function
  38.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  39.  
  40.  
  41. 'noise function related variables
  42. DIM SHARED perlin_octaves AS SINGLE, perlin_amp_falloff AS SINGLE
  43.  
  44. DIM SHARED mapW, mapH
  45. mapW = 800: mapH = 800 'control the size of the map or world
  46.  
  47. 'Terrain Map related variables
  48. 'terrainData(mapW,mapH) contain elevation data and moistureMap(mapW,mapH) contain moisture data
  49. DIM SHARED terrainMap(mapW, mapH), moistureMap(mapW, mapH), terrainData(mapW, mapH) AS vec3
  50. 'these stored the 3 Dimensional coordinates of the objects. Used as a array buffer with glDrawArrays(). glDrawArrays() is faster than normal glBegin() ... glEnd() for rendering
  51. DIM SHARED mountVert(mapW * mapH * 6) AS SINGLE, mountColor(mapW * mapH * 6), mountNormal(mapW * mapH * 6)
  52.  
  53. 'MODs
  54. DIM SHARED worldMOD
  55.  
  56. 'map
  57. DIM SHARED worldMap&, myLocation& 'stored the 2D Map
  58. worldMap& = _NEWIMAGE(mapW + 300, mapH + 300, 32)
  59. myLocation& = _NEWIMAGE(10, 10, 32)
  60.  
  61. 'surprise
  62. DIM SHARED Surprise AS blowMIND, snowMount
  63.  
  64. 'sky
  65. DIM SHARED worldTextures&(1), worldTextureHandle&(0)
  66. ' worldTextures&(0) = _NEWIMAGE(600, 600, 32)
  67. ' FOR i = 1 TO 5: worldTextures&(i) = _NEWIMAGE(200, 200, 32): NEXT
  68. tmp& = _LOADIMAGE("internal/source/qbicon32.png")
  69. worldTextures&(1) = _NEWIMAGE(32, 32, 32) '3 32's
  70. _PUTIMAGE (0, 32)-(32, 0), tmp&, worldTextures&(1)
  71.  
  72. _DEST worldMap&
  73. CLS , _RGB(0, 0, 255)
  74. 'The reason of commenting down below code is given on line number -    279
  75. '_DEST skyTextures&(0)
  76. 'CLS , _RGB(109, 164, 255)
  77. 'FOR y = 0 TO _HEIGHT - 1
  78. '    FOR x = 0 TO _WIDTH - 1
  79. '        noiseDetail 5, 0.5
  80. '        k! = (ABS(noise(x * 0.04, y * 0.04, x / y * 0.01)) * 1.3) ^ 3
  81. '        PSET (x, y), _RGBA(255, 255, 255, k! * 255)
  82. 'NEXT x, y
  83. 'skyW = _WIDTH(skyTextures&(0))
  84. 'skyH = _HEIGHT(skyTextures&(0))
  85. '_PUTIMAGE (0, 0), 0, skyTextures&(1), (skyW / 3, 0)-STEP(skyW / 3, skyH / 3) 'back or rear
  86. '_PUTIMAGE (0, 0), 0, skyTextures&(2), (0, skyH / 3)-STEP(skyW / 3, skyH / 3) 'left
  87. '_PUTIMAGE (0, 0), 0, skyTextures&(3), (skyW / 3, skyH / 3)-STEP(skyW / 3, skyH / 3) 'up
  88. '_PUTIMAGE (0, 0), 0, skyTextures&(4), (2 * (skyW / 3), skyH / 3)-STEP(skyW / 3, skyH / 3) 'right
  89. '_PUTIMAGE (0, 0), 0, skyTextures&(5), (skyW / 3, 2 * (skyH / 3))-STEP(skyW / 3, skyH / 3) 'front
  90. '_DEST 0
  91.  
  92. 'camera
  93. DIM SHARED Cam AS camera, theta, phi
  94.  
  95.  
  96. DIM SHARED glAllow AS _BYTE
  97. _DEST myLocation& 'Generating the blip icon
  98. FOR i = 0 TO 10
  99.     FOR j = 0 TO 10
  100.         READ cx
  101.         IF cx = 1 THEN PSET (j, i), _RGB(255, 0, 200)
  102. NEXT j, i
  103. 'image data of blip icon
  104. DATA 0,0,0,0,0,1,0,0,0,0,0
  105. DATA 0,0,0,0,0,1,0,0,0,0,0
  106. DATA 0,0,0,0,1,1,1,0,0,0,0
  107. DATA 0,0,0,1,1,1,1,1,0,0,0
  108. DATA 0,0,0,1,1,1,1,1,0,0,0
  109. DATA 0,0,1,1,1,1,1,1,1,0,0
  110. DATA 0,1,1,1,1,1,1,1,1,1,0
  111. DATA 0,1,1,1,1,1,1,1,1,1,0
  112. DATA 1,1,1,1,0,0,0,1,1,1,1
  113. DATA 1,1,0,0,0,0,0,0,0,1,1
  114. DATA 1,0,0,0,0,0,0,0,0,0,1
  115. DATA 0,0,0,0,0,0,0,0,0,0,0
  116.  
  117.  
  118. 'Map elevations and mositure calculation done here with the help of perlin noise
  119. _TITLE "Generating World..."
  120. freq = 1
  121. FOR y = 0 TO mapH
  122.     FOR x = 0 TO mapW
  123.         nx = x * 0.01
  124.         ny = y * 0.01
  125.         noiseDetail 2, 0.4
  126.         v! = ABS(noise(nx * freq, ny * freq, 0)) * 1.5 + ABS(noise(nx * freq * 4, ny * freq * 4, 0)) * .25
  127.         v! = v! ^ (3.9)
  128.         elev = v! * 255
  129.         noiseDetail 2, 0.4
  130.         m! = ABS(noise(nx * 2, ny * 2, 0))
  131.         m! = m! ^ 1.4
  132.  
  133.         ' PSET (x + mapW, y), _RGB(0, 0, m! * 255)
  134.         moistureMap(x, y) = m!
  135.  
  136.         ' PSET (x, y), _RGB(elev, elev, elev)
  137.         terrainMap(x, y) = (elev / 255) * mountHeightMax
  138.         terrainData(x, y).x = map(x, 0, mapW, -mapW * 0.04, mapW * 0.04)
  139.         terrainData(x, y).y = terrainMap(x, y)
  140.         terrainData(x, y).z = map(y, 0, mapH, -mapH * 0.04, mapH * 0.04)
  141.  
  142.         setMountColor x, y, 0, (elev / 255) * mountHeightMax, mountHeightMax
  143.         clr~& = _RGB(mountColor(0) * 255, mountColor(1) * 255, mountColor(2) * 255)
  144.         PSET (x, y), clr~&
  145.         _DEST worldMap&
  146.         PSET (x + 150, y + 150), clr~&
  147.         _DEST 0
  148.  
  149.         IF terrainMap(x, y) <= 0.3 * mountHeightMax AND RND > 0.99993 AND Surprise.set = 0 THEN
  150.             Surprise.POS = terrainData(x, y)
  151.             ' line(x-2,y-2)-step(4,4),_rgb(255,0,0),bf
  152.             Surprise.set = 1
  153.             sx = x: sy = y
  154.         END IF
  155.  
  156.     NEXT x
  157.  
  158.     'CLS
  159.     'PRINT "Generating World..."
  160.     'need to show a catchy progress bar
  161.     FOR j = 0 TO map(y, 0, mapH - 1, 0, _WIDTH - 1): LINE (j, _HEIGHT - 6)-(j, _HEIGHT - 1), hsb~&(map(j, 0, _WIDTH - 1, 0, 255), 255, 128, 255): NEXT j
  162.     _DISPLAY
  163. ' _TITLE "3D OpenWorld Mountails [Hit SPACE to switch between MODs]"
  164. _DEST worldMap&
  165. LINE (sx - 3 + 150, sy - 3 + 150)-STEP(6, 6), _RGB(255, 0, 0), BF
  166. generateTerrainData
  167. PRINT "Hit Enter To Step In The World."
  168. PRINT "Map size : "; (mapH * mapW * 24) / 1024; " kB"
  169.  
  170. glAllow = -1
  171.     theta = (_MOUSEX / _WIDTH) * _PI(2.5) 'controls x-axis rotation
  172.     phi = map(_MOUSEY, 0, _HEIGHT, -_PI(0), _PI(0.5)) 'controls y-axis rotation
  173.  
  174.     IF Cam.mpos.z > mapH - 2 THEN Cam.mpos.z = mapH - 2 'prevent reaching out of the world map
  175.     IF Cam.mpos.x > mapW - 2 THEN Cam.mpos.x = mapW - 2 '
  176.     IF Cam.mpos.z < 2 THEN Cam.mpos.z = 2 '
  177.     IF Cam.mpos.x < 2 THEN Cam.mpos.x = 2 '
  178.  
  179.     IF _KEYDOWN(ASC("w")) OR _KEYDOWN(ASC("W")) THEN 'forward movement based on y-axis rotation
  180.         Cam.mpos.z = Cam.mpos.z + SIN(theta) * 0.3: Cam.mpos.x = Cam.mpos.x + COS(theta) * 0.3
  181.     END IF
  182.     IF _KEYDOWN(ASC("s")) OR _KEYDOWN(ASC("S")) THEN ' backward movement based on y-axis rotation
  183.         Cam.mpos.z = Cam.mpos.z - SIN(theta) * 0.3: Cam.mpos.x = Cam.mpos.x - COS(theta) * 0.3
  184.     END IF
  185.     IF _KEYDOWN(ASC("a")) OR _KEYDOWN(ASC("A")) THEN 'left movement based on y-axis rotation
  186.         Cam.mpos.z = Cam.mpos.z + SIN(theta - _PI(0.5)) * 0.3: Cam.mpos.x = Cam.mpos.x + COS(theta - _PI(0.5)) * 0.3
  187.     END IF
  188.     IF _KEYDOWN(ASC("d")) OR _KEYDOWN(ASC("D")) THEN 'right movement based on y-axis rotation
  189.         Cam.mpos.z = Cam.mpos.z + SIN(theta + _PI(0.5)) * 0.3: Cam.mpos.x = Cam.mpos.x + COS(theta + _PI(0.5)) * 0.3
  190.     END IF
  191.  
  192.     IF _KEYHIT = ASC(" ") THEN 'switching between MODs
  193.         IF worldMOD = 2 OR worldMOD = 3 THEN worldMOD = 0 ELSE worldMOD = worldMOD + 1
  194.     END IF
  195.  
  196.     CLS , 1 'clear the screen and make it transparent so that GL context not get hidden.
  197.     _LIMIT 60
  198.  
  199.     'rotation of world causes rotation of map too. calculation of the source points of map is done below
  200.     sx1 = COS(_PI(.75) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy1 = SIN(_PI(.75) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  201.     sx2 = COS(_PI(1.25) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy2 = SIN(_PI(1.25) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  202.     sx3 = COS(_PI(1.75) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy3 = SIN(_PI(1.75) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  203.     sx4 = COS(_PI(2.25) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy4 = SIN(_PI(2.25) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  204.     'displaying the minimap
  205.     _MAPTRIANGLE (sx3, sy3)-(sx4, sy4)-(sx2, sy2), worldMap& TO(0, _HEIGHT - 150 * sqrt2)-(150 * sqrt2, _HEIGHT - 150 * sqrt2)-(0, _HEIGHT - 1)
  206.     _MAPTRIANGLE (sx2, sy2)-(sx4, sy4)-(sx1, sy1), worldMap& TO(0, _HEIGHT - 1)-(150 * sqrt2, _HEIGHT - 150 * sqrt2)-(150 * sqrt2, _HEIGHT - 1)
  207.     'showing your location
  208.     _PUTIMAGE (75 * sqrt2, _HEIGHT - 75 * sqrt2)-STEP(10, 10), myLocation&
  209.     'drawing red border along the map make it attractive
  210.     LINE (1, _HEIGHT - 150 * sqrt2)-STEP(150 * sqrt2, 150 * sqrt2), _RGB(255, 0, 0), B
  211.     _DISPLAY
  212.    
  213.     IF snowMount = 1 THEN
  214.         FOR i = 1 TO UBOUND(mountVert) STEP 3
  215.             setMountColor 0, 0, i - 1, mountVert(i), mountHeightMax
  216.         NEXT
  217.         snowMount = 2
  218.     END IF
  219.  
  220.  
  221. SUB _GL () STATIC
  222.  
  223.     IF glAllow = 0 THEN EXIT SUB 'we are not ready yet
  224.  
  225.     IF NOT glSetup THEN
  226.         glSetup = -1
  227.         _GLVIEWPORT 0, 0, _WIDTH, _HEIGHT 'define our rendering area
  228.  
  229.         aspect# = _WIDTH / _HEIGHT 'used to create perspective view
  230.  
  231.         rad = 1 'distance of camera from origin (0,0,0)
  232.         farPoint = 1.0 'far point of camera target
  233.  
  234.         'initialize camera
  235.         Cam.mpos.x = mapW / 2
  236.         Cam.mpos.z = mapH / 2
  237.         Cam.mpos.y = 8
  238.         'initialize textures for sky
  239.         FOR i = 1 TO UBOUND(worldTextures&)
  240.             _GLGENTEXTURES 1, _OFFSET(worldTextureHandle&(i - 1))
  241.  
  242.             DIM m AS _MEM
  243.             m = _MEMIMAGE(worldTextures&(i))
  244.  
  245.             _GLBINDTEXTURE _GL_TEXTURE_2D, worldTextureHandle&(i - 1)
  246.             _GLTEXIMAGE2D _GL_TEXTURE_2D, 0, _GL_RGB, _WIDTH(worldTextures&(i)), _HEIGHT(worldTextures&(i)), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  247.  
  248.             _MEMFREE m
  249.  
  250.             _GLTEXPARAMETERI _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  251.             _GLTEXPARAMETERI _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  252.             _FREEIMAGE worldTextures&(i)
  253.         NEXT
  254.     END IF
  255.  
  256.     IF worldMOD = 0 THEN _GLCLEARCOLOR 0.7, 0.8, 1.0, 1.0 'this makes the background look sky blue.
  257.     IF worldMOD = 1 THEN _GLCLEARCOLOR 0.031, 0.0, 0.307, 1.0 'night sky
  258.     IF worldMOD = 2 THEN _GLCLEARCOLOR 0.0, 0.0, 0.0, 1.0
  259.     IF worldMOD = 3 THEN
  260.         v~& = hsb~&(clock# MOD 255, 255, 128, 255)
  261.         kR = _RED(v~&) / 255: kG = _GREEN(v~&) / 255: kB = _BLUE(v~&) / 255
  262.         _GLCLEARCOLOR kR, kG, kB, 1
  263.     END IF
  264.     _GLCLEAR _GL_COLOR_BUFFER_BIT
  265.  
  266.     _GLENABLE _GL_DEPTH_TEST 'Of course, we are going to do 3D
  267.     _GLCLEARDEPTH 10.0
  268.  
  269.     _GLENABLE _GL_TEXTURE_2D 'so that we can use texture for our sky. :)
  270.  
  271.     IF worldMOD <> 2 THEN
  272.         _GLENABLE _GL_LIGHTING 'Without light, everything dull.
  273.         _GLENABLE _GL_LIGHT0
  274.     END IF
  275.  
  276.     IF worldMOD = 1 THEN
  277.         'night MOD
  278.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(0.05, 0.05, 0.33, 0)
  279.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.55, 0.55, 0.78, 0)
  280.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(0.75, 0.75, 0.98, 0)
  281.     ELSEIF worldMOD = 0 THEN
  282.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(0.35, 0.35, 0.33, 0) 'gives a bit yellowing color to the light
  283.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.75, 0.75, 0.60, 0) 'so it will feel like sun is in the sky
  284.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(0.95, 0.95, 0.80, 0)
  285.     ELSEIF worldMOD = 3 THEN 'disco light
  286.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(kR / 2, kG / 2, kB / 2, 0)
  287.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(kR * 0.9, kG * 0.9, kB * 0.9, 0)
  288.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(kR, kG, kB, 0)
  289.     END IF
  290.     _GLSHADEMODEL _GL_SMOOTH 'to make the rendering smooth
  291.  
  292.     _GLMATRIXMODE _GL_PROJECTION
  293.     _GLUPERSPECTIVE 70, aspect#, 0.01, 15.0 'set up out perpective
  294.  
  295.     _GLMATRIXMODE _GL_MODELVIEW
  296.  
  297.     IF Cam.mpos.y > (terrainMap(Cam.mpos.x, Cam.mpos.z)) THEN Cam.mpos.y = Cam.mpos.y - 0.03 ELSE Cam.mpos.y = (terrainMap(Cam.mpos.x, Cam.mpos.z)) 'if you are in air then you must fall.
  298.  
  299.     'calculation of camera eye, its target, etc...
  300.     Cam.target.y = Cam.POS.y * COS(phi)
  301.     Cam.target.x = Cam.POS.x + COS(theta) * farPoint
  302.     Cam.target.z = Cam.POS.z + SIN(theta) * farPoint
  303.  
  304.     Cam.POS.x = map(Cam.mpos.x, 0, mapW, -mapW * 0.04, mapW * 0.04)
  305.     Cam.POS.z = map(Cam.mpos.z, 0, mapH, -mapH * 0.04, mapH * 0.04)
  306.     Cam.POS.y = Cam.mpos.y + 0.3
  307.  
  308.     gluLookAt Cam.POS.x, Cam.POS.y, Cam.POS.z, Cam.target.x, Cam.target.y, Cam.target.z, 0, 1, 0
  309.  
  310.  
  311.     'use of this skybox was avoided by me because I believe that it makes the scene a bit unrealistic.
  312.     ' skybox 5.0
  313.  
  314.     ' draw the world
  315.     _GLENABLE _GL_COLOR_MATERIAL
  316.     _GLCOLORMATERIAL _GL_FRONT, _GL_AMBIENT_AND_DIFFUSE
  317.  
  318.     _GLENABLECLIENTSTATE _GL_VERTEX_ARRAY
  319.     _GLVERTEXPOINTER 3, _GL_FLOAT, 0, _OFFSET(mountVert())
  320.     _GLENABLECLIENTSTATE _GL_COLOR_ARRAY
  321.     _GLCOLORPOINTER 3, _GL_FLOAT, 0, _OFFSET(mountColor())
  322.     _GLENABLECLIENTSTATE _GL_NORMAL_ARRAY
  323.     _GLNORMALPOINTER _GL_FLOAT, 0, _OFFSET(mountNormal())
  324.  
  325.     IF worldMOD = 2 THEN _GLDRAWARRAYS _GL_LINE_STRIP, 0, UBOUND(mountvert) / 3 ELSE _GLDRAWARRAYS _GL_TRIANGLE_STRIP, 0, UBOUND(mountVert) / 3
  326.     _GLDISABLECLIENTSTATE _GL_VERTEX_ARRAY
  327.     _GLDISABLECLIENTSTATE _GL_COLOR_ARRAY
  328.     _GLDISABLECLIENTSTATE _GL_NORMAL_ARRAY
  329.    
  330.     _GLDISABLE _GL_LIGHTING
  331.     IF worldMOD <> 3 AND snowMount <> 2 THEN showSurprise 0.4, Cam.POS
  332.  
  333.     _GLFLUSH
  334.    
  335.     clock# = clock# + .5
  336.  
  337. SUB showSurprise (s, a AS vec3)
  338.     IF a.x > Surprise.POS.x - s AND a.x < Surprise.POS.x + s AND a.z > Surprise.POS.z - s AND a.z < Surprise.POS.z + s THEN
  339.         IF RND > 0.5 THEN
  340.             worldMOD = 3
  341.             _TITLE "You finally came to know that its QB64 Island!!"
  342.         ELSE
  343.             snowMount = 1
  344.             _TITLE "Welcome to this new world..."
  345.             Cam.mpos.y = 6
  346.         END IF
  347.     END IF
  348.    
  349.     _GLBINDTEXTURE _GL_TEXTURE_2D, worldTextureHandle&(0)
  350.  
  351.     _GLBEGIN _GL_QUADS
  352.     _GLTEXCOORD2F 0, 1
  353.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s 'front
  354.     _GLTEXCOORD2F 0, 0
  355.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s
  356.     _GLTEXCOORD2F 1, 0
  357.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  358.     _GLTEXCOORD2F 1, 1
  359.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  360.     _GLEND
  361.  
  362.     _GLBEGIN _GL_QUADS
  363.     _GLTEXCOORD2F 0, 1
  364.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'rear
  365.     _GLTEXCOORD2F 0, 0
  366.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  367.     _GLTEXCOORD2F 1, 0
  368.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  369.     _GLTEXCOORD2F 1, 1
  370.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  371.     _GLEND
  372.  
  373.     _GLBEGIN _GL_QUADS
  374.     _GLTEXCOORD2F 1, 0
  375.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'left
  376.     _GLTEXCOORD2F 0, 0
  377.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  378.     _GLTEXCOORD2F 0, 1
  379.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s
  380.     _GLTEXCOORD2F 1, 1
  381.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  382.     _GLEND
  383.  
  384.     _GLBEGIN _GL_QUADS
  385.     _GLTEXCOORD2F 1, 0
  386.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'right
  387.     _GLTEXCOORD2F 0, 0
  388.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  389.     _GLTEXCOORD2F 0, 1
  390.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  391.     _GLTEXCOORD2F 1, 1
  392.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  393.     _GLEND
  394.  
  395.     _GLBEGIN _GL_QUADS 'up
  396.     _GLTEXCOORD2F 0, 1
  397.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s 'up
  398.     _GLTEXCOORD2F 0, 0
  399.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  400.     _GLTEXCOORD2F 1, 0
  401.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  402.     _GLTEXCOORD2F 1, 1
  403.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  404.     _GLEND
  405.    
  406.     _GLBEGIN _GL_QUADS 'down
  407.     _GLTEXCOORD2F 0, 1
  408.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s 'up
  409.     _GLTEXCOORD2F 0, 0
  410.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  411.     _GLTEXCOORD2F 1, 0
  412.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  413.     _GLTEXCOORD2F 1, 1
  414.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  415.     _GLEND
  416.  
  417.  
  418. 'draws a beautiful sky
  419. SUB skybox (s)
  420.     _GLDISABLE _GL_LIGHTING
  421.     _GLDISABLE _GL_LIGHT0
  422.     _GLDISABLE _GL_DEPTH_TEST
  423.     _GLDEPTHMASK _GL_FALSE
  424.  
  425.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(4)
  426.  
  427.     _GLBEGIN _GL_QUADS
  428.     _GLTEXCOORD2F 0, 1
  429.     _GLVERTEX3F -s, s, -s 'front
  430.     _GLTEXCOORD2F 0, 0
  431.     _GLVERTEX3F -s, -s, -s
  432.     _GLTEXCOORD2F 1, 0
  433.     _GLVERTEX3F s, -s, -s
  434.     _GLTEXCOORD2F 1, 1
  435.     _GLVERTEX3F s, s, -s
  436.     _GLEND
  437.  
  438.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(0)
  439.     _GLBEGIN _GL_QUADS
  440.     _GLTEXCOORD2F 0, 1
  441.     _GLVERTEX3F -s, s, s 'rear
  442.     _GLTEXCOORD2F 0, 0
  443.     _GLVERTEX3F -s, -s, s
  444.     _GLTEXCOORD2F 1, 0
  445.     _GLVERTEX3F s, -s, s
  446.     _GLTEXCOORD2F 1, 1
  447.     _GLVERTEX3F s, s, s
  448.     _GLEND
  449.    
  450.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(1)
  451.     _GLBEGIN _GL_QUADS
  452.     _GLTEXCOORD2F 1, 0
  453.     _GLVERTEX3F -s, s, s 'left
  454.     _GLTEXCOORD2F 0, 0
  455.     _GLVERTEX3F -s, -s, s
  456.     _GLTEXCOORD2F 0, 1
  457.     _GLVERTEX3F -s, -s, -s
  458.     _GLTEXCOORD2F 1, 1
  459.     _GLVERTEX3F -s, s, -s
  460.     _GLEND
  461.    
  462.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(3)
  463.     _GLBEGIN _GL_QUADS
  464.     _GLTEXCOORD2F 1, 0
  465.     _GLVERTEX3F s, s, s 'right
  466.     _GLTEXCOORD2F 0, 0
  467.     _GLVERTEX3F s, -s, s
  468.     _GLTEXCOORD2F 0, 1
  469.     _GLVERTEX3F s, -s, -s
  470.     _GLTEXCOORD2F 1, 1
  471.     _GLVERTEX3F s, s, -s
  472.     _GLEND
  473.  
  474.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(2)
  475.     _GLBEGIN _GL_QUADS
  476.     _GLTEXCOORD2F 0, 1
  477.     _GLVERTEX3F -s, s, -s 'up
  478.     _GLTEXCOORD2F 0, 0
  479.     _GLVERTEX3F -s, s, s
  480.     _GLTEXCOORD2F 1, 0
  481.     _GLVERTEX3F s, s, s
  482.     _GLTEXCOORD2F 1, 1
  483.     _GLVERTEX3F s, s, -s
  484.     _GLEND
  485.    
  486.     _GLDEPTHMASK _GL_TRUE
  487.     _GLENABLE _GL_DEPTH_TEST
  488.     _GLENABLE _GL_LIGHTING
  489.     _GLENABLE _GL_LIGHT0
  490.  
  491. SUB setMountColor (xi, yi, i, h, h_max) 'assign color on the basis of height map and moisture map.
  492.     IF snowMount = 1 THEN
  493.         IF h > 0.8 * h_max THEN mountColor(i) = 0.439: mountColor(i + 1) = 0.988: mountColor(i + 2) = 0.988: EXIT SUB
  494.         mountColor(i) = 1: mountColor(i + 1) = 1: mountColor(i + 2) = 1
  495.         EXIT SUB
  496.     END IF
  497.     IF h > 0.8 * h_max THEN
  498.         IF moistureMap(xi, yi) < 0.1 THEN mountColor(i) = 0.333: mountColor(i + 1) = 0.333: mountColor(i + 2) = 0.333: EXIT SUB 'scorched
  499.         IF moistureMap(xi, yi) < 0.2 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.533: EXIT SUB 'bare
  500.         IF moistureMap(xi, yi) < 0.5 THEN mountColor(i) = 0.737: mountColor(i + 1) = 0.737: mountColor(i + 2) = 0.6705: EXIT SUB 'tundra
  501.         mountColor(i) = 0.8705: mountColor(i + 1) = 0.8705: mountColor(i + 2) = 0.898: EXIT SUB 'snow
  502.     END IF
  503.     IF h > 0.6 * h_max THEN
  504.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.788: mountColor(i + 1) = 0.823: mountColor(i + 2) = 0.607: EXIT SUB 'temperate desert
  505.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.466: EXIT SUB 'shrubland
  506.         mountColor(i) = 0.6: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.466: EXIT SUB 'taiga
  507.     END IF
  508.     IF h > 0.3 * h_max THEN
  509.         IF moistureMap(xi, yi) < 0.16 THEN mountColor(i) = 0.788: mountColor(i + 1) = 0.823: mountColor(i + 2) = 0.607: EXIT SUB 'temperate desert
  510.         IF moistureMap(xi, yi) < 0.50 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  511.         IF moistureMap(xi, yi) < 0.83 THEN mountColor(i) = 0.403: mountColor(i + 1) = 0.576: mountColor(i + 2) = 0.349: EXIT SUB 'temperate deciduous forest
  512.         mountColor(i) = 0.262: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.233: EXIT SUB 'temperate rain forest
  513.     END IF
  514.     IF h < 0.01 * h_max THEN mountColor(i) = 0.262: mountColor(i + 1) = 0.262: mountColor(i + 2) = 0.478: EXIT SUB 'ocean
  515.     IF h < 0.07 * h_max THEN mountColor(i) = 0.627: mountColor(i + 1) = 0.568: mountColor(i + 2) = 0.466: EXIT SUB 'beach
  516.     IF h <= 0.3 * h_max THEN
  517.         IF moistureMap(xi, yi) < 0.16 THEN mountColor(i) = 0.823: mountColor(i + 1) = 0.725: mountColor(i + 2) = 0.545: EXIT SUB 'subtropical desert
  518.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  519.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.337: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.266: EXIT SUB 'tropical seasonal forest
  520.         mountColor(i) = 0.2: mountColor(i + 1) = 0.466: mountColor(i + 2) = 0.333: EXIT SUB 'tropical rain forest
  521.     END IF
  522.  
  523. SUB generateTerrainData ()
  524.     DIM A AS vec3, B AS vec3, C AS vec3, R AS vec3
  525.     index = 0
  526.  
  527.     '##################################################################################################
  528.     '# Note : The below method consumes more memory. It uses 3x more vertex array than the next one.  #
  529.     '# So, use of this method was avoided by me.                                                      #
  530.     '##################################################################################################
  531.  
  532.     ' _dest _console
  533.     ' FOR z = 0 TO mapH - 1
  534.     ' FOR x = 0 TO mapW - 1
  535.     ' A = terrainData(x, z)
  536.     ' B = terrainData(x, z + 1)
  537.     ' C = terrainData(x + 1, z)
  538.     ' D = terrainData(x+1,z+1)
  539.  
  540.     ' ' ?index
  541.     ' ' OBJ_CalculateNormal A, B, C, R
  542.  
  543.     ' ' mountNormal(index) = R.x : mountNormal(index+1) = R.y : mountNormal(index+2) = R.z
  544.     ' ' mountNormal(index+3) = R.x : mountNormal(index+4) = R.y : mountNormal(index+5) = R.z
  545.     ' ' mountNormal(index+6) = R.x : mountNormal(index+7) = R.y : mountNormal(index+8) = R.z
  546.  
  547.     ' mountVert(index) = A.x : mountVert(index+1) = A.y : mountVert(index+2) = A.z : setMountColor x,z,index, A.y, mountHeightMax
  548.     ' mountVert(index+3) = B.x : mountVert(index+4) = B.y : mountVert(index+5) = B.z :  setMountColor x,z+1,index+3, B.y, mountHeightMax
  549.     ' mountVert(index+6) = C.x : mountVert(index+7) = C.y : mountVert(index+8) = C.z: setMountColor x+1,z,index+6, C.y, mountHeightMax
  550.  
  551.     ' ' OBJ_CalculateNormal C,B,D, R
  552.  
  553.     ' ' mountNormal(index+9) = R.x : mountNormal(index+10) = R.y : mountNormal(index+11) = R.z
  554.     ' ' mountNormal(index+12) = R.x : mountNormal(index+13) = R.y : mountNormal(index+14) = R.z
  555.     ' ' mountNormal(index+15) = R.x : mountNormal(index+16) = R.y : mountNormal(index+17) = R.z
  556.  
  557.     ' mountVert(index+9) = C.x : mountVert(index+10) = C.y : mountVert(index+11) = C.z: setMountColor x+1,z, index+9, C.y, mountHeightMax
  558.     ' mountVert(index+12) = B.x : mountVert(index+13) = B.y : mountVert(index+14) = B.z: setMountColor x,z+1,index+12, B.y, mountHeightMax
  559.     ' mountVert(index+15) = D.x : mountVert(index+16) = D.y : mountVert(index+17) = D.z: setMountColor x+1,z+1,index+15, D.y, mountHeightMax
  560.     ' index = index+18
  561.     ' NEXT x,z
  562.  
  563.     'this method is efficient than the above one.
  564.     DO
  565.         IF z MOD 2 = 0 THEN x = x + 1 ELSE x = x - 1
  566.  
  567.         A = terrainData(x, z) 'get out coordinates from our stored data
  568.         B = terrainData(x, z + 1)
  569.         C = terrainData(x + 1, z)
  570.  
  571.         OBJ_CalculateNormal A, B, C, R 'calculates the normal of a triangle
  572.  
  573.         'store color, coordinate & normal data in an array
  574.         mountNormal(index) = R.x: mountNormal(index + 1) = R.y: mountNormal(index + 2) = R.z
  575.         mountVert(index) = A.x: mountVert(index + 1) = A.y: mountVert(index + 2) = A.z: setMountColor x, z, index, A.y, mountHeightMax
  576.  
  577.         mountNormal(index + 3) = R.x: mountNormal(index + 4) = R.y: mountNormal(index + 5) = R.z
  578.         mountVert(index + 3) = B.x: mountVert(index + 4) = B.y: mountVert(index + 5) = B.z: setMountColor x, z + 1, index + 3, B.y, mountHeightMax
  579.  
  580.         index = index + 6
  581.  
  582.         IF x = mapW - 1 THEN
  583.             IF z MOD 2 = 0 THEN x = x + 1: z = z + 1
  584.         END IF
  585.         IF x = 1 THEN
  586.             IF z MOD 2 = 1 THEN x = x - 1: z = z + 1
  587.         END IF
  588.         IF z = mapH - 1 THEN EXIT DO
  589.     LOOP
  590.     _DEST 0
  591.  
  592. FUNCTION trimDecimal# (num, n%)
  593.     d$ = RTRIM$(STR$(num))
  594.     dd$ = d$
  595.     FOR i = 1 TO LEN(d$)
  596.         cA$ = MID$(d$, i, 1)
  597.         IF foundpoint = 1 THEN k = k + 1
  598.         IF cA$ = "." THEN foundpoint = 1
  599.         IF k = n% THEN dd$ = LEFT$(dd$, i)
  600.     NEXT i
  601.     trimDecimal# = VAL(dd$)
  602.  
  603.  
  604. FUNCTION p5random! (mn!, mx!)
  605.     IF mn! > mx! THEN
  606.         SWAP mn!, mx!
  607.     END IF
  608.     p5random! = RND * (mx! - mn!) + mn!
  609.  
  610.  
  611. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  612.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  613.  
  614. 'coded in QB64 by Fellipe Heitor
  615. 'Can be found in p5js.bas library
  616. 'http://bit.ly/p5jsbas
  617. FUNCTION noise! (x AS SINGLE, y AS SINGLE, z AS SINGLE)
  618.     STATIC p5NoiseSetup AS _BYTE
  619.     STATIC perlin() AS SINGLE
  620.     STATIC PERLIN_YWRAPB AS SINGLE, PERLIN_YWRAP AS SINGLE
  621.     STATIC PERLIN_ZWRAPB AS SINGLE, PERLIN_ZWRAP AS SINGLE
  622.     STATIC PERLIN_SIZE AS SINGLE
  623.  
  624.     IF p5NoiseSetup = 0 THEN
  625.         p5NoiseSetup = 1
  626.  
  627.         PERLIN_YWRAPB = 4
  628.         PERLIN_YWRAP = INT(1 * (2 ^ PERLIN_YWRAPB))
  629.         PERLIN_ZWRAPB = 8
  630.         PERLIN_ZWRAP = INT(1 * (2 ^ PERLIN_ZWRAPB))
  631.         PERLIN_SIZE = 4095
  632.  
  633.         perlin_octaves = 4
  634.         perlin_amp_falloff = 0.5
  635.  
  636.         REDIM perlin(PERLIN_SIZE + 1) AS SINGLE
  637.         DIM i AS SINGLE
  638.         FOR i = 0 TO PERLIN_SIZE + 1
  639.             perlin(i) = RND
  640.         NEXT
  641.     END IF
  642.  
  643.     x = ABS(x)
  644.     y = ABS(y)
  645.     z = ABS(z)
  646.  
  647.     DIM xi AS SINGLE, yi AS SINGLE, zi AS SINGLE
  648.     xi = INT(x)
  649.     yi = INT(y)
  650.     zi = INT(z)
  651.  
  652.     DIM xf AS SINGLE, yf AS SINGLE, zf AS SINGLE
  653.     xf = x - xi
  654.     yf = y - yi
  655.     zf = z - zi
  656.  
  657.     DIM r AS SINGLE, ampl AS SINGLE, o AS SINGLE
  658.     r = 0
  659.     ampl = .5
  660.  
  661.     FOR o = 1 TO perlin_octaves
  662.         DIM of AS SINGLE, rxf AS SINGLE
  663.         DIM ryf AS SINGLE, n1 AS SINGLE, n2 AS SINGLE, n3 AS SINGLE
  664.         of = xi + INT(yi * (2 ^ PERLIN_YWRAPB)) + INT(zi * (2 ^ PERLIN_ZWRAPB))
  665.  
  666.         rxf = 0.5 * (1.0 - COS(xf * _PI))
  667.         ryf = 0.5 * (1.0 - COS(yf * _PI))
  668.  
  669.         n1 = perlin(of AND PERLIN_SIZE)
  670.         n1 = n1 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n1)
  671.         n2 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  672.         n2 = n2 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n2)
  673.         n1 = n1 + ryf * (n2 - n1)
  674.  
  675.         of = of + PERLIN_ZWRAP
  676.         n2 = perlin(of AND PERLIN_SIZE)
  677.         n2 = n2 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n2)
  678.         n3 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  679.         n3 = n3 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n3)
  680.         n2 = n2 + ryf * (n3 - n2)
  681.  
  682.         n1 = n1 + (0.5 * (1.0 - COS(zf * _PI))) * (n2 - n1)
  683.  
  684.         r = r + n1 * ampl
  685.         ampl = ampl * perlin_amp_falloff
  686.         xi = INT(xi * (2 ^ 1))
  687.         xf = xf * 2
  688.         yi = INT(yi * (2 ^ 1))
  689.         yf = yf * 2
  690.         zi = INT(zi * (2 ^ 1))
  691.         zf = zf * 2
  692.  
  693.         IF xf >= 1.0 THEN xi = xi + 1: xf = xf - 1
  694.         IF yf >= 1.0 THEN yi = yi + 1: yf = yf - 1
  695.         IF zf >= 1.0 THEN zi = zi + 1: zf = zf - 1
  696.     NEXT
  697.     noise! = r
  698.  
  699. SUB noiseDetail (lod!, falloff!)
  700.     IF lod! > 0 THEN perlin_octaves = lod!
  701.     IF falloff! > 0 THEN perlin_amp_falloff = falloff!
  702.  
  703. 'method adapted form http://stackoverflow.com/questions/4106363/converting-rgb-to-hsb-colors
  704. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  705.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  706.  
  707.     H = map(__H, 0, 255, 0, 360)
  708.     S = map(__S, 0, 255, 0, 1)
  709.     B = map(__B, 0, 255, 0, 1)
  710.  
  711.     IF S = 0 THEN
  712.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  713.         EXIT FUNCTION
  714.     END IF
  715.  
  716.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  717.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  718.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  719.  
  720.     IF B > .5 THEN
  721.         fmx = B - (B * S) + S
  722.         fmn = B + (B * S) - S
  723.     ELSE
  724.         fmx = B + (B * S)
  725.         fmn = B - (B * S)
  726.     END IF
  727.  
  728.     iSextant = INT(H / 60)
  729.  
  730.     IF H >= 300 THEN
  731.         H = H - 360
  732.     END IF
  733.  
  734.     H = H / 60
  735.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  736.  
  737.     IF iSextant MOD 2 = 0 THEN
  738.         fmd = (H * (fmx - fmn)) + fmn
  739.     ELSE
  740.         fmd = fmn - (H * (fmx - fmn))
  741.     END IF
  742.  
  743.     imx = _ROUND(fmx * 255)
  744.     imd = _ROUND(fmd * 255)
  745.     imn = _ROUND(fmn * 255)
  746.  
  747.     SELECT CASE INT(iSextant)
  748.         CASE 1
  749.             hsb~& = _RGBA32(imd, imx, imn, A)
  750.         CASE 2
  751.             hsb~& = _RGBA32(imn, imx, imd, A)
  752.         CASE 3
  753.             hsb~& = _RGBA32(imn, imd, imx, A)
  754.         CASE 4
  755.             hsb~& = _RGBA32(imd, imn, imx, A)
  756.         CASE 5
  757.             hsb~& = _RGBA32(imx, imn, imd, A)
  758.         CASE ELSE
  759.             hsb~& = _RGBA32(imx, imd, imn, A)
  760.     END SELECT
  761.  
  762.  
  763.  
  764. SUB OBJ_CalculateNormal (p1 AS vec3, p2 AS vec3, p3 AS vec3, N AS vec3)
  765.     DIM U AS vec3, V AS vec3
  766.  
  767.     U.x = p2.x - p1.x
  768.     U.y = p2.y - p1.y
  769.     U.z = p2.z - p1.z
  770.  
  771.     V.x = p3.x - p1.x
  772.     V.y = p3.y - p1.y
  773.     V.z = p3.z - p1.z
  774.  
  775.     N.x = (U.y * V.z) - (U.z * V.y)
  776.     N.y = (U.z * V.x) - (U.x * V.z)
  777.     N.z = (U.x * V.y) - (U.y * V.x)
  778.     OBJ_Normalize N
  779.  
  780. SUB OBJ_Normalize (V AS vec3)
  781.     mag! = SQR(V.x * V.x + V.y * V.y + V.z * V.z)
  782.     V.x = V.x / mag!
  783.     V.y = V.y / mag!
  784.     V.z = V.z / mag!
  785.  
  786. FUNCTION glVec4%& (x, y, z, w)
  787.     STATIC internal_vec4(3)
  788.     internal_vec4(0) = x
  789.     internal_vec4(1) = y
  790.     internal_vec4(2) = z
  791.     internal_vec4(3) = w
  792.     glVec4%& = _OFFSET(internal_vec4())
  793.  
  794.  
« Last Edit: March 17, 2019, 06:16:13 AM by Ashish »
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories

Re: 3D OpenWorld Mountains
« Reply #26 on: March 17, 2019, 10:55:45 AM »
Hi Ashish,

Found surprise, but confess I had problem on line 77 loading it, so I had to fix the file load to get the new program to work.
Note: I run code from different folders so the path to the file didn't work.

I also ran into a bug, a line through the world, I will show one end and then the other:
 

 
B = B + ...

Offline Petr

  • The best code is the DNA of the hops.
Re: 3D OpenWorld Mountains
« Reply #27 on: March 17, 2019, 02:43:16 PM »
Hi Ashish. I was looking into my old Open World program, where the motion is solved, _gltranslate is used, and _glrotate for rotation. That makes work a lot easier. To tackle camera jumps in the Y axis - I don't want to interfere with your work at all, but I would do it by moving the camera a little above the surface and not reacting by changing the height to small changes in the surface, but only if is big change, camera will jump upper or lower by a larger piece.

Offline Ashish

  • The joy of coding is endless.
Re: 3D OpenWorld Mountains
« Reply #28 on: March 23, 2019, 09:20:24 AM »
Hi everyone!
+Petr
Thanks for suggestion, but I found another way to fix camera problem. Now, the camera y-point is calculated by the mean value of
surrounding area. I believe Pete will now become happy.
+Bplus
I tried the fix that line bug. I ran the program thrice. Didn't found that line again.

Here's the new & updated code -
Code: QB64 [Select]
  1. '3D OpenWorld Terrain Demo
  2. 'Using Perlin Noise
  3. 'By Ashish Kushwaha
  4.  
  5.  
  6. '$CONSOLE
  7.  
  8. _TITLE "3D OpenWorld Terrain"
  9. SCREEN _NEWIMAGE(800, 600, 32)
  10.  
  11.  
  12.  
  13. CONST sqrt2 = 2 ^ 0.5
  14. CONST mountHeightMax = 4
  15.  
  16. TYPE vec3
  17.     x AS SINGLE
  18.     y AS SINGLE
  19.     z AS SINGLE
  20.  
  21. TYPE vec2
  22.     x AS SINGLE
  23.     y AS SINGLE
  24.  
  25. TYPE tree
  26.     h AS SINGLE
  27.     POS AS vec3
  28.     mpos AS vec2
  29.  
  30. TYPE camera
  31.     POS AS vec3
  32.     mpos AS vec3
  33.     target AS vec3
  34.  
  35. TYPE blowMIND
  36.     POS AS vec3
  37.     set AS _BYTE
  38.  
  39. DECLARE LIBRARY 'camera control function
  40.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  41.  
  42.  
  43. 'noise function related variables
  44. DIM SHARED perlin_octaves AS SINGLE, perlin_amp_falloff AS SINGLE
  45.  
  46. DIM SHARED mapW, mapH
  47. mapW = 800: mapH = 800 'control the size of the map or world
  48.  
  49. 'Terrain Map related variables
  50. 'terrainData(mapW,mapH) contain elevation data and moistureMap(mapW,mapH) contain moisture data
  51. DIM SHARED terrainMap(mapW, mapH), moistureMap(mapW, mapH), terrainData(mapW, mapH) AS vec3
  52. 'these stored the 3 Dimensional coordinates of the objects. Used as a array buffer with glDrawArrays(). glDrawArrays() is faster than normal glBegin() ... glEnd() for rendering
  53. DIM SHARED mountVert(mapW * mapH * 6) AS SINGLE, mountColor(mapW * mapH * 6), mountNormal(mapW * mapH * 6)
  54.  
  55. 'MODs
  56. DIM SHARED worldMOD
  57.  
  58. 'map
  59. DIM SHARED worldMap&, myLocation& 'stored the 2D Map
  60. worldMap& = _NEWIMAGE(mapW + 300, mapH + 300, 32)
  61. myLocation& = _NEWIMAGE(10, 10, 32)
  62.  
  63. 'surprise
  64. DIM SHARED Surprise AS blowMIND, snowMount
  65.  
  66. 'sky
  67. DIM SHARED worldTextures&(1), worldTextureHandle&(0)
  68. ' worldTextures&(0) = _NEWIMAGE(600, 600, 32)
  69. ' FOR i = 1 TO 5: worldTextures&(i) = _NEWIMAGE(200, 200, 32): NEXT
  70. tmp& = _LOADIMAGE(WriteqbiconData$("qb.png"))
  71. KILL "qb.png"
  72. worldTextures&(1) = _NEWIMAGE(32, 32, 32) '3 32's
  73. _PUTIMAGE (0, 32)-(32, 0), tmp&, worldTextures&(1)
  74.  
  75. _DEST worldMap&
  76. CLS , _RGB(0, 0, 255)
  77. 'The reason of commenting down below code is given on line number -    279
  78. '_DEST skyTextures&(0)
  79. 'CLS , _RGB(109, 164, 255)
  80. 'FOR y = 0 TO _HEIGHT - 1
  81. '    FOR x = 0 TO _WIDTH - 1
  82. '        noiseDetail 5, 0.5
  83. '        k! = (ABS(noise(x * 0.04, y * 0.04, x / y * 0.01)) * 1.3) ^ 3
  84. '        PSET (x, y), _RGBA(255, 255, 255, k! * 255)
  85. 'NEXT x, y
  86. 'skyW = _WIDTH(skyTextures&(0))
  87. 'skyH = _HEIGHT(skyTextures&(0))
  88. '_PUTIMAGE (0, 0), 0, skyTextures&(1), (skyW / 3, 0)-STEP(skyW / 3, skyH / 3) 'back or rear
  89. '_PUTIMAGE (0, 0), 0, skyTextures&(2), (0, skyH / 3)-STEP(skyW / 3, skyH / 3) 'left
  90. '_PUTIMAGE (0, 0), 0, skyTextures&(3), (skyW / 3, skyH / 3)-STEP(skyW / 3, skyH / 3) 'up
  91. '_PUTIMAGE (0, 0), 0, skyTextures&(4), (2 * (skyW / 3), skyH / 3)-STEP(skyW / 3, skyH / 3) 'right
  92. '_PUTIMAGE (0, 0), 0, skyTextures&(5), (skyW / 3, 2 * (skyH / 3))-STEP(skyW / 3, skyH / 3) 'front
  93. '_DEST 0
  94.  
  95. 'camera
  96. DIM SHARED Cam AS camera, theta, phi
  97.  
  98.  
  99. DIM SHARED glAllow AS _BYTE
  100. RESTORE blipicon
  101. _DEST myLocation& 'Generating the blip icon
  102. FOR i = 0 TO 10
  103.     FOR j = 0 TO 10
  104.         READ cx
  105.         IF cx = 1 THEN PSET (j, i), _RGB(255, 0, 200)
  106. NEXT j, i
  107. 'image data of blip icon
  108. blipicon:
  109. DATA 0,0,0,0,0,1,0,0,0,0,0
  110. DATA 0,0,0,0,0,1,0,0,0,0,0
  111. DATA 0,0,0,0,1,1,1,0,0,0,0
  112. DATA 0,0,0,1,1,1,1,1,0,0,0
  113. DATA 0,0,0,1,1,1,1,1,0,0,0
  114. DATA 0,0,1,1,1,1,1,1,1,0,0
  115. DATA 0,1,1,1,1,1,1,1,1,1,0
  116. DATA 0,1,1,1,1,1,1,1,1,1,0
  117. DATA 1,1,1,1,0,0,0,1,1,1,1
  118. DATA 1,1,0,0,0,0,0,0,0,1,1
  119. DATA 1,0,0,0,0,0,0,0,0,0,1
  120. DATA 0,0,0,0,0,0,0,0,0,0,0
  121.  
  122.  
  123. 'Map elevations and mositure calculation done here with the help of perlin noise
  124. _TITLE "Generating World..."
  125. freq = 1
  126. FOR y = 0 TO mapH
  127.     FOR x = 0 TO mapW
  128.         nx = x * 0.01
  129.         ny = y * 0.01
  130.         noiseDetail 2, 0.4
  131.         v! = ABS(noise(nx * freq, ny * freq, 0)) * 1.5 + ABS(noise(nx * freq * 4, ny * freq * 4, 0)) * .25
  132.         v! = v! ^ (3.9)
  133.         elev = v! * 255
  134.         noiseDetail 2, 0.4
  135.         m! = ABS(noise(nx * 2, ny * 2, 0))
  136.         m! = m! ^ 1.4
  137.  
  138.         ' PSET (x + mapW, y), _RGB(0, 0, m! * 255)
  139.         moistureMap(x, y) = m!
  140.  
  141.         ' PSET (x, y), _RGB(elev, elev, elev)
  142.         terrainMap(x, y) = (elev / 255) * mountHeightMax
  143.         terrainData(x, y).x = map(x, 0, mapW, -mapW * 0.04, mapW * 0.04)
  144.         terrainData(x, y).y = terrainMap(x, y)
  145.         terrainData(x, y).z = map(y, 0, mapH, -mapH * 0.04, mapH * 0.04)
  146.  
  147.         setMountColor x, y, 0, (elev / 255) * mountHeightMax, mountHeightMax
  148.         clr~& = _RGB(mountColor(0) * 255, mountColor(1) * 255, mountColor(2) * 255)
  149.         PSET (x, y), clr~&
  150.         _DEST worldMap&
  151.         PSET (x + 150, y + 150), clr~&
  152.         _DEST 0
  153.  
  154.         IF terrainMap(x, y) <= 0.3 * mountHeightMax AND RND > 0.99993 AND Surprise.set = 0 THEN
  155.             Surprise.POS = terrainData(x, y)
  156.             ' line(x-2,y-2)-step(4,4),_rgb(255,0,0),bf
  157.             Surprise.set = 1
  158.             sx = x: sy = y
  159.         END IF
  160.  
  161.     NEXT x
  162.  
  163.     'CLS
  164.     'PRINT "Generating World..."
  165.     'need to show a catchy progress bar
  166.     FOR j = 0 TO map(y, 0, mapH - 1, 0, _WIDTH - 1): LINE (j, _HEIGHT - 6)-(j, _HEIGHT - 1), hsb~&(map(j, 0, _WIDTH - 1, 0, 255), 255, 128, 255): NEXT j
  167.     _DISPLAY
  168. ' _TITLE "3D OpenWorld Mountails [Hit SPACE to switch between MODs]"
  169. _DEST worldMap&
  170. LINE (sx - 3 + 150, sy - 3 + 150)-STEP(6, 6), _RGB(255, 0, 0), BF
  171. generateTerrainData
  172. PRINT "Hit Enter To Step In The World."
  173. PRINT "Map size : "; (mapH * mapW * 24) / 1024; " kB"
  174.  
  175. glAllow = -1
  176.     theta = (_MOUSEX / _WIDTH) * _PI(2.5) 'controls x-axis rotation
  177.     phi = map(_MOUSEY, 0, _HEIGHT, -_PI(0), _PI(0.5)) 'controls y-axis rotation
  178.  
  179.     IF Cam.mpos.z > mapH - 2 THEN Cam.mpos.z = mapH - 2 'prevent reaching out of the world map
  180.     IF Cam.mpos.x > mapW - 2 THEN Cam.mpos.x = mapW - 2 '
  181.     IF Cam.mpos.z < 2 THEN Cam.mpos.z = 2 '
  182.     IF Cam.mpos.x < 2 THEN Cam.mpos.x = 2 '
  183.  
  184.     IF _KEYDOWN(ASC("w")) OR _KEYDOWN(ASC("W")) THEN 'forward movement based on y-axis rotation
  185.         Cam.mpos.z = Cam.mpos.z + SIN(theta) * 0.45: Cam.mpos.x = Cam.mpos.x + COS(theta) * 0.45
  186.     END IF
  187.     IF _KEYDOWN(ASC("s")) OR _KEYDOWN(ASC("S")) THEN ' backward movement based on y-axis rotation
  188.         Cam.mpos.z = Cam.mpos.z - SIN(theta) * 0.45: Cam.mpos.x = Cam.mpos.x - COS(theta) * 0.45
  189.     END IF
  190.     IF _KEYDOWN(ASC("a")) OR _KEYDOWN(ASC("A")) THEN 'left movement based on y-axis rotation
  191.         Cam.mpos.z = Cam.mpos.z + SIN(theta - _PI(0.5)) * 0.45: Cam.mpos.x = Cam.mpos.x + COS(theta - _PI(0.5)) * 0.45
  192.     END IF
  193.     IF _KEYDOWN(ASC("d")) OR _KEYDOWN(ASC("D")) THEN 'right movement based on y-axis rotation
  194.         Cam.mpos.z = Cam.mpos.z + SIN(theta + _PI(0.5)) * 0.45: Cam.mpos.x = Cam.mpos.x + COS(theta + _PI(0.5)) * 0.45
  195.     END IF
  196.  
  197.     IF _KEYHIT = ASC(" ") THEN 'switching between MODs
  198.         IF worldMOD = 2 OR worldMOD = 3 THEN worldMOD = 0 ELSE worldMOD = worldMOD + 1
  199.     END IF
  200.  
  201.     CLS , 1 'clear the screen and make it transparent so that GL context not get hidden.
  202.     _LIMIT 60
  203.  
  204.     'rotation of world causes rotation of map too. calculation of the source points of map is done below
  205.     sx1 = COS(_PI(.75) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy1 = SIN(_PI(.75) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  206.     sx2 = COS(_PI(1.25) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy2 = SIN(_PI(1.25) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  207.     sx3 = COS(_PI(1.75) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy3 = SIN(_PI(1.75) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  208.     sx4 = COS(_PI(2.25) + theta) * 150 * sqrt2 + Cam.mpos.x + 150: sy4 = SIN(_PI(2.25) + theta) * 150 * sqrt2 + Cam.mpos.z + 150
  209.     'displaying the minimap
  210.     _MAPTRIANGLE (sx3, sy3)-(sx4, sy4)-(sx2, sy2), worldMap& TO(0, _HEIGHT - 150 * sqrt2)-(150 * sqrt2, _HEIGHT - 150 * sqrt2)-(0, _HEIGHT - 1)
  211.     _MAPTRIANGLE (sx2, sy2)-(sx4, sy4)-(sx1, sy1), worldMap& TO(0, _HEIGHT - 1)-(150 * sqrt2, _HEIGHT - 150 * sqrt2)-(150 * sqrt2, _HEIGHT - 1)
  212.     'showing your location
  213.     _PUTIMAGE (75 * sqrt2, _HEIGHT - 75 * sqrt2)-STEP(10, 10), myLocation&
  214.     'drawing red border along the map make it attractive
  215.     LINE (1, _HEIGHT - 150 * sqrt2)-STEP(150 * sqrt2, 150 * sqrt2), _RGB(255, 0, 0), B
  216.     _DISPLAY
  217.    
  218.     IF snowMount = 1 THEN
  219.         FOR i = 1 TO UBOUND(mountVert) STEP 3
  220.             setMountColor 0, 0, i - 1, mountVert(i), mountHeightMax
  221.         NEXT
  222.         snowMount = 2
  223.     END IF
  224.  
  225.  
  226. SUB _GL () STATIC
  227.  
  228.     IF glAllow = 0 THEN EXIT SUB 'we are not ready yet
  229.  
  230.     IF NOT glSetup THEN
  231.         glSetup = -1
  232.         _GLVIEWPORT 0, 0, _WIDTH, _HEIGHT 'define our rendering area
  233.  
  234.         aspect# = _WIDTH / _HEIGHT 'used to create perspective view
  235.  
  236.         rad = 1 'distance of camera from origin (0,0,0)
  237.         farPoint = 1.0 'far point of camera target
  238.  
  239.         'initialize camera
  240.         Cam.mpos.x = mapW / 2
  241.         Cam.mpos.z = mapH / 2
  242.         Cam.mpos.y = 8
  243.         'initialize textures for sky
  244.         FOR i = 1 TO UBOUND(worldTextures&)
  245.             _GLGENTEXTURES 1, _OFFSET(worldTextureHandle&(i - 1))
  246.  
  247.             DIM m AS _MEM
  248.             m = _MEMIMAGE(worldTextures&(i))
  249.  
  250.             _GLBINDTEXTURE _GL_TEXTURE_2D, worldTextureHandle&(i - 1)
  251.             _GLTEXIMAGE2D _GL_TEXTURE_2D, 0, _GL_RGB, _WIDTH(worldTextures&(i)), _HEIGHT(worldTextures&(i)), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  252.  
  253.             _MEMFREE m
  254.  
  255.             _GLTEXPARAMETERI _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  256.             _GLTEXPARAMETERI _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  257.             _FREEIMAGE worldTextures&(i)
  258.         NEXT
  259.     END IF
  260.  
  261.     IF worldMOD = 0 THEN _GLCLEARCOLOR 0.7, 0.8, 1.0, 1.0 'this makes the background look sky blue.
  262.     IF worldMOD = 1 THEN _GLCLEARCOLOR 0.031, 0.0, 0.307, 1.0 'night sky
  263.     IF worldMOD = 2 THEN _GLCLEARCOLOR 0.0, 0.0, 0.0, 1.0
  264.     IF worldMOD = 3 THEN
  265.         v~& = hsb~&(clock# MOD 255, 255, 128, 255)
  266.         kR = _RED(v~&) / 255: kG = _GREEN(v~&) / 255: kB = _BLUE(v~&) / 255
  267.         _GLCLEARCOLOR kR, kG, kB, 1
  268.     END IF
  269.     _GLCLEAR _GL_COLOR_BUFFER_BIT
  270.  
  271.     _GLENABLE _GL_DEPTH_TEST 'Of course, we are going to do 3D
  272.     _GLCLEARDEPTH 10.0
  273.  
  274.     _GLENABLE _GL_TEXTURE_2D 'so that we can use texture for our sky. :)
  275.  
  276.     IF worldMOD <> 2 THEN
  277.         _GLENABLE _GL_LIGHTING 'Without light, everything dull.
  278.         _GLENABLE _GL_LIGHT0
  279.     END IF
  280.  
  281.     IF worldMOD = 1 THEN
  282.         'night MOD
  283.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(0.05, 0.05, 0.33, 0)
  284.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.55, 0.55, 0.78, 0)
  285.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(0.75, 0.75, 0.98, 0)
  286.     ELSEIF worldMOD = 0 THEN
  287.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(0.35, 0.35, 0.33, 0) 'gives a bit yellowing color to the light
  288.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.75, 0.75, 0.60, 0) 'so it will feel like sun is in the sky
  289.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(0.95, 0.95, 0.80, 0)
  290.     ELSEIF worldMOD = 3 THEN 'disco light
  291.         _GLLIGHTFV _GL_LIGHT0, _GL_AMBIENT, glVec4(kR / 2, kG / 2, kB / 2, 0)
  292.         _GLLIGHTFV _GL_LIGHT0, _GL_DIFFUSE, glVec4(kR * 0.9, kG * 0.9, kB * 0.9, 0)
  293.         _GLLIGHTFV _GL_LIGHT0, _GL_SPECULAR, glVec4(kR, kG, kB, 0)
  294.     END IF
  295.     _GLSHADEMODEL _GL_SMOOTH 'to make the rendering smooth
  296.  
  297.     _GLMATRIXMODE _GL_PROJECTION
  298.     _GLUPERSPECTIVE 70, aspect#, 0.01, 15.0 'set up out perpective
  299.  
  300.     _GLMATRIXMODE _GL_MODELVIEW
  301.  
  302.     ' IF Cam.mpos.y > (terrainMap(Cam.mpos.x, Cam.mpos.z)) THEN Cam.mpos.y = Cam.mpos.y - 0.03 ELSE
  303.     Cam.mpos.y = meanAreaHeight(1, Cam.mpos.x, Cam.mpos.z) 'if you are in air then you must fall.
  304.  
  305.     'calculation of camera eye, its target, etc...
  306.     Cam.POS.x = map(Cam.mpos.x, 0, mapW, -mapW * 0.04, mapW * 0.04)
  307.     Cam.POS.z = map(Cam.mpos.z, 0, mapH, -mapH * 0.04, mapH * 0.04)
  308.     Cam.POS.y = Cam.mpos.y + 0.3
  309.  
  310.     Cam.target.y = Cam.POS.y * COS(phi)
  311.     Cam.target.x = Cam.POS.x + COS(theta) * farPoint
  312.     Cam.target.z = Cam.POS.z + SIN(theta) * farPoint
  313.  
  314.     gluLookAt Cam.POS.x, Cam.POS.y, Cam.POS.z, Cam.target.x, Cam.target.y, Cam.target.z, 0, 1, 0
  315.  
  316.  
  317.     'use of this skybox was avoided by me because I believe that it makes the scene a bit unrealistic.
  318.     ' skybox 5.0
  319.  
  320.     ' draw the world
  321.     _GLENABLE _GL_COLOR_MATERIAL
  322.     _GLCOLORMATERIAL _GL_FRONT, _GL_AMBIENT_AND_DIFFUSE
  323.  
  324.     _GLENABLECLIENTSTATE _GL_VERTEX_ARRAY
  325.     _GLVERTEXPOINTER 3, _GL_FLOAT, 0, _OFFSET(mountVert())
  326.     _GLENABLECLIENTSTATE _GL_COLOR_ARRAY
  327.     _GLCOLORPOINTER 3, _GL_FLOAT, 0, _OFFSET(mountColor())
  328.     _GLENABLECLIENTSTATE _GL_NORMAL_ARRAY
  329.     _GLNORMALPOINTER _GL_FLOAT, 0, _OFFSET(mountNormal())
  330.  
  331.     IF worldMOD = 2 THEN _GLDRAWARRAYS _GL_LINE_STRIP, 1, (UBOUND(mountvert) / 3) - 1 ELSE _GLDRAWARRAYS _GL_TRIANGLE_STRIP, 1, (UBOUND(mountVert) / 3) - 1
  332.     _GLDISABLECLIENTSTATE _GL_VERTEX_ARRAY
  333.     _GLDISABLECLIENTSTATE _GL_COLOR_ARRAY
  334.     _GLDISABLECLIENTSTATE _GL_NORMAL_ARRAY
  335.    
  336.     _GLDISABLE _GL_LIGHTING
  337.     IF worldMOD <> 3 AND snowMount <> 2 THEN showSurprise 0.4, Cam.POS
  338.  
  339.     _GLFLUSH
  340.    
  341.     clock# = clock# + .5
  342.  
  343. FUNCTION meanAreaHeight# (n%, x%, y%)
  344.     FOR i = y% - n% TO y% + n%
  345.         FOR j = x% - n% TO x% + n%
  346.             h# = h# + terrainMap(j, i)
  347.             g% = g% + 1
  348.     NEXT j, i
  349.     meanAreaHeight# = (h# / g%)
  350.  
  351. SUB showSurprise (s, a AS vec3)
  352.     IF a.x > Surprise.POS.x - s AND a.x < Surprise.POS.x + s AND a.z > Surprise.POS.z - s AND a.z < Surprise.POS.z + s THEN
  353.         IF RND > 0.5 THEN
  354.             worldMOD = 3
  355.             _TITLE "You finally came to know that its QB64 Island!!"
  356.         ELSE
  357.             snowMount = 1
  358.             _TITLE "Welcome to this new world..."
  359.             Cam.mpos.y = 6
  360.         END IF
  361.     END IF
  362.    
  363.     _GLBINDTEXTURE _GL_TEXTURE_2D, worldTextureHandle&(0)
  364.  
  365.     _GLBEGIN _GL_QUADS
  366.     _GLTEXCOORD2F 0, 1
  367.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s 'front
  368.     _GLTEXCOORD2F 0, 0
  369.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s
  370.     _GLTEXCOORD2F 1, 0
  371.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  372.     _GLTEXCOORD2F 1, 1
  373.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  374.     _GLEND
  375.  
  376.     _GLBEGIN _GL_QUADS
  377.     _GLTEXCOORD2F 0, 1
  378.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'rear
  379.     _GLTEXCOORD2F 0, 0
  380.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  381.     _GLTEXCOORD2F 1, 0
  382.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  383.     _GLTEXCOORD2F 1, 1
  384.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  385.     _GLEND
  386.  
  387.     _GLBEGIN _GL_QUADS
  388.     _GLTEXCOORD2F 1, 0
  389.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'left
  390.     _GLTEXCOORD2F 0, 0
  391.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  392.     _GLTEXCOORD2F 0, 1
  393.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s
  394.     _GLTEXCOORD2F 1, 1
  395.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  396.     _GLEND
  397.  
  398.     _GLBEGIN _GL_QUADS
  399.     _GLTEXCOORD2F 1, 0
  400.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s 'right
  401.     _GLTEXCOORD2F 0, 0
  402.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  403.     _GLTEXCOORD2F 0, 1
  404.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  405.     _GLTEXCOORD2F 1, 1
  406.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  407.     _GLEND
  408.  
  409.     _GLBEGIN _GL_QUADS 'up
  410.     _GLTEXCOORD2F 0, 1
  411.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z - s 'up
  412.     _GLTEXCOORD2F 0, 0
  413.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  414.     _GLTEXCOORD2F 1, 0
  415.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z + s
  416.     _GLTEXCOORD2F 1, 1
  417.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y + 2 * s, Surprise.POS.z - s
  418.     _GLEND
  419.    
  420.     _GLBEGIN _GL_QUADS 'down
  421.     _GLTEXCOORD2F 0, 1
  422.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z - s 'up
  423.     _GLTEXCOORD2F 0, 0
  424.     _GLVERTEX3F Surprise.POS.x - s, Surprise.POS.y, Surprise.POS.z + s
  425.     _GLTEXCOORD2F 1, 0
  426.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z + s
  427.     _GLTEXCOORD2F 1, 1
  428.     _GLVERTEX3F Surprise.POS.x + s, Surprise.POS.y, Surprise.POS.z - s
  429.     _GLEND
  430.  
  431.  
  432. 'draws a beautiful sky
  433. SUB skybox (s)
  434.     _GLDISABLE _GL_LIGHTING
  435.     _GLDISABLE _GL_LIGHT0
  436.     _GLDISABLE _GL_DEPTH_TEST
  437.     _GLDEPTHMASK _GL_FALSE
  438.  
  439.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(4)
  440.  
  441.     _GLBEGIN _GL_QUADS
  442.     _GLTEXCOORD2F 0, 1
  443.     _GLVERTEX3F -s, s, -s 'front
  444.     _GLTEXCOORD2F 0, 0
  445.     _GLVERTEX3F -s, -s, -s
  446.     _GLTEXCOORD2F 1, 0
  447.     _GLVERTEX3F s, -s, -s
  448.     _GLTEXCOORD2F 1, 1
  449.     _GLVERTEX3F s, s, -s
  450.     _GLEND
  451.  
  452.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(0)
  453.     _GLBEGIN _GL_QUADS
  454.     _GLTEXCOORD2F 0, 1
  455.     _GLVERTEX3F -s, s, s 'rear
  456.     _GLTEXCOORD2F 0, 0
  457.     _GLVERTEX3F -s, -s, s
  458.     _GLTEXCOORD2F 1, 0
  459.     _GLVERTEX3F s, -s, s
  460.     _GLTEXCOORD2F 1, 1
  461.     _GLVERTEX3F s, s, s
  462.     _GLEND
  463.    
  464.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(1)
  465.     _GLBEGIN _GL_QUADS
  466.     _GLTEXCOORD2F 1, 0
  467.     _GLVERTEX3F -s, s, s 'left
  468.     _GLTEXCOORD2F 0, 0
  469.     _GLVERTEX3F -s, -s, s
  470.     _GLTEXCOORD2F 0, 1
  471.     _GLVERTEX3F -s, -s, -s
  472.     _GLTEXCOORD2F 1, 1
  473.     _GLVERTEX3F -s, s, -s
  474.     _GLEND
  475.    
  476.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(3)
  477.     _GLBEGIN _GL_QUADS
  478.     _GLTEXCOORD2F 1, 0
  479.     _GLVERTEX3F s, s, s 'right
  480.     _GLTEXCOORD2F 0, 0
  481.     _GLVERTEX3F s, -s, s
  482.     _GLTEXCOORD2F 0, 1
  483.     _GLVERTEX3F s, -s, -s
  484.     _GLTEXCOORD2F 1, 1
  485.     _GLVERTEX3F s, s, -s
  486.     _GLEND
  487.  
  488.     _GLBINDTEXTURE _GL_TEXTURE_2D, skyTextureHandle&(2)
  489.     _GLBEGIN _GL_QUADS
  490.     _GLTEXCOORD2F 0, 1
  491.     _GLVERTEX3F -s, s, -s 'up
  492.     _GLTEXCOORD2F 0, 0
  493.     _GLVERTEX3F -s, s, s
  494.     _GLTEXCOORD2F 1, 0
  495.     _GLVERTEX3F s, s, s
  496.     _GLTEXCOORD2F 1, 1
  497.     _GLVERTEX3F s, s, -s
  498.     _GLEND
  499.  
  500.     _GLDEPTHMASK _GL_TRUE
  501.     _GLENABLE _GL_DEPTH_TEST
  502.     _GLENABLE _GL_LIGHTING
  503.     _GLENABLE _GL_LIGHT0
  504.  
  505. SUB setMountColor (xi, yi, i, h, h_max) 'assign color on the basis of height map and moisture map.
  506.     IF snowMount = 1 THEN
  507.         IF h > 0.8 * h_max THEN mountColor(i) = 0.439: mountColor(i + 1) = 0.988: mountColor(i + 2) = 0.988: EXIT SUB
  508.         mountColor(i) = 1: mountColor(i + 1) = 1: mountColor(i + 2) = 1
  509.         EXIT SUB
  510.     END IF
  511.     IF h > 0.8 * h_max THEN
  512.         IF moistureMap(xi, yi) < 0.1 THEN mountColor(i) = 0.333: mountColor(i + 1) = 0.333: mountColor(i + 2) = 0.333: EXIT SUB 'scorched
  513.         IF moistureMap(xi, yi) < 0.2 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.533: EXIT SUB 'bare
  514.         IF moistureMap(xi, yi) < 0.5 THEN mountColor(i) = 0.737: mountColor(i + 1) = 0.737: mountColor(i + 2) = 0.6705: EXIT SUB 'tundra
  515.         mountColor(i) = 0.8705: mountColor(i + 1) = 0.8705: mountColor(i + 2) = 0.898: EXIT SUB 'snow
  516.     END IF
  517.     IF h > 0.6 * h_max THEN
  518.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.788: mountColor(i + 1) = 0.823: mountColor(i + 2) = 0.607: EXIT SUB 'temperate desert
  519.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.466: EXIT SUB 'shrubland
  520.         mountColor(i) = 0.6: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.466: EXIT SUB 'taiga
  521.     END IF
  522.     IF h > 0.3 * h_max THEN
  523.         IF moistureMap(xi, yi) < 0.16 THEN mountColor(i) = 0.788: mountColor(i + 1) = 0.823: mountColor(i + 2) = 0.607: EXIT SUB 'temperate desert
  524.         IF moistureMap(xi, yi) < 0.50 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  525.         IF moistureMap(xi, yi) < 0.83 THEN mountColor(i) = 0.403: mountColor(i + 1) = 0.576: mountColor(i + 2) = 0.349: EXIT SUB 'temperate deciduous forest
  526.         mountColor(i) = 0.262: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.233: EXIT SUB 'temperate rain forest
  527.     END IF
  528.     IF h < 0.01 * h_max THEN mountColor(i) = 0.262: mountColor(i + 1) = 0.262: mountColor(i + 2) = 0.478: EXIT SUB 'ocean
  529.     IF h < 0.07 * h_max THEN mountColor(i) = 0.627: mountColor(i + 1) = 0.568: mountColor(i + 2) = 0.466: EXIT SUB 'beach
  530.     IF h <= 0.3 * h_max THEN
  531.         IF moistureMap(xi, yi) < 0.16 THEN mountColor(i) = 0.823: mountColor(i + 1) = 0.725: mountColor(i + 2) = 0.545: EXIT SUB 'subtropical desert
  532.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  533.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.337: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.266: EXIT SUB 'tropical seasonal forest
  534.         mountColor(i) = 0.2: mountColor(i + 1) = 0.466: mountColor(i + 2) = 0.333: EXIT SUB 'tropical rain forest
  535.     END IF
  536.  
  537. SUB generateTerrainData ()
  538.     DIM A AS vec3, B AS vec3, C AS vec3, R AS vec3
  539.     index = 0
  540.  
  541.     '##################################################################################################
  542.     '# Note : The below method consumes more memory. It uses 3x more vertex array than the next one.  #
  543.     '# So, use of this method was avoided by me.                                                      #
  544.     '##################################################################################################
  545.  
  546.     ' _dest _console
  547.     ' FOR z = 0 TO mapH - 1
  548.     ' FOR x = 0 TO mapW - 1
  549.     ' A = terrainData(x, z)
  550.     ' B = terrainData(x, z + 1)
  551.     ' C = terrainData(x + 1, z)
  552.     ' D = terrainData(x+1,z+1)
  553.  
  554.     ' ' ?index
  555.     ' ' OBJ_CalculateNormal A, B, C, R
  556.  
  557.     ' ' mountNormal(index) = R.x : mountNormal(index+1) = R.y : mountNormal(index+2) = R.z
  558.     ' ' mountNormal(index+3) = R.x : mountNormal(index+4) = R.y : mountNormal(index+5) = R.z
  559.     ' ' mountNormal(index+6) = R.x : mountNormal(index+7) = R.y : mountNormal(index+8) = R.z
  560.  
  561.     ' mountVert(index) = A.x : mountVert(index+1) = A.y : mountVert(index+2) = A.z : setMountColor x,z,index, A.y, mountHeightMax
  562.     ' mountVert(index+3) = B.x : mountVert(index+4) = B.y : mountVert(index+5) = B.z :  setMountColor x,z+1,index+3, B.y, mountHeightMax
  563.     ' mountVert(index+6) = C.x : mountVert(index+7) = C.y : mountVert(index+8) = C.z: setMountColor x+1,z,index+6, C.y, mountHeightMax
  564.  
  565.     ' ' OBJ_CalculateNormal C,B,D, R
  566.  
  567.     ' ' mountNormal(index+9) = R.x : mountNormal(index+10) = R.y : mountNormal(index+11) = R.z
  568.     ' ' mountNormal(index+12) = R.x : mountNormal(index+13) = R.y : mountNormal(index+14) = R.z
  569.     ' ' mountNormal(index+15) = R.x : mountNormal(index+16) = R.y : mountNormal(index+17) = R.z
  570.  
  571.     ' mountVert(index+9) = C.x : mountVert(index+10) = C.y : mountVert(index+11) = C.z: setMountColor x+1,z, index+9, C.y, mountHeightMax
  572.     ' mountVert(index+12) = B.x : mountVert(index+13) = B.y : mountVert(index+14) = B.z: setMountColor x,z+1,index+12, B.y, mountHeightMax
  573.     ' mountVert(index+15) = D.x : mountVert(index+16) = D.y : mountVert(index+17) = D.z: setMountColor x+1,z+1,index+15, D.y, mountHeightMax
  574.     ' index = index+18
  575.     ' NEXT x,z
  576.  
  577.     'this method is efficient than the above one.
  578.     DO
  579.         IF z MOD 2 = 0 THEN x = x + 1 ELSE x = x - 1
  580.  
  581.         A = terrainData(x, z) 'get out coordinates from our stored data
  582.         B = terrainData(x, z + 1)
  583.         C = terrainData(x + 1, z)
  584.  
  585.         OBJ_CalculateNormal A, B, C, R 'calculates the normal of a triangle
  586.  
  587.         'store color, coordinate & normal data in an array
  588.         mountNormal(index) = R.x: mountNormal(index + 1) = R.y: mountNormal(index + 2) = R.z
  589.         mountVert(index) = A.x: mountVert(index + 1) = A.y: mountVert(index + 2) = A.z: setMountColor x, z, index, A.y, mountHeightMax
  590.  
  591.         mountNormal(index + 3) = R.x: mountNormal(index + 4) = R.y: mountNormal(index + 5) = R.z
  592.         mountVert(index + 3) = B.x: mountVert(index + 4) = B.y: mountVert(index + 5) = B.z: setMountColor x, z + 1, index + 3, B.y, mountHeightMax
  593.  
  594.         index = index + 6
  595.  
  596.         IF x = mapW - 1 THEN
  597.             IF z MOD 2 = 0 THEN x = x + 1: z = z + 1
  598.         END IF
  599.         IF x = 1 THEN
  600.             IF z MOD 2 = 1 THEN x = x - 1: z = z + 1
  601.         END IF
  602.         IF z = mapH - 1 THEN EXIT DO
  603.     LOOP
  604.     _DEST 0
  605.  
  606. FUNCTION trimDecimal# (num, n%)
  607.     d$ = RTRIM$(STR$(num))
  608.     dd$ = d$
  609.     FOR i = 1 TO LEN(d$)
  610.         cA$ = MID$(d$, i, 1)
  611.         IF foundpoint = 1 THEN k = k + 1
  612.         IF cA$ = "." THEN foundpoint = 1
  613.         IF k = n% THEN dd$ = LEFT$(dd$, i)
  614.     NEXT i
  615.     trimDecimal# = VAL(dd$)
  616.  
  617.  
  618. FUNCTION p5random! (mn!, mx!)
  619.     IF mn! > mx! THEN
  620.         SWAP mn!, mx!
  621.     END IF
  622.     p5random! = RND * (mx! - mn!) + mn!
  623.  
  624.  
  625. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  626.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  627.  
  628. 'coded in QB64 by Fellipe Heitor
  629. 'Can be found in p5js.bas library
  630. 'http://bit.ly/p5jsbas
  631. FUNCTION noise! (x AS SINGLE, y AS SINGLE, z AS SINGLE)
  632.     STATIC p5NoiseSetup AS _BYTE
  633.     STATIC perlin() AS SINGLE
  634.     STATIC PERLIN_YWRAPB AS SINGLE, PERLIN_YWRAP AS SINGLE
  635.     STATIC PERLIN_ZWRAPB AS SINGLE, PERLIN_ZWRAP AS SINGLE
  636.     STATIC PERLIN_SIZE AS SINGLE
  637.  
  638.     IF p5NoiseSetup = 0 THEN
  639.         p5NoiseSetup = 1
  640.  
  641.         PERLIN_YWRAPB = 4
  642.         PERLIN_YWRAP = INT(1 * (2 ^ PERLIN_YWRAPB))
  643.         PERLIN_ZWRAPB = 8
  644.         PERLIN_ZWRAP = INT(1 * (2 ^ PERLIN_ZWRAPB))
  645.         PERLIN_SIZE = 4095
  646.  
  647.         perlin_octaves = 4
  648.         perlin_amp_falloff = 0.5
  649.  
  650.         REDIM perlin(PERLIN_SIZE + 1) AS SINGLE
  651.         DIM i AS SINGLE
  652.         FOR i = 0 TO PERLIN_SIZE + 1
  653.             perlin(i) = RND
  654.         NEXT
  655.     END IF
  656.  
  657.     x = ABS(x)
  658.     y = ABS(y)
  659.     z = ABS(z)
  660.  
  661.     DIM xi AS SINGLE, yi AS SINGLE, zi AS SINGLE
  662.     xi = INT(x)
  663.     yi = INT(y)
  664.     zi = INT(z)
  665.  
  666.     DIM xf AS SINGLE, yf AS SINGLE, zf AS SINGLE
  667.     xf = x - xi
  668.     yf = y - yi
  669.     zf = z - zi
  670.  
  671.     DIM r AS SINGLE, ampl AS SINGLE, o AS SINGLE
  672.     r = 0
  673.     ampl = .5
  674.  
  675.     FOR o = 1 TO perlin_octaves
  676.         DIM of AS SINGLE, rxf AS SINGLE
  677.         DIM ryf AS SINGLE, n1 AS SINGLE, n2 AS SINGLE, n3 AS SINGLE
  678.         of = xi + INT(yi * (2 ^ PERLIN_YWRAPB)) + INT(zi * (2 ^ PERLIN_ZWRAPB))
  679.  
  680.         rxf = 0.5 * (1.0 - COS(xf * _PI))
  681.         ryf = 0.5 * (1.0 - COS(yf * _PI))
  682.  
  683.         n1 = perlin(of AND PERLIN_SIZE)
  684.         n1 = n1 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n1)
  685.         n2 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  686.         n2 = n2 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n2)
  687.         n1 = n1 + ryf * (n2 - n1)
  688.  
  689.         of = of + PERLIN_ZWRAP
  690.         n2 = perlin(of AND PERLIN_SIZE)
  691.         n2 = n2 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n2)
  692.         n3 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  693.         n3 = n3 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n3)
  694.         n2 = n2 + ryf * (n3 - n2)
  695.  
  696.         n1 = n1 + (0.5 * (1.0 - COS(zf * _PI))) * (n2 - n1)
  697.  
  698.         r = r + n1 * ampl
  699.         ampl = ampl * perlin_amp_falloff
  700.         xi = INT(xi * (2 ^ 1))
  701.         xf = xf * 2
  702.         yi = INT(yi * (2 ^ 1))
  703.         yf = yf * 2
  704.         zi = INT(zi * (2 ^ 1))
  705.         zf = zf * 2
  706.  
  707.         IF xf >= 1.0 THEN xi = xi + 1: xf = xf - 1
  708.         IF yf >= 1.0 THEN yi = yi + 1: yf = yf - 1
  709.         IF zf >= 1.0 THEN zi = zi + 1: zf = zf - 1
  710.     NEXT
  711.     noise! = r
  712.  
  713. SUB noiseDetail (lod!, falloff!)
  714.     IF lod! > 0 THEN perlin_octaves = lod!
  715.     IF falloff! > 0 THEN perlin_amp_falloff = falloff!
  716.  
  717. 'method adapted form http://stackoverflow.com/questions/4106363/converting-rgb-to-hsb-colors
  718. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  719.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  720.  
  721.     H = map(__H, 0, 255, 0, 360)
  722.     S = map(__S, 0, 255, 0, 1)
  723.     B = map(__B, 0, 255, 0, 1)
  724.  
  725.     IF S = 0 THEN
  726.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  727.         EXIT FUNCTION
  728.     END IF
  729.  
  730.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  731.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  732.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  733.  
  734.     IF B > .5 THEN
  735.         fmx = B - (B * S) + S
  736.         fmn = B + (B * S) - S
  737.     ELSE
  738.         fmx = B + (B * S)
  739.         fmn = B - (B * S)
  740.     END IF
  741.  
  742.     iSextant = INT(H / 60)
  743.  
  744.     IF H >= 300 THEN
  745.         H = H - 360
  746.     END IF
  747.  
  748.     H = H / 60
  749.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  750.  
  751.     IF iSextant MOD 2 = 0 THEN
  752.         fmd = (H * (fmx - fmn)) + fmn
  753.     ELSE
  754.         fmd = fmn - (H * (fmx - fmn))
  755.     END IF
  756.  
  757.     imx = _ROUND(fmx * 255)
  758.     imd = _ROUND(fmd * 255)
  759.     imn = _ROUND(fmn * 255)
  760.  
  761.     SELECT CASE INT(iSextant)
  762.         CASE 1
  763.             hsb~& = _RGBA32(imd, imx, imn, A)
  764.         CASE 2
  765.             hsb~& = _RGBA32(imn, imx, imd, A)
  766.         CASE 3
  767.             hsb~& = _RGBA32(imn, imd, imx, A)
  768.         CASE 4
  769.             hsb~& = _RGBA32(imd, imn, imx, A)
  770.         CASE 5
  771.             hsb~& = _RGBA32(imx, imn, imd, A)
  772.         CASE ELSE
  773.             hsb~& = _RGBA32(imx, imd, imn, A)
  774.     END SELECT
  775.  
  776.  
  777.  
  778. SUB OBJ_CalculateNormal (p1 AS vec3, p2 AS vec3, p3 AS vec3, N AS vec3)
  779.     DIM U AS vec3, V AS vec3
  780.  
  781.     U.x = p2.x - p1.x
  782.     U.y = p2.y - p1.y
  783.     U.z = p2.z - p1.z
  784.  
  785.     V.x = p3.x - p1.x
  786.     V.y = p3.y - p1.y
  787.     V.z = p3.z - p1.z
  788.  
  789.     N.x = (U.y * V.z) - (U.z * V.y)
  790.     N.y = (U.z * V.x) - (U.x * V.z)
  791.     N.z = (U.x * V.y) - (U.y * V.x)
  792.     OBJ_Normalize N
  793.  
  794. SUB OBJ_Normalize (V AS vec3)
  795.     mag! = SQR(V.x * V.x + V.y * V.y + V.z * V.z)
  796.     V.x = V.x / mag!
  797.     V.y = V.y / mag!
  798.     V.z = V.z / mag!
  799.  
  800. FUNCTION glVec4%& (x, y, z, w)
  801.     STATIC internal_vec4(3)
  802.     internal_vec4(0) = x
  803.     internal_vec4(1) = y
  804.     internal_vec4(2) = z
  805.     internal_vec4(3) = w
  806.     glVec4%& = _OFFSET(internal_vec4())
  807.  
  808. '============================================================
  809. '=== This file was created with MakeDATA.bas by RhoSigma, ===
  810. '=== you must $INCLUDE this at the end of your program.   ===
  811. '============================================================
  812.  
  813. '=====================================================================
  814. 'Function to write the embedded DATAs back to disk. Call this FUNCTION
  815. 'once, before you will access the represented file for the first time.
  816. 'After the call always use the returned realFile$ ONLY to access the
  817. 'written file, as the filename was maybe altered in order to avoid the
  818. 'overwriting of an existing file of the same name in the given location.
  819. '---------------------------------------------------------------------
  820. 'SYNTAX: realFile$ = WriteqbiconData$ (wantFile$)
  821. '
  822. 'INPUTS: wantFile$ --> The filename you would like to write the DATAs
  823. '                      to, can contain a full or relative path.
  824. '
  825. 'RESULT: realFile$ --> On success the path and filename finally used
  826. '                      after applied checks, use ONLY this returned
  827. '                      name to access the file.
  828. '                   -> On failure this FUNCTION will panic with the
  829. '                      appropriate ERROR code, you may handle this as
  830. '                      needed with your own ON ERROR GOTO... handler.
  831. '=====================================================================
  832. FUNCTION WriteqbiconData$ (file$)
  833.     '--- separate filename body & extension ---
  834.     FOR po% = LEN(file$) TO 1 STEP -1
  835.         IF MID$(file$, po%, 1) = "." THEN
  836.             body$ = LEFT$(file$, po% - 1)
  837.             ext$ = MID$(file$, po%)
  838.             EXIT FOR
  839.         ELSEIF MID$(file$, po%, 1) = "\" OR MID$(file$, po%, 1) = "/" OR po% = 1 THEN
  840.             body$ = file$
  841.             ext$ = ""
  842.             EXIT FOR
  843.         END IF
  844.     NEXT po%
  845.     '--- avoid overwriting of existing files ---
  846.     num% = 1
  847.     WHILE _FILEEXISTS(file$)
  848.         file$ = body$ + "(" + LTRIM$(STR$(num%)) + ")" + ext$
  849.         num% = num% + 1
  850.     WEND
  851.     '--- write DATAs ---
  852.     ff% = FREEFILE
  853.     OPEN file$ FOR OUTPUT AS ff%
  854.     RESTORE qbicon
  855.     READ numL&, numB&
  856.     FOR i& = 1 TO numL&
  857.         READ dat&
  858.         PRINT #ff%, MKL$(dat&);
  859.     NEXT i&
  860.     IF numB& > 0 THEN
  861.         FOR i& = 1 TO numB&
  862.             READ dat&
  863.             PRINT #ff%, CHR$(dat&);
  864.         NEXT i&
  865.     END IF
  866.     CLOSE ff%
  867.     '--- set result ---
  868.     WriteqbiconData$ = file$
  869.  
  870.     '--- DATAs representing the contents of file qbicon32.png
  871.     '---------------------------------------------------------------------
  872.     qbicon:
  873.     DATA 144,4
  874.     DATA &H474E5089,&H0A1A0A0D,&H0D000000,&H52444849,&H20000000,&H20000000,&H00000608,&H7A7A7300
  875.     DATA &H000000F4,&H4D416704,&HB1000041,&H61FC0B8F,&H00000005,&H59487009,&H0E000073,&H0E0000C1
  876.     DATA &H91B801C1,&H0000ED6B,&H45741A00,&H6F537458,&H61777466,&H50006572,&H746E6961,&H54454E2E
  877.     DATA &H2E337620,&H30312E35,&HA172F430,&HC0010000,&H54414449,&H97C54758,&H20C371E1,&HA519850C
  878.     DATA &H064430A3,&HDB3124E8,&H823B3FB4,&H5D14C887,&H04A84D21,&H8C096308,&H87F6E2E0,&HD67E02F2
  879.     DATA &HBE7C5F13,&H6EE6318B,&H32F9F98D,&H4A6A13E6,&H66A141DF,&H060DE3F4,&H283CCDC8,&HA0AEB0D4
  880.     DATA &H869AC350,&HE1E5F0A0,&H42FAF78D,&H35621C7F,&HE71AB1F6,&H3CFE85F5,&H0F502444,&HA81115E9
  881.     DATA &H922AF485,&HE6F00828,&H8C2746EE,&H0F4B7EBA,&HEDCDE011,&H15184E93,&H25D3DCD7,&H0A938650
  882.     DATA &H1940834F,&H3D3C2A4E,&H551C3C02,&H6CBEC278,&H8E04EFFE,&H24E64F6A,&H92554702,&HBD808D39
  883.     DATA &HCD712195,&H2812A73D,&HA78549C3,&HF73DC047,&H9EE6B8E1,&H7F365D78,&HB54D0109,&H104A6808
  884.     DATA &H27157A98,&H62AF5302,&HDDC4A04E,&H11F35222,&H082D39E6,&HC89CE6F0,&HBCAE6276,&H020688E9
  885.     DATA &HB732A1F0,&H569436B4,&H8301F0E1,&HBCA6AC3A,&H00E288E9,&H5CB2C091,&H2EAD0057,&HD87DE3F4
  886.     DATA &HEF57B16C,&H5050FC1D,&H2616BDF8,&H237F613D,&HAA390B50,&H40244038,&H3878A98D,&H0230F4AA
  887.     DATA &H0BB9C03C,&HADA7B09D,&H9E953BE6,&H2FD8010E,&HD5B48E43,&H73D2A77C,&HFDB70122,&HCD7141C6
  888.     DATA &H39FAE93D,&HD2A680CF,&H9A026D70,&H24F0FBC2,&H2DAE13E5,&H6FEE0FBC,&H9F2E7013,&HB9AE2830
  889.     DATA &H66A75D27,&H52F6754D,&H0043A019,&HA93873F6,&HA90244F4,&H01CAA1D9,&H10DFFEC2,&H84039540
  890.     DATA &H033CD7FD,&H72A6AC3C,&H11BFB080,&HEB157B98,&HD75E3409,&H02184099,&H688E9A94,&H0854190E
  891.     DATA &H2FF0040F,&H46621E72,&H1B3509A1,&H05FDBBD5,&HF13FDC1C,&H6A6E33B4,&H00000000,&H444E4549
  892.     DATA &HAE,&H42,&H60,&H82
  893.  
  894.  
  895.  

if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories

Re: 3D OpenWorld Mountains
« Reply #29 on: March 23, 2019, 09:28:32 AM »
Outstanding!

The mountains seem more realistic. I see you have embedded the icon file. That sure is a different kind of sun light when the surprise is found. :)
« Last Edit: March 23, 2019, 09:30:38 AM by bplus »
B = B + ...