Cogs.Core
SeaCurrentsRenderer.cpp
1#include "SeaCurrentsRenderer.h"
2
3#include "SeaCurrentsSystem.h"
4
5#include "Context.h"
6#include "ExtensionRegistry.h"
7#include "Components/Core/TransformComponent.h"
8#include "Renderer/Renderer.h"
9#include "Renderer/RenderMaterialInstance.h"
10#include "Renderer/RenderStateUpdater.h"
11#include "Renderer/Tasks/RenderListTask.h"
12#include "Renderer/Tasks/RenderTask.h"
13#include "Systems/Core/TransformSystem.h"
14
15#include "Rendering/CommandGroupAnnotation.h"
16
17namespace Cogs::Core {
18 void renderCallback(RenderTaskContext* renderingContext, DrawContext* drawContext, const RenderItem* item) {
19 SeaCurrentsData& data = *item->getCallbackData<Cogs::Core::SeaCurrentsData>();
20 size_t instanceCount = data.mData.size();
21
22 if (!instanceCount) {
23 return;
24 }
25
26 Renderer* renderer = renderingContext->renderer;
27 IGraphicsDevice* device = renderer->getDevice();
28 IContext* deviceContext = device->getImmediateContext();
29 CommandGroupAnnotation commandGroup(deviceContext, "SeaCurrentsRenderer Callback");
30 const RenderStates& renderStates = renderer->getRenderStates();
31 RenderMesh* renderMesh = renderer->getRenderResources().getRenderMesh(data.mSystem->getArrowMesh());
32 IBuffers* buffers = device->getBuffers();
33
34 // PSO state
35 applyMaterialPermutation(renderingContext, drawContext, item->binding, item->renderMaterialInstance);
36 deviceContext->setDepthStencilState(renderStates.defaultDepthStencilStateHandle);
37 deviceContext->setBlendState(renderStates.blendStates[size_t(BlendMode::None)].handle);
38 deviceContext->setRasterizerState(renderStates.defaultRasterizerStateHandle);
39
40 updateEnvironmentBindings(drawContext, item->binding);
41 applyMaterialInstance(drawContext, item->binding, item->renderMaterialInstance);
42
43
44 // Copy Buffers
45 {
46 size_t dataSize = instanceCount * sizeof(InstanceData);
47
48 if (dataSize > data.mBufferSize) {
49 if (HandleIsValid(data.mBufferHandle)) {
50 buffers->releaseVertexBuffer(data.mBufferHandle);
51 }
52 data.mBufferHandle = buffers->loadVertexBuffer(nullptr, instanceCount, data.mSystem->getVertexFormatHandle());
53 buffers->annotate(data.mBufferHandle, "Sea Currents Instance Data");
54 data.mBufferSize = dataSize;
55 }
56
57 MappedBuffer<InstanceData> instanceData(deviceContext, data.mBufferHandle, Cogs::MapMode::WriteDiscard, dataSize);
58
59 if (instanceData) {
60 memcpy(static_cast<void*>(instanceData.get()), data.mData.data(), dataSize);
61 }
62 }
63
64 // Vertex buffers
65 std::array<VertexBufferHandle, MeshStreamsLayout::maxStreams> vertexBuffers;
66 std::array<uint32_t, MeshStreamsLayout::maxStreams> strides;
67 SeaCurrentsRenderer* seaCurrentsRenderer = static_cast<SeaCurrentsRenderer*>(item->callbackData2);
68
69 uint32_t n = 0;
70 for(size_t i = 0; i < renderMesh->streamsLayout.numStreams; i++){
71 vertexBuffers[n] = renderMesh->vertexBuffers[i];
72 strides[n++] = renderMesh->vertexStrides[i];
73 }
74 assert(n + 1 < MeshStreamsLayout::maxStreams);
75 vertexBuffers[n] = data.mBufferHandle;
76 strides[n++] = sizeof(InstanceData);
77
78 deviceContext->setVertexBuffers(vertexBuffers.data(), n, strides.data(), nullptr);
79 deviceContext->setIndexBuffer(seaCurrentsRenderer->mIndices, 2);
80
81 RenderItem copy = *item;
82 copy.worldMatrix = &data.mWorldMatrix;
83
84 applyMaterialPerObject(drawContext, item->renderMaterialInstance, copy);
85
86 // Draw
87 deviceContext->drawInstancedIndexed(item->primitiveType, 0, instanceCount, 0, 0);
88 }
89}
90
92 uint16_t indices[] = {
93 0,1,2,
94 3,4,5,
95 6,7,8,
96 9,10,11,
97 12,13,14,
98 15,16,17,
99 18,19,20,
100 };
101
102 mContext = context;
103 mDevice = device;
104 mSeaCurrentsSystem = ExtensionRegistry::getExtensionSystem<SeaCurrentsSystem>(context);
105 mIndices = device->getBuffers()->loadIndexBuffer(indices, sizeof(indices) / 2, 2);
106}
107
108void Cogs::Core::SeaCurrentsRenderer::handleEvent(uint32_t /*eventId*/, const DrawContext* /*renderingContext*/) {
109}
110
111void Cogs::Core::SeaCurrentsRenderer::generateCommands(const RenderTaskContext* renderingContext, RenderList* renderList) {
112 for(SeaCurrentsComponent& seaCurrentsComp : mSeaCurrentsSystem->pool) {
113 RenderItem& item = renderList->createCustom(&mSeaCurrentsSystem->getArrowInstancesStreamsLayout());
114 SeaCurrentsData& data = mSeaCurrentsSystem->getData(&seaCurrentsComp);
115 std::array<glm::vec3, 8> corners;
116
117 data.mWorldMatrix = renderingContext->context->transformSystem->getLocalToWorld(seaCurrentsComp.getComponent<TransformComponent>());
118 data.mTransformedBounds.min = glm::vec3(std::numeric_limits<float>::max());
119 data.mTransformedBounds.max = glm::vec3(std::numeric_limits<float>::lowest());
120
121 Geometry::corners(data.mBounds, corners);
122 for (const glm::vec3& corner : corners) {
123 glm::vec3 transformed = data.mWorldMatrix * glm::vec4(corner, 1.0f);
124
125 data.mTransformedBounds.min = glm::min(data.mTransformedBounds.min, transformed);
126 data.mTransformedBounds.max = glm::max(data.mTransformedBounds.max, transformed);
127 }
128
129 item.layer = RenderLayers::Default;
130 item.materialInstance = mSeaCurrentsSystem->getMaterialHandle().resolve();
131 item.drawOrder = 0;
132 item.depth = 0;
133 item.blendState = static_cast<uint16_t>(item.materialInstance->options.blendMode);
134 item.depthState = static_cast<uint16_t>(DepthMode::Default);
135 item.setBounds(&data.mTransformedBounds);
136 item.flags |= RenderItemFlags::Custom;
137 item.setCallbackData(&data);
138 item.setCallbackData2(this);
139 item.callback = &renderCallback;
140 }
141}
ComponentType * getComponent() const
Definition: Component.h:159
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
virtual void initialize(Context *context, IGraphicsDevice *device) override
Initialize the extension using the given context and device.
virtual void handleEvent(uint32_t eventId, const DrawContext *renderingContext) override
Called when rendering events occur.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
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 blending enabled for opaque shapes, defaults to Blend for transparent shapes.
@ Default
Default, depth test & write enabled.
@ InstanceData
Per instance data.
MaterialOptions options
Material rendering options used by this instance.
BlendMode blendMode
Blend mode to use when rendering geometry with the material instance.
static constexpr size_t maxStreams
int32_t drawOrder
Ordering of draw items within a bucket.
Definition: RenderList.h:172
RenderLayers layer
Visibility mask.
Definition: RenderList.h:170
float depth
Used for depth-sorting of transparent objects.
Definition: RenderList.h:171
Component for displaying surface currents based on the IHO S111 standard.
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.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Definition: Flags.h:103