renderCore.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2017 to 2019 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. #ifndef DFPSR_RENDER_MODEL_RENDERCORE
  24. #define DFPSR_RENDER_MODEL_RENDERCORE
  25. #include <cstdint>
  26. #include "Camera.h"
  27. #include "shader/Shader.h"
  28. #include "../base/threading.h"
  29. #include "../collection/List.h"
  30. namespace dsr {
  31. struct TriangleDrawData {
  32. // Color target
  33. ImageRgbaU8 *targetImage;
  34. // Depth target
  35. ImageF32 *depthBuffer;
  36. // When perspective is used, the depth buffer stores 1 / depth instead of linear depth.
  37. bool perspective;
  38. // The target blending method
  39. Filter filter;
  40. // Unprocessed triangle data in the standard layout
  41. TriangleInput triangleInput;
  42. // Function pointer to the method that will process the command
  43. DRAW_CALLBACK_TYPE processTriangle;
  44. TriangleDrawData(ImageRgbaU8 *targetImage, ImageF32 *depthBuffer, bool perspective, Filter filter, const TriangleInput &triangleInput, DRAW_CALLBACK_TYPE processTriangle)
  45. : targetImage(targetImage), depthBuffer(depthBuffer), perspective(perspective), filter(filter), triangleInput(triangleInput), processTriangle(processTriangle) {}
  46. };
  47. struct TriangleDrawCommand : public TriangleDrawData {
  48. // Triangle corners and projection
  49. // Not a part of TriangleDrawData, because the draw command is made after clipping into multiple smaller triangles
  50. ITriangle2D triangle;
  51. // The vertex interpolation weights for each corner to allow clipping triangles without
  52. // looping the same vertex colors and texture coordinates on every sub-triangle
  53. // Corner A's weight = (subB.x, subC.x)
  54. // Corner B's weight = (subB.y, subC.y)
  55. // Corner C's weight = (subB.z, subC.z)
  56. // The final vertex weight of a corner becomes a linear interpolation of the three original vertex weights
  57. // (A * (1 - subB - subC)) + (B * subB) + (C * subC)
  58. FVector3D subB, subC;
  59. // Extra clipping in case that the receiver of the command goes out of bound
  60. IRect clipBound;
  61. // Late removal of triangles without having to shuffle around any data
  62. bool occluded;
  63. TriangleDrawCommand(const TriangleDrawData &triangleDrawData, const ITriangle2D &triangle, const FVector3D &subB, const FVector3D &subC, const IRect &clipBound)
  64. : TriangleDrawData(triangleDrawData), triangle(triangle), subB(subB), subC(subC), clipBound(clipBound), occluded(false) {}
  65. };
  66. // Get the visibility state for the triangle as seen by the camera.
  67. // If clipFrustum is false, the culling test will be done with the actual bounds of the target image.
  68. // This is used to know when a triangle needs to be drawn.
  69. // If clipFrustum is true, the culling test will be done with extended clip bounds outside of the target image.
  70. // This is used to know when a triangle needs lossy clipping in floating-point coordinates
  71. // before it can be converted to integer coordinates without causing an overflow in rasterization.
  72. Visibility getTriangleVisibility(const ITriangle2D &triangle, const Camera &camera, bool clipFrustum);
  73. // Draws according to a draw command.
  74. void executeTriangleDrawing(const TriangleDrawCommand &command, const IRect &clipBound);
  75. // A queue of draw commands
  76. class CommandQueue {
  77. public:
  78. List<TriangleDrawCommand> buffer;
  79. void add(const TriangleDrawCommand &command);
  80. // Multi-threading will be disabled if jobCount equals 1.
  81. void execute(const IRect &clipBound, int jobCount = 12) const;
  82. void clear();
  83. };
  84. // Given a triangle and a shader that holds the additional vertex data, this method can be called to draw it.
  85. // Preconditions:
  86. // * triangle should have passed the triangle visibility test for the actual image bound.
  87. // Only construct the shader and make this call if "getTriangleVisibility(triangle, camera, false) != Visibility::Hidden" passed.
  88. // Otherwise, it will waste a lot of time on rasterizing triangles that are not even visible.
  89. // Given a set of triangle data, this method can automatically draw it using the fastest default shader.
  90. // Triangle culling is handled automatically but you might want to apply culling per model or something before drawing many triangles.
  91. // commandQueue can be null to render directly using a single thread.
  92. // targetImage can be null to avoid using the pixel shader.
  93. // depthBuffer can be null to render without depth buffering.
  94. void renderTriangleFromData(
  95. CommandQueue *commandQueue, ImageRgbaU8 *targetImage, ImageF32 *depthBuffer,
  96. const Camera &camera, const ProjectedPoint &posA, const ProjectedPoint &posB, const ProjectedPoint &posC,
  97. Filter filter, const TextureRgbaU8 *diffuse, const TextureRgbaU8 *light,
  98. TriangleTexCoords texCoords, TriangleColors colors
  99. );
  100. void renderTriangleFromDataDepth(ImageF32 *depthBuffer, const Camera &camera, const ProjectedPoint &posA, const ProjectedPoint &posB, const ProjectedPoint &posC);
  101. }
  102. #endif