Rendering optimizations.

This commit is contained in:
leo 2015-02-08 18:54:51 +00:00
parent beec734524
commit c670893deb
14 changed files with 95 additions and 98 deletions

View file

@ -5,6 +5,52 @@
#include "lc_colors.h"
#include "lc_mainwindow.h"
static int lcOpaqueRenderMeshCompare(const void* Elem1, const void* Elem2)
{
lcRenderMesh* Mesh1 = (lcRenderMesh*)Elem1;
lcRenderMesh* Mesh2 = (lcRenderMesh*)Elem2;
if (Mesh1->Mesh < Mesh2->Mesh)
return -1;
if (Mesh1->Mesh > Mesh2->Mesh)
return 1;
return 0;
}
static int lcTranslucentRenderMeshCompare(const void* Elem1, const void* Elem2)
{
lcRenderMesh* Mesh1 = (lcRenderMesh*)Elem1;
lcRenderMesh* Mesh2 = (lcRenderMesh*)Elem2;
if (Mesh1->Distance < Mesh2->Distance)
return -1;
if (Mesh1->Distance > Mesh2->Distance)
return 1;
return 0;
}
lcScene::lcScene()
: mOpaqueMeshes(0, 1024), mTranslucentMeshes(0, 1024), mInterfaceObjects(0, 1024)
{
}
void lcScene::Begin(const lcMatrix44& ViewMatrix)
{
mOpaqueMeshes.RemoveAll();
mTranslucentMeshes.RemoveAll();
mInterfaceObjects.RemoveAll();
}
void lcScene::End()
{
qsort(&mOpaqueMeshes[0], mOpaqueMeshes.GetSize(), sizeof(mOpaqueMeshes[0]), lcOpaqueRenderMeshCompare);
qsort(&mTranslucentMeshes[0], mTranslucentMeshes.GetSize(), sizeof(mTranslucentMeshes[0]), lcTranslucentRenderMeshCompare);
}
lcContext::lcContext()
{
mVertexBufferObject = 0;

View file

@ -4,12 +4,18 @@
#include "lc_array.h"
#include "lc_math.h"
struct lcScene
class lcScene
{
lcMatrix44 ViewMatrix;
lcArray<lcRenderMesh> OpaqueMeshes;
lcArray<lcRenderMesh> TranslucentMeshes;
lcArray<lcObject*> InterfaceObjects;
public:
lcScene();
void Begin(const lcMatrix44& ViewMatrix);
void End();
lcMatrix44 mViewMatrix;
lcArray<lcRenderMesh> mOpaqueMeshes;
lcArray<lcRenderMesh> mTranslucentMeshes;
lcArray<lcObject*> mInterfaceObjects;
};
class lcContext

View file

@ -63,7 +63,7 @@ class lcMesh;
struct lcMeshSection;
struct lcRenderMesh;
class lcTexture;
struct lcScene;
class lcScene;
class lcFile;
class lcMemFile;

View file

@ -576,17 +576,14 @@ inline lcMatrix33 lcMul(const lcMatrix33& a, const lcMatrix33& b)
inline lcMatrix44 lcMul(const lcMatrix44& a, const lcMatrix44& b)
{
lcVector4 Col0(b.r[0][0], b.r[1][0], b.r[2][0], b.r[3][0]);
lcVector4 Col1(b.r[0][1], b.r[1][1], b.r[2][1], b.r[3][1]);
lcVector4 Col2(b.r[0][2], b.r[1][2], b.r[2][2], b.r[3][2]);
lcVector4 Col3(b.r[0][3], b.r[1][3], b.r[2][3], b.r[3][3]);
lcMatrix44 Result;
lcVector4 Ret0(lcDot(a.r[0], Col0), lcDot(a.r[0], Col1), lcDot(a.r[0], Col2), lcDot(a.r[0], Col3));
lcVector4 Ret1(lcDot(a.r[1], Col0), lcDot(a.r[1], Col1), lcDot(a.r[1], Col2), lcDot(a.r[1], Col3));
lcVector4 Ret2(lcDot(a.r[2], Col0), lcDot(a.r[2], Col1), lcDot(a.r[2], Col2), lcDot(a.r[2], Col3));
lcVector4 Ret3(lcDot(a.r[3], Col0), lcDot(a.r[3], Col1), lcDot(a.r[3], Col2), lcDot(a.r[3], Col3));
Result.r[0] = b.r[0] * a[0].x + b.r[1] * a[0].y + b.r[2] * a[0].z + b.r[3] * a[0].w;
Result.r[1] = b.r[0] * a[1].x + b.r[1] * a[1].y + b.r[2] * a[1].z + b.r[3] * a[1].w;
Result.r[2] = b.r[0] * a[2].x + b.r[1] * a[2].y + b.r[2] * a[2].z + b.r[3] * a[2].w;
Result.r[3] = b.r[0] * a[3].x + b.r[1] * a[3].y + b.r[2] * a[3].z + b.r[3] * a[3].w;
return lcMatrix44(Ret0, Ret1, Ret2, Ret3);
return Result;
}
inline lcMatrix33::lcMatrix33(const lcMatrix44& Matrix)

View file

@ -362,19 +362,3 @@ void lcMesh::FileSave(lcFile& File)
else
File.WriteU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
}
int lcTranslucentRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b)
{
if (a.Distance > b.Distance)
return 1;
else
return -1;
}
int lcOpaqueRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b)
{
if (a.Mesh > b.Mesh)
return 1;
else
return -1;
}

View file

@ -169,15 +169,12 @@ struct lcRenderMesh
{
lcMatrix44 WorldMatrix;
lcMesh* Mesh;
int ColorIndex;
float Distance;
int ColorIndex;
bool Focused;
bool Selected;
};
int lcTranslucentRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b);
int lcOpaqueRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b);
extern lcMesh* gPlaceholderMesh;
#endif // _LC_MESH_H_

View file

@ -875,12 +875,7 @@ void lcModel::Paste()
void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const
{
Scene.ViewMatrix = ViewCamera->mWorldView;
Scene.OpaqueMeshes.RemoveAll();
Scene.OpaqueMeshes.AllocGrow(mPieces.GetSize());
Scene.TranslucentMeshes.RemoveAll();
Scene.TranslucentMeshes.AllocGrow(mPieces.GetSize());
Scene.InterfaceObjects.RemoveAll();
Scene.Begin(ViewCamera->mWorldView);
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
@ -906,7 +901,7 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface)
Info->AddRenderMeshes(Scene, Piece->mModelWorld, Piece->mColorIndex, Focused, Selected);
if (Selected)
Scene.InterfaceObjects.Add(Piece);
Scene.mInterfaceObjects.Add(Piece);
}
if (DrawInterface)
@ -916,7 +911,7 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface)
lcCamera* Camera = mCameras[CameraIdx];
if (Camera != ViewCamera && Camera->IsVisible())
Scene.InterfaceObjects.Add(Camera);
Scene.mInterfaceObjects.Add(Camera);
}
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
@ -924,12 +919,11 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface)
lcLight* Light = mLights[LightIdx];
if (Light->IsVisible())
Scene.InterfaceObjects.Add(Light);
Scene.mInterfaceObjects.Add(Light);
}
}
Scene.OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare);
Scene.TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
Scene.End();
}
void lcModel::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const

View file

@ -1140,18 +1140,19 @@ void MinifigWizard::OnDraw()
Calculate();
lcArray<lcRenderMesh> OpaqueMeshes(LC_MFW_NUMITEMS);
lcArray<lcRenderMesh> TranslucentMeshes;
lcScene Scene;
Scene.Begin(ViewMatrix);
for (int PieceIdx = 0; PieceIdx < LC_MFW_NUMITEMS; PieceIdx++)
if (mMinifig->Parts[PieceIdx])
mMinifig->Parts[PieceIdx]->AddRenderMeshes(ViewMatrix, mMinifig->Matrices[PieceIdx], mMinifig->Colors[PieceIdx], false, false, OpaqueMeshes, TranslucentMeshes);
mMinifig->Parts[PieceIdx]->AddRenderMeshes(Scene, mMinifig->Matrices[PieceIdx], mMinifig->Colors[PieceIdx], false, false);
OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare);
mContext->DrawOpaqueMeshes(ViewMatrix, OpaqueMeshes);
Scene.End();
TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
mContext->DrawTranslucentMeshes(ViewMatrix, TranslucentMeshes);
mContext->DrawOpaqueMeshes(ViewMatrix, Scene.mOpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, Scene.mTranslucentMeshes);
mContext->UnbindMesh(); // context remove
}
void MinifigWizard::OnLeftButtonDown()

View file

@ -255,40 +255,15 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i
bool Translucent = lcIsColorTranslucent(ColorIndex);
if ((mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent))
Scene.OpaqueMeshes.Add(RenderMesh);
Scene.mOpaqueMeshes.Add(RenderMesh);
if ((mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
{
lcVector3 Pos = lcMul31(WorldMatrix[3], Scene.ViewMatrix);
lcVector3 Pos = lcMul31(WorldMatrix[3], Scene.mViewMatrix);
RenderMesh.Distance = Pos[2];
Scene.TranslucentMeshes.Add(RenderMesh);
}
}
void PieceInfo::AddRenderMeshes(const lcMatrix44& ViewMatrix, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, lcArray<lcRenderMesh>& OpaqueMeshes, lcArray<lcRenderMesh>& TranslucentMeshes)
{
lcRenderMesh RenderMesh;
RenderMesh.WorldMatrix = WorldMatrix;
RenderMesh.Mesh = (mFlags & LC_PIECE_PLACEHOLDER) ? gPlaceholderMesh : mMesh;
RenderMesh.ColorIndex = ColorIndex;
RenderMesh.Focused = Focused;
RenderMesh.Selected = Selected;
bool Translucent = lcIsColorTranslucent(ColorIndex);
if ((mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent))
OpaqueMeshes.Add(RenderMesh);
if ((mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
{
lcVector3 Pos = lcMul31(WorldMatrix[3], ViewMatrix);
RenderMesh.Distance = Pos[2];
TranslucentMeshes.Add(RenderMesh);
Scene.mTranslucentMeshes.Add(RenderMesh);
}
}

View file

@ -107,7 +107,6 @@ public:
void ZoomExtents(const lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix, float* EyePos = NULL) const;
void AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected);
void AddRenderMeshes(const lcMatrix44& ViewMatrix, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, lcArray<lcRenderMesh>& OpaqueMeshes, lcArray<lcRenderMesh>& TranslucentMeshes);
void CreatePlaceholder(const char* Name);

View file

@ -60,15 +60,14 @@ void PiecePreview::OnDraw()
mContext->SetProjectionMatrix(ProjectionMatrix);
lcScene Scene;
Scene.ViewMatrix = ViewMatrix;
Scene.Begin(ViewMatrix);
m_PieceInfo->AddRenderMeshes(Scene, lcMatrix44Identity(), gMainWindow->mColorIndex, false, false);
Scene.OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare);
Scene.TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
Scene.End();
mContext->DrawOpaqueMeshes(ViewMatrix, Scene.OpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, Scene.TranslucentMeshes);
mContext->DrawOpaqueMeshes(ViewMatrix, Scene.mOpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, Scene.mTranslucentMeshes);
mContext->UnbindMesh(); // context remove
}

View file

@ -1218,15 +1218,14 @@ void Project::ExportHTML()
Info->ZoomExtents(ProjectionMatrix, ViewMatrix, CameraPosition);
lcScene Scene;
Scene.ViewMatrix = ViewMatrix;
Scene.Begin(ViewMatrix);
Info->AddRenderMeshes(Scene, lcMatrix44Identity(), Options.PartImagesColor, false, false);
Scene.OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare);
Scene.TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
Scene.End();
Context->DrawOpaqueMeshes(ViewMatrix, Scene.OpaqueMeshes);
Context->DrawTranslucentMeshes(ViewMatrix, Scene.TranslucentMeshes);
Context->DrawOpaqueMeshes(ViewMatrix, Scene.mOpaqueMeshes);
Context->DrawTranslucentMeshes(ViewMatrix, Scene.mTranslucentMeshes);
Context->UnbindMesh(); // context remove

View file

@ -350,15 +350,14 @@ void View::OnDraw()
{
bool DrawInterface = mWidget != NULL;
lcScene Scene;
mModel->GetScene(Scene, mCamera, DrawInterface);
mModel->GetScene(mScene, mCamera, DrawInterface);
if (DrawInterface && mTrackTool == LC_TRACKTOOL_INSERT)
{
PieceInfo* Info = gMainWindow->mPreviewWidget->GetCurrentPiece();
if (Info)
Info->AddRenderMeshes(Scene, GetPieceInsertPosition(), gMainWindow->mColorIndex, true, true);
Info->AddRenderMeshes(mScene, GetPieceInsertPosition(), gMainWindow->mColorIndex, true, true);
}
mContext->SetDefaultState();
@ -405,8 +404,8 @@ void View::OnDraw()
}
const lcMatrix44& ViewMatrix = mCamera->mWorldView;
mContext->DrawOpaqueMeshes(ViewMatrix, Scene.OpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, Scene.TranslucentMeshes);
mContext->DrawOpaqueMeshes(ViewMatrix, mScene.mOpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, mScene.mTranslucentMeshes);
mContext->UnbindMesh(); // context remove
@ -422,7 +421,7 @@ void View::OnDraw()
if (DrawInterface)
{
mContext->DrawInterfaceObjects(ViewMatrix, Scene.InterfaceObjects);
mContext->DrawInterfaceObjects(ViewMatrix, mScene.mInterfaceObjects);
mContext->SetLineWidth(Preferences.mLineWidth); // context remove

View file

@ -129,6 +129,7 @@ protected:
void StartTracking(lcTrackButton TrackButton);
void StopTracking(bool Accept);
lcScene mScene;
lcDragState mDragState;
lcTrackButton mTrackButton;
lcTrackTool mTrackTool;