| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // zlib open source license
- //
- // Copyright (c) 2017 to 2019 David Forsgren Piuva
- //
- // This software is provided 'as-is', without any express or implied
- // warranty. In no event will the authors be held liable for any damages
- // arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it
- // freely, subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented; you must not
- // claim that you wrote the original software. If you use this software
- // in a product, an acknowledgment in the product documentation would be
- // appreciated but is not required.
- //
- // 2. Altered source versions must be plainly marked as such, and must not be
- // misrepresented as being the original software.
- //
- // 3. This notice may not be removed or altered from any source
- // distribution.
- #ifndef DFPSR_RENDER_MODEL_RENDERCORE
- #define DFPSR_RENDER_MODEL_RENDERCORE
- #include <cstdint>
- #include "Camera.h"
- #include "shader/Shader.h"
- #include "../base/threading.h"
- #include "../collection/List.h"
- namespace dsr {
- struct TriangleDrawData {
- // Color target
- ImageRgbaU8 *targetImage;
- // Depth target
- ImageF32 *depthBuffer;
- // When perspective is used, the depth buffer stores 1 / depth instead of linear depth.
- bool perspective;
- // The target blending method
- Filter filter;
- // Unprocessed triangle data in the standard layout
- TriangleInput triangleInput;
- // Function pointer to the method that will process the command
- DRAW_CALLBACK_TYPE processTriangle;
- TriangleDrawData(ImageRgbaU8 *targetImage, ImageF32 *depthBuffer, bool perspective, Filter filter, const TriangleInput &triangleInput, DRAW_CALLBACK_TYPE processTriangle)
- : targetImage(targetImage), depthBuffer(depthBuffer), perspective(perspective), filter(filter), triangleInput(triangleInput), processTriangle(processTriangle) {}
- };
- struct TriangleDrawCommand : public TriangleDrawData {
- // Triangle corners and projection
- // Not a part of TriangleDrawData, because the draw command is made after clipping into multiple smaller triangles
- ITriangle2D triangle;
- // The vertex interpolation weights for each corner to allow clipping triangles without
- // looping the same vertex colors and texture coordinates on every sub-triangle
- // Corner A's weight = (subB.x, subC.x)
- // Corner B's weight = (subB.y, subC.y)
- // Corner C's weight = (subB.z, subC.z)
- // The final vertex weight of a corner becomes a linear interpolation of the three original vertex weights
- // (A * (1 - subB - subC)) + (B * subB) + (C * subC)
- FVector3D subB, subC;
- // Extra clipping in case that the receiver of the command goes out of bound
- IRect clipBound;
- // Late removal of triangles without having to shuffle around any data
- bool occluded;
- TriangleDrawCommand(const TriangleDrawData &triangleDrawData, const ITriangle2D &triangle, const FVector3D &subB, const FVector3D &subC, const IRect &clipBound)
- : TriangleDrawData(triangleDrawData), triangle(triangle), subB(subB), subC(subC), clipBound(clipBound), occluded(false) {}
- };
- // Get the visibility state for the triangle as seen by the camera.
- // If clipFrustum is false, the culling test will be done with the actual bounds of the target image.
- // This is used to know when a triangle needs to be drawn.
- // If clipFrustum is true, the culling test will be done with extended clip bounds outside of the target image.
- // This is used to know when a triangle needs lossy clipping in floating-point coordinates
- // before it can be converted to integer coordinates without causing an overflow in rasterization.
- Visibility getTriangleVisibility(const ITriangle2D &triangle, const Camera &camera, bool clipFrustum);
- // Draws according to a draw command.
- void executeTriangleDrawing(const TriangleDrawCommand &command, const IRect &clipBound);
- // A queue of draw commands
- class CommandQueue {
- public:
- List<TriangleDrawCommand> buffer;
- void add(const TriangleDrawCommand &command);
- // Multi-threading will be disabled if jobCount equals 1.
- void execute(const IRect &clipBound, int jobCount = 12) const;
- void clear();
- };
- // Given a triangle and a shader that holds the additional vertex data, this method can be called to draw it.
- // Preconditions:
- // * triangle should have passed the triangle visibility test for the actual image bound.
- // Only construct the shader and make this call if "getTriangleVisibility(triangle, camera, false) != Visibility::Hidden" passed.
- // Otherwise, it will waste a lot of time on rasterizing triangles that are not even visible.
- // Given a set of triangle data, this method can automatically draw it using the fastest default shader.
- // Triangle culling is handled automatically but you might want to apply culling per model or something before drawing many triangles.
- // commandQueue can be null to render directly using a single thread.
- // targetImage can be null to avoid using the pixel shader.
- // depthBuffer can be null to render without depth buffering.
- void renderTriangleFromData(
- CommandQueue *commandQueue, ImageRgbaU8 *targetImage, ImageF32 *depthBuffer,
- const Camera &camera, const ProjectedPoint &posA, const ProjectedPoint &posB, const ProjectedPoint &posC,
- Filter filter, const TextureRgbaU8 *diffuse, const TextureRgbaU8 *light,
- TriangleTexCoords texCoords, TriangleColors colors
- );
- void renderTriangleFromDataDepth(ImageF32 *depthBuffer, const Camera &camera, const ProjectedPoint &posA, const ProjectedPoint &posB, const ProjectedPoint &posC);
- }
- #endif
|