renderer.d 5.1 KB

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