1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 06:52:34 +02:00

Added multimaterial support

This commit is contained in:
Daniel Evans 2013-07-02 02:44:08 +01:00
parent 125f339232
commit db3fc6f2dd
4 changed files with 98 additions and 12 deletions

View File

@ -77,6 +77,8 @@ std::unique_ptr<Model> LoaderDFF::loadFromMemory(char *data)
size_t matI = 0;
materiallistsec.getNextChildSection(matI);
geometryStruct.materials.resize(materialList.nummaterials);
for (size_t m = 0; m < materialList.nummaterials; ++m) {
auto materialsec = materiallistsec.getNextChildSection(matI);
@ -84,10 +86,11 @@ std::unique_ptr<Model> LoaderDFF::loadFromMemory(char *data)
continue;
auto material = materialsec.readStructure<RW::BSMaterial>();
geometryStruct.materials[m].textures.resize(material.numtextures);
size_t texI = 0;
materialsec.getNextChildSection(texI);
for (size_t t = 0; t < material.numtextures; ++t) {
auto texsec = materialsec.getNextChildSection(texI);
auto texture = texsec.readStructure<RW::BSTexture>();
@ -103,13 +106,44 @@ std::unique_ptr<Model> LoaderDFF::loadFromMemory(char *data)
textureName = namesec.raw();
alphaName = alphasec.raw();
geometryStruct.textures.push_back({textureName, alphaName});
geometryStruct.materials[m].textures[t] = {textureName, alphaName};
}
}
if(item.hasMoreData(secI))
{
auto extensions = item.getNextChildSection(secI);
size_t extI = 0;
while(extensions.hasMoreData(extI))
{
auto extsec = extensions.getNextChildSection(extI);
if(extsec.header.id == RW::SID_BinMeshPLG)
{
auto meshplg = extsec.readSubStructure<RW::BSBinMeshPLG>(0);
geometryStruct.subgeom.resize(meshplg.numsplits);
size_t meshplgI = sizeof(RW::BSBinMeshPLG);
for(size_t i = 0; i < meshplg.numsplits; ++i)
{
auto plgHeader = extsec.readSubStructure<RW::BSMaterialSplit>(meshplgI);
meshplgI += sizeof(RW::BSMaterialSplit);
geometryStruct.subgeom[i].material = plgHeader.index;
geometryStruct.subgeom[i].indices.resize(plgHeader.numverts);
for (int j = 0; j < plgHeader.numverts; ++j) {
geometryStruct.subgeom[i].indices[j] = extsec.readSubStructure<uint32_t>(meshplgI);
meshplgI += sizeof(uint32_t);
}
}
}
}
}
// OpenGL buffer stuff
glGenBuffers(1, &geometryStruct.VBO);
glGenBuffers(1, &geometryStruct.EBO);
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
{
glGenBuffers(1, &(geometryStruct.subgeom[i].EBO));
}
size_t buffsize = (geometryStruct.vertices.size() * sizeof(float) * 3)
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
@ -162,9 +196,22 @@ std::unique_ptr<Model> LoaderDFF::loadFromMemory(char *data)
indicies,
GL_STATIC_DRAW
);
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.subgeom[i].EBO);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size(),
&(geometryStruct.subgeom[i].indices[0]),
GL_STATIC_DRAW
);
}
// Add it
model->geometries.push_back(geometryStruct);
}
}
}

View File

@ -18,6 +18,17 @@ public:
std::string name;
std::string alphaName;
};
struct Material {
std::vector<Texture> textures;
};
struct SubGeometry {
GLuint EBO;
size_t material;
std::vector<uint32_t> indices;
};
struct Geometry {
GLuint VBO, EBO;
@ -28,7 +39,8 @@ public:
std::vector<RW::BSTVector3> vertices;
std::vector<RW::BSTVector3> normals;
std::vector<Texture> textures;
std::vector<Material> materials;
std::vector<SubGeometry> subgeom;
};
std::vector<Geometry> geometries;

View File

@ -33,6 +33,8 @@ namespace RW
SID_HAnimPLG = 0x011E,
SID_BinMeshPLG = 0x50E,
SID_NodeName = 0x0253F2FE
};
@ -166,6 +168,19 @@ namespace RW
uint16_t unknown;
};
struct BSBinMeshPLG
{
uint32_t facetype;
uint32_t numsplits;
uint32_t numfaces;
};
struct BSMaterialSplit
{
uint32_t numverts;
uint32_t index;
};
/**
* Texture Dictionary Structures (TXD)
*/
@ -284,6 +299,11 @@ namespace RW
return *reinterpret_cast<T*>(data+offset+sizeof(BSSectionHeader)+internalOffset);
}
template<class T> T readRaw(size_t internalOffset)
{
return *reinterpret_cast<T*>(data+offset+internalOffset);
}
char* raw()
{
return data + offset + sizeof(BSSectionHeader);

View File

@ -242,11 +242,6 @@ void render()
// std::cout << "Rendering " << modelname << std::endl;
for (size_t g = 0; g < model->geometries.size(); g++) {
if (model->geometries[g].textures.size() > 0) {
// std::cout << model->geometries[g].textures.size() << std::endl;
// std::cout << "Looking for " << model->geometries[g].textures[0].name << std::endl;
textureLoader.bindTexture(model->geometries[g].textures[0].name);
}
// This is a hack I have no idea why negating the quaternion fixes the issue but it does.
glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ);
@ -255,15 +250,27 @@ void render()
matrixModel = glm::scale(matrixModel, glm::vec3(obj.scaleX, obj.scaleY, obj.scaleZ));
matrixModel = matrixModel * glm::mat4_cast(rot);
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(matrixModel));
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g].VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].EBO);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)(model->geometries[g].vertices.size() * sizeof(float) * 3));
glEnableVertexAttribArray(posAttrib);
glEnableVertexAttribArray(texAttrib);
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
{
if (model->geometries[g].materials.size() > model->geometries[g].subgeom[sg].material) {
// std::cout << model->geometries[g].textures.size() << std::endl;
// std::cout << "Looking for " << model->geometries[g].textures[0].name << std::endl;
if(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures.size() > 0) {
textureLoader.bindTexture(model->geometries[g].materials[model->geometries[g].subgeom[sg].material].textures[0].name);
}
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].subgeom[sg].EBO);
glDrawElements(GL_TRIANGLES, model->geometries[g].triangles.size() * 3, GL_UNSIGNED_SHORT, NULL);
glDrawElements(GL_TRIANGLES, model->geometries[g].subgeom[sg].indices.size(), GL_UNSIGNED_INT, NULL);
}
}
}
}