Use a single vertex buffer for all pieces.

This commit is contained in:
leo 2015-04-26 18:14:33 +00:00
parent 2063514f2f
commit aa861cd036
14 changed files with 289 additions and 178 deletions

View file

@ -4,6 +4,7 @@
#include "lc_texture.h" #include "lc_texture.h"
#include "lc_colors.h" #include "lc_colors.h"
#include "lc_mainwindow.h" #include "lc_mainwindow.h"
#include "lc_library.h"
static int lcOpaqueRenderMeshCompare(const void* Elem1, const void* Elem2) static int lcOpaqueRenderMeshCompare(const void* Elem1, const void* Elem2)
{ {
@ -300,6 +301,94 @@ bool lcContext::SaveRenderToTextureImage(const QString& FileName, int Width, int
return Result; return Result;
} }
lcVertexBuffer lcContext::CreateVertexBuffer(int Size, void* Data)
{
if (GL_HasVertexBufferObject())
{
lcVertexBuffer VertexBuffer;
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER_ARB, Size, Data, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); // context remove
mVertexBufferObject = 0;
return VertexBuffer;
}
else
{
void* VertexBuffer = malloc(Size);
memcpy(VertexBuffer, Data, Size);
return (lcVertexBuffer)VertexBuffer;
}
}
void lcContext::DestroyVertexBuffer(lcVertexBuffer& VertexBuffer)
{
if (!VertexBuffer)
return;
if (GL_HasVertexBufferObject())
{
if (mVertexBufferObject == VertexBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
mVertexBufferObject = 0;
}
glDeleteBuffers(1, &VertexBuffer);
}
else
{
free((void*)VertexBuffer);
}
}
lcIndexBuffer lcContext::CreateIndexBuffer(int Size, void* Data)
{
if (GL_HasVertexBufferObject())
{
lcIndexBuffer IndexBuffer;
glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB, Size, Data, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); // context remove
mIndexBufferObject = 0;
return IndexBuffer;
}
else
{
void* IndexBuffer = malloc(Size);
memcpy(IndexBuffer, Data, Size);
return (lcIndexBuffer)IndexBuffer;
}
}
void lcContext::DestroyIndexBuffer(lcIndexBuffer& IndexBuffer)
{
if (!IndexBuffer)
return;
if (GL_HasVertexBufferObject())
{
if (mIndexBufferObject == IndexBuffer)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
mIndexBufferObject = 0;
}
glDeleteBuffers(1, &IndexBuffer);
}
else
{
free((void*)IndexBuffer);
}
}
void lcContext::ClearVertexBuffer() void lcContext::ClearVertexBuffer()
{ {
mVertexBufferPointer = NULL; mVertexBufferPointer = NULL;
@ -318,11 +407,11 @@ void lcContext::ClearVertexBuffer()
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
} }
void lcContext::SetVertexBuffer(const lcVertexBuffer* VertexBuffer) void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer)
{ {
if (GL_HasVertexBufferObject()) if (GL_HasVertexBufferObject())
{ {
GLuint VertexBufferObject = VertexBuffer->mBuffer; GLuint VertexBufferObject = VertexBuffer;
mVertexBufferPointer = NULL; mVertexBufferPointer = NULL;
if (VertexBufferObject != mVertexBufferObject) if (VertexBufferObject != mVertexBufferObject)
@ -334,7 +423,7 @@ void lcContext::SetVertexBuffer(const lcVertexBuffer* VertexBuffer)
} }
else else
{ {
mVertexBufferPointer = (char*)VertexBuffer->mData; mVertexBufferPointer = (char*)VertexBuffer;
mVertexBufferOffset = (char*)~0; mVertexBufferOffset = (char*)~0;
} }
} }
@ -397,12 +486,14 @@ void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int TexCoord
void lcContext::BindMesh(lcMesh* Mesh) void lcContext::BindMesh(lcMesh* Mesh)
{ {
if (GL_HasVertexBufferObject()) lcPiecesLibrary* Library = lcGetPiecesLibrary();
if (Mesh->mVertexCacheOffset != -1)
{ {
GLuint VertexBufferObject = Mesh->mVertexBuffer.mBuffer; GLuint VertexBufferObject = Library->mVertexBuffer;
mVertexBufferPointer = NULL; mVertexBufferPointer = (char*)Mesh->mVertexCacheOffset;
GLuint IndexBufferObject = Mesh->mIndexBuffer.mBuffer; GLuint IndexBufferObject = Library->mIndexBuffer;
mIndexBufferPointer = NULL; mIndexBufferPointer = (char*)Mesh->mIndexCacheOffset;
if (VertexBufferObject != mVertexBufferObject) if (VertexBufferObject != mVertexBufferObject)
{ {
@ -419,8 +510,20 @@ void lcContext::BindMesh(lcMesh* Mesh)
} }
else else
{ {
mVertexBufferPointer = (char*)Mesh->mVertexBuffer.mData; if (mVertexBufferObject)
mIndexBufferPointer = (char*)Mesh->mIndexBuffer.mData; {
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
mVertexBufferObject = 0;
}
if (mIndexBufferObject)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
mIndexBufferObject = 0;
}
mVertexBufferPointer = (char*)Mesh->mVertexData;
mIndexBufferPointer = (char*)Mesh->mIndexData;
mVertexBufferOffset = (char*)~0; mVertexBufferOffset = (char*)~0;
} }
} }
@ -508,6 +611,8 @@ void lcContext::DrawOpaqueMeshes(const lcMatrix44& ViewMatrix, const lcArray<lcR
{ {
bool DrawLines = lcGetPreferences().mDrawEdgeLines; bool DrawLines = lcGetPreferences().mDrawEdgeLines;
lcGetPiecesLibrary()->UpdateBuffers(this); // TODO: find a better place for this update
for (int MeshIdx = 0; MeshIdx < OpaqueMeshes.GetSize(); MeshIdx++) for (int MeshIdx = 0; MeshIdx < OpaqueMeshes.GetSize(); MeshIdx++)
{ {
lcRenderMesh& RenderMesh = OpaqueMeshes[MeshIdx]; lcRenderMesh& RenderMesh = OpaqueMeshes[MeshIdx];

View file

@ -18,6 +18,12 @@ public:
lcArray<lcObject*> mInterfaceObjects; lcArray<lcObject*> mInterfaceObjects;
}; };
typedef quintptr lcVertexBuffer;
typedef quintptr lcIndexBuffer;
#define LC_INVALID_VERTEX_BUFFER 0
#define LC_INVALID_INDEX_BUFFER 0
class lcContext class lcContext
{ {
public: public:
@ -46,13 +52,17 @@ public:
void EndRenderToTexture(); void EndRenderToTexture();
bool SaveRenderToTextureImage(const QString& FileName, int Width, int Height); bool SaveRenderToTextureImage(const QString& FileName, int Width, int Height);
lcVertexBuffer CreateVertexBuffer(int Size, void* Data);
void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer);
lcIndexBuffer CreateIndexBuffer(int Size, void* Data);
void DestroyIndexBuffer(lcIndexBuffer& IndexBuffer);
void ClearVertexBuffer(); void ClearVertexBuffer();
void SetVertexBuffer(const lcVertexBuffer* VertexBuffer); void SetVertexBuffer(lcVertexBuffer VertexBuffer);
void SetVertexBufferPointer(const void* VertexBuffer); void SetVertexBufferPointer(const void* VertexBuffer);
void SetVertexFormat(int BufferOffset, int PositionSize, int TexCoordSize, int ColorSize); void SetVertexFormat(int BufferOffset, int PositionSize, int TexCoordSize, int ColorSize);
void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count); void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count);
void BindMesh(lcMesh* Mesh);
void UnbindMesh(); void UnbindMesh();
void DrawMeshSection(lcMesh* Mesh, lcMeshSection* Section); void DrawMeshSection(lcMesh* Mesh, lcMeshSection* Section);
void DrawOpaqueMeshes(const lcMatrix44& ViewMatrix, const lcArray<lcRenderMesh>& OpaqueMeshes); void DrawOpaqueMeshes(const lcMatrix44& ViewMatrix, const lcArray<lcRenderMesh>& OpaqueMeshes);
@ -60,6 +70,8 @@ public:
void DrawInterfaceObjects(const lcMatrix44& ViewMatrix, const lcArray<lcObject*>& InterfaceObjects); void DrawInterfaceObjects(const lcMatrix44& ViewMatrix, const lcArray<lcObject*>& InterfaceObjects);
protected: protected:
void BindMesh(lcMesh* Mesh);
GLuint mVertexBufferObject; GLuint mVertexBufferObject;
GLuint mIndexBufferObject; GLuint mIndexBufferObject;
char* mVertexBufferPointer; char* mVertexBufferPointer;

View file

@ -60,8 +60,6 @@ class lcMatrix33;
class lcMatrix44; class lcMatrix44;
class lcContext; class lcContext;
class lcVertexBuffer;
class lcIndexBuffer;
class lcMesh; class lcMesh;
struct lcMeshSection; struct lcMeshSection;
struct lcRenderMesh; struct lcRenderMesh;

View file

@ -8,6 +8,7 @@
#include "lc_category.h" #include "lc_category.h"
#include "lc_application.h" #include "lc_application.h"
#include "lc_mainwindow.h" #include "lc_mainwindow.h"
#include "lc_context.h"
#include "project.h" #include "project.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -31,6 +32,9 @@ lcPiecesLibrary::lcPiecesLibrary()
mCacheFile = NULL; mCacheFile = NULL;
mCacheFileName[0] = 0; mCacheFileName[0] = 0;
mSaveCache = false; mSaveCache = false;
mBuffersDirty = false;
mVertexBuffer = LC_INVALID_VERTEX_BUFFER;
mIndexBuffer = LC_INVALID_INDEX_BUFFER;
} }
lcPiecesLibrary::~lcPiecesLibrary() lcPiecesLibrary::~lcPiecesLibrary()
@ -919,7 +923,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
Mesh->Create(MeshData.mSections.GetSize(), MeshData.mVertices.GetSize(), MeshData.mTexturedVertices.GetSize(), NumIndices); Mesh->Create(MeshData.mSections.GetSize(), MeshData.mVertices.GetSize(), MeshData.mTexturedVertices.GetSize(), NumIndices);
lcVertex* DstVerts = (lcVertex*)Mesh->mVertexBuffer.mData; lcVertex* DstVerts = (lcVertex*)Mesh->mVertexData;
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
for (int VertexIdx = 0; VertexIdx < MeshData.mVertices.GetSize(); VertexIdx++) for (int VertexIdx = 0; VertexIdx < MeshData.mVertices.GetSize(); VertexIdx++)
@ -986,7 +990,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
{ {
DstSection.IndexOffset = NumIndices * 2; DstSection.IndexOffset = NumIndices * 2;
lcuint16* Index = (lcuint16*)Mesh->mIndexBuffer.mData + NumIndices; lcuint16* Index = (lcuint16*)Mesh->mIndexData + NumIndices;
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++) for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
*Index++ = SrcSection->mIndices[IndexIdx]; *Index++ = SrcSection->mIndices[IndexIdx];
@ -995,7 +999,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
{ {
DstSection.IndexOffset = NumIndices * 4; DstSection.IndexOffset = NumIndices * 4;
lcuint32* Index = (lcuint32*)Mesh->mIndexBuffer.mData + NumIndices; lcuint32* Index = (lcuint32*)Mesh->mIndexData + NumIndices;
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++) for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
*Index++ = SrcSection->mIndices[IndexIdx]; *Index++ = SrcSection->mIndices[IndexIdx];
@ -1019,10 +1023,75 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
NumIndices += DstSection.NumIndices; NumIndices += DstSection.NumIndices;
} }
Mesh->UpdateBuffers();
Info->SetMesh(Mesh); Info->SetMesh(Mesh);
} }
void lcPiecesLibrary::UpdateBuffers(lcContext* Context)
{
if (!GL_HasVertexBufferObject() || !mBuffersDirty)
return;
int VertexDataSize = 0;
int IndexDataSize = 0;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
if (Info->IsModel())
continue;
lcMesh* Mesh = Info->IsTemporary() ? gPlaceholderMesh : Info->GetMesh();
if (!Mesh)
continue;
VertexDataSize += Mesh->mVertexDataSize;
IndexDataSize += Mesh->mIndexDataSize;
}
Context->DestroyVertexBuffer(mVertexBuffer);
Context->DestroyIndexBuffer(mIndexBuffer);
if (!VertexDataSize || !IndexDataSize)
return;
void* VertexData = malloc(VertexDataSize);
void* IndexData = malloc(IndexDataSize);
VertexDataSize = 0;
IndexDataSize = 0;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
if (Info->IsModel())
continue;
lcMesh* Mesh = Info->IsTemporary() ? gPlaceholderMesh : Info->GetMesh();
if (!Mesh)
continue;
Mesh->mVertexCacheOffset = VertexDataSize;
Mesh->mIndexCacheOffset = IndexDataSize;
memcpy((char*)VertexData + VertexDataSize, Mesh->mVertexData, Mesh->mVertexDataSize);
memcpy((char*)IndexData + IndexDataSize, Mesh->mIndexData, Mesh->mIndexDataSize);
VertexDataSize += Mesh->mVertexDataSize;
IndexDataSize += Mesh->mIndexDataSize;
}
mVertexBuffer = Context->CreateVertexBuffer(VertexDataSize, VertexData);
mIndexBuffer = Context->CreateIndexBuffer(IndexDataSize, IndexData);
mBuffersDirty = false;
free(VertexData);
free(IndexData);
}
bool lcPiecesLibrary::LoadTexture(lcTexture* Texture) bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
{ {
char Name[LC_MAXPATH], FileName[LC_MAXPATH]; char Name[LC_MAXPATH], FileName[LC_MAXPATH];

View file

@ -1,6 +1,7 @@
#ifndef _LC_LIBRARY_H_ #ifndef _LC_LIBRARY_H_
#define _LC_LIBRARY_H_ #define _LC_LIBRARY_H_
#include "lc_context.h"
#include "lc_mesh.h" #include "lc_mesh.h"
#include "lc_math.h" #include "lc_math.h"
#include "lc_array.h" #include "lc_array.h"
@ -150,6 +151,7 @@ public:
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData); bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData);
void CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData); void CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
void UpdateBuffers(lcContext* Context);
lcArray<PieceInfo*> mPieces; lcArray<PieceInfo*> mPieces;
lcArray<lcLibraryPrimitive*> mPrimitives; lcArray<lcLibraryPrimitive*> mPrimitives;
@ -159,6 +161,10 @@ public:
char mLibraryPath[LC_MAXPATH]; char mLibraryPath[LC_MAXPATH];
bool mBuffersDirty;
lcVertexBuffer mVertexBuffer;
lcIndexBuffer mIndexBuffer;
protected: protected:
bool OpenArchive(const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(const char* FileName, lcZipFileType ZipFileType);
bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType);

View file

@ -2001,27 +2001,27 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
break; break;
case LC_PIECE_ROTATE_PLUSX: case LC_PIECE_ROTATE_PLUSX:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(lcMax((float)GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSX: case LC_PIECE_ROTATE_MINUSX:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(-lcVector3(lcMax((float)GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, true, true);
break; break;
case LC_PIECE_ROTATE_PLUSY: case LC_PIECE_ROTATE_PLUSY:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, lcMax((float)GetAngleSnap(), 1.0f), 0.0f)), true, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSY: case LC_PIECE_ROTATE_MINUSY:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax((float)GetAngleSnap(), 1.0f), 0.0f)), true, true, true);
break; break;
case LC_PIECE_ROTATE_PLUSZ: case LC_PIECE_ROTATE_PLUSZ:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax((float)GetAngleSnap(), 1.0f))), true, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSZ: case LC_PIECE_ROTATE_MINUSZ:
lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, true, true); lcGetActiveModel()->RotateSelectedPieces(mActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax((float)GetAngleSnap(), 1.0f))), true, true, true);
break; break;
case LC_PIECE_MINIFIG_WIZARD: case LC_PIECE_MINIFIG_WIZARD:

View file

@ -17,20 +17,20 @@
#define LC_RGBA_ALPHA(rgba) ((lcuint8)(((rgba) >> 24) & 0xff)) #define LC_RGBA_ALPHA(rgba) ((lcuint8)(((rgba) >> 24) & 0xff))
#define LC_FLOATRGB(f) LC_RGB(f[0]*255, f[1]*255, f[2]*255) #define LC_FLOATRGB(f) LC_RGB(f[0]*255, f[1]*255, f[2]*255)
template <typename T, typename U> template<typename T>
inline T lcMin(const T& a, const U& b) inline T lcMin(const T& a, const T& b)
{ {
return a < b ? a : b; return a < b ? a : b;
} }
template <typename T, typename U> template<typename T>
inline T lcMax(const T& a, const U& b) inline T lcMax(const T& a, const T& b)
{ {
return a > b ? a : b; return a > b ? a : b;
} }
template <typename T, typename U, typename V> template<typename T>
inline T lcClamp(const T& Value, const U& Min, const V& Max) inline T lcClamp(const T& Value, const T& Min, const T& Max)
{ {
if (Value > Max) if (Value > Max)
return Max; return Max;

View file

@ -16,10 +16,18 @@ lcMesh::lcMesh()
mNumVertices = 0; mNumVertices = 0;
mNumTexturedVertices = 0; mNumTexturedVertices = 0;
mIndexType = 0; mIndexType = 0;
mVertexData = NULL;
mVertexDataSize = 0;
mIndexData = NULL;
mIndexDataSize = 0;
mVertexCacheOffset = -1;
mIndexCacheOffset = -1;
} }
lcMesh::~lcMesh() lcMesh::~lcMesh()
{ {
free(mVertexData);
free(mIndexData);
delete[] mSections; delete[] mSections;
} }
@ -30,18 +38,21 @@ void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, i
mNumVertices = NumVertices; mNumVertices = NumVertices;
mNumTexturedVertices = NumTexturedVertices; mNumTexturedVertices = NumTexturedVertices;
mVertexBuffer.SetSize(NumVertices * sizeof(lcVertex) + NumTexturedVertices * sizeof(lcVertexTextured)); mVertexDataSize = NumVertices * sizeof(lcVertex) + NumTexturedVertices * sizeof(lcVertexTextured);
mVertexData = malloc(mVertexDataSize);
if (NumVertices < 0x10000 && NumTexturedVertices < 0x10000) if (NumVertices < 0x10000 && NumTexturedVertices < 0x10000)
{ {
mIndexType = GL_UNSIGNED_SHORT; mIndexType = GL_UNSIGNED_SHORT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLushort)); mIndexDataSize = NumIndices * sizeof(GLushort);
} }
else else
{ {
mIndexType = GL_UNSIGNED_INT; mIndexType = GL_UNSIGNED_INT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLuint)); mIndexDataSize = NumIndices * sizeof(GLuint);
} }
mIndexData = malloc(mIndexDataSize);
} }
void lcMesh::CreateBox() void lcMesh::CreateBox()
@ -51,8 +62,8 @@ void lcMesh::CreateBox()
lcVector3 Min(-10.0f, -10.0f, -24.0f); lcVector3 Min(-10.0f, -10.0f, -24.0f);
lcVector3 Max(10.0f, 10.0f, 4.0f); lcVector3 Max(10.0f, 10.0f, 4.0f);
float* Verts = (float*)mVertexBuffer.mData; float* Verts = (float*)mVertexData;
lcuint16* Indices = (lcuint16*)mIndexBuffer.mData; lcuint16* Indices = (lcuint16*)mIndexData;
*Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Min[2]; *Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Min[2];
*Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Min[2]; *Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Min[2];
@ -103,14 +114,12 @@ void lcMesh::CreateBox()
*Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5; *Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7; *Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7;
UpdateBuffers();
} }
template<typename IndexType> template<typename IndexType>
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection) bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
{ {
float* Verts = (float*)mVertexBuffer.mData; float* Verts = (float*)mVertexData;
bool Hit = false; bool Hit = false;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
@ -120,7 +129,7 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
if (Section->PrimitiveType != GL_TRIANGLES) if (Section->PrimitiveType != GL_TRIANGLES)
continue; continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType); IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{ {
@ -150,7 +159,7 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
template<typename IndexType> template<typename IndexType>
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6]) bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{ {
float* Verts = (float*)mVertexBuffer.mData; float* Verts = (float*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{ {
@ -159,7 +168,7 @@ bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
if (Section->PrimitiveType != GL_TRIANGLES) if (Section->PrimitiveType != GL_TRIANGLES)
continue; continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType); IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (lcTriangleIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], Planes)) if (lcTriangleIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], Planes))
@ -185,7 +194,7 @@ void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorT
sprintf(Line, "#declare lc_%s = union {\n", MeshName); sprintf(Line, "#declare lc_%s = union {\n", MeshName);
File.WriteLine(Line); File.WriteLine(Line);
float* Verts = (float*)mVertexBuffer.mData; float* Verts = (float*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{ {
@ -194,7 +203,7 @@ void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorT
if (Section->PrimitiveType != GL_TRIANGLES) if (Section->PrimitiveType != GL_TRIANGLES)
continue; continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType); IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
File.WriteLine(" mesh {\n"); File.WriteLine(" mesh {\n");
@ -237,7 +246,7 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
if (Section->PrimitiveType != GL_TRIANGLES) if (Section->PrimitiveType != GL_TRIANGLES)
continue; continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType); IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
if (Section->ColorIndex == gDefaultColor) if (Section->ColorIndex == gDefaultColor)
sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName); sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName);
@ -315,13 +324,11 @@ bool lcMesh::FileLoad(lcFile& File)
Section.Texture = NULL; Section.Texture = NULL;
} }
File.ReadFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices); File.ReadFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT) if (mIndexType == GL_UNSIGNED_SHORT)
File.ReadU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2); File.ReadU16((lcuint16*)mIndexData, mIndexDataSize / 2);
else else
File.ReadU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4); File.ReadU32((lcuint32*)mIndexData, mIndexDataSize / 4);
UpdateBuffers();
return true; return true;
} }
@ -335,7 +342,7 @@ void lcMesh::FileSave(lcFile& File)
File.WriteU16(mNumSections); File.WriteU16(mNumSections);
File.WriteU32(mNumVertices); File.WriteU32(mNumVertices);
File.WriteU32(mNumTexturedVertices); File.WriteU32(mNumTexturedVertices);
File.WriteU32(mIndexBuffer.mSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4)); File.WriteU32(mIndexDataSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4));
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{ {
@ -356,9 +363,9 @@ void lcMesh::FileSave(lcFile& File)
File.WriteU16(0); File.WriteU16(0);
} }
File.WriteFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices); File.WriteFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT) if (mIndexType == GL_UNSIGNED_SHORT)
File.WriteU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2); File.WriteU16((lcuint16*)mIndexData, mIndexDataSize / 2);
else else
File.WriteU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4); File.WriteU32((lcuint32*)mIndexData, mIndexDataSize / 4);
} }

View file

@ -19,98 +19,6 @@ struct lcVertexTextured
lcVector2 TexCoord; lcVector2 TexCoord;
}; };
class lcVertexBuffer
{
public:
lcVertexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcVertexBuffer()
{
if (mBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffers(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ARRAY_BUFFER_ARB, mBuffer);
glBufferData(GL_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
class lcIndexBuffer
{
public:
lcIndexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcIndexBuffer()
{
if (mBuffer)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDeleteBuffers(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
struct lcMeshSection struct lcMeshSection
{ {
int ColorIndex; int ColorIndex;
@ -118,7 +26,6 @@ struct lcMeshSection
int NumIndices; int NumIndices;
int PrimitiveType; int PrimitiveType;
lcTexture* Texture; lcTexture* Texture;
// BoundingBox Box;
}; };
class lcMesh class lcMesh
@ -149,17 +56,16 @@ public:
bool IntersectsPlanes(const lcVector4 Planes[6]); bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const lcVector4 Planes[6]); bool IntersectsPlanes(const lcVector4 Planes[6]);
void UpdateBuffers()
{
mVertexBuffer.UpdateBuffer();
mIndexBuffer.UpdateBuffer();
}
lcMeshSection* mSections; lcMeshSection* mSections;
int mNumSections; int mNumSections;
lcVertexBuffer mVertexBuffer; void* mVertexData;
lcIndexBuffer mIndexBuffer; int mVertexDataSize;
void* mIndexData;
int mIndexDataSize;
int mVertexCacheOffset;
int mIndexCacheOffset;
int mNumVertices; int mNumVertices;
int mNumTexturedVertices; int mNumTexturedVertices;
int mIndexType; int mIndexType;

View file

@ -250,8 +250,8 @@ void lcModel::UpdatePieceInfo(lcArray<lcModel*>& UpdatedModels)
if (Mesh) if (Mesh)
{ {
int NumVerts = Mesh->mVertexBuffer.mSize / sizeof(lcVertex); int NumVerts = Mesh->mNumVertices;
float* Vertex = (float*)Mesh->mVertexBuffer.mData; float* Vertex = (float*)Mesh->mVertexData;
for (int VertexIdx = 0; VertexIdx < NumVerts; VertexIdx++) for (int VertexIdx = 0; VertexIdx < NumVerts; VertexIdx++)
{ {
@ -1893,6 +1893,15 @@ void lcModel::AddPiece(lcPiece* Piece)
} }
} }
PieceInfo* Info = Piece->mPieceInfo;
if (!Info->IsModel())
{
lcMesh* Mesh = Info->IsTemporary() ? gPlaceholderMesh : Info->GetMesh();
if (Mesh->mVertexCacheOffset == -1)
lcGetPiecesLibrary()->mBuffersDirty = true;
}
mPieces.Add(Piece); mPieces.Add(Piece);
} }

View file

@ -91,7 +91,7 @@ lcuint64 lcZipFile::SearchCentralDir()
lcuint8 buf[CommentBufferSize + 4]; lcuint8 buf[CommentBufferSize + 4];
SizeFile = mFile->GetLength(); SizeFile = mFile->GetLength();
MaxBack = lcMin(SizeFile, 0xffffU); MaxBack = lcMin(SizeFile, 0xffffULL);
BackRead = 4; BackRead = 4;
PosFound = 0; PosFound = 0;
@ -134,7 +134,7 @@ lcuint64 lcZipFile::SearchCentralDir64()
lcuint8 buf[CommentBufferSize + 4]; lcuint8 buf[CommentBufferSize + 4];
SizeFile = mFile->GetLength(); SizeFile = mFile->GetLength();
MaxBack = lcMin(SizeFile, 0xffffU); MaxBack = lcMin(SizeFile, 0xffffULL);
BackRead = 4; BackRead = 4;
PosFound = 0; PosFound = 0;

View file

@ -734,7 +734,7 @@ void Project::Export3DStudio(const QString& FileName)
File.WriteU16(Mesh->mNumVertices); File.WriteU16(Mesh->mNumVertices);
float* Verts = (float*)Mesh->mVertexBuffer.mData; float* Verts = (float*)Mesh->mVertexData;
const lcMatrix44& ModelWorld = ModelParts[PartIdx].WorldMatrix; const lcMatrix44& ModelWorld = ModelParts[PartIdx].WorldMatrix;
for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++)
@ -785,7 +785,7 @@ void Project::Export3DStudio(const QString& FileName)
if (Section->PrimitiveType != GL_TRIANGLES) if (Section->PrimitiveType != GL_TRIANGLES)
continue; continue;
lcuint16* Indices = (lcuint16*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(lcuint16); lcuint16* Indices = (lcuint16*)Mesh->mIndexData + Section->IndexOffset / sizeof(lcuint16);
for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3) for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3)
{ {
@ -1657,7 +1657,7 @@ void Project::ExportWavefront(const QString& FileName)
continue; continue;
const lcMatrix44& ModelWorld = ModelParts[PartIdx].WorldMatrix; const lcMatrix44& ModelWorld = ModelParts[PartIdx].WorldMatrix;
float* Verts = (float*)Mesh->mVertexBuffer.mData; float* Verts = (float*)Mesh->mVertexData;
for (int i = 0; i < Mesh->mNumVertices * 3; i += 3) for (int i = 0; i < Mesh->mNumVertices * 3; i += 3)
{ {

View file

@ -17,7 +17,7 @@ View::View(lcModel* Model)
{ {
mModel = Model; mModel = Model;
mCamera = NULL; mCamera = NULL;
mGridBuffer = NULL; mGridBuffer = LC_INVALID_VERTEX_BUFFER;
memset(mGridSettings, 0, sizeof(mGridSettings)); memset(mGridSettings, 0, sizeof(mGridSettings));
mDragState = LC_DRAGSTATE_NONE; mDragState = LC_DRAGSTATE_NONE;
@ -33,7 +33,7 @@ View::View(lcModel* Model)
View::~View() View::~View()
{ {
delete mGridBuffer; mContext->DestroyVertexBuffer(mGridBuffer);
if (gMainWindow) if (gMainWindow)
gMainWindow->RemoveView(this); gMainWindow->RemoveView(this);
@ -1051,9 +1051,9 @@ void View::DrawSelectZoomRegionOverlay()
} }
Left = lcMax(Left, 0.0f); Left = lcMax(Left, 0.0f);
Right = lcMin(Right, mWidth - 1); Right = lcMin(Right, mWidth - 1.0f);
Bottom = lcMax(Bottom, 0.0f); Bottom = lcMax(Bottom, 0.0f);
Top = lcMin(Top, mHeight - 1); Top = lcMin(Top, mHeight - 1.0f);
float BorderX = lcMin(2.0f, Right - Left); float BorderX = lcMin(2.0f, Right - Left);
float BorderY = lcMin(2.0f, Top - Bottom); float BorderY = lcMin(2.0f, Top - Bottom);
@ -1122,7 +1122,7 @@ void View::DrawRotateViewOverlay()
*CurVert++ = sinf((float)i / 32.0f * (2.0f * LC_PI)) * r + cy; *CurVert++ = sinf((float)i / 32.0f * (2.0f * LC_PI)) * r + cy;
} }
const float OverlayCameraSquareSize = lcMax(8.0f, (w+h)/200); const float OverlayCameraSquareSize = lcMax(8.0f, (w + h) / 200.0f);
*CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize; *CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize;
*CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize; *CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize;
@ -1227,22 +1227,19 @@ void View::DrawGrid()
MaxY = 2; MaxY = 2;
} }
if (!mGridBuffer || MinX != mGridSettings[0] || MinY != mGridSettings[1] || MaxX != mGridSettings[2] || MaxY != mGridSettings[3] || if (mGridBuffer == LC_INVALID_VERTEX_BUFFER || MinX != mGridSettings[0] || MinY != mGridSettings[1] || MaxX != mGridSettings[2] || MaxY != mGridSettings[3] ||
Spacing != mGridSettings[4] || (Preferences.mDrawGridStuds ? 1 : 0) != mGridSettings[5] || (Preferences.mDrawGridLines ? 1 : 0) != mGridSettings[6]) Spacing != mGridSettings[4] || (Preferences.mDrawGridStuds ? 1 : 0) != mGridSettings[5] || (Preferences.mDrawGridLines ? 1 : 0) != mGridSettings[6])
{ {
int BufferSize = 0; int VertexBufferSize = 0;
if (Preferences.mDrawGridStuds) if (Preferences.mDrawGridStuds)
BufferSize += 4 * 5; VertexBufferSize += 4 * 5 * sizeof(float);
if (Preferences.mDrawGridLines) if (Preferences.mDrawGridLines)
BufferSize += 2 * (MaxX - MinX + MaxY - MinY + 2) * 3; VertexBufferSize += 2 * (MaxX - MinX + MaxY - MinY + 2) * 3 * sizeof(float);
if (!mGridBuffer) float* Verts = (float*)malloc(VertexBufferSize);
mGridBuffer = new lcVertexBuffer(); float* CurVert = Verts;
mGridBuffer->SetSize(BufferSize * sizeof(float));
float* CurVert = (float*)mGridBuffer->mData;
if (Preferences.mDrawGridStuds) if (Preferences.mDrawGridStuds)
{ {
@ -1312,7 +1309,9 @@ void View::DrawGrid()
mGridSettings[5] = (Preferences.mDrawGridStuds ? 1 : 0); mGridSettings[5] = (Preferences.mDrawGridStuds ? 1 : 0);
mGridSettings[6] = (Preferences.mDrawGridLines ? 1 : 0); mGridSettings[6] = (Preferences.mDrawGridLines ? 1 : 0);
mGridBuffer->UpdateBuffer(); mContext->DestroyVertexBuffer(mGridBuffer);
mGridBuffer = mContext->CreateVertexBuffer(VertexBufferSize, Verts);
free(Verts);
} }
int BufferOffset = 0; int BufferOffset = 0;
@ -1856,7 +1855,7 @@ void View::UpdateTrackTool()
float d = sqrtf((float)((cx - x) * (cx - x) + (cy - y) * (cy - y))); float d = sqrtf((float)((cx - x) * (cx - x) + (cy - y) * (cy - y)));
float r = lcMin(vw, vh) * 0.35f; float r = lcMin(vw, vh) * 0.35f;
const float SquareSize = lcMax(8.0f, (vw + vh) / 200); const float SquareSize = lcMax(8.0f, (vw + vh) / 200.0f);
if ((d < r + SquareSize) && (d > r - SquareSize)) if ((d < r + SquareSize) && (d > r - SquareSize))
{ {

View file

@ -138,7 +138,7 @@ protected:
int mMouseDownX; int mMouseDownX;
int mMouseDownY; int mMouseDownY;
lcVertexBuffer* mGridBuffer; lcVertexBuffer mGridBuffer;
int mGridSettings[7]; int mGridSettings[7];
}; };