Working Multithreading
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
#include <iostream>
|
||||
#include <future>
|
||||
|
||||
JsonParser::JsonParser(std::string path)
|
||||
JsonParser::JsonParser(const std::string& path)
|
||||
{
|
||||
std::ifstream file(path.c_str(), std::ifstream::binary);
|
||||
|
||||
@@ -28,17 +28,6 @@ JsonParser::~JsonParser()
|
||||
|
||||
}
|
||||
|
||||
static std::mutex s_ModelsMutex;
|
||||
|
||||
static void loadModel(const std::string modelName, const std::string modelPath, std::vector<Model*>* model_vec) {
|
||||
Model *current_model = new Model(modelName, modelPath);
|
||||
if(current_model) {
|
||||
std::lock_guard<std::mutex> lock(s_ModelsMutex);
|
||||
model_vec->push_back(current_model);
|
||||
std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Model*> JsonParser::getModels()
|
||||
{
|
||||
std::vector<Model*> temp_models;
|
||||
@@ -60,19 +49,20 @@ std::vector<Model*> JsonParser::getModels()
|
||||
}
|
||||
|
||||
std::vector<std::future<void>> futures;
|
||||
std::mutex mutex;
|
||||
|
||||
auto* temp_models_ptr = &temp_models;
|
||||
for (const auto& model_skeleton : model_skeletons) {
|
||||
/*auto loadModel = [](const std::string& modelName, const std::string& modelPath, std::mutex& mutex, std::vector<Model*>* model_vec) {
|
||||
Model *current_model = new Model(modelName, modelPath);
|
||||
auto loadModel = [&]() {
|
||||
Model *current_model = new Model(model_skeleton.model_name, model_skeleton.model_path);
|
||||
if(current_model) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
model_vec->push_back(current_model);
|
||||
std::cout << "Loaded Model \"" << modelName << "\" from \"" << modelPath << "\"" << std::endl;
|
||||
temp_models_ptr->push_back(current_model);
|
||||
std::cout << "Loaded Model \"" << model_skeleton.model_name << "\" from \"" << model_skeleton.model_path << "\"" << std::endl;
|
||||
}
|
||||
};*/
|
||||
};
|
||||
|
||||
futures.push_back(std::async(std::launch::async, loadModel, model_skeleton.model_name, model_skeleton.model_path, temp_models_ptr));
|
||||
futures.push_back(std::async(std::launch::async, loadModel));
|
||||
}
|
||||
|
||||
return temp_models;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
class JsonParser
|
||||
{
|
||||
public:
|
||||
JsonParser(std::string path);
|
||||
JsonParser(const std::string& path);
|
||||
~JsonParser();
|
||||
|
||||
std::vector<Model*> getModels();
|
||||
|
||||
@@ -24,6 +24,11 @@ Model::~Model()
|
||||
|
||||
void Model::draw(ShaderProgram *shaderProgram)
|
||||
{
|
||||
if (!model_prepared) {
|
||||
std::cout << "WARNING: Model not prepared! Unable to draw!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate through every mesh and call the draw function
|
||||
for (auto it = meshes.begin(); it != meshes.end(); it++) {
|
||||
(*it)->draw(shaderProgram);
|
||||
@@ -32,6 +37,11 @@ void Model::draw(ShaderProgram *shaderProgram)
|
||||
|
||||
void Model::drawWithoutTextures()
|
||||
{
|
||||
if (!model_prepared) {
|
||||
std::cout << "WARNING: Model not prepared! Unable to draw!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate through every mesh and call the draw function
|
||||
for (auto it = meshes.begin(); it != meshes.end(); it++) {
|
||||
(*it)->drawWithoutTextures();
|
||||
@@ -71,10 +81,15 @@ void Model::loadModel(const std::string &pathToModel)
|
||||
textureSources.push_back(currentTextureSource);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
TexturePrototype texture_prototype;
|
||||
std::string texturePath = directory + '/' + textureSources[i].c_str();
|
||||
|
||||
texture_prototype.texturePath = std::move(texturePath);
|
||||
texture_prototype.textureType = textureTypes[i];
|
||||
|
||||
modelTexturePrototypes.push_back(texture_prototype);
|
||||
}
|
||||
|
||||
// Here starts the first mesh
|
||||
@@ -83,6 +98,8 @@ void Model::loadModel(const std::string &pathToModel)
|
||||
|
||||
for (unsigned int j = 0; j < numMeshes; j++) {
|
||||
|
||||
MeshPrototype mesh_prototype;
|
||||
|
||||
uint32_t numMeshVertices, numMeshIndices, numMeshTextureIds;
|
||||
|
||||
input.read((char *) &numMeshVertices, sizeof(uint32_t));
|
||||
@@ -97,25 +114,48 @@ void Model::loadModel(const std::string &pathToModel)
|
||||
std::vector<Vertex> meshVertices;
|
||||
meshVertices.resize(numMeshVertices);
|
||||
input.read((char *) meshVertices.data(), vertexBlockSize);
|
||||
mesh_prototype.meshVertices = std::move(meshVertices);
|
||||
|
||||
std::vector<uint32_t> meshIndices;
|
||||
meshIndices.resize(numMeshIndices);
|
||||
input.read((char *) meshIndices.data(), indexBlockSize);
|
||||
mesh_prototype.meshIndices = std::move(meshIndices);
|
||||
|
||||
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_prototype.textureIds.push_back(currentTextureId);
|
||||
}
|
||||
|
||||
Mesh *currentMesh = new Mesh(meshVertices, meshIndices, meshTextures);
|
||||
meshes.push_back(currentMesh);
|
||||
modelMeshPrototypes.push_back(std::move(mesh_prototype));
|
||||
}
|
||||
|
||||
input.close();
|
||||
}
|
||||
|
||||
void Model::prepareModel()
|
||||
{
|
||||
model_prepared = true;
|
||||
|
||||
// Create textures on GPU
|
||||
for (auto& it : modelTexturePrototypes) {
|
||||
Texture *newTex = new Texture(it.texturePath.c_str(), it.textureType);
|
||||
loadedTextures.push_back(newTex);
|
||||
}
|
||||
|
||||
// Create meshes on GPU
|
||||
for (const auto& it : modelMeshPrototypes) {
|
||||
std::vector<Texture *> meshTextures;
|
||||
for (const auto it2 : it.textureIds) {
|
||||
meshTextures.push_back(loadedTextures[it2]);
|
||||
}
|
||||
|
||||
Mesh *currentMesh = new Mesh(std::move(it.meshVertices), std::move(it.meshIndices), meshTextures);
|
||||
meshes.push_back(currentMesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Mesh* Model::getMesh(unsigned int index)
|
||||
{
|
||||
return meshes[index];
|
||||
|
||||
18
src/Model.h
18
src/Model.h
@@ -5,12 +5,25 @@
|
||||
|
||||
#include "Mesh.h"
|
||||
|
||||
struct TexturePrototype {
|
||||
uint32_t textureType;
|
||||
std::string texturePath;
|
||||
};
|
||||
|
||||
struct MeshPrototype {
|
||||
std::vector<uint32_t> textureIds;
|
||||
std::vector<Vertex> meshVertices;
|
||||
std::vector<uint32_t> meshIndices;
|
||||
};
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
Model(const std::string& modelName, const std::string& pathToModel);
|
||||
~Model();
|
||||
|
||||
void prepareModel();
|
||||
|
||||
void draw(ShaderProgram *shaderProgram);
|
||||
void drawWithoutTextures();
|
||||
|
||||
@@ -24,8 +37,13 @@ private:
|
||||
std::vector<Mesh *> meshes;
|
||||
std::vector<Texture *> loadedTextures;
|
||||
|
||||
std::vector<TexturePrototype> modelTexturePrototypes;
|
||||
std::vector<MeshPrototype> modelMeshPrototypes;
|
||||
|
||||
std::string directory;
|
||||
|
||||
bool model_prepared = false;
|
||||
|
||||
static uint32_t id_counter;
|
||||
uint32_t id;
|
||||
std::string unique_name;
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
#include <stb/stb_image.h>
|
||||
#include <iostream>
|
||||
|
||||
Texture::Texture(const char *texturePath, uint8_t textureType)
|
||||
Texture::Texture(const std::string& texturePath, uint8_t textureType) :
|
||||
texturePath(texturePath), textureType(textureType)
|
||||
{
|
||||
this->texturePath = texturePath;
|
||||
this->textureType = textureType;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
auto *textureBuffer = stbi_load(texturePath, &textureWidth, &textureHeight, &numComponents, 0);
|
||||
auto *textureBuffer = stbi_load(texturePath.c_str(), &textureWidth, &textureHeight, &numComponents, 0);
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum dataFormat;
|
||||
|
||||
@@ -15,7 +15,7 @@ enum cubeMapFaces {cm_right, cm_left, cm_top, cm_bottom, cm_back, cm_front, CUBE
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
Texture(const char *texturePath, uint8_t textureType);
|
||||
Texture(const std::string& texturePath, uint8_t textureType);
|
||||
~Texture();
|
||||
|
||||
void bind(uint8_t textureUnit, ShaderProgram *shaderProgram, uint8_t textureTypeNum);
|
||||
|
||||
@@ -21,6 +21,11 @@ World::World(std::vector<ShaderProgram*> shaderPrograms) :
|
||||
|
||||
JsonParser modelParser("data/models.json");
|
||||
models = modelParser.getModels();
|
||||
|
||||
for (const auto& it : models) {
|
||||
it->prepareModel();
|
||||
}
|
||||
|
||||
entities = modelParser.getEntities(models, shaderPrograms);
|
||||
skybox = modelParser.getSkybox(getModelByName("cube"), Controller::getShaderProgramByName(shaderPrograms, "skyboxProgram"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user