diff --git a/.helix/config.toml b/.helix/config.toml new file mode 100644 index 0000000..d922310 --- /dev/null +++ b/.helix/config.toml @@ -0,0 +1,3 @@ +[keys.normal." "."o"] # test2 +r = ":run-shell-command odin run ." +d = ":run-shell-command odin run . -debug" diff --git a/assets/gfx/blood-crow-1x.png b/assets/gfx/blood-crow-1x.png new file mode 100644 index 0000000..e96f8b2 Binary files /dev/null and b/assets/gfx/blood-crow-1x.png differ diff --git a/assets/gfx/blood-crow-8x.png b/assets/gfx/blood-crow-8x.png new file mode 100644 index 0000000..3d8b895 Binary files /dev/null and b/assets/gfx/blood-crow-8x.png differ diff --git a/playerBlue_walk4.png b/assets/gfx/buddy.png similarity index 100% rename from playerBlue_walk4.png rename to assets/gfx/buddy.png diff --git a/fshader.glsl b/assets/shaders/fshader.glsl similarity index 79% rename from fshader.glsl rename to assets/shaders/fshader.glsl index e6628b2..8913c7a 100644 --- a/fshader.glsl +++ b/assets/shaders/fshader.glsl @@ -17,6 +17,9 @@ out vec4 finalColor; struct Light { int enabled; + float distanceNear; + float distanceFar; + float power; vec3 position; vec4 color; }; @@ -35,26 +38,23 @@ void main() vec3 lightDot = vec3(0.0); vec4 tint = colDiffuse * fragColor; vec3 normal = normalize(fragNormal); - float lightpower = 0.0; - // finalColor.rgb = vec3(0.0); for (int i = 0; i < MAX_LIGHTS; i++) { if (lights[i].enabled == 1) { - // finalColor.r += 0.05; vec3 light = vec3(0.0); light = normalize(lights[i].position - fragPosition); float dist = distance(lights[i].position, fragPosition); - float near = smoothstep(5.0, 2.0, dist); - float far = smoothstep(30.0, 1.0, dist) / 3.0; - float power = near + far * far * far; - lightpower += power; + float power = smoothstep(lights[i].distanceFar, lights[i].distanceNear, dist); + // float far = smoothstep(30.0, 1.0, dist) / 3.0; + // float power = near + far * far * far; + power = power * power; float NdotL = max(dot(normal, light), 0.0); // lightDot += lights[i].color.rgb * light * NdotL; // lightDot += lights[i].color.rgb * power * NdotL; - lightDot += lights[i].color.rgb * power; + lightDot += lights[i].color.rgb * power * lights[i].power; } } diff --git a/assets/shaders/postprocess.glsl b/assets/shaders/postprocess.glsl new file mode 100644 index 0000000..8f6a90b --- /dev/null +++ b/assets/shaders/postprocess.glsl @@ -0,0 +1,30 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform vec4 colDiffuse; + +#define POSTERIZE 5.0 + +out vec4 finalColor; + +void main() { + vec4 texelColor = texture(texture0, fragTexCoord); + float grey = 0.21 * texelColor.r + 0.71 * texelColor.g + 0.07 * texelColor.b ; + vec2 paluv = vec2(grey, 0.5); + vec4 paletteValue = texture(texture1, paluv); + + finalColor.a = 1.0; + // finalColor.rgb = floor(texelColor.rgb * POSTERIZE) / POSTERIZE; + + finalColor.rgb = paletteValue.rgb; + // + // finalColor.rgb = vec3(mean) + paletteValue.rgb; +} diff --git a/vshader.glsl b/assets/shaders/vshader.glsl similarity index 100% rename from vshader.glsl rename to assets/shaders/vshader.glsl diff --git a/main.odin b/main.odin index 1c34673..e0a82b0 100644 --- a/main.odin +++ b/main.odin @@ -16,12 +16,18 @@ Buddy :: struct { Light :: struct { - enabled: i32, - position: [3]f32, - color: [4]f32, - enabledLoc: i32, - positionLoc: i32, - colorLoc: i32, + 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 @@ -29,6 +35,7 @@ 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}) @@ -41,10 +48,14 @@ main :: proc() { rl.GenMeshTangents(&checkplane) w, h := rl.GetScreenWidth(), rl.GetScreenHeight() - target := rl.LoadRenderTexture(w / 2, h / 2) + 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("./playerBlue_walk4.png") + texture := rl.LoadTexture("assets/gfx/buddy.png") defer rl.UnloadTexture(texture) @@ -61,6 +72,7 @@ main :: proc() { shader := rl.LoadShaderFromMemory(vshader, fshader) posterizer := rl.LoadShaderFromMemory(nil, postprocess) + poster_palette := rl.GetShaderLocation(posterizer, "texture1") checkmtl.shader = shader for &light, i in lights { @@ -73,11 +85,27 @@ main :: proc() { 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) @@ -98,6 +126,11 @@ main :: proc() { 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) @@ -144,22 +177,24 @@ main :: proc() { rl.EndMode3D() rl.EndTextureMode() rl.BeginDrawing() - // rl.BeginShaderMode(posterizer) + rl.BeginShaderMode(posterizer) + rl.SetShaderValueTexture(posterizer, poster_palette, palette) rl.DrawTexturePro( target.texture, - rl.Rectangle{0, f32(h / 2), f32(w / 2), -f32(h / 2)}, + rl.Rectangle{0, f32(h / pixelize), f32(w / pixelize), -f32(h / pixelize)}, {0, 0, f32(w), f32(h)}, {}, 0, rl.WHITE, ) - // rl.EndShaderMode() + rl.EndShaderMode() + rl.DrawTexture(palette, 0, 0, rl.WHITE) rl.EndDrawing() } } -vshader: cstring = #load("./vshader.glsl", cstring) -fshader: cstring = #load("./fshader.glsl", cstring) -postprocess: cstring = #load("./postprocess.glsl", cstring) +vshader: cstring = #load("assets/shaders/vshader.glsl", cstring) +fshader: cstring = #load("assets/shaders/fshader.glsl", cstring) +postprocess: cstring = #load("assets/shaders/postprocess.glsl", cstring) diff --git a/postprocess.glsl b/postprocess.glsl deleted file mode 100644 index d652827..0000000 --- a/postprocess.glsl +++ /dev/null @@ -1,22 +0,0 @@ -#version 330 - -// Input vertex attributes (from vertex shader) -in vec3 fragPosition; -in vec2 fragTexCoord; -in vec4 fragColor; -in vec3 fragNormal; - -// Input uniform values -uniform sampler2D texture0; -uniform vec4 colDiffuse; - -#define POSTERIZE 5.0 - -out vec4 finalColor; - -void main() { - vec4 texelColor = texture(texture0, fragTexCoord); - - finalColor.a = 1.0; - finalColor.rgb = floor(texelColor.rgb * POSTERIZE) / POSTERIZE; -}