commit 5113f7ae93c355356d42275d5c313d7e6206e52f Author: nefrace Date: Mon May 12 00:56:47 2025 +0300 init, disco diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8908427 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +flashtest + diff --git a/fshader.glsl b/fshader.glsl new file mode 100644 index 0000000..e6628b2 --- /dev/null +++ b/fshader.glsl @@ -0,0 +1,67 @@ +#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; + +// Output fragment color +out vec4 finalColor; + +#define MAX_LIGHTS 12 + +struct Light { + int enabled; + vec3 position; + vec4 color; +}; + +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; + + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + if (texelColor.a == 0.0) discard; + if (fragColor.b < 1.0) { + finalColor = vec4(1.0, 1.0, 1.0, 1.0); + } else { + 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 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; + + } + } + finalColor.rgb = (texelColor.rgb * lightDot); + // finalColor.rgb = normal; + // finalColor = (texelColor * vec4(lightDot, 1.0)); + // finalColor = pow(finalColor, vec4(1.0/2.2)); + // finalColor.rgb = fragPosition; + } +} diff --git a/main.odin b/main.odin new file mode 100644 index 0000000..1c34673 --- /dev/null +++ b/main.odin @@ -0,0 +1,165 @@ +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, + position: [3]f32, + color: [4]f32, + enabledLoc: i32, + positionLoc: i32, + colorLoc: i32, +} + +MAX_LIGHTS :: 12 + +lights := [MAX_LIGHTS]Light{} + +main :: proc() { + 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() + target := rl.LoadRenderTexture(w / 2, h / 2) + + + texture := rl.LoadTexture("./playerBlue_walk4.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) + 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.enabledLoc = rl.GetShaderLocation(shader, rl.TextFormat("lights[%i].enabled", 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.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() { + 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.DrawTexturePro( + target.texture, + rl.Rectangle{0, f32(h / 2), f32(w / 2), -f32(h / 2)}, + {0, 0, f32(w), f32(h)}, + {}, + 0, + rl.WHITE, + ) + // rl.EndShaderMode() + rl.EndDrawing() + } +} + + +vshader: cstring = #load("./vshader.glsl", cstring) +fshader: cstring = #load("./fshader.glsl", cstring) +postprocess: cstring = #load("./postprocess.glsl", cstring) + diff --git a/playerBlue_walk4.png b/playerBlue_walk4.png new file mode 100644 index 0000000..2176a39 Binary files /dev/null and b/playerBlue_walk4.png differ diff --git a/postprocess.glsl b/postprocess.glsl new file mode 100644 index 0000000..d652827 --- /dev/null +++ b/postprocess.glsl @@ -0,0 +1,22 @@ +#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; +} diff --git a/vshader.glsl b/vshader.glsl new file mode 100644 index 0000000..37e83f0 --- /dev/null +++ b/vshader.glsl @@ -0,0 +1,35 @@ + + +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; + +// Output vertex attributes (to fragment shader) +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +// NOTE: Add your custom variables here + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + // fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +}