Skip to content

Commit

Permalink
Merge addLitRenderable and addRenderable
Browse files Browse the repository at this point in the history
addLitRenderable() is now just addRenderable(), and replaces the previous
addRenderable() which accepted a LightList instead of a LitObject. In order to
support non-lit objects, the LitObject parameter is now an optional pointer
rather than a mandatory reference.
  • Loading branch information
Matthew Mott committed Dec 2, 2020
1 parent 78efba0 commit 4309d9e
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 146 deletions.
68 changes: 28 additions & 40 deletions include/irenderable.h
Expand Up @@ -32,58 +32,46 @@ class RenderableCollector
public:
virtual ~RenderableCollector() {}

/**
* Submit an OpenGLRenderable object for rendering using the given shader.
*
* \param shader
* The Shader object this Renderable will be attached to.
*
* \param renderable
* The renderable object to submit.
*
* \param world
* The local to world transform that should be applied to this object when
* it is rendered.
*
* \param lights
* Optional LightSources containing lights illuminating this Renderable.
*
* \param entity
* Optional IRenderEntity exposing parameters which affect the rendering of
* this Renderable.
*/
virtual void addRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& world,
const LightSources* lights = nullptr,
const IRenderEntity* entity = nullptr) = 0;

/**
* \brief
* Submit a renderable object to be illuminated by scene lights.
* Submit a renderable object
*
* This method allows renderable geometry to be submitted under the control
* of a LitObject which will determine whether and how the renderable is
* illuminated by scene lights. Each objected submitted with this method
* will be considered for lighting by the lights which are submitted to the
* same RenderableCollector using addLight().
*
* Most of the parameters have identical meanings to those in
* addRenderable().
* Objects may be submitted without a LitObject if they are not affected by
* scene lights.
*
* \param litObject
* A LitObject determining lighting interactions for this renderable. This
* may or may not be the same actual object as the OpenGLRenderable,
* depending on how the object tree is set up. If a single LitObject
* contains multiple renderables, a separate call to this method must be
* made for each renderable (with the same litObject parameter).
* \param shader
* The Shader object this Renderable will be attached to.
*
* \param renderable
* The renderable object to submit.
*
* \param localToWorld
* The local to world transform that should be applied to this object when
* it is rendered.
*
* \param entity
* Optional IRenderEntity exposing parameters which affect the rendering of
* this Renderable.
*
* \param litObject
* Optional LitObject determining lighting interactions for this
* renderable. This may or may not be the same actual object as the
* OpenGLRenderable, depending on how the object class hierarchy is set up.
* If a single LitObject contains multiple renderables, a separate call to
* this method must be made for each renderable (with the same litObject
* parameter).
*/
virtual void addLitRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& localToWorld,
const LitObject& litObject,
const IRenderEntity* entity = nullptr) = 0;
virtual void addRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& localToWorld,
const LitObject* litObject = nullptr,
const IRenderEntity* entity = nullptr) = 0;

/**
* \brief
Expand Down
92 changes: 9 additions & 83 deletions libs/render/CamRenderer.h
Expand Up @@ -29,34 +29,13 @@ class CamRenderer: public RenderableCollector
// All lights we have received from the scene
std::list<const RendererLight*> _sceneLights;

// Legacy lit renderable which provided its own LightSources to
// addRenderable()
struct LegacyLitRenderable
{
const OpenGLRenderable& renderable;
const LightSources* lights = nullptr;
Matrix4 local2World;
const IRenderEntity* entity = nullptr;

LegacyLitRenderable(const OpenGLRenderable& r, const LightSources* l,
const Matrix4& l2w, const IRenderEntity* e)
: renderable(r), lights(l), local2World(l2w), entity(e)
{}
};
using LegacyLitRenderables = std::vector<LegacyLitRenderable>;

// Legacy renderables with their own light lists. No processing needed;
// just store them until it's time to submit to shaders.
using LegacyRenderablesByShader = std::map<Shader*, LegacyLitRenderables>;
LegacyRenderablesByShader _legacyRenderables;

// Lit renderable provided via addLitRenderable(), for which we construct
// the light list with lights received via addLight().
// Lit renderable provided via addRenderable(), for which we construct the
// light list with lights received via addLight().
struct LitRenderable
{
// Renderable information submitted with addLitObject()
const OpenGLRenderable& renderable;
const LitObject& litObject;
const LitObject* litObject = nullptr;
Matrix4 local2World;
const IRenderEntity* entity = nullptr;

Expand All @@ -83,7 +62,7 @@ class CamRenderer: public RenderableCollector
// the scene
for (const RendererLight* l: _sceneLights)
{
if (j->litObject.intersectsLight(*l))
if (j->litObject && j->litObject->intersectsLight(*l))
j->lights.addLight(*l);
}
}
Expand All @@ -107,23 +86,6 @@ class CamRenderer: public RenderableCollector
// Calculate intersections between lights and renderables we have received
calculateLightIntersections();

// Render legacy renderables with submitted light lists
for (auto i = _legacyRenderables.begin();
i != _legacyRenderables.end();
++i)
{
// Iterate over the list of renderables for this shader, submitting
// each one
Shader* shader = i->first;
wxASSERT(shader);
for (auto j = i->second.begin(); j != i->second.end(); ++j)
{
const LegacyLitRenderable& lr = *j;
shader->addRenderable(lr.renderable, lr.local2World,
lr.lights, lr.entity);
}
}

// Render objects with calculated light lists
for (auto i = _litRenderables.begin(); i != _litRenderables.end(); ++i)
{
Expand Down Expand Up @@ -178,47 +140,11 @@ class CamRenderer: public RenderableCollector
++_totalLights;
}

void addRenderable(Shader& shader, const OpenGLRenderable& renderable,
const Matrix4& world, const LightSources* lights,
const IRenderEntity* entity) override
{
if (_highlightPrimitives && _highlightedPrimitiveShader)
_highlightedPrimitiveShader->addRenderable(renderable, world,
lights, entity);

if (_highlightFaces && _highlightedFaceShader)
_highlightedFaceShader->addRenderable(renderable, world,
lights, entity);

// Construct an entry for this shader in the map if it is the first
// time we've seen it
auto iter = _legacyRenderables.find(&shader);
if (iter == _legacyRenderables.end())
{
// Add an entry for this shader, and pre-allocate some space in the
// vector to avoid too many expansions during scenegraph traversal.
LegacyLitRenderables emptyList;
emptyList.reserve(1024);

auto result = _legacyRenderables.insert(
std::make_pair(&shader, std::move(emptyList))
);
wxASSERT(result.second);
iter = result.first;
}
wxASSERT(iter != _legacyRenderables.end());

// Add the renderable and its lights to the list of lit renderables for
// this shader
wxASSERT(iter->first == &shader);
iter->second.emplace_back(renderable, lights, world, entity);
}

void addLitRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& localToWorld,
const LitObject& litObject,
const IRenderEntity* entity = nullptr) override
void addRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& localToWorld,
const LitObject* litObject = nullptr,
const IRenderEntity* entity = nullptr) override
{
if (_highlightPrimitives && _highlightedPrimitiveShader)
_highlightedPrimitiveShader->addRenderable(renderable, localToWorld,
Expand Down
20 changes: 6 additions & 14 deletions radiant/xyview/XYRenderer.h
Expand Up @@ -55,28 +55,20 @@ class XYRenderer: public RenderableCollector

void addRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& world, const LightSources*,
const IRenderEntity* entity) override
const Matrix4& localToWorld,
const LitObject* /* litObject */,
const IRenderEntity* entity = nullptr) override
{
if (_state.highlightPrimitives)
{
if (_state.highlightAsGroupMember)
_selectedShaderGroup->addRenderable(renderable, world,
_selectedShaderGroup->addRenderable(renderable, localToWorld,
nullptr, entity);
else
_selectedShader->addRenderable(renderable, world, nullptr, entity);
_selectedShader->addRenderable(renderable, localToWorld, nullptr, entity);
}

shader.addRenderable(renderable, world, nullptr, entity);
}

void addLitRenderable(Shader& shader,
const OpenGLRenderable& renderable,
const Matrix4& localToWorld,
const LitObject& /* litObject */,
const IRenderEntity* entity = nullptr) override
{
addRenderable(shader, renderable, localToWorld, nullptr, entity);
shader.addRenderable(renderable, localToWorld, nullptr, entity);
}

void render(const Matrix4& modelview, const Matrix4& projection)
Expand Down
6 changes: 3 additions & 3 deletions radiantcore/brush/BrushNode.cpp
Expand Up @@ -436,10 +436,10 @@ void BrushNode::renderSolid(RenderableCollector& collector,
if (highlight)
collector.setHighlightFlag(RenderableCollector::Highlight::Faces, true);

// greebo: BrushNodes have always an identity l2w, don't do any transforms
collector.addLitRenderable(
// greebo: BrushNodes have always an identity l2w, don't do any transforms
collector.addRenderable(
*face.getFaceShader().getGLShader(), face.getWinding(),
Matrix4::getIdentity(), *this, _renderEntity
Matrix4::getIdentity(), this, _renderEntity
);

if (highlight)
Expand Down
4 changes: 2 additions & 2 deletions radiantcore/model/md5/MD5ModelNode.cpp
Expand Up @@ -112,10 +112,10 @@ void MD5ModelNode::render(RenderableCollector& collector, const VolumeTest& volu
if (surfaceShader->isVisible())
{
assert(i->shader); // shader must be captured at this point
collector.addLitRenderable(
collector.addRenderable(
collector.supportsFullMaterials() ? *i->shader
: *entity.getWireShader(),
*i->surface, localToWorld, *this, &entity
*i->surface, localToWorld, this, &entity
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions radiantcore/model/picomodel/StaticModel.cpp
Expand Up @@ -111,8 +111,8 @@ void StaticModel::renderSolid(RenderableCollector& rend,
foreachVisibleSurface([&](const Surface& s)
{
// Submit the ordinary shader for material-based rendering
rend.addLitRenderable(*s.shader, *s.surface, localToWorld,
litObject, &entity);
rend.addRenderable(*s.shader, *s.surface, localToWorld,
&litObject, &entity);
});
}

Expand Down
4 changes: 2 additions & 2 deletions radiantcore/patch/PatchNode.cpp
Expand Up @@ -277,9 +277,9 @@ void PatchNode::renderSolid(RenderableCollector& collector, const VolumeTest& vo
assert(_renderEntity); // patches rendered without parent - no way!

// Render the patch itself
collector.addLitRenderable(
collector.addRenderable(
*m_patch._shader.getGLShader(), m_patch._solidRenderable,
localToWorld(), *this, _renderEntity
localToWorld(), this, _renderEntity
);

#if DEBUG_PATCH_NTB_VECTORS
Expand Down

0 comments on commit 4309d9e

Please sign in to comment.