Compare commits

...

3 Commits

Author SHA1 Message Date
952c5062bc you can now print images on the screen 2026-04-16 00:29:05 +02:00
291f774a95 added uniforms 2026-04-15 23:54:09 +02:00
ee06b834b9 added indexbuffer 2026-04-15 23:08:28 +02:00
10 changed files with 7658 additions and 12 deletions

View File

@@ -11,7 +11,11 @@ add_executable(${PROJECT_NAME} src/main.cpp
include/VertexBuffer.hpp
include/defines.hpp
src/Shader.cpp
include/Shader.hpp)
include/Shader.hpp
include/IndexBuffer.hpp
libs/stb_image.hpp)
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:_DEBUG>)
target_include_directories(${PROJECT_NAME} PRIVATE include)
target_include_directories(${PROJECT_NAME} PRIVATE shaders)

34
include/IndexBuffer.hpp Normal file
View File

@@ -0,0 +1,34 @@
#pragma once
#include <GL/glew.h>
#include "defines.hpp"
struct IndexBuffer {
IndexBuffer(void* data, uint32 numIndices, uint8 elementSize) {
glGenBuffers(1, &bufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*elementSize, data, GL_STATIC_DRAW);
// POSITION
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,x));
// COLOR
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,r));
glBindVertexArray(0);
};
virtual ~IndexBuffer() {
glDeleteBuffers(1, &bufferId);
}
void bind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferId);
}
void unbind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
private:
GLuint bufferId;
};

View File

@@ -10,6 +10,8 @@ struct Shader {
void bind();
void unbind();
GLuint getShaderId();
private:
GLuint compile(std::string shaderSource, GLenum shaderType);
std::string parse(const char* filename);

View File

@@ -15,9 +15,12 @@ struct VertexBuffer {
// POSITION
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,x));
// COLOR
// TEXTURE COORDINATES
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,r));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,u));
// COLOR
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex,r));
glBindVertexArray(0);
};

View File

@@ -16,5 +16,6 @@ typedef double float64;
struct Vertex {
float32 x, y, z; // position
float32 u, v; // texture coordinates
float32 r, g, b, a; // color
};

7462
libs/stb_image.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,12 @@
layout(location = 0) out vec4 f_color;
in vec4 v_color;
in vec2 v_texCoord;
uniform sampler2D u_texture;
uniform vec4 u_color;
void main() {
f_color = v_color;
vec4 texColor = texture(u_texture, v_texCoord);
f_color = texColor;
}

View File

@@ -1,11 +1,14 @@
#version 330 core
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec4 a_color;
layout(location = 1) in vec2 a_texCoord;
layout(location = 2) in vec4 a_color;
out vec4 v_color;
out vec2 v_texCoord;
void main() {
gl_Position = vec4(a_position, 1.0f);
v_color = a_color;
v_texCoord = a_texCoord;
}

View File

@@ -18,6 +18,10 @@ void Shader::unbind() {
glUseProgram(0);
}
GLuint Shader::getShaderId() {
return this->shaderId;
}
GLuint Shader::compile(std::string shaderSource, GLenum shaderType) {
GLuint id = glCreateShader(shaderType);
const char* src = shaderSource.c_str();

View File

@@ -2,11 +2,67 @@
#define GLEW_STATIC
#include <GL/glew.h>
#define SDL_MAIN_HANDLED
#include <cmath>
#include <SDL3/SDL.h>
#include "defines.hpp"
#include "IndexBuffer.hpp"
#include "VertexBuffer.hpp"
#include "Shader.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "../libs/stb_image.hpp"
void openGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) {
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) return; //ignore notifications (mostly performance information)
std::cerr << "--------------------- OpenGL Debug Message ---------------------" << std::endl;
std::cerr << "Message: " << message << std::endl;
std::cerr << "ID: " << id << std::endl;
std::string sourceStr;
switch (source) {
case GL_DEBUG_SOURCE_API: sourceStr = "API"; break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceStr = "Window System"; break;
case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceStr = "Shader Compiler"; break;
case GL_DEBUG_SOURCE_THIRD_PARTY: sourceStr = "Third Party"; break;
case GL_DEBUG_SOURCE_APPLICATION: sourceStr = "Application"; break;
case GL_DEBUG_SOURCE_OTHER: sourceStr = "Other"; break;
default: sourceStr = "Unknown"; break;
}
std::string typeStr;
switch (type) {
case GL_DEBUG_TYPE_ERROR: typeStr = "Error"; break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeStr = "Deprecated Behavior"; break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeStr = "Undefined Behavior"; break;
case GL_DEBUG_TYPE_PORTABILITY: typeStr = "Portability"; break;
case GL_DEBUG_TYPE_PERFORMANCE: typeStr = "Performance"; break;
case GL_DEBUG_TYPE_MARKER: typeStr = "Marker"; break;
case GL_DEBUG_TYPE_PUSH_GROUP: typeStr = "Push Group"; break;
case GL_DEBUG_TYPE_POP_GROUP: typeStr = "Pop Group"; break;
case GL_DEBUG_TYPE_OTHER: typeStr = "Other"; break;
default: typeStr = "Unknown"; break;
}
std::string severityStr;
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH: severityStr = "HIGH"; break;
case GL_DEBUG_SEVERITY_MEDIUM: severityStr = "MEDIUM"; break;
case GL_DEBUG_SEVERITY_LOW: severityStr = "LOW"; break;
case GL_DEBUG_SEVERITY_NOTIFICATION: severityStr = "NOTIFICATION"; break;
default: severityStr = "UNKNOWN"; break;
}
std::cerr << "Source: " << sourceStr << std::endl;
std::cerr << "Type: " << typeStr << std::endl;
std::cerr << "Severity: " << severityStr << std::endl;
std::cerr << "---------------------------------------------------------------" << std::endl;
// Breakpoint
if (severity == GL_DEBUG_SEVERITY_HIGH) {
std::cerr << "Kritischer Fehler! Programm wird unterbrochen." << std::endl;
__builtin_trap(); // only for linux/gcc/clang
}
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
@@ -18,6 +74,10 @@ int main() {
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#ifdef _DEBUG
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); //remove for stable release
#endif
uint32 flags = SDL_WINDOW_OPENGL; //| SDL_WINDOW_FULLSCREEN;
@@ -35,20 +95,75 @@ int main() {
return -1;
}
std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
#ifdef _DEBUG
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(openGLDebugCallback, nullptr);
#endif
Vertex vertices[] = {
Vertex{-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
Vertex{0.0f, 0.5f, 0.0f, 0.0, 1.0f, 0.0f, 1.0f},
Vertex{0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f},
Vertex{-0.5f, -0.5f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f},
Vertex{-0.5f, 0.5f, 0.0f,
0.0f, 1.0f,
0.0, 1.0f, 0.0f, 1.0f},
Vertex{0.5f, -0.5f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 1.0f},
Vertex{0.5f, 0.5f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f},
};
uint32_t numVertices = 3;
uint32 numVertices = sizeof(vertices) / sizeof(Vertex);
uint32 indices[] = {
0, 1, 2,
1, 2, 3
};
uint32 numIndices = sizeof(indices) / sizeof(uint32);
IndexBuffer indexBuffer(indices, numIndices, sizeof(indices[0]));
VertexBuffer vertexBuffer(vertices, numVertices);
vertexBuffer.unbind();
int32 textureWidth = 0;
int32 textureHeight = 0;
int32 bitsPerPixel = 0;
stbi_set_flip_vertically_on_load(true);
auto textureBuffer = stbi_load("../assets/logo.png", &textureWidth, &textureHeight, &bitsPerPixel, 4);
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // or GL_NEAREST for pixel like style (instead of GL_LINEAR -> interpolation)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer);
glBindTexture(GL_TEXTURE_2D, 0);
if (textureBuffer) {
stbi_image_free(textureBuffer);
}
Shader shader("shaders/basic.vert", "shaders/basic.frag");
shader.bind();
int colorUniformLocation = glGetUniformLocation(shader.getShaderId(), "u_color");
if (colorUniformLocation != 1) {
glUniform4f(colorUniformLocation, 1.0f, 0.0f, 1.0f, 1.0f);
}
int textureUniformLocation = glGetUniformLocation(shader.getShaderId(), "u_texture");
if (textureUniformLocation != 1) {
glUniform1i(textureUniformLocation, 0);
}
const uint64 perfCounterFrequency = SDL_GetPerformanceFrequency();
uint64 lastCounter = SDL_GetPerformanceCounter();
float32 delta = 0.0f;
@@ -56,16 +171,27 @@ int main() {
// WIREFRAME
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
float time = 0.0f;
bool running = true;
SDL_Event e;
while (running) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
time += delta;
if (colorUniformLocation != 1) {
glUniform4f(colorUniformLocation, sinf(time)*sinf(time), 0.0f, 1.0f, 1.0f);
}
// FRAME GENERATION
vertexBuffer.bind();
glDrawArrays(GL_TRIANGLES, 0, numVertices);
indexBuffer.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);
vertexBuffer.unbind();
indexBuffer.unbind();
SDL_GL_SwapWindow(window);
@@ -79,10 +205,12 @@ int main() {
const uint64 counterElapsed = endCounter - lastCounter;
delta = (static_cast<float32>(counterElapsed) / static_cast<float32>(perfCounterFrequency));
const auto FPS = static_cast<uint32>(static_cast<float32>(perfCounterFrequency) / static_cast<float32>(counterElapsed));
std::cout << "FPS: " << FPS << std::endl;
//std::cout << "FPS: " << FPS << std::endl;
lastCounter = endCounter;
}
glDeleteTextures(1, &textureId);
SDL_GL_DestroyContext(context);
SDL_DestroyWindow(window);
SDL_Quit();