package main import "core:log" import "core:math" import "core:math/linalg" import "core:math/rand" import rl "vendor:raylib" Buddy :: struct { pos: [3]f32, gothit: bool, hit_timer: f32, } Light :: struct { enabled: i32, distanceNear: f32, distanceFar: f32, power: f32, position: [3]f32, color: [4]f32, enabledLoc: i32, distanceNearLoc: i32, distanceFarLoc: i32, powerLoc: i32, positionLoc: i32, colorLoc: i32, } MAX_LIGHTS :: 12 lights := [MAX_LIGHTS]Light{} main :: proc() { rl.SetConfigFlags({.WINDOW_RESIZABLE, .MSAA_4X_HINT}) rl.InitWindow(900, 600, "flash") checker := rl.GenImageChecked(128, 128, 32, 32, {128, 128, 128, 255}, {150, 150, 150, 255}) defer rl.UnloadImage(checker) checktex := rl.LoadTextureFromImage(checker) defer rl.UnloadTexture(checktex) checkmtl := rl.LoadMaterialDefault() rl.SetMaterialTexture(&checkmtl, .ALBEDO, checktex) checkplane := rl.GenMeshPlane(30, 30, 1, 1) rl.GenMeshTangents(&checkplane) w, h := rl.GetScreenWidth(), rl.GetScreenHeight() pixelize: i32 = 2 target := rl.LoadRenderTexture(w / pixelize, h / pixelize) palette := rl.LoadTexture("assets/gfx/blood-crow-1x.png") rl.SetTextureFilter(palette, .POINT) texture := rl.LoadTexture("assets/gfx/buddy.png") defer rl.UnloadTexture(texture) buddies := [dynamic]Buddy{} defer delete(buddies) for i := 0; i < 1000; i += 1 { buddy := Buddy { pos = {rand.float32_range(-10, 10), 1, rand.float32_range(-10, 10)}, gothit = false, hit_timer = rand.float32_range(1, 15), } append(&buddies, buddy) } shader := rl.LoadShaderFromMemory(vshader, fshader) posterizer := rl.LoadShaderFromMemory(nil, postprocess) poster_palette := rl.GetShaderLocation(posterizer, "texture1") checkmtl.shader = shader for &light, i in lights { light.enabled = 1 color := rl.ColorFromHSV(f32(i) / f32(MAX_LIGHTS) * 360, 1, 1) light.color = [4]f32 { f32(color.r) / 255, f32(color.g) / 255, f32(color.b) / 255, f32(color.a) / 255, } light.position = {rand.float32_range(-20, 20), 3, rand.float32_range(-20, 20)} light.power = rand.float32_range(0.9, 1.5) light.distanceFar = rand.float32_range(7, 11) light.enabledLoc = rl.GetShaderLocation(shader, rl.TextFormat("lights[%i].enabled", i)) light.distanceNearLoc = rl.GetShaderLocation( shader, rl.TextFormat("lights[%i].distanceNear", i), ) light.distanceFarLoc = rl.GetShaderLocation( shader, rl.TextFormat("lights[%i].distanceFar", i), ) light.powerLoc = rl.GetShaderLocation(shader, rl.TextFormat("lights[%i].power", i)) light.positionLoc = rl.GetShaderLocation(shader, rl.TextFormat("lights[%i].position", i)) light.colorLoc = rl.GetShaderLocation(shader, rl.TextFormat("lights[%i].color", i)) rl.SetShaderValue(shader, light.enabledLoc, &(light.enabled), .INT) rl.SetShaderValue(shader, light.distanceNearLoc, &(light.distanceNear), .FLOAT) rl.SetShaderValue(shader, light.distanceFarLoc, &(light.distanceFar), .FLOAT) rl.SetShaderValue(shader, light.powerLoc, &(light.power), .FLOAT) rl.SetShaderValue(shader, light.enabledLoc, &(light.enabled), .INT) rl.SetShaderValue(shader, light.enabledLoc, &(light.enabled), .INT) rl.SetShaderValue(shader, light.positionLoc, &(light.position), .VEC3) rl.SetShaderValue(shader, light.colorLoc, &(light.color), .VEC4) } cam := rl.Camera3D { position = {20, 20, 20}, target = {0, 0, 0}, up = {0, 1, 0}, fovy = 25, projection = .PERSPECTIVE, } log.info("Buddies: ", len(buddies)) rotation: f32 = 0.0 for !rl.WindowShouldClose() { if rl.IsWindowResized() { w, h = rl.GetScreenWidth(), rl.GetScreenHeight() rl.UnloadRenderTexture(target) target = rl.LoadRenderTexture(w / pixelize, h / pixelize) } delta := rl.GetFrameTime() rotation += delta rl.BeginTextureMode(target) rl.ClearBackground(rl.BLACK) rl.BeginMode3D(cam) // rl.DrawPlane({0, 0, 0}, {30, 30}, rl.WHITE) for &light, i in lights { color: [4]u8 = { u8(light.color.r * 255), u8(light.color.g * 255), u8(light.color.b * 255), u8(light.color.a * 255), } light.position.xz = [2]f32 { math.cos_f32(rotation + (f32(i) / f32(MAX_LIGHTS)) * math.PI * 2) * 8, math.sin_f32(rotation + (f32(i) / f32(MAX_LIGHTS)) * math.PI * 2) * 8, } rl.SetShaderValue(shader, light.positionLoc, &(light.position), .VEC3) rl.DrawSphere(light.position, 1, transmute(rl.Color)color) } rl.BeginShaderMode(shader) rl.DrawMesh(checkplane, checkmtl, rl.Matrix(1)) // rl.DrawPlane({}, 100, rl.GREEN) for &buddy in buddies { buddy.hit_timer -= delta if buddy.hit_timer < 0.2 { buddy.gothit = true if buddy.hit_timer < 0 { buddy.gothit = false buddy.hit_timer = rand.float32_range(1, 5) } } color := rl.WHITE if buddy.gothit do color = rl.RED rl.DrawBillboard(cam, texture, buddy.pos, 1, color) } // for &buddy in buddies { // color := rl.WHITE // if buddy.gothit do color = rl.RED // rl.DrawCubeV(buddy.pos, {0.3, 0.5, 0.3}, color) // } rl.EndShaderMode() rl.EndMode3D() rl.EndTextureMode() rl.BeginDrawing() rl.BeginShaderMode(posterizer) rl.SetShaderValueTexture(posterizer, poster_palette, palette) rl.DrawTexturePro( target.texture, rl.Rectangle{0, f32(h / pixelize), f32(w / pixelize), -f32(h / pixelize)}, {0, 0, f32(w), f32(h)}, {}, 0, rl.WHITE, ) rl.EndShaderMode() rl.DrawTexture(palette, 0, 0, rl.WHITE) rl.EndDrawing() } } vshader: cstring = #load("assets/shaders/vshader.glsl", cstring) fshader: cstring = #load("assets/shaders/fshader.glsl", cstring) postprocess: cstring = #load("assets/shaders/postprocess.glsl", cstring)