1
0
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:
Daniel Evans 2013-09-25 09:05:18 +01:00
parent 5e0d021b4f
commit ffea4964e3
7 changed files with 384 additions and 333 deletions

View File

@ -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)

View File

@ -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>

View File

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

View File

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

View File

@ -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:

View 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