ADD: Render Textures

This commit is contained in:
sebastian 2026-02-07 17:15:19 +01:00
parent 84d6aee22e
commit 9a606a9cc6
19 changed files with 8244 additions and 26 deletions

View File

@ -17,7 +17,7 @@
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />

View File

@ -26,8 +26,8 @@ add_executable(Dicewars_Siedler src/main.cpp
src/game/DicewarsApp.h src/game/DicewarsApp.h
src/engine/renderer/model/RawModel.cpp src/engine/renderer/model/RawModel.cpp
src/engine/renderer/model/RawModel.h src/engine/renderer/model/RawModel.h
src/engine/renderer/model/Loader.cpp src/engine/renderer/loader/Loader.cpp
src/engine/renderer/model/Loader.h src/engine/renderer/loader/Loader.h
src/engine/renderer/Renderer.cpp src/engine/renderer/Renderer.cpp
src/engine/renderer/Renderer.h src/engine/renderer/Renderer.h
src/engine/layer/Layer.cpp src/engine/layer/Layer.cpp
@ -37,11 +37,19 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/renderer/shaders/ShaderProgram.cpp src/engine/renderer/shaders/ShaderProgram.cpp
src/engine/renderer/shaders/ShaderProgram.h src/engine/renderer/shaders/ShaderProgram.h
src/engine/renderer/shaders/StaticShader.cpp src/engine/renderer/shaders/StaticShader.cpp
src/engine/renderer/shaders/StaticShader.h) src/engine/renderer/shaders/StaticShader.h
src/engine/renderer/loader/Texture2D.h
src/engine/renderer/loader/TextureLoader.cpp
src/engine/renderer/loader/TextureLoader.h
src/engine/renderer/textures/ModelTexture.cpp
src/engine/renderer/textures/ModelTexture.h
src/engine/renderer/model/TexturedModel.cpp
src/engine/renderer/model/TexturedModel.h)
target_include_directories(Dicewars_Siedler PRIVATE target_include_directories(Dicewars_Siedler PRIVATE
lib/glfw/include lib/glfw/include
lib/glm lib/glm
lib/stb_image
) )
target_link_libraries(Dicewars_Siedler target_link_libraries(Dicewars_Siedler

View File

@ -1,9 +1,11 @@
#version 400 core #version 400 core
in vec3 color; in vec2 pass_textureCoords;
out vec4 outColor; out vec4 outColor;
uniform sampler2D textureSampler;
void main(void) { void main(void) {
outColor = vec4(color, 1.0f); outColor = texture(textureSampler, pass_textureCoords);
} }

View File

@ -1,11 +1,12 @@
#version 400 core #version 400 core
in vec3 position; in vec3 position;
in vec2 textureCoords;
out vec3 color; out vec2 pass_textureCoords;
void main() void main()
{ {
gl_Position = vec4(position, 1.0); gl_Position = vec4(position, 1.0);
color = vec3(position.x + 0.5, 1.0, position.y + 0.5); pass_textureCoords = textureCoords;
} }

7995
lib/stb_image/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,10 @@
#include "GameLayer.h" #include "GameLayer.h"
#include "../renderer/Renderer.h" #include "../renderer/Renderer.h"
#include "../renderer/model/TexturedModel.h"
#include "../renderer/textures/ModelTexture.h"
GameLayer::GameLayer() :model(0,0) //Platzhalter, echtes Model kommt in onAttach GameLayer::GameLayer() :texturedModel(0,0) //Platzhalter, echtes Model kommt in onAttach
{ {
} }
@ -24,7 +26,16 @@ void GameLayer::onAttach()
3,1,2 3,1,2
}; };
model = loader.loadToVAO(vertices, indices); std::vector<float> textureCoords = {
0,0, //v0
0,1, // v1
1,1, // v2
1,0 //v3
};
RawModel model = loader.loadToVAO(vertices, textureCoords, indices);
ModelTexture texture = ModelTexture(loader.loadTexture("assets/textures/texture.png"));
texturedModel = TexturedModel(std::make_shared<RawModel>(model), std::make_shared<ModelTexture>(texture));
} }
void GameLayer::onDetach() void GameLayer::onDetach()
@ -34,7 +45,7 @@ void GameLayer::onDetach()
void GameLayer::onUpdate() void GameLayer::onUpdate()
{ {
renderer.renderFrame(model); renderer.renderFrame(texturedModel);
} }

View File

@ -6,7 +6,8 @@
#define DICEWARS_SIEDLER_GAMELAYER_H #define DICEWARS_SIEDLER_GAMELAYER_H
#include "Layer.h" #include "Layer.h"
#include "../renderer/Renderer.h" #include "../renderer/Renderer.h"
#include "../renderer/model/Loader.h" #include "../renderer/loader/Loader.h"
#include "../renderer/model/TexturedModel.h"
class GameLayer: public Layer { class GameLayer: public Layer {
@ -20,7 +21,7 @@ public:
private: private:
Loader loader; Loader loader;
RawModel model; TexturedModel texturedModel;
Renderer renderer; Renderer renderer;
}; };

View File

@ -5,24 +5,30 @@
#include "Renderer.h" #include "Renderer.h"
#include "glad/glad.h" #include "glad/glad.h"
#include "model/TexturedModel.h"
void Renderer::prepare() { void Renderer::prepare() {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
void Renderer::renderFrame(const RawModel& model) { void Renderer::renderFrame(const TexturedModel& model) {
prepare(); prepare();
staticShader.start(); staticShader.start();
renderRawModel(model); renderRawModel(model);
staticShader.stop(); staticShader.stop();
} }
void Renderer::renderRawModel(const RawModel& model) { void Renderer::renderRawModel(const TexturedModel& texturedModel) {
glBindVertexArray(model.vaoID); auto model = texturedModel.getRawModel();
glBindVertexArray(model->vaoID);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES , model.vertexCount, GL_UNSIGNED_INT, 0); glEnableVertexAttribArray(1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texturedModel.getTexture()->getTextureID());
glDrawElements(GL_TRIANGLES , model->vertexCount, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -5,15 +5,16 @@
#ifndef DICEWARS_SIEDLER_RENDERER_H #ifndef DICEWARS_SIEDLER_RENDERER_H
#define DICEWARS_SIEDLER_RENDERER_H #define DICEWARS_SIEDLER_RENDERER_H
#include "model/RawModel.h" #include "model/RawModel.h"
#include "model/TexturedModel.h"
#include "shaders/StaticShader.h" #include "shaders/StaticShader.h"
class Renderer { class Renderer {
public: public:
void prepare(); void prepare();
void renderFrame(const RawModel& moddel); void renderFrame(const TexturedModel &model);
private: private:
void renderRawModel(const RawModel &model); void renderRawModel(const TexturedModel &model);
StaticShader staticShader; StaticShader staticShader;
}; };

View File

@ -4,9 +4,13 @@
#include "Loader.h" #include "Loader.h"
RawModel Loader::loadToVAO(const std::vector<float>& vertices, const std::vector<int>& indices){ #include "Texture2D.h"
#include "TextureLoader.h"
RawModel Loader::loadToVAO(const std::vector<float> &vertices, const std::vector<float> &textureCoords, const std::vector<int> &indices) {
GLuint vaoID = createVAO(); GLuint vaoID = createVAO();
storeDataInAttributeList(0, vertices); storeDataInAttributeList(0, 3, vertices);
storeDataInAttributeList(1, 2, textureCoords);
bindIndicesBuffer(indices); bindIndicesBuffer(indices);
unbindVAO(); unbindVAO();
return {vaoID, static_cast<int>(indices.size())}; return {vaoID, static_cast<int>(indices.size())};
@ -24,6 +28,16 @@ void Loader::cleanUp() {
for (GLuint vboID: vboIDs) { for (GLuint vboID: vboIDs) {
glDeleteBuffers(1, &vboID); glDeleteBuffers(1, &vboID);
} }
for (GLuint textureID: textureIDs) {
glDeleteTextures(1, &textureID);
}
}
GLuint Loader::loadTexture(const std::string &path) {
Texture2D texture = TextureLoader::loadTexture(path);
textureIDs.push_back(texture.id);
return texture.id;
} }
GLuint Loader::createVAO() { GLuint Loader::createVAO() {
@ -34,14 +48,14 @@ GLuint Loader::createVAO() {
return vaoID; return vaoID;
} }
void Loader::storeDataInAttributeList(int attributeNumber, const std::vector<float> &data) { void Loader::storeDataInAttributeList(int attributeNumber, const int coordinateSize, const std::vector<float> &data) {
GLuint vboID; GLuint vboID;
glGenBuffers(1, &vboID); glGenBuffers(1, &vboID);
vboIDs.push_back(vboID); vboIDs.push_back(vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID); glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), data.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), data.data(), GL_STATIC_DRAW);
glVertexAttribPointer(attributeNumber, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }

View File

@ -4,27 +4,30 @@
#ifndef DICEWARS_SIEDLER_LOADER_H #ifndef DICEWARS_SIEDLER_LOADER_H
#define DICEWARS_SIEDLER_LOADER_H #define DICEWARS_SIEDLER_LOADER_H
#include <string>
#include <vector> #include <vector>
#include "RawModel.h" #include "../model/RawModel.h"
#include "glad/glad.h" #include "glad/glad.h"
class Loader class Loader
{ {
public: public:
RawModel loadToVAO(const std::vector<float>& vertices, const std::vector<int>& indices); RawModel loadToVAO(const std::vector<float>& vertices, const std::vector<float>& textureCoords, const std::vector<int>& indices);
~Loader(); ~Loader();
void cleanUp(); void cleanUp();
GLuint loadTexture(const std::string &path);
private: private:
GLuint createVAO(); GLuint createVAO();
void storeDataInAttributeList(int attributeNumber, const std::vector<float> &data); void storeDataInAttributeList(int attributeNumber, int coordinateSize, const std::vector<float> &data);
void bindIndicesBuffer(const std::vector<int> &indices); void bindIndicesBuffer(const std::vector<int> &indices);
void unbindVAO(); void unbindVAO();
std::vector<GLuint> vaoIDs; std::vector<GLuint> vaoIDs;
std::vector<GLuint> vboIDs; std::vector<GLuint> vboIDs;
std::vector<GLuint> textureIDs;
}; };

View File

@ -0,0 +1,19 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef TEXTURE2D_H
#define TEXTURE2D_H
#include "glad/glad.h"
struct Texture2D {
GLuint id = 0;
int width = 0;
int height = 0;
int channels = 0;
unsigned char* pixels = nullptr;
};
#endif //TEXTURE2D_H

View File

@ -0,0 +1,75 @@
//
// Created by sebastian on 07.02.26.
//
#include "TextureLoader.h"
#include <stdexcept>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
Texture2D TextureLoader::loadTexture(const std::string &path) {
Texture2D texture;
stbi_set_flip_vertically_on_load(true);
texture.pixels = stbi_load(
path.c_str(),
&texture.width,
&texture.height,
&texture.channels,
0
);
if (!texture.pixels) {
throw std::runtime_error("Failed to load texture: " + path);
}
GLenum format = GL_RGB;
if (texture.channels == 4)
format = GL_RGBA;
else if (texture.channels == 3)
format = GL_RGB;
else if (texture.channels == 1)
format = GL_RED;
glGenTextures(1, &texture.id);
glBindTexture(GL_TEXTURE_2D, texture.id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
format,
texture.width,
texture.height,
0,
format,
GL_UNSIGNED_BYTE,
texture.pixels
);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
return texture;
}
void TextureLoader::free(Texture2D &texture) {
if (texture.id != 0) {
glDeleteTextures(1, &texture.id);
texture.id = 0;
}
if (texture.pixels) {
stbi_image_free(texture.pixels);
texture.pixels = nullptr;
}
}

View File

@ -0,0 +1,21 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef TEXTURELOADER_H
#define TEXTURELOADER_H
#include <string>
#include "Texture2D.h"
class TextureLoader {
public:
static Texture2D loadTexture(const std::string& path);
static void free(Texture2D& texture);
};
#endif //TEXTURELOADER_H

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 07.02.26.
//
#include "TexturedModel.h"

View File

@ -0,0 +1,28 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef TEXTUREDMODEL_H
#define TEXTUREDMODEL_H
#include <memory>
#include <utility>
#include "RawModel.h"
#include "../textures/ModelTexture.h"
class TexturedModel {
private:
std::shared_ptr<RawModel> rawModel;
std::shared_ptr<ModelTexture> texture;
public:
TexturedModel(std::shared_ptr<RawModel> rawModel, std::shared_ptr<ModelTexture> texture) : rawModel(std::move(rawModel)), texture(std::move(texture)) {};
[[nodiscard]] const std::shared_ptr<RawModel> getRawModel() const {return rawModel;}
[[nodiscard]] const std::shared_ptr<ModelTexture> getTexture() const {return texture;}
};
#endif //TEXTUREDMODEL_H

View File

@ -10,4 +10,5 @@ StaticShader::StaticShader() : ShaderProgram(VERTEX_FILE, FRAGMENT_FILE) {
void StaticShader::bindAttributes() const { void StaticShader::bindAttributes() const {
bindAttribute(0, "position"); bindAttribute(0, "position");
bindAttribute(1, "textureCoords");
} }

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 07.02.26.
//
#include "ModelTexture.h"

View File

@ -0,0 +1,22 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef MODELTEXTURE_H
#define MODELTEXTURE_H
#include "glad/glad.h"
class ModelTexture {
private:
GLuint textureID;
public:
explicit ModelTexture(GLuint textureID) : textureID(textureID) {};
[[nodiscard]] GLuint getTextureID() const {return textureID;}
};
#endif //MODELTEXTURE_H