1
1

renderer.d 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. module three.renderer;
  2. import three.common;
  3. import three.scene;
  4. import three.camera;
  5. import three.renderTarget;
  6. import three.viewport;
  7. import three.mesh;
  8. import std.string : toStringz;
  9. import std.exception : collectException;
  10. import std.experimental.logger;
  11. //======================================================================================================================
  12. //
  13. //======================================================================================================================
  14. enum GlBufferTarget {
  15. Array = GL_ARRAY_BUFFER,
  16. AtomicCounter = GL_ATOMIC_COUNTER_BUFFER,
  17. CopyRead= GL_COPY_READ_BUFFER,
  18. CopyWrite = GL_COPY_WRITE_BUFFER,
  19. DrawIndirect = GL_DRAW_INDIRECT_BUFFER,
  20. DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER,
  21. ElementArray = GL_ELEMENT_ARRAY_BUFFER,
  22. PixelPack = GL_PIXEL_PACK_BUFFER,
  23. PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
  24. QueryBuffer = GL_QUERY_BUFFER,
  25. ShaderStorage = GL_SHADER_STORAGE_BUFFER,
  26. Texture = GL_TEXTURE_BUFFER,
  27. TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
  28. Uniform = GL_UNIFORM_BUFFER
  29. }
  30. struct GlBuffer(GlBufferTarget Target, T) {
  31. alias BufferTarget = Target;
  32. alias ValueType = T;
  33. GLuint handle;
  34. GLuint length;
  35. T* data;
  36. }
  37. void construct(GlBufferTarget Target, T)(out GlBuffer!(Target, T) buffer, GLuint length, GLbitfield createFlags, GLbitfield mapFlags) {
  38. glCheck!glGenBuffers(1, &buffer.handle);
  39. glCheck!glBindBuffer(Target, buffer.handle);
  40. glCheck!glBufferStorage(Target, length * T.sizeof, null, createFlags);
  41. buffer.data = cast(T*)glCheck!glMapBufferRange(Target, 0, length * T.sizeof, mapFlags);
  42. buffer.length = length;
  43. if (buffer.data is null) {
  44. throw new Exception("glMapBufferRange failed, probable bug.");
  45. }
  46. }
  47. void destruct(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  48. glCheck!glBindBuffer(Target, buffer.handle);
  49. glCheck!glUnmapBuffer(Target);
  50. glCheck!glDeleteBuffers(1, &buffer.handle);
  51. buffer = buffer.init;
  52. }
  53. void bind(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  54. glCheck!glBindBuffer(Target, buffer.handle);
  55. }
  56. void unbind(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  57. glCheck!glBindBuffer(Target, 0);
  58. }
  59. alias GlArrayBuffer(T) = GlBuffer!(GlBufferTarget.Array, T);
  60. alias GlElementArrayBuffer(T) = GlBuffer!(GlBufferTarget.ElementArray, T);
  61. alias GlShaderStorageBuffer(T) = GlBuffer!(GlBufferTarget.ShaderStorage, T);
  62. alias GlDispatchIndirectBuffer(T) = GlBuffer!(GlBufferTarget.DispatchIndirect, T);
  63. alias GlTextureBuffer(T) = GlBuffer!(GlBufferTarget.Texture, T);
  64. alias GlUniformBuffer(T) = GlBuffer!(GlBufferTarget.Uniform, T);
  65. //======================================================================================================================
  66. //
  67. //======================================================================================================================
  68. struct DrawElementsIndirectCommand {
  69. GLuint count;
  70. GLuint instanceCount;
  71. GLuint firstIndex;
  72. GLuint baseVertex;
  73. GLuint baseInstance;
  74. }
  75. struct DrawParameter {
  76. Matrix4 transformationMatrix;
  77. }
  78. //======================================================================================================================
  79. //
  80. //======================================================================================================================
  81. struct Renderer {
  82. uint width;
  83. uint height;
  84. GlArrayBuffer!VertexData vertexBuffer; // vertex data for all meshes
  85. GlElementArrayBuffer!IndexData indexBuffer; //index data for all meshes
  86. GlShaderStorageBuffer!DrawParameter perInstanceParamBuffer; // is filled with draw parameters for each instance each frame. shall be accessed as a ringbuffer
  87. GlDispatchIndirectBuffer!DrawElementsIndirectCommand dispatchIndirectCommandBuffer; // is filled with DrawElementsIndirectCommand for each mesh each frame. shall be accessed as a ringbuffer
  88. }
  89. void construct(out Renderer renderer, uint width, uint height) {
  90. GLbitfield createFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;//TODO: ?? | GL_MAP_DYNAMIC_STORAGE_BIT;
  91. GLbitfield mapFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
  92. renderer.vertexBuffer.construct(1024, createFlags, mapFlags);
  93. renderer.indexBuffer.construct(1024, createFlags, mapFlags);
  94. renderer.perInstanceParamBuffer.construct(1024, createFlags, mapFlags);
  95. renderer.dispatchIndirectCommandBuffer.construct(1024, createFlags, mapFlags);
  96. glCheck!glEnableVertexAttribArray(0);
  97. glCheck!glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)0 );
  98. glCheck!glEnableVertexAttribArray(1);
  99. glCheck!glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)3 );
  100. glCheck!glEnableVertexAttribArray(2);
  101. glCheck!glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)6 );
  102. glCheck!glEnableVertexAttribArray(3);
  103. glCheck!glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)10 );
  104. }
  105. void destruct(ref Renderer renderer) {
  106. renderer.vertexBuffer.destruct();
  107. renderer.indexBuffer.destruct();
  108. renderer.perInstanceParamBuffer.destruct();
  109. renderer.dispatchIndirectCommandBuffer.destruct();
  110. renderer = renderer.init;
  111. }
  112. void uploadModelData(ref Renderer renderer, ModelData modelData) {
  113. }
  114. void renderOneFrame(ref Renderer renderer, ref Scene scene, ref Camera camera, ref RenderTarget renderTarget, ref Viewport viewport) {
  115. /*
  116. foreach(renderTarget) //framebuffer
  117. foreach(pass)
  118. foreach(material) //shaders
  119. foreach(materialInstance) //textures
  120. foreach(vertexFormat) //vertex buffers
  121. foreach(object) {
  122. write uniform data;
  123. glDrawElementsBaseVertex
  124. }
  125. */
  126. GLsizei meshCount = 0;
  127. glCheck!glViewport(0, 0, renderer.width, renderer.height);
  128. //enable depth mask _before_ glClear ing the depth buffer!
  129. glCheck!glDepthMask(GL_TRUE); scope(exit) glCheck!glDepthMask(GL_FALSE);
  130. glCheck!glEnable(GL_DEPTH_TEST); scope(exit) glCheck!glDisable(GL_DEPTH_TEST);
  131. glCheck!glDepthFunc(GL_LEQUAL);
  132. // write draw parameters
  133. // write draw commmands
  134. //draw //TODO: pass offset (cast to ptr) into command buffer instead of null
  135. renderer.vertexBuffer.bind();
  136. renderer.indexBuffer.bind();
  137. renderer.perInstanceParamBuffer.bind();
  138. renderer.dispatchIndirectCommandBuffer.bind();
  139. glCheck!glMultiDrawElementsIndirect(GL_TRIANGLES, toGlType!(renderer.indexBuffer.ValueType), null, meshCount, 0);
  140. }
  141. debug {
  142. void blitGBufferToScreen(ref Renderer renderer) {
  143. }
  144. }