ADD: Basic Shader and Attribute Infrastructure for OpenGL

This commit is contained in:
sebastian 2026-07-29 13:37:59 +02:00
parent 4ada346252
commit 8ae128e0ee
7 changed files with 234 additions and 0 deletions

View File

@ -87,6 +87,8 @@ add_library(Engine STATIC
engine/src/utils/openglWrapper/GLStateCache.h engine/src/utils/openglWrapper/GLStateCache.h
engine/src/utils/openglWrapper/GLRenderState.cpp engine/src/utils/openglWrapper/GLRenderState.cpp
engine/src/utils/openglWrapper/GLRenderState.h engine/src/utils/openglWrapper/GLRenderState.h
engine/src/utils/openglWrapper/openglObjects/Attribute.cpp
engine/src/utils/openglWrapper/openglObjects/Attribute.h
) )
target_include_directories(Engine PUBLIC engine/src) target_include_directories(Engine PUBLIC engine/src)
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui)
@ -96,6 +98,8 @@ add_executable(ColorRace
game/src/main.cpp game/src/main.cpp
game/src/ColorRaceApp.cpp game/src/ColorRaceApp.cpp
game/src/ColorRaceApp.h game/src/ColorRaceApp.h
engine/src/utils/openglWrapper/shader/ShaderProgram.cpp
engine/src/utils/openglWrapper/shader/ShaderProgram.h
) )
target_link_libraries(ColorRace PRIVATE target_link_libraries(ColorRace PRIVATE

View File

@ -0,0 +1,7 @@
#version 460 core
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.5, 0.2, 1.0);
}

View File

@ -0,0 +1,6 @@
#version 460 core
layout(location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}

View File

@ -0,0 +1,55 @@
//
// Created by sebastian on 29.07.26.
//
#include "Attribute.h"
#include <iostream>
using namespace engine;
Attribute::Attribute(const unsigned int attributeNumber, const unsigned int dataType, const int componentCount, const bool normalized)
: m_attributeNumber(attributeNumber), m_dataType(dataType),
m_componentCount(componentCount), m_normalized(normalized),
m_bytesPerVertex(calcBytesPerVertex()) {}
Attribute::Attribute(const unsigned int attributeNumber, const unsigned int dataType, const int componentCount)
: m_attributeNumber(attributeNumber), m_dataType(dataType),
m_componentCount(componentCount), m_normalized(false),
m_bytesPerVertex(calcBytesPerVertex()) {}
void Attribute::enable(bool enable) const {
if (enable) {
glEnableVertexAttribArray(m_attributeNumber);
} else {
glDisableVertexAttribArray(m_attributeNumber);
}
}
void Attribute::link(const int offset, const int stride) {
glVertexAttribPointer(m_attributeNumber, m_componentCount, m_dataType, m_normalized, stride, reinterpret_cast<void*>(offset));
}
int Attribute::calcBytesPerVertex() const {
switch (m_dataType) {
case GL_FLOAT:
case GL_UNSIGNED_INT:
case GL_INT:
return 4 * m_componentCount;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
return 2 * m_componentCount;
case GL_BYTE:
case GL_UNSIGNED_BYTE:
return 1 * m_componentCount;
case GL_UNSIGNED_INT_2_10_10_10_REV:
return 4; // gepackt: 4 Bytes gesamt, unabhängig von componentCount
default:
std::cerr << "Unsupported data type for attribute\n";
return 0;
}
}
void IntAttribute::link(int offset, int stride) {
glVertexAttribIPointer(m_attributeNumber, m_componentCount, GL_INT, stride,
reinterpret_cast<void*>(offset));
}

View File

@ -0,0 +1,60 @@
//
// Created by sebastian on 29.07.26.
//
#ifndef COLORRACE_ATTRIBUTE_H
#define COLORRACE_ATTRIBUTE_H
#pragma once
#include <glad/glad.h>
namespace engine {
class Attribute {
public:
Attribute(unsigned int attributeNumber, unsigned int dataType, int componentCount);
Attribute(unsigned int attributeNumber, unsigned int dataType, int componentCount, bool normalized);
virtual ~Attribute() = default;
void enable(bool enable) const;
virtual void link(int offset, int stride);
protected:
unsigned int m_attributeNumber;
unsigned int m_dataType;
int m_componentCount;
bool m_normalized;
int m_bytesPerVertex;
private:
int calcBytesPerVertex() const;
};
class Vec2Attribute : public Attribute {
public:
explicit Vec2Attribute(unsigned int attributeNumber) : Attribute(attributeNumber, GL_FLOAT, 2) {}
};
class Vec3Attribute : public Attribute {
public:
explicit Vec3Attribute(unsigned int attributeNumber) : Attribute(attributeNumber, GL_FLOAT, 3) {}
};
class ColorAttribute : public Attribute {
public:
explicit ColorAttribute(unsigned int attributeNumber) : Attribute(attributeNumber, GL_UNSIGNED_BYTE, 4, true) {}
};
class NormalAttribute : public Attribute {
public:
explicit NormalAttribute(unsigned int attributeNumber) : Attribute(attributeNumber, GL_UNSIGNED_INT_2_10_10_10_REV, 3) {}
};
class IntAttribute : public Attribute {
public:
explicit IntAttribute(unsigned int attributeNumber) : Attribute(attributeNumber, GL_INT, 1) {}
void link(int offset, int stride) override;
};
}
#endif //COLORRACE_ATTRIBUTE_H

View File

@ -0,0 +1,72 @@
//
// Created by sebastian on 29.07.26.
//
#include "ShaderProgram.h"
#include <glad/glad.h>
#include <fstream>
#include <sstream>
#include <stdexcept>
using namespace engine;
std::string ShaderProgram::loadSource(const std::string &filePath) {
std::ifstream file(filePath);
if (!file.is_open()) {
throw std::runtime_error("Could not open shader file: " + filePath);
}
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
unsigned int ShaderProgram::compileShader(unsigned int type, const std::string &source, const std::string &debugPath) {
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
int success;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if (!success) {
char log[512];
glGetShaderInfoLog(id, 512, nullptr, log);
throw std::runtime_error("Shader compile error (" + debugPath + "): " + log);
}
return id;
}
ShaderProgram::ShaderProgram(const std::string &vertexShader, const std::string &fragmentShader) {
unsigned int vertexShaderId = compileShader(GL_VERTEX_SHADER, loadSource(vertexShader), vertexShader);
unsigned int fragmentShaderId = compileShader(GL_FRAGMENT_SHADER, loadSource(fragmentShader), fragmentShader);
m_programId = glCreateProgram();
glAttachShader(m_programId, vertexShaderId);
glAttachShader(m_programId, fragmentShaderId);
glLinkProgram(m_programId);
int success;
glGetProgramiv(m_programId, GL_LINK_STATUS, &success);
if (!success) {
char log[512];
glGetProgramInfoLog(m_programId, 512, nullptr, log);
throw std::runtime_error(std::string("Shader link error: ") + log);
}
glDetachShader(m_programId, vertexShaderId);
glDetachShader(m_programId, fragmentShaderId);
glDeleteShader(vertexShaderId);
glDeleteShader(fragmentShaderId);
}
ShaderProgram::~ShaderProgram() {
glDeleteProgram(m_programId);
}
void ShaderProgram::start() const {
glUseProgram(m_programId);
}
void ShaderProgram::stop() const {
glUseProgram(0);
}

View File

@ -0,0 +1,30 @@
//
// Created by sebastian on 29.07.26.
//
#ifndef COLORRACE_SHADERPROGRAM_H
#define COLORRACE_SHADERPROGRAM_H
#include <string>
namespace engine {
class ShaderProgram {
public:
ShaderProgram(const std::string& vertexShader, const std::string& fragmentShader);
~ShaderProgram();
ShaderProgram(const ShaderProgram&) = delete;
ShaderProgram& operator=(const ShaderProgram&) = delete;
void start() const;
void stop() const;
private:
unsigned int m_programId;
static std::string loadSource(const std::string& filePath);
static unsigned int compileShader(unsigned int type, const std::string& source, const std::string& debugPath);
};
}
#endif //COLORRACE_SHADERPROGRAM_H