Skip to content

Commit

Permalink
#5912: Before drawing any geometry, make sure everything is committed…
Browse files Browse the repository at this point in the history
… to the IGeometryStore
  • Loading branch information
codereader committed Mar 6, 2022
1 parent fc0fc7b commit e23c0e6
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 9 deletions.
7 changes: 7 additions & 0 deletions radiantcore/rendersystem/backend/FullBrightRenderer.cpp
@@ -1,6 +1,7 @@
#include "FullBrightRenderer.h"

#include "OpenGLShaderPass.h"
#include "OpenGLShader.h"

namespace render
{
Expand Down Expand Up @@ -29,6 +30,12 @@ class FullBrightRenderResult :

IRenderResult::Ptr FullBrightRenderer::render(RenderStateFlags globalstate, const IRenderView& view, std::size_t time)
{
// Make sure all the geometry is ready for rendering
for (const auto& [_, pass] : _sortedStates)
{
pass->getShader().prepareForRendering();
}

// Construct default OpenGL state
OpenGLState current;
setupState(current);
Expand Down
2 changes: 2 additions & 0 deletions radiantcore/rendersystem/backend/LightingModeRenderer.cpp
Expand Up @@ -45,6 +45,8 @@ IRenderResult::Ptr LightingModeRenderer::render(RenderStateFlags globalFlagsMask
interactionLists.emplace_back(std::move(interaction));
}

// Past this point, everything in the geometry store is up to date

// Run the depth fill pass
for (auto& interactionList : interactionLists)
{
Expand Down
7 changes: 7 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShader.cpp
Expand Up @@ -135,6 +135,13 @@ bool OpenGLShader::hasSurfaces() const
return !_geometryRenderer.empty() || !_surfaceRenderer.empty();
}

void OpenGLShader::prepareForRendering()
{
_surfaceRenderer.prepareForRendering();
_windingRenderer->prepareForRendering();
// _geometryRenderer doesn't need to prepare at this point
}

IGeometryRenderer::Slot OpenGLShader::addGeometry(GeometryType indexType,
const std::vector<MeshVertex>& vertices, const std::vector<unsigned int>& indices)
{
Expand Down
1 change: 1 addition & 0 deletions radiantcore/rendersystem/backend/OpenGLShader.h
Expand Up @@ -104,6 +104,7 @@ class OpenGLShader :

bool hasSurfaces() const;
void drawSurfaces(const VolumeTest& view);
void prepareForRendering();

IGeometryRenderer::Slot addGeometry(GeometryType indexType,
const std::vector<MeshVertex>& vertices, const std::vector<unsigned int>& indices) override;
Expand Down
5 changes: 5 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShaderPass.h
Expand Up @@ -87,6 +87,11 @@ class OpenGLShaderPass
_owner(owner)
{}

OpenGLShader& getShader()
{
return _owner;
}

// Returns true if the stage associated to this pass is active and should be rendered
bool stateIsActive();

Expand Down
29 changes: 28 additions & 1 deletion radiantcore/rendersystem/backend/SurfaceRenderer.h
Expand Up @@ -33,10 +33,14 @@ class SurfaceRenderer :

Slot _freeSlotMappingHint;

std::vector<Slot> _surfacesNeedingUpdate;
bool _surfacesNeedUpdate;

public:
SurfaceRenderer(IGeometryStore& store) :
_store(store),
_freeSlotMappingHint(0)
_freeSlotMappingHint(0),
_surfacesNeedUpdate(false)
{}

bool empty() const
Expand Down Expand Up @@ -78,6 +82,8 @@ class SurfaceRenderer :
void updateSurface(Slot slot) override
{
_surfaces.at(slot).surfaceDataChanged = true;
_surfacesNeedingUpdate.push_back(slot);
_surfacesNeedUpdate = true;
}

void render(const VolumeTest& view)
Expand All @@ -98,6 +104,27 @@ class SurfaceRenderer :
return _surfaces.at(slot).storageHandle;
}

// Ensures the data in the IGeometryStore is up to date
void prepareForRendering()
{
if (!_surfacesNeedUpdate) return;

_surfacesNeedUpdate = false;

for (auto slotIndex : _surfacesNeedingUpdate)
{
auto& surfaceInfo = _surfaces.at(slotIndex);

if (surfaceInfo.surfaceDataChanged)
{
surfaceInfo.surfaceDataChanged = false;

auto& surface = surfaceInfo.surface.get();
_store.updateData(surfaceInfo.storageHandle, surface.getVertices(), surface.getIndices());
}
}
}

private:
void renderSlot(SurfaceInfo& slot, const VolumeTest* view = nullptr)
{
Expand Down
34 changes: 26 additions & 8 deletions radiantcore/rendersystem/backend/WindingRenderer.h
Expand Up @@ -23,6 +23,9 @@ class IBackendWindingRenderer :

// Submit the geometry of all windings in this renderer
virtual void renderAllWindings() = 0;

// Ensures that everything in the IGeometryStore is up to date
virtual void prepareForRendering() = 0;
};

// Traits class to retrieve the GLenum render mode based on the indexer type
Expand Down Expand Up @@ -343,12 +346,15 @@ class WindingRenderer final :

std::unique_ptr<EntityWindings> _entitySurfaces;

bool _geometryUpdatePending;

public:
WindingRenderer(IGeometryStore& geometryStore, Shader* owningShader) :
_geometryStore(geometryStore),
_owningShader(owningShader),
_windingCount(0),
_freeSlotMappingHint(InvalidSlotMapping)
_freeSlotMappingHint(InvalidSlotMapping),
_geometryUpdatePending(false)
{
if (RenderingTraits<WindingIndexerT>::SupportsEntitySurfaces())
{
Expand Down Expand Up @@ -484,12 +490,10 @@ class WindingRenderer final :

void renderAllWindings() override
{
for (auto bucketIndex = 0; bucketIndex < _buckets.size(); ++bucketIndex)
{
auto& bucket = _buckets[bucketIndex];

ensureBucketIsReady(bucket);
assert(!_geometryUpdatePending); // prepareForRendering should have been called

for (auto& bucket : _buckets)
{
if (bucket.storageHandle == InvalidStorageHandle) continue; // nothing here

auto primitiveMode = RenderingTraits<WindingIndexerT>::Mode();
Expand All @@ -499,14 +503,14 @@ class WindingRenderer final :

void renderWinding(IWindingRenderer::RenderMode mode, IWindingRenderer::Slot slot) override
{
assert(!_geometryUpdatePending); // prepareForRendering should have been called

assert(slot < _slots.size());
auto& slotMapping = _slots[slot];

assert(slotMapping.bucketIndex != InvalidBucketIndex);
auto& bucket = _buckets[slotMapping.bucketIndex];

ensureBucketIsReady(bucket);

const auto& vertices = bucket.buffer.getVertices();
const auto& indices = bucket.buffer.getIndices();

Expand All @@ -526,6 +530,19 @@ class WindingRenderer final :
}
}

// Ensure all data is written to the IGeometryStore
void prepareForRendering()
{
if (!_geometryUpdatePending) return;

_geometryUpdatePending = false;

for (auto& bucket : _buckets)
{
ensureBucketIsReady(bucket);
}
}

private:
void ensureBucketIsReady(BucketIndex bucketIndex)
{
Expand All @@ -543,6 +560,7 @@ class WindingRenderer final :
// Update the modified range
bucket.modifiedSlotRange.first = std::min(bucket.modifiedSlotRange.first, modifiedSlot);
bucket.modifiedSlotRange.second = std::max(bucket.modifiedSlotRange.second, modifiedSlot);
_geometryUpdatePending = true;
}

// Commit all local buffer changes to the geometry store
Expand Down

0 comments on commit e23c0e6

Please sign in to comment.