QB64.org Forum

Active Forums => Programs => Topic started by: Ashish on March 08, 2019, 08:35:56 am

Title: 3D OpenWorld Mountains
Post by: Ashish on March 08, 2019, 08:35:56 am
Hi everyone!
This is my first attempt to code a OpenWorld Terrain/Mountain demo. A lot of effort is made by me to make it realistic.
Run the code below and enjoy!

Controls -
Suggestions are welcome! 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 camera
  20.     pos AS vec3
  21.     mpos AS vec3
  22.     target AS vec3
  23.  
  24. DECLARE LIBRARY 'camera control function
  25.     SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
  26.  
  27.  
  28. 'noise function related variables
  29. DIM SHARED perlin_octaves AS SINGLE, perlin_amp_falloff AS SINGLE
  30.  
  31. DIM SHARED mapW, mapH
  32. mapW = 800: mapH = 800 'control the size of the map or world
  33.  
  34. 'Terrain Map related variables
  35. 'terrainData(mapW,mapH) contain elevation data and moistureMap(mapW,mapH) contain moisture data
  36. DIM SHARED terrainMap(mapW, mapH), moistureMap(mapW, mapH), terrainData(mapW, mapH) AS vec3
  37. '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
  38. DIM SHARED mountVert(mapW * mapH * 6) AS SINGLE, mountColor(mapW * mapH * 6), mountNormal(mapW * mapH * 6)
  39.  
  40. 'MODs
  41. DIM SHARED worldMOD
  42.  
  43. 'map
  44. DIM SHARED worldMap&, myLocation& 'stored the 2D Map
  45. worldMap& = _NEWIMAGE(mapW + 300, mapH + 300, 32)
  46. myLocation& = _NEWIMAGE(10, 10, 32)
  47.  
  48. 'sky
  49. DIM SHARED skyTextures&(5), skyTextureHandle&(4)
  50. skyTextures&(0) = _NEWIMAGE(600, 600, 32)
  51. FOR i = 1 TO 5: skyTextures&(i) = _NEWIMAGE(200, 200, 32): NEXT
  52.  
  53. _DEST worldMap&
  54. CLS , _RGB(0, 0, 255)
  55. 'The reason of commenting down below code is given on line number -    279
  56. '_DEST skyTextures&(0)
  57. 'CLS , _RGB(109, 164, 255)
  58. 'FOR y = 0 TO _HEIGHT - 1
  59. '    FOR x = 0 TO _WIDTH - 1
  60. '        noiseDetail 5, 0.5
  61. '        k! = (ABS(noise(x * 0.04, y * 0.04, x / y * 0.01)) * 1.3) ^ 3
  62. '        PSET (x, y), _RGBA(255, 255, 255, k! * 255)
  63. 'NEXT x, y
  64. 'skyW = _WIDTH(skyTextures&(0))
  65. 'skyH = _HEIGHT(skyTextures&(0))
  66. '_PUTIMAGE (0, 0), 0, skyTextures&(1), (skyW / 3, 0)-STEP(skyW / 3, skyH / 3) 'back or rear
  67. '_PUTIMAGE (0, 0), 0, skyTextures&(2), (0, skyH / 3)-STEP(skyW / 3, skyH / 3) 'left
  68. '_PUTIMAGE (0, 0), 0, skyTextures&(3), (skyW / 3, skyH / 3)-STEP(skyW / 3, skyH / 3) 'up
  69. '_PUTIMAGE (0, 0), 0, skyTextures&(4), (2 * (skyW / 3), skyH / 3)-STEP(skyW / 3, skyH / 3) 'right
  70. '_PUTIMAGE (0, 0), 0, skyTextures&(5), (skyW / 3, 2 * (skyH / 3))-STEP(skyW / 3, skyH / 3) 'front
  71. '_DEST 0
  72.  
  73. 'camera
  74. DIM SHARED Cam AS camera, theta, phi
  75.  
  76.  
  77. DIM SHARED glAllow AS _BYTE
  78. _DEST myLocation& 'Generating the blip icon
  79. FOR i = 0 TO 10
  80.     FOR j = 0 TO 10
  81.         READ cx
  82.         IF cx = 1 THEN PSET (j, i), _RGB(255, 0, 200)
  83. NEXT j, i
  84. 'image data of blip icon
  85. DATA 0,0,0,0,0,1,0,0,0,0,0
  86. DATA 0,0,0,0,0,1,0,0,0,0,0
  87. DATA 0,0,0,0,1,1,1,0,0,0,0
  88. DATA 0,0,0,1,1,1,1,1,0,0,0
  89. DATA 0,0,0,1,1,1,1,1,0,0,0
  90. DATA 0,0,1,1,1,1,1,1,1,0,0
  91. DATA 0,1,1,1,1,1,1,1,1,1,0
  92. DATA 0,1,1,1,1,1,1,1,1,1,0
  93. DATA 1,1,1,1,0,0,0,1,1,1,1
  94. DATA 1,1,0,0,0,0,0,0,0,1,1
  95. DATA 1,0,0,0,0,0,0,0,0,0,1
  96. DATA 0,0,0,0,0,0,0,0,0,0,0
  97.  
  98.  
  99. 'Map elevations and mositure calculation done here with the help of perlin noise
  100. freq = 2
  101. FOR y = 0 TO mapH
  102.     FOR x = 0 TO mapW
  103.         nx = x * 0.01
  104.         ny = y * 0.01
  105.         noiseDetail 2, 0.4
  106.         v! = ABS(noise(nx * freq, ny * freq, 0)) * 1.5 + ABS(noise(nx * freq * 4, ny * freq * 4, 0)) * .25
  107.         v! = v! ^ (3.9)
  108.         elev = v! * 255
  109.         noiseDetail 2, 0.4
  110.         m! = ABS(noise(nx * 2, ny * 2, 0))
  111.         m! = m! ^ 1.4
  112.  
  113.         ' pset (x+mapW,y),_rgb(0,0,m!*255)
  114.         moistureMap(x, y) = m!
  115.  
  116.         ' PSET (x, y), _RGB(elev, elev, elev)
  117.         terrainMap(x, y) = (elev / 255) * mountHeightMax
  118.         terrainData(x, y).x = map(x, 0, mapW, -mapW * 0.02, mapW * 0.02)
  119.         terrainData(x, y).y = terrainMap(x, y)
  120.         terrainData(x, y).z = map(y, 0, mapH, -mapH * 0.02, mapH * 0.02)
  121.  
  122.         setMountColor x, y, 0, elev / 255, mountHeightMax
  123.         clr~& = _RGB(mountColor(0) * 255, mountColor(1) * 255, mountColor(2) * 255)
  124.         _DEST worldMap&
  125.         PSET (x + 150, y + 150), clr~&
  126.         _DEST 0
  127.         ' pset(x,y+mapH),clr~&
  128.     NEXT x
  129.  
  130.     CLS
  131.     PRINT "Generating World..."
  132.     'need to show a catchy progress bar
  133.     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
  134.     _DISPLAY
  135. generateTerrainData
  136. PRINT "Hit Enter To Step In The World."
  137. PRINT "Map size : "; (mapH * mapW * 24) / 1024; " kB"
  138.  
  139. glAllow = -1
  140.     theta = (_MOUSEX / _WIDTH) * _PI(2.5) 'controls x-axis rotation
  141.     phi = map(_MOUSEY, 0, _HEIGHT, -_PI(0), _PI(0.5)) 'controls y-axis rotation
  142.  
  143.     IF Cam.mpos.z > mapH - 2 THEN Cam.mpos.z = mapH - 2 'prevent reaching out of the world map
  144.     IF Cam.mpos.x > mapW - 2 THEN Cam.mpos.x = mapW - 2 '
  145.     IF Cam.mpos.z < 2 THEN Cam.mpos.z = 2 '
  146.     IF Cam.mpos.x < 2 THEN Cam.mpos.x = 2 '
  147.  
  148.     IF _KEYDOWN(ASC("w")) OR _KEYDOWN(ASC("W")) THEN 'forward movement based on y-axis rotation
  149.         Cam.mpos.z = Cam.mpos.z + SIN(theta) * 0.3: Cam.mpos.x = Cam.mpos.x + COS(theta) * 0.3
  150.     END IF
  151.     IF _KEYDOWN(ASC("s")) OR _KEYDOWN(ASC("S")) THEN ' backward movement based on y-axis rotation
  152.         Cam.mpos.z = Cam.mpos.z - SIN(theta) * 0.3: Cam.mpos.x = Cam.mpos.x - COS(theta) * 0.3
  153.     END IF
  154.     IF _KEYDOWN(ASC("a")) OR _KEYDOWN(ASC("A")) THEN 'left movement based on y-axis rotation
  155.         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
  156.     END IF
  157.     IF _KEYDOWN(ASC("d")) OR _KEYDOWN(ASC("D")) THEN 'right movement based on y-axis rotation
  158.         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
  159.     END IF
  160.  
  161.     IF _KEYHIT = ASC(" ") THEN 'switching between MODs
  162.         IF worldMOD = 2 THEN worldMOD = 0 ELSE worldMOD = worldMOD + 1
  163.     END IF
  164.  
  165.     CLS , 1 'clear the screen and make it transparent so that GL context not get hidden.
  166.     _LIMIT 60
  167.  
  168.     'rotation of world causes rotation of map too. calculation of the source points of map is done below
  169.     sx1 = COS(_PI(.75) + theta) * 50 * sqrt2 + Cam.mpos.x + 150: sy1 = SIN(_PI(.75) + theta) * 50 * sqrt2 + Cam.mpos.z + 150
  170.     sx2 = COS(_PI(1.25) + theta) * 50 * sqrt2 + Cam.mpos.x + 150: sy2 = SIN(_PI(1.25) + theta) * 50 * sqrt2 + Cam.mpos.z + 150
  171.     sx3 = COS(_PI(1.75) + theta) * 50 * sqrt2 + Cam.mpos.x + 150: sy3 = SIN(_PI(1.75) + theta) * 50 * sqrt2 + Cam.mpos.z + 150
  172.     sx4 = COS(_PI(2.25) + theta) * 50 * sqrt2 + Cam.mpos.x + 150: sy4 = SIN(_PI(2.25) + theta) * 50 * sqrt2 + Cam.mpos.z + 150
  173.     'displaying the minimap
  174.     _MAPTRIANGLE (sx3, sy3)-(sx4, sy4)-(sx2, sy2), worldMap& TO(0, _HEIGHT - 100 * sqrt2)-(100 * sqrt2, _HEIGHT - 100 * sqrt2)-(0, _HEIGHT - 1)
  175.     _MAPTRIANGLE (sx2, sy2)-(sx4, sy4)-(sx1, sy1), worldMap& TO(0, _HEIGHT - 1)-(100 * sqrt2, _HEIGHT - 100 * sqrt2)-(100 * sqrt2, _HEIGHT - 1)
  176.     'showing your location
  177.     _PUTIMAGE (50 * sqrt2, _HEIGHT - 50 * sqrt2)-STEP(10, 10), myLocation&
  178.     'drawing red border along the map make it attractive
  179.     LINE (1, _HEIGHT - 100 * sqrt2)-STEP(100 * sqrt2, 100 * sqrt2), _RGB(255, 0, 0), B
  180.     _DISPLAY
  181.  
  182.  
  183. SUB _GL () STATIC
  184.  
  185.     IF glAllow = 0 THEN EXIT SUB 'we are not ready yet
  186.  
  187.     IF NOT glSetup THEN
  188.         glSetup = -1
  189.         _glViewport 0, 0, _WIDTH, _HEIGHT 'define our rendering area
  190.  
  191.         aspect# = _WIDTH / _HEIGHT 'used to create perspective view
  192.  
  193.         rad = 1 'distance of camera from origin (0,0,0)
  194.         farPoint = 1.0 'far point of camera target
  195.  
  196.         'initialize camera
  197.         Cam.mpos.x = mapW / 2
  198.         Cam.mpos.z = mapH / 2
  199.         Cam.mpos.y = 6
  200.         'initialize textures for sky
  201.         FOR i = 1 TO UBOUND(skyTextures&)
  202.             _glGenTextures 1, _OFFSET(skyTextureHandle&(i - 1))
  203.  
  204.             DIM m AS _MEM
  205.             m = _MEMIMAGE(skyTextures&(i))
  206.  
  207.             _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(i - 1)
  208.             _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGB, _WIDTH(skyTextures&(i)), _HEIGHT(skyTextures&(i)), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  209.  
  210.             _MEMFREE m
  211.  
  212.             _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  213.             _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  214.             _FREEIMAGE skyTextures&(i)
  215.         NEXT
  216.     END IF
  217.  
  218.     IF worldMOD = 0 THEN _glClearColor 0.7, 0.8, 1.0, 1.0 'this makes the background look sky blue.
  219.     IF worldMOD = 1 THEN _glClearColor 0.031, 0.0, 0.307, 1.0 'night sky
  220.     IF worldMOD = 2 THEN _glClearColor 0.0, 0.0, 0.0, 1.0
  221.     _glClear _GL_COLOR_BUFFER_BIT
  222.  
  223.     _glEnable _GL_DEPTH_TEST 'Of course, we are going to do 3D
  224.     _glClearDepth 10.0
  225.  
  226.     '_glEnable _GL_TEXTURE_2D 'so that we can use texture for our sky. :)
  227.  
  228.     IF worldMOD <> 2 THEN
  229.         _glEnable _GL_LIGHTING 'Without light, everything dull.
  230.         _glEnable _GL_LIGHT0
  231.     END IF
  232.  
  233.     IF worldMOD = 1 THEN
  234.         'night MOD
  235.         _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(0.05, 0.05, 0.33, 0)
  236.         _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.55, 0.55, 0.78, 0)
  237.         _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(0.75, 0.75, 0.98, 0)
  238.     ELSEIF worldMOD = 0 THEN
  239.         _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(0.35, 0.35, 0.33, 0) 'gives a bit yellowing color to the light
  240.         _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.75, 0.75, 0.60, 0) 'so it will feel like sun is in the sky
  241.         _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(0.95, 0.95, 0.80, 0)
  242.     END IF
  243.     _glShadeModel _GL_SMOOTH 'to make the rendering smooth
  244.  
  245.     _glMatrixMode _GL_PROJECTION
  246.     _gluPerspective 70, aspect#, 0.01, 10.0 'set up out perpective
  247.  
  248.     _glMatrixMode _GL_MODELVIEW
  249.  
  250.     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.
  251.  
  252.     'calculation of camera eye, its target, etc...
  253.     Cam.target.y = Cam.pos.y * COS(phi)
  254.     Cam.target.x = Cam.pos.x + COS(theta) * farPoint
  255.     Cam.target.z = Cam.pos.z + SIN(theta) * farPoint
  256.  
  257.     Cam.pos.x = map(Cam.mpos.x, 0, mapW, -mapW * 0.02, mapW * 0.02)
  258.     Cam.pos.z = map(Cam.mpos.z, 0, mapH, -mapH * 0.02, mapH * 0.02)
  259.     Cam.pos.y = Cam.mpos.y + 0.3
  260.  
  261.     gluLookAt Cam.pos.x, Cam.pos.y, Cam.pos.z, Cam.target.x, Cam.target.y, Cam.target.z, 0, 1, 0
  262.  
  263.  
  264.     'use of this skybox was avoided by me because I believe that it makes the scene a bit unrealistic.
  265.     ' skybox 5.0
  266.  
  267.     ' draw the world
  268.     _glEnable _GL_COLOR_MATERIAL
  269.     _glColorMaterial _GL_FRONT, _GL_AMBIENT_AND_DIFFUSE
  270.  
  271.     _glEnableClientState _GL_VERTEX_ARRAY
  272.     _glVertexPointer 3, _GL_FLOAT, 0, _OFFSET(mountVert())
  273.     _glEnableClientState _GL_COLOR_ARRAY
  274.     _glColorPointer 3, _GL_FLOAT, 0, _OFFSET(mountColor())
  275.     _glEnableClientState _GL_NORMAL_ARRAY
  276.     _glNormalPointer _GL_FLOAT, 0, _OFFSET(mountNormal())
  277.  
  278.     IF worldMOD = 2 THEN _glDrawArrays _GL_LINE_STRIP, 0, UBOUND(mountvert) / 3 ELSE _glDrawArrays _GL_TRIANGLE_STRIP, 0, UBOUND(mountVert) / 3
  279.  
  280.     _glDisableClientState _GL_VERTEX_ARRAY
  281.  
  282.  
  283.     _glFlush
  284.  
  285. 'draws a beautiful sky
  286. SUB skybox (s)
  287.     _glDisable _GL_LIGHTING
  288.     _glDisable _GL_LIGHT0
  289.     _glDisable _GL_DEPTH_TEST
  290.     _glDepthMask _GL_FALSE
  291.    
  292.     _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(4)
  293.    
  294.     _glBegin _GL_QUADS
  295.     _glTexCoord2f 0, 1
  296.     _glVertex3f -s, s, -s 'front
  297.     _glTexCoord2f 0, 0
  298.     _glVertex3f -s, -s, -s
  299.     _glTexCoord2f 1, 0
  300.     _glVertex3f s, -s, -s
  301.     _glTexCoord2f 1, 1
  302.     _glVertex3f s, s, -s
  303.     _glEnd
  304.    
  305.     _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(0)
  306.     _glBegin _GL_QUADS
  307.     _glTexCoord2f 0, 1
  308.     _glVertex3f -s, s, s 'rear
  309.     _glTexCoord2f 0, 0
  310.     _glVertex3f -s, -s, s
  311.     _glTexCoord2f 1, 0
  312.     _glVertex3f s, -s, s
  313.     _glTexCoord2f 1, 1
  314.     _glVertex3f s, s, s
  315.     _glEnd
  316.    
  317.     _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(1)
  318.     _glBegin _GL_QUADS
  319.     _glTexCoord2f 1, 0
  320.     _glVertex3f -s, s, s 'left
  321.     _glTexCoord2f 0, 0
  322.     _glVertex3f -s, -s, s
  323.     _glTexCoord2f 0, 1
  324.     _glVertex3f -s, -s, -s
  325.     _glTexCoord2f 1, 1
  326.     _glVertex3f -s, s, -s
  327.     _glEnd
  328.    
  329.     _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(3)
  330.     _glBegin _GL_QUADS
  331.     _glTexCoord2f 1, 0
  332.     _glVertex3f s, s, s 'right
  333.     _glTexCoord2f 0, 0
  334.     _glVertex3f s, -s, s
  335.     _glTexCoord2f 0, 1
  336.     _glVertex3f s, -s, -s
  337.     _glTexCoord2f 1, 1
  338.     _glVertex3f s, s, -s
  339.     _glEnd
  340.  
  341.     _glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(2)
  342.     _glBegin _GL_QUADS
  343.     _glTexCoord2f 0, 1
  344.     _glVertex3f -s, s, -s 'up
  345.     _glTexCoord2f 0, 0
  346.     _glVertex3f -s, s, s
  347.     _glTexCoord2f 1, 0
  348.     _glVertex3f s, s, s
  349.     _glTexCoord2f 1, 1
  350.     _glVertex3f s, s, -s
  351.     _glEnd
  352.    
  353.     _glDepthMask _GL_TRUE
  354.     _glEnable _GL_DEPTH_TEST
  355.     _glEnable _GL_LIGHTING
  356.     _glEnable _GL_LIGHT0
  357.  
  358. SUB setMountColor (xi, yi, i, h, h_max) 'assign color on the basis of height map and moisture map.
  359.     IF h > 0.8 * h_max THEN
  360.         IF moistureMap(xi, yi) < 0.1 THEN mountColor(i) = 0.333: mountColor(i + 1) = 0.333: mountColor(i + 2) = 0.333: EXIT SUB 'scorched
  361.         IF moistureMap(xi, yi) < 0.2 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.533: EXIT SUB 'bare
  362.         IF moistureMap(xi, yi) < 0.5 THEN mountColor(i) = 0.737: mountColor(i + 1) = 0.737: mountColor(i + 2) = 0.6705: EXIT SUB 'tundra
  363.         mountColor(i) = 0.8705: mountColor(i + 1) = 0.8705: mountColor(i + 2) = 0.898: EXIT SUB 'snow
  364.     END IF
  365.     IF h > 0.6 * h_max THEN
  366.         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
  367.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.466: EXIT SUB 'shrubland
  368.         mountColor(i) = 0.6: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.466: EXIT SUB 'taiga
  369.     END IF
  370.     IF h > 0.3 * h_max THEN
  371.         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
  372.         IF moistureMap(xi, yi) < 0.50 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  373.         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
  374.         mountColor(i) = 0.262: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.233: EXIT SUB 'temperate rain forest
  375.     END IF
  376.     IF h < 0.1 * h THEN mountColor(i) = 0.262: mountColor(i + 1) = 0.262: mountColor(i + 2) = 0.478: EXIT SUB 'ocean
  377.     IF h < 0.14 * h THEN mountColor(i) = 0.627: mountColor(i + 1) = 0.568: mountColor(i + 2) = 0.466: EXIT SUB 'beach
  378.     IF h <= 0.3 * h_max THEN
  379.         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
  380.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  381.         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
  382.         mountColor(i) = 0.2: mountColor(i + 1) = 0.466: mountColor(i + 2) = 0.333: EXIT SUB 'tropical rain forest
  383.     END IF
  384.  
  385. SUB generateTerrainData ()
  386.     DIM A AS vec3, B AS vec3, C AS vec3, R AS vec3
  387.     index = 0
  388.  
  389.     '##################################################################################################
  390.     '# Note : The below method consumes more memory. It uses 3x more vertex array than the next one.  #
  391.     '# So, use of this method was avoided by me.                                                      #
  392.     '##################################################################################################
  393.  
  394.     ' _dest _console
  395.     ' FOR z = 0 TO mapH - 1
  396.     ' FOR x = 0 TO mapW - 1
  397.     ' A = terrainData(x, z)
  398.     ' B = terrainData(x, z + 1)
  399.     ' C = terrainData(x + 1, z)
  400.     ' D = terrainData(x+1,z+1)
  401.  
  402.     ' ' ?index
  403.     ' ' OBJ_CalculateNormal A, B, C, R
  404.  
  405.     ' ' mountNormal(index) = R.x : mountNormal(index+1) = R.y : mountNormal(index+2) = R.z
  406.     ' ' mountNormal(index+3) = R.x : mountNormal(index+4) = R.y : mountNormal(index+5) = R.z
  407.     ' ' mountNormal(index+6) = R.x : mountNormal(index+7) = R.y : mountNormal(index+8) = R.z
  408.  
  409.     ' mountVert(index) = A.x : mountVert(index+1) = A.y : mountVert(index+2) = A.z : setMountColor x,z,index, A.y, mountHeightMax
  410.     ' mountVert(index+3) = B.x : mountVert(index+4) = B.y : mountVert(index+5) = B.z :  setMountColor x,z+1,index+3, B.y, mountHeightMax
  411.     ' mountVert(index+6) = C.x : mountVert(index+7) = C.y : mountVert(index+8) = C.z: setMountColor x+1,z,index+6, C.y, mountHeightMax
  412.  
  413.     ' ' OBJ_CalculateNormal C,B,D, R
  414.  
  415.     ' ' mountNormal(index+9) = R.x : mountNormal(index+10) = R.y : mountNormal(index+11) = R.z
  416.     ' ' mountNormal(index+12) = R.x : mountNormal(index+13) = R.y : mountNormal(index+14) = R.z
  417.     ' ' mountNormal(index+15) = R.x : mountNormal(index+16) = R.y : mountNormal(index+17) = R.z
  418.  
  419.     ' mountVert(index+9) = C.x : mountVert(index+10) = C.y : mountVert(index+11) = C.z: setMountColor x+1,z, index+9, C.y, mountHeightMax
  420.     ' mountVert(index+12) = B.x : mountVert(index+13) = B.y : mountVert(index+14) = B.z: setMountColor x,z+1,index+12, B.y, mountHeightMax
  421.     ' 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
  422.     ' index = index+18
  423.     ' NEXT x,z
  424.  
  425.     'this method is efficient than the above one.
  426.     DO
  427.         IF z MOD 2 = 0 THEN x = x + 1 ELSE x = x - 1
  428.  
  429.         A = terrainData(x, z) 'get out coordinates from our stored data
  430.         B = terrainData(x, z + 1)
  431.         C = terrainData(x + 1, z)
  432.  
  433.         OBJ_CalculateNormal A, B, C, R 'calculates the normal of a triangle
  434.  
  435.         'store color, coordinate & normal data in an array
  436.         mountNormal(index) = R.x: mountNormal(index + 1) = R.y: mountNormal(index + 2) = R.z
  437.         mountVert(index) = A.x: mountVert(index + 1) = A.y: mountVert(index + 2) = A.z: setMountColor x, z, index, A.y, mountHeightMax
  438.  
  439.         mountNormal(index + 3) = R.x: mountNormal(index + 4) = R.y: mountNormal(index + 5) = R.z
  440.         mountVert(index + 3) = B.x: mountVert(index + 4) = B.y: mountVert(index + 5) = B.z: setMountColor x, z + 1, index + 3, B.y, mountHeightMax
  441.  
  442.         index = index + 6
  443.  
  444.         IF x = mapW - 1 THEN
  445.             IF z MOD 2 = 0 THEN x = x + 1: z = z + 1
  446.         END IF
  447.         IF x = 1 THEN
  448.             IF z MOD 2 = 1 THEN x = x - 1: z = z + 1
  449.         END IF
  450.         IF z = mapH - 1 THEN EXIT DO
  451.     LOOP
  452.     _DEST 0
  453.  
  454.  
  455. FUNCTION p5random! (mn!, mx!)
  456.     IF mn! > mx! THEN
  457.         SWAP mn!, mx!
  458.     END IF
  459.     p5random! = RND * (mx! - mn!) + mn!
  460.  
  461.  
  462. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  463.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  464.  
  465. 'coded in QB64 by Fellipe Heitor
  466. 'Can be found in p5js.bas library
  467. 'http://bit.ly/p5jsbas
  468. FUNCTION noise! (x AS SINGLE, y AS SINGLE, z AS SINGLE)
  469.     STATIC p5NoiseSetup AS _BYTE
  470.     STATIC perlin() AS SINGLE
  471.     STATIC PERLIN_YWRAPB AS SINGLE, PERLIN_YWRAP AS SINGLE
  472.     STATIC PERLIN_ZWRAPB AS SINGLE, PERLIN_ZWRAP AS SINGLE
  473.     STATIC PERLIN_SIZE AS SINGLE
  474.  
  475.     IF p5NoiseSetup = 0 THEN
  476.         p5NoiseSetup = 1
  477.  
  478.         PERLIN_YWRAPB = 4
  479.         PERLIN_YWRAP = INT(1 * (2 ^ PERLIN_YWRAPB))
  480.         PERLIN_ZWRAPB = 8
  481.         PERLIN_ZWRAP = INT(1 * (2 ^ PERLIN_ZWRAPB))
  482.         PERLIN_SIZE = 4095
  483.  
  484.         perlin_octaves = 4
  485.         perlin_amp_falloff = 0.5
  486.  
  487.         REDIM perlin(PERLIN_SIZE + 1) AS SINGLE
  488.         DIM i AS SINGLE
  489.         FOR i = 0 TO PERLIN_SIZE + 1
  490.             perlin(i) = RND
  491.         NEXT
  492.     END IF
  493.  
  494.     x = ABS(x)
  495.     y = ABS(y)
  496.     z = ABS(z)
  497.  
  498.     DIM xi AS SINGLE, yi AS SINGLE, zi AS SINGLE
  499.     xi = INT(x)
  500.     yi = INT(y)
  501.     zi = INT(z)
  502.  
  503.     DIM xf AS SINGLE, yf AS SINGLE, zf AS SINGLE
  504.     xf = x - xi
  505.     yf = y - yi
  506.     zf = z - zi
  507.  
  508.     DIM r AS SINGLE, ampl AS SINGLE, o AS SINGLE
  509.     r = 0
  510.     ampl = .5
  511.  
  512.     FOR o = 1 TO perlin_octaves
  513.         DIM of AS SINGLE, rxf AS SINGLE
  514.         DIM ryf AS SINGLE, n1 AS SINGLE, n2 AS SINGLE, n3 AS SINGLE
  515.         of = xi + INT(yi * (2 ^ PERLIN_YWRAPB)) + INT(zi * (2 ^ PERLIN_ZWRAPB))
  516.  
  517.         rxf = 0.5 * (1.0 - COS(xf * _PI))
  518.         ryf = 0.5 * (1.0 - COS(yf * _PI))
  519.  
  520.         n1 = perlin(of AND PERLIN_SIZE)
  521.         n1 = n1 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n1)
  522.         n2 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  523.         n2 = n2 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n2)
  524.         n1 = n1 + ryf * (n2 - n1)
  525.  
  526.         of = of + PERLIN_ZWRAP
  527.         n2 = perlin(of AND PERLIN_SIZE)
  528.         n2 = n2 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n2)
  529.         n3 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  530.         n3 = n3 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n3)
  531.         n2 = n2 + ryf * (n3 - n2)
  532.  
  533.         n1 = n1 + (0.5 * (1.0 - COS(zf * _PI))) * (n2 - n1)
  534.  
  535.         r = r + n1 * ampl
  536.         ampl = ampl * perlin_amp_falloff
  537.         xi = INT(xi * (2 ^ 1))
  538.         xf = xf * 2
  539.         yi = INT(yi * (2 ^ 1))
  540.         yf = yf * 2
  541.         zi = INT(zi * (2 ^ 1))
  542.         zf = zf * 2
  543.  
  544.         IF xf >= 1.0 THEN xi = xi + 1: xf = xf - 1
  545.         IF yf >= 1.0 THEN yi = yi + 1: yf = yf - 1
  546.         IF zf >= 1.0 THEN zi = zi + 1: zf = zf - 1
  547.     NEXT
  548.     noise! = r
  549.  
  550. SUB noiseDetail (lod!, falloff!)
  551.     IF lod! > 0 THEN perlin_octaves = lod!
  552.     IF falloff! > 0 THEN perlin_amp_falloff = falloff!
  553.  
  554. 'method adapted form http://stackoverflow.com/questions/4106363/converting-rgb-to-hsb-colors
  555. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  556.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  557.  
  558.     H = map(__H, 0, 255, 0, 360)
  559.     S = map(__S, 0, 255, 0, 1)
  560.     B = map(__B, 0, 255, 0, 1)
  561.  
  562.     IF S = 0 THEN
  563.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  564.         EXIT FUNCTION
  565.     END IF
  566.  
  567.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  568.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  569.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  570.  
  571.     IF B > .5 THEN
  572.         fmx = B - (B * S) + S
  573.         fmn = B + (B * S) - S
  574.     ELSE
  575.         fmx = B + (B * S)
  576.         fmn = B - (B * S)
  577.     END IF
  578.  
  579.     iSextant = INT(H / 60)
  580.  
  581.     IF H >= 300 THEN
  582.         H = H - 360
  583.     END IF
  584.  
  585.     H = H / 60
  586.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  587.  
  588.     IF iSextant MOD 2 = 0 THEN
  589.         fmd = (H * (fmx - fmn)) + fmn
  590.     ELSE
  591.         fmd = fmn - (H * (fmx - fmn))
  592.     END IF
  593.  
  594.     imx = _ROUND(fmx * 255)
  595.     imd = _ROUND(fmd * 255)
  596.     imn = _ROUND(fmn * 255)
  597.  
  598.     SELECT CASE INT(iSextant)
  599.         CASE 1
  600.             hsb~& = _RGBA32(imd, imx, imn, A)
  601.         CASE 2
  602.             hsb~& = _RGBA32(imn, imx, imd, A)
  603.         CASE 3
  604.             hsb~& = _RGBA32(imn, imd, imx, A)
  605.         CASE 4
  606.             hsb~& = _RGBA32(imd, imn, imx, A)
  607.         CASE 5
  608.             hsb~& = _RGBA32(imx, imn, imd, A)
  609.         CASE ELSE
  610.             hsb~& = _RGBA32(imx, imd, imn, A)
  611.     END SELECT
  612.  
  613.  
  614.  
  615. SUB OBJ_CalculateNormal (p1 AS vec3, p2 AS vec3, p3 AS vec3, N AS vec3)
  616.     DIM U AS vec3, V AS vec3
  617.  
  618.     U.x = p2.x - p1.x
  619.     U.y = p2.y - p1.y
  620.     U.z = p2.z - p1.z
  621.  
  622.     V.x = p3.x - p1.x
  623.     V.y = p3.y - p1.y
  624.     V.z = p3.z - p1.z
  625.  
  626.     N.x = (U.y * V.z) - (U.z * V.y)
  627.     N.y = (U.z * V.x) - (U.x * V.z)
  628.     N.z = (U.x * V.y) - (U.y * V.x)
  629.     OBJ_Normalize N
  630.  
  631. SUB OBJ_Normalize (V AS vec3)
  632.     mag! = SQR(V.x * V.x + V.y * V.y + V.z * V.z)
  633.     V.x = V.x / mag!
  634.     V.y = V.y / mag!
  635.     V.z = V.z / mag!
  636.  
  637. FUNCTION glVec4%& (x, y, z, w)
  638.     STATIC internal_vec4(3)
  639.     internal_vec4(0) = x
  640.     internal_vec4(1) = y
  641.     internal_vec4(2) = z
  642.     internal_vec4(3) = w
  643.     glVec4%& = _OFFSET(internal_vec4())
  644.  


 [ This attachment cannot be displayed inline in 'Print Page' view ]  
MOD : Sunny Day

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
MOD : Night time.
Title: Re: 3D OpenWorld Mountains
Post by: bplus on March 08, 2019, 08:38:49 am
Wow! Fabulous!
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 08, 2019, 08:43:35 am
@bplus
I'm glad you enjoyed it. :D
Title: Re: 3D OpenWorld Mountains
Post by: FellippeHeitor on March 08, 2019, 08:59:56 am
This is *very* impressive, Ashish. Great job!
Title: Re: 3D OpenWorld Mountains
Post by: johnno56 on March 08, 2019, 09:04:46 am
What! No trees or bunny rabbits? Nah, kidding. Very nicely done indeed...
But, seriously, I wandered all over that landscape and didn't spot one zombie or alien...
Title: Re: 3D OpenWorld Mountains
Post by: qb4ever on March 08, 2019, 09:08:45 am
WOW Ashish !
Stunning job !
Title: Re: 3D OpenWorld Mountains
Post by: _vince on March 08, 2019, 09:24:04 am
nice job, reminds me of http://www.petesqbsite.com/reviews/engines/xeno.html (http://www.petesqbsite.com/reviews/engines/xeno.html) also a similar concept to static's sanctus
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 08, 2019, 09:28:21 am
@Fellippe, @qb4ever
Thank You!
@johnno56
I agree. I think this program can be modify into a 3D game or something? like PUBG?
@vince
Thanks! Yeah. I was inspired by many of them. I liked STxAxTIC's engine and also a similar demo posted by Petr using _MAPTRIANGLE.
Title: Re: 3D OpenWorld Mountains
Post by: Petr on March 08, 2019, 09:54:15 am
God, that's something! That's fantastic!
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 08, 2019, 10:01:07 am
Thank You, Petr! :)
Title: Re: 3D OpenWorld Mountains
Post by: TempodiBasic on March 08, 2019, 07:25:08 pm
Hi Ashish

cool this world!
But where is the EasterEgg? Moving across it I haven't met hidden surprise!

Thanks to share it.
Title: Re: 3D OpenWorld Mountains
Post by: STxAxTIC on March 09, 2019, 01:01:59 pm
Looks fantastic Ashish, you continue to astound us all! This code is a great guide for people (thinking mostly of myself here) to understand how QB64 interfaces with GL tech in a less-than-trivial way.

It looks like GL has done the 'painter's algorithm' (or something similar) to avoid drawing the background first - or did you explicitly do some z-sorting without being obvious about it? I also assume the nasty math of calculating 3D projections is handled by GL somewhere deep behind the blue screen.

All that said, this demo is worth becoming an entry in the Samples section. Are you supposing this is the final version for now, or should we wait a little while?

When I was your age I was proud to make a Mystify screensaver clone. Are you sure your last name isn't Skywalker?
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 10, 2019, 11:52:29 am
Hi Ashish

cool this world!
But where is the EasterEgg? Moving across it I haven't met hidden surprise!

Thanks to share it.
Thank You. Okay I think many of you expect a surprise in this demo. I will add a surprsie in it soon. (You know my final exams are going on).

Looks fantastic Ashish, you continue to astound us all! This code is a great guide for people (thinking mostly of myself here) to understand how QB64 interfaces with GL tech in a less-than-trivial way.

It looks like GL has done the 'painter's algorithm' (or something similar) to avoid drawing the background first - or did you explicitly do some z-sorting without being obvious about it? I also assume the nasty math of calculating 3D projections is handled by GL somewhere deep behind the blue screen.

All that said, this demo is worth becoming an entry in the Samples section. Are you supposing this is the final version for now, or should we wait a little while?

When I was your age I was proud to make a Mystify screensaver clone. Are you sure your last name isn't Skywalker?
Thank you, STxAxTIC. I don't have to do any calculation except for position of camera, its target & for elevation data. OpenGL do calculation of projection with function gluPerspective(fov,aspect,zNear,zFar). Depth calculation done automatically by GPU when it is enable using glEnable(GL_DEPTH_TEST).

I will be proud if it get into samples gallery but this is not final version. It will receive one or two more updates by me. I apologize, but you all have to wait a little. :)

My last name is "Kushwaha". But what I have to do with last name Skywalker? What does it mean?
Title: Re: 3D OpenWorld Mountains
Post by: Pete on March 10, 2019, 02:10:45 pm
... But what I have to do with last name Skywalker? What does it mean?

It means you're my new best friend! Man, I hate Star Wars. Nice to meet someone who apparently never heard of it, never saw it, or saw it and was so bored, never took in who the main character was. :D :D :D

Anyway... Hey new best friend, you owe me a new set of dentures! That's right, they broke with all that bumpiness I experienced while traveling. Can there be a way to travel without all that bumpiness? A gain / decrease altitude key maybe? Well, other than that, I curious how much GL you had to learn to put this together? I figure you're just a few IQ points behind me, when I was your age and washing machines were being invented... (wow, I bet he's worried about his future now...) So you have me wondering if I could pick up on this stuff someday? I can envision a golf simulator, so when I'm too old to carry the clubs, thinking next Tuesday, I can just carry a mouse and navigate through Torrey Pines. Anyway, kidding aside, great job! If I saw homemade stuff like this 40 years ago, I'd probably  be a retire graphics designer. I'd put fire breathing dragons in this simulation, and give the point of view character a cross bow. Evade the dragons and shoot them or get hit by fire balls and loose a life. Maybe put a castle somewhere in the map, and if you reach it, you win.

Oh well, enough rambling, it's time for my mid-morning nap. Oh, don't worry too much about the teeth and the mind stuff. Your hair will fall out long before any of that stuff happens.

Pete

- My the Force be without you!
Title: Re: 3D OpenWorld Mountains
Post by: TempodiBasic on March 10, 2019, 02:13:37 pm
@Pete
why do you hate SpaceBalls?
Title: Re: 3D OpenWorld Mountains
Post by: Pete 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
Title: Re: 3D OpenWorld Mountains
Post by: johnno56 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
Title: Re: 3D OpenWorld Mountains
Post by: Ashish 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".
Title: Re: 3D OpenWorld Mountains
Post by: Jack002 on March 14, 2019, 02:49:48 pm
Firefly is better than either
Title: Re: 3D OpenWorld Mountains
Post by: Petr 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
Title: Re: 3D OpenWorld Mountains
Post by: SMcNeill 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/
Title: Re: 3D OpenWorld Mountains
Post by: TempodiBasic 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=QRl-LiF1VsU)
https://www.youtube.com/watch?v=EBh_m9hx2bE (https://www.youtube.com/watch?v=EBh_m9hx2bE)
https://www.youtube.com/watch?v=wBi_W6euny0 (https://www.youtube.com/watch?v=wBi_W6euny0)
Title: Re: 3D OpenWorld Mountains
Post by: Pete 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=QRl-LiF1VsU)
https://www.youtube.com/watch?v=EBh_m9hx2bE (https://www.youtube.com/watch?v=EBh_m9hx2bE)
https://www.youtube.com/watch?v=wBi_W6euny0 (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
Title: Re: 3D OpenWorld Mountains
Post by: TempodiBasic 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
Title: Re: 3D OpenWorld Mountains
Post by: Pete 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.
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 17, 2019, 06:13:51 am
Hi everyone!

Here are the some changes done to the program -

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.  
Title: Re: 3D OpenWorld Mountains
Post by: bplus 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:
  [ This attachment cannot be displayed inline in 'Print Page' view ]  
  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: 3D OpenWorld Mountains
Post by: Petr 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.
Title: Re: 3D OpenWorld Mountains
Post by: Ashish 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.  

Title: Re: 3D OpenWorld Mountains
Post by: bplus 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. :)
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 23, 2019, 09:38:47 am
Have you found the another secret ice MOD?
Title: Re: 3D OpenWorld Mountains
Post by: Petr on March 23, 2019, 09:52:12 am
Hi Ashish. It works great. To build something on such a level with the MAPTRIANGLE command would be utter insanity. It's just wonderful. Especially after passing through the surprise.
Title: Re: 3D OpenWorld Mountains
Post by: bplus on March 23, 2019, 10:01:46 am
Quote
"Find another secret ice MOD?"

Guess not, I checked out small dots like red for cube, no luck...

Is it too early to ask for hint?
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 23, 2019, 10:25:59 am
@Petr
Thanks. It will receive some more updates.
@bplus
Hint : When you pass through surprise, then there are possibility of showing 2 secret MODs on random. If you found one, try to run the program again. You will be lucky if you find other.
Title: Re: 3D OpenWorld Mountains
Post by: Ashish on March 23, 2019, 11:44:38 am
NEW UPDATE -

Here's the 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&(3), worldTextureHandle&(2)
  68.  
  69. tmp& = _LOADIMAGE(WriteqbiconData$("qb.png"))
  70. KILL "qb.png"
  71. worldTextures&(1) = _NEWIMAGE(32, 32, 32) '3 32's
  72. _PUTIMAGE (0, 32)-(32, 0), tmp&, worldTextures&(1)
  73.  
  74. _DEST worldMap&
  75. CLS , _RGB(0, 0, 255)
  76.  
  77. 'day sky containing some clouds
  78. worldTextures&(2) = _NEWIMAGE(400, 400, 32)
  79.  
  80. _DEST worldTextures&(2)
  81. CLS , _RGB(109, 164, 255)
  82. FOR y = 0 TO _HEIGHT - 1
  83.     FOR x = 0 TO _WIDTH - 1
  84.         j1# = map(ABS((_WIDTH / 2) - x), _WIDTH / 2, 70, 0, 1)
  85.         j2# = map(ABS((_HEIGHT / 2) - y), _HEIGHT / 2, 70, 0, 1)
  86.         noiseDetail 5, 0.46789
  87.         k! = (ABS(noise(x * 0.04, y * 0.04, x / y * 0.01)) * 1.3) ^ 3 * j1# * j2#
  88.         PSET (x, y), _RGBA(255, 255, 255, k! * 255)
  89. NEXT x, y
  90. 'starry night sky texture
  91. worldTextures&(3) = _NEWIMAGE(_WIDTH * 3, _HEIGHT * 3, 32)
  92. _DEST worldTextures&(3)
  93. CLS , _RGB(7, 0, 102)
  94. FOR i = 0 TO 300
  95.     cx = p5random(10, _WIDTH - 10): cy = p5random(10, _HEIGHT - 10)
  96.     CircleFill cx, cy, p5random(0, 2), _RGBA(255, 255, 255, p5random(0, 255))
  97. DIM SHARED Cam AS camera, theta, phi
  98.  
  99.  
  100. DIM SHARED glAllow AS _BYTE
  101. RESTORE blipicon
  102. _DEST myLocation& 'Generating the blip icon
  103. FOR i = 0 TO 10
  104.     FOR j = 0 TO 10
  105.         READ cx
  106.         IF cx = 1 THEN PSET (j, i), _RGB(255, 0, 200)
  107. NEXT j, i
  108. 'image data of blip icon
  109. blipicon:
  110. DATA 0,0,0,0,0,1,0,0,0,0,0
  111. DATA 0,0,0,0,0,1,0,0,0,0,0
  112. DATA 0,0,0,0,1,1,1,0,0,0,0
  113. DATA 0,0,0,1,1,1,1,1,0,0,0
  114. DATA 0,0,0,1,1,1,1,1,0,0,0
  115. DATA 0,0,1,1,1,1,1,1,1,0,0
  116. DATA 0,1,1,1,1,1,1,1,1,1,0
  117. DATA 0,1,1,1,1,1,1,1,1,1,0
  118. DATA 1,1,1,1,0,0,0,1,1,1,1
  119. DATA 1,1,0,0,0,0,0,0,0,1,1
  120. DATA 1,0,0,0,0,0,0,0,0,0,1
  121. DATA 0,0,0,0,0,0,0,0,0,0,0
  122.  
  123.  
  124. 'Map elevations and mositure calculation done here with the help of perlin noise
  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 OR _GL_DEPTH_BUFFER_BIT
  270.  
  271.     _glEnable _GL_DEPTH_TEST 'Of course, we are going to do 3D
  272.     _glDepthMask _GL_TRUE
  273.  
  274.  
  275.     _glEnable _GL_TEXTURE_2D 'so that we can use texture for our sky. :)
  276.  
  277.     IF worldMOD <> 2 THEN
  278.         _glEnable _GL_LIGHTING 'Without light, everything dull.
  279.         _glEnable _GL_LIGHT0
  280.     END IF
  281.  
  282.     IF worldMOD = 1 THEN
  283.         'night MOD
  284.         _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(0.05, 0.05, 0.33, 0)
  285.         _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.55, 0.55, 0.78, 0)
  286.         _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(0.75, 0.75, 0.98, 0)
  287.     ELSEIF worldMOD = 0 THEN
  288.         _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(0.35, 0.35, 0.33, 0) 'gives a bit yellowing color to the light
  289.         _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.75, 0.75, 0.60, 0) 'so it will feel like sun is in the sky
  290.         _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(0.95, 0.95, 0.80, 0)
  291.     ELSEIF worldMOD = 3 THEN 'disco light
  292.         _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(kR / 2, kG / 2, kB / 2, 0)
  293.         _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(kR * 0.9, kG * 0.9, kB * 0.9, 0)
  294.         _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(kR, kG, kB, 0)
  295.     END IF
  296.     _glShadeModel _GL_SMOOTH 'to make the rendering smooth
  297.  
  298.     _glMatrixMode _GL_PROJECTION
  299.     _gluPerspective 70, aspect#, 0.01, 15.0 'set up out perpective
  300.  
  301.     _glMatrixMode _GL_MODELVIEW
  302.  
  303.     ' IF Cam.mpos.y > (terrainMap(Cam.mpos.x, Cam.mpos.z)) THEN Cam.mpos.y = Cam.mpos.y - 0.03 ELSE
  304.     Cam.mpos.y = meanAreaHeight(1, Cam.mpos.x, Cam.mpos.z) 'if you are in air then you must fall.
  305.  
  306.     'calculation of camera eye, its target, etc...
  307.     Cam.pos.x = map(Cam.mpos.x, 0, mapW, -mapW * 0.04, mapW * 0.04)
  308.     Cam.pos.z = map(Cam.mpos.z, 0, mapH, -mapH * 0.04, mapH * 0.04)
  309.     Cam.pos.y = Cam.mpos.y + 0.3
  310.  
  311.     Cam.target.y = Cam.pos.y * COS(phi)
  312.     Cam.target.x = Cam.pos.x + COS(theta) * farPoint
  313.     Cam.target.z = Cam.pos.z + SIN(theta) * farPoint
  314.  
  315.     gluLookAt Cam.pos.x, Cam.pos.y, Cam.pos.z, Cam.target.x, Cam.target.y, Cam.target.z, 0, 1, 0
  316.  
  317.  
  318.  
  319.     ' draw the world
  320.     _glEnable _GL_COLOR_MATERIAL
  321.     _glColorMaterial _GL_FRONT, _GL_AMBIENT_AND_DIFFUSE
  322.  
  323.     _glEnableClientState _GL_VERTEX_ARRAY
  324.     _glVertexPointer 3, _GL_FLOAT, 0, _OFFSET(mountVert())
  325.     _glEnableClientState _GL_COLOR_ARRAY
  326.     _glColorPointer 3, _GL_FLOAT, 0, _OFFSET(mountColor())
  327.     _glEnableClientState _GL_NORMAL_ARRAY
  328.     _glNormalPointer _GL_FLOAT, 0, _OFFSET(mountNormal())
  329.  
  330.     IF worldMOD = 2 THEN _glDrawArrays _GL_LINE_STRIP, 1, (UBOUND(mountvert) / 3) - 1 ELSE _glDrawArrays _GL_TRIANGLE_STRIP, 1, (UBOUND(mountVert) / 3) - 1
  331.     _glDisableClientState _GL_VERTEX_ARRAY
  332.     _glDisableClientState _GL_COLOR_ARRAY
  333.     _glDisableClientState _GL_NORMAL_ARRAY
  334.     _glDisable _GL_COLOR_MATERIAL
  335.  
  336.  
  337.     _glDisable _GL_LIGHTING
  338.     IF worldMOD <> 3 AND snowMount <> 2 THEN showSurprise 0.4, Cam.pos
  339.  
  340.     _glMatrixMode _GL_PROJECTION
  341.     _gluPerspective 70, aspect#, 0.01, 100
  342.  
  343.     _glMatrixMode _GL_MODELVIEW
  344.  
  345.     skybox 32.0 'sky
  346.  
  347.     _glFlush
  348.  
  349.     clock# = clock# + .5
  350.  
  351. FUNCTION meanAreaHeight# (n%, x%, y%)
  352.     FOR i = y% - n% TO y% + n%
  353.         FOR j = x% - n% TO x% + n%
  354.             h# = h# + terrainMap(j, i)
  355.             g% = g% + 1
  356.     NEXT j, i
  357.     meanAreaHeight# = (h# / g%)
  358.  
  359. SUB showSurprise (s, a AS vec3)
  360.     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
  361.         IF RND > 0.5 THEN
  362.             worldMOD = 3
  363.             _TITLE "You finally came to know that its QB64 Island!!"
  364.         ELSE
  365.             snowMount = 1
  366.             _TITLE "Welcome to this new world..."
  367.             Cam.mpos.y = 6
  368.         END IF
  369.     END IF
  370.  
  371.     _glBindTexture _GL_TEXTURE_2D, worldTextureHandle&(0)
  372.  
  373.     _glBegin _GL_QUADS
  374.     _glTexCoord2f 0, 1
  375.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y + 2 * s, Surprise.pos.z - s 'front
  376.     _glTexCoord2f 0, 0
  377.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, Surprise.pos.z - s
  378.     _glTexCoord2f 1, 0
  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 0, 1
  386.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y + 2 * s, Surprise.pos.z + s 'rear
  387.     _glTexCoord2f 0, 0
  388.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, Surprise.pos.z + s
  389.     _glTexCoord2f 1, 0
  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
  396.     _glTexCoord2f 1, 0
  397.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y + 2 * s, Surprise.pos.z + s 'left
  398.     _glTexCoord2f 0, 0
  399.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, Surprise.pos.z + s
  400.     _glTexCoord2f 0, 1
  401.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, 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
  407.     _glTexCoord2f 1, 0
  408.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y + 2 * s, Surprise.pos.z + s 'right
  409.     _glTexCoord2f 0, 0
  410.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y, Surprise.pos.z + s
  411.     _glTexCoord2f 0, 1
  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 + 2 * s, Surprise.pos.z - s
  415.     _glEnd
  416.  
  417.     _glBegin _GL_QUADS 'up
  418.     _glTexCoord2f 0, 1
  419.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y + 2 * s, Surprise.pos.z - s 'up
  420.     _glTexCoord2f 0, 0
  421.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y + 2 * s, Surprise.pos.z + s
  422.     _glTexCoord2f 1, 0
  423.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y + 2 * s, Surprise.pos.z + s
  424.     _glTexCoord2f 1, 1
  425.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y + 2 * s, Surprise.pos.z - s
  426.     _glEnd
  427.  
  428.     _glBegin _GL_QUADS 'down
  429.     _glTexCoord2f 0, 1
  430.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, Surprise.pos.z - s 'up
  431.     _glTexCoord2f 0, 0
  432.     _glVertex3f Surprise.pos.x - s, Surprise.pos.y, Surprise.pos.z + s
  433.     _glTexCoord2f 1, 0
  434.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y, Surprise.pos.z + s
  435.     _glTexCoord2f 1, 1
  436.     _glVertex3f Surprise.pos.x + s, Surprise.pos.y, Surprise.pos.z - s
  437.     _glEnd
  438.  
  439.  
  440. 'draws a beautiful sky
  441. SUB skybox (s)
  442.     IF worldMOD > 1 THEN EXIT SUB
  443.  
  444.     _glDepthMask _GL_FALSE
  445.  
  446.     IF worldMOD = 0 THEN _glBindTexture _GL_TEXTURE_2D, worldTextureHandle&(1) ELSE _glBindTexture _GL_TEXTURE_2D, worldTextureHandle&(2)
  447.  
  448.     _glBegin _GL_QUADS
  449.     _glTexCoord2f 0, 1
  450.     _glVertex3f -s, s, -s 'front
  451.     _glTexCoord2f 0, 0
  452.     _glVertex3f -s, -s, -s
  453.     _glTexCoord2f 1, 0
  454.     _glVertex3f s, -s, -s
  455.     _glTexCoord2f 1, 1
  456.     _glVertex3f s, s, -s
  457.     _glEnd
  458.  
  459.     '_glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(0)
  460.     _glBegin _GL_QUADS
  461.     _glTexCoord2f 0, 1
  462.     _glVertex3f -s, s, s 'rear
  463.     _glTexCoord2f 0, 0
  464.     _glVertex3f -s, -s, s
  465.     _glTexCoord2f 1, 0
  466.     _glVertex3f s, -s, s
  467.     _glTexCoord2f 1, 1
  468.     _glVertex3f s, s, s
  469.     _glEnd
  470.  
  471.     '_glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(1)
  472.     _glBegin _GL_QUADS
  473.     _glTexCoord2f 1, 0
  474.     _glVertex3f -s, s, s 'left
  475.     _glTexCoord2f 0, 0
  476.     _glVertex3f -s, -s, s
  477.     _glTexCoord2f 0, 1
  478.     _glVertex3f -s, -s, -s
  479.     _glTexCoord2f 1, 1
  480.     _glVertex3f -s, s, -s
  481.     _glEnd
  482.  
  483.     '_glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(3)
  484.     _glBegin _GL_QUADS
  485.     _glTexCoord2f 1, 0
  486.     _glVertex3f s, s, s 'right
  487.     _glTexCoord2f 0, 0
  488.     _glVertex3f s, -s, s
  489.     _glTexCoord2f 0, 1
  490.     _glVertex3f s, -s, -s
  491.     _glTexCoord2f 1, 1
  492.     _glVertex3f s, s, -s
  493.     _glEnd
  494.  
  495.     '_glBindTexture _GL_TEXTURE_2D, skyTextureHandle&(2)
  496.     _glBegin _GL_QUADS
  497.     _glTexCoord2f 0, 1
  498.     _glVertex3f -s, s, -s 'up
  499.     _glTexCoord2f 0, 0
  500.     _glVertex3f -s, s, s
  501.     _glTexCoord2f 1, 0
  502.     _glVertex3f s, s, s
  503.     _glTexCoord2f 1, 1
  504.     _glVertex3f s, s, -s
  505.     _glEnd
  506.  
  507.     _glDepthMask _GL_TRUE
  508.  
  509. SUB setMountColor (xi, yi, i, h, h_max) 'assign color on the basis of height map and moisture map.
  510.     IF snowMount = 1 THEN
  511.         IF h > 0.8 * h_max THEN mountColor(i) = 0.439: mountColor(i + 1) = 0.988: mountColor(i + 2) = 0.988: EXIT SUB
  512.         mountColor(i) = 1: mountColor(i + 1) = 1: mountColor(i + 2) = 1
  513.         EXIT SUB
  514.     END IF
  515.     IF h > 0.8 * h_max THEN
  516.         IF moistureMap(xi, yi) < 0.1 THEN mountColor(i) = 0.333: mountColor(i + 1) = 0.333: mountColor(i + 2) = 0.333: EXIT SUB 'scorched
  517.         IF moistureMap(xi, yi) < 0.2 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.533: EXIT SUB 'bare
  518.         IF moistureMap(xi, yi) < 0.5 THEN mountColor(i) = 0.737: mountColor(i + 1) = 0.737: mountColor(i + 2) = 0.6705: EXIT SUB 'tundra
  519.         mountColor(i) = 0.8705: mountColor(i + 1) = 0.8705: mountColor(i + 2) = 0.898: EXIT SUB 'snow
  520.     END IF
  521.     IF h > 0.6 * h_max THEN
  522.         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
  523.         IF moistureMap(xi, yi) < 0.66 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.600: mountColor(i + 2) = 0.466: EXIT SUB 'shrubland
  524.         mountColor(i) = 0.6: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.466: EXIT SUB 'taiga
  525.     END IF
  526.     IF h > 0.3 * h_max THEN
  527.         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
  528.         IF moistureMap(xi, yi) < 0.50 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  529.         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
  530.         mountColor(i) = 0.262: mountColor(i + 1) = 0.533: mountColor(i + 2) = 0.233: EXIT SUB 'temperate rain forest
  531.     END IF
  532.     IF h < 0.01 * h_max THEN mountColor(i) = 0.262: mountColor(i + 1) = 0.262: mountColor(i + 2) = 0.478: EXIT SUB 'ocean
  533.     IF h < 0.07 * h_max THEN mountColor(i) = 0.627: mountColor(i + 1) = 0.568: mountColor(i + 2) = 0.466: EXIT SUB 'beach
  534.     IF h <= 0.3 * h_max THEN
  535.         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
  536.         IF moistureMap(xi, yi) < 0.33 THEN mountColor(i) = 0.533: mountColor(i + 1) = 0.6705: mountColor(i + 2) = 0.333: EXIT SUB 'grassland
  537.         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
  538.         mountColor(i) = 0.2: mountColor(i + 1) = 0.466: mountColor(i + 2) = 0.333: EXIT SUB 'tropical rain forest
  539.     END IF
  540.  
  541. SUB generateTerrainData ()
  542.     DIM A AS vec3, B AS vec3, C AS vec3, R AS vec3
  543.     index = 0
  544.  
  545.     '##################################################################################################
  546.     '# Note : The below method consumes more memory. It uses 3x more vertex array than the next one.  #
  547.     '# So, use of this method was avoided by me.                                                      #
  548.     '##################################################################################################
  549.  
  550.     ' _dest _console
  551.     ' FOR z = 0 TO mapH - 1
  552.     ' FOR x = 0 TO mapW - 1
  553.     ' A = terrainData(x, z)
  554.     ' B = terrainData(x, z + 1)
  555.     ' C = terrainData(x + 1, z)
  556.     ' D = terrainData(x+1,z+1)
  557.  
  558.     ' ' ?index
  559.     ' ' OBJ_CalculateNormal A, B, C, R
  560.  
  561.     ' ' mountNormal(index) = R.x : mountNormal(index+1) = R.y : mountNormal(index+2) = R.z
  562.     ' ' mountNormal(index+3) = R.x : mountNormal(index+4) = R.y : mountNormal(index+5) = R.z
  563.     ' ' mountNormal(index+6) = R.x : mountNormal(index+7) = R.y : mountNormal(index+8) = R.z
  564.  
  565.     ' mountVert(index) = A.x : mountVert(index+1) = A.y : mountVert(index+2) = A.z : setMountColor x,z,index, A.y, mountHeightMax
  566.     ' mountVert(index+3) = B.x : mountVert(index+4) = B.y : mountVert(index+5) = B.z :  setMountColor x,z+1,index+3, B.y, mountHeightMax
  567.     ' mountVert(index+6) = C.x : mountVert(index+7) = C.y : mountVert(index+8) = C.z: setMountColor x+1,z,index+6, C.y, mountHeightMax
  568.  
  569.     ' ' OBJ_CalculateNormal C,B,D, R
  570.  
  571.     ' ' mountNormal(index+9) = R.x : mountNormal(index+10) = R.y : mountNormal(index+11) = R.z
  572.     ' ' mountNormal(index+12) = R.x : mountNormal(index+13) = R.y : mountNormal(index+14) = R.z
  573.     ' ' mountNormal(index+15) = R.x : mountNormal(index+16) = R.y : mountNormal(index+17) = R.z
  574.  
  575.     ' mountVert(index+9) = C.x : mountVert(index+10) = C.y : mountVert(index+11) = C.z: setMountColor x+1,z, index+9, C.y, mountHeightMax
  576.     ' mountVert(index+12) = B.x : mountVert(index+13) = B.y : mountVert(index+14) = B.z: setMountColor x,z+1,index+12, B.y, mountHeightMax
  577.     ' 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
  578.     ' index = index+18
  579.     ' NEXT x,z
  580.  
  581.     'this method is efficient than the above one.
  582.     DO
  583.         IF z MOD 2 = 0 THEN x = x + 1 ELSE x = x - 1
  584.  
  585.         A = terrainData(x, z) 'get out coordinates from our stored data
  586.         B = terrainData(x, z + 1)
  587.         C = terrainData(x + 1, z)
  588.  
  589.         OBJ_CalculateNormal A, B, C, R 'calculates the normal of a triangle
  590.  
  591.         'store color, coordinate & normal data in an array
  592.         mountNormal(index) = R.x: mountNormal(index + 1) = R.y: mountNormal(index + 2) = R.z
  593.         mountVert(index) = A.x: mountVert(index + 1) = A.y: mountVert(index + 2) = A.z: setMountColor x, z, index, A.y, mountHeightMax
  594.  
  595.         mountNormal(index + 3) = R.x: mountNormal(index + 4) = R.y: mountNormal(index + 5) = R.z
  596.         mountVert(index + 3) = B.x: mountVert(index + 4) = B.y: mountVert(index + 5) = B.z: setMountColor x, z + 1, index + 3, B.y, mountHeightMax
  597.  
  598.         index = index + 6
  599.  
  600.         IF x = mapW - 1 THEN
  601.             IF z MOD 2 = 0 THEN x = x + 1: z = z + 1
  602.         END IF
  603.         IF x = 1 THEN
  604.             IF z MOD 2 = 1 THEN x = x - 1: z = z + 1
  605.         END IF
  606.         IF z = mapH - 1 THEN EXIT DO
  607.     LOOP
  608.     _DEST 0
  609.  
  610. FUNCTION trimDecimal# (num, n%)
  611.     d$ = RTRIM$(STR$(num))
  612.     dd$ = d$
  613.     FOR i = 1 TO LEN(d$)
  614.         cA$ = MID$(d$, i, 1)
  615.         IF foundpoint = 1 THEN k = k + 1
  616.         IF cA$ = "." THEN foundpoint = 1
  617.         IF k = n% THEN dd$ = LEFT$(dd$, i)
  618.     NEXT i
  619.     trimDecimal# = VAL(dd$)
  620.  
  621.  
  622. FUNCTION p5random! (mn!, mx!)
  623.     IF mn! > mx! THEN
  624.         SWAP mn!, mx!
  625.     END IF
  626.     p5random! = RND * (mx! - mn!) + mn!
  627.  
  628.  
  629. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  630.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  631.  
  632. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS _UNSIGNED LONG)
  633.     'This sub from here: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1848.msg17254#msg17254
  634.     DIM Radius AS LONG
  635.     DIM RadiusError AS LONG
  636.     DIM X AS LONG
  637.     DIM Y AS LONG
  638.  
  639.     Radius = ABS(R)
  640.     RadiusError = -Radius
  641.     X = Radius
  642.     Y = 0
  643.  
  644.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  645.  
  646.     ' Draw the middle span here so we don't draw it twice in the main loop,
  647.     ' which would be a problem with blending turned on.
  648.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  649.  
  650.     WHILE X > Y
  651.  
  652.         RadiusError = RadiusError + Y * 2 + 1
  653.  
  654.         IF RadiusError >= 0 THEN
  655.  
  656.             IF X <> Y + 1 THEN
  657.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  658.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  659.             END IF
  660.  
  661.             X = X - 1
  662.             RadiusError = RadiusError - X * 2
  663.  
  664.         END IF
  665.  
  666.         Y = Y + 1
  667.  
  668.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  669.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  670.  
  671.     WEND
  672.  
  673.  
  674.  
  675. 'coded in QB64 by Fellipe Heitor
  676. 'Can be found in p5js.bas library
  677. 'http://bit.ly/p5jsbas
  678. FUNCTION noise! (x AS SINGLE, y AS SINGLE, z AS SINGLE)
  679.     STATIC p5NoiseSetup AS _BYTE
  680.     STATIC perlin() AS SINGLE
  681.     STATIC PERLIN_YWRAPB AS SINGLE, PERLIN_YWRAP AS SINGLE
  682.     STATIC PERLIN_ZWRAPB AS SINGLE, PERLIN_ZWRAP AS SINGLE
  683.     STATIC PERLIN_SIZE AS SINGLE
  684.  
  685.     IF p5NoiseSetup = 0 THEN
  686.         p5NoiseSetup = 1
  687.  
  688.         PERLIN_YWRAPB = 4
  689.         PERLIN_YWRAP = INT(1 * (2 ^ PERLIN_YWRAPB))
  690.         PERLIN_ZWRAPB = 8
  691.         PERLIN_ZWRAP = INT(1 * (2 ^ PERLIN_ZWRAPB))
  692.         PERLIN_SIZE = 4095
  693.  
  694.         perlin_octaves = 4
  695.         perlin_amp_falloff = 0.5
  696.  
  697.         REDIM perlin(PERLIN_SIZE + 1) AS SINGLE
  698.         DIM i AS SINGLE
  699.         FOR i = 0 TO PERLIN_SIZE + 1
  700.             perlin(i) = RND
  701.         NEXT
  702.     END IF
  703.  
  704.     x = ABS(x)
  705.     y = ABS(y)
  706.     z = ABS(z)
  707.  
  708.     DIM xi AS SINGLE, yi AS SINGLE, zi AS SINGLE
  709.     xi = INT(x)
  710.     yi = INT(y)
  711.     zi = INT(z)
  712.  
  713.     DIM xf AS SINGLE, yf AS SINGLE, zf AS SINGLE
  714.     xf = x - xi
  715.     yf = y - yi
  716.     zf = z - zi
  717.  
  718.     DIM r AS SINGLE, ampl AS SINGLE, o AS SINGLE
  719.     r = 0
  720.     ampl = .5
  721.  
  722.     FOR o = 1 TO perlin_octaves
  723.         DIM of AS SINGLE, rxf AS SINGLE
  724.         DIM ryf AS SINGLE, n1 AS SINGLE, n2 AS SINGLE, n3 AS SINGLE
  725.         of = xi + INT(yi * (2 ^ PERLIN_YWRAPB)) + INT(zi * (2 ^ PERLIN_ZWRAPB))
  726.  
  727.         rxf = 0.5 * (1.0 - COS(xf * _PI))
  728.         ryf = 0.5 * (1.0 - COS(yf * _PI))
  729.  
  730.         n1 = perlin(of AND PERLIN_SIZE)
  731.         n1 = n1 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n1)
  732.         n2 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  733.         n2 = n2 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n2)
  734.         n1 = n1 + ryf * (n2 - n1)
  735.  
  736.         of = of + PERLIN_ZWRAP
  737.         n2 = perlin(of AND PERLIN_SIZE)
  738.         n2 = n2 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n2)
  739.         n3 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
  740.         n3 = n3 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n3)
  741.         n2 = n2 + ryf * (n3 - n2)
  742.  
  743.         n1 = n1 + (0.5 * (1.0 - COS(zf * _PI))) * (n2 - n1)
  744.  
  745.         r = r + n1 * ampl
  746.         ampl = ampl * perlin_amp_falloff
  747.         xi = INT(xi * (2 ^ 1))
  748.         xf = xf * 2
  749.         yi = INT(yi * (2 ^ 1))
  750.         yf = yf * 2
  751.         zi = INT(zi * (2 ^ 1))
  752.         zf = zf * 2
  753.  
  754.         IF xf >= 1.0 THEN xi = xi + 1: xf = xf - 1
  755.         IF yf >= 1.0 THEN yi = yi + 1: yf = yf - 1
  756.         IF zf >= 1.0 THEN zi = zi + 1: zf = zf - 1
  757.     NEXT
  758.     noise! = r
  759.  
  760. SUB noiseDetail (lod!, falloff!)
  761.     IF lod! > 0 THEN perlin_octaves = lod!
  762.     IF falloff! > 0 THEN perlin_amp_falloff = falloff!
  763.  
  764. 'method adapted form http://stackoverflow.com/questions/4106363/converting-rgb-to-hsb-colors
  765. FUNCTION hsb~& (__H AS _FLOAT, __S AS _FLOAT, __B AS _FLOAT, A AS _FLOAT)
  766.     DIM H AS _FLOAT, S AS _FLOAT, B AS _FLOAT
  767.  
  768.     H = map(__H, 0, 255, 0, 360)
  769.     S = map(__S, 0, 255, 0, 1)
  770.     B = map(__B, 0, 255, 0, 1)
  771.  
  772.     IF S = 0 THEN
  773.         hsb~& = _RGBA32(B * 255, B * 255, B * 255, A)
  774.         EXIT FUNCTION
  775.     END IF
  776.  
  777.     DIM fmx AS _FLOAT, fmn AS _FLOAT
  778.     DIM fmd AS _FLOAT, iSextant AS INTEGER
  779.     DIM imx AS INTEGER, imd AS INTEGER, imn AS INTEGER
  780.  
  781.     IF B > .5 THEN
  782.         fmx = B - (B * S) + S
  783.         fmn = B + (B * S) - S
  784.     ELSE
  785.         fmx = B + (B * S)
  786.         fmn = B - (B * S)
  787.     END IF
  788.  
  789.     iSextant = INT(H / 60)
  790.  
  791.     IF H >= 300 THEN
  792.         H = H - 360
  793.     END IF
  794.  
  795.     H = H / 60
  796.     H = H - (2 * INT(((iSextant + 1) MOD 6) / 2))
  797.  
  798.     IF iSextant MOD 2 = 0 THEN
  799.         fmd = (H * (fmx - fmn)) + fmn
  800.     ELSE
  801.         fmd = fmn - (H * (fmx - fmn))
  802.     END IF
  803.  
  804.     imx = _ROUND(fmx * 255)
  805.     imd = _ROUND(fmd * 255)
  806.     imn = _ROUND(fmn * 255)
  807.  
  808.     SELECT CASE INT(iSextant)
  809.         CASE 1
  810.             hsb~& = _RGBA32(imd, imx, imn, A)
  811.         CASE 2
  812.             hsb~& = _RGBA32(imn, imx, imd, A)
  813.         CASE 3
  814.             hsb~& = _RGBA32(imn, imd, imx, A)
  815.         CASE 4
  816.             hsb~& = _RGBA32(imd, imn, imx, A)
  817.         CASE 5
  818.             hsb~& = _RGBA32(imx, imn, imd, A)
  819.         CASE ELSE
  820.             hsb~& = _RGBA32(imx, imd, imn, A)
  821.     END SELECT
  822.  
  823.  
  824.  
  825. SUB OBJ_CalculateNormal (p1 AS vec3, p2 AS vec3, p3 AS vec3, N AS vec3)
  826.     DIM U AS vec3, V AS vec3
  827.  
  828.     U.x = p2.x - p1.x
  829.     U.y = p2.y - p1.y
  830.     U.z = p2.z - p1.z
  831.  
  832.     V.x = p3.x - p1.x
  833.     V.y = p3.y - p1.y
  834.     V.z = p3.z - p1.z
  835.  
  836.     N.x = (U.y * V.z) - (U.z * V.y)
  837.     N.y = (U.z * V.x) - (U.x * V.z)
  838.     N.z = (U.x * V.y) - (U.y * V.x)
  839.     OBJ_Normalize N
  840.  
  841. SUB OBJ_Normalize (V AS vec3)
  842.     mag! = SQR(V.x * V.x + V.y * V.y + V.z * V.z)
  843.     V.x = V.x / mag!
  844.     V.y = V.y / mag!
  845.     V.z = V.z / mag!
  846.  
  847. FUNCTION glVec4%& (x, y, z, w)
  848.     STATIC internal_vec4(3)
  849.     internal_vec4(0) = x
  850.     internal_vec4(1) = y
  851.     internal_vec4(2) = z
  852.     internal_vec4(3) = w
  853.     glVec4%& = _OFFSET(internal_vec4())
  854.  
  855. '============================================================
  856. '=== This file was created with MakeDATA.bas by RhoSigma, ===
  857. '=== you must $INCLUDE this at the end of your program.   ===
  858. '============================================================
  859.  
  860. '=====================================================================
  861. 'Function to write the embedded DATAs back to disk. Call this FUNCTION
  862. 'once, before you will access the represented file for the first time.
  863. 'After the call always use the returned realFile$ ONLY to access the
  864. 'written file, as the filename was maybe altered in order to avoid the
  865. 'overwriting of an existing file of the same name in the given location.
  866. '---------------------------------------------------------------------
  867. 'SYNTAX: realFile$ = WriteqbiconData$ (wantFile$)
  868. '
  869. 'INPUTS: wantFile$ --> The filename you would like to write the DATAs
  870. '                      to, can contain a full or relative path.
  871. '
  872. 'RESULT: realFile$ --> On success the path and filename finally used
  873. '                      after applied checks, use ONLY this returned
  874. '                      name to access the file.
  875. '                   -> On failure this FUNCTION will panic with the
  876. '                      appropriate ERROR code, you may handle this as
  877. '                      needed with your own ON ERROR GOTO... handler.
  878. '=====================================================================
  879. FUNCTION WriteqbiconData$ (file$)
  880.     '--- separate filename body & extension ---
  881.     FOR po% = LEN(file$) TO 1 STEP -1
  882.         IF MID$(file$, po%, 1) = "." THEN
  883.             body$ = LEFT$(file$, po% - 1)
  884.             ext$ = MID$(file$, po%)
  885.             EXIT FOR
  886.         ELSEIF MID$(file$, po%, 1) = "\" OR MID$(file$, po%, 1) = "/" OR po% = 1 THEN
  887.             body$ = file$
  888.             ext$ = ""
  889.             EXIT FOR
  890.         END IF
  891.     NEXT po%
  892.     '--- avoid overwriting of existing files ---
  893.     num% = 1
  894.     WHILE _FILEEXISTS(file$)
  895.         file$ = body$ + "(" + LTRIM$(STR$(num%)) + ")" + ext$
  896.         num% = num% + 1
  897.     WEND
  898.     '--- write DATAs ---
  899.     ff% = FREEFILE
  900.     OPEN file$ FOR OUTPUT AS ff%
  901.     RESTORE qbicon
  902.     READ numL&, numB&
  903.     FOR i& = 1 TO numL&
  904.         READ dat&
  905.         PRINT #ff%, MKL$(dat&);
  906.     NEXT i&
  907.     IF numB& > 0 THEN
  908.         FOR i& = 1 TO numB&
  909.             READ dat&
  910.             PRINT #ff%, CHR$(dat&);
  911.         NEXT i&
  912.     END IF
  913.     CLOSE ff%
  914.     '--- set result ---
  915.     WriteqbiconData$ = file$
  916.  
  917.     '--- DATAs representing the contents of file qbicon32.png
  918.     '---------------------------------------------------------------------
  919.     qbicon:
  920.     DATA 144,4
  921.     DATA &H474E5089,&H0A1A0A0D,&H0D000000,&H52444849,&H20000000,&H20000000,&H00000608,&H7A7A7300
  922.     DATA &H000000F4,&H4D416704,&HB1000041,&H61FC0B8F,&H00000005,&H59487009,&H0E000073,&H0E0000C1
  923.     DATA &H91B801C1,&H0000ED6B,&H45741A00,&H6F537458,&H61777466,&H50006572,&H746E6961,&H54454E2E
  924.     DATA &H2E337620,&H30312E35,&HA172F430,&HC0010000,&H54414449,&H97C54758,&H20C371E1,&HA519850C
  925.     DATA &H064430A3,&HDB3124E8,&H823B3FB4,&H5D14C887,&H04A84D21,&H8C096308,&H87F6E2E0,&HD67E02F2
  926.     DATA &HBE7C5F13,&H6EE6318B,&H32F9F98D,&H4A6A13E6,&H66A141DF,&H060DE3F4,&H283CCDC8,&HA0AEB0D4
  927.     DATA &H869AC350,&HE1E5F0A0,&H42FAF78D,&H35621C7F,&HE71AB1F6,&H3CFE85F5,&H0F502444,&HA81115E9
  928.     DATA &H922AF485,&HE6F00828,&H8C2746EE,&H0F4B7EBA,&HEDCDE011,&H15184E93,&H25D3DCD7,&H0A938650
  929.     DATA &H1940834F,&H3D3C2A4E,&H551C3C02,&H6CBEC278,&H8E04EFFE,&H24E64F6A,&H92554702,&HBD808D39
  930.     DATA &HCD712195,&H2812A73D,&HA78549C3,&HF73DC047,&H9EE6B8E1,&H7F365D78,&HB54D0109,&H104A6808
  931.     DATA &H27157A98,&H62AF5302,&HDDC4A04E,&H11F35222,&H082D39E6,&HC89CE6F0,&HBCAE6276,&H020688E9
  932.     DATA &HB732A1F0,&H569436B4,&H8301F0E1,&HBCA6AC3A,&H00E288E9,&H5CB2C091,&H2EAD0057,&HD87DE3F4
  933.     DATA &HEF57B16C,&H5050FC1D,&H2616BDF8,&H237F613D,&HAA390B50,&H40244038,&H3878A98D,&H0230F4AA
  934.     DATA &H0BB9C03C,&HADA7B09D,&H9E953BE6,&H2FD8010E,&HD5B48E43,&H73D2A77C,&HFDB70122,&HCD7141C6
  935.     DATA &H39FAE93D,&HD2A680CF,&H9A026D70,&H24F0FBC2,&H2DAE13E5,&H6FEE0FBC,&H9F2E7013,&HB9AE2830
  936.     DATA &H66A75D27,&H52F6754D,&H0043A019,&HA93873F6,&HA90244F4,&H01CAA1D9,&H10DFFEC2,&H84039540
  937.     DATA &H033CD7FD,&H72A6AC3C,&H11BFB080,&HEB157B98,&HD75E3409,&H02184099,&H688E9A94,&H0854190E
  938.     DATA &H2FF0040F,&H46621E72,&H1B3509A1,&H05FDBBD5,&HF13FDC1C,&H6A6E33B4,&H00000000,&H444E4549
  939.     DATA &HAE,&H42,&H60,&H82
  940.  
  941.  


 [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: 3D OpenWorld Mountains
Post by: TerryRitchie on February 25, 2020, 03:35:07 pm
Wow, can't believe I missed this. Nice work!

I'm thinking ... 3D Scorched Earth!