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_colors.h"
#include "lc_mainwindow.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() lcContext::lcContext()
{ {
mVertexBufferObject = 0; mVertexBufferObject = 0;

View file

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

View file

@ -63,7 +63,7 @@ class lcMesh;
struct lcMeshSection; struct lcMeshSection;
struct lcRenderMesh; struct lcRenderMesh;
class lcTexture; class lcTexture;
struct lcScene; class lcScene;
class lcFile; class lcFile;
class lcMemFile; 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) 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]); lcMatrix44 Result;
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]);
lcVector4 Ret0(lcDot(a.r[0], Col0), lcDot(a.r[0], Col1), lcDot(a.r[0], Col2), lcDot(a.r[0], 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;
lcVector4 Ret1(lcDot(a.r[1], Col0), lcDot(a.r[1], Col1), lcDot(a.r[1], Col2), lcDot(a.r[1], Col3)); 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;
lcVector4 Ret2(lcDot(a.r[2], Col0), lcDot(a.r[2], Col1), lcDot(a.r[2], Col2), lcDot(a.r[2], Col3)); 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;
lcVector4 Ret3(lcDot(a.r[3], Col0), lcDot(a.r[3], Col1), lcDot(a.r[3], Col2), lcDot(a.r[3], Col3)); 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) inline lcMatrix33::lcMatrix33(const lcMatrix44& Matrix)

View file

@ -362,19 +362,3 @@ void lcMesh::FileSave(lcFile& File)
else else
File.WriteU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4); 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; lcMatrix44 WorldMatrix;
lcMesh* Mesh; lcMesh* Mesh;
int ColorIndex;
float Distance; float Distance;
int ColorIndex;
bool Focused; bool Focused;
bool Selected; bool Selected;
}; };
int lcTranslucentRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b);
int lcOpaqueRenderMeshCompare(const lcRenderMesh& a, const lcRenderMesh& b);
extern lcMesh* gPlaceholderMesh; extern lcMesh* gPlaceholderMesh;
#endif // _LC_MESH_H_ #endif // _LC_MESH_H_

View file

@ -875,12 +875,7 @@ void lcModel::Paste()
void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const
{ {
Scene.ViewMatrix = ViewCamera->mWorldView; Scene.Begin(ViewCamera->mWorldView);
Scene.OpaqueMeshes.RemoveAll();
Scene.OpaqueMeshes.AllocGrow(mPieces.GetSize());
Scene.TranslucentMeshes.RemoveAll();
Scene.TranslucentMeshes.AllocGrow(mPieces.GetSize());
Scene.InterfaceObjects.RemoveAll();
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) 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); Info->AddRenderMeshes(Scene, Piece->mModelWorld, Piece->mColorIndex, Focused, Selected);
if (Selected) if (Selected)
Scene.InterfaceObjects.Add(Piece); Scene.mInterfaceObjects.Add(Piece);
} }
if (DrawInterface) if (DrawInterface)
@ -916,7 +911,7 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface)
lcCamera* Camera = mCameras[CameraIdx]; lcCamera* Camera = mCameras[CameraIdx];
if (Camera != ViewCamera && Camera->IsVisible()) if (Camera != ViewCamera && Camera->IsVisible())
Scene.InterfaceObjects.Add(Camera); Scene.mInterfaceObjects.Add(Camera);
} }
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++) 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]; lcLight* Light = mLights[LightIdx];
if (Light->IsVisible()) if (Light->IsVisible())
Scene.InterfaceObjects.Add(Light); Scene.mInterfaceObjects.Add(Light);
} }
} }
Scene.OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare); Scene.End();
Scene.TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
} }
void lcModel::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const 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(); Calculate();
lcArray<lcRenderMesh> OpaqueMeshes(LC_MFW_NUMITEMS); lcScene Scene;
lcArray<lcRenderMesh> TranslucentMeshes; Scene.Begin(ViewMatrix);
for (int PieceIdx = 0; PieceIdx < LC_MFW_NUMITEMS; PieceIdx++) for (int PieceIdx = 0; PieceIdx < LC_MFW_NUMITEMS; PieceIdx++)
if (mMinifig->Parts[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); Scene.End();
mContext->DrawOpaqueMeshes(ViewMatrix, OpaqueMeshes);
TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare); mContext->DrawOpaqueMeshes(ViewMatrix, Scene.mOpaqueMeshes);
mContext->DrawTranslucentMeshes(ViewMatrix, TranslucentMeshes); mContext->DrawTranslucentMeshes(ViewMatrix, Scene.mTranslucentMeshes);
mContext->UnbindMesh(); // context remove
} }
void MinifigWizard::OnLeftButtonDown() void MinifigWizard::OnLeftButtonDown()

View file

@ -255,40 +255,15 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i
bool Translucent = lcIsColorTranslucent(ColorIndex); bool Translucent = lcIsColorTranslucent(ColorIndex);
if ((mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent)) 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)) 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]; RenderMesh.Distance = Pos[2];
Scene.TranslucentMeshes.Add(RenderMesh); Scene.mTranslucentMeshes.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);
} }
} }

View file

@ -107,7 +107,6 @@ public:
void ZoomExtents(const lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix, float* EyePos = NULL) const; 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(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); void CreatePlaceholder(const char* Name);

View file

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

View file

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

View file

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

View file

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