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

@@ -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();
};