Skip to content

Commit

Permalink
#5893: Add third render pass drawing the non-interaction stages
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Feb 20, 2022
1 parent fe94f37 commit d3c1f1d
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 50 deletions.
52 changes: 50 additions & 2 deletions radiantcore/rendersystem/OpenGLRenderSystem.cpp
Expand Up @@ -350,7 +350,7 @@ IRenderResult::Ptr OpenGLRenderSystem::renderLitScene(RenderStateFlags globalFla

interactionLists.emplace_back(std::move(interaction));
}

// Run the depth fill pass
for (auto& interactionList : interactionLists)
{
Expand All @@ -364,8 +364,56 @@ IRenderResult::Ptr OpenGLRenderSystem::renderLitScene(RenderStateFlags globalFla
result->drawCalls += interactionList.getDrawCalls();
}

glEnableClientState(GL_VERTEX_ARRAY);

// Draw non-interaction passes (like skyboxes or blend stages)
// TODO
for (const auto& entity : _entities)
{
entity->foreachRenderable([&](const render::IRenderableObject::Ptr& object, Shader* shader)
{
// Skip empty objects
if (!object->isVisible()) return;

// Don't collect invisible shaders
if (!shader->isVisible()) return;

auto glShader = static_cast<OpenGLShader*>(shader);

// We only consider materials designated for camera rendering
if (!glShader->isApplicableTo(RenderViewType::Camera))
{
return;
}

// For each pass except for the depth fill and interaction passes, draw the geometry
glShader->foreachNonInteractionPass([&](OpenGLShaderPass& pass)
{
if (!pass.stateIsActive())
{
return;
}

// Reset the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadMatrixd(Matrix4::getIdentity());

glMatrixMode(GL_MODELVIEW);

// Apply our state to the current state object
pass.applyState(current, globalFlagsMask, view.getViewer(), _time, entity.get());

RenderInfo info(current.getRenderFlags(), view.getViewer(), current.cubeMapMode);

if (current.glProgram)
{
OpenGLShaderPass::SetUpNonInteractionProgram(current, view.getViewer(), object->getObjectTransform());
}

LightInteractions::SubmitObject(*object, _geometryStore);
result->drawCalls++;
});
});
}

renderText();

Expand Down
85 changes: 41 additions & 44 deletions radiantcore/rendersystem/backend/LightInteractions.cpp
Expand Up @@ -5,44 +5,6 @@
namespace render
{

namespace detail
{

inline void submitObject(IRenderableObject& object, IGeometryStore& store)
{
if (object.getObjectTransform().getHandedness() == Matrix4::RIGHTHANDED)
{
glFrontFace(GL_CW);
}
else
{
glFrontFace(GL_CCW);
}

glMatrixMode(GL_MODELVIEW);

auto renderParams = store.getRenderParameters(object.getStorageLocation());

glPushMatrix();

glMultMatrixd(object.getObjectTransform());

glVertexPointer(3, GL_DOUBLE, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->vertex);

glVertexAttribPointer(GLProgramAttribute::Position, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->vertex);
glVertexAttribPointer(GLProgramAttribute::Normal, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->normal);
glVertexAttribPointer(GLProgramAttribute::TexCoord, 2, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->texcoord);
glVertexAttribPointer(GLProgramAttribute::Tangent, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->tangent);
glVertexAttribPointer(GLProgramAttribute::Bitangent, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->bitangent);

glDrawElementsBaseVertex(GL_TRIANGLES, static_cast<GLsizei>(renderParams.indexCount),
GL_UNSIGNED_INT, renderParams.firstIndex, static_cast<GLint>(renderParams.firstVertex));

glPopMatrix();
}

}

void LightInteractions::addObject(IRenderableObject& object, IRenderEntity& entity, OpenGLShader* shader)
{
auto& objectsByMaterial = _objectsByEntity.emplace(
Expand Down Expand Up @@ -132,7 +94,7 @@ void LightInteractions::fillDepthBuffer(OpenGLState& state, RenderStateFlags glo

for (auto object : objectList)
{
detail::submitObject(object.get(), _store);
SubmitObject(object.get(), _store);
++_drawCalls;
}
}
Expand Down Expand Up @@ -162,9 +124,11 @@ void LightInteractions::render(OpenGLState& state, RenderStateFlags globalFlagsM

if (!shader->isVisible()) continue;

shader->foreachPassWithoutDepthPass([&](OpenGLShaderPass& pass)
auto pass = shader->getInteractionPass();

if (pass)
{
if (!pass.stateIsActive())
if (!pass->stateIsActive())
{
return;
}
Expand All @@ -176,7 +140,7 @@ void LightInteractions::render(OpenGLState& state, RenderStateFlags globalFlagsM
glMatrixMode(GL_MODELVIEW);

// Apply our state to the current state object
pass.applyState(state, globalFlagsMask, view.getViewer(), renderTime, entity);
pass->applyState(state, globalFlagsMask, view.getViewer(), renderTime, entity);

RenderInfo info(state.getRenderFlags(), view.getViewer(), state.cubeMapMode);

Expand All @@ -188,14 +152,47 @@ void LightInteractions::render(OpenGLState& state, RenderStateFlags globalFlagsM
view.getViewer(), object.get().getObjectTransform(), renderTime, state.isColourInverted());
}

detail::submitObject(object.get(), _store);
SubmitObject(object.get(), _store);
++_drawCalls;
}
});
}
}
}

glDisableClientState(GL_VERTEX_ARRAY);
}

void LightInteractions::SubmitObject(IRenderableObject& object, IGeometryStore& store)
{
if (object.getObjectTransform().getHandedness() == Matrix4::RIGHTHANDED)
{
glFrontFace(GL_CW);
}
else
{
glFrontFace(GL_CCW);
}

glMatrixMode(GL_MODELVIEW);

auto renderParams = store.getRenderParameters(object.getStorageLocation());

glPushMatrix();

glMultMatrixd(object.getObjectTransform());

glVertexPointer(3, GL_DOUBLE, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->vertex);

glVertexAttribPointer(GLProgramAttribute::Position, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->vertex);
glVertexAttribPointer(GLProgramAttribute::Normal, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->normal);
glVertexAttribPointer(GLProgramAttribute::TexCoord, 2, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->texcoord);
glVertexAttribPointer(GLProgramAttribute::Tangent, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->tangent);
glVertexAttribPointer(GLProgramAttribute::Bitangent, 3, GL_DOUBLE, 0, sizeof(ArbitraryMeshVertex), &renderParams.bufferStart->bitangent);

glDrawElementsBaseVertex(GL_TRIANGLES, static_cast<GLsizei>(renderParams.indexCount),
GL_UNSIGNED_INT, renderParams.firstIndex, static_cast<GLint>(renderParams.firstVertex));

glPopMatrix();
}

}
2 changes: 2 additions & 0 deletions radiantcore/rendersystem/backend/LightInteractions.h
Expand Up @@ -74,6 +74,8 @@ class LightInteractions

void render(OpenGLState& state, RenderStateFlags globalFlagsMask,
const IRenderView& view, std::size_t renderTime);

static void SubmitObject(IRenderableObject& object, IGeometryStore& store);
};

}
4 changes: 2 additions & 2 deletions radiantcore/rendersystem/backend/OpenGLShader.cpp
Expand Up @@ -819,11 +819,11 @@ void OpenGLShader::foreachPass(const std::function<void(OpenGLShaderPass&)>& fun
}
}

void OpenGLShader::foreachPassWithoutDepthPass(const std::function<void(OpenGLShaderPass&)>& functor)
void OpenGLShader::foreachNonInteractionPass(const std::function<void(OpenGLShaderPass&)>& functor)
{
for (auto& pass : _shaderPasses)
{
if (pass != _depthFillPass)
if (pass != _depthFillPass && pass != _interactionPass)
{
functor(*pass);
}
Expand Down
4 changes: 3 additions & 1 deletion radiantcore/rendersystem/backend/OpenGLShader.h
Expand Up @@ -151,7 +151,9 @@ class OpenGLShader :
void setMergeModeEnabled(bool enabled);

void foreachPass(const std::function<void(OpenGLShaderPass&)>& functor);
void foreachPassWithoutDepthPass(const std::function<void(OpenGLShaderPass&)>& functor);

// All non-interaction, non-depth fill passes are forwarded to the functor
void foreachNonInteractionPass(const std::function<void(OpenGLShaderPass&)>& functor);

// Returns the depth fill pass of this shader, or null if this shader doesn't have one
OpenGLShaderPass* getDepthFillPass() const;
Expand Down
10 changes: 9 additions & 1 deletion radiantcore/rendersystem/backend/OpenGLShaderPass.cpp
Expand Up @@ -589,7 +589,7 @@ void OpenGLShaderPass::setUpLightingCalculation(OpenGLState& current,
GLuint attenuation_z = lightMat->lightFalloffImage()->getGLTexNum();

// Bind the falloff textures
//assert(current.testRenderFlag(RENDER_TEXTURE_2D));
assert(current.testRenderFlag(RENDER_TEXTURE_2D));

setTextureState(
current.texture3, attenuation_xy, GL_TEXTURE3, GL_TEXTURE_2D
Expand All @@ -614,6 +614,14 @@ void OpenGLShaderPass::setUpLightingCalculation(OpenGLState& current,
current.glProgram->applyRenderParams(osViewer, objTransform, parms);
}

void OpenGLShaderPass::SetUpNonInteractionProgram(OpenGLState& current, const Vector3& viewer, const Matrix4& objTransform)
{
static GLProgram::Params parms({ 0,0,0 }, { 0,0,0,0 }, Matrix4::getIdentity());

assert(current.glProgram);
current.glProgram->applyRenderParams(viewer, objTransform, parms);
}

// Flush renderables
void OpenGLShaderPass::renderAllContained(const Renderables& renderables,
OpenGLState& current,
Expand Down
2 changes: 2 additions & 0 deletions radiantcore/rendersystem/backend/OpenGLShaderPass.h
Expand Up @@ -175,6 +175,8 @@ class OpenGLShaderPass
std::size_t time,
bool invertVertexColour);

static void SetUpNonInteractionProgram(OpenGLState& current, const Vector3& viewer, const Matrix4& objTransform);

static void setTextureState(GLint& current,
const GLint& texture,
GLenum textureUnit,
Expand Down

0 comments on commit d3c1f1d

Please sign in to comment.