2
0

2.1.basic_lighting_diffuse.bmx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. ' https://learnopengl.com/
  2. SuperStrict
  3. Framework GLFW.GLFWWindow
  4. Import "../shader.bmx"
  5. Import "../camera.bmx"
  6. Import GLFW.GLFW
  7. Import GLFW.GLFWOpenGL
  8. Import GLFW.GLFWSystem
  9. Import BRL.JpgLoader
  10. Import BRL.PngLoader
  11. Import BRL.StandardIO
  12. Local app_name:String = "Basic Lighting Diffuse"
  13. Const SCR_WIDTH:UInt = 800
  14. Const SCR_HEIGHT:UInt = 600
  15. ' camera
  16. Global camera:TCamera = New TCamera(New SVec3F(0.0, 0.0, 3.0))
  17. Global firstMouse:Int = True
  18. Global lastX:Float = SCR_WIDTH / 2.0
  19. Global lastY:Float = SCR_HEIGHT / 2.0
  20. ' timing
  21. Global deltaTime:Float ' time between current frame and last frame
  22. Global lastFrame:Float
  23. ' lighting
  24. Global lightPos:SVec3F = New SVec3F(1.2, 1.0, 2.0)
  25. Type TGameWindow Extends TGLFWWindow
  26. ' whenever the window size changed (by OS or user resize) this callback method executes
  27. Method OnFrameBufferSize (width:Int, height:Int)
  28. ' make sure the viewport matches the new window dimensions; note that width and
  29. ' height will be significantly larger than specified on retina displays.
  30. glViewport (0, 0, width, height)
  31. EndMethod
  32. Method OnCursorPosition(x:Double, y:Double)
  33. If firstMouse Then
  34. lastX = x
  35. lastY = y
  36. firstMouse = False
  37. End If
  38. Local xoffset:Float = x - lastX
  39. Local yoffset:Float = lastY - y ' reversed since y-coordinates go from bottom To top
  40. lastX = x
  41. lastY = y
  42. camera.ProcessMouseMovement(xoffset, yoffset)
  43. End Method
  44. Method OnScroll(xOffset:Double, yOffset:Double)
  45. camera.ProcessMouseScroll(Float(yoffset))
  46. End Method
  47. EndType
  48. ' process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
  49. Function ProcessInput (window:TGLFWWindow)
  50. If window.IsKeyDown (GLFW_KEY_ESCAPE)
  51. window.SetShouldClose (True)
  52. EndIf
  53. If window.IsKeyDown(GLFW_KEY_W) Then
  54. camera.ProcessKeyboard(ECameraMovement.Forward, deltaTime)
  55. End If
  56. If window.IsKeyDown(GLFW_KEY_S) Then
  57. camera.ProcessKeyboard(ECameraMovement.Backward, deltaTime)
  58. End If
  59. If window.IsKeyDown(GLFW_KEY_A) Then
  60. camera.ProcessKeyboard(ECameraMovement.Left, deltaTime)
  61. End If
  62. If window.IsKeyDown(GLFW_KEY_D) Then
  63. camera.ProcessKeyboard(ECameraMovement.Right, deltaTime)
  64. End If
  65. EndFunction
  66. ' glfw: initialize and configure
  67. TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
  68. TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
  69. TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
  70. ?MacOS ' Ewww...
  71. TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
  72. ?
  73. ' glfw window creation
  74. Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
  75. If Not window
  76. Print "Failed to create GLFW window!"
  77. End
  78. EndIf
  79. window.MakeContextCurrent ()
  80. ' tell GLFW to capture our mouse
  81. window.SetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED)
  82. ' glad: load all OpenGL function pointers
  83. gladLoadGL (glfwGetProcAddress)
  84. ' configure global opengl state
  85. glEnable(GL_DEPTH_TEST)
  86. ' build and compile our shader program
  87. Local lightingShader:TShader = New TShader("2.1.basic_lighting.vs", "2.1.basic_lighting.fs")
  88. Local lampShader:TShader = New TShader("2.1.lamp.vs", "2.1.lamp.fs")
  89. ' set up vertex data (and buffer(s)) and configure vertex attributes
  90. Local vertices:Float [] = [..
  91. -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, ..
  92. 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, ..
  93. 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, ..
  94. 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, ..
  95. -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, ..
  96. -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, ..
  97. ..
  98. -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, ..
  99. 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, ..
  100. 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, ..
  101. 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, ..
  102. -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, ..
  103. -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, ..
  104. ..
  105. -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, ..
  106. -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, ..
  107. -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, ..
  108. -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, ..
  109. -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, ..
  110. -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, ..
  111. ..
  112. 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, ..
  113. 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, ..
  114. 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, ..
  115. 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, ..
  116. 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, ..
  117. 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, ..
  118. ..
  119. -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, ..
  120. 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, ..
  121. 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, ..
  122. 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, ..
  123. -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, ..
  124. -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, ..
  125. ..
  126. -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, ..
  127. 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, ..
  128. 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, ..
  129. 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, ..
  130. -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, ..
  131. -0.5, 0.5, -0.5, 0.0, 1.0, 0.0]
  132. Local VBO:UInt
  133. Local cubeVAO:UInt
  134. glGenVertexArrays (1, Varptr cubeVAO)
  135. glGenBuffers (1, Varptr VBO)
  136. glBindVertexArray (cubeVAO)
  137. glBindBuffer (GL_ARRAY_BUFFER, VBO)
  138. glBufferData (GL_ARRAY_BUFFER, Int(vertices.length * SizeOf (0:Float)), vertices, GL_STATIC_DRAW)
  139. ' position attribute
  140. glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, Int(6 * SizeOf (0:Float)), 0:Byte Ptr)
  141. glEnableVertexAttribArray (0)
  142. Local attribute_offset:Int = 3 * SizeOf (0:Float)
  143. ' normal attribute
  144. glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, Int(6 * SizeOf (0:Float)), Byte Ptr (attribute_offset))
  145. glEnableVertexAttribArray (1)
  146. ' second, configure the light's VAO (VBO stays the same; the vertices are the same for the light object which is also a 3D cube)
  147. Local lightVAO:UInt
  148. glGenVertexArrays(1, Varptr lightVAO)
  149. glBindVertexArray(lightVAO)
  150. glBindBuffer (GL_ARRAY_BUFFER, VBO)
  151. ' note that we update the lamp's position attribute's stride to reflect the updated buffer data
  152. glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, Int(6 * SizeOf (0:Float)), 0:Byte Ptr)
  153. glEnableVertexAttribArray (0)
  154. ' render loop
  155. ' -----------
  156. While Not window.ShouldClose ()
  157. ' per-frame time logic
  158. Local currentFrame:Float = MilliSecs() / 1000.0
  159. deltaTime = currentFrame - lastFrame
  160. lastFrame = currentFrame
  161. ' input
  162. ' -----
  163. ProcessInput (window)
  164. ' render
  165. ' ------
  166. glClearColor (0.1, 0.1, 0.1, 1.0)
  167. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  168. ' be sure to activate shader when setting uniforms/drawing objects
  169. lightingShader.use()
  170. lightingShader.setVec3("objectColor", 1.0, 0.5, 0.31)
  171. lightingShader.setVec3("lightColor", 1.0, 1.0, 1.0)
  172. lightingShader.setVec3("lightPos", lightPos)
  173. ' view/projection transformations
  174. Local projection:SMat4F = SMat4F.Perspective(camera.Zoom, SCR_WIDTH, SCR_HEIGHT, 0.1, 100.0)
  175. Local view:SMat4F = camera.GetViewMatrix()
  176. lightingShader.setMat4("projection", projection)
  177. lightingShader.setMat4("view", view)
  178. ' world transformation
  179. Local model:SMat4F = SMat4F.Identity()
  180. lightingShader.setMat4("model", model)
  181. ' render the cube
  182. glBindVertexArray(cubeVAO)
  183. glDrawArrays(GL_TRIANGLES, 0, 36)
  184. ' also draw the lamp object
  185. lampShader.use()
  186. lampShader.setMat4("projection", projection)
  187. lampShader.setMat4("view", view)
  188. model = SMat4F.Identity()
  189. model = model.Translate(lightPos)
  190. model = model.Scale(New SVec3F(0.2, 0.2, 0.2)) ' a smaller cube
  191. lampShader.setMat4("model", model)
  192. glBindVertexArray(lightVAO)
  193. glDrawArrays(GL_TRIANGLES, 0, 36)
  194. ' glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
  195. window.SwapBuffers ()
  196. PollSystem ()
  197. Wend
  198. ' optional: de-allocate all resources once they've outlived their purpose
  199. glDeleteVertexArrays(1, Varptr cubeVAO)
  200. glDeleteVertexArrays (1, Varptr lightVAO)
  201. glDeleteBuffers (1, Varptr VBO)
  202. End