7.4.camera_class.bmx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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 = "Camera Class"
  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. Type TGameWindow Extends TGLFWWindow
  24. ' whenever the window size changed (by OS or user resize) this callback method executes
  25. Method OnFrameBufferSize (width:Int, height:Int)
  26. ' make sure the viewport matches the new window dimensions; note that width and
  27. ' height will be significantly larger than specified on retina displays.
  28. glViewport (0, 0, width, height)
  29. EndMethod
  30. Method OnCursorPosition(x:Double, y:Double)
  31. If firstMouse Then
  32. lastX = x
  33. lastY = y
  34. firstMouse = False
  35. End If
  36. Local xoffset:Float = x - lastX
  37. Local yoffset:Float = lastY - y ' reversed since y-coordinates go from bottom To top
  38. lastX = x
  39. lastY = y
  40. camera.ProcessMouseMovement(xoffset, yoffset)
  41. End Method
  42. Method OnScroll(xOffset:Double, yOffset:Double)
  43. camera.ProcessMouseScroll(Float(yoffset))
  44. End Method
  45. EndType
  46. ' process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
  47. Function ProcessInput (window:TGLFWWindow)
  48. If window.IsKeyDown (GLFW_KEY_ESCAPE)
  49. window.SetShouldClose (True)
  50. EndIf
  51. If window.IsKeyDown(GLFW_KEY_W) Then
  52. camera.ProcessKeyboard(ECameraMovement.Forward, deltaTime)
  53. End If
  54. If window.IsKeyDown(GLFW_KEY_S) Then
  55. camera.ProcessKeyboard(ECameraMovement.Backward, deltaTime)
  56. End If
  57. If window.IsKeyDown(GLFW_KEY_A) Then
  58. camera.ProcessKeyboard(ECameraMovement.Left, deltaTime)
  59. End If
  60. If window.IsKeyDown(GLFW_KEY_D) Then
  61. camera.ProcessKeyboard(ECameraMovement.Right, deltaTime)
  62. End If
  63. EndFunction
  64. ' glfw: initialize and configure
  65. TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
  66. TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
  67. TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
  68. ?MacOS ' Ewww...
  69. TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
  70. ?
  71. ' glfw window creation
  72. Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
  73. If Not window
  74. Print "Failed to create GLFW window!"
  75. End
  76. EndIf
  77. window.MakeContextCurrent ()
  78. ' tell GLFW to capture our mouse
  79. window.SetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED)
  80. ' glad: load all OpenGL function pointers
  81. gladLoadGL (glfwGetProcAddress)
  82. ' configure global opengl state
  83. glEnable(GL_DEPTH_TEST)
  84. ' build and compile our shader program
  85. Local ourShader:TShader = New TShader("7.4.camera.vs", "7.4.camera.fs")
  86. ' set up vertex data (and buffer(s)) and configure vertex attributes
  87. Local vertices:Float [] = [..
  88. -0.5, -0.5, -0.5, 0.0, 0.0, ..
  89. 0.5, -0.5, -0.5, 1.0, 0.0, ..
  90. 0.5, 0.5, -0.5, 1.0, 1.0, ..
  91. 0.5, 0.5, -0.5, 1.0, 1.0, ..
  92. -0.5, 0.5, -0.5, 0.0, 1.0, ..
  93. -0.5, -0.5, -0.5, 0.0, 0.0, ..
  94. ..
  95. -0.5, -0.5, 0.5, 0.0, 0.0, ..
  96. 0.5, -0.5, 0.5, 1.0, 0.0, ..
  97. 0.5, 0.5, 0.5, 1.0, 1.0, ..
  98. 0.5, 0.5, 0.5, 1.0, 1.0, ..
  99. -0.5, 0.5, 0.5, 0.0, 1.0, ..
  100. -0.5, -0.5, 0.5, 0.0, 0.0, ..
  101. ..
  102. -0.5, 0.5, 0.5, 1.0, 0.0, ..
  103. -0.5, 0.5, -0.5, 1.0, 1.0, ..
  104. -0.5, -0.5, -0.5, 0.0, 1.0, ..
  105. -0.5, -0.5, -0.5, 0.0, 1.0, ..
  106. -0.5, -0.5, 0.5, 0.0, 0.0, ..
  107. -0.5, 0.5, 0.5, 1.0, 0.0, ..
  108. ..
  109. 0.5, 0.5, 0.5, 1.0, 0.0, ..
  110. 0.5, 0.5, -0.5, 1.0, 1.0, ..
  111. 0.5, -0.5, -0.5, 0.0, 1.0, ..
  112. 0.5, -0.5, -0.5, 0.0, 1.0, ..
  113. 0.5, -0.5, 0.5, 0.0, 0.0, ..
  114. 0.5, 0.5, 0.5, 1.0, 0.0, ..
  115. ..
  116. -0.5, -0.5, -0.5, 0.0, 1.0, ..
  117. 0.5, -0.5, -0.5, 1.0, 1.0, ..
  118. 0.5, -0.5, 0.5, 1.0, 0.0, ..
  119. 0.5, -0.5, 0.5, 1.0, 0.0, ..
  120. -0.5, -0.5, 0.5, 0.0, 0.0, ..
  121. -0.5, -0.5, -0.5, 0.0, 1.0, ..
  122. ..
  123. -0.5, 0.5, -0.5, 0.0, 1.0, ..
  124. 0.5, 0.5, -0.5, 1.0, 1.0, ..
  125. 0.5, 0.5, 0.5, 1.0, 0.0, ..
  126. 0.5, 0.5, 0.5, 1.0, 0.0, ..
  127. -0.5, 0.5, 0.5, 0.0, 0.0, ..
  128. -0.5, 0.5, -0.5, 0.0, 1.0]
  129. ' world space positions of our cubes
  130. Local cubePositions:SVec3F[] = [ ..
  131. New SVec3F( 0.0, 0.0, 0.0), ..
  132. New SVec3F( 2.0, 5.0, -15.0), ..
  133. New SVec3F(-1.5, -2.2, -2.5), ..
  134. New SVec3F(-3.8, -2.0, -12.3), ..
  135. New SVec3F( 2.4, -0.4, -3.5), ..
  136. New SVec3F(-1.7, 3.0, -7.5), ..
  137. New SVec3F( 1.3, -2.0, -2.5), ..
  138. New SVec3F( 1.5, 2.0, -2.5), ..
  139. New SVec3F( 1.5, 0.2, -1.5), ..
  140. New SVec3F(-1.3, 1.0, -1.5) ..
  141. ]
  142. Local VBO:UInt
  143. Local VAO:UInt
  144. glGenVertexArrays (1, Varptr VAO)
  145. glGenBuffers (1, Varptr VBO)
  146. ' bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
  147. glBindVertexArray (VAO)
  148. glBindBuffer (GL_ARRAY_BUFFER, VBO)
  149. glBufferData (GL_ARRAY_BUFFER, Int(vertices.length * SizeOf (0:Float)), vertices, GL_STATIC_DRAW)
  150. ' position attribute
  151. glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, Int(5 * SizeOf (0:Float)), 0:Byte Ptr)
  152. glEnableVertexAttribArray (0)
  153. Local attribute_offset:Int = 3 * SizeOf (0:Float)
  154. ' texture coord attribute
  155. glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, Int(5 * SizeOf (0:Float)), Byte Ptr (attribute_offset))
  156. glEnableVertexAttribArray (1)
  157. ' load and create a texture
  158. ' -------------------------
  159. Local texture1:UInt
  160. Local texture2:UInt
  161. ' texture 1
  162. ' ---------
  163. glGenTextures(1, Varptr texture1)
  164. glBindTexture(GL_TEXTURE_2D, texture1)
  165. ' set the texture wrapping parameters
  166. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  167. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  168. ' set texture filtering parameters
  169. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  170. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  171. ' load image, create texture and generate mipmaps
  172. Local pixmap:TPixmap = LoadPixmap(PATH_PREFIX + "../resources/textures/container.jpg")
  173. If pixmap Then
  174. pixmap = YFlipPixmap(pixmap)
  175. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pixmap.width, pixmap.height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixmap.pixels)
  176. glGenerateMipmap(GL_TEXTURE_2D)
  177. Else
  178. Print "Failed to load texture"
  179. End
  180. End If
  181. ' texture 2
  182. ' ---------
  183. glGenTextures(1, Varptr texture2)
  184. glBindTexture(GL_TEXTURE_2D, texture2)
  185. ' set the texture wrapping parameters
  186. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  187. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  188. ' set texture filtering parameters
  189. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  190. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  191. ' load image, create texture and generate mipmaps
  192. pixmap = LoadPixmap(PATH_PREFIX + "../resources/textures/awesomeface.png")
  193. If pixmap Then
  194. pixmap = YFlipPixmap(pixmap)
  195. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pixmap.width, pixmap.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixmap.pixels)
  196. glGenerateMipmap(GL_TEXTURE_2D)
  197. Else
  198. Print "Failed to load texture"
  199. End
  200. End If
  201. pixmap = Null
  202. ' tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
  203. ourShader.use()
  204. ourShader.setInt("texture1", 0)
  205. ourShader.setInt("texture2", 1)
  206. ' pass projection matrix to shader (as projection matrix rarely changes there's no need to do this per frame)
  207. Local projection:SMat4F = SMat4F.Perspective(45.0, SCR_WIDTH, SCR_HEIGHT, 0.1, 100.0)
  208. ourShader.setMat4("projection", projection)
  209. ' render loop
  210. ' -----------
  211. While Not window.ShouldClose ()
  212. ' per-frame time logic
  213. Local currentFrame:Float = MilliSecs() / 1000.0
  214. deltaTime = currentFrame - lastFrame
  215. lastFrame = currentFrame
  216. ' input
  217. ' -----
  218. ProcessInput (window)
  219. ' render
  220. ' ------
  221. glClearColor (0.2, 0.3, 0.3, 1.0)
  222. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ' also clear the depth buffer now!
  223. ' bind textures on corresponding texture units
  224. glActiveTexture(GL_TEXTURE0)
  225. glBindTexture(GL_TEXTURE_2D, texture1)
  226. glActiveTexture(GL_TEXTURE1)
  227. glBindTexture(GL_TEXTURE_2D, texture2)
  228. ' activate shader
  229. ourShader.use()
  230. ' camera/view transformation
  231. Local view:SMat4F = camera.GetViewMatrix()
  232. ourShader.setMat4("view", view)
  233. ' render boxes
  234. glBindVertexArray (VAO)
  235. For Local i:Int = 0 Until 10
  236. ' calculate the model matrix for each object and pass it to shader before drawing
  237. Local model:SMat4F = SMat4F.Identity()
  238. model = model.Translate(cubePositions[i])
  239. Local angle:Float = 20.0 * i
  240. model = model.Rotate(New SVec3F(1.0, 0.3, 0.5), angle)
  241. ourShader.setMat4("model", model)
  242. glDrawArrays(GL_TRIANGLES, 0, 36)
  243. Next
  244. ' glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
  245. window.SwapBuffers ()
  246. PollSystem ()
  247. Wend
  248. ' optional: de-allocate all resources once they've outlived their purpose
  249. glDeleteVertexArrays (1, Varptr VAO)
  250. glDeleteBuffers (1, Varptr VBO)
  251. End