mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 18:32:44 +01:00
Refactored Model and Rendering
This commit is contained in:
parent
5e0d021b4f
commit
ffea4964e3
@ -1,6 +1,7 @@
|
||||
#include <renderwure/engine/Animator.hpp>
|
||||
#include <renderwure/loaders/LoaderDFF.hpp>
|
||||
#include <renderwure/loaders/LoaderIFP.hpp>
|
||||
#include <renderwure/render/Model.hpp>
|
||||
|
||||
Animator::Animator()
|
||||
: animation(nullptr), model(nullptr), time(0.f), serverTime(0.f), lastServerTime(0.f)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <renderwure/loaders/LoaderIDE.hpp>
|
||||
#include <renderwure/ai/GTADefaultAIController.hpp>
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
#include <renderwure/render/Model.hpp>
|
||||
|
||||
// 3 isn't enough to cause a factory.
|
||||
#include <renderwure/objects/GTACharacter.hpp>
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <renderwure/engine/GTAEngine.hpp>
|
||||
#include <renderwure/engine/Animator.hpp>
|
||||
#include <renderwure/render/TextureAtlas.hpp>
|
||||
#include <renderwure/render/Model.hpp>
|
||||
|
||||
#include <renderwure/objects/GTACharacter.hpp>
|
||||
#include <renderwure/objects/GTAInstance.hpp>
|
||||
@ -265,36 +266,7 @@ void GTARenderer::renderWorld()
|
||||
|
||||
auto& textureLoader = engine->gameData.textureLoader;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
|
||||
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*3*4));
|
||||
glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*3*4 + sizeof(float)*2*4));
|
||||
glVertexAttribPointer(colourAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*3*4 + sizeof(float)*2*4 + sizeof(float)*3*4));
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
glEnableVertexAttribArray(normalAttrib);
|
||||
glEnableVertexAttribArray(colourAttrib);
|
||||
glBindTexture(GL_TEXTURE_2D, engine->gameData.textures["water_old"].texName);
|
||||
|
||||
for( size_t w = 0; w < engine->gameData.waterRects.size(); ++w) {
|
||||
GTATypes::WaterRect& r = engine->gameData.waterRects[w];
|
||||
glm::vec3 vert[4] = {
|
||||
glm::vec3(r.xRight, r.yTop, r.height),
|
||||
glm::vec3(r.xLeft, r.yTop, r.height),
|
||||
glm::vec3(r.xRight, r.yBottom, r.height),
|
||||
glm::vec3(r.xLeft, r.yBottom, r.height)
|
||||
};
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * 4, vert);
|
||||
|
||||
glm::mat4 matrixModel(1.f);
|
||||
|
||||
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(matrixModel));
|
||||
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < engine->pedestrians.size(); ++i) {
|
||||
for(size_t i = 0; i < engine->pedestrians.size(); ++i) {
|
||||
GTACharacter* charac = engine->pedestrians[i];
|
||||
|
||||
glm::mat4 matrixModel;
|
||||
@ -327,7 +299,7 @@ void GTARenderer::renderWorld()
|
||||
float mindist = 100000.f;
|
||||
for (size_t g = 0; g < inst.model->geometries.size(); g++)
|
||||
{
|
||||
RW::BSGeometryBounds& bounds = inst.model->geometries[g].geometryBounds;
|
||||
RW::BSGeometryBounds& bounds = inst.model->geometries[g]->geometryBounds;
|
||||
mindist = std::min(mindist, glm::length((glm::vec3(matrixModel[3])+bounds.center) - camera.worldPos) - bounds.radius);
|
||||
}
|
||||
|
||||
@ -421,7 +393,7 @@ void GTARenderer::renderNamedFrame(Model* model, const glm::mat4 &matrix, const
|
||||
}
|
||||
|
||||
size_t g = f;
|
||||
RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds;
|
||||
RW::BSGeometryBounds& bounds = model->geometries[g]->geometryBounds;
|
||||
if(! camera.frustum.intersects(bounds.center + glm::vec3(matrix[3]), bounds.radius)) {
|
||||
culled++;
|
||||
continue;
|
||||
@ -437,30 +409,25 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
|
||||
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g].VBO);
|
||||
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));
|
||||
glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, 0,
|
||||
(void *) ((model->geometries[g].vertices.size() * sizeof(float) * 3) + (model->geometries[g].texcoords.size() * sizeof(float) * 2))
|
||||
);
|
||||
glVertexAttribPointer(colourAttrib, 4, GL_FLOAT, GL_FALSE, 0,
|
||||
(void *) ((model->geometries[g].vertices.size() * sizeof(float) * 3)
|
||||
+ (model->geometries[g].texcoords.size() * sizeof(float) * 2)
|
||||
+ (model->geometries[g].normals.size() * sizeof(float) * 3))
|
||||
);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g]->VBO);
|
||||
|
||||
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsVert);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsTexCoords);
|
||||
glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsNormals);
|
||||
glVertexAttribPointer(colourAttrib, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsColours);
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
glEnableVertexAttribArray(normalAttrib);
|
||||
glEnableVertexAttribArray(colourAttrib);
|
||||
glEnableVertexAttribArray(normalAttrib);
|
||||
glEnableVertexAttribArray(colourAttrib);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g]->EBO);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g].EBO);
|
||||
for(size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg)
|
||||
{
|
||||
auto& subgeom = model->geometries[g]->subgeom[sg];
|
||||
|
||||
for(size_t sg = 0; sg < model->geometries[g].subgeom.size(); ++sg)
|
||||
{
|
||||
auto& subgeom = model->geometries[g].subgeom[sg];
|
||||
|
||||
if (model->geometries[g].materials.size() > subgeom.material) {
|
||||
Model::Material& mat = model->geometries[g].materials[subgeom.material];
|
||||
if (model->geometries[g]->materials.size() > subgeom.material) {
|
||||
Model::Material& mat = model->geometries[g]->materials[subgeom.material];
|
||||
|
||||
if(mat.textures.size() > 0 ) {
|
||||
TextureInfo& tex = engine->gameData.textures[mat.textures[0].name];
|
||||
@ -475,7 +442,7 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
|
||||
}
|
||||
}
|
||||
|
||||
if( (model->geometries[g].flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
|
||||
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
|
||||
auto colmasked = mat.colour;
|
||||
size_t R = colmasked % 256; colmasked /= 256;
|
||||
size_t G = colmasked % 256; colmasked /= 256;
|
||||
@ -503,9 +470,9 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
|
||||
|
||||
rendered++;
|
||||
|
||||
glDrawElements((model->geometries[g].facetype == Model::Triangles ?
|
||||
glDrawElements((model->geometries[g]->facetype == Model::Triangles ?
|
||||
GL_TRIANGLES : GL_TRIANGLE_STRIP),
|
||||
subgeom.indices.size(), GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * subgeom.start));
|
||||
subgeom.numIndices, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * subgeom.start));
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,7 +481,7 @@ void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAObj
|
||||
for (size_t a = 0; a < model->atomics.size(); a++)
|
||||
{
|
||||
size_t g = model->atomics[a].geometry;
|
||||
RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds;
|
||||
RW::BSGeometryBounds& bounds = model->geometries[g]->geometryBounds;
|
||||
if(! camera.frustum.intersects(bounds.center + glm::vec3(modelMatrix[3]), bounds.radius)) {
|
||||
culled++;
|
||||
continue;
|
||||
@ -530,7 +497,7 @@ void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAObj
|
||||
}
|
||||
}
|
||||
|
||||
if( (model->geometries[g].flags & RW::BSGeometry::ModuleMaterialColor) != RW::BSGeometry::ModuleMaterialColor) {
|
||||
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) != RW::BSGeometry::ModuleMaterialColor) {
|
||||
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include <renderwure/loaders/LoaderDFF.hpp>
|
||||
#include <renderwure/engine/GTAData.hpp>
|
||||
#include <renderwure/render/Model.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <cstring>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
@ -66,7 +68,8 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
|
||||
auto list = sec.readStructure<RW::BSGeometryList>();
|
||||
size_t gdataI = 0;
|
||||
while (sec.hasMoreData(gdataI)) {
|
||||
Model::Geometry geometryStruct;
|
||||
std::shared_ptr<Model::Geometry> geom(new Model::Geometry);
|
||||
|
||||
auto item = sec.getNextChildSection(gdataI);
|
||||
|
||||
if (item.header.id == RW::SID_Geometry) {
|
||||
@ -74,7 +77,7 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
|
||||
auto geometry = item.readStructure<RW::BSGeometry>();
|
||||
// std::cout << " verts(" << geometry.numverts << ") tris(" << geometry.numtris << ")" << std::endl;
|
||||
|
||||
geometryStruct.flags = geometry.flags;
|
||||
geom->flags = geometry.flags;
|
||||
|
||||
item.getNextChildSection(secI);
|
||||
char *data = item.raw() + sizeof(RW::BSSectionHeader) + sizeof(RW::BSGeometry);
|
||||
@ -82,7 +85,8 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
|
||||
if (item.header.versionid < 0x1003FFFF)
|
||||
auto colors = readStructure<RW::BSGeometryColor>(data, dataI);
|
||||
|
||||
geometryStruct.colours.reserve(geometry.numverts);
|
||||
std::vector<glm::vec4> colours;
|
||||
colours.resize(geometry.numverts);
|
||||
if ((geometry.flags & RW::BSGeometry::VertexColors) == RW::BSGeometry::VertexColors) {
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
auto s = readStructure<RW::BSColor>(data, dataI);
|
||||
@ -90,135 +94,56 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
|
||||
size_t G = s % 256; s /= 256;
|
||||
size_t B = s % 256; s /= 256;
|
||||
size_t A = s % 256;
|
||||
geometryStruct.colours.push_back(glm::vec4(R/255.f, G/255.f, B/255.f, A/255.f));
|
||||
colours[v] = glm::vec4(R/255.f, G/255.f, B/255.f, A/255.f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// To save needing another shader, just insert a white colour for each vertex
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
geometryStruct.colours.push_back(glm::vec4(1.f));
|
||||
colours[v] = glm::vec4(1.f);
|
||||
}
|
||||
}
|
||||
|
||||
geom->setColours(colours);
|
||||
|
||||
/** TEX COORDS **/
|
||||
if ((geometry.flags & RW::BSGeometry::TexCoords1) == RW::BSGeometry::TexCoords1 ||
|
||||
(geometry.flags & RW::BSGeometry::TexCoords2) == RW::BSGeometry::TexCoords1) {
|
||||
geometryStruct.texcoords.reserve(geometry.numverts);
|
||||
std::vector<glm::vec2> texcoords;
|
||||
texcoords.resize(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
geometryStruct.texcoords.push_back(readStructure<RW::BSGeometryUV>(data, dataI));
|
||||
texcoords[v] = readStructure<glm::vec2>(data, dataI);
|
||||
}
|
||||
geom->setTexCoords(texcoords);
|
||||
}
|
||||
|
||||
/** INDICIES **/
|
||||
geometryStruct.triangles.reserve(geometry.numtris);
|
||||
//geometryStruct.triangles.reserve(geometry.numtris);
|
||||
for (int j = 0; j < geometry.numtris; ++j) {
|
||||
geometryStruct.triangles.push_back(readStructure<RW::BSGeometryTriangle>(data, dataI));
|
||||
readStructure<RW::BSGeometryTriangle>(data, dataI);
|
||||
}
|
||||
|
||||
/** GEOMETRY BOUNDS **/
|
||||
geometryStruct.geometryBounds = readStructure<RW::BSGeometryBounds>(data, dataI);
|
||||
geom->geometryBounds = readStructure<RW::BSGeometryBounds>(data, dataI);
|
||||
|
||||
/** VERTICES **/
|
||||
geometryStruct.vertices.reserve(geometry.numverts);
|
||||
for (int v = 0; v < geometry.numverts; ++v) {
|
||||
geometryStruct.vertices.push_back(readStructure<RW::BSTVector3>(data, dataI));
|
||||
std::vector<glm::vec3> positions;
|
||||
positions.resize(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
positions[v] = readStructure<glm::vec3>(data, dataI);
|
||||
}
|
||||
geom->setVertexData(positions);
|
||||
|
||||
/** NORMALS **/
|
||||
if ((geometry.flags & RW::BSGeometry::StoreNormals) == RW::BSGeometry::StoreNormals) {
|
||||
geometryStruct.normals.reserve(geometry.numverts);
|
||||
for (int n = 0; n < geometry.numverts; ++n) {
|
||||
geometryStruct.normals.push_back(readStructure<RW::BSTVector3>(data, dataI));
|
||||
std::vector<glm::vec3> normals;
|
||||
normals.reserve(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
normals[v] = readStructure<glm::vec3>(data, dataI);
|
||||
}
|
||||
geom->setNormals(normals);
|
||||
}
|
||||
|
||||
/** TEXTURES **/
|
||||
auto materiallistsec = item.getNextChildSection(secI);
|
||||
auto materialList = materiallistsec.readStructure<RW::BSMaterialList>();
|
||||
|
||||
// Skip over the per-material byte values that I don't know what do.
|
||||
dataI += sizeof(uint32_t) * materialList.nummaterials;
|
||||
|
||||
size_t matI = 0;
|
||||
materiallistsec.getNextChildSection(matI);
|
||||
|
||||
geometryStruct.materials.resize(materialList.nummaterials);
|
||||
std::map<std::string, TextureInfo> availableTextures;
|
||||
|
||||
for (size_t m = 0; m < materialList.nummaterials; ++m) {
|
||||
auto materialsec = materiallistsec.getNextChildSection(matI);
|
||||
if (materialsec.header.id != RW::SID_Material)
|
||||
continue;
|
||||
|
||||
auto material = materialsec.readStructure<RW::BSMaterial>();
|
||||
geometryStruct.materials[m].textures.resize(material.numtextures);
|
||||
|
||||
geometryStruct.materials[m].colour = material.color;
|
||||
geometryStruct.materials[m].diffuseIntensity = material.diffuse;
|
||||
geometryStruct.materials[m].ambientIntensity = material.ambient;
|
||||
|
||||
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>();
|
||||
|
||||
std::string textureName, alphaName;
|
||||
size_t yetAnotherI = 0;
|
||||
texsec.getNextChildSection(yetAnotherI);
|
||||
|
||||
auto namesec = texsec.getNextChildSection(yetAnotherI);
|
||||
auto alphasec = texsec.getNextChildSection(yetAnotherI);
|
||||
|
||||
// The data is null terminated anyway.
|
||||
textureName = namesec.raw();
|
||||
alphaName = alphasec.raw();
|
||||
|
||||
geometryStruct.materials[m].textures[t] = {textureName, alphaName};
|
||||
}
|
||||
|
||||
if(geometryStruct.materials[m].textures.size() < 1) continue;
|
||||
|
||||
auto textureIt = gameData->textures
|
||||
.find(geometryStruct.materials[m].textures[0].name);
|
||||
if(textureIt != gameData->textures.end()) {
|
||||
availableTextures.insert({textureIt->first, textureIt->second});
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
geometryStruct.facetype = static_cast<Model::FaceType>(meshplg.facetype);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate normals if they don't exist already
|
||||
if (geometryStruct.normals.size() == 0) {
|
||||
geometryStruct.normals.resize(geometry.numverts);
|
||||
else {
|
||||
// Generate normals.
|
||||
/*geometryStruct.normals.resize(geometry.numverts);
|
||||
for (auto &subgeom : geometryStruct.subgeom) {
|
||||
glm::vec3 normal{0, 0, 0};
|
||||
for (size_t i = 0; i+2 < subgeom.indices.size(); i += 3) {
|
||||
@ -240,102 +165,99 @@ Model* LoaderDFF::loadFromMemory(char *data, GTAData *gameData)
|
||||
geometryStruct.normals[subgeom.indices[i+1]] = normal;
|
||||
geometryStruct.normals[subgeom.indices[i+2]] = normal;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/** TEXTURES **/
|
||||
auto materiallistsec = item.getNextChildSection(secI);
|
||||
auto materialList = materiallistsec.readStructure<RW::BSMaterialList>();
|
||||
|
||||
// Skip over the per-material byte values that I don't know what do.
|
||||
dataI += sizeof(uint32_t) * materialList.nummaterials;
|
||||
|
||||
size_t matI = 0;
|
||||
materiallistsec.getNextChildSection(matI);
|
||||
|
||||
geom->materials.resize(materialList.nummaterials);
|
||||
std::map<std::string, TextureInfo> availableTextures;
|
||||
|
||||
for (size_t m = 0; m < materialList.nummaterials; ++m) {
|
||||
auto materialsec = materiallistsec.getNextChildSection(matI);
|
||||
if (materialsec.header.id != RW::SID_Material)
|
||||
continue;
|
||||
|
||||
auto material = materialsec.readStructure<RW::BSMaterial>();
|
||||
geom->materials[m].textures.resize(material.numtextures);
|
||||
|
||||
geom->materials[m].colour = material.color;
|
||||
geom->materials[m].diffuseIntensity = material.diffuse;
|
||||
geom->materials[m].ambientIntensity = material.ambient;
|
||||
|
||||
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>();
|
||||
|
||||
std::string textureName, alphaName;
|
||||
size_t yetAnotherI = 0;
|
||||
texsec.getNextChildSection(yetAnotherI);
|
||||
|
||||
auto namesec = texsec.getNextChildSection(yetAnotherI);
|
||||
auto alphasec = texsec.getNextChildSection(yetAnotherI);
|
||||
|
||||
// The data is null terminated anyway.
|
||||
textureName = namesec.raw();
|
||||
alphaName = alphasec.raw();
|
||||
|
||||
geom->materials[m].textures[t] = {textureName, alphaName};
|
||||
}
|
||||
|
||||
if(geom->materials[m].textures.size() < 1) continue;
|
||||
|
||||
auto textureIt = gameData->textures
|
||||
.find(geom->materials[m].textures[0].name);
|
||||
if(textureIt != gameData->textures.end()) {
|
||||
availableTextures.insert({textureIt->first, textureIt->second});
|
||||
}
|
||||
}
|
||||
|
||||
// OpenGL buffer stuff
|
||||
glGenBuffers(1, &geometryStruct.VBO);
|
||||
glGenBuffers(1, &geometryStruct.EBO);
|
||||
|
||||
size_t buffsize = (geometryStruct.vertices.size() * sizeof(float) * 3)
|
||||
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
|
||||
+ (geometryStruct.normals.size() * sizeof(float) * 3)
|
||||
+ (geometryStruct.colours.size() * sizeof(glm::vec4));
|
||||
|
||||
// Vertices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, geometryStruct.VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffsize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
0,
|
||||
(geometryStruct.vertices.size() * sizeof(float) * 3),
|
||||
&geometryStruct.vertices[0]
|
||||
);
|
||||
|
||||
if(geometryStruct.texcoords.size() > 0)
|
||||
if(item.hasMoreData(secI))
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
(geometryStruct.vertices.size() * sizeof(float) * 3),
|
||||
(geometryStruct.texcoords.size() * sizeof(float) * 2),
|
||||
&geometryStruct.texcoords[0]
|
||||
);
|
||||
}
|
||||
|
||||
if(geometryStruct.normals.size() > 0 )
|
||||
{
|
||||
// std::cout << "Buffering " << geometryStruct.normals.size() << " normals" << std::endl;
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
(geometryStruct.vertices.size() * sizeof(float) * 3) + (geometryStruct.texcoords.size() * sizeof(float) * 2),
|
||||
geometryStruct.normals.size() * 3 * sizeof(float),
|
||||
&geometryStruct.normals[0]
|
||||
);
|
||||
}
|
||||
|
||||
if(geometryStruct.colours.size() > 0 )
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
(geometryStruct.vertices.size() * sizeof(float) * 3)
|
||||
+ (geometryStruct.texcoords.size() * sizeof(float) * 2)
|
||||
+ (geometryStruct.normals.size() * sizeof(float) * 3),
|
||||
geometryStruct.colours.size() * sizeof(glm::vec4),
|
||||
&geometryStruct.colours[0]
|
||||
);
|
||||
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);
|
||||
geom->subgeom.resize(meshplg.numsplits);
|
||||
geom->facetype = static_cast<Model::FaceType>(meshplg.facetype);
|
||||
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);
|
||||
geom->subgeom[i].material = plgHeader.index;
|
||||
geom->subgeom[i].indices = new uint32_t[plgHeader.numverts];
|
||||
geom->subgeom[i].numIndices = plgHeader.numverts;
|
||||
for (int j = 0; j < plgHeader.numverts; ++j) {
|
||||
geom->subgeom[i].indices[j] = extsec.readSubStructure<uint32_t>(meshplgI);
|
||||
meshplgI += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Elements
|
||||
uint16_t indicies[geometryStruct.triangles.size() * 3];
|
||||
size_t i = 0;
|
||||
for (auto &tri : geometryStruct.triangles) {
|
||||
indicies[i] = tri.first;
|
||||
indicies[i + 1] = tri.second;
|
||||
indicies[i + 2] = tri.third;
|
||||
i += 3;
|
||||
}
|
||||
|
||||
size_t Ecount = 0;
|
||||
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
||||
{
|
||||
geometryStruct.subgeom[i].start = Ecount;
|
||||
Ecount += geometryStruct.subgeom[i].indices.size();
|
||||
}
|
||||
geometryStruct.indicesCount = Ecount;
|
||||
|
||||
// Allocate complete EBO buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometryStruct.EBO);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(uint32_t) * geometryStruct.indicesCount,
|
||||
nullptr,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Upload each subgeometry
|
||||
for(size_t i = 0; i < geometryStruct.subgeom.size(); ++i)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
geometryStruct.subgeom[i].start * sizeof(uint32_t),
|
||||
sizeof(uint32_t) * geometryStruct.subgeom[i].indices.size(),
|
||||
&(geometryStruct.subgeom[i].indices[0]));
|
||||
}
|
||||
geom->buildBuffers();
|
||||
|
||||
geometryStruct.clumpNum = clumpID;
|
||||
geom->clumpNum = clumpID;
|
||||
|
||||
// Add it
|
||||
model->geometries.push_back(geometryStruct);
|
||||
model->geometries.push_back(geom);
|
||||
}
|
||||
}
|
||||
clumpID++;
|
||||
|
122
framework2/Model.cpp
Normal file
122
framework2/Model.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include "renderwure/render/Model.hpp"
|
||||
#include <GL/glew.h>
|
||||
|
||||
Model::Geometry::Geometry()
|
||||
: VBO(0), EBO(0),
|
||||
flags(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Model::Geometry::~Geometry()
|
||||
{
|
||||
if(VBO != 0) {
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
if(EBO != 0) {
|
||||
glDeleteBuffers(1, &EBO);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::Geometry::generateNormals()
|
||||
{
|
||||
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
void Model::Geometry::buildBuffers()
|
||||
{
|
||||
// OpenGL buffer stuff
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
size_t buffsize = (vertices.size() * sizeof(glm::vec3))
|
||||
+ texcoords.size() * sizeof(glm::vec2)
|
||||
+ normals.size() * sizeof(glm::vec3)
|
||||
+ colours.size() * sizeof(glm::vec4);
|
||||
|
||||
// Vertices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffsize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
size_t dataOffset = 0;
|
||||
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
0,
|
||||
(vertices.size() * sizeof(glm::vec3)),
|
||||
vertices.data()
|
||||
);
|
||||
offsVert = dataOffset;
|
||||
dataOffset += (vertices.size() * sizeof(glm::vec3));
|
||||
|
||||
if(texcoords.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
(texcoords.size() * sizeof(glm::vec2)),
|
||||
texcoords.data()
|
||||
);
|
||||
offsTexCoords = dataOffset;
|
||||
dataOffset += (texcoords.size() * sizeof(glm::vec2));
|
||||
}
|
||||
else {
|
||||
offsTexCoords = -1;
|
||||
}
|
||||
|
||||
if(normals.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
(normals.size() * sizeof(glm::vec3)),
|
||||
normals.data()
|
||||
);
|
||||
offsNormals = dataOffset;
|
||||
dataOffset += (normals.size() * sizeof(glm::vec3));
|
||||
}
|
||||
else {
|
||||
offsNormals = -1;
|
||||
}
|
||||
|
||||
if(colours.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
colours.size() * sizeof(glm::vec4),
|
||||
colours.data()
|
||||
);
|
||||
offsColours = dataOffset;
|
||||
}
|
||||
else {
|
||||
offsColours = -1;
|
||||
}
|
||||
|
||||
size_t Ecount = 0;
|
||||
for(size_t i = 0; i < subgeom.size(); ++i)
|
||||
{
|
||||
subgeom[i].start = Ecount;
|
||||
Ecount += subgeom[i].numIndices;
|
||||
}
|
||||
indicesCount = Ecount;
|
||||
|
||||
// Allocate complete EBO buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(uint32_t) * indicesCount,
|
||||
nullptr,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Upload each subgeometry
|
||||
for(size_t i = 0; i < subgeom.size(); ++i)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
subgeom[i].start * sizeof(uint32_t),
|
||||
sizeof(uint32_t) * subgeom[i].numIndices,
|
||||
subgeom[i].indices);
|
||||
}
|
||||
}
|
@ -11,91 +11,10 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class Model;
|
||||
|
||||
class GTAData;
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
enum FaceType {
|
||||
Triangles = 0,
|
||||
TriangleStrip = 1
|
||||
};
|
||||
|
||||
RW::BSClump clump;
|
||||
|
||||
struct Texture {
|
||||
std::string name;
|
||||
std::string alphaName;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
std::vector<Texture> textures;
|
||||
uint32_t colour;
|
||||
|
||||
float diffuseIntensity;
|
||||
float ambientIntensity;
|
||||
};
|
||||
|
||||
struct SubGeometry {
|
||||
GLuint start = 0;
|
||||
size_t material;
|
||||
std::vector<uint32_t> indices;
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
GLuint VBO, EBO;
|
||||
|
||||
RW::BSGeometryBounds geometryBounds;
|
||||
|
||||
uint32_t clumpNum;
|
||||
|
||||
FaceType facetype;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
std::vector<RW::BSGeometryUV> texcoords;
|
||||
std::vector<RW::BSGeometryTriangle> triangles;
|
||||
std::vector<glm::vec4> colours;
|
||||
std::vector<RW::BSTVector3> vertices;
|
||||
std::vector<RW::BSTVector3> normals;
|
||||
uint32_t indicesCount;
|
||||
|
||||
std::vector<Material> materials;
|
||||
std::vector<SubGeometry> subgeom;
|
||||
};
|
||||
|
||||
struct Atomic {
|
||||
uint32_t frame;
|
||||
uint32_t geometry;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
glm::mat4 matrix;
|
||||
glm::mat3 defaultRotation;
|
||||
glm::vec3 defaultTranslation;
|
||||
int32_t parentFrameIndex;
|
||||
};
|
||||
|
||||
std::vector<std::string> frameNames;
|
||||
|
||||
std::vector<Geometry> geometries;
|
||||
std::vector<Atomic> atomics;
|
||||
std::vector<Frame> frames;
|
||||
|
||||
int32_t rootFrameIdx;
|
||||
|
||||
glm::mat4 getFrameMatrix(int32_t frameIndex)
|
||||
{
|
||||
Frame& frame = frames[frameIndex];
|
||||
if( frame.parentFrameIndex != -1 ) {
|
||||
return getFrameMatrix(frame.parentFrameIndex) * frame.matrix;
|
||||
}
|
||||
else {
|
||||
return frame.matrix;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class LoaderDFF
|
||||
{
|
||||
private:
|
||||
|
119
framework2/include/renderwure/render/Model.hpp
Normal file
119
framework2/include/renderwure/render/Model.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
#pragma once
|
||||
#ifndef _MODEL_HPP_
|
||||
#define _MODEL_HPP_
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <glm/glm.hpp>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <renderwure/loaders/rwbinarystream.h>
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
enum FaceType {
|
||||
Triangles = 0,
|
||||
TriangleStrip = 1
|
||||
};
|
||||
|
||||
RW::BSClump clump;
|
||||
|
||||
struct Texture {
|
||||
std::string name;
|
||||
std::string alphaName;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
std::vector<Texture> textures;
|
||||
uint32_t colour;
|
||||
|
||||
float diffuseIntensity;
|
||||
float ambientIntensity;
|
||||
};
|
||||
|
||||
struct SubGeometry {
|
||||
GLuint start = 0;
|
||||
size_t material;
|
||||
uint32_t* indices;
|
||||
size_t numIndices;
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
GLuint VBO, EBO;
|
||||
|
||||
RW::BSGeometryBounds geometryBounds;
|
||||
|
||||
uint32_t clumpNum;
|
||||
|
||||
FaceType facetype;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
size_t offsVert;
|
||||
std::vector<glm::vec3> vertices;
|
||||
size_t offsNormals;
|
||||
std::vector<glm::vec3> normals;
|
||||
size_t offsTexCoords;
|
||||
std::vector<glm::vec2> texcoords;
|
||||
size_t offsColours;
|
||||
std::vector<glm::vec4> colours;
|
||||
|
||||
size_t indicesCount;
|
||||
|
||||
std::vector<Material> materials;
|
||||
std::vector<SubGeometry> subgeom;
|
||||
|
||||
Geometry();
|
||||
~Geometry();
|
||||
|
||||
void setVertexData(const std::vector<glm::vec3>& vertices) {
|
||||
this->vertices = vertices;
|
||||
}
|
||||
void setColours(const std::vector<glm::vec4>& colours) {
|
||||
this->colours = colours;
|
||||
}
|
||||
void setTexCoords(const std::vector<glm::vec2>& coords) {
|
||||
this->texcoords = coords;
|
||||
}
|
||||
void setNormals(const std::vector<glm::vec3>& normals) {
|
||||
this->normals = normals;
|
||||
}
|
||||
void generateNormals();
|
||||
|
||||
void buildBuffers();
|
||||
};
|
||||
|
||||
struct Atomic {
|
||||
uint32_t frame;
|
||||
uint32_t geometry;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
glm::mat4 matrix;
|
||||
glm::mat3 defaultRotation;
|
||||
glm::vec3 defaultTranslation;
|
||||
int32_t parentFrameIndex;
|
||||
};
|
||||
|
||||
std::vector<std::string> frameNames;
|
||||
|
||||
std::vector<std::shared_ptr<Geometry>> geometries;
|
||||
std::vector<Atomic> atomics;
|
||||
std::vector<Frame> frames;
|
||||
|
||||
int32_t rootFrameIdx;
|
||||
|
||||
glm::mat4 getFrameMatrix(int32_t frameIndex)
|
||||
{
|
||||
Frame& frame = frames[frameIndex];
|
||||
if( frame.parentFrameIndex != -1 ) {
|
||||
return getFrameMatrix(frame.parentFrameIndex) * frame.matrix;
|
||||
}
|
||||
else {
|
||||
return frame.matrix;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user