mirror of
https://github.com/leozide/leocad
synced 2025-01-29 20:34:50 +01:00
Use a single vertex buffer for all pieces.
This commit is contained in:
parent
2063514f2f
commit
aa861cd036
14 changed files with 289 additions and 178 deletions
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -60,8 +60,6 @@ class lcMatrix33;
|
|||
class lcMatrix44;
|
||||
|
||||
class lcContext;
|
||||
class lcVertexBuffer;
|
||||
class lcIndexBuffer;
|
||||
class lcMesh;
|
||||
struct lcMeshSection;
|
||||
struct lcRenderMesh;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
108
common/lc_mesh.h
108
common/lc_mesh.h
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -138,7 +138,7 @@ protected:
|
|||
int mMouseDownX;
|
||||
int mMouseDownY;
|
||||
|
||||
lcVertexBuffer* mGridBuffer;
|
||||
lcVertexBuffer mGridBuffer;
|
||||
int mGridSettings[7];
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue