New model loading
This commit is contained in:
1
lib/CMakeLists.txt
vendored
1
lib/CMakeLists.txt
vendored
@@ -1,4 +1,3 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/stb)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glm)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/assimp)
|
||||
|
||||
@@ -48,21 +48,21 @@ void Controller::run() {
|
||||
|
||||
std::vector<Entity> scene;
|
||||
|
||||
//Model model_backpack("res/models/backpack.obj");
|
||||
Model model_plant("res/models/plant.obj");
|
||||
//Model model_container("res/models/container.obj");
|
||||
Model model_cube("res/models/cube.obj");
|
||||
//Model model_sphere("res/models/sphere.obj");
|
||||
Model model_backpack("res/models/backpack.ffo");
|
||||
//Model model_plant("res/models/plant.obj");
|
||||
//Model model_container("res/models/container.ffo");
|
||||
Model model_cube("res/models/cube.ffo");
|
||||
//Model model_sphere("res/models/sphere.ffo");
|
||||
|
||||
//Entity backpack1(&model_backpack, &shaderProgram);
|
||||
Entity backpack(&model_backpack, &shaderProgram);
|
||||
//Entity sphere(&model_sphere, &shaderProgram);
|
||||
//Entity cube(&model_container, &shaderProgram);
|
||||
Entity plant(&model_plant, &shaderProgram);
|
||||
//Entity container(&model_container, &shaderProgram);
|
||||
//Entity plant(&model_plant, &shaderProgram);
|
||||
Entity lightSource(&model_cube, &lightProgram);
|
||||
|
||||
lightSource.translate(glm::vec3(-5.0f, 1.0f, 0.0f));
|
||||
lightSource.scale(0.2f);
|
||||
plant.scale(5.0f);
|
||||
//plant.scale(5.0f);
|
||||
|
||||
glm::vec3 lightColor = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 diffuseColor = lightColor * glm::vec3(1.0f);
|
||||
@@ -86,7 +86,7 @@ void Controller::run() {
|
||||
shaderProgram.setUniform("u_material.shininess", 32.0f);
|
||||
shaderProgram.unbind();
|
||||
|
||||
scene.push_back(plant);
|
||||
scene.push_back(backpack);
|
||||
scene.push_back(lightSource);
|
||||
|
||||
camera->translate(glm::vec3(0.0f, 0.0f, 7.5f));
|
||||
|
||||
168
src/Model.cpp
168
src/Model.cpp
@@ -1,11 +1,16 @@
|
||||
#include "Model.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
|
||||
Model::Model(const char* pathToModel) {
|
||||
// Todo: check if model isn't already loaded --> will boost startup time drastically
|
||||
// actually all models should be loaded at startup and only a handle should be given to the entites...
|
||||
|
||||
std::string modelSource = pathToModel;
|
||||
directory = modelSource.substr(0, modelSource.find_last_of('/'));
|
||||
|
||||
loadModel(pathToModel);
|
||||
|
||||
}
|
||||
|
||||
Model::~Model() {
|
||||
@@ -25,122 +30,79 @@ void Model::draw(ShaderProgram *shaderProgram) {
|
||||
}
|
||||
|
||||
void Model::loadModel(std::string pathToModel) {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(pathToModel, aiProcess_Triangulate | aiProcess_FlipUVs); //aiProcess_OptimizeMeshes ?
|
||||
|
||||
std::ifstream input(pathToModel, std::ios::in | std::ios::binary);
|
||||
|
||||
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
||||
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
|
||||
return;
|
||||
if(!input.is_open()) {
|
||||
std::cout << "Could not find model file " << pathToModel << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t numTextures;
|
||||
input.read((char*) &numTextures, sizeof(uint32_t));
|
||||
|
||||
std::vector<uint32_t> textureTypes;
|
||||
for(unsigned int i = 0; i < numTextures; i++) {
|
||||
uint32_t currentTextureType;
|
||||
input.read((char*) ¤tTextureType, sizeof(uint32_t));
|
||||
textureTypes.push_back(currentTextureType);
|
||||
}
|
||||
|
||||
directory = pathToModel.substr(0, pathToModel.find_last_of('/'));
|
||||
std::vector<std::string> textureSources;
|
||||
for(unsigned int i = 0; i < numTextures; i++) {
|
||||
std::string currentTextureSource;
|
||||
for(unsigned int i = 0; i < 128; i++) {
|
||||
uint8_t currentChar;
|
||||
input.read((char*) ¤tChar, sizeof(uint8_t));
|
||||
|
||||
processNode(scene->mRootNode, scene);
|
||||
}
|
||||
|
||||
void Model::processNode(aiNode *node, const aiScene *scene) {
|
||||
|
||||
// Push the node's meshes into the mesh vector
|
||||
for(uint32_t i = 0; i < node->mNumMeshes; i++) {
|
||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
meshes.push_back(processMesh(mesh, scene));
|
||||
if(currentChar)
|
||||
currentTextureSource.push_back(currentChar);
|
||||
}
|
||||
textureSources.push_back(currentTextureSource);
|
||||
}
|
||||
|
||||
// Process child nodes too
|
||||
for(uint32_t i = 0; i < node->mNumChildren; i++) {
|
||||
processNode(node->mChildren[i], scene);
|
||||
for(unsigned int i = 0; i < numTextures; i++) {
|
||||
std::string textureSource = directory + '/' + textureSources[i].c_str();
|
||||
Texture *newTex = new Texture(textureSource.c_str(), textureTypes[i]);
|
||||
loadedTextures.push_back(newTex);
|
||||
}
|
||||
|
||||
}
|
||||
// Here starts the first mesh
|
||||
uint32_t numMeshes;
|
||||
for(unsigned int j = 0; j < numMeshes; j++) {
|
||||
|
||||
Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene) {
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
std::vector<Texture*> textures;
|
||||
input.read((char*) &numMeshes, sizeof(uint32_t));
|
||||
|
||||
for(uint32_t i = 0; i < mesh->mNumVertices; i++) {
|
||||
Vertex vertex;
|
||||
uint32_t numMeshVertices, numMeshIndices, numMeshTextureIds;
|
||||
|
||||
// Position
|
||||
glm::vec3 vector;
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.position = vector;
|
||||
input.read((char*) &numMeshVertices, sizeof(uint32_t));
|
||||
input.read((char*) &numMeshIndices, sizeof(uint32_t));
|
||||
input.read((char*) &numMeshTextureIds, sizeof(uint32_t));
|
||||
|
||||
// Normals
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.normalVec = vector;
|
||||
// Here starts the first Vertex data
|
||||
|
||||
// Texture UV mapping
|
||||
if(mesh->mTextureCoords[0]) {
|
||||
glm::vec2 vec;
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.textureCoords = vec;
|
||||
} else {
|
||||
vertex.textureCoords = glm::vec2(0.0f, 0.0f);
|
||||
std::vector<Vertex> meshVertices;
|
||||
for(unsigned int i = 0; i < numMeshVertices; i++) {
|
||||
Vertex currentVertex;
|
||||
input.read((char*) ¤tVertex, sizeof(Vertex));
|
||||
meshVertices.push_back(currentVertex);
|
||||
}
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
|
||||
// Indices
|
||||
for(uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
aiFace face = mesh->mFaces[i];
|
||||
for(uint32_t j = 0; j < face.mNumIndices; j++) {
|
||||
indices.push_back(face.mIndices[j]);
|
||||
std::vector<uint32_t> meshIndices;
|
||||
for(unsigned int i = 0; i < numMeshIndices; i++) {
|
||||
uint32_t currentIndex;
|
||||
input.read((char*) ¤tIndex, sizeof(uint32_t));
|
||||
meshIndices.push_back(currentIndex);
|
||||
}
|
||||
|
||||
std::vector<Texture*> meshTextures;
|
||||
for(unsigned int i = 0; i < numMeshTextureIds; i++) {
|
||||
uint32_t currentTextureId;
|
||||
input.read((char*) ¤tTextureId, sizeof(uint32_t));
|
||||
meshTextures.push_back(loadedTextures[currentTextureId]);
|
||||
}
|
||||
|
||||
Mesh currentMesh(meshVertices, meshIndices, meshTextures);
|
||||
meshes.push_back(currentMesh);
|
||||
}
|
||||
|
||||
// Material
|
||||
if(mesh->mMaterialIndex > 0) {
|
||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
std::vector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, texture_diffuse);
|
||||
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||
|
||||
std::vector<Texture*> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, texture_specular);
|
||||
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
|
||||
|
||||
std::vector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, texture_normal);
|
||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||
|
||||
std::vector<Texture*> heightMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, texture_height);
|
||||
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
|
||||
}
|
||||
|
||||
return Mesh(vertices, indices, textures);
|
||||
}
|
||||
|
||||
std::vector<Texture*> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType) {
|
||||
|
||||
std::vector<Texture*> textures;
|
||||
for(uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
||||
aiString filename;
|
||||
mat->GetTexture(type, i, &filename);
|
||||
|
||||
std::string currentPath = directory + '/' + filename.C_Str();
|
||||
|
||||
bool skip = 0;
|
||||
for(uint32_t j = 0; j < loadedTextures.size(); j++) {
|
||||
if(std::strcmp(loadedTextures[j]->getPath().c_str(), currentPath.c_str()) == 0) {
|
||||
textures.push_back(loadedTextures[j]);
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip) {
|
||||
Texture *texture = new Texture(currentPath.c_str(), textureType);
|
||||
loadedTextures.push_back(texture);
|
||||
|
||||
// Add newest texture pointer to the mesh's texture-pointer vector
|
||||
Texture *new_tex = loadedTextures.back();
|
||||
textures.push_back(new_tex);
|
||||
}
|
||||
}
|
||||
|
||||
return textures;
|
||||
}
|
||||
|
||||
14
src/Model.h
14
src/Model.h
@@ -1,10 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Mesh.h"
|
||||
|
||||
@@ -22,17 +19,10 @@ private:
|
||||
|
||||
void loadModel(std::string pathToModel);
|
||||
|
||||
void processNode(aiNode *node, const aiScene *scene);
|
||||
Mesh processMesh(aiMesh *mesh, const aiScene *scene);
|
||||
|
||||
std::vector<Texture*> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType);
|
||||
|
||||
|
||||
std::vector<Mesh> meshes;
|
||||
|
||||
std::vector<Texture*> loadedTextures;
|
||||
|
||||
void textureFromFile(aiMaterial *mat, aiTextureType type);
|
||||
|
||||
std::string directory;
|
||||
|
||||
};
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include <cstdint>
|
||||
#include <glad/glad.h>
|
||||
#include <string>
|
||||
|
||||
enum textureType{texture_diffuse, texture_specular, texture_normal, texture_height, TEXTURE_TYPE_NUM_ITEMS};
|
||||
|
||||
class Texture {
|
||||
|
||||
public:
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
#define INIT_WINDOW_WIDTH 960
|
||||
#define INIT_WINDOW_HEIGHT 720
|
||||
|
||||
enum textureType{texture_diffuse, texture_specular, texture_normal, texture_height, TEXTURE_TYPE_NUM_ITEMS};
|
||||
|
||||
struct Vertex {
|
||||
// Postition
|
||||
glm::vec3 position;
|
||||
|
||||
@@ -2,4 +2,4 @@ project(obj-converter)
|
||||
|
||||
add_executable(obj-converter main.cpp)
|
||||
|
||||
target_link_libraries(obj-converter assimp)
|
||||
target_link_libraries(obj-converter assimp glm)
|
||||
|
||||
29
tools/fileformat.txt
Normal file
29
tools/fileformat.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
NUM_TEXTURES
|
||||
TYPE_DIFFUSE
|
||||
TYPE_DIFFUSE
|
||||
TYPE_SPECULAR
|
||||
TYPE_NORMAL
|
||||
TYPE_HEIGHT
|
||||
./diffuse0.jpg000000000000
|
||||
./diffuse1.jpg000000000000
|
||||
./specular.jpg000000000000
|
||||
./normal.jpg00000000000000
|
||||
./height.jpg00000000000000
|
||||
NUM_VERTICES
|
||||
NUM_INDICES
|
||||
NUM_TEXTUREIDS
|
||||
<mesh1_vertexdata>
|
||||
<mesh1_indexdata>
|
||||
<mesh1_textureiddata>
|
||||
NUM_VERTICES
|
||||
NUM_INDICES
|
||||
NUM_TEXTUREIDS
|
||||
<mesh2_vertexdata>
|
||||
<mesh2_indexdata>
|
||||
<mesh2_textureiddata>
|
||||
NUM_VERTICES
|
||||
NUM_INDICES
|
||||
NUM_TEXTUREIDS
|
||||
<mesh3_vertexdata>
|
||||
<mesh3_indexdata>
|
||||
<mesh3_textureiddata>
|
||||
237
tools/main.cpp
237
tools/main.cpp
@@ -1,7 +1,240 @@
|
||||
/*
|
||||
|
||||
This is the tool to generate model files for the Fall-Fever game. It's used to
|
||||
reduce loading time of the game, and also to reduce runtime dependencies (libassimp).
|
||||
|
||||
The model files do not support material colors; only textures at this point.
|
||||
All path strings are 128 elements long.
|
||||
|
||||
*/
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
|
||||
#include "../src/defines.h"
|
||||
#include "primitiveModel.h"
|
||||
|
||||
void processNode(aiNode *node, const aiScene *scene, Model *model);
|
||||
Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model);
|
||||
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, Model *model);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(argc <= 1) {
|
||||
std::cout << "Usage: " << argv[0] << " <Modelfiles>" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<std::string> modelSources;
|
||||
|
||||
for(int i = 0; i < argc - 1; i++) {
|
||||
modelSources.push_back(argv[i+1]);
|
||||
}
|
||||
|
||||
Assimp::Importer importer;
|
||||
|
||||
for(auto it = modelSources.begin(); it != modelSources.end(); it++) {
|
||||
unsigned int flags =
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_FlipUVs |
|
||||
aiProcess_PreTransformVertices |
|
||||
aiProcess_GenNormals |
|
||||
aiProcess_OptimizeMeshes |
|
||||
aiProcess_OptimizeGraph |
|
||||
aiProcess_JoinIdenticalVertices |
|
||||
aiProcess_ImproveCacheLocality |
|
||||
aiProcess_CalcTangentSpace;
|
||||
|
||||
const aiScene* scene = importer.ReadFile((*it).c_str(), flags);
|
||||
|
||||
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
||||
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Model currentModel;
|
||||
if(((*it).find('/')) < (*it).length()) {
|
||||
// source includes a /
|
||||
currentModel.directory = (*it).substr(0, (*it).find_last_of('/'));
|
||||
} else {
|
||||
currentModel.directory = ".";
|
||||
}
|
||||
|
||||
processNode(scene->mRootNode, scene, ¤tModel);
|
||||
|
||||
std::string filenameWithoutExtension = (*it).substr(0, (*it).find_last_of('.'));
|
||||
std::string outputFilename = filenameWithoutExtension + ".ffo";
|
||||
|
||||
std::ofstream output(outputFilename, std::ios::out | std::ios::binary);
|
||||
|
||||
uint32_t numTextures = currentModel.textures.size();
|
||||
output.write((char*) &numTextures, sizeof(uint32_t));
|
||||
|
||||
// Write texture types in order
|
||||
for(auto it1 = currentModel.textures.begin(); it1 != currentModel.textures.end(); it1++) {
|
||||
uint32_t currentTextureType = (*it1).textureType;
|
||||
output.write((char*) ¤tTextureType, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
// Write texture sources
|
||||
for(auto it1 = currentModel.textures.begin(); it1 != currentModel.textures.end(); it1++) {
|
||||
for(unsigned int i = 0; i < 128; i++) {
|
||||
if(i < (*it1).pathToTexture.size()) {
|
||||
uint8_t character = (*it1).pathToTexture[i];
|
||||
output.write((char*) &character, sizeof(uint8_t));
|
||||
} else {
|
||||
uint8_t character = 0;
|
||||
output.write((char*) &character, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Write meshes
|
||||
uint32_t numMeshes = currentModel.meshes.size();
|
||||
output.write((char*) &numMeshes, sizeof(uint32_t));
|
||||
for(auto it1 = currentModel.meshes.begin(); it1 != currentModel.meshes.end(); it1++) {
|
||||
uint32_t numVertices = (*it1).vertices.size();
|
||||
uint32_t numIndices = (*it1).indices.size();
|
||||
uint32_t numTextureIds = (*it1).textureIds.size();
|
||||
|
||||
output.write((char*) &numVertices, sizeof(uint32_t));
|
||||
output.write((char*) &numIndices, sizeof(uint32_t));
|
||||
output.write((char*) &numTextureIds, sizeof(uint32_t));
|
||||
|
||||
Vertex *vertexData = (*it1).vertices.data();
|
||||
output.write((char*) vertexData, numVertices * sizeof(Vertex));
|
||||
|
||||
uint32_t *indexData = (*it1).indices.data();
|
||||
output.write((char*) indexData, numIndices * sizeof(uint32_t));
|
||||
|
||||
uint32_t *textureIdData = (*it1).textureIds.data();
|
||||
output.write((char*) textureIdData, numTextureIds * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
output.close();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void processNode(aiNode *node, const aiScene *scene, Model* model) {
|
||||
|
||||
// Push the node's meshes into the mesh vector
|
||||
for(uint32_t i = 0; i < node->mNumMeshes; i++) {
|
||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
model->meshes.push_back(processMesh(mesh, scene, model));
|
||||
}
|
||||
|
||||
// Process child nodes too
|
||||
for(uint32_t i = 0; i < node->mNumChildren; i++) {
|
||||
processNode(node->mChildren[i], scene, model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model) {
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
std::vector<Texture> textures;
|
||||
Mesh currentMesh;
|
||||
|
||||
for(uint32_t i = 0; i < mesh->mNumVertices; i++) {
|
||||
Vertex vertex;
|
||||
|
||||
// Position
|
||||
glm::vec3 vector;
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.position = vector;
|
||||
|
||||
// Normals
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.normalVec = vector;
|
||||
|
||||
// Texture UV mapping
|
||||
if(mesh->mTextureCoords[0]) {
|
||||
glm::vec2 vec;
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.textureCoords = vec;
|
||||
} else {
|
||||
vertex.textureCoords = glm::vec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
|
||||
// Indices
|
||||
for(uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||
aiFace face = mesh->mFaces[i];
|
||||
for(uint32_t j = 0; j < face.mNumIndices; j++) {
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Material
|
||||
if(mesh->mMaterialIndex > 0) {
|
||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
std::vector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, texture_diffuse, ¤tMesh, model);
|
||||
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||
|
||||
std::vector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, texture_specular, ¤tMesh, model);
|
||||
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
|
||||
|
||||
std::vector<Texture> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, texture_normal, ¤tMesh, model);
|
||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||
|
||||
std::vector<Texture> heightMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, texture_height, ¤tMesh, model);
|
||||
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
|
||||
}
|
||||
|
||||
currentMesh.vertices = vertices;
|
||||
currentMesh.indices = indices;
|
||||
|
||||
return currentMesh;
|
||||
}
|
||||
|
||||
std::vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, Model *model) {
|
||||
|
||||
std::vector<Texture> textures;
|
||||
for(uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
||||
aiString filename;
|
||||
mat->GetTexture(type, i, &filename);
|
||||
|
||||
std::string currentPath = model->directory + '/' + filename.C_Str();
|
||||
|
||||
bool skip = 0;
|
||||
for(uint32_t j = 0; j < model->textures.size(); j++) {
|
||||
if(std::strcmp(model->textures[j].pathToTexture.c_str(), currentPath.c_str()) == 0) {
|
||||
textures.push_back(model->textures[j]);
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip) {
|
||||
Texture texture;
|
||||
texture.pathToTexture = currentPath;
|
||||
texture.textureType = textureType;
|
||||
// textureIds start at 0, but vector elements start at 1.
|
||||
texture.textureId = model->textures.size();
|
||||
|
||||
model->textures.push_back(texture);
|
||||
|
||||
// Add newest texture id to mesh
|
||||
mesh->textureIds.push_back(texture.textureId);
|
||||
}
|
||||
}
|
||||
|
||||
return textures;
|
||||
}
|
||||
|
||||
28
tools/primitiveModel.h
Normal file
28
tools/primitiveModel.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct Texture {
|
||||
|
||||
std::string pathToTexture;
|
||||
uint32_t textureType;
|
||||
uint32_t textureId;
|
||||
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
std::vector<uint32_t> textureIds;
|
||||
|
||||
};
|
||||
|
||||
struct Model {
|
||||
|
||||
std::vector<Texture> textures;
|
||||
std::vector<Mesh> meshes;
|
||||
std::string directory;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user