Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
DVDGeometryBuffer.cpp
Go to the documentation of this file.
1
2
3/***********************************************************************
4 created: Wed, 8th Feb 2012
5 author: Lukas E Meindl (based on code by Paul D Turner)
6*************************************************************************/
7/***************************************************************************
8 * Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 ***************************************************************************/
29
30
32#include "Headers/DVDTexture.h"
34
35#include "CEGUI/RenderEffect.h"
36#include "CEGUI/Vertex.h"
37
42
43#ifndef GLM_FORCE_DEPTH_ZERO_TO_ONE
44#define GLM_FORCE_DEPTH_ZERO_TO_ONE
45#endif
46
47#include "glm/glm.hpp"
48#include "glm/gtc/quaternion.hpp"
49#include "glm/gtc/matrix_transform.hpp"
50
51// Start of CEGUI namespace section
52namespace CEGUI
53{
54
55//----------------------------------------------------------------------------//
57 : _owner( &owner )
58 , _bufferSize(1 << 8u)
59{
60 thread_local size_t BUFFER_IDX = 0u;
61
62 _gvd = owner.context().newGVD(Divide::Config::MAX_FRAMES_IN_FLIGHT + 1u, Divide::Util::StringFormat("IMGUI_{}", BUFFER_IDX++).c_str());
63
64 recreateBuffer(nullptr, 0u);
65
70}
71
73{
74 using namespace Divide;
75
76 const CEGUI::Rectf viewPort = _owner->getActiveViewPort();
77
78 GFX::CommandBuffer* cmdBuffer = _owner->cmdBuffer();
79 Divide::Rect<I32>& clipRect = GFX::EnqueueCommand<GFX::SetScissorCommand>( *cmdBuffer )->_rect;
80
81 // setup clip region
82 clipRect.offsetX = to_I32( _clipRect.left() );
83 clipRect.offsetY = to_I32( viewPort.getHeight() - _clipRect.bottom() );
84 clipRect.sizeX = to_I32( _clipRect.getWidth() );
85 clipRect.sizeY = to_I32( _clipRect.getHeight() );
86
88 {
89 clipRect.offsetY = to_I32(_clipRect.top());
90 }
91
92 // apply the transformations we need to use.
93 if (!_matrixValid)
94 {
96 }
97
98 // Send ModelViewProjection matrix to shader
99 const glm::mat4 modelViewProjectionMatrix = _owner->getViewProjectionMatrix() * _matrix;
100
101 const int pass_count = _effect ? _effect->getPassCount() : 1;
102
103 Divide::U32 pos = 0u;
105 drawCmd._sourceBuffer = _gvd->handle();
106
107 for (int pass = 0; pass < pass_count; ++pass)
108 {
109 // set up RenderEffect
110 if (_effect)
111 {
112 _effect->performPreRenderFunctions(pass);
113 }
114
115 // draw the batches
116 for (const BatchInfo& currentBatch : _batches)
117 {
118 if ( currentBatch.vertexCount == 0u )
119 {
120 continue;
121 }
122
123 _owner->bindDefaultState( currentBatch.clip, d_blendMode, modelViewProjectionMatrix );
124
125 if (currentBatch.texture != Divide::INVALID_HANDLE<Divide::Texture> )
126 {
127 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>( *cmdBuffer );
128 cmd->_usage = DescriptorSetUsage::PER_DRAW;
129
130 DescriptorSetBinding& binding = AddBinding( cmd->_set, 0u, ShaderStageVisibility::FRAGMENT );
131 Set( binding._data, currentBatch.texture, _sampler );
132 }
133
134 drawCmd._cmd.baseVertex = pos;
135 drawCmd._cmd.vertexCount = currentBatch.vertexCount;
136
137 GFX::EnqueueCommand<GFX::DrawCommand>( *cmdBuffer )->_drawCommands.emplace_back(drawCmd);
138
139 pos += currentBatch.vertexCount;
140 }
141 }
142
143 // clean up RenderEffect
144 if (_effect)
145 {
146 _effect->performPostRenderFunctions();
147 }
148}
149
150void DVDGeometryBuffer::appendGeometry(const Vertex* const vbuff, uint vertex_count)
151{
153
154 // update size of current batch
155 _batches.back().vertexCount += vertex_count;
156
157 // buffer these vertices
158 DVDVertex vd{};
159 const Vertex* vs = vbuff;
160 for ( uint i = 0u; i < vertex_count; ++i, ++vs )
161 {
162 // copy vertex info the buffer, converting from CEGUI::Vertex to something directly usable by the rendering API as needed.
163 vd.tex[0] = vs->tex_coords.d_x;
164 vd.tex[1] = vs->tex_coords.d_y;
165 vd.colour[0] = vs->colour_val.getRed();
166 vd.colour[1] = vs->colour_val.getGreen();
167 vd.colour[2] = vs->colour_val.getBlue();
168 vd.colour[3] = vs->colour_val.getAlpha();
169 vd.position[0] = vs->position.d_x;
170 vd.position[1] = vs->position.d_y;
171 vd.position[2] = vs->position.d_z;
172 _vertices.push_back( vd );
173 }
174
176}
177
179{
180 _batches.clear();
181 _vertices.clear();
182 _activeTexture = nullptr;
183
185}
186
187void DVDGeometryBuffer::recreateBuffer( Divide::Byte* initialData, const size_t intialDataSize )
188{
189 using namespace Divide;
190
192 params._bindConfig = { 0u, 0u };
193 params._useRingBuffer = true;
194 params._initialData = { initialData, intialDataSize };
195
197 params._bufferParams._elementSize = sizeof( DVDVertex );
198 params._bufferParams._flags._updateFrequency = BufferUpdateFrequency::OFTEN;
199 params._bufferParams._flags._updateUsage = BufferUpdateUsage::CPU_TO_GPU;
200
201 const BufferLock lock = _gvd->setBuffer( params );
202
203 if ( _owner->memCmd() )
204 {
205 _owner->memCmd()->_bufferLocks.push_back( lock );
206 }
207}
208
210{
211 const Divide::U32 vertexCount = Divide::to_U32(_vertices.size());
212 if ( vertexCount > 0u )
213 {
214 bool needNewBuffer = false;
215 if(_bufferSize < vertexCount)
216 {
217 needNewBuffer = true;
218 _bufferSize = vertexCount;
219 }
220
221 Divide::Byte* data = (Divide::Byte*)_vertices.data();
222 if( needNewBuffer )
223 {
224 recreateBuffer(data, vertexCount * sizeof( DVDVertex ) );
225 }
226 else
227 {
228 _gvd->incQueue();
229 _owner->memCmd()->_bufferLocks.push_back(_gvd->updateBuffer(0u, 0u, vertexCount, data));
230 }
231 }
232}
233
235{
236 Divide::Handle<Divide::Texture> tex = _activeTexture ? _activeTexture->getDVDTexture() : Divide::INVALID_HANDLE<Divide::Texture>;
237
238 // create a new batch if there are no batches yet, or if the active texture differs from that used by the current batch.
239 if ( _batches.empty() ||
240 tex != _batches.back().texture ||
241 _clippingActive != _batches.back().clip )
242 {
243 _batches.emplace_back(BatchInfo
244 {
245 .texture = tex,
246 .vertexCount = 0,
247 .clip = _clippingActive
248 });
249 }
250}
251
252const glm::mat4& DVDGeometryBuffer::getMatrix() const
253{
254 if ( !_matrixValid )
255 {
256 updateMatrix();
257 }
258
259 return _matrix;
260}
261
263{
264 glm::mat4& modelMatrix = _matrix;
265 modelMatrix = glm::mat4( 1.f );
266
267 const glm::vec3 final_trans( _translation.d_x + _pivot.d_x,
268 _translation.d_y + _pivot.d_y,
269 _translation.d_z + _pivot.d_z );
270
271 modelMatrix = glm::translate( modelMatrix, final_trans );
272
273 const glm::quat rotationQuat = glm::quat( _rotation.d_w, _rotation.d_x, _rotation.d_y, _rotation.d_z );
274 const glm::mat4 rotation_matrix = glm::mat4_cast( rotationQuat );
275
276 modelMatrix = modelMatrix * rotation_matrix;
277
278 const glm::vec3 transl = glm::vec3( -_pivot.d_x, -_pivot.d_y, -_pivot.d_z );
279 const glm::mat4 translMatrix = glm::translate( glm::mat4( 1.f ), transl );
280 modelMatrix = modelMatrix * translMatrix;
281
282 _matrixValid = true;
283}
284
285} // End of CEGUI namespace section
286
Divide::GFX::CommandBuffer * cmdBuffer() const
Divide::GFXDevice & context()
bool flipClippingHeight() const noexcept
const Rectf & getActiveViewPort() const
Divide::GFX::MemoryBarrierCommand * memCmd() const
const glm::mat4 & getViewProjectionMatrix() const noexcept
void bindDefaultState(bool scissor, BlendMode mode, const glm::mat4 &viewProjMat)
void draw() const override
BatchList _batches
list of texture batches added to the geometry buffer
Rectf _clipRect
rectangular clip region
Vector3f _pivot
pivot point for rotation
RenderEffect * _effect
RenderEffect that will be used by the GeometryBuffer.
Vector3f _translation
translation vector
VertexList _vertices
container where added geometry is stored.
DVDGeometryBuffer(CEGUIRenderer &owner)
bool _clippingActive
whether clipping will be active for the current batch
uint _bufferSize
Size of the buffer that is currently in use.
DVDTexture * _activeTexture
last texture that was set as active
void recreateBuffer(Divide::Byte *initialData, size_t intialDataSize)
recreates the Divide specific geometry buffer. Usually called if "initialDataSize" is larger than the...
bool _matrixValid
true when d_matrix is valid and up to date
void updateMatrix() const
update cached matrix
void appendGeometry(const Vertex *vbuff, uint vertex_count) override
CEGUIRenderer * _owner
CEGUIRenderer that owns the GeometryBuffer.
void performBatchManagement()
perform batch management operations prior to adding new geometry.
Divide::GenericVertexData_ptr _gvd
Divide specific geometry buffer.
const glm::mat4 & getMatrix() const
Quaternion _rotation
rotation quaternion
glm::mat4 _matrix
model matrix cache - we use double because gluUnproject takes double
Divide::SamplerDescriptor _sampler
Sampler hash to use if the current batch needs a texture bound.
Divide::Handle< Divide::Texture > getDVDTexture() const
Return the internal Divide::Texture pointer used by this Texture object.
Definition: DVDTexture.inl:60
GenericVertexData_ptr newGVD(U32 ringBufferLength, std::string_view name)
Definition: GFXDevice.inl:219
constexpr U8 MAX_FRAMES_IN_FLIGHT
Maximum number of active frames until we start waiting on a fence/sync.
Definition: config.h:100
Str StringFormat(const char *fmt, Args &&...args)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::byte Byte
constexpr U32 to_U32(const T value)
uint32_t U32
type to track info for per-texture sub batches of geometry
Divide::Handle< Divide::Texture > texture
BufferUpdateUsage _updateUsage
Definition: BufferParams.h:40
BufferUpdateFrequency _updateFrequency
Definition: BufferParams.h:39
size_t _elementSize
Buffer primitive size in bytes.
Definition: BufferParams.h:50
BufferFlags _flags
Definition: BufferParams.h:48
DescriptorSetBindingData _data
std::pair< bufferPtr, size_t > _initialData
TextureWrap _wrapU
Texture wrap mode (Or S-R-T)
U8 _anisotropyLevel
The value must be in the range [0...255] and is automatically clamped by the max HW supported level.