From 1ab2377f8ee6bb2c2a0cb304b500c2a4cf9436b2 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sun, 4 Jan 2026 13:07:56 +0100 Subject: [PATCH] add basic texture --- include/td/render/loader/TextureLoader.h | 31 +++++++ include/td/render/renderer/EntityRenderer.h | 2 + src/td/render/loader/FbxLoader.cpp | 2 +- src/td/render/loader/TextureLoader.cpp | 89 +++++++++++++++++++++ src/td/render/renderer/EntityRenderer.cpp | 6 +- src/td/render/shader/EntityShader.cpp | 10 ++- xmake.lua | 4 +- 7 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 include/td/render/loader/TextureLoader.h create mode 100644 src/td/render/loader/TextureLoader.cpp diff --git a/include/td/render/loader/TextureLoader.h b/include/td/render/loader/TextureLoader.h new file mode 100644 index 0000000..c1d854e --- /dev/null +++ b/include/td/render/loader/TextureLoader.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace td { +namespace GL { + +class Texture : private sp::NonCopyable { + public: + Texture(const char* a_Data, int a_Width, int a_Height, int a_Comp); + Texture(Texture&& a_Other); + + ~Texture(); + + void Bind() const; + void Unbind() const; + + private: + unsigned int m_ID; +}; + +} // namespace GL + +namespace TextureLoader { + +GL::Texture LoadTexture(const std::string& fileName); + +} + +} // namespace td \ No newline at end of file diff --git a/include/td/render/renderer/EntityRenderer.h b/include/td/render/renderer/EntityRenderer.h index b7db1e4..57ee0cb 100644 --- a/include/td/render/renderer/EntityRenderer.h +++ b/include/td/render/renderer/EntityRenderer.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -12,6 +13,7 @@ class EntityRenderer : public Renderer { private: game::WorldPtr m_World; Model m_EntityModel; + std::unique_ptr m_EntityTexture; public: EntityRenderer(Camera& a_Camera, const game::WorldPtr& a_World); diff --git a/src/td/render/loader/FbxLoader.cpp b/src/td/render/loader/FbxLoader.cpp index 9252156..0c0818e 100644 --- a/src/td/render/loader/FbxLoader.cpp +++ b/src/td/render/loader/FbxLoader.cpp @@ -107,7 +107,7 @@ Model LoadModel(const std::string& fileName) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_SortByPType | - aiProcess_OptimizeGraph | aiProcess_OptimizeMeshes | aiProcess_GlobalScale); + aiProcess_OptimizeGraph | aiProcess_OptimizeMeshes | aiProcess_GlobalScale | aiProcess_FlipUVs); if (!scene) { std::cerr << "[ModelLoader] Failed to load model !\n"; diff --git a/src/td/render/loader/TextureLoader.cpp b/src/td/render/loader/TextureLoader.cpp new file mode 100644 index 0000000..73fdfbf --- /dev/null +++ b/src/td/render/loader/TextureLoader.cpp @@ -0,0 +1,89 @@ +/* + * TextureLoader.cpp + * + * Created on: 15 nov. 2020 + * Author: simon + */ + +// #include "render/loader/TextureLoader.h" +// #include "render/loader/stb_image.h" +// #include "render/GL.h" +// #include "misc/Log.h" +// #include "misc/Format.h" + +#include + +#include +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#include + +#include + +namespace td { +namespace TextureLoader { + +GL::Texture LoadTexture(const std::string& fileName) { + + int width, height, comp; + + unsigned char* image = stbi_load(fileName.c_str(), &width, &height, &comp, STBI_rgb_alpha); + + if (image == nullptr) { + utils::LOGE("Erreur lors du chargement de la texture !"); + throw std::runtime_error("Failed to load texture"); + } + + GL::Texture texture(reinterpret_cast(image), width, height, comp); + + stbi_image_free(image); + + // utils::LOGD(utils::format("Texture %s chargée !", fileName.c_str())); + + return texture; +} + +} // namespace TextureLoader + +namespace GL { + +Texture::Texture(const char* textureData, int width, int height, int comp) { + glGenTextures(1, &m_ID); + + Bind(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + assert(comp == 3 || comp == 4); + + if (comp == 3) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); + + Unbind(); +} + +Texture::Texture(Texture&& a_Other) { + std::swap(m_ID, a_Other.m_ID); +} + +Texture::~Texture() { + glDeleteTextures(1, &m_ID); +} + +void Texture::Bind() const { + glBindTexture(GL_TEXTURE_2D, m_ID); +} + +void Texture::Unbind() const { + glBindTexture(GL_TEXTURE_2D, 0); +} + + +} // namespace GL + +} // namespace td \ No newline at end of file diff --git a/src/td/render/renderer/EntityRenderer.cpp b/src/td/render/renderer/EntityRenderer.cpp index 645c44e..20baebb 100644 --- a/src/td/render/renderer/EntityRenderer.cpp +++ b/src/td/render/renderer/EntityRenderer.cpp @@ -1,4 +1,6 @@ #include "td/render/Renderer.h" +#include "td/render/loader/TextureLoader.h" +#include #include #include @@ -8,8 +10,9 @@ namespace render { EntityRenderer::EntityRenderer(Camera& a_Camera, const game::WorldPtr& a_World) : Renderer(a_Camera), m_World(a_World) { m_EntityModel = ModelLoader::LoadModel("assets/zombie.fbx"); + m_EntityTexture = std::make_unique(TextureLoader::LoadTexture("assets/zombie.png")); m_Shader->Start(); - m_Shader->SetColorEffect({1, 0, 1}); + m_Shader->SetColorEffect({1, 1, 1}); } EntityRenderer::~EntityRenderer() {} @@ -24,6 +27,7 @@ void EntityRenderer::Render(float a_Lerp) { float z = Lerp(*mob, a_Lerp, [](const game::Mob& a_Mob) { return static_cast(a_Mob.m_Position.y); }); m_Shader->SetModelPos({x, .001, z}); + m_EntityTexture->Bind(); Renderer::Render(m_EntityModel); } } diff --git a/src/td/render/shader/EntityShader.cpp b/src/td/render/shader/EntityShader.cpp index 3080487..c83b93d 100644 --- a/src/td/render/shader/EntityShader.cpp +++ b/src/td/render/shader/EntityShader.cpp @@ -53,12 +53,16 @@ static const char vertexSource[] = R"( #version 330 layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texCoords; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; uniform vec3 modelPosition; +out vec2 pass_textureCoords; + void main(void){ + pass_textureCoords = texCoords; gl_Position = projectionMatrix * viewMatrix * vec4(position + modelPosition, 1.0); } )"; @@ -66,19 +70,23 @@ void main(void){ static const char fragmentSource[] = R"( #version 330 +in vec2 pass_textureCoords; + out vec4 out_color; uniform vec3 ColorEffect; +uniform sampler2D textureSampler; void main(void){ - vec4 color = vec4(ColorEffect, 1.0); + vec4 color = vec4(ColorEffect, 1.0) * texture(textureSampler, pass_textureCoords); if (color.a <= 0.1) discard; out_color = color; + } )"; #endif diff --git a/xmake.lua b/xmake.lua index 1e47320..90e76f8 100644 --- a/xmake.lua +++ b/xmake.lua @@ -3,7 +3,7 @@ add_rules("mode.debug", "mode.release") add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git") add_requires("imgui 1.92.0", {configs = {sdl3 = true, opengl3 = true}}) -add_requires("libsdl3 3.2.16", "splib 2.3.2", "zlib", "glew", "fpm", "enet6", "assimp") +add_requires("libsdl3 3.2.16", "splib 2.3.2", "zlib", "glew", "fpm", "enet6", "assimp", "stb") set_languages("c++20") @@ -21,7 +21,7 @@ target("Tower-Defense2") add_includedirs("include", {public = true}) set_kind("binary") add_files("src/**.cpp") - add_packages("libsdl3", "imgui", "glew", "splib", "zlib", "fpm", "assimp", "enet6", {public = true}) + add_packages("libsdl3", "imgui", "glew", "splib", "zlib", "fpm", "assimp", "enet6", "stb", {public = true}) set_rundir(".") add_defines("TD_GL_LOADER_GLEW")