1
0
chip8-zig/src/test-scene.zig

208 lines
7.3 KiB
Zig

const Self = @This();
const rl = @import("raylib");
const gl = @import("opengl");
const std = @import("std");
const Allocator = std.mem.Allocator;
const ShaderCode = @import("./shader-code.zig");
const Light = @import("./light.zig");
const assert = std.debug.assert;
const max_lights = 1;
const SHADER_LOC_VECTOR_VIEW = @intFromEnum(rl.ShaderLocationIndex.SHADER_LOC_VECTOR_VIEW);
shader: rl.Shader,
bloom_shader: rl.Shader,
frame_buffer: rl.RenderTexture2D,
bloom_texture: rl.Texture2D,
camera: rl.Camera3D,
lights: [max_lights]Light,
rect: OpenglRect,
cube: rl.Model,
const OpenglRect = struct {
vbo: u32,
vao: u32,
fn init() OpenglRect {
var rect: OpenglRect = undefined;
const vertices = [_]f32{
// Coords // texCoords
1.0, -1.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 0.0,
1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 1.0, 0.0,
};
gl.genVertexArrays(1, &rect.vao);
gl.genBuffers(1, &rect.vbo);
gl.bindVertexArray(rect.vao);
gl.bindBuffer(gl.ARRAY_BUFFER, rect.vbo);
gl.bufferData(gl.ARRAY_BUFFER, vertices.len * @sizeOf(f32), @ptrCast(&vertices), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, gl.FALSE, 4 * @sizeOf(f32), @ptrFromInt(0));
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 4 * @sizeOf(f32), @ptrFromInt(2 * @sizeOf(f32)));
return rect;
}
fn draw(self: OpenglRect) void {
gl.bindVertexArray(self.vao);
gl.disable(gl.DEPTH_TEST);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
};
fn loadEmptyTexture(width: i32, height: i32, format: rl.PixelFormat) rl.Texture2D {
var target: rl.Texture2D = undefined;
target.id = rl.rlLoadTexture(null, width, height, format, 1);
target.width = width;
target.height = height;
target.format = format;
target.mipmaps = 1;
return target;
}
pub fn init(allocator: Allocator) !Self {
const main_shader_code = try ShaderCode.init(allocator, max_lights);
defer main_shader_code.deinit();
const shader = rl.LoadShaderFromMemory(main_shader_code.vertex, main_shader_code.fragment);
errdefer rl.UnloadShader(shader);
if (shader.id == rl.rlGetShaderIdDefault()) {
return error.CompileShader;
}
const bloom_shader = rl.LoadShaderFromMemory(@embedFile("shaders/bloom_vs.glsl"), @embedFile("shaders/bloom_fs.glsl"));
errdefer rl.UnloadShader(bloom_shader);
if (bloom_shader.id == rl.rlGetShaderIdDefault()) {
return error.CompileShader;
}
const screen_width = rl.GetScreenWidth();
const screen_height = rl.GetScreenHeight();
const frame_buffer = rl.LoadRenderTexture(screen_width, screen_height);
errdefer rl.UnloadRenderTexture(frame_buffer);
var bloom_texture = loadEmptyTexture(screen_width, screen_height, .PIXELFORMAT_UNCOMPRESSED_R8G8B8);
rl.rlFramebufferAttach(frame_buffer.id, bloom_texture.id, .RL_ATTACHMENT_COLOR_CHANNEL1, .RL_ATTACHMENT_TEXTURE2D, 0);
if (rl.rlFramebufferComplete(frame_buffer.id)) std.debug.print("INFO: Successfully attached bloom texture", .{});
rl.rlActiveDrawBuffers(2);
var lights: [max_lights]Light = undefined;
for (0..max_lights) |i| {
lights[i] = Light.init(shader, i);
}
Light.init(shader, 0).set_point(rl.RED, rl.Vector3{ .x = 1, .y = 1, .z = 0.5 }, 2.0);
shader.locs.?[SHADER_LOC_VECTOR_VIEW] = rl.GetShaderLocation(shader, "viewPos");
const ambientLoc = rl.GetShaderLocation(shader, "ambient");
rl.SetShaderValue(shader, ambientLoc, &[4]f32{ 0.6, 0.6, 1, 1.0 }, .SHADER_UNIFORM_VEC4);
const rect = OpenglRect.init();
return Self{
.shader = shader,
.bloom_shader = bloom_shader,
.rect = rect,
.frame_buffer = frame_buffer,
.bloom_texture = bloom_texture,
.camera = rl.Camera3D{
.position = rl.Vector3.new(0, 0, -10),
.target = rl.Vector3.new(0.0, 0.0, 0.0),
.up = rl.Vector3.new(0.0, 1.0, 0.0),
.fovy = 45.0,
.projection = rl.CameraProjection.CAMERA_PERSPECTIVE,
},
.lights = lights,
.cube = rl.LoadModelFromMesh(rl.GenMeshCube(1.0, 1.0, 1.0))
};
}
pub fn deinit(self: Self) void {
rl.UnloadShader(self.shader);
rl.UnloadRenderTexture(self.frame_buffer);
}
pub fn update(self: *Self, dt: f32) void {
const screen_width = rl.GetScreenWidth();
const screen_height = rl.GetScreenHeight();
if (self.frame_buffer.texture.width != screen_width or self.frame_buffer.texture.height != screen_height) {
rl.UnloadRenderTexture(self.frame_buffer);
rl.UnloadTexture(self.bloom_texture);
self.frame_buffer = rl.LoadRenderTexture(screen_width, screen_height);
self.bloom_texture = loadEmptyTexture(screen_width, screen_height, .PIXELFORMAT_UNCOMPRESSED_R8G8B8A8);
rl.rlFramebufferAttach(self.frame_buffer.id, self.bloom_texture.id, .RL_ATTACHMENT_COLOR_CHANNEL1, .RL_ATTACHMENT_TEXTURE2D, 0);
if (rl.rlFramebufferComplete(self.frame_buffer.id)) std.debug.print("INFO: Successfully attached bloom texture", .{});
}
rl.UpdateCamera(&self.camera, .CAMERA_THIRD_PERSON);
const cameraPos = [3]f32{ self.camera.position.x, self.camera.position.y, self.camera.position.z };
rl.SetShaderValue(self.shader, self.shader.locs.?[SHADER_LOC_VECTOR_VIEW], @ptrCast(&cameraPos), .SHADER_UNIFORM_VEC3);
_ = dt;
}
pub fn draw(self: *Self) void {
rl.BeginTextureMode(self.frame_buffer);
{
rl.rlActiveDrawBuffers(2);
const bg_color = [_]f32{ 33.0 / 255.0, 33.0 / 255.0, 33.0 / 255.0, 1.0 };
gl.clearBufferfv(gl.COLOR, 0, &bg_color);
const transparent_color = [_]f32{ 0.0, 0.0, 0.0, 0.0 };
gl.clearBufferfv(gl.COLOR, 1, &transparent_color);
gl.clear(gl.DEPTH_BUFFER_BIT);
rl.BeginMode3D(self.camera);
rl.BeginShaderMode(self.shader);
self.cube.materials.?[0].shader = self.shader;
rl.DrawModel(self.cube, rl.Vector3Zero(), 1.0, rl.WHITE);
rl.EndShaderMode();
rl.EndMode3D();
}
rl.EndTextureMode();
const screen_width = rl.GetScreenWidth();
const screen_height = rl.GetScreenHeight();
// const screen_rect = rl.Rectangle{ .x = 0, .y = 0, .width = @floatFromInt(screen_width), .height = @floatFromInt(screen_height) };
rl.BeginDrawing();
gl.useProgram(self.bloom_shader.id);
rl.rlDisableDepthTest();
const renderSize = [_]f32{ @floatFromInt(screen_width), @floatFromInt(screen_height) };
rl.rlSetUniform(rl.rlGetLocationUniform(self.bloom_shader.id, "renderSize"), &renderSize, @intFromEnum(rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2), 1);
rl.rlSetUniformSampler(rl.rlGetLocationUniform(self.bloom_shader.id, "screenTexture"), self.frame_buffer.texture.id);
rl.rlSetUniformSampler(rl.rlGetLocationUniform(self.bloom_shader.id, "bloomTexture"), self.bloom_texture.id);
gl.bindVertexArray(self.rect.vao);
rl.rlActiveTextureSlot(1);
rl.rlEnableTexture(self.frame_buffer.texture.id);
rl.rlActiveTextureSlot(2);
rl.rlEnableTexture(self.bloom_texture.id);
gl.drawArrays(gl.TRIANGLES, 0, 6);
rl.EndDrawing();
}