diff options
| author | tslil clingman <> | 2021-10-27 15:37:28 -0400 |
|---|---|---|
| committer | tslil clingman <> | 2021-10-27 15:37:28 -0400 |
| commit | 48dee0817f5fe8c09a085f0150e0c6b4a699ab7c (patch) | |
| tree | d6ab0a54f2260cb73c79e00ca1489c034f555f09 /src/sfml/graphics/RenderTexture.zig | |
| parent | 486935299e4b7e097754611d9f8dd40003351ae4 (diff) | |
Update SFML wrapper
Diffstat (limited to 'src/sfml/graphics/RenderTexture.zig')
| -rw-r--r-- | src/sfml/graphics/RenderTexture.zig | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/sfml/graphics/RenderTexture.zig b/src/sfml/graphics/RenderTexture.zig new file mode 100644 index 0000000..70b93ba --- /dev/null +++ b/src/sfml/graphics/RenderTexture.zig @@ -0,0 +1,177 @@ +//! Target for off-screen 2D rendering into a texture. + +const sf = struct { + pub usingnamespace @import("../sfml.zig"); + pub usingnamespace sf.system; + pub usingnamespace sf.graphics; +}; + +const RenderTexture = @This(); + +// Constructor/destructor + +/// Inits a render texture with a size (use createWithDepthBuffer if you want a depth buffer) +pub fn create(size: sf.Vector2u) !RenderTexture { + var rtex = sf.c.sfRenderTexture_create(size.x, size.y, 0); //0 means no depth buffer + + if (rtex) |t| { + return RenderTexture{ ._ptr = t }; + } else return sf.Error.nullptrUnknownReason; +} +/// Inits a render texture with a size, it will have a depth buffer +pub fn createWithDepthBuffer(size: sf.Vector2u) !RenderTexture { + var rtex = sf.c.sfRenderTexture_create(size.x, size.y, 1); + + if (rtex) |t| { + return .{ ._ptr = t }; + } else return sf.Error.nullptrUnknownReason; +} + +/// Destroys this render texture +pub fn destroy(self: *RenderTexture) void { + sf.c.sfRenderTexture_destroy(self._ptr); +} + +// Drawing functions + +/// Clears the drawing target with a color +pub fn clear(self: *RenderTexture, color: sf.Color) void { + sf.c.sfRenderTexture_clear(self._ptr, color._toCSFML()); +} + +/// Updates the texture with what has been drawn on the render area +pub fn display(self: *RenderTexture) void { + sf.c.sfRenderTexture_display(self._ptr); +} + +/// Draw something on the texture (won't be visible until display is called) +/// Object must have a sfDraw function (look at CircleShape for reference) +/// You can pass a render state or null for default +pub fn draw(self: *RenderTexture, to_draw: anytype, states: ?sf.RenderStates) void { + const T = @TypeOf(to_draw); + if (comptime @import("std").meta.trait.hasFn("sfDraw")(T)) { + // Inline call of object's draw function + if (states) |s| { + var cstates = s._toCSFML(); + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, &cstates }); + } else + @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self.*, null }); + // to_draw.sfDraw(self, states); + } else @compileError("You must provide a drawable object (struct with \"sfDraw\" method)."); +} + +/// Gets a const reference to the target texture (the reference doesn't change) +pub fn getTexture(self: RenderTexture) sf.Texture { + const tex = sf.c.sfRenderTexture_getTexture(self._ptr); + return sf.Texture{ ._const_ptr = tex.? }; +} + +// Texture related stuff + +/// Generates a mipmap for the current texture data, returns true if the operation succeeded +pub fn generateMipmap(self: *RenderTexture) bool { + return sf.c.sfRenderTexture_generateMipmap(self._ptr) != 0; +} + +/// Tells whether or not the texture is to be smoothed +pub fn isSmooth(self: RenderTexture) bool { + return sf.c.sfRenderTexture_isSmooth(self._ptr) != 0; +} +/// Enables or disables texture smoothing +pub fn setSmooth(self: *RenderTexture, smooth: bool) void { + sf.c.sfRenderTexture_setSmooth(self._ptr, @boolToInt(smooth)); +} + +/// Tells whether or not the texture should repeat when rendering outside its bounds +pub fn isRepeated(self: RenderTexture) bool { + return sf.c.sfRenderTexture_isRepeated(self._ptr) != 0; +} +/// Enables or disables texture repeating +pub fn setRepeated(self: *RenderTexture, repeated: bool) void { + sf.c.sfRenderTexture_setRepeated(self._ptr, @boolToInt(repeated)); +} + +/// Gets the size of this window +pub fn getSize(self: RenderTexture) sf.Vector2u { + return sf.Vector2u._fromCSFML(sf.c.sfRenderTexture_getSize(self._ptr)); +} + +// Target related stuff + +/// Gets the current view of the target +/// Unlike in SFML, you don't get a const pointer but a copy +pub fn getView(self: RenderTexture) sf.View { + return sf.View._fromCSFML(sf.c.sfRenderTexture_getView(self._ptr).?); +} +/// Gets the default view of this target +/// Unlike in SFML, you don't get a const pointer but a copy +pub fn getDefaultView(self: RenderTexture) sf.View { + return sf.View._fromCSFML(sf.c.sfRenderTexture_getDefaultView(self._ptr).?); +} +/// Sets the view of this target +pub fn setView(self: *RenderTexture, view: sf.View) void { + var cview = view._toCSFML(); + defer sf.c.sfView_destroy(cview); + sf.c.sfRenderTexture_setView(self._ptr, cview); +} +/// Gets the viewport of this target +pub fn getViewport(self: RenderTexture, view: sf.View) sf.IntRect { + return sf.IntRect._fromCSFML(sf.c.sfRenderTexture_getViewPort(self._ptr, view._ptr)); +} + +/// Convert a point from target coordinates to world coordinates, using the current view (or the specified view) +pub fn mapPixelToCoords(self: RenderTexture, pixel: sf.Vector2i, view: ?sf.View) sf.Vector2f { + if (view) |v| { + var cview = v._toCSFML(); + defer sf.c.sfView_destroy(cview); + return sf.Vector2f._fromCSFML(sf.c.sfRenderTexture_mapPixelToCoords(self._ptr, pixel._toCSFML(), cview)); + } else return sf.Vector2f._fromCSFML(sf.c.sfRenderTexture_mapPixelToCoords(self._ptr, pixel._toCSFML(), null)); +} +/// Convert a point from world coordinates to target coordinates, using the current view (or the specified view) +pub fn mapCoordsToPixel(self: RenderTexture, coords: sf.Vector2f, view: ?sf.View) sf.Vector2i { + if (view) |v| { + var cview = v._toCSFML(); + defer sf.c.sfView_destroy(cview); + return sf.Vector2i._fromCSFML(sf.c.sfRenderTexture_mapCoordsToPixel(self._ptr, coords._toCSFML(), cview)); + } else return sf.Vector2i._fromCSFML(sf.c.sfRenderTexture_mapCoordsToPixel(self._ptr, coords._toCSFML(), null)); +} + +/// Pointer to the csfml structure +_ptr: *sf.c.sfRenderTexture, + +test "rendertexture tests" { + const tst = @import("std").testing; + + var rentex = try RenderTexture.create(.{ .x = 10, .y = 10 }); + defer rentex.destroy(); + + rentex.setRepeated(true); + rentex.setSmooth(true); + + rentex.clear(sf.Color.Red); + { + var rect = try sf.RectangleShape.create(.{ .x = 5, .y = 5 }); + defer rect.destroy(); + + rect.setFillColor(sf.Color.Blue); + + rentex.draw(rect, null); + } + rentex.display(); + + _ = rentex.generateMipmap(); + + try tst.expect(rentex.isRepeated()); + try tst.expect(rentex.isSmooth()); + + const tex = rentex.getTexture(); + + try tst.expectEqual(sf.Vector2u{ .x = 10, .y = 10 }, tex.getSize()); + try tst.expectEqual(sf.Vector2u{ .x = 10, .y = 10 }, rentex.getSize()); + + var img = tex.copyToImage(); + defer img.destroy(); + + try tst.expectEqual(sf.Color.Blue, img.getPixel(.{ .x = 1, .y = 1 })); + try tst.expectEqual(sf.Color.Red, img.getPixel(.{ .x = 6, .y = 3 })); +} |
