From c670893deba2e747ff3a227083ba78278dc9022c Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 8 Feb 2015 18:54:51 +0000 Subject: [PATCH] Rendering optimizations. --- common/lc_context.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ common/lc_context.h | 16 ++++++++++----- common/lc_global.h | 2 +- common/lc_math.h | 15 ++++++-------- common/lc_mesh.cpp | 16 --------------- common/lc_mesh.h | 5 +---- common/lc_model.cpp | 16 +++++---------- common/minifig.cpp | 15 +++++++------- common/pieceinf.cpp | 31 +++-------------------------- common/pieceinf.h | 1 - common/preview.cpp | 9 ++++----- common/project.cpp | 9 ++++----- common/view.cpp | 11 +++++------ common/view.h | 1 + 14 files changed, 95 insertions(+), 98 deletions(-) diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 8aa9dcfd..67bd6776 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -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; diff --git a/common/lc_context.h b/common/lc_context.h index 4f3c38c0..f27a04f3 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -4,12 +4,18 @@ #include "lc_array.h" #include "lc_math.h" -struct lcScene +class lcScene { - lcMatrix44 ViewMatrix; - lcArray OpaqueMeshes; - lcArray TranslucentMeshes; - lcArray InterfaceObjects; +public: + lcScene(); + + void Begin(const lcMatrix44& ViewMatrix); + void End(); + + lcMatrix44 mViewMatrix; + lcArray mOpaqueMeshes; + lcArray mTranslucentMeshes; + lcArray mInterfaceObjects; }; class lcContext diff --git a/common/lc_global.h b/common/lc_global.h index 3e02ba4b..32f52dac 100644 --- a/common/lc_global.h +++ b/common/lc_global.h @@ -63,7 +63,7 @@ class lcMesh; struct lcMeshSection; struct lcRenderMesh; class lcTexture; -struct lcScene; +class lcScene; class lcFile; class lcMemFile; diff --git a/common/lc_math.h b/common/lc_math.h index c367a438..0c36557a 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -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) diff --git a/common/lc_mesh.cpp b/common/lc_mesh.cpp index 0279dd7b..e37d3c7e 100644 --- a/common/lc_mesh.cpp +++ b/common/lc_mesh.cpp @@ -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; -} diff --git a/common/lc_mesh.h b/common/lc_mesh.h index 8d9e5fe8..81488d7d 100644 --- a/common/lc_mesh.h +++ b/common/lc_mesh.h @@ -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_ diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 568c3c51..5580eddb 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -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 diff --git a/common/minifig.cpp b/common/minifig.cpp index e2678035..8431c9c9 100644 --- a/common/minifig.cpp +++ b/common/minifig.cpp @@ -1140,18 +1140,19 @@ void MinifigWizard::OnDraw() Calculate(); - lcArray OpaqueMeshes(LC_MFW_NUMITEMS); - lcArray 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() diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 8c5ff5f0..5ee6b83e 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -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& OpaqueMeshes, lcArray& 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); } } diff --git a/common/pieceinf.h b/common/pieceinf.h index 432e1a41..2f4d4132 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -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& OpaqueMeshes, lcArray& TranslucentMeshes); void CreatePlaceholder(const char* Name); diff --git a/common/preview.cpp b/common/preview.cpp index f5ef9a9c..f7414d36 100644 --- a/common/preview.cpp +++ b/common/preview.cpp @@ -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 } diff --git a/common/project.cpp b/common/project.cpp index 55d8f639..914b3390 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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 diff --git a/common/view.cpp b/common/view.cpp index a4c7ca0a..a5328313 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -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 diff --git a/common/view.h b/common/view.h index 05263e1d..8efe0375 100644 --- a/common/view.h +++ b/common/view.h @@ -129,6 +129,7 @@ protected: void StartTracking(lcTrackButton TrackButton); void StopTracking(bool Accept); + lcScene mScene; lcDragState mDragState; lcTrackButton mTrackButton; lcTrackTool mTrackTool;