Working Multithreading

This commit is contained in:
2021-04-13 20:29:29 +02:00
parent 741f44e7d8
commit d3c755713d
7 changed files with 83 additions and 32 deletions

View File

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

View File

@@ -13,7 +13,7 @@
class JsonParser
{
public:
JsonParser(std::string path);
JsonParser(const std::string& path);
~JsonParser();
std::vector<Model*> getModels();

View File

@@ -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 *) &currentTextureId, 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];

View File

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

View File

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

View File

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

View File

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