Implemented logic to track the source of the mesh data and perform appropriate cleanup depending on if it was malloc'ed or mmap'ed.

Implemented writePack method

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4017
This commit is contained in:
kearwood
2012-03-16 00:53:15 +00:00
parent d43989cd88
commit d305bd1438
3 changed files with 122 additions and 48 deletions

View File

@@ -52,6 +52,7 @@
E4BBBB9F1512A4B100F43B5B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4BBBB941512A45500F43B5B /* Cocoa.framework */; };
E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017F13C99BDC0098455B /* KRVector3.cpp */; };
E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017E13C99BDC0098455B /* KRVector3.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4F711A51512BB56007EE923 /* libfbxsdk-2012.2-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4F711A41512BB56007EE923 /* libfbxsdk-2012.2-static.a */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
@@ -121,6 +122,7 @@
E4BBBB961512A46700F43B5B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; };
E4BBBB981512A47500F43B5B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
E4BBBB9A1512A48200F43B5B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
E4F711A41512BB56007EE923 /* libfbxsdk-2012.2-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfbxsdk-2012.2-static.a"; path = "../../../../../../../../Applications/Autodesk/FBXSDK20122/lib/gcc4/ub/libfbxsdk-2012.2-static.a"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -142,6 +144,7 @@
E46DBE7F1512AF0200D59F86 /* OpenGL.framework in Frameworks */,
E4BBBB9E1512A4AE00F43B5B /* AppKit.framework in Frameworks */,
E4BBBB9F1512A4B100F43B5B /* Cocoa.framework in Frameworks */,
E4F711A51512BB56007EE923 /* libfbxsdk-2012.2-static.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -271,6 +274,7 @@
E4BBBB931512A41500F43B5B /* OSX Frameworks */ = {
isa = PBXGroup;
children = (
E4F711A41512BB56007EE923 /* libfbxsdk-2012.2-static.a */,
E46DBE7D1512AD4900D59F86 /* OpenGL.framework */,
E4BBBB9A1512A48200F43B5B /* Foundation.framework */,
E4BBBB981512A47500F43B5B /* CoreData.framework */,
@@ -525,6 +529,10 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INFOPLIST_FILE = "krengine_osx/krengine_osx-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBXSDK20122/lib/gcc4/ub\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -556,6 +564,10 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INFOPLIST_FILE = "krengine_osx/krengine_osx-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBXSDK20122/lib/gcc4/ub\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;

View File

@@ -63,6 +63,11 @@ KRMesh::~KRMesh() {
}
}
clearBuffers();
}
void KRMesh::clearBuffers() {
m_submeshes.clear();
if(m_pBuffers != NULL) {
glDeleteBuffers(m_cBuffers, m_pBuffers);
delete m_pBuffers;
@@ -79,6 +84,7 @@ void KRMesh::loadPack(std::string path) {
} else {
m_iPackFileSize = statbuf.st_size;
clearBuffers();
pack_header *pHeader = (pack_header *)m_pPackData;
@@ -88,37 +94,54 @@ void KRMesh::loadPack(std::string path) {
m_maxx = pHeader->maxx;
m_maxy = pHeader->maxy;
m_maxz = pHeader->maxz;
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
pack_material *pPackMaterial = pPackMaterials + iMaterial;
Submesh *pSubmesh = new Submesh();
pSubmesh->start_vertex = pPackMaterial->start_vertex;
pSubmesh->vertex_count = pPackMaterial->vertex_count;
strcpy(pSubmesh->szMaterialName, pPackMaterial->szName);
m_submeshes.push_back(pSubmesh);
}
m_pVertexData = (VertexData *)(pPackMaterials + pHeader->submesh_count);
m_cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
m_pBuffers = new GLuint[m_cBuffers];
glGenBuffers(m_cBuffers, m_pBuffers);
for(GLsizei iBuffer=0; iBuffer < m_cBuffers; iBuffer++) {
GLsizei cVertexes = iBuffer < m_cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffers[iBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * cVertexes, m_pVertexData + iBuffer * MAX_VBO_SIZE, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
}
}
}
bool KRMesh::writePack(std::string path) {
clearBuffers();
int fdNewFile = open(path.c_str(), O_RDWR);
if(fdNewFile == 0) {
return false;
} else {
void *pNewData = mmap(0, m_iPackFileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fdNewFile, 0);
if(pNewData == (caddr_t) -1) {
close(fdNewFile);
return false;
} else {
memcpy(pNewData, m_pPackData, m_iPackFileSize);
mprotect(pNewData, m_iPackFileSize, PROT_READ);
if(m_fdPackFile) {
if(m_pPackData != NULL) {
void *malloc_data = malloc(m_iPackFileSize);
memcpy(malloc_data, m_pPackData, m_iPackFileSize);
munmap(m_pPackData, m_iPackFileSize);
}
close(m_fdPackFile);
}
m_fdPackFile = fdNewFile;
m_pPackData = pNewData;
return true;
}
}
}
void KRMesh::unmap() {
clearBuffers();
if(m_fdPackFile) {
if(m_pPackData != NULL) {
void *malloc_data = malloc(m_iPackFileSize);
memcpy(malloc_data, m_pPackData, m_iPackFileSize);
munmap(m_pPackData, m_iPackFileSize);
m_pPackData = malloc_data;
}
close(m_fdPackFile);
}
}
GLfloat KRMesh::getMaxDimension() {
GLfloat m = 0.0;
if(m_maxx - m_minx > m) m = m_maxx - m_minx;
@@ -147,12 +170,42 @@ GLfloat KRMesh::getMaxZ() {
}
vector<KRMesh::Submesh *> KRMesh::getSubmeshes() {
if(m_submeshes.size() == 0) {
pack_header *pHeader = (pack_header *)m_pPackData;
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
m_submeshes.clear();
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
pack_material *pPackMaterial = pPackMaterials + iMaterial;
Submesh *pSubmesh = new Submesh();
pSubmesh->start_vertex = pPackMaterial->start_vertex;
pSubmesh->vertex_count = pPackMaterial->vertex_count;
strcpy(pSubmesh->szMaterialName, pPackMaterial->szName);
m_submeshes.push_back(pSubmesh);
}
}
return m_submeshes;
}
void KRMesh::renderSubmesh(int iSubmesh, int *iPrevBuffer) {
Submesh *pSubmesh = m_submeshes[iSubmesh];
VertexData *pVertexData = getVertexData();
if(m_cBuffers == 0) {
pack_header *pHeader = (pack_header *)m_pPackData;
m_cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
m_pBuffers = new GLuint[m_cBuffers];
glGenBuffers(m_cBuffers, m_pBuffers);
for(GLsizei iBuffer=0; iBuffer < m_cBuffers; iBuffer++) {
GLsizei cVertexes = iBuffer < m_cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffers[iBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * cVertexes, pVertexData + iBuffer * MAX_VBO_SIZE, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
vector<KRMesh::Submesh *> submeshes = getSubmeshes();
Submesh *pSubmesh = submeshes[iSubmesh];
int iVertex = pSubmesh->start_vertex;
int iBuffer = iVertex / MAX_VBO_SIZE;
@@ -192,3 +245,9 @@ void KRMesh::renderSubmesh(int iSubmesh, int *iPrevBuffer) {
}
}
}
KRMesh::VertexData *KRMesh::getVertexData() {
pack_header *pHeader = (pack_header *)m_pPackData;
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
return (VertexData *)(pPackMaterials + pHeader->submesh_count);
}

View File

@@ -48,6 +48,7 @@ public:
~KRMesh();
void loadPack(std::string path);
bool writePack(std::string path);
void renderSubmesh(int iSubmesh, int *iPrevBuffer);
GLfloat getMaxDimension();
@@ -64,6 +65,26 @@ public:
char szMaterialName[64];
} Submesh;
typedef struct {
GLfloat x;
GLfloat y;
GLfloat z;
} Vertex3D, KRVector3D;
typedef struct {
GLfloat u;
GLfloat v;
} TexCoord;
typedef struct {
Vertex3D vertex;
KRVector3D normal;
KRVector3D tangent;
TexCoord texcoord;
} VertexData;
VertexData *getVertexData();
vector<Submesh *> getSubmeshes();
protected:
@@ -85,33 +106,15 @@ protected:
int32_t vertex_count;
char szName[64];
} pack_material;
typedef struct {
GLfloat x;
GLfloat y;
GLfloat z;
} Vertex3D, KRVector3D;
typedef struct {
GLfloat u;
GLfloat v;
} TexCoord;
typedef struct {
Vertex3D vertex;
KRVector3D normal;
KRVector3D tangent;
TexCoord texcoord;
} VertexData;
VertexData *m_pVertexData;
GLsizei m_cBuffers;
GLuint *m_pBuffers;
vector<Submesh *> m_submeshes;
void unmap();
void clearBuffers();
};