app.d 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. import std.stdio;
  2. import three;
  3. import std.typecons;
  4. import derelict.opengl3.gl3;
  5. import three.gl.util;
  6. import derelict.anttweakbar.anttweakbar;
  7. import derelict.glfw3.glfw3;
  8. import derelict.assimp3.assimp;
  9. import std.string;
  10. import std.experimental.logger;
  11. //======================================================================================================================
  12. // GBuffer
  13. //======================================================================================================================
  14. struct GBuffer {
  15. GLuint hDepth;
  16. GLuint hNormal;
  17. GLuint hColor;
  18. GLuint hFin;
  19. GLuint hStencil;
  20. };
  21. GBuffer createGBuffer() {
  22. GBuffer gBuffer;
  23. check!glGenTextures(1, &gBuffer.hDepth);
  24. check!glBindTexture(GL_TEXTURE_2D, gBuffer.hDepth);
  25. with(_window) check!glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, width, height);
  26. with(_window) check!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_FLOAT, null);
  27. check!glBindTexture(GL_TEXTURE_2D, 0);
  28. check!glGenTextures(1, &gBuffer.hNormal);
  29. check!glBindTexture(GL_TEXTURE_2D, gBuffer.hNormal);
  30. with(_window) check!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB10_A2, width, height);
  31. with(_window) check!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);
  32. check!glBindTexture(GL_TEXTURE_2D, 0);
  33. check!glGenTextures(1, &gBuffer.hColor);
  34. check!glBindTexture(GL_TEXTURE_2D, gBuffer.hColor);
  35. with(_window) check!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
  36. with(_window) check!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);
  37. check!glBindTexture(GL_TEXTURE_2D, 0);
  38. check!glGenTextures(1, &gBuffer.hFin);
  39. check!glBindTexture(GL_TEXTURE_2D, gBuffer.hFin);
  40. with(_window) check!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB32F, width, height);
  41. with(_window) check!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_FLOAT, null);
  42. check!glBindTexture(GL_TEXTURE_2D, 0);
  43. check!glGenTextures(1, &gBuffer.hStencil);
  44. check!glBindTexture(GL_TEXTURE_2D, gBuffer.hStencil);
  45. with(_window) check!glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, width, height);
  46. with(_window) check!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, null);
  47. check!glBindTexture(GL_TEXTURE_2D, 0);
  48. return gBuffer;
  49. }
  50. void destroyGBuffer(ref GBuffer gBuffer) {
  51. check!glDeleteTextures(1, &gBuffer.hStencil);
  52. check!glDeleteTextures(1, &gBuffer.hFin);
  53. check!glDeleteTextures(1, &gBuffer.hColor);
  54. check!glDeleteTextures(1, &gBuffer.hNormal);
  55. check!glDeleteTextures(1, &gBuffer.hDepth);
  56. }
  57. //======================================================================================================================
  58. // FrameBuffer
  59. //======================================================================================================================
  60. struct FrameBuffer {
  61. GLuint hFrameBuffer;
  62. };
  63. FrameBuffer createFrameBuffer() {
  64. FrameBuffer frameBuffer;
  65. check!glGenFramebuffers(1, &frameBuffer.hFrameBuffer);
  66. check!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.hFrameBuffer);
  67. check!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, gBuffer.hDepth, 0);
  68. check!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 1, GL_TEXTURE_2D, gBuffer.hNormal, 0);
  69. check!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 2, GL_TEXTURE_2D, gBuffer.hColor, 0);
  70. check!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 3, GL_TEXTURE_2D, gBuffer.hFin, 0);
  71. check!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, gBuffer.hStencil, 0);
  72. check!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  73. return frameBuffer;
  74. }
  75. void destroyFrameBuffer(ref FrameBuffer frameBuffer) {
  76. check!glDeleteFramebuffers(1, &frameBuffer.hFrameBuffer);
  77. }
  78. //======================================================================================================================
  79. // ShaderPipeline
  80. //======================================================================================================================
  81. struct ShaderPipeline {
  82. GLuint hShaderPipeline;
  83. };
  84. ShaderPipeline createShaderPipeline() {
  85. ShaderPipeline shaderPipeline;
  86. glGenProgramPipelines(1, &shaderPipeline.hShaderPipeline);
  87. return shaderPipeline;
  88. }
  89. void destroyShaderPipeline(ref ShaderPipeline shaderPipeline) {
  90. glDeleteProgramPipelines(1, &shaderPipeline.hShaderPipeline);
  91. }
  92. //======================================================================================================================
  93. // ShaderProgram
  94. //======================================================================================================================
  95. struct ShaderProgram {
  96. GLuint hShaderProgram;
  97. };
  98. ShaderProgram createShaderProgram(string source) {
  99. ShaderProgram shaderProgram;
  100. auto szSource = [source.toStringz()];
  101. shaderProgram.hShaderProgram = check!glCreateShaderProgramv(GL_VERTEX_SHADER, 1, szSource.ptr);
  102. debug {
  103. int len;
  104. check!glGetProgramiv(this._id, GL_INFO_LOG_LENGTH , &len);
  105. if (len > 1) {
  106. char[] msg = new char[len];
  107. check!glGetProgramInfoLog(this._id, len, null, cast(char*) msg);
  108. error(cast(string)msg);
  109. }
  110. }
  111. return shaderProgram;
  112. }
  113. void destroyShaderProgram(ref ShaderProgram shaderProgram) {
  114. check!glDeleteProgram(shaderProgram.hShaderProgram);
  115. }
  116. //======================================================================================================================
  117. // VertexArrayObject
  118. //======================================================================================================================
  119. struct VertexArrayObject {
  120. GLuint hVertexArrayObject;
  121. }
  122. VertexArrayObject createVertexArrayObject() {
  123. VertexArrayObject vertexArrayObject;
  124. check!glGenVertexArrays(1, &vertexArrayObject.hVertexArrayObject);
  125. return vertexArrayObject;
  126. }
  127. void destroyVertexArrayObject(ref VertexArrayObject vertexArrayObject) {
  128. check!glDeleteVertexArrays(1, &vertexArrayObject.hVertexArrayObject);
  129. }
  130. //======================================================================================================================
  131. // VertexBufferObject
  132. //======================================================================================================================
  133. struct VertexBufferObject {
  134. GLuint hVertexBufferObject;
  135. }
  136. VertexBufferObject createVertexBufferObject() {
  137. VertexBufferObject vertexBufferObject;
  138. check!glGenBuffers(1, &vertexBufferObject.hVertexBufferObject);
  139. return vertexBufferObject;
  140. }
  141. void destroyVertexArrayObject(ref VertexBufferObject vertexBufferObject) {
  142. check!glDeleteVertexArrays(1, &vertexBufferObject.hVertexBufferObject);
  143. }
  144. //======================================================================================================================
  145. //
  146. //======================================================================================================================
  147. final class Camera {
  148. }
  149. final class Viewport {
  150. int x;
  151. int y;
  152. int width;
  153. int height;
  154. }
  155. final class Scene {
  156. VertexBufferObject[] vertexBufferObjects;
  157. VertexArrayObject[] vertexArrayObjects;
  158. }
  159. struct RenderGroup {
  160. Scene scene;
  161. Camera camera;
  162. Viewport viewport;
  163. }
  164. class OpenGlRenderer {
  165. private:
  166. Window _window;
  167. GBuffer _gBuffer;
  168. GBuffer _frameBuffer;
  169. ShaderProgram _geometryPassVertexShader;
  170. ShaderProgram _geometryPassFragmentShader;
  171. ShaderProgram _stencilPassVertexShader;
  172. ShaderProgram _stencilPassFragmentShader;
  173. ShaderProgram _pointLightPassVertexShader;
  174. ShaderProgram _pointLightPassFragmentShader;
  175. ShaderPipeline _shaderPipeline;
  176. Camera[] _cameras;
  177. Viewport[] _viewports;
  178. Scene[] _scenes;
  179. RenderGroup[] _renderGroups;
  180. public:
  181. this(Window window) {
  182. _window = window;
  183. _gBuffer = createGBuffer();
  184. _frameBuffer = createFrameBuffer();
  185. _geometryPassVertexShader = createShaderProgram("TODO: load and pass source code");
  186. _geometryPassFragmentShader = createShaderProgram("TODO: load and pass source code");
  187. _stencilPassVertexShader = createShaderProgram("TODO: load and pass source code");
  188. _stencilPassFragmentShader = createShaderProgram("TODO: load and pass source code");
  189. _pointLightPassVertexShader = createShaderProgram("TODO: load and pass source code");
  190. _pointLightPassFragmentShader = createShaderProgram("TODO: load and pass source code");
  191. _shaderPipeline = createShaderPipeline();
  192. }
  193. ~this() {
  194. destroyShaderPipeline(_shaderPipeline);
  195. destroyShaderProgram(_pointLightPassFragmentShader);
  196. destroyShaderProgram(_pointLightPassVertexShader);
  197. destroyShaderProgram(_stencilPassFragmentShader);
  198. destroyShaderProgram(_stencilPassVertexShader);
  199. destroyShaderProgram(_geometryPassFragmentShader);
  200. destroyShaderProgram(_geometryPassVertexShader);
  201. destroyFrameBuffer(_frameBuffer);
  202. destroyGBuffer(_gBuffer);
  203. }
  204. void run() {
  205. //--------------------------------------------------------------------------------------------------------------
  206. // Render Loop
  207. //--------------------------------------------------------------------------------------------------------------
  208. while(_keepRunning) {
  209. _window.makeAktiveRenderWindow();
  210. glClearColor(0, 0, 0, 1);
  211. glClearDepth(1.0);
  212. for(renderGroup; _renderGroups) {
  213. with(renderGroup.viewport) glViewport(x, y, width, height);
  214. geometryPass();
  215. lightningPass();
  216. finalPass();
  217. }
  218. }
  219. }
  220. void stop() {
  221. this._keepRunning = false;
  222. }
  223. private:
  224. //------------------------------------------------------------------------------------------------------------------
  225. // Geometry Pass
  226. //------------------------------------------------------------------------------------------------------------------
  227. void geometryPass() {
  228. //enable depth mask _before_ glClear ing the depth buffer!
  229. check!glDepthMask(GL_TRUE);
  230. check!glEnable(GL_DEPTH_TEST);
  231. check!glDepthFunc(GL_LEQUAL);
  232. check!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _frameBuffer.hframeBuffer);
  233. check!glDrawBuffer(GL_COLOR_ATTACHMENT3);
  234. GLenum[] drawBuffers = [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2];
  235. check!glDrawBuffers(drawBuffers.length, drawBuffers.ptr);
  236. check!glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  237. glBindProgramPipeline(shaderPipeline.hShaderPipeline);
  238. foreach(vao; _scenes) {
  239. mesh._vertexData.bind();
  240. glUseProgramStages(_shaderPipeline.hShaderPipeline, GL_VERTEX_SHADER_BIT, _geometryPassVertexShader);
  241. glUseProgramStages(_shaderPipeline.hShaderPipeline, GL_FRAGMENT_SHADER_BIT, _geometryPassFragmentShader);
  242. setCullMode(CullMode.Back);
  243. mesh._vertexShader.sendUniform("u_vpMatrix", camera.viewProjectionMatrix);
  244. mesh._fragmentShader.sendTexture("u_textureImage", this._texture, 0);
  245. foreach(model; this._models) {
  246. mesh._vertexShader.sendUniform("u_modelMatrix", model.modelMatrix);
  247. check!glDrawArrays(GL_TRIANGLES, 0, 36);
  248. }
  249. mesh._vertexData.unbind();
  250. }
  251. glBindProgramPipeline(0);
  252. check!glDepthMask(GL_FALSE);
  253. }
  254. //------------------------------------------------------------------------------------------------------------------
  255. // Lightning Pass
  256. //------------------------------------------------------------------------------------------------------------------
  257. void lightningPass() {
  258. this.framebuffer.bind(FrameBuffer.Target.Write);
  259. check!glDrawBuffer(GL_COLOR_ATTACHMENT3);
  260. check!glEnable(GL_STENCIL_TEST);
  261. foreach(pointLight; scene.pointLights)
  262. {
  263. //------------------------------------------------------------------------------------------------------
  264. // Stencil Pass
  265. //------------------------------------------------------------------------------------------------------
  266. glBindProgramPipeline(shaderPipeline.hShaderPipeline);
  267. this.framebuffer.bind(FrameBuffer.Target.Write);
  268. check!glDrawBuffer(GL_NONE);
  269. check!glClear(GL_STENCIL_BUFFER_BIT);//TODO: reqired?
  270. this._vao.bind();
  271. check!glEnable(GL_DEPTH_TEST);
  272. check!glDisable(GL_CULL_FACE);
  273. check!glStencilFunc(GL_ALWAYS, 0, 0);
  274. check!glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP);
  275. check!glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP);
  276. glUseProgramStages(shaderPipeline.hShaderPipeline, GL_VERTEX_SHADER_BIT, stencilPassVertexShader);
  277. glUseProgramStages(shaderPipeline.hShaderPipeline, GL_FRAGMENT_SHADER_BIT, stencilPassFragmentShader);
  278. this.vertexShader.sendUniform("u_mvpMatrix", camera.viewProjectionMatrix * pointLight.modelMatrix);
  279. check!glDrawArrays(GL_TRIANGLES, 0, 36);
  280. this._vao.unbind();
  281. glBindProgramPipeline(0);
  282. //------------------------------------------------------------------------------------------------------
  283. // PointLight Pass
  284. //------------------------------------------------------------------------------------------------------
  285. glBindProgramPipeline(shaderPipeline.hShaderPipeline);
  286. //~ camera.gbuffer.bind(GBuffer.Pass.Lighting);
  287. this.framebuffer.bind(FrameBuffer.Target.Write);
  288. check!glDrawBuffer(GL_COLOR_ATTACHMENT3);
  289. this._vao.bind();
  290. check!glDisable(GL_DEPTH_TEST);
  291. check!glEnable(GL_BLEND);
  292. check!glBlendFunc(GL_ONE, GL_ONE);
  293. check!glBlendEquation(GL_FUNC_ADD);
  294. check!glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
  295. check!glEnable(GL_CULL_FACE);
  296. check!glCullFace(GL_FRONT);
  297. glUseProgramStages(shaderPipeline.hShaderPipeline, GL_VERTEX_SHADER_BIT, pointLightPassVertexShader);
  298. glUseProgramStages(shaderPipeline.hShaderPipeline, GL_FRAGMENT_SHADER_BIT, pointLightPassFragmentShader);
  299. this.vertexShader.sendUniform("u_mvpMatrix", camera.viewProjectionMatrix * pointLight.modelMatrix);
  300. this.fragmentShader.sendUniform("u_viewport", Vec4f(camera.viewport.x, camera.viewport.y, camera.viewport.width, camera.viewport.height));
  301. this.fragmentShader.sendUniform("u_viewProjMatrix", camera.viewProjectionMatrix);
  302. this.fragmentShader.sendUniform("u_projMatrix", camera.projectionMatrix);
  303. this.fragmentShader.sendUniform("u_viewMatrix", camera.viewMatrix);
  304. this.fragmentShader.sendTexture("u_gbuffer.depth", camera.gbuffer.depth, 0);
  305. this.fragmentShader.sendTexture("u_gbuffer.normal", camera.gbuffer.normal, 1);
  306. this.fragmentShader.sendTexture("u_gbuffer.color", camera.gbuffer.color, 2);
  307. this.fragmentShader.sendTexture("u_gbuffer.depthstencil", camera.gbuffer.depthstencil, 4);
  308. this.fragmentShader.sendUniform("u_light.color", pointLight.color);
  309. this.fragmentShader.sendUniform("u_light.ambientIntensity", pointLight.ambientIntensity);
  310. this.fragmentShader.sendUniform("u_light.diffuseIntensity", pointLight.diffuseIntensity);
  311. this.fragmentShader.sendUniform("u_light.constant", pointLight.constant);
  312. this.fragmentShader.sendUniform("u_light.linear", pointLight.linear);
  313. this.fragmentShader.sendUniform("u_light.exp", pointLight.exp);
  314. this.fragmentShader.sendUniform("u_light.position", pointLight.position);
  315. check!glDrawArrays(GL_TRIANGLES, 0, 36);
  316. this._vao.unbind();
  317. check!glDisable(GL_BLEND);
  318. glBindProgramPipeline(0);
  319. }
  320. check!glDisable(GL_STENCIL_TEST);
  321. }
  322. //------------------------------------------------------------------------------------------------------------------
  323. // Final Pass
  324. //------------------------------------------------------------------------------------------------------------------
  325. void finalPass() {
  326. check!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  327. check!glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  328. check!glReadBuffer(GL_COLOR_ATTACHMENT3);
  329. with(camera.viewport) {
  330. check!glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
  331. }
  332. _window.swapBuffers();
  333. }
  334. }
  335. struct Vertex {
  336. float x, y, z;
  337. }
  338. struct Normal {
  339. float x, y, z;
  340. }
  341. struct UV {
  342. float u, v;
  343. }
  344. final class Mesh {
  345. public:
  346. Vertex[] vertexData;
  347. Normal[] normalData;
  348. UV[] textureData;
  349. RGBAf[] colorData;
  350. VertexArrayObject vao;
  351. VertexBufferObject!(VertexBufferObjectTarget.Array) vboVertexData;
  352. VertexBufferObject!(VertexBufferObjectTarget.Array) vboNormalData;
  353. VertexBufferObject!(VertexBufferObjectTarget.Array) vboTextureData;
  354. VertexBufferObject!(VertexBufferObjectTarget.Array) vboColorData;
  355. this(string filePath) {
  356. writeln("loading scene: ", filePath);
  357. auto scene = aiImportFile(filePath.toStringz(), aiProcess_Triangulate);
  358. writeln("meshes: ", scene.mNumMeshes);
  359. for(uint m = 0; m < scene.mNumMeshes; ++m) {
  360. const(aiMesh*) mesh = scene.mMeshes[m];
  361. assert(mesh !is null);
  362. writeln("mesh[", m, "] faces : ", mesh.mNumFaces);
  363. for (uint f = 0; f < mesh.mNumFaces; ++f) {
  364. const(aiFace*) face = &mesh.mFaces[f];
  365. assert(face !is null);
  366. for(uint v = 0; v < 3; ++v) {
  367. aiVector3D p, n, uv;
  368. assert(face.mNumIndices > v);
  369. uint vertex = face.mIndices[v];
  370. assert(mesh.mNumVertices > vertex);
  371. p = mesh.mVertices[vertex];
  372. n = mesh.mNormals[vertex];
  373. // check if the mesh has texture coordinates
  374. if(mesh.mTextureCoords[0] !is null) {
  375. uv = mesh.mTextureCoords[0][vertex];
  376. }
  377. vertexData ~= Vertex(p.x, p.y, p.z);
  378. normalData ~= Normal(n.x, n.y, n.z);
  379. textureData ~= UV(uv.x, uv.y);
  380. colorData ~= RGBAf(n.x, n.y, n.z, 1.0f);
  381. }
  382. }
  383. }
  384. writeln("unloading scene: ", filePath);
  385. aiReleaseImport(scene);
  386. //-----------------------------
  387. // upload
  388. writeln("uploading mesh: ", filePath);
  389. vao = new VertexArrayObject();
  390. vao.bind();
  391. writeln("vertex data");
  392. vboVertexData = new VertexBufferObject!(VertexBufferObjectTarget.Array);
  393. vboVertexData.bind();
  394. GLuint attribIndex = 0;
  395. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Vertex.sizeof * vertexData.length) , vertexData.ptr, GL_STATIC_DRAW);
  396. glEnableVertexAttribArray(attribIndex);
  397. glVertexAttribPointer(attribIndex, 3, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  398. vboVertexData.unbind();
  399. writeln("normal data");
  400. vboNormalData = new VertexBufferObject!(VertexBufferObjectTarget.Array);
  401. vboNormalData.bind();
  402. attribIndex = 1;
  403. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Normal.sizeof * normalData.length) , normalData.ptr, GL_STATIC_DRAW);
  404. glEnableVertexAttribArray(attribIndex);
  405. glVertexAttribPointer(attribIndex, 3, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  406. vboNormalData.unbind();
  407. writeln("uv data");
  408. vboTextureData = new VertexBufferObject!(VertexBufferObjectTarget.Array);
  409. vboTextureData.bind();
  410. attribIndex = 2;
  411. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(UV.sizeof * textureData.length) , textureData.ptr, GL_STATIC_DRAW);
  412. glEnableVertexAttribArray(attribIndex);
  413. glVertexAttribPointer(attribIndex, 2, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  414. vboTextureData.unbind();
  415. writeln("color data");
  416. vboColorData = new VertexBufferObject!(VertexBufferObjectTarget.Array);
  417. vboColorData.bind();
  418. attribIndex = 3;
  419. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(RGBAf.sizeof * colorData.length) , colorData.ptr, GL_STATIC_DRAW);
  420. glEnableVertexAttribArray(attribIndex);
  421. glVertexAttribPointer(attribIndex, 4, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  422. vboColorData.unbind();
  423. vao.unbind();
  424. writeln("done");
  425. }
  426. }
  427. void setupTweakbar() {
  428. writeln("creating TweakBar");
  429. double time = 0, dt; // Current time and enlapsed time
  430. double turn = 0; // Model turn counter
  431. double speed = 0.3; // Model rotation speed
  432. int wire = 0; // Draw model in wireframe?
  433. uint frameCount = 0;
  434. double fps = 0;
  435. float bgColor[3] = [0.1f, 0.2f, 0.4f]; // Background color
  436. ubyte cubeColor[4] = [255, 0, 0, 128]; // Model color (32bits RGBA)
  437. auto quat = Quaternionf(0,0,0,1);
  438. // auto w = this._window.getBounds()[2];
  439. // auto h = this._window.getBounds()[3];
  440. TwWindowSize(1600, 900);
  441. // // Create a tweak bar
  442. // auto bar = TwNewBar("TweakBar");
  443. // TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar with GLFW and OpenGL.' "); // Message added to the help bar.
  444. // // Add 'speed' to 'bar': it is a modifable (RW) variable of type TW_TYPE_DOUBLE. Its key shortcuts are [s] and [S].
  445. // TwAddVarRW(bar, "speed", TW_TYPE_DOUBLE, &speed, " label='Rot speed' min=0 max=2 step=0.01 keyIncr=s keyDecr=S help='Rotation speed (turns/second)' ");
  446. // // Add 'wire' to 'bar': it is a modifable variable of type TW_TYPE_BOOL32 (32 bits boolean). Its key shortcut is [w].
  447. // TwAddVarRW(bar, "wire", TW_TYPE_BOOL32, &wire, " label='Wireframe mode' key=CTRL+w help='Toggle wireframe display mode.' ");
  448. // // Add 'time' to 'bar': it is a read-only (RO) variable of type TW_TYPE_DOUBLE, with 1 precision digit
  449. // TwAddVarRO(bar, "time", TW_TYPE_DOUBLE, &time, " label='Time' precision=1 help='Time (in seconds).' ");
  450. // //
  451. // TwAddVarRO(bar, "frameCount", TW_TYPE_UINT32, &frameCount, " label='FrameCount' precision=1 help='FrameCount (in counts).' ");
  452. // TwAddVarRO(bar, "fps", TW_TYPE_DOUBLE, &fps, " label='fps' precision=1 help='fps (in fps).' ");
  453. // // Add 'bgColor' to 'bar': it is a modifable variable of type TW_TYPE_COLOR3F (3 floats color)
  454. // TwAddVarRW(bar, "bgColor", TW_TYPE_COLOR3F, &bgColor, " label='Background color' ");
  455. // // Add 'cubeColor' to 'bar': it is a modifable variable of type TW_TYPE_COLOR32 (32 bits color) with alpha
  456. // TwAddVarRW(bar, "cubeColor", TW_TYPE_COLOR32, &cubeColor, " label='Cube color' alpha help='Color and transparency of the cube.' ");
  457. // //
  458. // TwAddVarRW(bar, "quaternion", TW_TYPE_QUAT4F, &quat, " label='Cubde color' alpha help='Color anwdwd transparency of the cube.' ");
  459. }
  460. //-----------------
  461. // Create Shaders
  462. enum vertexShaderSource = "
  463. #version 420 core
  464. layout(location = 0) in vec3 in_position;
  465. layout(location = 1) in vec3 in_normal;
  466. layout(location = 2) in vec2 in_texcoord;
  467. layout(location = 3) in vec4 in_color;
  468. out vec4 v_color;
  469. out gl_PerVertex
  470. {
  471. vec4 gl_Position;
  472. };
  473. void main()
  474. {
  475. gl_Position = vec4(0.005 * in_position.x, 0.005 * in_position.y, 0.005* in_position.z, 1.0);
  476. v_color = in_color;
  477. }
  478. ";
  479. enum fragmentShaderSource = "
  480. #version 420 core
  481. in vec4 v_color;
  482. out vec4 FragColor;
  483. void main()
  484. {
  485. FragColor = v_color;
  486. }
  487. ";
  488. auto createShaderPipeline(Shader!(ShaderType.Vertex) vertexShader, Shader!(ShaderType.Fragment) fragmentShader) {
  489. assert(vertexShader.isLinked, vertexShader.infoLog());
  490. assert(fragmentShader.isLinked, fragmentShader.infoLog());
  491. writeln("a: ");
  492. auto shaderPipeline = new ShaderPipeline();
  493. shaderPipeline.bind();
  494. shaderPipeline.use(vertexShader);
  495. shaderPipeline.use(fragmentShader);
  496. writeln("b: ");
  497. assert(shaderPipeline.isValidProgramPipeline, shaderPipeline.infoLog());
  498. shaderPipeline.unbind();
  499. writeln("c: ");
  500. return shaderPipeline;
  501. }
  502. class Tester {
  503. Window _window;
  504. bool _keepRunning = true;
  505. this() {
  506. this._window = initThree();
  507. this._window.onKey.connect!"_onKey"(this);
  508. this._window.onClose.connect!"_onClose"(this);
  509. }
  510. ~this() {
  511. import core.memory;
  512. writeln("GC.collect: ");
  513. GC.collect();
  514. //Collect window _AFTER_ everything else
  515. this._window = null;
  516. GC.collect();
  517. deinitThree();
  518. }
  519. void run() {
  520. RGBAf rgg;
  521. auto mesh = new Mesh("C:/Coding/models/Collada/duck.dae");
  522. setupTweakbar();
  523. writeln("creating shaders: ");
  524. auto vertexShader = new Shader!(ShaderType.Vertex)(vertexShaderSource);
  525. auto fragmentShader = new Shader!(ShaderType.Fragment)(fragmentShaderSource);
  526. writeln("creating shader pipeline: ");
  527. auto shaderPipeline = createShaderPipeline(vertexShader, fragmentShader);
  528. writeln("connectiong window callbacks: ");
  529. this._window.onSize.connect!"onSize"(this);
  530. this._window.onPosition.connect!"onPosition"(this);
  531. this._window.onButton.connect!"onButton"(this);
  532. this._window.onCursorPos.connect!"onCursorPos"(this);
  533. writeln("begin render loop: ");
  534. //-----------------
  535. // Render Loop
  536. glfwSetTime(0);
  537. while(this._keepRunning) {
  538. this._window.clear(0, 0, 0.5, 1);
  539. shaderPipeline.bind();
  540. mesh.vao.bind();
  541. //vboVertexData.bind();
  542. glDrawArrays(GL_TRIANGLES, 0, mesh.vertexData.length);
  543. //vbo.unbind();
  544. mesh.vao.unbind();
  545. shaderPipeline.unbind();
  546. TwDraw();
  547. this._window.swapBuffers();
  548. updateWindows();
  549. // ++frameCount;
  550. // //if(frameCount % 100 == 0) {
  551. // time = glfwGetTime();
  552. // fps = cast(double)frameCount / time;
  553. // //}
  554. }
  555. }
  556. void onSize(Window window, int width, int height) {
  557. TwWindowSize(width, height);
  558. }
  559. void onPosition(Window window, int x, int y) {
  560. }
  561. void onButton(Window window , int button, ButtonAction action) {
  562. TwMouseAction twaction = action == ButtonAction.Pressed ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED;
  563. TwMouseButtonID twbutton;
  564. switch(button) {
  565. default:
  566. case GLFW_MOUSE_BUTTON_LEFT: twbutton = TW_MOUSE_LEFT; break;
  567. case GLFW_MOUSE_BUTTON_RIGHT: twbutton = TW_MOUSE_RIGHT; break;
  568. case GLFW_MOUSE_BUTTON_MIDDLE: twbutton = TW_MOUSE_MIDDLE; break;
  569. }
  570. TwMouseButton(twaction, twbutton);
  571. }
  572. void onCursorPos(Window window, double x, double y) {
  573. TwMouseMotion(cast(int)x, this._window.getBounds()[3] - cast(int)y);
  574. }
  575. void stop() {
  576. this._keepRunning = false;
  577. }
  578. void _onKey(Window window, Key key, ScanCode scanCode, KeyAction action, KeyMod keyMod) {
  579. if(window is this._window && action == KeyAction.Pressed) {
  580. if(key == Key.Escape) {
  581. this.stop();
  582. }
  583. }
  584. }
  585. void _onClose(Window window) {
  586. this.stop();
  587. }
  588. }
  589. class InputHandler {
  590. private:
  591. Window _window;
  592. OpenGlRenderer _renderer;
  593. public:
  594. this(Window window, OpenGlRenderer renderer) {
  595. _window = window;
  596. _renderer = renderer;
  597. _window.onKey.connect!"_onKey"(this);
  598. _window.onClose.connect!"_onClose"(this);
  599. _window.onSize.connect!"_onSize"(this);
  600. _window.onPosition.connect!"_onPosition"(this);
  601. _window.onButton.connect!"_onButton"(this);
  602. _window.onCursorPos.connect!"_onCursorPos"(this);
  603. }
  604. private:
  605. void _onKey(Window window, Key key, ScanCode scanCode, KeyAction action, KeyMod keyMod) {
  606. if(window is _window && action == KeyAction.Pressed) {
  607. if(key == Key.Escape) {
  608. _renderer.stop();
  609. }
  610. }
  611. }
  612. void _onClose(Window window) {
  613. _renderer.stop();
  614. }
  615. void _onSize(Window window, int width, int height) {
  616. }
  617. void _onPosition(Window window, int x, int y) {
  618. }
  619. void _onButton(Window window , int button, ButtonAction action) {
  620. }
  621. void _onCursorPos(Window window, double x, double y) {
  622. }
  623. }
  624. void main() {
  625. auto window = initThree();
  626. {
  627. OpenGlRenderer renderer = new OpenGlRenderer(window);
  628. InputHandler inputHandler = new InputHandler(window, renderer);
  629. renderer.run();
  630. }
  631. import core.memory;
  632. GC.collect();
  633. //Collect window _AFTER_ everything else
  634. this._window = null;
  635. GC.collect();
  636. deinitThree();
  637. }