Skip to content

Commit

Permalink
#5584: Introduce view type flags applied to OpenGLShaders. Shaders ar…
Browse files Browse the repository at this point in the history
…e now maintaining geometry between frames, and not all of them should be submitting their geometry to every view type.
  • Loading branch information
codereader committed Nov 14, 2021
1 parent b49f973 commit d41a172
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 16 deletions.
11 changes: 10 additions & 1 deletion include/irender.h
Expand Up @@ -479,6 +479,14 @@ typedef std::shared_ptr<Shader> ShaderPtr;

const char* const MODULE_RENDERSYSTEM("ShaderCache");

// Render view type enumeration, is used to select (or leave out)
// Shader objects during rendering
enum class RenderViewType
{
Camera = 1 << 0,
OrthoView = 1 << 1,
};

/**
* \brief
* The main interface for the backend renderer.
Expand Down Expand Up @@ -526,7 +534,8 @@ class RenderSystem
* \param viewer
* Location of the viewer in world space.
*/
virtual void render(RenderStateFlags globalFlagsMask,
virtual void render(RenderViewType renderViewType,
RenderStateFlags globalFlagsMask,
const Matrix4& modelview,
const Matrix4& projection,
const Vector3& viewer) = 0;
Expand Down
4 changes: 2 additions & 2 deletions libs/wxutil/preview/RenderPreview.cpp
Expand Up @@ -500,7 +500,7 @@ bool RenderPreview::drawPreview()

// Launch the back end rendering
renderer.submitToShaders();
_renderSystem->render(flags, _volumeTest.GetModelview(), projection, _viewOrigin);
_renderSystem->render(RenderViewType::Camera, flags, _volumeTest.GetModelview(), projection, _viewOrigin);

// Give subclasses an opportunity to render their own on-screen stuff
onPostRender();
Expand All @@ -525,7 +525,7 @@ void RenderPreview::renderWireFrame()

// Launch the back end rendering
renderer.submitToShaders();
_renderSystem->render(flags, _volumeTest.GetModelview(), projection, _viewOrigin);
_renderSystem->render(RenderViewType::Camera, flags, _volumeTest.GetModelview(), projection, _viewOrigin);
}

void RenderPreview::onGLMouseClick(wxMouseEvent& ev)
Expand Down
4 changes: 2 additions & 2 deletions radiant/camera/CamWnd.cpp
Expand Up @@ -806,8 +806,8 @@ void CamWnd::Cam_Draw()
_renderer->submitToShaders(
getCameraSettings()->getRenderMode() == RENDER_MODE_LIGHTING
);
GlobalRenderSystem().render(allowedRenderFlags, _camera->getModelView(),
_camera->getProjection(), _view.getViewer());
GlobalRenderSystem().render(RenderViewType::Camera, allowedRenderFlags,
_camera->getModelView(), _camera->getProjection(), _view.getViewer());

_renderer->cleanup();
}
Expand Down
2 changes: 1 addition & 1 deletion radiant/xyview/XYRenderer.h
Expand Up @@ -114,6 +114,6 @@ class XYRenderer :

void render(const Matrix4& modelview, const Matrix4& projection)
{
GlobalRenderSystem().render(_globalstate, modelview, projection, Vector3(0,0,0));
GlobalRenderSystem().render(RenderViewType::OrthoView, _globalstate, modelview, projection, Vector3(0,0,0));
}
}; // class XYRenderer
21 changes: 12 additions & 9 deletions radiantcore/rendersystem/OpenGLRenderSystem.cpp
Expand Up @@ -117,10 +117,11 @@ ShaderPtr OpenGLRenderSystem::capture(const std::string& name)
* Render all states in the ShaderCache along with their renderables. This
* is where the actual OpenGL rendering starts.
*/
void OpenGLRenderSystem::render(RenderStateFlags globalstate,
const Matrix4& modelview,
const Matrix4& projection,
const Vector3& viewer)
void OpenGLRenderSystem::render(RenderViewType renderViewType,
RenderStateFlags globalstate,
const Matrix4& modelview,
const Matrix4& projection,
const Vector3& viewer)
{
glPushAttrib(GL_ALL_ATTRIB_BITS);

Expand Down Expand Up @@ -206,15 +207,17 @@ void OpenGLRenderSystem::render(RenderStateFlags globalstate,
// OpenGLShaderPasses (containing the renderable geometry), and render the
// contents of each bucket. Each pass is passed a reference to the "current"
// state, which it can change.
for (OpenGLStates::iterator i = _state_sorted.begin();
i != _state_sorted.end();
++i)
for (const auto& pair : _state_sorted)
{
// Render the OpenGLShaderPass
if (!i->second->empty())
if (pair.second->empty()) continue;

if (pair.second->isApplicableTo(renderViewType))
{
i->second->render(current, globalstate, viewer, _time);
pair.second->render(current, globalstate, viewer, _time);
}

pair.second->clearRenderables();
}

#ifdef RENDERABLE_GEOMETRY
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/rendersystem/OpenGLRenderSystem.h
Expand Up @@ -62,7 +62,7 @@ class OpenGLRenderSystem
/* RenderSystem implementation */

ShaderPtr capture(const std::string& name) override;
void render(RenderStateFlags globalstate,
void render(RenderViewType renderViewType, RenderStateFlags globalstate,
const Matrix4& modelview,
const Matrix4& projection,
const Vector3& viewer) override;
Expand Down
65 changes: 65 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShader.cpp
Expand Up @@ -819,6 +819,8 @@ void OpenGLShader::construct()
state.setRenderFlag(RENDER_CULLFACE);
state.setRenderFlag(RENDER_DEPTHWRITE);
state.setSortPosition(OpenGLState::SORT_FULLBRIGHT);

enableViewType(RenderViewType::Camera);
break;
}

Expand All @@ -839,6 +841,8 @@ void OpenGLShader::construct()
state.setRenderFlag(RENDER_DEPTHWRITE);
state.setRenderFlag(RENDER_BLEND);
state.setSortPosition(OpenGLState::SORT_TRANSLUCENT);

enableViewType(RenderViewType::Camera);
break;
}

Expand All @@ -860,6 +864,8 @@ void OpenGLShader::construct()
state.setDepthFunc(GL_LESS);
state.m_linewidth = 1;
state.m_pointsize = 1;

enableViewType(RenderViewType::OrthoView);
break;
}

Expand All @@ -875,6 +881,9 @@ void OpenGLShader::construct()

state.setSortPosition(OpenGLState::SORT_POINT_FIRST);
state.m_pointsize = 4;

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$SELPOINT")
{
Expand All @@ -883,6 +892,9 @@ void OpenGLShader::construct()

state.setSortPosition(OpenGLState::SORT_POINT_LAST);
state.m_pointsize = 4;

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$BIGPOINT")
{
Expand All @@ -891,6 +903,9 @@ void OpenGLShader::construct()

state.setSortPosition(OpenGLState::SORT_POINT_FIRST);
state.m_pointsize = 6;

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$PIVOT")
{
Expand All @@ -905,18 +920,26 @@ void OpenGLShader::construct()
hiddenLine.setSortPosition(OpenGLState::SORT_GUI0);
hiddenLine.m_linewidth = 2;
hiddenLine.setDepthFunc(GL_GREATER);

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$LATTICE")
{
state.setColour(1, 0.5, 0, 1);
state.setRenderFlag(RENDER_DEPTHWRITE);
state.setSortPosition(OpenGLState::SORT_POINT_FIRST);

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
#if 0
else if (_name == "$WIREFRAME")
{
state.setRenderFlags(RENDER_DEPTHTEST | RENDER_DEPTHWRITE);
state.setSortPosition(OpenGLState::SORT_FULLBRIGHT);
}
#endif
else if (_name == "$CAM_HIGHLIGHT")
{
// This is the shader drawing a coloured overlay
Expand All @@ -931,6 +954,8 @@ void OpenGLShader::construct()
state.setSortPosition(OpenGLState::SORT_HIGHLIGHT);
state.polygonOffset = 0.5f;
state.setDepthFunc(GL_LEQUAL);

enableViewType(RenderViewType::Camera);
}
else if (_name == "$CAM_OVERLAY")
{
Expand All @@ -952,6 +977,8 @@ void OpenGLShader::construct()
hiddenLine.setSortPosition(OpenGLState::SORT_OVERLAY_FIRST);
hiddenLine.setDepthFunc(GL_GREATER);
hiddenLine.m_linestipple_factor = 2;

enableViewType(RenderViewType::Camera);
}
else if (string::starts_with(_name, "$MERGE_ACTION_"))
{
Expand Down Expand Up @@ -999,6 +1026,8 @@ void OpenGLShader::construct()
linesOverlay.setColour(colour);
linesOverlay.setRenderFlags(RENDER_OFFSETLINE | RENDER_DEPTHTEST | RENDER_BLEND);
linesOverlay.setSortPosition(lineSortPosition);

enableViewType(RenderViewType::Camera);
}
else if (_name == "$XY_OVERLAY")
{
Expand All @@ -1011,6 +1040,8 @@ void OpenGLShader::construct()
state.setSortPosition(OpenGLState::SORT_HIGHLIGHT);
state.m_linewidth = 2;
state.m_linestipple_factor = 3;

enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$XY_OVERLAY_GROUP")
{
Expand All @@ -1023,6 +1054,8 @@ void OpenGLShader::construct()
state.setSortPosition(OpenGLState::SORT_HIGHLIGHT);
state.m_linewidth = 2;
state.m_linestipple_factor = 3;

enableViewType(RenderViewType::OrthoView);
}
else if (string::starts_with(_name, "$XY_MERGE_ACTION_"))
{
Expand Down Expand Up @@ -1054,6 +1087,8 @@ void OpenGLShader::construct()
state.setColour(colour);
state.setSortPosition(OpenGLState::SORT_OVERLAY_FIRST);
state.m_linewidth = 2;

enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$XY_INACTIVE_NODE")
{
Expand All @@ -1072,18 +1107,25 @@ void OpenGLShader::construct()

state.m_linewidth = 1;
state.m_pointsize = 1;

enableViewType(RenderViewType::OrthoView);
}
#if 0
else if (_name == "$DEBUG_CLIPPED")
{
state.setRenderFlag(RENDER_DEPTHWRITE);
state.setSortPosition(OpenGLState::SORT_LAST);
}
#endif
else if (_name == "$POINTFILE")
{
state.setColour(1, 0, 0, 1);
state.setRenderFlags(RENDER_DEPTHTEST | RENDER_DEPTHWRITE);
state.setSortPosition(OpenGLState::SORT_FULLBRIGHT);
state.m_linewidth = 4;

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$WIRE_OVERLAY")
{
Expand All @@ -1103,6 +1145,9 @@ void OpenGLShader::construct()
| RENDER_VERTEX_COLOUR);
hiddenLine.setSortPosition(OpenGLState::SORT_GUI0);
hiddenLine.setDepthFunc(GL_GREATER);

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$FLATSHADE_OVERLAY")
{
Expand Down Expand Up @@ -1130,6 +1175,9 @@ void OpenGLShader::construct()
| RENDER_POLYGONSTIPPLE);
hiddenLine.setSortPosition(OpenGLState::SORT_GUI0);
hiddenLine.setDepthFunc(GL_GREATER);

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$CLIPPER_OVERLAY")
{
Expand All @@ -1139,6 +1187,9 @@ void OpenGLShader::construct()
| RENDER_FILL
| RENDER_POLYGONSTIPPLE);
state.setSortPosition(OpenGLState::SORT_OVERLAY_FIRST);

enableViewType(RenderViewType::Camera);
enableViewType(RenderViewType::OrthoView);
}
else if (_name == "$AAS_AREA")
{
Expand All @@ -1157,6 +1208,8 @@ void OpenGLShader::construct()
| RENDER_LINESTIPPLE);
hiddenLine.setSortPosition(OpenGLState::SORT_OVERLAY_LAST);
hiddenLine.setDepthFunc(GL_GREATER);

enableViewType(RenderViewType::Camera);
}
else
{
Expand All @@ -1169,6 +1222,8 @@ void OpenGLShader::construct()
{
// This is not a hard-coded shader, construct from the shader system
constructNormalShader();

enableViewType(RenderViewType::Camera);
}
} // switch (name[0])
}
Expand All @@ -1185,5 +1240,15 @@ void OpenGLShader::onMaterialChanged()
realise();
}

bool OpenGLShader::isApplicableTo(RenderViewType renderViewType) const
{
return (_enabledViewTypes & static_cast<std::size_t>(renderViewType)) != 0;
}

void OpenGLShader::enableViewType(RenderViewType renderViewType)
{
_enabledViewTypes |= static_cast<std::size_t>(renderViewType);
}

}

6 changes: 6 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShader.h
Expand Up @@ -56,6 +56,9 @@ class OpenGLShader final :

std::unique_ptr<IBackendWindingRenderer> _windingRenderer;

// Each shader can be used by either camera or orthoview, or both
std::size_t _enabledViewTypes;

private:

// Start point for constructing shader passes from the shader name
Expand Down Expand Up @@ -149,6 +152,9 @@ class OpenGLShader final :
const MaterialPtr& getMaterial() const override;

unsigned int getFlags() const override;

bool isApplicableTo(RenderViewType renderViewType) const;
void enableViewType(RenderViewType renderViewType);
};

typedef std::shared_ptr<OpenGLShader> OpenGLShaderPtr;
Expand Down
8 changes: 8 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShaderPass.cpp
Expand Up @@ -599,7 +599,10 @@ void OpenGLShaderPass::render(OpenGLState& current,

renderAllContained(i->second, current, viewer, time);
}
}

void OpenGLShaderPass::clearRenderables()
{
_renderablesWithoutEntity.clear();
_renderables.clear();
}
Expand All @@ -614,6 +617,11 @@ bool OpenGLShaderPass::empty()
;
}

bool OpenGLShaderPass::isApplicableTo(RenderViewType renderViewType) const
{
return _owner.isApplicableTo(renderViewType);
}

bool OpenGLShaderPass::stateIsActive()
{
return ((_glState.stage0 == NULL || _glState.stage0->isVisible()) &&
Expand Down
6 changes: 6 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShaderPass.h
Expand Up @@ -196,6 +196,12 @@ class OpenGLShaderPass
*/
bool empty();

// Clear out all renderable references accumulated during this frame
void clearRenderables();

// Whether this shader pass is suitable for the give view type
bool isApplicableTo(RenderViewType renderViewType) const;

friend std::ostream& operator<<(std::ostream& st, const OpenGLShaderPass& self);
};

Expand Down

0 comments on commit d41a172

Please sign in to comment.