strichmaennchen git · main
git clone https://git.christianimmanuel.de/games/strichmaennchen.gitwget https://git.christianimmanuel.de/games/strichmaennchen/archive/strichmaennchen.tar.gzrenderer.c raw
#include <SDL3/SDL.h>
#include <SDL3/SDL_video.h>
#include <stdio.h>
#include <stdlib.h>
#include "renderer.h"
#include "mesh.h"
#include "shader.h"
#include "glfuncs.h"
#include "platform.h"
Renderer* Renderer_create(int width, int height) {
Renderer* renderer = calloc(1, sizeof(Renderer));
printf("sizeof(Renderer) = %zu\n", sizeof(Renderer));
if (!renderer) {
SDL_Log("Renderer allocation failed.");
return NULL;
}
if (!Platform_init(renderer)) {
SDL_Log("Renderer Platform_init failed.");
return NULL;
}
if (!Renderer_init(renderer, width, height)) {
SDL_Log("Renderer init failed");
Platform_shutdown(renderer);
return NULL;
}
return renderer;
}
bool Renderer_init(Renderer* renderer, int width, int height) {
renderer->width = width;
renderer->height = height;
char* vertSrc = readFile("shaders/basic.vert");
char* fragSrc = readFile("shaders/basic.frag");
if (!vertSrc || !fragSrc) {
fprintf(stderr, "Failed to load shader files\n");
free(vertSrc); free(fragSrc);
return false;
}
renderer->shaderProgram = createShaderProgram(vertSrc, fragSrc);
free(vertSrc);
free(fragSrc);
if (!renderer->shaderProgram) return false;
// Initialize shadow shader
char* shadowVert = readFile("shaders/simple.vert");
char* shadowFrag = readFile("shaders/simple.frag");
if (!shadowVert || !shadowFrag) {
fprintf(stderr, "Failed to load shadow shader files\n");
free(shadowVert); free(shadowFrag);
return false;
}
renderer->shadowShader = createShaderProgram(shadowVert, shadowFrag);
free(shadowVert); free(shadowFrag);
if (!renderer->shadowShader) return false;
// Initialize shadow map
renderer->shadowMapWidth = 4096; // Increased resolution for sharper shadows
renderer->shadowMapHeight = 4096;
glGenTextures(1, &renderer->shadowMap);
glBindTexture(GL_TEXTURE_2D, renderer->shadowMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, renderer->shadowMapWidth, renderer->shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // For PCF
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float borderColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glGenFramebuffers(1, &renderer->shadowFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->shadowFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderer->shadowMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "Shadow framebuffer incomplete!\n");
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.1f,0.1f,0.1f,1.0f);
return true;
}
void Renderer_resize(Renderer* renderer) {
SDL_GetWindowSize(renderer->window, &renderer->width, &renderer->height);
glViewport(0, 0, renderer->width, renderer->height);
}
void Renderer_clear(float r, float g, float b, float a) {
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Renderer_shutdown(Renderer* renderer) {
if (renderer->shaderProgram) glDeleteProgram(renderer->shaderProgram);
if (renderer->shadowShader) glDeleteProgram(renderer->shadowShader);
glDeleteFramebuffers(1, &renderer->shadowFramebuffer);
glDeleteTextures(1, &renderer->shadowMap);
}