package main import "core:fmt" 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 :: 4 lights := [MAX_LIGHTS]Light{} main :: proc() { rl.SetConfigFlags({.WINDOW_RESIZABLE, .MSAA_4X_HINT}) rl.InitWindow(900, 600, "flash") rl.ToggleBorderlessWindowed() 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 = 3 target := rl.LoadRenderTexture(w / pixelize, h / pixelize) posttarget := rl.LoadRenderTexture(w / pixelize, h / pixelize) palette := rl.LoadTexture("assets/gfx/bluem0ld-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, 0, 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 = 0.8 light.distanceFar = 10 light.distanceNear = 0 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) } lights[0].power = 1.1 lights[0].distanceNear = 1 rl.SetShaderValue(shader, lights[0].distanceNearLoc, &(lights[0].distanceNear), .FLOAT) rl.SetShaderValue(shader, lights[0].powerLoc, &(lights[0].power), .FLOAT) sponza := rl.LoadModel("assets/models/sponza.glb") for &material in sponza.materials[:sponza.materialCount] { material.shader = shader } cam := rl.Camera3D { position = {0, 1, 0}, target = {1, 1, 0}, up = {0, 1, 0}, fovy = 90, projection = .PERSPECTIVE, } log.info("Buddies: ", len(buddies)) rotation: f32 = 0.0 rl.DisableCursor() for !rl.WindowShouldClose() { if rl.IsWindowResized() { w, h = rl.GetScreenWidth(), rl.GetScreenHeight() rl.UnloadRenderTexture(target) target = rl.LoadRenderTexture(w / pixelize, h / pixelize) rl.UnloadRenderTexture(posttarget) posttarget = rl.LoadRenderTexture(w / pixelize, h / pixelize) } rl.UpdateCamera(&cam, .FIRST_PERSON) 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[1:] { 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) * 5, math.sin_f32(rotation + (f32(i) / f32(MAX_LIGHTS)) * math.PI * 2) * 5, } rl.SetShaderValue(shader, light.positionLoc, &(light.position), .VEC3) rl.DrawSphere(light.position, 0.1, transmute(rl.Color)color) } lights[0].position = cam.position rl.SetShaderValue(shader, lights[0].positionLoc, &(lights[0].position), .VEC3) rl.DrawModel(sponza, {}, 1, rl.WHITE) 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.BeginTextureMode(posttarget) 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.DrawTexture(target.texture, 0, 0, rl.WHITE) rl.EndShaderMode() rl.EndTextureMode() rl.BeginDrawing() // rl.BeginTextureMode(posttarget) // rl.BeginShaderMode(posterizer) // rl.SetShaderValueTexture(posterizer, poster_palette, palette) rl.DrawTexturePro( posttarget.texture, rl.Rectangle{0, 0, f32(w / pixelize), f32(h / pixelize)}, {0, 0, f32(w), f32(h)}, {}, 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)