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_colors.h"
#include "lc_mainwindow.h"
#include "lc_library.h"
static int lcOpaqueRenderMeshCompare(const void* Elem1, const void* Elem2)
{
@ -300,6 +301,94 @@ bool lcContext::SaveRenderToTextureImage(const QString& FileName, int Width, int
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()
{
mVertexBufferPointer = NULL;
@ -318,11 +407,11 @@ void lcContext::ClearVertexBuffer()
glDisableClientState(GL_COLOR_ARRAY);
}
void lcContext::SetVertexBuffer(const lcVertexBuffer* VertexBuffer)
void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer)
{
if (GL_HasVertexBufferObject())
{
GLuint VertexBufferObject = VertexBuffer->mBuffer;
GLuint VertexBufferObject = VertexBuffer;
mVertexBufferPointer = NULL;
if (VertexBufferObject != mVertexBufferObject)
@ -334,7 +423,7 @@ void lcContext::SetVertexBuffer(const lcVertexBuffer* VertexBuffer)
}
else
{
mVertexBufferPointer = (char*)VertexBuffer->mData;
mVertexBufferPointer = (char*)VertexBuffer;
mVertexBufferOffset = (char*)~0;
}
}
@ -397,12 +486,14 @@ void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int TexCoord
void lcContext::BindMesh(lcMesh* Mesh)
{
if (GL_HasVertexBufferObject())
lcPiecesLibrary* Library = lcGetPiecesLibrary();
if (Mesh->mVertexCacheOffset != -1)
{
GLuint VertexBufferObject = Mesh->mVertexBuffer.mBuffer;
mVertexBufferPointer = NULL;
GLuint IndexBufferObject = Mesh->mIndexBuffer.mBuffer;
mIndexBufferPointer = NULL;
GLuint VertexBufferObject = Library->mVertexBuffer;
mVertexBufferPointer = (char*)Mesh->mVertexCacheOffset;
GLuint IndexBufferObject = Library->mIndexBuffer;
mIndexBufferPointer = (char*)Mesh->mIndexCacheOffset;
if (VertexBufferObject != mVertexBufferObject)
{
@ -419,8 +510,20 @@ void lcContext::BindMesh(lcMesh* Mesh)
}
else
{
mVertexBufferPointer = (char*)Mesh->mVertexBuffer.mData;
mIndexBufferPointer = (char*)Mesh->mIndexBuffer.mData;
if (mVertexBufferObject)
{
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;
}
}
@ -508,6 +611,8 @@ void lcContext::DrawOpaqueMeshes(const lcMatrix44& ViewMatrix, const lcArray<lcR
{
bool DrawLines = lcGetPreferences().mDrawEdgeLines;
lcGetPiecesLibrary()->UpdateBuffers(this); // TODO: find a better place for this update
for (int MeshIdx = 0; MeshIdx < OpaqueMeshes.GetSize(); MeshIdx++)
{
lcRenderMesh& RenderMesh = OpaqueMeshes[MeshIdx];

View file

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

View file

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

View file

@ -8,6 +8,7 @@
#include "lc_category.h"
#include "lc_application.h"
#include "lc_mainwindow.h"
#include "lc_context.h"
#include "project.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -31,6 +32,9 @@ lcPiecesLibrary::lcPiecesLibrary()
mCacheFile = NULL;
mCacheFileName[0] = 0;
mSaveCache = false;
mBuffersDirty = false;
mVertexBuffer = LC_INVALID_VERTEX_BUFFER;
mIndexBuffer = LC_INVALID_INDEX_BUFFER;
}
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);
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);
for (int VertexIdx = 0; VertexIdx < MeshData.mVertices.GetSize(); VertexIdx++)
@ -986,7 +990,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
{
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++)
*Index++ = SrcSection->mIndices[IndexIdx];
@ -995,7 +999,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
{
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++)
*Index++ = SrcSection->mIndices[IndexIdx];
@ -1019,10 +1023,75 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
NumIndices += DstSection.NumIndices;
}
Mesh->UpdateBuffers();
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)
{
char Name[LC_MAXPATH], FileName[LC_MAXPATH];

View file

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

View file

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

View file

@ -16,10 +16,18 @@ lcMesh::lcMesh()
mNumVertices = 0;
mNumTexturedVertices = 0;
mIndexType = 0;
mVertexData = NULL;
mVertexDataSize = 0;
mIndexData = NULL;
mIndexDataSize = 0;
mVertexCacheOffset = -1;
mIndexCacheOffset = -1;
}
lcMesh::~lcMesh()
{
free(mVertexData);
free(mIndexData);
delete[] mSections;
}
@ -30,18 +38,21 @@ void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, i
mNumVertices = NumVertices;
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)
{
mIndexType = GL_UNSIGNED_SHORT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLushort));
mIndexDataSize = NumIndices * sizeof(GLushort);
}
else
{
mIndexType = GL_UNSIGNED_INT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLuint));
mIndexDataSize = NumIndices * sizeof(GLuint);
}
mIndexData = malloc(mIndexDataSize);
}
void lcMesh::CreateBox()
@ -51,8 +62,8 @@ void lcMesh::CreateBox()
lcVector3 Min(-10.0f, -10.0f, -24.0f);
lcVector3 Max(10.0f, 10.0f, 4.0f);
float* Verts = (float*)mVertexBuffer.mData;
lcuint16* Indices = (lcuint16*)mIndexBuffer.mData;
float* Verts = (float*)mVertexData;
lcuint16* Indices = (lcuint16*)mIndexData;
*Verts++ = Min[0]; *Verts++ = Min[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++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7;
UpdateBuffers();
}
template<typename IndexType>
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;
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)
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)
{
@ -150,7 +159,7 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
template<typename IndexType>
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
float* Verts = (float*)mVertexBuffer.mData;
float* Verts = (float*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
@ -159,7 +168,7 @@ bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
if (Section->PrimitiveType != GL_TRIANGLES)
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)
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);
File.WriteLine(Line);
float* Verts = (float*)mVertexBuffer.mData;
float* Verts = (float*)mVertexData;
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)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
File.WriteLine(" mesh {\n");
@ -237,7 +246,7 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
if (Section->ColorIndex == gDefaultColor)
sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName);
@ -315,13 +324,11 @@ bool lcMesh::FileLoad(lcFile& File)
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)
File.ReadU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
File.ReadU16((lcuint16*)mIndexData, mIndexDataSize / 2);
else
File.ReadU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
UpdateBuffers();
File.ReadU32((lcuint32*)mIndexData, mIndexDataSize / 4);
return true;
}
@ -335,7 +342,7 @@ void lcMesh::FileSave(lcFile& File)
File.WriteU16(mNumSections);
File.WriteU32(mNumVertices);
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++)
{
@ -356,9 +363,9 @@ void lcMesh::FileSave(lcFile& File)
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)
File.WriteU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
File.WriteU16((lcuint16*)mIndexData, mIndexDataSize / 2);
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;
};
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
{
int ColorIndex;
@ -118,7 +26,6 @@ struct lcMeshSection
int NumIndices;
int PrimitiveType;
lcTexture* Texture;
// BoundingBox Box;
};
class lcMesh
@ -149,17 +56,16 @@ public:
bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const lcVector4 Planes[6]);
void UpdateBuffers()
{
mVertexBuffer.UpdateBuffer();
mIndexBuffer.UpdateBuffer();
}
lcMeshSection* mSections;
int mNumSections;
lcVertexBuffer mVertexBuffer;
lcIndexBuffer mIndexBuffer;
void* mVertexData;
int mVertexDataSize;
void* mIndexData;
int mIndexDataSize;
int mVertexCacheOffset;
int mIndexCacheOffset;
int mNumVertices;
int mNumTexturedVertices;
int mIndexType;

View file

@ -250,8 +250,8 @@ void lcModel::UpdatePieceInfo(lcArray<lcModel*>& UpdatedModels)
if (Mesh)
{
int NumVerts = Mesh->mVertexBuffer.mSize / sizeof(lcVertex);
float* Vertex = (float*)Mesh->mVertexBuffer.mData;
int NumVerts = Mesh->mNumVertices;
float* Vertex = (float*)Mesh->mVertexData;
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);
}

View file

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

View file

@ -734,7 +734,7 @@ void Project::Export3DStudio(const QString& FileName)
File.WriteU16(Mesh->mNumVertices);
float* Verts = (float*)Mesh->mVertexBuffer.mData;
float* Verts = (float*)Mesh->mVertexData;
const lcMatrix44& ModelWorld = ModelParts[PartIdx].WorldMatrix;
for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++)
@ -785,7 +785,7 @@ void Project::Export3DStudio(const QString& FileName)
if (Section->PrimitiveType != GL_TRIANGLES)
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)
{
@ -1657,7 +1657,7 @@ void Project::ExportWavefront(const QString& FileName)
continue;
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)
{

View file

@ -17,7 +17,7 @@ View::View(lcModel* Model)
{
mModel = Model;
mCamera = NULL;
mGridBuffer = NULL;
mGridBuffer = LC_INVALID_VERTEX_BUFFER;
memset(mGridSettings, 0, sizeof(mGridSettings));
mDragState = LC_DRAGSTATE_NONE;
@ -33,7 +33,7 @@ View::View(lcModel* Model)
View::~View()
{
delete mGridBuffer;
mContext->DestroyVertexBuffer(mGridBuffer);
if (gMainWindow)
gMainWindow->RemoveView(this);
@ -1051,9 +1051,9 @@ void View::DrawSelectZoomRegionOverlay()
}
Left = lcMax(Left, 0.0f);
Right = lcMin(Right, mWidth - 1);
Right = lcMin(Right, mWidth - 1.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 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;
}
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;
@ -1227,22 +1227,19 @@ void View::DrawGrid()
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])
{
int BufferSize = 0;
int VertexBufferSize = 0;
if (Preferences.mDrawGridStuds)
BufferSize += 4 * 5;
VertexBufferSize += 4 * 5 * sizeof(float);
if (Preferences.mDrawGridLines)
BufferSize += 2 * (MaxX - MinX + MaxY - MinY + 2) * 3;
VertexBufferSize += 2 * (MaxX - MinX + MaxY - MinY + 2) * 3 * sizeof(float);
if (!mGridBuffer)
mGridBuffer = new lcVertexBuffer();
mGridBuffer->SetSize(BufferSize * sizeof(float));
float* CurVert = (float*)mGridBuffer->mData;
float* Verts = (float*)malloc(VertexBufferSize);
float* CurVert = Verts;
if (Preferences.mDrawGridStuds)
{
@ -1312,7 +1309,9 @@ void View::DrawGrid()
mGridSettings[5] = (Preferences.mDrawGridStuds ? 1 : 0);
mGridSettings[6] = (Preferences.mDrawGridLines ? 1 : 0);
mGridBuffer->UpdateBuffer();
mContext->DestroyVertexBuffer(mGridBuffer);
mGridBuffer = mContext->CreateVertexBuffer(VertexBufferSize, Verts);
free(Verts);
}
int BufferOffset = 0;
@ -1856,7 +1855,7 @@ void View::UpdateTrackTool()
float d = sqrtf((float)((cx - x) * (cx - x) + (cy - y) * (cy - y)));
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))
{

View file

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