strichmaennchen git · main
git clone https://git.christianimmanuel.de/games/strichmaennchen.gitwget https://git.christianimmanuel.de/games/strichmaennchen/archive/strichmaennchen.tar.gzworld.c raw
#include "world.h"
#include "glfuncs.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
void World_init(World *world) {
world->countObjects = 0;
world->capacityObjects = 16;
world->objects = malloc(world->capacityObjects * sizeof(Object*));
world->countHumans = 0;
world->capacityHumans = 16;
world->humans = malloc(world->capacityHumans * sizeof(Object*));
}
void World_addObject(World *world, Object *obj) {
if (world->countObjects >= world->capacityObjects) {
world->capacityObjects *= 2;
world->objects = realloc(world->objects, world->capacityObjects * sizeof(Object*));
}
world->objects[world->countObjects++] = obj;
}
void World_removeObject(World *world, Object *obj) {
for (int i = 0; i < world->countObjects; i++) {
if (world->objects[i] == obj) {
world->objects[i] = world->objects[--world->countObjects];
return;
}
}
}
void World_addHuman(World *world, Human *hum) {
if (world->countHumans >= world->capacityHumans) {
world->capacityHumans *= 2;
world->humans = realloc(world->humans, world->capacityHumans * sizeof(Human*));
}
world->humans[world->countHumans++] = hum;
World_addObject(world, hum->object);
}
void World_removeHuman(World *world, Human *hum) {
for (int i = 0; i < world->countHumans; i++) {
if (world->humans[i] == hum) {
world->humans[i] = world->humans[--world->countHumans];
return;
}
}
}
void World_update(World *world, float dt) {
for (int i = 0; i < world->countObjects; i++) {
Object_update(world->objects[i], world->objects, world->countObjects, dt);
}
}
void World_render(World *world, Renderer *renderer, Camera *camera, Time* time) {
for (int i = 0; i < world->countObjects; i++) {
Object_render(world->objects[i], renderer, camera, time);
}
}
void World_renderShadows(World* world, Renderer* renderer, Time* time) {
// Compute light matrices
Vec3 forward = vec3_normalize(time->sunDirection);
Vec3 arbitrary = fabsf(forward.y) > 0.99f ? (Vec3){1,0,0} : (Vec3){0,1,0};
Vec3 right = vec3_normalize(vec3_cross(arbitrary, forward));
Vec3 up = vec3_cross(forward, right);
Vec3 lightPos = vec3_scale(forward, 50.0f);
Vec3 lightTarget = (Vec3){0, 0, 0};
renderer->lightView = mat4_lookAt(lightPos, lightTarget, up);
float left = -30.0f, rightv = 30.0f, bottom = -30.0f, top = 30.0f, near = -100.0f, far = 100.0f;
renderer->lightProjection = mat4_orthographic(left, rightv, bottom, top, near, far);
// Shadow pass
glViewport(0, 0, renderer->shadowMapWidth, renderer->shadowMapHeight);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->shadowFramebuffer);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0f, 1.0f);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glUseProgram(renderer->shadowShader);
for (int i = 0; i < world->countObjects; i++) {
Object* obj = world->objects[i];
Mat4 model = mat4_translate(vec3_add(obj->position, obj->position_center));
model = mat4_mul(model, mat4_rotate_x(obj->rotation.x));
model = mat4_mul(model, mat4_rotate_y(obj->rotation.y));
model = mat4_mul(model, mat4_rotate_z(obj->rotation.z));
Mat4 lightSpace = mat4_mul(renderer->lightProjection, mat4_mul(renderer->lightView, model));
GLint loc = glGetUniformLocation(renderer->shadowShader, "lightSpaceMatrix");
glUniformMatrix4fv(loc, 1, GL_FALSE, (float*)&lightSpace);
glBindVertexArray(obj->mesh.vao);
if (obj->mesh.hasIndices) {
glDrawElements(GL_TRIANGLES, obj->mesh.indexCount, GL_UNSIGNED_INT, 0);
} else {
glDrawArrays(obj->mesh.drawMode, 0, obj->mesh.vertexCount);
}
}
glDisable(GL_CULL_FACE);
glDisable(GL_POLYGON_OFFSET_FILL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, renderer->width, renderer->height);
}
void World_destroy(World *world) {
for (int i = 0; i < world->countObjects; i++) {
Object_destroy(world->objects[i]);
}
free(world->objects);
}