diff options
Diffstat (limited to 'src/sfml/graphics/texture.zig')
| -rw-r--r-- | src/sfml/graphics/texture.zig | 148 |
1 files changed, 89 insertions, 59 deletions
diff --git a/src/sfml/graphics/texture.zig b/src/sfml/graphics/texture.zig index 317738a..55de1ae 100644 --- a/src/sfml/graphics/texture.zig +++ b/src/sfml/graphics/texture.zig @@ -9,84 +9,89 @@ const sf = struct { const std = @import("std"); const assert = std.debug.assert; -const TextureType = enum { ptr, const_ptr }; +const TextureType = enum { _ptr, _const_ptr }; pub const Texture = union(TextureType) { - const Self = @This(); - // Constructor/destructor /// Creates a texture from nothing - pub fn create(size: sf.Vector2u) !Self { - var tex = sf.c.sfTexture_create(@intCast(c_uint, size.x), @intCast(c_uint, size.y)); + pub fn create(size: sf.Vector2u) !Texture { + const tex = sf.c.sfTexture_create(@intCast(c_uint, size.x), @intCast(c_uint, size.y)); if (tex == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Loads a texture from a file - pub fn createFromFile(path: [:0]const u8) !Self { - var tex = sf.c.sfTexture_createFromFile(path, null); + pub fn createFromFile(path: [:0]const u8) !Texture { + const tex = sf.c.sfTexture_createFromFile(path, null); if (tex == null) return sf.Error.resourceLoadingError; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Creates an texture from an image - pub fn createFromImage(image: sf.Image, area: ?sf.IntRect) !Self { - var tex = if (area) |a| - sf.c.sfTexture_createFromImage(image.ptr, &a.toCSFML()) + pub fn createFromImage(image: sf.Image, area: ?sf.IntRect) !Texture { + const tex = if (area) |a| + sf.c.sfTexture_createFromImage(image._ptr, &a._toCSFML()) else - sf.c.sfTexture_createFromImage(image.ptr, null); + sf.c.sfTexture_createFromImage(image._ptr, null); if (tex == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = tex.? }; + return Texture{ ._ptr = tex.? }; } /// Destroys a texture /// Be careful, you can only destroy non const textures - pub fn destroy(self: Self) void { + pub fn destroy(self: *Texture) void { // TODO : is it possible to detect that comptime? // Should this panic? - if (self == .const_ptr) + if (self.* == ._const_ptr) @panic("Can't destroy a const texture pointer"); - sf.c.sfTexture_destroy(self.ptr); + sf.c.sfTexture_destroy(self._ptr); } // Getters/Setters /// Gets a const pointer to this texture - pub fn get(self: Self) *const sf.c.sfTexture { + /// For inner workings + pub fn _get(self: Texture) *const sf.c.sfTexture { return switch (self) { - .ptr => self.ptr, - .const_ptr => self.const_ptr, + ._ptr => self._ptr, + ._const_ptr => self._const_ptr, }; } + /// Clones this texture (the clone won't be const) - pub fn copy(self: Self) !Self { - var cpy = sf.c.sfTexture_copy(self.get()); + pub fn copy(self: Texture) !Texture { + const cpy = sf.c.sfTexture_copy(self._get()); if (cpy == null) return sf.Error.nullptrUnknownReason; - return Self{ .ptr = cpy.? }; + return Texture{ ._ptr = cpy.? }; } + /// Copy this texture to an image in ram + pub fn copyToImage(self: Texture) sf.Image { + return .{ ._ptr = sf.c.sfTexture_copyToImage(self._get()).? }; + } + /// Makes this texture constant (I don't know why you would do that) - pub fn makeConst(self: *Self) void { - self.* = Self{ .const_ptr = self.get() }; + pub fn makeConst(self: *Texture) void { + self.* = Texture{ ._const_ptr = self._get() }; } /// Gets the size of this image - pub fn getSize(self: Self) sf.Vector2u { - const size = sf.c.sfTexture_getSize(self.get()); + pub fn getSize(self: Texture) sf.Vector2u { + const size = sf.c.sfTexture_getSize(self._get()); return sf.Vector2u{ .x = size.x, .y = size.y }; } /// Gets the pixel count of this image - pub fn getPixelCount(self: Self) usize { - var dim = self.getSize(); + pub fn getPixelCount(self: Texture) usize { + const dim = self.getSize(); return dim.x * dim.y; } /// Updates the pixels of the image from an array of pixels (colors) - pub fn updateFromPixels(self: Self, pixels: []const sf.Color, zone: ?sf.Rect(c_uint)) !void { - if (self == .const_ptr) + pub fn updateFromPixels(self: *Texture, pixels: []const sf.Color, zone: ?sf.Rect(c_uint)) !void { + if (self.* == ._const_ptr) @panic("Can't set pixels on a const texture"); if (self.isSrgb()) @panic("Updating an srgb from a pixel array isn't implemented"); @@ -114,78 +119,94 @@ pub const Texture = union(TextureType) { if (pixels.len < real_zone.width * real_zone.height) return sf.Error.notEnoughData; - sf.c.sfTexture_updateFromPixels(self.ptr, @ptrCast([*]const u8, pixels.ptr), real_zone.width, real_zone.height, real_zone.left, real_zone.top); + sf.c.sfTexture_updateFromPixels(self._ptr, @ptrCast([*]const u8, pixels.ptr), real_zone.width, real_zone.height, real_zone.left, real_zone.top); } /// Updates the pixels of the image from an other texture - pub fn updateFromTexture(self: Self, other: Texture, copy_pos: ?sf.Vector2u) void { + pub fn updateFromTexture(self: *Texture, other: Texture, copy_pos: ?sf.Vector2u) void { + if (self == ._const_ptr) + @panic("Can't set pixels on a const texture"); + var pos = if (copy_pos) |a| a else sf.Vector2u{ .x = 0, .y = 0 }; var max = other.getSize().add(pos); var size = self.getSize(); - assert(max.x < size.x and max.y < size.y); + assert(max.x <= size.x and max.y <= size.y); - sf.c.sfTexture_updateFromTexture(self.ptr, other.get(), pos.x, pos.y); + sf.c.sfTexture_updateFromTexture(self._ptr, other._get(), pos.x, pos.y); } /// Updates the pixels of the image from an image - pub fn updateFromImage(self: Self, image: sf.Image, copy_pos: ?sf.Vector2u) void { + pub fn updateFromImage(self: *Texture, image: sf.Image, copy_pos: ?sf.Vector2u) void { + if (self.* == ._const_ptr) + @panic("Can't set pixels on a const texture"); + var pos = if (copy_pos) |a| a else sf.Vector2u{ .x = 0, .y = 0 }; var max = image.getSize().add(pos); var size = self.getSize(); - assert(max.x < size.x and max.y < size.y); + assert(max.x <= size.x and max.y <= size.y); - sf.c.sfTexture_updateFromImage(self.ptr, image.ptr, pos.x, pos.y); + sf.c.sfTexture_updateFromImage(self._ptr, image._ptr, pos.x, pos.y); } /// Tells whether or not this texture is to be smoothed - pub fn isSmooth(self: Self) bool { - return sf.c.sfTexture_isSmooth(self.ptr) != 0; + pub fn isSmooth(self: Texture) bool { + return sf.c.sfTexture_isSmooth(self._ptr) != 0; } /// Enables or disables texture smoothing - pub fn setSmooth(self: Self, smooth: bool) void { - if (self == .const_ptr) + pub fn setSmooth(self: *Texture, smooth: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setSmooth(self.ptr, if (smooth) 1 else 0); + sf.c.sfTexture_setSmooth(self._ptr, @boolToInt(smooth)); } /// Tells whether or not this texture should repeat when rendering outside its bounds - pub fn isRepeated(self: Self) bool { - return sf.c.sfTexture_isRepeated(self.ptr) != 0; + pub fn isRepeated(self: Texture) bool { + return sf.c.sfTexture_isRepeated(self._ptr) != 0; } /// Enables or disables texture repeating - pub fn setRepeated(self: Self, repeated: bool) void { - if (self == .const_ptr) + pub fn setRepeated(self: *Texture, repeated: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setRepeated(self.ptr, if (repeated) 1 else 0); + sf.c.sfTexture_setRepeated(self._ptr, @boolToInt(repeated)); } /// Tells whether or not this texture has colors in the SRGB format /// SRGB functions arent implemented yet - pub fn isSrgb(self: Self) bool { - return sf.c.sfTexture_isSrgb(self.ptr) != 0; + pub fn isSrgb(self: Texture) bool { + return sf.c.sfTexture_isSrgb(self._ptr) != 0; } /// Enables or disables SRGB - pub fn setSrgb(self: Self, srgb: bool) void { - if (self == .const_ptr) + pub fn setSrgb(self: *Texture, srgb: bool) void { + if (self.* == ._const_ptr) @panic("Can't set properties on a const texture"); - sf.c.sfTexture_setSrgb(self.ptr, if (srgb) 1 else 0); + sf.c.sfTexture_setSrgb(self._ptr, @boolToInt(srgb)); } /// Swaps this texture's contents with an other texture - pub fn swap(self: Self, other: Texture) void { - if (self == .const_ptr or other == .const_ptr) + pub fn swap(self: *Texture, other: *Texture) void { + if (self.* == ._const_ptr or other.* == ._const_ptr) @panic("Texture swapping must be done between two non const textures"); - sf.c.sfTexture_swap(self.ptr, other.ptr); + sf.c.sfTexture_swap(self._ptr, other._ptr); + } + + // Others + + /// Generates a mipmap for the current texture data, returns true if the operation succeeded + pub fn generateMipmap(self: *Texture) bool { + if (self == ._const_ptr) + @panic("Can't act on a const texture"); + + return sf.c.sfTexture_generateMipmap(self._ptr) != 0; } /// Pointer to the csfml texture - ptr: *sf.c.sfTexture, + _ptr: *sf.c.sfTexture, /// Const pointer to the csfml texture - const_ptr: *const sf.c.sfTexture + _const_ptr: *const sf.c.sfTexture }; test "texture: sane getters and setters" { @@ -212,12 +233,21 @@ test "texture: sane getters and setters" { c.* = sf.graphics.Color.fromHSVA(@intToFloat(f32, i) / 144 * 360, 100, 100, 1); } + pixel_data[0] = sf.Color.Green; + try tex.updateFromPixels(pixel_data, null); try tst.expect(!tex.isSrgb()); try tst.expect(tex.isSmooth()); try tst.expect(tex.isRepeated()); + var img = tex.copyToImage(); + defer img.destroy(); + + try tst.expectEqual(sf.Color.Green, img.getPixel(.{ .x = 0, .y = 0 })); + + tex.updateFromImage(img, null); + var t = tex; t.makeConst(); @@ -228,7 +258,7 @@ test "texture: sane getters and setters" { var tex2 = try Texture.create(.{ .x = 100, .y = 100 }); defer tex2.destroy(); - copy.swap(tex2); + copy.swap(&tex2); try tst.expectEqual(@as(usize, 100 * 100), copy.getPixelCount()); try tst.expectEqual(@as(usize, 120), tex2.getPixelCount()); |
