diff options
Diffstat (limited to 'src/Textures.zig')
-rw-r--r-- | src/Textures.zig | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/Textures.zig b/src/Textures.zig new file mode 100644 index 0000000..068db80 --- /dev/null +++ b/src/Textures.zig @@ -0,0 +1,85 @@ +// Texture store +// Copyright (C) 2002 David Rosen +// Copyright (C) 2021-2023 Nguyễn Gia Phong +// +// This file is part of Black Shades. +// +// Black Shades is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Black Shades is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Black Shades. If not, see <https://www.gnu.org/licenses/>. + +const allocator = std.heap.c_allocator; +const c = @import("cimport.zig"); +const cwd = std.fs.cwd; +const data_dir = misc.data_dir; +const formatIntBuf = std.fmt.formatIntBuf; +const misc = @import("misc.zig"); +const qoi = @import("qoi"); +const readFile = misc.readFile; +const sep = std.fs.path.sep; +const span = std.mem.span; +const std = @import("std"); + +/// Load QOI file into an OpenGL buffer bound to the given texture. +fn load(texture: u32, path: [*:0]const u8) !void { + const file = try readFile(cwd(), data_dir ++ "textures{c}{s}", .{ + sep, path, + }); + defer allocator.free(file); + + var image = try qoi.decodeBuffer(allocator, file); + defer image.deinit(allocator); + const data: [*c]const u8 = @ptrCast(image.pixels.ptr); + + c.glBindTexture(c.GL_TEXTURE_2D, texture); + defer c.glBindTexture(c.GL_TEXTURE_2D, 0); + c.glTexEnvi(c.GL_TEXTURE_ENV, c.GL_TEXTURE_ENV_MODE, c.GL_MODULATE); + c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR); + c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR); + c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_GENERATE_MIPMAP, c.GL_TRUE); + + const width: i32 = @intCast(image.width); + const height: i32 = @intCast(image.height); + c.glPixelStorei(c.GL_UNPACK_ALIGNMENT, 1); + c.glTexImage2D(c.GL_TEXTURE_2D, 0, 4, width, height, + 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, data); +} + +export fn loadTexture(path: [*:0]const u8) u32 { + var texture: u32 = undefined; + c.glGenTextures(1, &texture); + load(texture, path) catch unreachable; + return texture; +} + +const Textures = @This(); +const size = @sizeOf(Textures) / @sizeOf(u32); +bullet_hole: u32, +crater: u32, +blood_pool: [11]u32, + +pub fn init() !Textures { + var self: Textures = undefined; + c.glGenTextures(size, @ptrCast(&self)); + try load(self.bullet_hole, "bullet-hole.qoi"); + try load(self.crater, "black.qoi"); + for (0..11) |i| { + var buf: [2]u8 = undefined; + _ = formatIntBuf(&buf, i, 10, .lower, .{ .width = 2, .fill = '0' }); + try load(self.blood_pool[i], "blood/" ++ buf ++ ".qoi"); + } + return self; +} + +pub fn deinit(self: Textures) void { + c.glDeleteTextures(size, @ptrCast(&self)); +} |