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/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" 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/=CppClassNeedsConstructorBecauseOfUninitializedMember/@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/engine/renderer/model/RawModel.cpp
src/engine/renderer/model/RawModel.h
src/engine/renderer/model/Loader.cpp
src/engine/renderer/model/Loader.h
src/engine/renderer/loader/Loader.cpp
src/engine/renderer/loader/Loader.h
src/engine/renderer/Renderer.cpp
src/engine/renderer/Renderer.h
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.h
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
lib/glfw/include
lib/glm
lib/stb_image
)
target_link_libraries(Dicewars_Siedler

View File

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

View File

@ -1,11 +1,12 @@
#version 400 core
in vec3 position;
in vec2 textureCoords;
out vec3 color;
out vec2 pass_textureCoords;
void main()
{
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 "../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
};
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()
@ -34,7 +45,7 @@ void GameLayer::onDetach()
void GameLayer::onUpdate()
{
renderer.renderFrame(model);
renderer.renderFrame(texturedModel);
}

View File

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

View File

@ -5,24 +5,30 @@
#include "Renderer.h"
#include "glad/glad.h"
#include "model/TexturedModel.h"
void Renderer::prepare() {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void Renderer::renderFrame(const RawModel& model) {
void Renderer::renderFrame(const TexturedModel& model) {
prepare();
staticShader.start();
renderRawModel(model);
staticShader.stop();
}
void Renderer::renderRawModel(const RawModel& model) {
glBindVertexArray(model.vaoID);
void Renderer::renderRawModel(const TexturedModel& texturedModel) {
auto model = texturedModel.getRawModel();
glBindVertexArray(model->vaoID);
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(1);
glBindVertexArray(0);
}

View File

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

View File

@ -4,9 +4,13 @@
#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();
storeDataInAttributeList(0, vertices);
storeDataInAttributeList(0, 3, vertices);
storeDataInAttributeList(1, 2, textureCoords);
bindIndicesBuffer(indices);
unbindVAO();
return {vaoID, static_cast<int>(indices.size())};
@ -24,6 +28,16 @@ void Loader::cleanUp() {
for (GLuint vboID: vboIDs) {
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() {
@ -34,14 +48,14 @@ GLuint Loader::createVAO() {
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;
glGenBuffers(1, &vboID);
vboIDs.push_back(vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
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);
}

View File

@ -4,27 +4,30 @@
#ifndef DICEWARS_SIEDLER_LOADER_H
#define DICEWARS_SIEDLER_LOADER_H
#include <string>
#include <vector>
#include "RawModel.h"
#include "../model/RawModel.h"
#include "glad/glad.h"
class Loader
{
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();
void cleanUp();
GLuint loadTexture(const std::string &path);
private:
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 unbindVAO();
std::vector<GLuint> vaoIDs;
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 {
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