Optimize model texture loading, test assimp with complicated model
This commit is contained in:
parent
ab3f6c98ff
commit
475bb08f0e
|
@ -1,5 +1,2 @@
|
||||||
*.blend
|
*
|
||||||
*.obj
|
!shaders
|
||||||
*.png
|
|
||||||
*.bin
|
|
||||||
*.gltf
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "entt/entity/fwd.hpp"
|
|
||||||
#include "simpleengine/camera.h"
|
#include "simpleengine/camera.h"
|
||||||
#include "simpleengine/ecs/component/mesh_component.h"
|
#include "simpleengine/ecs/component/mesh_component.h"
|
||||||
#include <simpleengine/ecs/component/model_component.h>
|
#include <simpleengine/ecs/component/model_component.h>
|
||||||
|
@ -12,7 +11,6 @@
|
||||||
#include "simpleengine/gfx/renderer.h"
|
#include "simpleengine/gfx/renderer.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/vector.h"
|
#include "simpleengine/vector.h"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <simpleengine/gfx/shader.h>
|
#include <simpleengine/gfx/shader.h>
|
||||||
#include <simpleengine/renderable.h>
|
#include <simpleengine/renderable.h>
|
||||||
#include <simpleengine/event/event.h>
|
#include <simpleengine/event/event.h>
|
||||||
|
@ -21,11 +19,8 @@
|
||||||
#include <simpleengine/vertex.h>
|
#include <simpleengine/vertex.h>
|
||||||
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
||||||
#include <simpleengine/gfx/model.h>
|
#include <simpleengine/gfx/model.h>
|
||||||
|
|
||||||
#include <simpleengine/scene.h>
|
#include <simpleengine/scene.h>
|
||||||
|
|
||||||
//#include <simpleengine/scene.h>
|
|
||||||
|
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
#include <glm/fwd.hpp>
|
#include <glm/fwd.hpp>
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
|
@ -170,8 +165,8 @@ int main(int argc, char *argv[]) {
|
||||||
5, 6, 12, 12, 6, 13
|
5, 6, 12, 12, 6, 13
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<aiTextureType, std::vector<se::gfx::Texture>> textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<se::gfx::Texture>>> textures;
|
||||||
textures.emplace(white_texture.type, std::vector<se::gfx::Texture>{ white_texture });
|
textures.emplace(white_texture.type, std::vector<std::shared_ptr<se::gfx::Texture>>{ std::make_shared<se::gfx::Texture>(white_texture) });
|
||||||
se::gfx::Material white_material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
se::gfx::Material white_material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
// Create a renderer
|
// Create a renderer
|
||||||
|
@ -184,10 +179,17 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Create an Entity in the Scene and add components to it.
|
// Create an Entity in the Scene and add components to it.
|
||||||
se::ecs::Entity entity = scene->create_entity();
|
se::ecs::Entity entity = scene->create_entity();
|
||||||
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/dragon.obj");
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/dragon.obj");
|
||||||
entity.add_component<se::RotatingComponent>();
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/stall.obj");
|
||||||
|
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/backpack/backpack.obj");
|
||||||
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
|
||||||
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
|
||||||
|
//entity.add_component<se::RotatingComponent>();
|
||||||
auto& transform_comp = entity.add_component<se::TransformComponent>();
|
auto& transform_comp = entity.add_component<se::TransformComponent>();
|
||||||
transform_comp.translate(12.f, -4.f, 0.f);
|
transform_comp.translate(15.f, -8.f, 0.f);
|
||||||
|
/* transform_comp.scale(0.1f);
|
||||||
|
transform_comp.rotate_z(-90.f);*/
|
||||||
|
transform_comp.rotate_x(-90.f);
|
||||||
|
|
||||||
|
|
||||||
// Create the entity and add the model component to it.
|
// Create the entity and add the model component to it.
|
||||||
|
|
|
@ -3,12 +3,14 @@
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
class Material {
|
class Material {
|
||||||
public:
|
public:
|
||||||
std::unordered_map<aiTextureType, std::vector<Texture>> textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures;
|
||||||
|
|
||||||
float ambient_scalar;
|
float ambient_scalar;
|
||||||
float diffuse_scalar;
|
float diffuse_scalar;
|
||||||
|
@ -16,7 +18,7 @@ namespace simpleengine::gfx {
|
||||||
float shine;
|
float shine;
|
||||||
float reflectivity;
|
float reflectivity;
|
||||||
|
|
||||||
Material(std::unordered_map<aiTextureType, std::vector<Texture>> textures, float shine = 1.f, float reflectivity = 0.f, float specular_scalar = 0.f, float ambient_scalar = 0.f, float diffuse_scalar = 0.f) :
|
Material(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures, float shine = 1.f, float reflectivity = 0.f, float specular_scalar = 0.f, float ambient_scalar = 0.f, float diffuse_scalar = 0.f) :
|
||||||
textures(textures), ambient_scalar(ambient_scalar), diffuse_scalar(diffuse_scalar), specular_scalar(specular_scalar),
|
textures(textures), ambient_scalar(ambient_scalar), diffuse_scalar(diffuse_scalar), specular_scalar(specular_scalar),
|
||||||
shine(shine), reflectivity(reflectivity) {
|
shine(shine), reflectivity(reflectivity) {
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,10 @@ namespace simpleengine::gfx {
|
||||||
Model(std::string file_path);
|
Model(std::string file_path);
|
||||||
|
|
||||||
void load_model(std::string path);
|
void load_model(std::string path);
|
||||||
void process_node(aiNode* node, const aiScene* scene);
|
void process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene);
|
||||||
gfx::Mesh process_mesh(aiMesh* mesh, const aiScene* scene);
|
gfx::Mesh process_mesh(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMesh* mesh, const aiScene* scene);
|
||||||
std::vector<Texture> load_material_textures(aiMaterial* material, aiTextureType type);
|
|
||||||
|
std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material);
|
||||||
|
std::vector<std::shared_ptr<Texture>> load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -30,6 +30,7 @@ namespace simpleengine::gfx {
|
||||||
int width;
|
int width;
|
||||||
int channels;
|
int channels;
|
||||||
aiTextureType type;
|
aiTextureType type;
|
||||||
|
std::string path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Texture object from a path.
|
* @brief Construct a new Texture object from a path.
|
||||||
|
@ -38,7 +39,7 @@ namespace simpleengine::gfx {
|
||||||
* @param img_2d Whether or not the texture is 2D.
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
* @param mipmap Whether or not to generate mipmaps for this texture.
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
*/
|
*/
|
||||||
Texture(const char* path, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool mipmap = true);
|
Texture(const char* path, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Texture object from the loaded file buffer.
|
* @brief Construct a new Texture object from the loaded file buffer.
|
||||||
|
@ -48,7 +49,7 @@ namespace simpleengine::gfx {
|
||||||
* @param img_2d Whether or not the texture is 2D.
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
* @param mipmap Whether or not to generate mipmaps for this texture.
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
*/
|
*/
|
||||||
Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool mipmap = true);
|
Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Texture object from the loaded file buffer.
|
* @brief Construct a new Texture object from the loaded file buffer.
|
||||||
|
@ -57,7 +58,7 @@ namespace simpleengine::gfx {
|
||||||
* @param img_2d Whether or not the texture is 2D.
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
* @param mipmap Whether or not to generate mipmaps for this texture.
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
*/
|
*/
|
||||||
Texture(std::vector<unsigned char> buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool mipmap = true);
|
Texture(std::vector<unsigned char> buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true);
|
||||||
|
|
||||||
static Texture white_texture();
|
static Texture white_texture();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,5 @@ pkgs.mkShell {
|
||||||
glfw
|
glfw
|
||||||
glm
|
glm
|
||||||
assimp
|
assimp
|
||||||
(callPackage ./soil2.nix { })
|
|
||||||
];
|
];
|
||||||
}
|
}
|
37
soil2.nix
37
soil2.nix
|
@ -1,37 +0,0 @@
|
||||||
{ lib
|
|
||||||
, stdenv
|
|
||||||
, fetchFromGitHub
|
|
||||||
, cmake
|
|
||||||
, libGL
|
|
||||||
, libX11
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
version = "39028e64921c03cabbc53b937da4a85aba264e00";
|
|
||||||
pname = "soil2";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "SpartanJ";
|
|
||||||
repo = pname;
|
|
||||||
rev = version;
|
|
||||||
sha256 = "sha256-zQQ8lwOkMCxdlf6zfnIOYVUTGVqnJuHL/LL8fbzxwHY=";
|
|
||||||
};
|
|
||||||
|
|
||||||
nativeBuildInputs = [ cmake libGL libX11 ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
cmake --build . --target install --config Release
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "SOIL2 is a tiny C library used primarily for uploading textures into OpenGL.";
|
|
||||||
homepage = "https://github.com/SpartanJ/SOIL2";
|
|
||||||
license = licenses.mit0;
|
|
||||||
platforms = platforms.unix;
|
|
||||||
maintainers = with maintainers; [ seanomik ];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -31,26 +31,26 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
model_directory = path.substr(0, path.find_last_of('/'));
|
model_directory = path.substr(0, path.find_last_of('/'));
|
||||||
|
|
||||||
process_node(scene->mRootNode, scene);
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> processed_textures;
|
||||||
|
process_node(processed_textures, scene->mRootNode, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::process_node(aiNode* node, const aiScene* scene) {
|
void Model::process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene) {
|
||||||
// process all the node's meshes (if any)
|
// process all the node's meshes (if any)
|
||||||
for (int i = 0; i < node->mNumMeshes; i++) {
|
for (int i = 0; i < node->mNumMeshes; i++) {
|
||||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||||
meshes.push_back(process_mesh(mesh, scene));
|
meshes.push_back(process_mesh(processed_textures, mesh, scene));
|
||||||
}
|
}
|
||||||
|
|
||||||
// then do the same for each of its children
|
// then do the same for each of its children
|
||||||
for (int i = 0; i < node->mNumChildren; i++) {
|
for (int i = 0; i < node->mNumChildren; i++) {
|
||||||
process_node(node->mChildren[i], scene);
|
process_node(processed_textures, node->mChildren[i], scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Mesh Model::process_mesh(aiMesh* mesh, const aiScene* scene) {
|
gfx::Mesh Model::process_mesh(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMesh* mesh, const aiScene* scene) {
|
||||||
std::vector<LitVertex> vertices;
|
std::vector<LitVertex> vertices;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
std::vector<Texture> textures;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
|
||||||
LitVertex vertex;
|
LitVertex vertex;
|
||||||
|
@ -83,18 +83,18 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
// Create a default material and white texture.
|
// Create a default material and white texture.
|
||||||
auto white_texture = gfx::Texture::white_texture();
|
auto white_texture = gfx::Texture::white_texture();
|
||||||
std::unordered_map<aiTextureType, std::vector<Texture>> default_textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> default_textures;
|
||||||
default_textures.emplace(white_texture.type, std::vector<Texture>{ white_texture });
|
default_textures.emplace(white_texture.type, std::vector<std::shared_ptr<Texture>>{ std::make_shared<Texture>(white_texture) });
|
||||||
gfx::Material mat(default_textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
gfx::Material mat(default_textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
if (mesh->mMaterialIndex >= 0) {
|
if (mesh->mMaterialIndex >= 0) {
|
||||||
std::cout << "TODO: Process model materials!" << std::endl;
|
std::cout << "TODO: Process model materials!" << std::endl;
|
||||||
|
|
||||||
std::unordered_map<aiTextureType, std::vector<Texture>> textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures;
|
||||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
// Load Diffuse texture maps
|
// Load Diffuse texture maps
|
||||||
std::vector<Texture> diffuse_maps = load_material_textures(material, aiTextureType_DIFFUSE);
|
std::vector<std::shared_ptr<Texture>> diffuse_maps = load_material_texture(processed_textures, material, aiTextureType_DIFFUSE);
|
||||||
if (!diffuse_maps.empty()) textures.emplace(aiTextureType_DIFFUSE, diffuse_maps);
|
if (!diffuse_maps.empty()) textures.emplace(aiTextureType_DIFFUSE, diffuse_maps);
|
||||||
|
|
||||||
// TODO Handle other types of texture maps
|
// TODO Handle other types of texture maps
|
||||||
|
@ -102,25 +102,73 @@ namespace simpleengine::gfx {
|
||||||
if (!textures.empty()) {
|
if (!textures.empty()) {
|
||||||
// TODO: Find a way to let the user set the scalars.
|
// TODO: Find a way to let the user set the scalars.
|
||||||
mat = Material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
mat = Material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
// Add `textures` into the `processed_textures` list.
|
||||||
|
for (const auto& pair : textures) {
|
||||||
|
for (const auto& texture : pair.second) {
|
||||||
|
bool contains = false;
|
||||||
|
|
||||||
|
auto found = processed_textures.find(pair.first);
|
||||||
|
if (found != processed_textures.end()) {
|
||||||
|
for (const auto& processed_text : found->second) {
|
||||||
|
if (processed_text->path == texture->path) {
|
||||||
|
contains = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contains) {
|
||||||
|
//found->second
|
||||||
|
found->second.emplace_back(texture);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
processed_textures.emplace(pair.first, std::vector<std::shared_ptr<Texture>>{ pair.second });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mesh(vertices, indices, mat);
|
return Mesh(vertices, indices, mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Texture> Model::load_material_textures(aiMaterial* material, aiTextureType type) {
|
std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material) {
|
||||||
std::vector<Texture> textures;
|
// Load Diffuse texture maps
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Texture>> Model::load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type) {
|
||||||
|
std::vector<std::shared_ptr<Texture>> textures;
|
||||||
|
|
||||||
for (int i = 0; i < material->GetTextureCount(type); i++) {
|
for (int i = 0; i < material->GetTextureCount(type); i++) {
|
||||||
aiString texture_path;
|
aiString texture_path_ai;
|
||||||
material->GetTexture(type, i, &texture_path);
|
material->GetTexture(type, i, &texture_path_ai);
|
||||||
|
std::string texture_path = texture_path_ai.C_Str();
|
||||||
|
|
||||||
|
// If the texture has been read, we should skip it.
|
||||||
|
bool skip = false;
|
||||||
|
for (const auto& pair : processed_textures) {
|
||||||
|
if (pair.first == type) {
|
||||||
|
for (const auto& texture : pair.second) {
|
||||||
|
if (texture->path == texture_path) {
|
||||||
|
textures.emplace_back(texture); // Push a copy of the texture for this Mesh.
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skip) continue;
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << model_directory << "/" << texture_path.C_Str();
|
ss << model_directory << "/" << texture_path;
|
||||||
std::string full_path = ss.str();
|
std::string full_path = ss.str();
|
||||||
|
|
||||||
Texture texture(full_path.c_str(), type);
|
Texture texture(full_path.c_str(), type, true, true);
|
||||||
textures.emplace_back(texture);
|
texture.path = texture_path;
|
||||||
|
textures.emplace_back(std::make_shared<Texture>(texture));
|
||||||
|
|
||||||
|
std::cout << "Texture full path: " << full_path << ", texture_path: " << texture_path << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return textures;
|
return textures;
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace simpleengine::gfx {
|
||||||
if (texture_count >= 16) break;
|
if (texture_count >= 16) break;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + texture_count);
|
glActiveTexture(GL_TEXTURE0 + texture_count);
|
||||||
glBindTextureUnit(texture_count, texture.get_texture_id());
|
glBindTextureUnit(texture_count, texture->get_texture_id());
|
||||||
|
|
||||||
texture_count++;
|
texture_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
Texture::Texture(const char* path, aiTextureType type, bool img_2d, bool mipmap): type(type) {
|
Texture::Texture(const char* path, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap): type(type) {
|
||||||
image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||||
|
|
||||||
glGenTextures(1, &texture_id);
|
glGenTextures(1, &texture_id);
|
||||||
|
@ -17,6 +17,8 @@ namespace simpleengine::gfx {
|
||||||
glTexParameteri(image_type_gl, GL_TEXTURE_MIN_FILTER, linear_param);
|
glTexParameteri(image_type_gl, GL_TEXTURE_MIN_FILTER, linear_param);
|
||||||
glTexParameteri(image_type_gl, GL_TEXTURE_MAG_FILTER, linear_param);
|
glTexParameteri(image_type_gl, GL_TEXTURE_MAG_FILTER, linear_param);
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(flip_vertically);
|
||||||
|
|
||||||
// Read 4 channels (RGBA)
|
// Read 4 channels (RGBA)
|
||||||
img_data = stbi_load(path, &width, &height, &channels, 4);
|
img_data = stbi_load(path, &width, &height, &channels, 4);
|
||||||
if(!img_data) {
|
if(!img_data) {
|
||||||
|
@ -32,10 +34,12 @@ namespace simpleengine::gfx {
|
||||||
glGenerateMipmap(image_type_gl);
|
glGenerateMipmap(image_type_gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(false);
|
||||||
|
|
||||||
unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type, bool img_2d, bool mipmap): type(type) {
|
Texture::Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap): type(type) {
|
||||||
image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||||
|
|
||||||
glGenTextures(1, &texture_id);
|
glGenTextures(1, &texture_id);
|
||||||
|
@ -48,6 +52,8 @@ namespace simpleengine::gfx {
|
||||||
glTexParameteri(image_type_gl, GL_TEXTURE_MIN_FILTER, linear_param);
|
glTexParameteri(image_type_gl, GL_TEXTURE_MIN_FILTER, linear_param);
|
||||||
glTexParameteri(image_type_gl, GL_TEXTURE_MAG_FILTER, linear_param);
|
glTexParameteri(image_type_gl, GL_TEXTURE_MAG_FILTER, linear_param);
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(flip_vertically);
|
||||||
|
|
||||||
// Read 4 channels (RGBA)
|
// Read 4 channels (RGBA)
|
||||||
img_data = stbi_load_from_memory(buffer, buffer_length, &width, &height, &channels, 4);
|
img_data = stbi_load_from_memory(buffer, buffer_length, &width, &height, &channels, 4);
|
||||||
if(!img_data) {
|
if(!img_data) {
|
||||||
|
@ -63,10 +69,12 @@ namespace simpleengine::gfx {
|
||||||
glGenerateMipmap(image_type_gl);
|
glGenerateMipmap(image_type_gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(false);
|
||||||
|
|
||||||
unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(std::vector<unsigned char> buffer, aiTextureType type, bool img_2d, bool mipmap) :
|
Texture::Texture(std::vector<unsigned char> buffer, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap) :
|
||||||
Texture(buffer.data(), buffer.size(), type, img_2d, mipmap) {
|
Texture(buffer.data(), buffer.size(), type, img_2d, mipmap) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue