Cogs.Core
PotreeRenderer.cpp
1#include "ExtensionRegistry.h"
2#include "Renderer/Renderer.h"
3#include "Renderer/RenderList.h"
4#include "Renderer/RenderStateUpdater.h"
5#include "Renderer/RenderTarget.h"
6#include "Renderer/Tasks/RenderListTask.h"
7#include "Renderer/Tasks/FilterListTask.h"
8#include "Renderer/Tasks/GenerateListTask.h"
9#include "Renderer/CustomRenderer/DebugGeometryRenderers.h"
10
11#include "PotreeRenderer.h"
12#include "PotreeSystem.h"
13
14#include "Rendering/IGraphicsDevice.h"
15
16#include "Foundation/Logging/Logger.h"
17
18#include <glm/glm.hpp>
19
20#include <array>
21
22using namespace Cogs;
23using namespace Cogs::Core;
24
25namespace {
27
28 bool setRenderItemState(float& scale, RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
29 {
30 const auto* camData = drawContext->cameraData;
31 if (camData == nullptr) return false;
32
33 scale = 1.f;
34 float w = camData->viewportSize.x;
35 float h = camData->viewportSize.y;
36 if (drawContext->task->viewportFromTarget && drawContext->renderTarget) {
37 w = float(drawContext->renderTarget->width);
38 h = float(drawContext->renderTarget->height);
39 scale = 0.5f*(w / std::max(1.f, camData->viewportSize.x) + h / std::max(1.f, camData->viewportSize.y));
40 }
41
42 Renderer* renderer = taskContext->renderer;
43
44 auto* device = renderer->getDevice();
45 auto* iContext = device->getImmediateContext();
46
47 iContext->setViewport(camData->viewportOrigin.x, camData->viewportOrigin.y, w, h);
48 iContext->setDepthStencilState(taskContext->states->commonDepthStates[renderItem->depthState]);
49 iContext->setBlendState(taskContext->states->blendStates[renderItem->blendState].handle);
50
51 const RenderPassOptions passOptions = initRenderPassOptions(*camData, renderItem->materialInstance);
52 iContext->setRasterizerState(taskContext->states->rasterizerStateHandles[getRasterizerState(renderer, *renderItem, passOptions, camData->flipWindingOrder, true)]);
53
54 const ClipShapeCache::Item& clipShape = drawContext->clipShapeCache->data[renderItem->clipShapeIx];
55 updateViewportBuffer(taskContext, taskContext->engineBuffers->sceneBufferHandle, taskContext->engineBuffers->viewBufferHandle, drawContext->renderTarget, renderItem->viewportData ? renderItem->viewportData : drawContext->cameraData, &clipShape.clipEquations);
56
57 // Invokes updateSceneBindings
58 // Invokes updateMaterialBindings(instance=false)
59 applyMaterialPermutation(taskContext, drawContext, renderItem->binding, renderItem->renderMaterialInstance);
60
61 // INvokes updateEnvironmentBindings,
62 // Updates permutation->constant buffers
63 drawContext->task->applyMaterial(*drawContext, *renderItem);
64
65 // Invokes updateMaterialBindings -> applyMaterialProperties
66 applyMaterialInstance(drawContext, renderItem->binding, renderItem->renderMaterialInstance);
67
68 updateSceneBindings(drawContext, drawContext->cameraData, renderItem->binding);
69
70 updateMaterialBindings(drawContext, renderItem->renderMaterialInstance, renderItem->binding, true);
71
72 // applyMaterialPerObject, but worldMatrix is stuffed with callback pointer
73 const auto bindings = renderItem->binding;
74 auto& engineBuffers = *drawContext->engineBuffers;
75 auto* potreeData = static_cast<PotreeData*>(renderItem->callbackData);
76 // assert(HandleIsValid(bindings->objectBufferBinding));
77 if(!HandleIsValid(bindings->objectBufferBinding)) return false;
78 {
79 Cogs::MappedBuffer<ObjectBuffer> objectBuffer(iContext, engineBuffers.objectBufferHandle, Cogs::MapMode::WriteDiscard);
80 if (objectBuffer) {
81 objectBuffer->worldMatrix = potreeData->worldFromOcttreeFrame;
82 objectBuffer->objectId = renderItem->objectId;
83 }
84 }
85 iContext->setConstantBuffer(bindings->objectBufferBinding, engineBuffers.objectBufferHandle);
86
87 return true;
88 }
89
90
91 void potreeCallback(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
92 {
93 auto* potreeData = static_cast<PotreeData*>(renderItem->callbackData);
94 if (potreeData->state != PotreeState::Running) return;
95
96 float scale = 1.f;
97 if (!setRenderItemState(scale, taskContext, drawContext, renderItem)) return;
98
99 // We use camera viewport to control rendering for consistent look during dynamic render resolution,
100 // we pass the scaling factor so that pointsize sent to the rendering API can be adjusted.
101 const float w = drawContext->cameraData->viewportSize.x;
102 const float h = drawContext->cameraData->viewportSize.y;
103
104 Cogs::Core::Renderer* renderer = taskContext->renderer;
105 Cogs::IGraphicsDevice* device = renderer->getDevice();
106 Cogs::IContext* iContext = device->getImmediateContext();
107
108 if (!HandleIsValid(potreeData->octtreeTexture)) {
109 return;
110 }
111 PotreeRenderer* potreeRenderer = static_cast<PotreeRenderer*>(renderItem->callbackData2);
112 PotreeSystem* potreeSystem = potreeRenderer->potreeSystem;
113 bool useInstancing = potreeSystem->useInstancing;
114
115 iContext->setTexture("octtree", 0, potreeData->octtreeTexture);
116 iContext->setSamplerState("octtreeSampler", 0, renderer->getRenderStates().commonSamplerStates[3]);
117
118 float viewScale = std::cbrt(glm::determinant(glm::mat3(potreeData->worldFromOcttreeFrame) * glm::mat3(drawContext->cameraData->viewMatrix)));
119
121 passControl.push_back(glm::vec4(viewScale * potreeData->modelSpaceRadius,
122 w * viewScale * potreeData->modelSpaceRadius,
123 2.f / (w * scale), 2.f / (h * scale)));
124 for (size_t i = 0; i < potreeData->clipPlaneCount; i++) {
125 passControl.push_back(potreeData->clipPlanes[i] * drawContext->cameraData->inverseViewProjectionMatrix);
126 }
127 glm::vec4 pointControl[2] = {
128 glm::vec4(potreeData->densitySized.levelScale,
129 potreeData->densitySized.scale,
130 potreeData->densitySized.bias,
131 0.5f),
132 glm::vec4(scale, 1.f / w, 1.f / h, 0.f)
133 };
134 // assert(HandleIsValid(potreeData->pointParametersBuffer));
135 if(!HandleIsValid(potreeData->pointParametersBuffer)) return;
136 {
137 Cogs::MappedBuffer<PointParameters> buffer(iContext, potreeData->pointParametersBuffer, Cogs::MapMode::WriteDiscard);
138 if(buffer){ // TODO can this buffer be prefilled outside the render loop?
139 buffer->passControl[0] = passControl[0];
140 for (size_t i = 1; i <= potreeData->clipPlaneCount; i++) {
141 buffer->passControl[i] = passControl[i];
142 }
143 buffer->pointControl[0] = pointControl[0];
144 buffer->pointControl[1] = pointControl[1];
145 }
146 }
147 iContext->setConstantBuffer("PointParameters", potreeData->pointParametersBuffer);
148
149
150 for (auto* cell : potreeData->activeCells) {
151 if (cell->pointCount && HandleIsValid(cell->pointData)) {
152 if (useInstancing) {
153 VertexBufferHandle handles[2] = {
154 cell->pointData,
155 potreeRenderer->quadVertices
156 };
157 iContext->setVertexBuffers(handles, 2);
158 iContext->drawInstanced(Cogs::PrimitiveType::TriangleStrip, 0, 4, 0, cell->pointCount);
159 }
160 else {
161 iContext->setVertexBuffers(&cell->pointData, 1);
162 iContext->draw(Cogs::PrimitiveType::PointList, 0, cell->pointCount);
163 }
164 }
165 }
166 }
167
168 void potreeBoxCallback(RenderTaskContext* taskContext, DrawContext* drawContext, const RenderItem* renderItem)
169 {
170 auto* potreeData = static_cast<PotreeData*>(renderItem->callbackData);
171 if (potreeData->state != PotreeState::Running) return;
172
173 float scale = 1.f;
174 if (!setRenderItemState(scale, taskContext, drawContext, renderItem)) return;
175
176 auto* renderer = taskContext->renderer;
177 auto* device = renderer->getDevice();
178 auto* iContext = device->getImmediateContext();
179
180 auto* potreeRenderer = static_cast<PotreeRenderer*>(renderItem->callbackData2);
181
182 iContext->setVertexBuffers(&potreeRenderer->boxVertices, 1);
183 iContext->setIndexBuffer(potreeRenderer->boxEdgeIndices, 2, 0);
184
185 for (auto* cell : potreeData->activeCells) {
186 if (cell->kind != PotreeCell::Kind::RegularNode) continue;
187 if (potreeData->debugBoxes == PotreeDebugBoxes::ActiveLeafCells && (cell->texOffset == 0xffffu || potreeData->octtreeTextureData[cell->texOffset].r != 0)) continue;
188
189 auto color = cell->owningSubtree->l + cell->l;// cell->owningSubtree->subtreeId * 4091;
190
191 glm::vec4 boxControl[3] = {
192 glm::vec4(cell->tbmin, 1.f),
193 glm::vec4(cell->tbmax - cell->tbmin, 1.f),
194 //glm::vec4(((color >> 0) & 0x3) / 15.f, ((color >> 2) & 0x3) / 15.f,((color >> 2) & 0x3) / 3.f,1.f)
195 glm::vec4(((color >> 0) & 0x1), ((color >> 1) & 0x1), ((color >> 2) & 0x1), 1.f)
196 };
197 if(!HandleIsValid(cell->boxParametersBuffer)){
198 auto* buffers = device->getBuffers();
199 cell->boxParametersBuffer = buffers->loadBuffer(nullptr, sizeof(BoxParameters), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
200 }
201 //assert(HandleIsValid(cell->boxParametersBuffer));
202 if(!HandleIsValid(cell->boxParametersBuffer)) continue;
203 {
204 Cogs::MappedBuffer<BoxParameters> buffer(iContext, cell->boxParametersBuffer, Cogs::MapMode::WriteDiscard);
205 if(buffer){ // TODO can this buffer be prefilled outside the render loop?
206 buffer->boxControl[0] = boxControl[0];
207 buffer->boxControl[1] = boxControl[1];
208 buffer->boxControl[2] = boxControl[2];
209 }
210 }
211 iContext->setConstantBuffer("BoxParameters", cell->boxParametersBuffer);
212
213 iContext->drawIndexed(Cogs::PrimitiveType::LineList, 0, potreeRenderer->boxEdgeIndexPrimitives);
214 }
215
216 const glm::mat4 M = drawContext->cameraData->viewProjection * potreeData->frustum;
217 drawOneOneWireBox(taskContext, drawContext, nullptr, M, 0);
218 }
219}
220
222{
223 this->device = device;
224 this->context = context;
225 potreeSystem = ExtensionRegistry::getExtensionSystem<PotreeSystem>(context);
226 IBuffers* buffers = device->getBuffers();
227
228 // Create a single quad (as triangle strip) used for instancing
229 std::array<Cogs::VertexElement,1> quadElements = {
231 };
232 static const float quadVertexData[][2] = {
233 { -1.f, -1.f },
234 { 1.f, -1.f },
235 { -1.f, 1.f },
236 { 1.f, 1.f }
237 };
238 quadStreamsLayout.vertexFormats[0] = VertexFormats::createVertexFormat(quadElements.data(), quadElements.size());
239 quadStreamsLayout.numStreams = 1;
240 quadStreamsLayout.updateHash();
241 quadVertices = buffers->loadVertexBuffer(quadVertexData, sizeof(quadVertexData) / sizeof(quadVertexData[0]), quadStreamsLayout.vertexFormats[0]);
242
243 // Create wireframe unit box geometry
244 std::array<Cogs::VertexElement,1> boxElements = {
245 Cogs::VertexElement{0, Cogs::DataFormat::R32G32B32_FLOAT, Cogs::ElementSemantic::Position, 0, Cogs::InputType::VertexData, 0}
246 };
247 static const float boxVertexData[][3] = {
248 { 0.f, 0.f, 0.f },
249 { 1.f, 0.f, 0.f },
250 { 1.f, 1.f, 0.f },
251 { 0.f, 1.f, 0.f },
252 { 0.f, 0.f, 1.f },
253 { 1.f, 0.f, 1.f },
254 { 1.f, 1.f, 1.f },
255 { 0.f, 1.f, 1.f },
256 };
257 static const uint16_t boxEdgeIndexData[] = {
258 0, 1, 1, 2, 2, 3, 3, 0,
259 4, 5, 5, 6, 6, 7, 7, 4,
260 0, 4, 1, 5, 2, 6, 3, 7
261 };
262
263 boxStreamsLayout.vertexFormats[0] = VertexFormats::createVertexFormat(boxElements.data(), boxElements.size());
264 boxStreamsLayout.numStreams = 1;
265 boxStreamsLayout.updateHash();
266 boxVertices = buffers->loadVertexBuffer(boxVertexData, sizeof(boxVertexData) / sizeof(boxVertexData[0]), boxStreamsLayout.vertexFormats[0]);
267 boxEdgeIndexPrimitives = static_cast<unsigned>(sizeof(boxEdgeIndexData) / sizeof(boxEdgeIndexData[0]));
268 boxEdgeIndices = buffers->loadIndexBuffer(boxEdgeIndexData, boxEdgeIndexPrimitives, sizeof(boxEdgeIndexData[0]));
269}
270
271void Cogs::Core::PotreeRenderer::handleEvent(uint32_t eventId, const DrawContext * renderingContext)
272{
273 if (!renderingContext) return;
274
275 switch (eventId) {
277 IBuffers* buffers = renderingContext->device->getBuffers();
278 ITextures* textures = renderingContext->device->getTextures();
279 for (auto& poComp : potreeSystem->pool) {
280 PotreeDataHolder& poDataHolder = potreeSystem->getData(&poComp);
281 PotreeData* poData = poDataHolder.poData.get();
282 assert(poData);
283
284 if(!HandleIsValid(poData->pointParametersBuffer)){
285 poData->pointParametersBuffer = buffers->loadBuffer(nullptr, sizeof(PointParameters), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
286 }
287
288 if (HandleIsValid(poData->octtreeTexture)) {
289 textures->releaseTexture(poData->octtreeTexture);
290 poData->octtreeTexture = Cogs::TextureHandle::NoHandle;
291 }
292
293 if (poData->octtreeTextureData.size()) {
294 TextureDescription desc{};
295 desc.target = Cogs::ResourceDimensions::Texture2D;
296 desc.width = static_cast<uint32_t>(poData->octtreeTextureData.size());
297 desc.height = 1;
298 desc.format = Cogs::TextureFormat::R8G8B8A8_UNORM;
299 desc.flags = Cogs::TextureFlags::Default;
300
301 TextureData data(poData->octtreeTextureData.data(), TextureExtent{ desc.width, 1, 1 }, 1, 1, 1, desc.format);
302 poData->octtreeTexture = textures->loadTexture(desc, &data);
303 }
304 }
305 break;
306 }
308 break;
309
310 default:
311 break;
312 }
313}
314
315void Cogs::Core::PotreeRenderer::generateCommands(const RenderTaskContext * renderingContext, RenderList * renderList)
316{
317 if (!renderingContext) return;
318
319 for (auto & poComp : potreeSystem->pool) {
320 if (!poComp.isVisible()) continue;
321
322 PotreeDataHolder& poDataHolder = potreeSystem->getData(&poComp);
323 PotreeData* poData = poDataHolder.poData.get();
324 assert(poData);
325
326 if (poData->state != PotreeState::Running) continue;
327
328 // Just skip instance if we haven't gotten metadata yet
329 if (poData->streamsLayout.numStreams == 0) continue;
330
331 MaterialInstance* pointMaterialInstance = poData->pointMaterial.instance.resolve();
332 if (pointMaterialInstance) {
333
334 assert(!HandleIsValid(poComp.pointMaterial) || poComp.pointMaterial == poData->pointMaterial.instance);
335
336 RenderItem& renderItem = renderList->createCustom(&poData->streamsLayout);
337
338 if (!poComp.clipShapeComponent.Empty()) {
339 renderItem.clipShapeIx = renderList->clipShapeCache->getIndex(context, poComp.clipShapeComponent);
340 }
341
342 renderItem.lod = poComp.lod;
343 renderItem.layer = poComp.layer;
344 renderItem.cullingIndex = ~0u;;
345 renderItem.objectId = poComp.objectId;
346 renderItem.flags |= (pointMaterialInstance->instanceFlags & MaterialFlags::CustomBucket) != 0 ? RenderItemFlags::CustomBucket : RenderItemFlags::None;
347 renderItem.flags |= pointMaterialInstance->hasTransparency() ? RenderItemFlags::Transparent : RenderItemFlags::None;
348 renderItem.flags |= pointMaterialInstance->isBackdrop() ? RenderItemFlags::Backdrop : RenderItemFlags::None;
349 renderItem.flags |= poComp.castShadows() ? RenderItemFlags::CastShadows : RenderItemFlags::None;
350 renderItem.materialInstance = pointMaterialInstance;
351 getTransparencyState(renderingContext->renderer->getRenderStates(), pointMaterialInstance, renderItem);
352 renderItem.drawOrder = pointMaterialInstance->options.drawOrder != 0 ? pointMaterialInstance->options.drawOrder : poComp.drawOrder;
353 renderItem.setCallbackData(poData);
354 renderItem.setCallbackData2(this);
355 renderItem.callback = potreeCallback;
356 }
357
358 if (poComp.debugBoxes != PotreeDebugBoxes::None) {
359 MaterialInstance* boxMaterialInstance = poData->boxMaterial.instance.resolve();
360 if (boxMaterialInstance) {
361
362 assert(!HandleIsValid(poComp.boxMaterial) || poComp.boxMaterial == poData->boxMaterial.instance);
363
364 RenderItem& renderItem = renderList->createCustom(&boxStreamsLayout);
365 renderItem.lod = poComp.lod;
366 renderItem.layer = poComp.layer;
367 renderItem.cullingIndex = ~0u;;
368 renderItem.objectId = poComp.objectId;
369 renderItem.flags |= (boxMaterialInstance->instanceFlags & MaterialFlags::CustomBucket) != 0 ? RenderItemFlags::CustomBucket : RenderItemFlags::None;
370 renderItem.flags |= boxMaterialInstance->hasTransparency() ? RenderItemFlags::Transparent : RenderItemFlags::None;
371 renderItem.flags |= boxMaterialInstance->isBackdrop() ? RenderItemFlags::Backdrop : RenderItemFlags::None;
372 renderItem.flags |= poComp.castShadows() ? RenderItemFlags::CastShadows : RenderItemFlags::None;
373 renderItem.materialInstance = boxMaterialInstance;
374 getTransparencyState(renderingContext->renderer->getRenderStates(), boxMaterialInstance, renderItem);
375 renderItem.drawOrder = boxMaterialInstance->options.drawOrder != 0 ? boxMaterialInstance->options.drawOrder : poComp.drawOrder;
376 renderItem.setCallbackData(poData);
377 renderItem.setCallbackData2(this);
378 renderItem.callback = potreeBoxCallback;
379 }
380 }
381
382 }
383}
Vector with inline storage for up to Size elements, avoiding heap allocation for small collections.
Definition: SmallVector.h:460
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Core renderer system.
Definition: Renderer.h:28
RenderStates & getRenderStates() override
Get the reference to the RenderStates structure.
Definition: Renderer.h:68
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:45
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual ITextures * getTextures()=0
Get a pointer to the texture management interface.
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
Log implementation class.
Definition: LogManager.h:140
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ None
No debug node outlines.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
@ VertexData
Per vertex data.
@ PointList
List of points.
@ TriangleStrip
Triangle strip.
@ LineList
List of lines.
@ Position
Position semantic.
@ Write
The buffer can be mapped and written to by the CPU after creation.
Definition: Flags.h:50
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
Definition: Flags.h:72
@ CustomBucket
Items with this flag should be put in Custom rendering buckets.
Definition: Material.h:64
Material instances represent a specialized Material combined with state for all its buffers and prope...
bool hasTransparency() const
Get if this instance has any transparency and should be rendered with blending enabled.
bool isBackdrop() const
Get if geometry rendered with this material instance is to be treated as backdrops.
MaterialOptions options
Material rendering options used by this instance.
uint16_t instanceFlags
Material instance flags.
VertexFormatHandle vertexFormats[maxStreams]
COGSCORE_DLL_API void updateHash()
void initialize(Context *context, IGraphicsDevice *device) override
Initialize the extension using the given context and device.
void handleEvent(uint32_t eventId, const DrawContext *renderingContext) override
Called when rendering events occur.
int32_t drawOrder
Ordering of draw items within a bucket.
Definition: RenderList.h:174
uint32_t objectId
Lower 6 of upper 8 bits are instance id bits, lower 24 bits are object id.
Definition: RenderList.h:176
RenderLayers layer
Visibility mask.
Definition: RenderList.h:172
@ PostRender
Rendering has finished for a given rendering context.
Definition: IRenderer.h:101
@ PreRender
Pre rendering happening for a given rendering context.
Definition: IRenderer.h:93
ResourceType * resolve() const
Resolve the handle, returning a pointer to the actual resource.
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
Provides buffer management functionality.
Definition: IBuffers.h:13
virtual IndexBufferHandle loadIndexBuffer(const void *indexData, const size_t count, const size_t indexSize)=0
Loads a new index buffer and populates it with the given indexData.
virtual BufferHandle loadBuffer(const void *data, const size_t size, Usage::EUsage usage, uint32_t accessMode, uint32_t bindFlags, uint32_t stride=0)=0
Loads a new buffer using the given data to populate the buffer.
virtual VertexBufferHandle loadVertexBuffer(const void *vertexData, const size_t count, const VertexFormat &vertexFormat)=0
Loads a new vertex buffer and populates it with the given data.
Represents a graphics device context which can receive rendering commands.
Definition: IContext.h:43
virtual void setTexture(const StringView &name, unsigned int unit, TextureHandle textureHandle)=0
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void drawIndexed(PrimitiveType primitiveType, const size_t startIndex, const size_t numIndexes, const size_t startVertex=0)=0
Draws indexed, non-instanced primitives.
virtual void setIndexBuffer(IndexBufferHandle bufferHandle, uint32_t stride=4, uint32_t offset=0)=0
Sets the current index buffer.
virtual void drawInstanced(PrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes, const size_t startInstance, const size_t numInstances)=0
Draws non-indexed, instanced primitives.
virtual void setConstantBuffer(const StringView &name, const BufferHandle bufferHandle, const uint32_t offset=0, const uint32_t size=~0u)=0
Sets a constant buffer to be bound to the given name and slot.
virtual void setViewport(const float x, const float y, const float width, const float height)=0
Sets the current viewport to the given location and dimensions.
virtual void draw(PrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes)=0
Draws non-indexed, non-instanced primitives.
virtual void setSamplerState(const StringView &name, unsigned int unit, SamplerStateHandle samplerStateHandle)=0
Sets the sampler slot given by unit with the given name to contain the given sampler state.
virtual void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count, const uint32_t *strides, const uint32_t *offsets)=0
Sets the current vertex buffers.
Provides texture management functionality.
Definition: ITextures.h:40
virtual void releaseTexture(TextureHandle textureHandle)=0
Release the texture with the given textureHandle.
virtual TextureHandle loadTexture(const unsigned char *bytes, unsigned int width, unsigned int height, TextureFormat format, unsigned int flags=0)=0
Load a texture using the given data to populate the texture contents.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Definition: Flags.h:103
Provides RAII style mapping of a buffer resource.
Definition: IBuffers.h:160
@ Default
Default usage, the texture can be loaded once and bound and sampled in shaders.
Definition: Flags.h:116
@ Dynamic
Buffer will be loaded and modified with some frequency.
Definition: Flags.h:30
Vertex element structure used to describe a single data element in a vertex for the input assembler.
Definition: VertexFormat.h:38