1
1

renderer.d 5.2 KB

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