Renderer changes; render buckets now use new abstract class IRenderable instead of CSceneNode to allow rendering non-nodes, plus renderer modified to easily allow multiple rendering passes overlaid on each other

This commit is contained in:
parax0 2015-08-15 00:04:56 -04:00
parent 4d7774f19e
commit 928381f8e4
16 changed files with 166 additions and 98 deletions

View File

@ -1,18 +1,42 @@
#ifndef ENUMUTIL
#define ENUMUTIL
#define DEFINE_ENUM_FLAGS(X) \
inline X operator|(const X& A, const X& B) { \
return (X) ((int) A | (int) B); \
} \
inline void operator|= (X& A, X& B) { \
A = A | B; \
} \
inline X operator|(const X& A, const int B) { \
return (X) ((int) A | B); \
} \
inline void operator|= (X& A, int B) { \
A = A | B; \
#define DEFINE_ENUM_FLAGS(X) \
inline X operator|(const X& A, const X& B) { \
return (X) ((int) A | (int) B); \
} \
inline void operator|= (X& A, X& B) { \
A = A | B; \
} \
inline X operator|(const X& A, const int B) { \
return (X) ((int) A | B); \
} \
inline void operator|= (X& A, int B) { \
A = A | B; \
} \
inline X operator|(const X& A, const unsigned int B) { \
return (X) ((int) A | B); \
} \
inline void operator|= (X& A, unsigned int B) { \
A = A | B; \
} \
inline X operator&(const X& A, const X& B) { \
return (X) ((int) A & (int) B); \
} \
inline void operator&= (X& A, X& B) { \
A = A & B; \
} \
inline X operator&(const X& A, const int B) { \
return (X) ((int) A & B); \
} \
inline void operator&= (X& A, int B) { \
A = A & B; \
} \
inline X operator&(const X& A, const unsigned int B) { \
return (X) ((int) A & B); \
} \
inline void operator&= (X& A, unsigned int B) { \
A = A & B; \
}
#endif // ENUMUTIL

View File

@ -157,3 +157,10 @@ void CGraphics::SetDefaultLighting()
sDefaultDirectionalLights[1].Load();
sDefaultDirectionalLights[2].Load();
}
void CGraphics::SetIdentityMVP()
{
sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
sMVPBlock.ViewMatrix = CMatrix4f::skIdentity;
sMVPBlock.ProjectionMatrix = CMatrix4f::skIdentity;
}

View File

@ -92,6 +92,7 @@ public:
static void ReleaseContext(u32 Index);
static void SetActiveContext(u32 Index);
static void SetDefaultLighting();
static void SetIdentityMVP();
};
#endif // CGRAPHICS_H

View File

@ -14,12 +14,12 @@ void CRenderBucket::SetSortType(ESortType Type)
mSortType = Type;
}
void CRenderBucket::Add(const SMeshPointer& Mesh)
void CRenderBucket::Add(const SRenderablePtr& ptr)
{
if (mSize >= mEstSize)
mNodes.push_back(Mesh);
mRenderables.push_back(ptr);
else
mNodes[mSize] = Mesh;
mRenderables[mSize] = ptr;
mSize++;
}
@ -28,7 +28,7 @@ void CRenderBucket::Sort(CCamera& Camera)
{
struct {
CCamera *pCamera;
bool operator()(SMeshPointer left, SMeshPointer right) {
bool operator()(SRenderablePtr left, SRenderablePtr right) {
CVector3f cPos = pCamera->Position();
CVector3f cDir = pCamera->GetDirection();
@ -42,7 +42,7 @@ void CRenderBucket::Sort(CCamera& Camera)
backToFront.pCamera = &Camera;
if (mSortType == BackToFront)
std::stable_sort(mNodes.begin(), mNodes.begin() + mSize, backToFront);
std::stable_sort(mRenderables.begin(), mRenderables.begin() + mSize, backToFront);
// Test: draw node bounding boxes + vertices used for sorting
/*for (u32 iNode = 0; iNode < mNodes.size(); iNode++)
@ -67,7 +67,7 @@ void CRenderBucket::Sort(CCamera& Camera)
void CRenderBucket::Clear()
{
mEstSize = mSize;
if (mNodes.size() > mSize) mNodes.resize(mSize);
if (mRenderables.size() > mSize) mRenderables.resize(mSize);
mSize = 0;
}
@ -75,14 +75,14 @@ void CRenderBucket::Draw(ERenderOptions Options)
{
for (u32 n = 0; n < mSize; n++)
{
if (mNodes[n].Command == eDrawMesh)
mNodes[n].pNode->Draw(Options);
if (mRenderables[n].Command == eDrawMesh)
mRenderables[n].pRenderable->Draw(Options);
else if (mNodes[n].Command == eDrawAsset)
mNodes[n].pNode->DrawAsset(Options, mNodes[n].Asset);
else if (mRenderables[n].Command == eDrawAsset)
mRenderables[n].pRenderable->DrawAsset(Options, mRenderables[n].Asset);
else if (mNodes[n].Command == eDrawSelection)
mNodes[n].pNode->DrawSelection();
else if (mRenderables[n].Command == eDrawSelection)
mRenderables[n].pRenderable->DrawSelection();
// todo: implementation for eDrawExtras
}

View File

@ -3,8 +3,8 @@
#include "CCamera.h"
#include "ERenderOptions.h"
#include "SRenderablePtr.h"
#include <Common/types.h>
#include <OpenGL/SMeshPointer.h>
#include <vector>
class CRenderBucket
@ -17,14 +17,14 @@ public:
};
private:
ESortType mSortType;
std::vector<SMeshPointer> mNodes;
std::vector<SRenderablePtr> mRenderables;
u32 mEstSize;
u32 mSize;
public:
CRenderBucket();
void SetSortType(ESortType Type);
void Add(const SMeshPointer& Mesh);
void Add(const SRenderablePtr& ptr);
void Sort(CCamera& Camera);
void Clear();
void Draw(ERenderOptions Options);

View File

@ -60,12 +60,14 @@ bool CRenderer::IsUVAnimationOn()
void CRenderer::ToggleBackfaceCull(bool b)
{
mOptions = (ERenderOptions) ((mOptions & ~eEnableBackfaceCull) | (b << 1));
if (b) mOptions |= eEnableBackfaceCull;
else mOptions &= ~eEnableBackfaceCull;
}
void CRenderer::ToggleUVAnimation(bool b)
{
mOptions = (ERenderOptions) ((mOptions & ~eEnableUVScroll) | b);
if (b) mOptions |= eEnableUVScroll;
else mOptions &= ~eEnableUVScroll;
}
void CRenderer::ToggleGrid(bool b)
@ -75,12 +77,14 @@ void CRenderer::ToggleGrid(bool b)
void CRenderer::ToggleOccluders(bool b)
{
mOptions = (ERenderOptions) ((mOptions & ~eEnableOccluders) | (b << 2));
if (b) mOptions |= eEnableOccluders;
else mOptions &= ~eEnableOccluders;
}
void CRenderer::ToggleAlphaDisabled(bool b)
{
mOptions = (ERenderOptions) ((mOptions & ~eNoAlpha) | (b << 5));
if (b) mOptions |= eNoAlpha;
else mOptions &= ~eNoAlpha;
}
void CRenderer::SetBloom(EBloomMode BloomMode)
@ -88,9 +92,9 @@ void CRenderer::SetBloom(EBloomMode BloomMode)
mBloomMode = BloomMode;
if (BloomMode != eNoBloom)
mOptions = (ERenderOptions) (mOptions | eEnableBloom);
mOptions |= eEnableBloom;
else
mOptions = (ERenderOptions) (mOptions & ~eEnableBloom);
mOptions &= ~eEnableBloom;
}
void CRenderer::SetFont(CFont *pFont)
@ -118,22 +122,33 @@ void CRenderer::SetViewportSize(u32 Width, u32 Height)
}
// ************ RENDER ************
void CRenderer::RenderScene(CCamera& Camera)
void CRenderer::RenderBuckets(CCamera& Camera)
{
if (!mInitialized) Init();
// Set backface culling
if (mOptions & eEnableBackfaceCull) glEnable(GL_CULL_FACE);
else glDisable(GL_CULL_FACE);
// Render scene to texture
glDepthRange(0.f, 1.f);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
mOpaqueBucket.Draw(mOptions);
mOpaqueBucket.Clear();
mTransparentBucket.Sort(Camera);
mTransparentBucket.Draw(mOptions);
mTransparentBucket.Clear();
// Clear depth buffer to enable more rendering passes
glClear(GL_DEPTH_BUFFER_BIT);
}
void CRenderer::RenderBloom()
{
// Check to ensure bloom is enabled
if (mBloomMode == eNoBloom) return;
// Setup
static const float skHOffset[6] = { -0.008595f, -0.005470f, -0.002345f,
0.002345f, 0.005470f, 0.008595f };
@ -158,9 +173,7 @@ void CRenderer::RenderBloom()
glClearColor(0.f, 0.f, 0.f, 0.f);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
CGraphics::sMVPBlock.ViewMatrix = CMatrix4f::skIdentity;
CGraphics::sMVPBlock.ProjectionMatrix = CMatrix4f::skIdentity;
CGraphics::SetIdentityMVP();
CGraphics::UpdateMVPBlock();
// Pass 1: Alpha-blend the scene texture on a black background
@ -211,6 +224,28 @@ void CRenderer::RenderBloom()
glBlendFunc(GL_ONE, GL_ONE);
CDrawUtil::DrawSquare();
}
// Render result onto main scene framebuffer
mSceneFramebuffer.Bind();
glViewport(0, 0, mViewportWidth, mViewportHeight);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
CGraphics::SetIdentityMVP();
CGraphics::UpdateMVPBlock();
CDrawUtil::UseTextureShader();
glBlendFunc(GL_ONE, GL_ONE);
mBloomFramebuffers[2].Texture()->Bind(0);
CDrawUtil::DrawSquare();
if (mBloomMode == eBloomMaps)
{
// Bloom maps are in the framebuffer alpha channel.
// White * dst alpha = bloom map colors
CDrawUtil::UseColorShader(CColor::skWhite);
glBlendFunc(GL_DST_ALPHA, GL_ZERO);
CDrawUtil::DrawSquare();
}
}
void CRenderer::RenderSky(CModel *pSkyboxModel, CVector3f CameraPosition)
@ -236,24 +271,24 @@ void CRenderer::RenderSky(CModel *pSkyboxModel, CVector3f CameraPosition)
pSkyboxModel->Draw(mOptions, 0);
}
void CRenderer::AddOpaqueMesh(CSceneNode *pNode, u32 AssetID, CAABox& AABox, ERenderCommand Command)
void CRenderer::AddOpaqueMesh(IRenderable *pRenderable, u32 AssetID, CAABox& AABox, ERenderCommand Command)
{
SMeshPointer mesh;
mesh.pNode = pNode;
mesh.Asset = AssetID;
mesh.AABox = AABox;
mesh.Command = Command;
mOpaqueBucket.Add(mesh);
SRenderablePtr ptr;
ptr.pRenderable = pRenderable;
ptr.Asset = AssetID;
ptr.AABox = AABox;
ptr.Command = Command;
mOpaqueBucket.Add(ptr);
}
void CRenderer::AddTransparentMesh(CSceneNode *pNode, u32 AssetID, CAABox& AABox, ERenderCommand Command)
void CRenderer::AddTransparentMesh(IRenderable *pRenderable, u32 AssetID, CAABox& AABox, ERenderCommand Command)
{
SMeshPointer mesh;
mesh.pNode = pNode;
mesh.Asset = AssetID;
mesh.AABox = AABox;
mesh.Command = Command;
mTransparentBucket.Add(mesh);
SRenderablePtr ptr;
ptr.pRenderable = pRenderable;
ptr.Asset = AssetID;
ptr.AABox = AABox;
ptr.Command = Command;
mTransparentBucket.Add(ptr);
}
void CRenderer::BeginFrame()
@ -269,15 +304,12 @@ void CRenderer::BeginFrame()
glViewport(0, 0, mViewportWidth, mViewportHeight);
InitFramebuffer();
if (mOptions & eEnableBackfaceCull) glEnable(GL_CULL_FACE);
else glDisable(GL_CULL_FACE);
}
void CRenderer::EndFrame()
{
// Post-processing
if ((mBloomMode == eBloom) || (mBloomMode == eFakeBloom))
if (mBloomMode != eNoBloom)
RenderBloom();
// Render result to screen
@ -285,9 +317,7 @@ void CRenderer::EndFrame()
InitFramebuffer();
glViewport(0, 0, mViewportWidth, mViewportHeight);
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
CGraphics::sMVPBlock.ViewMatrix = CMatrix4f::skIdentity;
CGraphics::sMVPBlock.ProjectionMatrix = CMatrix4f::skIdentity;
CGraphics::SetIdentityMVP();
CGraphics::UpdateMVPBlock();
glDisable(GL_DEPTH_TEST);
@ -298,23 +328,6 @@ void CRenderer::EndFrame()
mSceneFramebuffer.Texture()->Bind(0);
CDrawUtil::DrawSquare();
if ((mBloomMode == eBloom) || (mBloomMode == eFakeBloom))
{
CDrawUtil::UseTextureShader();
glBlendFunc(GL_ONE, GL_ONE);
mBloomFramebuffers[2].Texture()->Bind(0);
CDrawUtil::DrawSquare();
}
else if (mBloomMode == eBloomMaps)
{
// Bloom maps are in the framebuffer alpha channel.
// White * dst alpha = bloom map colors
CDrawUtil::UseColorShader(CColor::skWhite);
glBlendFunc(GL_DST_ALPHA, GL_ZERO);
CDrawUtil::DrawSquare();
}
glEnable(GL_DEPTH_TEST);
gDrawCount = 0;
}

View File

@ -8,12 +8,12 @@
#include "CRenderBucket.h"
#include "ERenderOptions.h"
#include "ERenderCommand.h"
#include "SRenderablePtr.h"
#include <Common/CAABox.h>
#include <Common/CColor.h>
#include <Common/CMatrix4f.h>
#include <Common/types.h>
#include <OpenGL/CFramebuffer.h>
#include <OpenGL/SMeshPointer.h>
#include <Resource/CFont.h>
#include <Resource/CLight.h>
#include <Resource/CTexture.h>
@ -65,11 +65,11 @@ public:
void SetViewportSize(u32 Width, u32 Height);
// Render
void RenderScene(CCamera& Camera);
void RenderBuckets(CCamera& Camera);
void RenderBloom();
void RenderSky(CModel *pSkyboxModel, CVector3f CameraPosition);
void AddOpaqueMesh(CSceneNode *pNode, u32 AssetID, CAABox& AABox, ERenderCommand Command);
void AddTransparentMesh(CSceneNode *pNode, u32 AssetID, CAABox& AABox, ERenderCommand Command);
void AddOpaqueMesh(IRenderable *pRenderable, u32 AssetID, CAABox& AABox, ERenderCommand Command);
void AddTransparentMesh(IRenderable *pRenderable, u32 AssetID, CAABox& AABox, ERenderCommand Command);
void BeginFrame();
void EndFrame();

21
Core/IRenderable.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef IRENDERABLE_H
#define IRENDERABLE_H
#include "ERenderOptions.h"
#include <Common/CAABox.h>
#include <Common/types.h>
class CRenderer;
class IRenderable
{
public:
IRenderable() {}
virtual ~IRenderable() {}
virtual void AddToRenderer(CRenderer *pRenderer) = 0;
virtual void Draw(ERenderOptions options) = 0;
virtual void DrawAsset(ERenderOptions, u32) {}
virtual void DrawSelection() {}
};
#endif // IRENDERABLE_H

View File

@ -1,5 +1,5 @@
#ifndef SMESHPOINTER_H
#define SMESHPOINTER_H
#ifndef SRENDERABLEPTR_H
#define SRENDERABLEPTR_H
#include <Common/CAABox.h>
#include <Common/types.h>
@ -7,12 +7,12 @@
#include <Scene/CSceneNode.h>
#include <Resource/CMaterial.h>
struct SMeshPointer
struct SRenderablePtr
{
CSceneNode *pNode;
IRenderable *pRenderable;
u32 Asset;
CAABox AABox;
ERenderCommand Command;
};
#endif // SMESHPOINTER_H
#endif // SRENDERABLEPTR_H

View File

@ -71,9 +71,9 @@ void CDynamicVertexBuffer::ClearBuffers()
{
for (u32 iAttrib = 0; iAttrib < 12; iAttrib++)
{
u8 Bit = 1 << iAttrib;
int bit = 1 << iAttrib;
if (mBufferedFlags & Bit)
if (mBufferedFlags & bit)
glDeleteBuffers(1, &mAttribBuffers[iAttrib]);
}

View File

@ -159,7 +159,6 @@ HEADERS += \
OpenGL/CShaderGenerator.h \
OpenGL/CVertexBuffer.h \
OpenGL/GLCommon.h \
OpenGL/SMeshPointer.h \
UI/CWorldEditorWindow.h \
UI/PWEMaterialEditor.h \
UI/CStartWindow.h \
@ -282,7 +281,9 @@ HEADERS += \
UI/WScanPreviewPanel.h \
UI/WIntegralSpinBox.h \
UI/CAboutDialog.h \
UI/CGizmo.h
UI/CGizmo.h \
Core/IRenderable.h \
Core/SRenderablePtr.h
FORMS += \
UI/CWorldEditorWindow.ui \

View File

@ -120,7 +120,7 @@ void CMaterialPass::SetAnimCurrent(ERenderOptions Options, u32 PassIndex)
case eUVScroll: // Mode 2
{
if (Options & eUVScroll)
if (Options & eEnableUVScroll)
{
TexMtx[0][3] = (s * mAnimParams[2]) + mAnimParams[0];
TexMtx[1][3] = (s * mAnimParams[3]) + mAnimParams[1];
@ -130,7 +130,7 @@ void CMaterialPass::SetAnimCurrent(ERenderOptions Options, u32 PassIndex)
case eUVRotation: // Mode 3
{
if (Options & eUVScroll)
if (Options & eEnableUVScroll)
{
float Angle = (s * mAnimParams[1]) + mAnimParams[0];
@ -150,7 +150,7 @@ void CMaterialPass::SetAnimCurrent(ERenderOptions Options, u32 PassIndex)
case eHFilmstrip: // Mode 4
case eVFilmstrip: // Mode 5
{
if (Options & eUVScroll)
if (Options & eEnableUVScroll)
{
float Offset = mAnimParams[2] * mAnimParams[0] * (mAnimParams[3] + s);
Offset = (float)(short)(float)(mAnimParams[1] * fmod(Offset, 1.0f)) * mAnimParams[2];

View File

@ -1,6 +1,7 @@
#ifndef CSCENENODE_H
#define CSCENENODE_H
#include <Core/IRenderable.h>
#include "ENodeType.h"
#include <Common/CVector3f.h>
#include <Common/CQuaternion.h>
@ -16,7 +17,7 @@
class CRenderer;
class CSceneManager;
class CSceneNode
class CSceneNode : public IRenderable
{
private:
CTransform4f _mCachedTransform;
@ -50,9 +51,8 @@ public:
virtual ~CSceneNode();
virtual ENodeType NodeType() = 0;
virtual std::string PrefixedName() const;
virtual void AddToRenderer(CRenderer *pRenderer) = 0;
virtual void Draw(ERenderOptions Options) = 0;
virtual void DrawAsset(ERenderOptions Options, u32 Asset) = 0;
virtual void Draw(ERenderOptions options) = 0;
virtual void DrawAsset(ERenderOptions options, u32 asset) = 0;
virtual void DrawSelection();
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester);
virtual SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 AssetID) = 0;

View File

@ -587,7 +587,7 @@ void CModelEditorWindow::PaintViewport(CCamera& Camera)
{
CDrawUtil::DrawGrid();
mpCurrentModelNode->AddToRenderer(mpRenderer);
mpRenderer->RenderScene(Camera);
mpRenderer->RenderBuckets(Camera);
}
else if (mDrawMode == eDrawSphere)

View File

@ -281,7 +281,8 @@ void CWorldEditor::ViewportRender(CCamera& Camera)
if (pSky) mpRenderer->RenderSky(pSky, Camera.Position());
}
mpRenderer->RenderScene(Camera);
mpRenderer->RenderBuckets(Camera);
mpRenderer->RenderBloom();
mpRenderer->EndFrame();
mFrameTimer.Stop();
mFrameCount++;

View File

@ -98,7 +98,7 @@ void CWorldEditorWindow::PaintViewport(double DeltaTime)
if (pSky) mpRenderer->RenderSky(pSky, mCamera.Position());
}
mpRenderer->RenderScene(mCamera);
mpRenderer->RenderBuckets(mCamera);
mpRenderer->EndFrame();
}