diff --git a/assets/shaders/mesh.frag.glsl b/assets/shaders/mesh.frag.glsl index 662df20..1891868 100644 --- a/assets/shaders/mesh.frag.glsl +++ b/assets/shaders/mesh.frag.glsl @@ -1,30 +1,44 @@ #version 450 core -#define MAX_POINT_LIGHTS 1 +// Keep in sync with cpu +#define MAX_POINT_LIGHTS 8 layout(location = 0) in vec3 position; layout(location = 1) in vec3 normal; struct Light { vec4 pos; - // vec4 color; + vec4 color; }; layout(binding = 1, std140) uniform Lights { Light lights[MAX_POINT_LIGHTS]; + uint lights_count; }; +layout(location = 2) uniform vec3 color; + out vec4 FragColor; void main() { - vec3 diffuseColor = vec3(0.2, 0.5, 0.2); + vec3 diffuseColor = color; vec3 finalColor = vec3(0); - for (int i = 0; i < MAX_POINT_LIGHTS; i++) { - vec3 lightVec = normalize(lights[i].pos.xyz - position); - float ndotl = dot(normal, lightVec); + for (int i = 0; i < lights_count; i++) { + float radius = lights[i].pos.w; + vec3 L = lights[i].pos.xyz - position; + float dist = length(L); + float d = max(dist - radius, 0); + L /= dist; - finalColor += ndotl * diffuseColor; + float denom = d/radius + 1; + float att = 1 / (denom * denom); + // TODO: cutoff + att = max(att, 0); + + float ndotl = max(dot(L, normal), 0); + + finalColor += ndotl * lights[i].color.xyz * att * diffuseColor; } FragColor = vec4(finalColor, 1.0f); diff --git a/assets/sphere.mtl b/assets/sphere.mtl new file mode 100644 index 0000000..763e0ab --- /dev/null +++ b/assets/sphere.mtl @@ -0,0 +1,2 @@ +# Blender 4.0.2 MTL File: 'None' +# www.blender.org diff --git a/assets/sphere.obj b/assets/sphere.obj new file mode 100644 index 0000000..a34fff2 --- /dev/null +++ b/assets/sphere.obj @@ -0,0 +1,270 @@ +# Blender 4.0.2 +# www.blender.org +mtllib sphere.mtl +o Icosphere +v 0.000000 -0.100000 0.000000 +v 0.072361 -0.044722 0.052573 +v -0.027639 -0.044722 0.085065 +v -0.089443 -0.044722 0.000000 +v -0.027639 -0.044722 -0.085065 +v 0.072361 -0.044722 -0.052573 +v 0.027639 0.044722 0.085065 +v -0.072361 0.044722 0.052573 +v -0.072361 0.044722 -0.052573 +v 0.027639 0.044722 -0.085065 +v 0.089443 0.044722 0.000000 +v 0.000000 0.100000 0.000000 +v -0.016246 -0.085065 0.050000 +v 0.042532 -0.085065 0.030901 +v 0.026287 -0.052574 0.080901 +v 0.085065 -0.052574 0.000000 +v 0.042532 -0.085065 -0.030901 +v -0.052573 -0.085065 0.000000 +v -0.068819 -0.052574 0.050000 +v -0.016246 -0.085065 -0.050000 +v -0.068819 -0.052574 -0.050000 +v 0.026287 -0.052574 -0.080901 +v 0.095106 0.000000 0.030901 +v 0.095106 0.000000 -0.030901 +v 0.000000 0.000000 0.100000 +v 0.058779 0.000000 0.080902 +v -0.095106 0.000000 0.030901 +v -0.058779 0.000000 0.080902 +v -0.058779 0.000000 -0.080902 +v -0.095106 0.000000 -0.030901 +v 0.058779 0.000000 -0.080902 +v 0.000000 0.000000 -0.100000 +v 0.068819 0.052574 0.050000 +v -0.026287 0.052574 0.080901 +v -0.085065 0.052574 0.000000 +v -0.026287 0.052574 -0.080901 +v 0.068819 0.052574 -0.050000 +v 0.016246 0.085065 0.050000 +v 0.052573 0.085065 0.000000 +v -0.042532 0.085065 0.030901 +v -0.042532 0.085065 -0.030901 +v 0.016246 0.085065 -0.050000 +vn 0.1024 -0.9435 0.3151 +vn 0.7002 -0.6617 0.2680 +vn -0.2680 -0.9435 0.1947 +vn -0.2680 -0.9435 -0.1947 +vn 0.1024 -0.9435 -0.3151 +vn 0.9050 -0.3304 0.2680 +vn 0.0247 -0.3304 0.9435 +vn -0.8897 -0.3304 0.3151 +vn -0.5746 -0.3304 -0.7488 +vn 0.5346 -0.3304 -0.7779 +vn 0.8026 -0.1256 0.5831 +vn -0.3066 -0.1256 0.9435 +vn -0.9921 -0.1256 -0.0000 +vn -0.3066 -0.1256 -0.9435 +vn 0.8026 -0.1256 -0.5831 +vn 0.4089 0.6617 0.6284 +vn -0.4713 0.6617 0.5831 +vn -0.7002 0.6617 -0.2680 +vn 0.0385 0.6617 -0.7488 +vn 0.7240 0.6617 -0.1947 +vn 0.2680 0.9435 -0.1947 +vn 0.4911 0.7947 -0.3568 +vn 0.4089 0.6617 -0.6284 +vn -0.1024 0.9435 -0.3151 +vn -0.1876 0.7947 -0.5773 +vn -0.4713 0.6617 -0.5831 +vn -0.3313 0.9435 -0.0000 +vn -0.6071 0.7947 -0.0000 +vn -0.7002 0.6617 0.2680 +vn -0.1024 0.9435 0.3151 +vn -0.1876 0.7947 0.5773 +vn 0.0385 0.6617 0.7488 +vn 0.2680 0.9435 0.1947 +vn 0.4911 0.7947 0.3568 +vn 0.7240 0.6617 0.1947 +vn 0.8897 0.3304 -0.3151 +vn 0.7947 0.1876 -0.5773 +vn 0.5746 0.3304 -0.7488 +vn -0.0247 0.3304 -0.9435 +vn -0.3035 0.1876 -0.9342 +vn -0.5346 0.3304 -0.7779 +vn -0.9050 0.3304 -0.2680 +vn -0.9822 0.1876 -0.0000 +vn -0.9050 0.3304 0.2680 +vn -0.5346 0.3304 0.7779 +vn -0.3035 0.1876 0.9342 +vn -0.0247 0.3304 0.9435 +vn 0.5746 0.3304 0.7488 +vn 0.7947 0.1876 0.5773 +vn 0.8897 0.3304 0.3151 +vn 0.3066 0.1256 -0.9435 +vn 0.3035 -0.1876 -0.9342 +vn 0.0247 -0.3304 -0.9435 +vn -0.8026 0.1256 -0.5831 +vn -0.7947 -0.1876 -0.5773 +vn -0.8897 -0.3304 -0.3151 +vn -0.8026 0.1256 0.5831 +vn -0.7947 -0.1876 0.5773 +vn -0.5746 -0.3304 0.7488 +vn 0.3066 0.1256 0.9435 +vn 0.3035 -0.1876 0.9342 +vn 0.5346 -0.3304 0.7779 +vn 0.9921 0.1256 -0.0000 +vn 0.9822 -0.1876 -0.0000 +vn 0.9050 -0.3304 -0.2680 +vn 0.4713 -0.6617 -0.5831 +vn 0.1876 -0.7947 -0.5773 +vn -0.0385 -0.6617 -0.7488 +vn -0.4089 -0.6617 -0.6284 +vn -0.4911 -0.7947 -0.3568 +vn -0.7240 -0.6617 -0.1947 +vn -0.7240 -0.6617 0.1947 +vn -0.4911 -0.7947 0.3568 +vn -0.4089 -0.6617 0.6284 +vn 0.7002 -0.6617 -0.2680 +vn 0.6071 -0.7947 -0.0000 +vn 0.3313 -0.9435 -0.0000 +vn -0.0385 -0.6617 0.7488 +vn 0.1876 -0.7947 0.5773 +vn 0.4713 -0.6617 0.5831 +vt 0.181819 0.000000 +vt 0.227273 0.078731 +vt 0.136365 0.078731 +vt 0.272728 0.157461 +vt 0.318182 0.078731 +vt 0.363637 0.157461 +vt 0.909091 0.000000 +vt 0.954545 0.078731 +vt 0.863636 0.078731 +vt 0.727273 0.000000 +vt 0.772727 0.078731 +vt 0.681818 0.078731 +vt 0.545455 0.000000 +vt 0.590909 0.078731 +vt 0.500000 0.078731 +vt 0.318182 0.236191 +vt 0.090910 0.157461 +vt 0.181819 0.157461 +vt 0.136365 0.236191 +vt 0.818182 0.157461 +vt 0.909091 0.157461 +vt 0.863636 0.236191 +vt 0.636364 0.157461 +vt 0.727273 0.157461 +vt 0.681818 0.236191 +vt 0.454546 0.157461 +vt 0.545455 0.157461 +vt 0.500000 0.236191 +vt 0.227273 0.236191 +vt 0.045455 0.236191 +vt 0.772727 0.236191 +vt 0.590909 0.236191 +vt 0.409092 0.236191 +vt 0.181819 0.314921 +vt 0.272728 0.314921 +vt 0.227273 0.393651 +vt 0.000000 0.314921 +vt 0.090910 0.314921 +vt 0.045455 0.393651 +vt 0.727273 0.314921 +vt 0.818182 0.314921 +vt 0.772727 0.393651 +vt 0.545455 0.314921 +vt 0.636364 0.314921 +vt 0.590909 0.393651 +vt 0.363637 0.314921 +vt 0.454546 0.314921 +vt 0.409092 0.393651 +vt 0.500000 0.393651 +vt 0.454546 0.472382 +vt 0.681818 0.393651 +vt 0.636364 0.472382 +vt 0.863636 0.393651 +vt 0.818182 0.472382 +vt 0.909091 0.314921 +vt 0.136365 0.393651 +vt 0.090910 0.472382 +vt 0.318182 0.393651 +vt 0.272728 0.472382 +vt 0.954545 0.236191 +vt 1.000000 0.157461 +vt 0.409092 0.078731 +vt 0.363637 0.000000 +s 0 +f 1/1/1 14/2/1 13/3/1 +f 2/4/2 14/5/2 16/6/2 +f 1/7/3 13/8/3 18/9/3 +f 1/10/4 18/11/4 20/12/4 +f 1/13/5 20/14/5 17/15/5 +f 2/4/6 16/6/6 23/16/6 +f 3/17/7 15/18/7 25/19/7 +f 4/20/8 19/21/8 27/22/8 +f 5/23/9 21/24/9 29/25/9 +f 6/26/10 22/27/10 31/28/10 +f 2/4/11 23/16/11 26/29/11 +f 3/17/12 25/19/12 28/30/12 +f 4/20/13 27/22/13 30/31/13 +f 5/23/14 29/25/14 32/32/14 +f 6/26/15 31/28/15 24/33/15 +f 7/34/16 33/35/16 38/36/16 +f 8/37/17 34/38/17 40/39/17 +f 9/40/18 35/41/18 41/42/18 +f 10/43/19 36/44/19 42/45/19 +f 11/46/20 37/47/20 39/48/20 +f 39/48/21 42/49/21 12/50/21 +f 39/48/22 37/47/22 42/49/22 +f 37/47/23 10/43/23 42/49/23 +f 42/45/24 41/51/24 12/52/24 +f 42/45/25 36/44/25 41/51/25 +f 36/44/26 9/40/26 41/51/26 +f 41/42/27 40/53/27 12/54/27 +f 41/42/28 35/41/28 40/53/28 +f 35/41/29 8/55/29 40/53/29 +f 40/39/30 38/56/30 12/57/30 +f 40/39/31 34/38/31 38/56/31 +f 34/38/32 7/34/32 38/56/32 +f 38/36/33 39/58/33 12/59/33 +f 38/36/34 33/35/34 39/58/34 +f 33/35/35 11/46/35 39/58/35 +f 24/33/36 37/47/36 11/46/36 +f 24/33/37 31/28/37 37/47/37 +f 31/28/38 10/43/38 37/47/38 +f 32/32/39 36/44/39 10/43/39 +f 32/32/40 29/25/40 36/44/40 +f 29/25/41 9/40/41 36/44/41 +f 30/31/42 35/41/42 9/40/42 +f 30/31/43 27/22/43 35/41/43 +f 27/22/44 8/55/44 35/41/44 +f 28/30/45 34/38/45 8/37/45 +f 28/30/46 25/19/46 34/38/46 +f 25/19/47 7/34/47 34/38/47 +f 26/29/48 33/35/48 7/34/48 +f 26/29/49 23/16/49 33/35/49 +f 23/16/50 11/46/50 33/35/50 +f 31/28/51 32/32/51 10/43/51 +f 31/28/52 22/27/52 32/32/52 +f 22/27/53 5/23/53 32/32/53 +f 29/25/54 30/31/54 9/40/54 +f 29/25/55 21/24/55 30/31/55 +f 21/24/56 4/20/56 30/31/56 +f 27/22/57 28/60/57 8/55/57 +f 27/22/58 19/21/58 28/60/58 +f 19/21/59 3/61/59 28/60/59 +f 25/19/60 26/29/60 7/34/60 +f 25/19/61 15/18/61 26/29/61 +f 15/18/62 2/4/62 26/29/62 +f 23/16/63 24/33/63 11/46/63 +f 23/16/64 16/6/64 24/33/64 +f 16/6/65 6/26/65 24/33/65 +f 17/15/66 22/27/66 6/26/66 +f 17/15/67 20/14/67 22/27/67 +f 20/14/68 5/23/68 22/27/68 +f 20/12/69 21/24/69 5/23/69 +f 20/12/70 18/11/70 21/24/70 +f 18/11/71 4/20/71 21/24/71 +f 18/9/72 19/21/72 4/20/72 +f 18/9/73 13/8/73 19/21/73 +f 13/8/74 3/61/74 19/21/74 +f 16/6/75 17/62/75 6/26/75 +f 16/6/76 14/5/76 17/62/76 +f 14/5/77 1/63/77 17/62/77 +f 13/3/78 15/18/78 3/17/78 +f 13/3/79 14/2/79 15/18/79 +f 14/2/80 2/4/80 15/18/80 diff --git a/src/game.zig b/src/game.zig index 5cbb711..bcb6b2b 100644 --- a/src/game.zig +++ b/src/game.zig @@ -34,7 +34,7 @@ const DEFAULT_WIDTH = 800; const DEFAULT_HEIGHT = 600; const MAX_ENTITIES = 1024; -const MAX_POINT_LIGHTS = 1; +const MAX_POINT_LIGHTS = 8; // TODO: move out into renderer file maybe const Attrib = enum(gl.GLuint) { @@ -68,6 +68,7 @@ pub const Entity = struct { active: bool = false, mesh: bool = false, point_light: bool = false, + rotate: bool = false, }; pub const Transform = struct { @@ -83,10 +84,20 @@ pub const Entity = struct { pub const Mesh = struct { handle: AssetManager.Handle.Mesh = .{}, + color: Vec3 = Vec3.one(), }; - pub const PointLight = struct { - color: Vec4 = Vec4.one(), + radius: f32 = std.math.floatEps(f32), // should never be 0 or bad things happen + color_intensity: Vec4 = Vec4.one(), // x, y, z - color, w - intensity + + pub fn color(self: *PointLight) Vec3 { + const col = self.color_intensity; + return Vec3.new(col.x(), col.y(), col.z()); + } + }; + pub const Rotate = struct { + axis: Vec3 = Vec3.up(), + rate: f32 = 0, // deg/s }; // Entity list and handle management @@ -99,6 +110,7 @@ pub const Entity = struct { transform: Transform = .{}, mesh: Mesh = .{}, point_light: PointLight = .{}, + rotate: Rotate = .{}, }; pub const EntityHandle = packed struct { @@ -404,9 +416,20 @@ export fn game_init(global_allocator: *std.mem.Allocator) void { } _ = g_mem.world.addEntity(.{ - .transform = .{ .pos = Vec3.new(0, 1, 0) }, - .flags = .{ .point_light = true }, - .point_light = .{ .color = Vec4.new(1.0, 0.5, 0.2, 1.0) }, + .transform = .{ .pos = Vec3.new(1, 1, 0) }, + .flags = .{ .point_light = true, .rotate = true }, + .point_light = .{ .color_intensity = Vec4.new(1.0, 0.5, 0.2, 1.0), .radius = 1 }, + .rotate = .{ .axis = Vec3.up(), .rate = 60 }, + }); + + _ = g_mem.world.addEntity(.{ + .transform = .{ .pos = Vec3.new(-1, 1, 0) }, + .flags = .{ .point_light = true, .rotate = true }, + .point_light = .{ + .color_intensity = Vec4.new(0.2, 0.5, 1.0, 1.0), + .radius = 1, + }, + .rotate = .{ .axis = Vec3.up(), .rate = -60 }, }); // 10 bunnies @@ -429,12 +452,13 @@ pub const CameraMatrices = extern struct { view: Mat4, }; pub const RenderPointLight = extern struct { - pos: Vec4, // it's vec3, but glsl std140 requires 16 byte alignment anyway - // color: Vec4, + pos_radius: Vec4, // x, y, z - pos, w - radius + color_intensity: Vec4, // x, y, z - color, w - intensity }; pub const RenderPointLightArray = extern struct { lights: [MAX_POINT_LIGHTS]RenderPointLight, + count: c_uint, }; export fn game_update() bool { @@ -610,25 +634,29 @@ export fn game_update() bool { // Collect point lights { const point_lights = &gmem.point_lights[gmem.tripple_buffer_index]; - var point_lights_count: usize = 0; + point_lights.count = 0; for (0..gmem.world.entity_count) |i| { const ent = &gmem.world.entities[i]; if (!ent.flags.active) continue; - if (ent.flags.point_light) { + if (ent.flags.rotate) { + const old_pos = ent.transform.pos; const new_pos = Mat4.fromRotation( - gmem.rotation, - Vec3.up(), - ).mulByVec4(Vec4.new(2, 1, 0, 1)); + ent.rotate.rate * gmem.delta_time, + ent.rotate.axis, + ).mulByVec4(Vec4.new(old_pos.x(), old_pos.y(), old_pos.z(), 1)); ent.transform.pos = Vec3.new(new_pos.x(), new_pos.y(), new_pos.z()); + } - point_lights.lights[point_lights_count] = .{ - .pos = new_pos, - // .color = ent.point_light.color, + if (ent.flags.point_light) { + const pos = ent.transform.pos; + point_lights.lights[point_lights.count] = .{ + .pos_radius = Vec4.new(pos.x(), pos.y(), pos.z(), ent.point_light.radius), + .color_intensity = ent.point_light.color_intensity, }; - point_lights_count += 1; - if (point_lights_count == point_lights.lights.len) { + point_lights.count += 1; + if (point_lights.count == MAX_POINT_LIGHTS) { break; } } @@ -651,23 +679,28 @@ export fn game_update() bool { gmem.rotation += 60 * gmem.delta_time; - // Render meshes + // Render meshes and lights for (0..gmem.world.entity_count) |i| { const ent = &gmem.world.entities[i]; - if (!ent.flags.active or !ent.flags.mesh) continue; + if (!ent.flags.active) continue; - gl.uniformMatrix4fv(1, 1, gl.FALSE, @ptrCast(&ent.transform.matrix().data)); + if (ent.flags.mesh or ent.flags.point_light) { + const color = if (ent.flags.mesh) ent.mesh.color else ent.point_light.color(); + gl.uniformMatrix4fv(1, 1, gl.FALSE, @ptrCast(&ent.transform.matrix().data)); + gl.uniform3fv(2, 1, @ptrCast(&color.data)); - const mesh = g_assetman.resolveMesh(ent.mesh.handle); - mesh.positions.bind(Attrib.Position.value()); - mesh.normals.bind(Attrib.Normal.value()); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer); - gl.drawElements( - gl.TRIANGLES, - mesh.indices.count, - mesh.indices.type, - @ptrFromInt(mesh.indices.offset), - ); + const mesh_handle = if (ent.flags.mesh) ent.mesh.handle else a.Meshes.sphere; + const mesh = g_assetman.resolveMesh(mesh_handle); + mesh.positions.bind(Attrib.Position.value()); + mesh.normals.bind(Attrib.Normal.value()); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer); + gl.drawElements( + gl.TRIANGLES, + mesh.indices.count, + mesh.indices.type, + @ptrFromInt(mesh.indices.offset), + ); + } } c.SDL_GL_SwapWindow(ginit.window); diff --git a/src/gen/asset_manifest.gen.zig b/src/gen/asset_manifest.gen.zig index a976314..0900330 100644 --- a/src/gen/asset_manifest.gen.zig +++ b/src/gen/asset_manifest.gen.zig @@ -5,6 +5,7 @@ const Handle = @import("assets").Handle; pub const Meshes = struct { pub const bunny = Handle.Mesh{ .id = 1 }; + pub const sphere = Handle.Mesh{ .id = 7 }; }; pub const Shaders = struct { @@ -25,6 +26,7 @@ pub const asset_paths = [_][]const u8{ "assets\\shaders\\mesh.prog", "assets\\shaders\\mesh.vert.glsl", "assets\\shaders\\vert.glsl", + "assets\\sphere.mesh", }; pub const asset_path_to_asset_id = std.ComptimeStringMap(u32, .{ @@ -34,5 +36,6 @@ pub const asset_path_to_asset_id = std.ComptimeStringMap(u32, .{ .{ "assets\\shaders\\mesh.prog", 4 }, .{ "assets\\shaders\\mesh.vert.glsl", 5 }, .{ "assets\\shaders\\vert.glsl", 6 }, + .{ "assets\\sphere.mesh", 7 }, });