| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- //
- // Copyright (c) 2008-2017 the Urho3D project.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #pragma once
- #include "../Core/Object.h"
- #include "../Core/Timer.h"
- #include "../Container/ArrayPtr.h"
- #include "../Graphics/GraphicsDefs.h"
- #include "../Math/Frustum.h"
- namespace Atomic
- {
- class BoundingBox;
- class Camera;
- class IndexBuffer;
- class IntRect;
- class VertexBuffer;
- struct Edge;
- struct Gradients;
- /// Occlusion hierarchy depth value.
- struct DepthValue
- {
- /// Minimum value.
- int min_;
- /// Maximum value.
- int max_;
- };
- /// Per-thread occlusion buffer data.
- struct OcclusionBufferData
- {
- /// Full buffer data with safety padding.
- SharedArrayPtr<int> dataWithSafety_;
- /// Buffer data.
- int* data_;
- /// Use flag.
- bool used_;
- };
- /// Stored occlusion render job.
- struct OcclusionBatch
- {
- /// Model matrix.
- Matrix3x4 model_;
- /// Vertex data pointer.
- const void* vertexData_;
- /// Vertex size in bytes.
- unsigned vertexSize_;
- /// Index data pointer. Null if using non-indexed geometry.
- const void* indexData_;
- /// Index size in bytes.
- unsigned indexSize_;
- /// Draw start. First index for indexed geometry, otherwise first vertex.
- unsigned drawStart_;
- /// Index or vertex count.
- unsigned drawCount_;
- };
- static const int OCCLUSION_MIN_SIZE = 8;
- static const int OCCLUSION_DEFAULT_MAX_TRIANGLES = 5000;
- static const float OCCLUSION_RELATIVE_BIAS = 0.00001f;
- static const int OCCLUSION_FIXED_BIAS = 16;
- static const float OCCLUSION_X_SCALE = 65536.0f;
- static const float OCCLUSION_Z_SCALE = 16777216.0f;
- /// Software renderer for occlusion.
- class ATOMIC_API OcclusionBuffer : public Object
- {
- ATOMIC_OBJECT(OcclusionBuffer, Object);
- public:
- /// Construct.
- OcclusionBuffer(Context* context);
- /// Destruct.
- virtual ~OcclusionBuffer();
- /// Set occlusion buffer size and whether to reserve multiple buffers for threading optimization.
- bool SetSize(int width, int height, bool threaded);
- /// Set camera view to render from.
- void SetView(Camera* camera);
- /// Set maximum triangles to render.
- void SetMaxTriangles(unsigned triangles);
- /// Set culling mode.
- void SetCullMode(CullMode mode);
- /// Reset number of triangles.
- void Reset();
- /// Clear the buffer.
- void Clear();
- /// Submit a triangle mesh to the buffer using non-indexed geometry. Return true if did not overflow the allowed triangle count.
- bool AddTriangles(const Matrix3x4& model, const void* vertexData, unsigned vertexSize, unsigned vertexStart, unsigned vertexCount);
- /// Submit a triangle mesh to the buffer using indexed geometry. Return true if did not overflow the allowed triangle count.
- bool AddTriangles(const Matrix3x4& model, const void* vertexData, unsigned vertexSize, const void* indexData, unsigned indexSize,
- unsigned indexStart, unsigned indexCount);
- /// Draw submitted batches. Uses worker threads if enabled during SetSize().
- void DrawTriangles();
- /// Build reduced size mip levels.
- void BuildDepthHierarchy();
- /// Reset last used timer.
- void ResetUseTimer();
- /// Return highest level depth values.
- int* GetBuffer() const { return buffers_.Size() ? buffers_[0].data_ : (int*)0; }
- /// Return view transform matrix.
- const Matrix3x4& GetView() const { return view_; }
- /// Return projection matrix.
- const Matrix4& GetProjection() const { return projection_; }
- /// Return buffer width.
- int GetWidth() const { return width_; }
- /// Return buffer height.
- int GetHeight() const { return height_; }
- /// Return number of rendered triangles.
- unsigned GetNumTriangles() const { return numTriangles_; }
- /// Return maximum number of triangles.
- unsigned GetMaxTriangles() const { return maxTriangles_; }
- /// Return culling mode.
- CullMode GetCullMode() const { return cullMode_; }
- /// Return whether is using threads to speed up rendering.
- bool IsThreaded() const { return buffers_.Size() > 1; }
- /// Test a bounding box for visibility. For best performance, build depth hierarchy first.
- bool IsVisible(const BoundingBox& worldSpaceBox) const;
- /// Return time since last use in milliseconds.
- unsigned GetUseTimer();
- /// Draw a batch. Called internally.
- void DrawBatch(const OcclusionBatch& batch, unsigned threadIndex);
- private:
- /// Apply modelview transform to vertex.
- inline Vector4 ModelTransform(const Matrix4& transform, const Vector3& vertex) const;
- /// Apply projection and viewport transform to vertex.
- inline Vector3 ViewportTransform(const Vector4& vertex) const;
- /// Clip an edge.
- inline Vector4 ClipEdge(const Vector4& v0, const Vector4& v1, float d0, float d1) const;
- /// Return signed area of a triangle. If negative, is clockwise.
- inline float SignedArea(const Vector3& v0, const Vector3& v1, const Vector3& v2) const;
- /// Calculate viewport transform.
- void CalculateViewport();
- /// Draw a triangle.
- void DrawTriangle(Vector4* vertices, unsigned threadIndex);
- /// Clip vertices against a plane.
- void ClipVertices(const Vector4& plane, Vector4* vertices, bool* triangles, unsigned& numTriangles);
- /// Draw a clipped triangle.
- void DrawTriangle2D(const Vector3* vertices, bool clockwise, unsigned threadIndex);
- /// Clear a thread work buffer.
- void ClearBuffer(unsigned threadIndex);
- /// Merge thread work buffers into the first buffer.
- void MergeBuffers();
- /// Highest-level buffer data per thread.
- Vector<OcclusionBufferData> buffers_;
- /// Reduced size depth buffers.
- Vector<SharedArrayPtr<DepthValue> > mipBuffers_;
- /// Submitted render jobs.
- PODVector<OcclusionBatch> batches_;
- /// Buffer width.
- int width_;
- /// Buffer height.
- int height_;
- /// Number of rendered triangles.
- unsigned numTriangles_;
- /// Maximum number of triangles.
- unsigned maxTriangles_;
- /// Culling mode.
- CullMode cullMode_;
- /// Depth hierarchy needs update flag.
- bool depthHierarchyDirty_;
- /// Culling reverse flag.
- bool reverseCulling_;
- /// View transform matrix.
- Matrix3x4 view_;
- /// Projection matrix.
- Matrix4 projection_;
- /// Combined view and projection matrix.
- Matrix4 viewProj_;
- /// Last used timer.
- Timer useTimer_;
- /// Near clip distance.
- float nearClip_;
- /// Far clip distance.
- float farClip_;
- /// X scaling for viewport transform.
- float scaleX_;
- /// Y scaling for viewport transform.
- float scaleY_;
- /// X offset for viewport transform.
- float offsetX_;
- /// Y offset for viewport transform.
- float offsetY_;
- /// Combined X projection and viewport transform.
- float projOffsetScaleX_;
- /// Combined Y projection and viewport transform.
- float projOffsetScaleY_;
- };
- }
|