From d305bd1438e42bd0e6d94647a7338bac93305982 Mon Sep 17 00:00:00 2001 From: kearwood Date: Fri, 16 Mar 2012 00:53:15 +0000 Subject: [PATCH] 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 --- KREngine/KREngine.xcodeproj/project.pbxproj | 12 +++ KREngine/KREngine/Classes/KRMesh.cpp | 113 +++++++++++++++----- KREngine/KREngine/Classes/KRMesh.h | 45 ++++---- 3 files changed, 122 insertions(+), 48 deletions(-) diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 5324e14..1d2e40d 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -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 = ""; }; /* 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; diff --git a/KREngine/KREngine/Classes/KRMesh.cpp b/KREngine/KREngine/Classes/KRMesh.cpp index dbaf625..7d2a617 100644 --- a/KREngine/KREngine/Classes/KRMesh.cpp +++ b/KREngine/KREngine/Classes/KRMesh.cpp @@ -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::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 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); +} diff --git a/KREngine/KREngine/Classes/KRMesh.h b/KREngine/KREngine/Classes/KRMesh.h index cb4d8da..aeb73bf 100644 --- a/KREngine/KREngine/Classes/KRMesh.h +++ b/KREngine/KREngine/Classes/KRMesh.h @@ -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 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 m_submeshes; + + void unmap(); + void clearBuffers(); };