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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user