Skip to content

Commit

Permalink
#5584: Winding rendering support. Updates in basic scenarios are work…
Browse files Browse the repository at this point in the history
…ing, everything else is crashing.
  • Loading branch information
codereader committed Nov 7, 2021
1 parent 70959f8 commit b435b0b
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 12 deletions.
2 changes: 1 addition & 1 deletion libs/render/CompactWindingVertexBuffer.h
Expand Up @@ -74,8 +74,8 @@ class CompactWindingVertexBuffer
for (unsigned int n = static_cast<unsigned int>(_size) - 1; n - 1 > 0; --n)
{
_indices.push_back(static_cast<unsigned int>(currentSize) + 0);
_indices.push_back(static_cast<unsigned int>(currentSize) + n - 1);
_indices.push_back(static_cast<unsigned int>(currentSize) + n);
_indices.push_back(static_cast<unsigned int>(currentSize) + n - 1);
}

return static_cast<Slot>(position);
Expand Down
37 changes: 37 additions & 0 deletions libs/render/WindingRenderer.h
@@ -1,8 +1,10 @@
#pragma once

#include "igl.h"
#include <limits>
#include "iwindingrenderer.h"
#include "CompactWindingVertexBuffer.h"
#include "debugging/gl.h"

namespace render
{
Expand All @@ -18,7 +20,18 @@ class WindingRenderer :

using BucketIndex = std::uint16_t;

std::size_t _windings;

public:
WindingRenderer() :
_windings(0)
{}

bool empty() const
{
return _windings == 0;
}

Slot addWinding(const std::vector<ArbitraryMeshVertex>& vertices) override
{
auto windingSize = vertices.size();
Expand All @@ -29,6 +42,7 @@ class WindingRenderer :
auto bucketIndex = getBucketIndexForWindingSize(windingSize);
auto& bucket = ensureBucketForWindingSize(windingSize);
auto bufferSlot = _buckets[bucketIndex].pushWinding(vertices);
++_windings;

return getSlot(bucketIndex, bufferSlot);
}
Expand All @@ -37,6 +51,7 @@ class WindingRenderer :
{
auto bucket = getBucketIndex(slot);
auto bufferSlot = getVertexBufferSlot(slot);
--_windings;

_buckets[bucket].removeWinding(bufferSlot);
}
Expand All @@ -56,6 +71,28 @@ class WindingRenderer :
bucket.replaceWinding(bufferSlot, vertices);
}

void render()
{
for (const auto& bucket : _buckets)
{
if (bucket.getVertices().empty()) continue;

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

glDisableClientState(GL_COLOR_ARRAY);
glColor3f(1, 1, 1);

glVertexPointer(3, GL_DOUBLE, sizeof(ArbitraryMeshVertex), &vertices.front().vertex);
glTexCoordPointer(2, GL_DOUBLE, sizeof(ArbitraryMeshVertex), &vertices.front().texcoord);
glNormalPointer(GL_DOUBLE, sizeof(ArbitraryMeshVertex), &vertices.front().normal);

glDrawElements(GL_TRIANGLES, GLint(indices.size()), GL_UNSIGNED_INT, &indices.front());

debug::checkGLErrors();
}
}

private:
inline static BucketIndex getBucketIndex(IWindingRenderer::Slot slot)
{
Expand Down
6 changes: 5 additions & 1 deletion radiantcore/brush/Face.cpp
Expand Up @@ -142,6 +142,8 @@ Brush& Face::getBrushInternal()

void Face::planeChanged()
{
_windingSurface.queueUpdate();

revertTransform();
_owner.onFacePlaneChanged();
}
Expand Down Expand Up @@ -335,7 +337,9 @@ void Face::freezeTransform()
updateWinding();
}

void Face::updateWinding() {
void Face::updateWinding()
{
_windingSurface.queueUpdate();
m_winding.updateNormals(m_plane.getPlane().normal());
}

Expand Down
55 changes: 50 additions & 5 deletions radiantcore/brush/RenderableWinding.h
Expand Up @@ -11,35 +11,61 @@ class RenderableWinding
{
private:
const Winding& _winding;
ShaderPtr _shader;
bool _needsUpdate;

IWindingRenderer::Slot _slot;
Winding::size_type _windingSize;

public:
RenderableWinding(const Winding& winding) :
_winding(winding),
_needsUpdate(true)
_needsUpdate(true),
_slot(IWindingRenderer::InvalidSlot),
_windingSize(0)
{}

void queueUpdate()
{
_needsUpdate = true;
}

void update(const ShaderPtr& shader)
{
if (!_needsUpdate) return;
bool shaderChanged = _shader != shader;

if (!_needsUpdate && !shaderChanged) return;

_needsUpdate = false;

auto numPoints = _winding.size();
if (numPoints < 3) return;

if (numPoints < 3 || !shader)
{
if (_slot != IWindingRenderer::InvalidSlot && _shader)
{
_shader->removeWinding(_slot);
}

_slot = IWindingRenderer::InvalidSlot;
_windingSize = 0;
_shader.reset();
return;
}

#if 0
// Triangulate our winding and submit
std::vector<unsigned int> indices;
indices.reserve(3 * (numPoints - 2));

#endif
std::vector<ArbitraryMeshVertex> vertices;
vertices.reserve(numPoints);

for (const auto& vertex : _winding)
{
vertices.emplace_back(ArbitraryMeshVertex(vertex.vertex, vertex.normal, vertex.texcoord, { 1, 1, 1 }));
}

#if 0
for (unsigned int n = static_cast<unsigned int>(numPoints) - 1; n - 1 > 0; --n)
{
indices.push_back(0);
Expand All @@ -48,6 +74,25 @@ class RenderableWinding
}

shader->addSurface(vertices, indices);
#endif
if (_shader && _slot != IWindingRenderer::InvalidSlot && (shaderChanged || numPoints != _windingSize))
{
_shader->removeWinding(_slot);
_slot = IWindingRenderer::InvalidSlot;
_windingSize = 0;
}

_shader = shader;
_windingSize = numPoints;

if (_slot == IWindingRenderer::InvalidSlot)
{
_slot = shader->addWinding(vertices);
}
else
{
shader->updateWinding(_slot, vertices);
}
}
};

Expand Down
19 changes: 15 additions & 4 deletions radiantcore/rendersystem/backend/OpenGLShader.cpp
Expand Up @@ -128,12 +128,12 @@ void OpenGLShader::addSurface(const std::vector<ArbitraryMeshVertex>& vertices,

void OpenGLShader::drawSurfaces()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

if (hasSurfaces())
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

_vertexBuffer->renderAllBatches(GL_TRIANGLES, false);
#if 0
// Render all triangles
Expand All @@ -157,6 +157,12 @@ void OpenGLShader::drawSurfaces()
glBindBuffer(GL_VERTEX_ARRAY, 0);
#endif
}

// Render all windings
WindingRenderer::render();

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

bool OpenGLShader::hasSurfaces() const
Expand All @@ -179,6 +185,11 @@ void OpenGLShader::updateWinding(Slot slot, const std::vector<ArbitraryMeshVerte
WindingRenderer::updateWinding(slot, vertices);
}

bool OpenGLShader::hasWindings() const
{
return !WindingRenderer::empty();
}

void OpenGLShader::setVisible(bool visible)
{
// Control visibility by inserting or removing our shader passes from the GL
Expand Down
1 change: 1 addition & 0 deletions radiantcore/rendersystem/backend/OpenGLShader.h
Expand Up @@ -108,6 +108,7 @@ class OpenGLShader final :
Slot addWinding(const std::vector<ArbitraryMeshVertex>& vertices) override;
void removeWinding(Slot slot) override;
void updateWinding(Slot slot, const std::vector<ArbitraryMeshVertex>& vertices) override;
bool hasWindings() const;

void setVisible(bool visible) override;
bool isVisible() const override;
Expand Down
4 changes: 3 additions & 1 deletion radiantcore/rendersystem/backend/OpenGLShaderPass.cpp
Expand Up @@ -576,6 +576,8 @@ void OpenGLShaderPass::render(OpenGLState& current,
// Apply our state to the current state object
applyState(current, flagsMask, viewer, time, NULL);

// Surfaces like windings are using CCW culling and an identity matrix
glFrontFace(GL_CCW);
_owner.drawSurfaces();

if (!_renderablesWithoutEntity.empty())
Expand Down Expand Up @@ -604,7 +606,7 @@ void OpenGLShaderPass::render(OpenGLState& current,

bool OpenGLShaderPass::empty()
{
return _renderables.empty() && _renderablesWithoutEntity.empty() && !_owner.hasSurfaces();
return _renderables.empty() && _renderablesWithoutEntity.empty() && !_owner.hasSurfaces() && !_owner.hasWindings();
}

bool OpenGLShaderPass::stateIsActive()
Expand Down

0 comments on commit b435b0b

Please sign in to comment.