aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.zig11
-rw-r--r--src/render.zig6
-rw-r--r--src/sfml/audio/Music.zig56
-rw-r--r--src/sfml/audio/Sound.zig52
-rw-r--r--src/sfml/audio/SoundBuffer.zig20
-rw-r--r--src/sfml/graphics/BlendMode.zig92
-rw-r--r--src/sfml/graphics/CircleShape.zig97
-rw-r--r--src/sfml/graphics/Font.zig34
-rw-r--r--src/sfml/graphics/Image.zig24
-rw-r--r--src/sfml/graphics/RectangleShape.zig103
-rw-r--r--src/sfml/graphics/RenderStates.zig20
-rw-r--r--src/sfml/graphics/RenderTexture.zig177
-rw-r--r--src/sfml/graphics/RenderWindow.zig124
-rw-r--r--src/sfml/graphics/Shader.zig96
-rw-r--r--src/sfml/graphics/Sprite.zig78
-rw-r--r--src/sfml/graphics/Text.zig106
-rw-r--r--src/sfml/graphics/VertexArray.zig16
-rw-r--r--src/sfml/graphics/View.zig22
-rw-r--r--src/sfml/graphics/color.zig31
-rw-r--r--src/sfml/graphics/glsl.zig16
-rw-r--r--src/sfml/graphics/rect.zig16
-rw-r--r--src/sfml/graphics/texture.zig148
-rw-r--r--src/sfml/sfml.zig41
-rw-r--r--src/sfml/system/Clock.zig14
-rw-r--r--src/sfml/system/Time.zig18
-rw-r--r--src/sfml/system/vector.zig89
-rw-r--r--src/sfml/window/context_settings.zig28
-rw-r--r--src/sfml/window/event.zig2
-rw-r--r--src/sfml/window/mouse.zig8
29 files changed, 1093 insertions, 452 deletions
diff --git a/src/main.zig b/src/main.zig
index 6a10921..30add69 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -98,14 +98,13 @@ pub fn main() !void {
// Initialise SFML
//--------------------------------------------------------------------------
- var window = try sf.RenderWindow.create(.{ .x = constants.ScreenWidth, .y = constants.ScreenHeight }, 32, "zirc", sf.window.Style.none);
+ var window = try sf.RenderWindow.create(.{ .x = constants.ScreenWidth, .y = constants.ScreenHeight }, 32, "zirc", sf.window.Style.none, null);
defer window.destroy();
window.setFramerateLimit(40);
- // TODO: implement this in the SFML wrapper and make a PR
- sf.c.sfRenderWindow_setMouseCursorGrabbed(window.ptr, 1);
- sf.c.sfRenderWindow_setMouseCursorVisible(window.ptr, 0);
+ window.setMouseCursorGrabbed(true);
+ window.setMouseCursorVisible(false);
// Load the background skybox, really `skycylinder', and assign it to a
// sprite -- it's set to repeating so that it goes on forever. We need to
@@ -207,11 +206,11 @@ pub fn main() !void {
try renderer.renderWorld(
plyr,
- window,
+ &window,
objects_image,
walls_image,
surfaces_image,
- rendered_surfaces_texture,
+ &rendered_surfaces_texture,
rendered_surfaces_sprite,
map,
);
diff --git a/src/render.zig b/src/render.zig
index 49595dd..4e9cf4b 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -47,11 +47,11 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
pub fn renderWorld(
self: *@This(),
plyr: player.Player,
- window: RenderWindow,
+ window: *RenderWindow,
objects_image: Image,
walls_image: Image,
surfaces_image: Image,
- rendered_surfaces_texture: Texture,
+ rendered_surfaces_texture: *Texture,
rendered_surfaces_sprite: Sprite,
map: level.Map,
) !void {
@@ -69,7 +69,7 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// use the z_buffer to render sprites
self.renderObjects(plyr, objects_image, map, &pixels);
- try rendered_surfaces_texture.updateFromPixels(&pixels, null);
+ try rendered_surfaces_texture.updateFromPixels(pixels[0..], null);
window.draw(rendered_surfaces_sprite, null);
}
diff --git a/src/sfml/audio/Music.zig b/src/sfml/audio/Music.zig
index b02b620..d55a718 100644
--- a/src/sfml/audio/Music.zig
+++ b/src/sfml/audio/Music.zig
@@ -11,92 +11,92 @@ pub fn createFromFile(path: [:0]const u8) !Music {
var music = sf.c.sfMusic_createFromFile(path);
if (music == null)
return sf.Error.resourceLoadingError;
- return Music{ .ptr = music.? };
+ return Music{ ._ptr = music.? };
}
pub const initFromMemory = @compileError("Function is not implemented yet.");
pub const initFromStream = @compileError("Function is not implemented yet.");
/// Destroys this music object
-pub fn destroy(self: Music) void {
- sf.c.sfMusic_destroy(self.ptr);
+pub fn destroy(self: *Music) void {
+ sf.c.sfMusic_destroy(self._ptr);
}
// Music control functions
/// Plays the music
-pub fn play(self: Music) void {
- sf.c.sfMusic_play(self.ptr);
+pub fn play(self: *Music) void {
+ sf.c.sfMusic_play(self._ptr);
}
/// Pauses the music
-pub fn pause(self: Music) void {
- sf.c.sfMusic_pause(self.ptr);
+pub fn pause(self: *Music) void {
+ sf.c.sfMusic_pause(self._ptr);
}
/// Stops the music and resets the player position
-pub fn stop(self: Music) void {
- sf.c.sfMusic_stop(self.ptr);
+pub fn stop(self: *Music) void {
+ sf.c.sfMusic_stop(self._ptr);
}
// Getters / Setters
/// Gets the total duration of the music
pub fn getDuration(self: Music) sf.Time {
- return sf.Time.fromCSFML(sf.c.sfMusic_getDuration(self.ptr));
+ return sf.Time._fromCSFML(sf.c.sfMusic_getDuration(self._ptr));
}
/// Gets the current stream position of the music
pub fn getPlayingOffset(self: Music) sf.Time {
- return sf.Time.fromCSFML(sf.c.sfMusic_getPlayingOffset(self.ptr));
+ return sf.Time._fromCSFML(sf.c.sfMusic_getPlayingOffset(self._ptr));
}
/// Sets the current stream position of the music
-pub fn setPlayingOffset(self: Music, offset: sf.Time) void {
- sf.c.sfMusic_setPlayingOffset(self.ptr, offset.toCSFML());
+pub fn setPlayingOffset(self: *Music, offset: sf.Time) void {
+ sf.c.sfMusic_setPlayingOffset(self._ptr, offset._toCSFML());
}
/// Gets the loop points of the music
pub fn getLoopPoints(self: Music) sf.TimeSpan {
- return sf.TimeSpan.fromCSFML(sf.c.sfMusic_getLoopPoints(self.ptr));
+ return sf.TimeSpan._fromCSFML(sf.c.sfMusic_getLoopPoints(self._ptr));
}
/// Gets the loop points of the music
-pub fn setLoopPoints(self: Music, span: sf.TimeSpan) void {
- sf.c.sfMusic_setLoopPoints(self.ptr, span.toCSFML());
+pub fn setLoopPoints(self: *Music, span: sf.TimeSpan) void {
+ sf.c.sfMusic_setLoopPoints(self._ptr, span._toCSFML());
}
/// Tells whether or not this stream is in loop mode
pub fn getLoop(self: Music) bool {
- return sf.c.sfMusic_getLoop(self.ptr) != 0;
+ return sf.c.sfMusic_getLoop(self._ptr) != 0;
}
/// Enable or disable auto loop
-pub fn setLoop(self: Music, loop: bool) void {
- sf.c.sfMusic_setLoop(self.ptr, if (loop) 1 else 0);
+pub fn setLoop(self: *Music, loop: bool) void {
+ sf.c.sfMusic_setLoop(self._ptr, @boolToInt(loop));
}
/// Sets the pitch of the music
pub fn getPitch(self: Music) f32 {
- return sf.c.sfMusic_getPitch(self.ptr);
+ return sf.c.sfMusic_getPitch(self._ptr);
}
/// Gets the pitch of the music
-pub fn setPitch(self: Music, pitch: f32) void {
- sf.c.sfMusic_setPitch(self.ptr, pitch);
+pub fn setPitch(self: *Music, pitch: f32) void {
+ sf.c.sfMusic_setPitch(self._ptr, pitch);
}
/// Sets the volume of the music
pub fn getVolume(self: Music) f32 {
- return sf.c.sfMusic_getVolume(self.ptr);
+ return sf.c.sfMusic_getVolume(self._ptr);
}
/// Gets the volume of the music
-pub fn setVolume(self: Music, volume: f32) void {
- sf.c.sfMusic_setVolume(self.ptr, volume);
+pub fn setVolume(self: *Music, volume: f32) void {
+ sf.c.sfMusic_setVolume(self._ptr, volume);
}
/// Gets the sample rate of this music
pub fn getSampleRate(self: Music) usize {
- return @intCast(usize, sf.c.sfMusic_getSampleRate(self.ptr));
+ return @intCast(usize, sf.c.sfMusic_getSampleRate(self._ptr));
}
/// Gets the channel count of the music
pub fn getChannelCount(self: Music) usize {
- return @intCast(usize, sf.c.sfMusic_getChannelCount(self.ptr));
+ return @intCast(usize, sf.c.sfMusic_getChannelCount(self._ptr));
}
pub const getStatus = @compileError("Function is not implemented yet.");
@@ -108,4 +108,4 @@ pub const getMinDistance = @compileError("Function is not implemented yet.");
pub const getAttenuation = @compileError("Function is not implemented yet.");
/// Pointer to the csfml music
-ptr: *sf.c.sfMusic,
+_ptr: *sf.c.sfMusic,
diff --git a/src/sfml/audio/Sound.zig b/src/sfml/audio/Sound.zig
index 073aa5f..92acb46 100644
--- a/src/sfml/audio/Sound.zig
+++ b/src/sfml/audio/Sound.zig
@@ -14,7 +14,7 @@ pub fn create() !Sound {
var sound = sf.c.sfSound_create();
if (sound == null)
return sf.Error.nullptrUnknownReason;
- return Sound{ .ptr = sound.? };
+ return Sound{ ._ptr = sound.? };
}
/// Inits a sound with a SoundBuffer object
@@ -25,74 +25,74 @@ pub fn createFromBuffer(buffer: sf.SoundBuffer) !Sound {
}
/// Destroys this sound object
-pub fn destroy(self: Sound) void {
- sf.c.sfSound_destroy(self.ptr);
+pub fn destroy(self: *Sound) void {
+ sf.c.sfSound_destroy(self._ptr);
}
// Sound control functions
/// Plays the sound
-pub fn play(self: Sound) void {
- sf.c.sfSound_play(self.ptr);
+pub fn play(self: *Sound) void {
+ sf.c.sfSound_play(self._ptr);
}
/// Pauses the sound
-pub fn pause(self: Sound) void {
- sf.c.sfSound_pause(self.ptr);
+pub fn pause(self: *Sound) void {
+ sf.c.sfSound_pause(self._ptr);
}
/// Stops the sound and resets the player position
-pub fn stop(self: Sound) void {
- sf.c.sfSound_stop(self.ptr);
+pub fn stop(self: *Sound) void {
+ sf.c.sfSound_stop(self._ptr);
}
// Getters / Setters
/// Gets the buffer this sound is attached to
pub fn getBuffer(self: Sound) ?sf.SoundBuffer {
- var buf = sf.c.sfSound_getBuffer(self.ptr);
+ var buf = sf.c.sfSound_getBuffer(self._ptr);
if (buf) |buffer| {
- return .{ .ptr = buffer };
+ return .{ ._ptr = buffer };
} else return null;
}
/// Sets the buffer this sound will play
-pub fn setBuffer(self: Sound, buffer: sf.SoundBuffer) void {
- sf.c.sfSound_setBuffer(self.ptr, buffer.ptr);
+pub fn setBuffer(self: *Sound, buffer: sf.SoundBuffer) void {
+ sf.c.sfSound_setBuffer(self._ptr, buffer._ptr);
}
/// Gets the current playing offset of the sound
pub fn getPlayingOffset(self: Sound) sf.Time {
- return sf.Time.fromCSFML(sf.c.sfSound_getPlayingOffset(self.ptr));
+ return sf.Time._fromCSFML(sf.c.sfSound_getPlayingOffset(self._ptr));
}
/// Sets the current playing offset of the sound
-pub fn setPlayingOffset(self: Sound, offset: sf.Time) void {
- sf.c.sfSound_setPlayingOffset(self.ptr, offset.toCSFML());
+pub fn setPlayingOffset(self: *Sound, offset: sf.Time) void {
+ sf.c.sfSound_setPlayingOffset(self._ptr, offset._toCSFML());
}
/// Tells whether or not this sound is in loop mode
pub fn getLoop(self: Sound) bool {
- return sf.c.sfSound_getLoop(self.ptr) != 0;
+ return sf.c.sfSound_getLoop(self._ptr) != 0;
}
/// Enable or disable auto loop
-pub fn setLoop(self: Sound, loop: bool) void {
- sf.c.sfSound_setLoop(self.ptr, if (loop) 1 else 0);
+pub fn setLoop(self: *Sound, loop: bool) void {
+ sf.c.sfSound_setLoop(self._ptr, @boolToInt(loop));
}
/// Sets the pitch of the sound
pub fn getPitch(self: Sound) f32 {
- return sf.c.sfSound_getPitch(self.ptr);
+ return sf.c.sfSound_getPitch(self._ptr);
}
/// Gets the pitch of the sound
-pub fn setPitch(self: Sound, pitch: f32) void {
- sf.c.sfSound_setPitch(self.ptr, pitch);
+pub fn setPitch(self: *Sound, pitch: f32) void {
+ sf.c.sfSound_setPitch(self._ptr, pitch);
}
/// Sets the volume of the sound
pub fn getVolume(self: Sound) f32 {
- return sf.c.sfSound_getVolume(self.ptr);
+ return sf.c.sfSound_getVolume(self._ptr);
}
/// Gets the volume of the sound
-pub fn setVolume(self: Sound, volume: f32) void {
- sf.c.sfSound_setVolume(self.ptr, volume);
+pub fn setVolume(self: *Sound, volume: f32) void {
+ sf.c.sfSound_setVolume(self._ptr, volume);
}
pub const getStatus = @compileError("Function is not implemented yet.");
@@ -104,4 +104,4 @@ pub const getMinDistance = @compileError("Function is not implemented yet.");
pub const getAttenuation = @compileError("Function is not implemented yet.");
/// Pointer to the csfml sound
-ptr: *sf.c.sfSound,
+_ptr: *sf.c.sfSound,
diff --git a/src/sfml/audio/SoundBuffer.zig b/src/sfml/audio/SoundBuffer.zig
index 9727088..39ed082 100644
--- a/src/sfml/audio/SoundBuffer.zig
+++ b/src/sfml/audio/SoundBuffer.zig
@@ -10,56 +10,56 @@ pub fn createFromFile(path: [:0]const u8) !SoundBuffer {
var sound = sf.c.sfSoundBuffer_createFromFile(path);
if (sound == null)
return sf.Error.resourceLoadingError;
- return SoundBuffer{ .ptr = sound.? };
+ return SoundBuffer{ ._ptr = sound.? };
}
/// Creates a sound buffer from sample data
pub fn createFromSamples(samples: []const i16, channel_count: usize, sample_rate: usize) !SoundBuffer {
var sound = sf.c.sfSoundBuffer_createFromSamples(@ptrCast([*c]const c_short, samples.ptr), samples.len, @intCast(c_uint, channel_count), @intCast(c_uint, sample_rate));
if (sound == null)
return sf.Error.resourceLoadingError;
- return SoundBuffer{ .ptr = sound.? };
+ return SoundBuffer{ ._ptr = sound.? };
}
pub const initFromMemory = @compileError("Function is not implemented yet.");
pub const initFromStream = @compileError("Function is not implemented yet.");
/// Destroys this music object
-pub fn destroy(self: SoundBuffer) void {
- sf.c.sfSoundBuffer_destroy(self.ptr);
+pub fn destroy(self: *SoundBuffer) void {
+ sf.c.sfSoundBuffer_destroy(self._ptr);
}
// Getters / Setters
/// Gets the duration of the sound
pub fn getDuration(self: SoundBuffer) sf.system.Time {
- return sf.system.Time.fromCSFML(sf.c.sfSoundBuffer_getDuration(self.ptr));
+ return sf.system.Time._fromCSFML(sf.c.sfSoundBuffer_getDuration(self._ptr));
}
/// Gets the sample count of this sound
pub fn getSampleCount(self: SoundBuffer) usize {
- return @intCast(usize, sf.c.sfSoundBuffer_getSampleCount(self.ptr));
+ return @intCast(usize, sf.c.sfSoundBuffer_getSampleCount(self._ptr));
}
/// Gets the sample rate of this sound (n° of samples per second, often 44100)
pub fn getSampleRate(self: SoundBuffer) usize {
- return @intCast(usize, sf.c.sfSoundBuffer_getSampleRate(self.ptr));
+ return @intCast(usize, sf.c.sfSoundBuffer_getSampleRate(self._ptr));
}
/// Gets the channel count (2 is stereo for instance)
pub fn getChannelCount(self: SoundBuffer) usize {
- return @intCast(usize, sf.c.sfSoundBuffer_getChannelCount(self.ptr));
+ return @intCast(usize, sf.c.sfSoundBuffer_getChannelCount(self._ptr));
}
// Misc
/// Save the sound buffer to an audio file
pub fn saveToFile(self: SoundBuffer, path: [:0]const u8) !void {
- if (sf.c.sfSoundBuffer_saveToFile(self.ptr, path) != 1)
+ if (sf.c.sfSoundBuffer_saveToFile(self._ptr, path) != 1)
return sf.Error.savingInFileFailed;
}
/// Pointer to the csfml texture
-ptr: *sf.c.sfSoundBuffer,
+_ptr: *sf.c.sfSoundBuffer,
test "sound buffer: sane getter and setters" {
const std = @import("std");
diff --git a/src/sfml/graphics/BlendMode.zig b/src/sfml/graphics/BlendMode.zig
new file mode 100644
index 0000000..d78d60d
--- /dev/null
+++ b/src/sfml/graphics/BlendMode.zig
@@ -0,0 +1,92 @@
+//! Blending modes for drawing (for render states)
+
+// Enums
+pub const Factor = enum(c_int) {
+ zero,
+ one,
+ srcColor,
+ oneMinusSrcColor,
+ dstColor,
+ oneMinusDstColor,
+ srcAlpha,
+ oneMinusSrcAlpha,
+ dstAlpha,
+ oneMinusDstAlpha
+};
+
+pub const Equation = enum(c_int) {
+ add,
+ subtract,
+ reverseSubtract
+};
+
+const BlendMode = @This();
+
+// Preset blend modes
+pub const BlendAlpha = BlendMode{
+ .color_src_factor = .srcAlpha,
+ .color_dst_factor = .oneMinusSrcAlpha,
+ .color_equation = .add,
+ .alpha_src_factor = .one,
+ .alpha_dst_factor = .oneMinusSrcAlpha,
+ .alpha_equation = .add
+};
+
+pub const BlendAdd = BlendMode{
+ .color_src_factor = .srcAlpha,
+ .color_dst_factor = .one,
+ .color_equation = .add,
+ .alpha_src_factor = .one,
+ .alpha_dst_factor = .one,
+ .alpha_equation = .add
+};
+
+pub const BlendMultiply = BlendMode{
+ .color_src_factor = .dstColor,
+ .color_dst_factor = .zero,
+ .color_equation = .add,
+ .alpha_src_factor = .dstColor,
+ .alpha_dst_factor = .zero,
+ .alpha_equation = .add
+};
+
+pub const BlendMin = BlendMode{
+ .color_src_factor = .one,
+ .color_dst_factor = .one,
+ .color_equation = .min,
+ .alpha_src_factor = .one,
+ .alpha_dst_factor = .one,
+ .alpha_equation = .min
+};
+
+pub const BlendMax = BlendMode{
+ .color_src_factor = .one,
+ .color_dst_factor = .one,
+ .color_equation = .max,
+ .alpha_src_factor = .one,
+ .alpha_dst_factor = .one,
+ .alpha_equation = .max
+};
+
+pub const BlendNone = BlendMode{
+ .color_src_factor = .one,
+ .color_dst_factor = .zero,
+ .color_equation = .add,
+ .alpha_src_factor = .one,
+ .alpha_dst_factor = .zero,
+ .alpha_equation = .add
+};
+
+const sfBlendMode = @import("../sfml_import.zig").c.sfBlendMode;
+/// Bitcasts this blendmode to the csfml struct
+/// For inner workings
+pub fn _toCSFML(self: BlendMode) sfBlendMode {
+ return @bitCast(sfBlendMode, self);
+}
+
+color_src_factor: Factor,
+color_dst_factor: Factor,
+color_equation: Equation,
+alpha_src_factor: Factor,
+alpha_dst_factor: Factor,
+alpha_equation: Equation \ No newline at end of file
diff --git a/src/sfml/graphics/CircleShape.zig b/src/sfml/graphics/CircleShape.zig
index b2759e5..ea66dcb 100644
--- a/src/sfml/graphics/CircleShape.zig
+++ b/src/sfml/graphics/CircleShape.zig
@@ -19,107 +19,129 @@ pub fn create(radius: f32) !CircleShape {
sf.c.sfCircleShape_setFillColor(circle, sf.c.sfWhite);
sf.c.sfCircleShape_setRadius(circle, radius);
- return CircleShape{ .ptr = circle.? };
+ return CircleShape{ ._ptr = circle.? };
}
/// Destroys a circle shape
-pub fn destroy(self: CircleShape) void {
- sf.c.sfCircleShape_destroy(self.ptr);
+pub fn destroy(self: *CircleShape) void {
+ sf.c.sfCircleShape_destroy(self._ptr);
}
// Draw function
-pub fn sfDraw(self: CircleShape, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void {
- sf.c.sfRenderWindow_drawCircleShape(window.ptr, self.ptr, states);
+pub fn sfDraw(self: CircleShape, window: anytype, states: ?*sf.c.sfRenderStates) void {
+ switch (@TypeOf(window)) {
+ sf.RenderWindow => sf.c.sfRenderWindow_drawCircleShape(window._ptr, self._ptr, states),
+ sf.RenderTexture => sf.c.sfRenderTexture_drawCircleShape(window._ptr, self._ptr, states),
+ else => @compileError("window must be a render target"),
+ }
}
// Getters/setters
/// Gets the fill color of this circle shape
pub fn getFillColor(self: CircleShape) sf.Color {
- return sf.Color.fromCSFML(sf.c.sfCircleShape_getFillColor(self.ptr));
+ return sf.Color._fromCSFML(sf.c.sfCircleShape_getFillColor(self._ptr));
}
/// Sets the fill color of this circle shape
-pub fn setFillColor(self: CircleShape, color: sf.Color) void {
- sf.c.sfCircleShape_setFillColor(self.ptr, color.toCSFML());
+pub fn setFillColor(self: *CircleShape, color: sf.Color) void {
+ sf.c.sfCircleShape_setFillColor(self._ptr, color._toCSFML());
+}
+
+/// Gets the outline color of this circle shape
+pub fn getOutlineColor(self: CircleShape) sf.Color {
+ return sf.Color._fromCSFML(sf.c.sfCircleShape_getOutlineColor(self._ptr));
+}
+/// Sets the outline color of this circle shape
+pub fn setOutlineColor(self: *CircleShape, color: sf.Color) void {
+ sf.c.sfCircleShape_setOutlineColor(self._ptr, color._toCSFML());
+}
+
+/// Gets the outline thickness of this circle shape
+pub fn getOutlineThickness(self: CircleShape) f32 {
+ return sf.c.sfCircleShape_getOutlineThickness(self._ptr);
+}
+/// Sets the outline thickness of this circle shape
+pub fn setOutlineThickness(self: *CircleShape, thickness: f32) void {
+ sf.c.sfCircleShape_setOutlineThickness(self._ptr, thickness);
}
/// Gets the radius of this circle shape
pub fn getRadius(self: CircleShape) f32 {
- return sf.c.sfCircleShape_getRadius(self.ptr);
+ return sf.c.sfCircleShape_getRadius(self._ptr);
}
/// Sets the radius of this circle shape
-pub fn setRadius(self: CircleShape, radius: f32) void {
- sf.c.sfCircleShape_setRadius(self.ptr, radius);
+pub fn setRadius(self: *CircleShape, radius: f32) void {
+ sf.c.sfCircleShape_setRadius(self._ptr, radius);
}
/// Gets the position of this circle shape
pub fn getPosition(self: CircleShape) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfCircleShape_getPosition(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfCircleShape_getPosition(self._ptr));
}
/// Sets the position of this circle shape
-pub fn setPosition(self: CircleShape, pos: sf.Vector2f) void {
- sf.c.sfCircleShape_setPosition(self.ptr, pos.toCSFML());
+pub fn setPosition(self: *CircleShape, pos: sf.Vector2f) void {
+ sf.c.sfCircleShape_setPosition(self._ptr, pos._toCSFML());
}
/// Adds the offset to this shape's position
-pub fn move(self: CircleShape, offset: sf.Vector2f) void {
- sf.c.sfCircleShape_move(self.ptr, offset.toCSFML());
+pub fn move(self: *CircleShape, offset: sf.Vector2f) void {
+ sf.c.sfCircleShape_move(self._ptr, offset._toCSFML());
}
/// Gets the origin of this circle shape
pub fn getOrigin(self: CircleShape) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfCircleShape_getOrigin(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfCircleShape_getOrigin(self._ptr));
}
/// Sets the origin of this circle shape
-pub fn setOrigin(self: CircleShape, origin: sf.Vector2f) void {
- sf.c.sfCircleShape_setOrigin(self.ptr, origin.toCSFML());
+pub fn setOrigin(self: *CircleShape, origin: sf.Vector2f) void {
+ sf.c.sfCircleShape_setOrigin(self._ptr, origin._toCSFML());
}
/// Gets the rotation of this circle shape
pub fn getRotation(self: CircleShape) f32 {
- return sf.c.sfCircleShape_getRotation(self.ptr);
+ return sf.c.sfCircleShape_getRotation(self._ptr);
}
/// Sets the rotation of this circle shape
-pub fn setRotation(self: CircleShape, angle: f32) void {
- sf.c.sfCircleShape_setRotation(self.ptr, angle);
+pub fn setRotation(self: *CircleShape, angle: f32) void {
+ sf.c.sfCircleShape_setRotation(self._ptr, angle);
}
/// Rotates this shape by a given amount
-pub fn rotate(self: CircleShape, angle: f32) void {
- sf.c.sfCircleShape_rotate(self.ptr, angle);
+pub fn rotate(self: *CircleShape, angle: f32) void {
+ sf.c.sfCircleShape_rotate(self._ptr, angle);
}
/// Gets the texture of this shape
pub fn getTexture(self: CircleShape) ?sf.Texture {
- const t = sf.c.sfCircleShape_getTexture(self.ptr);
+ const t = sf.c.sfCircleShape_getTexture(self._ptr);
if (t) |tex| {
- return sf.Texture{ .const_ptr = tex };
+ return sf.Texture{ ._const_ptr = tex };
} else return null;
}
/// Sets the texture of this shape
-pub fn setTexture(self: CircleShape, texture: ?sf.Texture) void {
- var tex = if (texture) |t| t.get() else null;
- sf.c.sfCircleShape_setTexture(self.ptr, tex, 0);
+pub fn setTexture(self: *CircleShape, texture: ?sf.Texture) void {
+ var tex = if (texture) |t| t._get() else null;
+ sf.c.sfCircleShape_setTexture(self._ptr, tex, 0);
}
/// Gets the sub-rectangle of the texture that the shape will display
pub fn getTextureRect(self: CircleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getTextureRect(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getTextureRect(self._ptr));
}
/// Sets the sub-rectangle of the texture that the shape will display
-pub fn setTextureRect(self: CircleShape, rect: sf.FloatRect) void {
- sf.c.sfCircleShape_getCircleRect(self.ptr, rect.toCSFML());
+pub fn setTextureRect(self: *CircleShape, rect: sf.FloatRect) void {
+ sf.c.sfCircleShape_getCircleRect(self._ptr, rect._toCSFML());
}
/// Gets the bounds in the local coordinates system
pub fn getLocalBounds(self: CircleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getLocalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getLocalBounds(self._ptr));
}
/// Gets the bounds in the global coordinates
pub fn getGlobalBounds(self: CircleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfCircleShape_getGlobalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfCircleShape_getGlobalBounds(self._ptr));
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfCircleShape,
+_ptr: *sf.c.sfCircleShape,
test "circle shape: sane getters and setters" {
const tst = @import("std").testing;
@@ -128,14 +150,17 @@ test "circle shape: sane getters and setters" {
defer circle.destroy();
circle.setFillColor(sf.Color.Yellow);
+ circle.setOutlineColor(sf.Color.Red);
+ circle.setOutlineThickness(3);
circle.setRadius(50);
circle.setRotation(15);
circle.setPosition(.{ .x = 1, .y = 2 });
circle.setOrigin(.{ .x = 20, .y = 25 });
circle.setTexture(null);
- // TODO : issue #2
try tst.expectEqual(sf.Color.Yellow, circle.getFillColor());
+ try tst.expectEqual(sf.Color.Red, circle.getOutlineColor());
+ try tst.expectEqual(@as(f32, 3), circle.getOutlineThickness());
try tst.expectEqual(@as(f32, 50), circle.getRadius());
try tst.expectEqual(@as(f32, 15), circle.getRotation());
try tst.expectEqual(sf.Vector2f{ .x = 1, .y = 2 }, circle.getPosition());
diff --git a/src/sfml/graphics/Font.zig b/src/sfml/graphics/Font.zig
index 78bd5a6..ecc1a56 100644
--- a/src/sfml/graphics/Font.zig
+++ b/src/sfml/graphics/Font.zig
@@ -11,15 +11,41 @@ pub fn createFromFile(path: [:0]const u8) !Font {
var font = sf.c.sfFont_createFromFile(path);
if (font == null)
return sf.Error.resourceLoadingError;
- return Font{ .ptr = font.? };
+ return Font{ ._ptr = font.? };
}
/// Destroys a font
-pub fn destroy(self: Font) void {
- sf.c.sfFont_destroy(self.ptr);
+pub fn destroy(self: *Font) void {
+ sf.c.sfFont_destroy(self._ptr);
}
+/// Gets the family name of this font
+/// Normally, this is done through getInfo, but as info only contains this data, this makes more sense
+pub fn getFamily(self: Font) [*:0]const u8 {
+ return sf.c.sfFont_getInfo(self._ptr).family;
+}
+
+/// Gets the kerning offset of two glyphs
+pub fn getKerning(self: Font, first: u32, second: u32, character_size: usize) f32 {
+ return sf.c.sfFont_getKerning(self._ptr, first, second, @intCast(c_uint, character_size));
+}
+
+/// Gets the default spacing between two lines
+pub fn getLineSpacing(self: Font, character_size: usize) f32 {
+ return sf.c.sfFont_getLineSpacing(self._ptr, @intCast(c_uint, character_size));
+}
+
+/// Gets the vertical offset of the underline
+pub fn getUnderlinePosition(self: Font, character_size: usize) f32 {
+ return sf.c.sfFont_getUnderlinePosition(self._ptr, @intCast(c_uint, character_size));
+}
+/// Gets the underline thickness
+pub fn getUnderlineThickness(self: Font, character_size: usize) f32 {
+ return sf.c.sfFont_getUnderlineThickness(self._ptr, @intCast(c_uint, character_size));
+}
+
+pub const getGlyph = @compileError("Function is not implemented yet.");
pub const initFromMemory = @compileError("Function is not implemented yet.");
pub const initFromStream = @compileError("Function is not implemented yet.");
/// Pointer to the csfml font
-ptr: *sf.c.sfFont,
+_ptr: *sf.c.sfFont,
diff --git a/src/sfml/graphics/Image.zig b/src/sfml/graphics/Image.zig
index 8ddf8e3..61dd027 100644
--- a/src/sfml/graphics/Image.zig
+++ b/src/sfml/graphics/Image.zig
@@ -15,10 +15,10 @@ const Image = @This();
/// Creates a new image
pub fn create(size: sf.Vector2u, color: sf.Color) !Image {
- var img = sf.c.sfImage_createFromColor(size.x, size.y, color.toCSFML());
+ var img = sf.c.sfImage_createFromColor(size.x, size.y, color._toCSFML());
if (img == null)
return sf.Error.nullptrUnknownReason;
- return Image{ .ptr = img.? };
+ return Image{ ._ptr = img.? };
}
/// Creates an image from a pixel array
@@ -31,7 +31,7 @@ pub fn createFromPixels(size: sf.Vector2u, pixels: []const sf.Color) !Image {
if (img == null)
return sf.Error.nullptrUnknownReason;
- return Image{ .ptr = img.? };
+ return Image{ ._ptr = img.? };
}
/// Loads an image from a file
@@ -39,17 +39,17 @@ pub fn createFromFile(path: [:0]const u8) !Image {
var img = sf.c.sfImage_createFromFile(path);
if (img == null)
return sf.Error.resourceLoadingError;
- return Image{ .ptr = img.? };
+ return Image{ ._ptr = img.? };
}
/// Destroys an image
-pub fn destroy(self: Image) void {
- sf.c.sfImage_destroy(self.ptr);
+pub fn destroy(self: *Image) void {
+ sf.c.sfImage_destroy(self._ptr);
}
// Save an image to a file
pub fn saveToFile(self: Image, path: [:0]const u8) !void {
- if (sf.c.sfImage_saveToFile(self.ptr, path) != 1)
+ if (sf.c.sfImage_saveToFile(self._ptr, path) != 1)
return sf.Error.savingInFileFailed;
}
@@ -60,24 +60,24 @@ pub fn getPixel(self: Image, pixel_pos: sf.Vector2u) sf.Color {
const size = self.getSize();
assert(pixel_pos.x < size.x and pixel_pos.y < size.y);
- return sf.Color.fromCSFML(sf.c.sfImage_getPixel(self.ptr, pixel_pos.x, pixel_pos.y));
+ return sf.Color._fromCSFML(sf.c.sfImage_getPixel(self._ptr, pixel_pos.x, pixel_pos.y));
}
/// Sets a pixel on this image (bounds are only checked in an assertion)
-pub fn setPixel(self: Image, pixel_pos: sf.Vector2u, color: sf.Color) void {
+pub fn setPixel(self: *Image, pixel_pos: sf.Vector2u, color: sf.Color) void {
const size = self.getSize();
assert(pixel_pos.x < size.x and pixel_pos.y < size.y);
- sf.c.sfImage_setPixel(self.ptr, pixel_pos.x, pixel_pos.y, color.toCSFML());
+ sf.c.sfImage_setPixel(self._ptr, pixel_pos.x, pixel_pos.y, color._toCSFML());
}
/// Gets the size of this image
pub fn getSize(self: Image) sf.Vector2u {
- const size = sf.c.sfImage_getSize(self.ptr);
+ const size = sf.c.sfImage_getSize(self._ptr);
return sf.Vector2u{ .x = size.x, .y = size.y };
}
/// Pointer to the csfml texture
-ptr: *sf.c.sfImage,
+_ptr: *sf.c.sfImage,
test "image: sane getters and setters" {
const tst = std.testing;
diff --git a/src/sfml/graphics/RectangleShape.zig b/src/sfml/graphics/RectangleShape.zig
index 34bb114..324199e 100644
--- a/src/sfml/graphics/RectangleShape.zig
+++ b/src/sfml/graphics/RectangleShape.zig
@@ -17,110 +17,131 @@ pub fn create(size: sf.Vector2f) !RectangleShape {
return sf.Error.nullptrUnknownReason;
sf.c.sfRectangleShape_setFillColor(rect, sf.c.sfWhite);
- sf.c.sfRectangleShape_setSize(rect, size.toCSFML());
+ sf.c.sfRectangleShape_setSize(rect, size._toCSFML());
- return RectangleShape{ .ptr = rect.? };
+ return RectangleShape{ ._ptr = rect.? };
}
/// Destroys a rectangle shape
-pub fn destroy(self: RectangleShape) void {
- sf.c.sfRectangleShape_destroy(self.ptr);
+pub fn destroy(self: *RectangleShape) void {
+ sf.c.sfRectangleShape_destroy(self._ptr);
}
// Draw function
-pub fn sfDraw(self: RectangleShape, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void {
- sf.c.sfRenderWindow_drawRectangleShape(window.ptr, self.ptr, states);
+pub fn sfDraw(self: RectangleShape, window: anytype, states: ?*sf.c.sfRenderStates) void {
+ switch (@TypeOf(window)) {
+ sf.RenderWindow => sf.c.sfRenderWindow_drawRectangleShape(window._ptr, self._ptr, states),
+ sf.RenderTexture => sf.c.sfRenderTexture_drawRectangleShape(window._ptr, self._ptr, states),
+ else => @compileError("window must be a render target"),
+ }
}
// Getters/setters
/// Gets the fill color of this rectangle shape
pub fn getFillColor(self: RectangleShape) sf.Color {
- return sf.Color.fromCSFML(sf.c.sfRectangleShape_getFillColor(self.ptr));
+ return sf.Color._fromCSFML(sf.c.sfRectangleShape_getFillColor(self._ptr));
}
/// Sets the fill color of this rectangle shape
-pub fn setFillColor(self: RectangleShape, color: sf.Color) void {
- sf.c.sfRectangleShape_setFillColor(self.ptr, color.toCSFML());
+pub fn setFillColor(self: *RectangleShape, color: sf.Color) void {
+ sf.c.sfRectangleShape_setFillColor(self._ptr, color._toCSFML());
+}
+
+/// Gets the outline color of this rectangle shape
+pub fn getOutlineColor(self: RectangleShape) sf.Color {
+ return sf.Color._fromCSFML(sf.c.sfRectangleShape_getOutlineColor(self._ptr));
+}
+/// Sets the outline color of this rectangle shape
+pub fn setOutlineColor(self: *RectangleShape, color: sf.Color) void {
+ sf.c.sfRectangleShape_setOutlineColor(self._ptr, color._toCSFML());
+}
+
+/// Gets the outline thickness of this rectangle shape
+pub fn getOutlineThickness(self: RectangleShape) f32 {
+ return sf.c.sfRectangleShape_getOutlineThickness(self._ptr);
+}
+/// Sets the outline thickness of this rectangle shape
+pub fn setOutlineThickness(self: *RectangleShape, thickness: f32) void {
+ sf.c.sfRectangleShape_setOutlineThickness(self._ptr, thickness);
}
/// Gets the size of this rectangle shape
pub fn getSize(self: RectangleShape) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getSize(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getSize(self._ptr));
}
/// Sets the size of this rectangle shape
-pub fn setSize(self: RectangleShape, size: sf.Vector2f) void {
- sf.c.sfRectangleShape_setSize(self.ptr, size.toCSFML());
+pub fn setSize(self: *RectangleShape, size: sf.Vector2f) void {
+ sf.c.sfRectangleShape_setSize(self._ptr, size._toCSFML());
}
/// Gets the position of this rectangle shape
pub fn getPosition(self: RectangleShape) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getPosition(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getPosition(self._ptr));
}
/// Sets the position of this rectangle shape
-pub fn setPosition(self: RectangleShape, pos: sf.Vector2f) void {
- sf.c.sfRectangleShape_setPosition(self.ptr, pos.toCSFML());
+pub fn setPosition(self: *RectangleShape, pos: sf.Vector2f) void {
+ sf.c.sfRectangleShape_setPosition(self._ptr, pos._toCSFML());
}
/// Adds the offset to this shape's position
-pub fn move(self: RectangleShape, offset: sf.Vector2f) void {
- sf.c.sfRectangleShape_move(self.ptr, offset.toCSFML());
+pub fn move(self: *RectangleShape, offset: sf.Vector2f) void {
+ sf.c.sfRectangleShape_move(self._ptr, offset._toCSFML());
}
/// Gets the origin of this rectangle shape
pub fn getOrigin(self: RectangleShape) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfRectangleShape_getOrigin(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfRectangleShape_getOrigin(self._ptr));
}
/// Sets the origin of this rectangle shape
-pub fn setOrigin(self: RectangleShape, origin: sf.Vector2f) void {
- sf.c.sfRectangleShape_setOrigin(self.ptr, origin.toCSFML());
+pub fn setOrigin(self: *RectangleShape, origin: sf.Vector2f) void {
+ sf.c.sfRectangleShape_setOrigin(self._ptr, origin._toCSFML());
}
/// Gets the rotation of this rectangle shape
pub fn getRotation(self: RectangleShape) f32 {
- return sf.c.sfRectangleShape_getRotation(self.ptr);
+ return sf.c.sfRectangleShape_getRotation(self._ptr);
}
/// Sets the rotation of this rectangle shape
-pub fn setRotation(self: RectangleShape, angle: f32) void {
- sf.c.sfRectangleShape_setRotation(self.ptr, angle);
+pub fn setRotation(self: *RectangleShape, angle: f32) void {
+ sf.c.sfRectangleShape_setRotation(self._ptr, angle);
}
/// Rotates this shape by a given amount
-pub fn rotate(self: RectangleShape, angle: f32) void {
- sf.c.sfRectangleShape_rotate(self.ptr, angle);
+pub fn rotate(self: *RectangleShape, angle: f32) void {
+ sf.c.sfRectangleShape_rotate(self._ptr, angle);
}
/// Gets the texture of this shape
pub fn getTexture(self: RectangleShape) ?sf.Texture {
- const t = sf.c.sfRectangleShape_getTexture(self.ptr);
+ const t = sf.c.sfRectangleShape_getTexture(self._ptr);
if (t) |tex| {
- return sf.Texture{ .const_ptr = tex };
- } else
- return null;
+ return sf.Texture{ ._const_ptr = tex };
+ } else return null;
}
/// Sets the texture of this shape
-pub fn setTexture(self: RectangleShape, texture: ?sf.Texture) void {
- var tex = if (texture) |t| t.get() else null;
- sf.c.sfRectangleShape_setTexture(self.ptr, tex, 0);
+pub fn setTexture(self: *RectangleShape, texture: ?sf.Texture) void {
+ var tex = if (texture) |t| t._get() else null;
+ sf.c.sfRectangleShape_setTexture(self._ptr, tex, 0);
}
/// Gets the sub-rectangle of the texture that the shape will display
pub fn getTextureRect(self: RectangleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getTextureRect(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getTextureRect(self._ptr));
}
/// Sets the sub-rectangle of the texture that the shape will display
-pub fn setTextureRect(self: RectangleShape, rect: sf.FloatRect) void {
- sf.c.sfRectangleShape_getTextureRect(self.ptr, rect.toCSFML());
+pub fn setTextureRect(self: *RectangleShape, rect: sf.FloatRect) void {
+ sf.c.sfRectangleShape_getTextureRect(self._ptr, rect._toCSFML());
}
/// Gets the bounds in the local coordinates system
pub fn getLocalBounds(self: RectangleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getLocalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getLocalBounds(self._ptr));
}
/// Gets the bounds in the global coordinates
pub fn getGlobalBounds(self: RectangleShape) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfRectangleShape_getGlobalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfRectangleShape_getGlobalBounds(self._ptr));
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfRectangleShape,
+_ptr: *sf.c.sfRectangleShape,
test "rectangle shape: sane getters and setters" {
const tst = @import("std").testing;
@@ -131,13 +152,17 @@ test "rectangle shape: sane getters and setters" {
try tst.expectEqual(sf.Vector2f{ .x = 30, .y = 50 }, rect.getSize());
rect.setFillColor(sf.Color.Yellow);
+ rect.setOutlineColor(sf.Color.Red);
+ rect.setOutlineThickness(3);
rect.setSize(.{ .x = 15, .y = 510 });
rect.setRotation(15);
rect.setPosition(.{ .x = 1, .y = 2 });
rect.setOrigin(.{ .x = 20, .y = 25 });
- rect.setTexture(null); //Weirdly, getTexture if texture wasn't set gives a wrong pointer
+ rect.setTexture(null); //Weirdly, getTexture if texture wasn't set gives a wrong pointer
try tst.expectEqual(sf.Color.Yellow, rect.getFillColor());
+ try tst.expectEqual(sf.Color.Red, rect.getOutlineColor());
+ try tst.expectEqual(@as(f32, 3), rect.getOutlineThickness());
try tst.expectEqual(sf.Vector2f{ .x = 15, .y = 510 }, rect.getSize());
try tst.expectEqual(@as(f32, 15), rect.getRotation());
try tst.expectEqual(sf.Vector2f{ .x = 1, .y = 2 }, rect.getPosition());
diff --git a/src/sfml/graphics/RenderStates.zig b/src/sfml/graphics/RenderStates.zig
new file mode 100644
index 0000000..e7234ae
--- /dev/null
+++ b/src/sfml/graphics/RenderStates.zig
@@ -0,0 +1,20 @@
+//! Defines settings for drawing things on a target
+
+const sf = struct {
+ pub usingnamespace @import("../sfml.zig");
+ pub usingnamespace sf.graphics;
+};
+
+blend_mode: sf.BlendMode = sf.BlendMode.BlendAlpha,
+//transform: null, // TODO: implement transforms (#25)
+texture: ?sf.Texture = null,
+shader: ?sf.Shader = null,
+
+pub fn _toCSFML(self: @This()) sf.c.sfRenderStates {
+ return .{
+ .blendMode = self.blend_mode._toCSFML(),
+ .transform = .{ .matrix = .{ 1, 0, 0, 0, 1, 0, 0, 0, 1} },
+ .texture = if (self.texture) |t| t._get() else null,
+ .shader = if (self.shader) |s| s._ptr else null
+ };
+} \ No newline at end of file
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 }));
+}
diff --git a/src/sfml/graphics/RenderWindow.zig b/src/sfml/graphics/RenderWindow.zig
index dd6c7e3..a88adbf 100644
--- a/src/sfml/graphics/RenderWindow.zig
+++ b/src/sfml/graphics/RenderWindow.zig
@@ -4,6 +4,7 @@ const sf = struct {
pub usingnamespace @import("../sfml.zig");
pub usingnamespace sf.system;
pub usingnamespace sf.graphics;
+ pub usingnamespace sf.window;
};
const RenderWindow = @This();
@@ -12,7 +13,7 @@ const RenderWindow = @This();
/// Inits a render window with a size, a bits per pixel (most put 32), a title and a style
/// The window will have the default style
-pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32) !RenderWindow {
+pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32, settings: ?sf.ContextSettings) !RenderWindow {
var ret: RenderWindow = undefined;
var mode: sf.c.sfVideoMode = .{
@@ -21,17 +22,15 @@ pub fn create(size: sf.Vector2u, bpp: usize, title: [:0]const u8, style: u32) !R
.bitsPerPixel = @intCast(c_uint, bpp),
};
- var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), style, null);
+ const c_settings = if (settings) |s| s._toCSFML() else null;
+ var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), style, if (c_settings) |s| &s else null);
if (window) |w| {
- ret.ptr = w;
- } else {
- return sf.Error.windowCreationFailed;
- }
+ ret._ptr = w;
+ } else return sf.Error.windowCreationFailed;
return ret;
}
-
/// Inits a render window with a size and a title
/// The window will have the default style
pub fn createDefault(size: sf.Vector2u, title: [:0]const u8) !RenderWindow {
@@ -46,137 +45,162 @@ pub fn createDefault(size: sf.Vector2u, title: [:0]const u8) !RenderWindow {
var window = sf.c.sfRenderWindow_create(mode, @ptrCast([*c]const u8, title), sf.window.Style.defaultStyle, null);
if (window) |w| {
- ret.ptr = w;
- } else {
- return sf.Error.windowCreationFailed;
- }
+ ret._ptr = w;
+ } else return sf.Error.windowCreationFailed;
return ret;
}
+/// Inits a rendering plane from a window handle. The handle can actually be to any drawing surface.
+pub fn createFromHandle(handle: sf.WindowHandle, settings: ?sf.ContextSettings) !RenderWindow {
+ const c_settings = if (settings) |s| s._toCSFML() else null;
+ const window = sf.c.sfRenderWindow_createFromHandle(handle, if (c_settings) |s| &s else null);
+
+ if (window) |w| {
+ return .{ ._ptr = w };
+ } else return sf.Error.windowCreationFailed;
+}
/// Destroys this window object
-pub fn destroy(self: RenderWindow) void {
- sf.c.sfRenderWindow_destroy(self.ptr);
+pub fn destroy(self: *RenderWindow) void {
+ sf.c.sfRenderWindow_destroy(self._ptr);
}
// Event related
/// Returns true if this window is still open
pub fn isOpen(self: RenderWindow) bool {
- return sf.c.sfRenderWindow_isOpen(self.ptr) != 0;
+ return sf.c.sfRenderWindow_isOpen(self._ptr) != 0;
}
/// Closes this window
-pub fn close(self: RenderWindow) void {
- sf.c.sfRenderWindow_close(self.ptr);
+pub fn close(self: *RenderWindow) void {
+ sf.c.sfRenderWindow_close(self._ptr);
}
/// Gets an event from the queue, returns null is theres none
/// Use while on this to get all the events in your game loop
-pub fn pollEvent(self: RenderWindow) ?sf.window.Event {
+pub fn pollEvent(self: *RenderWindow) ?sf.window.Event {
var event: sf.c.sfEvent = undefined;
- if (sf.c.sfRenderWindow_pollEvent(self.ptr, &event) == 0)
+ if (sf.c.sfRenderWindow_pollEvent(self._ptr, &event) == 0)
return null;
// Skip sfEvtMouseWheelMoved to avoid sending mouseWheelScrolled twice
if (event.type == sf.c.sfEvtMouseWheelMoved) {
return self.pollEvent();
}
- return sf.window.Event.fromCSFML(event);
+ return sf.window.Event._fromCSFML(event);
}
// Drawing functions
/// Clears the drawing screen with a color
-pub fn clear(self: RenderWindow, color: sf.Color) void {
- sf.c.sfRenderWindow_clear(self.ptr, color.toCSFML());
+pub fn clear(self: *RenderWindow, color: sf.Color) void {
+ sf.c.sfRenderWindow_clear(self._ptr, color._toCSFML());
}
/// Displays what has been drawn on the render area
-pub fn display(self: RenderWindow) void {
- sf.c.sfRenderWindow_display(self.ptr);
+pub fn display(self: *RenderWindow) void {
+ sf.c.sfRenderWindow_display(self._ptr);
}
/// Draw something on the screen (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: RenderWindow, to_draw: anytype, states: ?*sf.c.sfRenderStates) void {
+pub fn draw(self: *RenderWindow, 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
- @call(.{ .modifier = .always_inline }, T.sfDraw, .{ to_draw, self, states });
+ 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).");
}
// Getters/setters
+
/// Gets the current view of the window
/// Unlike in SFML, you don't get a const pointer but a copy
pub fn getView(self: RenderWindow) sf.View {
- return sf.View.fromCSFML(sf.c.sfRenderWindow_getView(self.ptr).?);
+ return sf.View._fromCSFML(sf.c.sfRenderWindow_getView(self._ptr).?);
}
/// Gets the default view of this window
/// Unlike in SFML, you don't get a const pointer but a copy
pub fn getDefaultView(self: RenderWindow) sf.View {
- return sf.View.fromCSFML(sf.c.sfRenderWindow_getDefaultView(self.ptr).?);
+ return sf.View._fromCSFML(sf.c.sfRenderWindow_getDefaultView(self._ptr).?);
}
/// Sets the view of this window
-pub fn setView(self: RenderWindow, view: sf.View) void {
- var cview = view.toCSFML();
+pub fn setView(self: *RenderWindow, view: sf.View) void {
+ var cview = view._toCSFML();
defer sf.c.sfView_destroy(cview);
- sf.c.sfRenderWindow_setView(self.ptr, cview);
+ sf.c.sfRenderWindow_setView(self._ptr, cview);
+}
+/// Gets the viewport of this render target
+pub fn getViewport(self: RenderWindow, view: sf.View) sf.IntRect {
+ return sf.IntRect._fromCSFML(sf.c.sfRenderWindow_getViewPort(self._ptr, view._ptr));
+}
+
+/// Set mouse cursor grabbing
+pub fn setMouseCursorGrabbed(self : RenderWindow, grab : bool) void {
+ sf.c.sfRenderWindow_setMouseCursorGrabbed(self._ptr, if (grab) 1 else 0);
+}
+
+/// Set mouse cursor visibility
+pub fn setMouseCursorVisible(self : RenderWindow, visible : bool) void {
+ sf.c.sfRenderWindow_setMouseCursorVisible(self._ptr, if (visible) 1 else 0);
}
/// Gets the size of this window
pub fn getSize(self: RenderWindow) sf.Vector2u {
- return sf.Vector2u.fromCSFML(sf.c.sfRenderWindow_getSize(self.ptr));
+ return sf.Vector2u._fromCSFML(sf.c.sfRenderWindow_getSize(self._ptr));
}
/// Sets the size of this window
-pub fn setSize(self: RenderWindow, size: sf.Vector2u) void {
- sf.c.sfRenderWindow_setSize(self.ptr, size.toCSFML());
+pub fn setSize(self: *RenderWindow, size: sf.Vector2u) void {
+ sf.c.sfRenderWindow_setSize(self._ptr, size._toCSFML());
}
/// Gets the position of this window
pub fn getPosition(self: RenderWindow) sf.Vector2i {
- return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_getPosition(self.ptr));
+ return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_getPosition(self._ptr));
}
/// Sets the position of this window
-pub fn setPosition(self: RenderWindow, pos: sf.Vector2i) void {
- sf.c.sfRenderWindow_setPosition(self.ptr, pos.toCSFML());
+pub fn setPosition(self: *RenderWindow, pos: sf.Vector2i) void {
+ sf.c.sfRenderWindow_setPosition(self._ptr, pos._toCSFML());
}
// TODO : unicode title?
/// Sets the title of this window
-pub fn setTitle(self: RenderWindow, title: [:0]const u8) void {
- sf.c.sfRenderWindow_setTitle(self.ptr, title);
+pub fn setTitle(self: *RenderWindow, title: [:0]const u8) void {
+ sf.c.sfRenderWindow_setTitle(self._ptr, title);
}
/// Sets the windows's framerate limit
-pub fn setFramerateLimit(self: RenderWindow, fps: c_uint) void {
- sf.c.sfRenderWindow_setFramerateLimit(self.ptr, fps);
+pub fn setFramerateLimit(self: *RenderWindow, fps: c_uint) void {
+ sf.c.sfRenderWindow_setFramerateLimit(self._ptr, fps);
}
/// Enables or disables vertical sync
-pub fn setVerticalSyncEnabled(self: RenderWindow, enabled: bool) void {
- sf.c.sfRenderWindow_setFramerateLimit(self.ptr, if (enabled) 1 else 0);
+pub fn setVerticalSyncEnabled(self: *RenderWindow, enabled: bool) void {
+ sf.c.sfRenderWindow_setVerticalSyncEnabled(self._ptr, @boolToInt(enabled));
}
/// Convert a point from target coordinates to world coordinates, using the current view (or the specified view)
pub fn mapPixelToCoords(self: RenderWindow, pixel: sf.Vector2i, view: ?sf.View) sf.Vector2f {
if (view) |v| {
- var cview = v.toCSFML();
+ var cview = v._toCSFML();
defer sf.c.sfView_destroy(cview);
- return sf.Vector2f.fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self.ptr, pixel.toCSFML(), cview));
- } else return sf.Vector2f.fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self.ptr, pixel.toCSFML(), null));
+ return sf.Vector2f._fromCSFML(sf.c.sfRenderWindow_mapPixelToCoords(self._ptr, pixel._toCSFML(), cview));
+ } else return sf.Vector2f._fromCSFML(sf.c.sfRenderWindow_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: RenderWindow, coords: sf.Vector2f, view: ?sf.View) sf.Vector2i {
if (view) |v| {
- var cview = v.toCSFML();
+ var cview = v._toCSFML();
defer sf.c.sfView_destroy(cview);
- return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self.ptr, coords.toCSFML(), cview));
- } else return sf.Vector2i.fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self.ptr, coords.toCSFML(), null));
+ return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self._ptr, coords._toCSFML(), cview));
+ } else return sf.Vector2i._fromCSFML(sf.c.sfRenderWindow_mapCoordsToPixel(self._ptr, coords._toCSFML(), null));
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfRenderWindow
+_ptr: *sf.c.sfRenderWindow
diff --git a/src/sfml/graphics/Shader.zig b/src/sfml/graphics/Shader.zig
new file mode 100644
index 0000000..ea5072c
--- /dev/null
+++ b/src/sfml/graphics/Shader.zig
@@ -0,0 +1,96 @@
+//! Shader class
+
+const sf = @import("../sfml.zig");
+const glsl = sf.graphics.glsl;
+
+const Shader = @This();
+
+// Constructor/destructor
+
+/// Creates a shader object from shader files, you can omit some shader types by passing null
+pub fn createFromFile(
+ vertex_shader_path: ?[:0]const u8,
+ geometry_shader_path: ?[:0]const u8,
+ fragment_shader_path: ?[:0]const u8
+) !Shader {
+ const shader = sf.c.sfShader_createFromFile(
+ if (vertex_shader_path) |vsp| @ptrCast([*c]const u8, vsp) else null,
+ if (geometry_shader_path) |gsp| @ptrCast([*c]const u8, gsp) else null,
+ if (fragment_shader_path) |fsp| @ptrCast([*c]const u8, fsp) else null
+ );
+ if (shader) |s| {
+ return Shader{ ._ptr = s };
+ } else return sf.Error.nullptrUnknownReason;
+}
+/// Create a shader object from glsl code as string, you can omit some shader types by passing null
+pub fn createFromMemory(
+ vertex_shader: ?[:0]const u8,
+ geometry_shader: ?[:0]const u8,
+ fragment_shader: ?[:0]const u8
+) !Shader {
+ const shader = sf.c.sfShader_createFromMemory(
+ if (vertex_shader) |vs| @ptrCast([*c]const u8, vs) else null,
+ if (geometry_shader) |gs| @ptrCast([*c]const u8, gs) else null,
+ if (fragment_shader) |fs| @ptrCast([*c]const u8, fs) else null
+ );
+ if (shader) |s| {
+ return Shader{ ._ptr = s };
+ } else return sf.Error.nullptrUnknownReason;
+}
+/// Destroys this shader object
+pub fn destroy(self: *Shader) void {
+ sf.c.sfShader_destroy(self._ptr);
+}
+
+// Availability
+
+/// Checks whether or not shaders can be used in the system
+pub fn isAvailable() bool {
+ return sf.c.sfShader_isAvailable();
+}
+/// Checks whether or not geometry shaders can be used
+pub fn isGeometryAvailable() bool {
+ return sf.c.sfShader_isAvailable();
+}
+
+const CurrentTextureT = struct{};
+/// Special value to pass to setUniform to have an uniform of the texture used for drawing
+/// which cannot be known in advance
+pub const CurrentTexture: CurrentTextureT = .{};
+
+// Uniform
+
+/// Sets an uniform for the shader
+/// Colors are vectors so if you want to pass a color use .toIVec4() or .toFVec4()
+/// Pass CurrentTexture if you want to have the drawing texture as an uniform, which cannot be known in advance
+pub fn setUniform(self: *Shader, name: [:0]const u8, value: anytype) void {
+ const T = @TypeOf(value);
+ switch (T) {
+ f32 => sf.c.sfShader_setFloatUniform(self._ptr, name, value),
+ c_int => sf.c.sfShader_setIntUniform(self._ptr, name, value),
+ bool => sf.c.sfShader_setBoolUniform(self._ptr, name, value),
+ glsl.FVec2 => sf.c.sfShader_setVec2Uniform(self._ptr, name, value._toCSFML()),
+ glsl.FVec3 => sf.c.sfShader_setVec3Uniform(self._ptr, name, value._toCSFML()),
+ glsl.FVec4 => sf.c.sfShader_setVec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslVec4, value)),
+ glsl.IVec2 => sf.c.sfShader_setIvec2Uniform(self._ptr, name, value._toCSFML()),
+ glsl.IVec3 => sf.c.sfShader_setIvec3Uniform(self._ptr, name, @bitCast(sf.c.sfGlslIvec3, value)),
+ glsl.IVec4 => sf.c.sfShader_setIvec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslIvec4, value)),
+ glsl.BVec2 => sf.c.sfShader_setBvec2Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec2, value)),
+ glsl.BVec3 => sf.c.sfShader_setBvec3Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec3, value)),
+ glsl.BVec4 => sf.c.sfShader_setBvec4Uniform(self._ptr, name, @bitCast(sf.c.sfGlslBvec4, value)),
+ glsl.Mat3 => sf.c.sfShader_setMat3Uniform(self._ptr, name, @ptrCast(*const sf.c.sfGlslMat3, @alignCast(4, &value))),
+ glsl.Mat4 => sf.c.sfShader_setMat4Uniform(self._ptr, name, @ptrCast(*const sf.c.sfGlslMat4, @alignCast(4, &value))),
+ sf.graphics.Texture => sf.c.sfShader_setTextureUniform(self._ptr, name, value._get()),
+ CurrentTextureT => sf.c.sfShader_setCurrentTextureUniform(self._ptr, name),
+ []const f32 => sf.c.sfShader_setFloatUniformArray(self._ptr, name, value.ptr, value.len),
+ []const glsl.FVec2 => sf.c.sfShader_setVec2UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec2, value.ptr), value.len),
+ []const glsl.FVec3 => sf.c.sfShader_setVec3UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec3, value.ptr), value.len),
+ []const glsl.FVec4 => sf.c.sfShader_setVec4UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec4, value.ptr), value.len),
+ []const glsl.Mat3 => sf.c.sfShader_setMat3UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslMat3, value.ptr), value.len),
+ []const glsl.Mat4 => sf.c.sfShader_setMat4UniformArray(self._ptr, name, @ptrCast(*sf.c.sfGlslVec4, value.ptr), value.len),
+ else => @compileError("Uniform of type \"" ++ @typeName(T) ++ "\" cannot be set inside shader.")
+ }
+}
+
+/// Pointer to the CSFML structure
+_ptr: *sf.c.sfShader \ No newline at end of file
diff --git a/src/sfml/graphics/Sprite.zig b/src/sfml/graphics/Sprite.zig
index 4f24735..872c980 100644
--- a/src/sfml/graphics/Sprite.zig
+++ b/src/sfml/graphics/Sprite.zig
@@ -16,7 +16,7 @@ pub fn create() !Sprite {
if (sprite == null)
return sf.Error.nullptrUnknownReason;
- return Sprite{ .ptr = sprite.? };
+ return Sprite{ ._ptr = sprite.? };
}
/// Inits a sprite with a texture
@@ -25,103 +25,107 @@ pub fn createFromTexture(texture: sf.Texture) !Sprite {
if (sprite == null)
return sf.Error.nullptrUnknownReason;
- sf.c.sfSprite_setTexture(sprite, texture.get(), 1);
+ sf.c.sfSprite_setTexture(sprite, texture._get(), 1);
- return Sprite{ .ptr = sprite.? };
+ return Sprite{ ._ptr = sprite.? };
}
/// Destroys this sprite
-pub fn destroy(self: Sprite) void {
- sf.c.sfSprite_destroy(self.ptr);
+pub fn destroy(self: *Sprite) void {
+ sf.c.sfSprite_destroy(self._ptr);
}
// Draw function
-pub fn sfDraw(self: Sprite, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void {
- sf.c.sfRenderWindow_drawSprite(window.ptr, self.ptr, states);
+pub fn sfDraw(self: Sprite, window: anytype, states: ?*sf.c.sfRenderStates) void {
+ switch (@TypeOf(window)) {
+ sf.RenderWindow => sf.c.sfRenderWindow_drawSprite(window._ptr, self._ptr, states),
+ sf.RenderTexture => sf.c.sfRenderTexture_drawSprite(window._ptr, self._ptr, states),
+ else => @compileError("window must be a render target"),
+ }
}
// Getters/setters
/// Gets the position of this sprite
pub fn getPosition(self: Sprite) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfSprite_getPosition(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfSprite_getPosition(self._ptr));
}
/// Sets the position of this sprite
-pub fn setPosition(self: Sprite, pos: sf.Vector2f) void {
- sf.c.sfSprite_setPosition(self.ptr, pos.toCSFML());
+pub fn setPosition(self: *Sprite, pos: sf.Vector2f) void {
+ sf.c.sfSprite_setPosition(self._ptr, pos._toCSFML());
}
/// Adds the offset to this shape's position
-pub fn move(self: Sprite, offset: sf.Vector2f) void {
- sf.c.sfSprite_move(self.ptr, offset.toCSFML());
+pub fn move(self: *Sprite, offset: sf.Vector2f) void {
+ sf.c.sfSprite_move(self._ptr, offset._toCSFML());
}
/// Gets the scale of this sprite
pub fn getScale(self: Sprite) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfSprite_getScale(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfSprite_getScale(self._ptr));
}
/// Sets the scale of this sprite
-pub fn setScale(self: Sprite, factor: sf.Vector2f) void {
- sf.c.sfSprite_setScale(self.ptr, factor.toCSFML());
+pub fn setScale(self: *Sprite, factor: sf.Vector2f) void {
+ sf.c.sfSprite_setScale(self._ptr, factor._toCSFML());
}
/// Scales this sprite
-pub fn scale(self: Sprite, factor: sf.Vector2f) void {
- sf.c.sfSprite_scale(self.ptr, factor.toCSFML());
+pub fn scale(self: *Sprite, factor: sf.Vector2f) void {
+ sf.c.sfSprite_scale(self._ptr, factor._toCSFML());
}
/// Gets the origin of this sprite
pub fn getOrigin(self: Sprite) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfSprite_getOrigin(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfSprite_getOrigin(self._ptr));
}
/// Sets the origin of this sprite
-pub fn setOrigin(self: Sprite, origin: sf.Vector2f) void {
- sf.c.sfSprite_setOrigin(self.ptr, origin.toCSFML());
+pub fn setOrigin(self: *Sprite, origin: sf.Vector2f) void {
+ sf.c.sfSprite_setOrigin(self._ptr, origin._toCSFML());
}
/// Gets the rotation of this sprite
pub fn getRotation(self: Sprite) f32 {
- return sf.c.sfSprite_getRotation(self.ptr);
+ return sf.c.sfSprite_getRotation(self._ptr);
}
/// Sets the rotation of this sprite
-pub fn setRotation(self: Sprite, angle: f32) void {
- sf.c.sfSprite_setRotation(self.ptr, angle);
+pub fn setRotation(self: *Sprite, angle: f32) void {
+ sf.c.sfSprite_setRotation(self._ptr, angle);
}
/// Rotates this shape by a given amount
-pub fn rotate(self: Sprite, angle: f32) void {
- sf.c.sfSprite_rotate(self.ptr, angle);
+pub fn rotate(self: *Sprite, angle: f32) void {
+ sf.c.sfSprite_rotate(self._ptr, angle);
}
/// Gets the color of this sprite
pub fn getColor(self: Sprite) sf.Color {
- return sf.Color.fromCSFML(sf.c.sfSprite_getColor(self.ptr));
+ return sf.Color._fromCSFML(sf.c.sfSprite_getColor(self._ptr));
}
/// Sets the color of this sprite
-pub fn setColor(self: Sprite, color: sf.Color) void {
- sf.c.sfSprite_setColor(self.ptr, color.toCSFML());
+pub fn setColor(self: *Sprite, color: sf.Color) void {
+ sf.c.sfSprite_setColor(self._ptr, color._toCSFML());
}
/// Gets the texture of this shape
pub fn getTexture(self: Sprite) ?sf.Texture {
- const t = sf.c.sfSprite_getTexture(self.ptr);
+ const t = sf.c.sfSprite_getTexture(self._ptr);
if (t) |tex| {
- return sf.Texture{ .const_ptr = tex };
+ return sf.Texture{ ._const_ptr = tex };
} else return null;
}
/// Sets this sprite's texture (the sprite will take the texture's dimensions)
-pub fn setTexture(self: Sprite, texture: ?sf.Texture) void {
- var tex = if (texture) |t| t.get() else null;
- sf.c.sfSprite_setTexture(self.ptr, tex, 1);
+pub fn setTexture(self: *Sprite, texture: ?sf.Texture) void {
+ var tex = if (texture) |t| t._get() else null;
+ sf.c.sfSprite_setTexture(self._ptr, tex, 1);
}
/// Gets the sub-rectangle of the texture that the sprite will display
pub fn getTextureRect(self: Sprite) sf.IntRect {
- return sf.IntRect.fromCSFML(sf.c.sfSprite_getTextureRect(self.ptr));
+ return sf.IntRect._fromCSFML(sf.c.sfSprite_getTextureRect(self._ptr));
}
/// Sets the sub-rectangle of the texture that the sprite will display
-pub fn setTextureRect(self: Sprite, rect: sf.IntRect) void {
- sf.c.sfSprite_setTextureRect(self.ptr, rect.toCSFML());
+pub fn setTextureRect(self: *Sprite, rect: sf.IntRect) void {
+ sf.c.sfSprite_setTextureRect(self._ptr, rect._toCSFML());
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfSprite,
+_ptr: *sf.c.sfSprite,
test "sprite: sane getters and setters" {
const tst = @import("std").testing;
diff --git a/src/sfml/graphics/Text.zig b/src/sfml/graphics/Text.zig
index caaefa5..b64a2f4 100644
--- a/src/sfml/graphics/Text.zig
+++ b/src/sfml/graphics/Text.zig
@@ -15,161 +15,165 @@ pub fn create() !Text {
var text = sf.c.sfText_create();
if (text == null)
return sf.Error.nullptrUnknownReason;
- return Text{ .ptr = text.? };
+ return Text{ ._ptr = text.? };
}
/// Inits a text with content
pub fn createWithText(string: [:0]const u8, font: sf.Font, character_size: usize) !Text {
var text = sf.c.sfText_create();
if (text == null)
return sf.Error.nullptrUnknownReason;
- sf.c.sfText_setFont(text, font.ptr);
+ sf.c.sfText_setFont(text, font._ptr);
sf.c.sfText_setCharacterSize(text, @intCast(c_uint, character_size));
sf.c.sfText_setString(text, string);
- return Text{ .ptr = text.? };
+ return Text{ ._ptr = text.? };
}
/// Destroys a text
-pub fn destroy(self: Text) void {
- sf.c.sfText_destroy(self.ptr);
+pub fn destroy(self: *Text) void {
+ sf.c.sfText_destroy(self._ptr);
}
// Draw function
-pub fn sfDraw(self: Text, window: sf.RenderWindow, states: ?*sf.c.sfRenderStates) void {
- sf.c.sfRenderWindow_drawText(window.ptr, self.ptr, states);
+pub fn sfDraw(self: Text, window: anytype, states: ?*sf.c.sfRenderStates) void {
+ switch (@TypeOf(window)) {
+ sf.RenderWindow => sf.c.sfRenderWindow_drawText(window._ptr, self._ptr, states),
+ sf.RenderTexture => sf.c.sfRenderTexture_drawText(window._ptr, self._ptr, states),
+ else => @compileError("window must be a render target"),
+ }
}
// Getters/setters
/// Sets the content of this text
-pub fn setString(self: Text, string: [:0]const u8) void {
- sf.c.sfText_setString(self.ptr, string);
+pub fn setString(self: *Text, string: [:0]const u8) void {
+ sf.c.sfText_setString(self._ptr, string);
}
/// Sets the font of this text
-pub fn setFont(self: Text, font: sf.Font) void {
- sf.c.sfText_setFont(self.ptr, font.ptr);
+pub fn setFont(self: *Text, font: sf.Font) void {
+ sf.c.sfText_setFont(self._ptr, font._ptr);
}
/// Gets the character size of this text
pub fn getCharacterSize(self: Text) usize {
- return @intCast(usize, sf.c.sfText_getCharacterSize(self.ptr));
+ return @intCast(usize, sf.c.sfText_getCharacterSize(self._ptr));
}
/// Sets the character size of this text
-pub fn setCharacterSize(self: Text, character_size: usize) void {
- sf.c.sfText_setCharacterSize(self.ptr, @intCast(c_uint, character_size));
+pub fn setCharacterSize(self: *Text, character_size: usize) void {
+ sf.c.sfText_setCharacterSize(self._ptr, @intCast(c_uint, character_size));
}
/// Gets the fill color of this text
pub fn getFillColor(self: Text) sf.Color {
- return sf.Color.fromCSFML(sf.c.sfText_getFillColor(self.ptr));
+ return sf.Color._fromCSFML(sf.c.sfText_getFillColor(self._ptr));
}
/// Sets the fill color of this text
-pub fn setFillColor(self: Text, color: sf.Color) void {
- sf.c.sfText_setFillColor(self.ptr, color.toCSFML());
+pub fn setFillColor(self: *Text, color: sf.Color) void {
+ sf.c.sfText_setFillColor(self._ptr, color._toCSFML());
}
/// Gets the outline color of this text
pub fn getOutlineColor(self: Text) sf.Color {
- return sf.Color.fromCSFML(sf.c.sfText_getOutlineColor(self.ptr));
+ return sf.Color._fromCSFML(sf.c.sfText_getOutlineColor(self._ptr));
}
/// Sets the outline color of this text
-pub fn setOutlineColor(self: Text, color: sf.Color) void {
- sf.c.sfText_setOutlineColor(self.ptr, color.toCSFML());
+pub fn setOutlineColor(self: *Text, color: sf.Color) void {
+ sf.c.sfText_setOutlineColor(self._ptr, color._toCSFML());
}
/// Gets the outline thickness of this text
pub fn getOutlineThickness(self: Text) f32 {
- return sf.c.sfText_getOutlineThickness(self.ptr);
+ return sf.c.sfText_getOutlineThickness(self._ptr);
}
/// Sets the outline thickness of this text
-pub fn setOutlineThickness(self: Text, thickness: f32) void {
- sf.c.sfText_setOutlineThickness(self.ptr, thickness);
+pub fn setOutlineThickness(self: *Text, thickness: f32) void {
+ sf.c.sfText_setOutlineThickness(self._ptr, thickness);
}
/// Gets the position of this text
pub fn getPosition(self: Text) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfText_getPosition(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfText_getPosition(self._ptr));
}
/// Sets the position of this text
-pub fn setPosition(self: Text, pos: sf.Vector2f) void {
- sf.c.sfText_setPosition(self.ptr, pos.toCSFML());
+pub fn setPosition(self: *Text, pos: sf.Vector2f) void {
+ sf.c.sfText_setPosition(self._ptr, pos._toCSFML());
}
/// Adds the offset to this text
-pub fn move(self: Text, offset: sf.Vector2f) void {
- sf.c.sfText_move(self.ptr, offset.toCSFML());
+pub fn move(self: *Text, offset: sf.Vector2f) void {
+ sf.c.sfText_move(self._ptr, offset._toCSFML());
}
/// Gets the origin of this text
pub fn getOrigin(self: Text) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfText_getOrigin(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfText_getOrigin(self._ptr));
}
/// Sets the origin of this text
-pub fn setOrigin(self: Text, origin: sf.Vector2f) void {
- sf.c.sfText_setOrigin(self.ptr, origin.toCSFML());
+pub fn setOrigin(self: *Text, origin: sf.Vector2f) void {
+ sf.c.sfText_setOrigin(self._ptr, origin._toCSFML());
}
/// Gets the rotation of this text
pub fn getRotation(self: Text) f32 {
- return sf.c.sfText_getRotation(self.ptr);
+ return sf.c.sfText_getRotation(self._ptr);
}
/// Sets the rotation of this text
-pub fn setRotation(self: Text, angle: f32) void {
- sf.c.sfText_setRotation(self.ptr, angle);
+pub fn setRotation(self: *Text, angle: f32) void {
+ sf.c.sfText_setRotation(self._ptr, angle);
}
/// Rotates this text by a given amount
-pub fn rotate(self: Text, angle: f32) void {
- sf.c.sfText_rotate(self.ptr, angle);
+pub fn rotate(self: *Text, angle: f32) void {
+ sf.c.sfText_rotate(self._ptr, angle);
}
/// Gets the scale of this text
pub fn getScale(self: Text) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfText_getScale(self.ptr));
+ return sf.Vector2f._fromCSFML(sf.c.sfText_getScale(self._ptr));
}
/// Sets the scale of this text
-pub fn setScale(self: Text, factor: sf.Vector2f) void {
- sf.c.sfText_setScale(self.ptr, factor.toCSFML());
+pub fn setScale(self: *Text, factor: sf.Vector2f) void {
+ sf.c.sfText_setScale(self._ptr, factor._toCSFML());
}
/// Scales this text
-pub fn scale(self: Text, factor: sf.Vector2f) void {
- sf.c.sfText_scale(self.ptr, factor.toCSFML());
+pub fn scale(self: *Text, factor: sf.Vector2f) void {
+ sf.c.sfText_scale(self._ptr, factor._toCSFML());
}
/// return the position of the index-th character
pub fn findCharacterPos(self: Text, index: usize) sf.Vector2f {
- return sf.Vector2f.fromCSFML(sf.c.sfText_findCharacterPos(self.ptr, index));
+ return sf.Vector2f._fromCSFML(sf.c.sfText_findCharacterPos(self._ptr, index));
}
/// Gets the letter spacing factor
pub fn getLetterSpacing(self: Text) f32 {
- return sf.c.sfText_getLetterSpacing(self.ptr);
+ return sf.c.sfText_getLetterSpacing(self._ptr);
}
/// Sets the letter spacing factor
-pub fn setLetterSpacing(self: Text, spacing_factor: f32) void {
- sf.c.sfText_setLetterSpacing(self.ptr, spacing_factor);
+pub fn setLetterSpacing(self: *Text, spacing_factor: f32) void {
+ sf.c.sfText_setLetterSpacing(self._ptr, spacing_factor);
}
/// Gets the line spacing factor
pub fn getLineSpacing(self: Text) f32 {
- return sf.c.sfText_getLineSpacing(self.ptr);
+ return sf.c.sfText_getLineSpacing(self._ptr);
}
/// Sets the line spacing factor
-pub fn setLineSpacing(self: Text, spacing_factor: f32) void {
- sf.c.sfText_setLineSpacing(self.ptr, spacing_factor);
+pub fn setLineSpacing(self: *Text, spacing_factor: f32) void {
+ sf.c.sfText_setLineSpacing(self._ptr, spacing_factor);
}
/// Gets the local bounding rectangle of the text
pub fn getLocalBounds(self: Text) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfText_getLocalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfText_getLocalBounds(self._ptr));
}
/// Gets the global bounding rectangle of the text
pub fn getGlobalBounds(self: Text) sf.FloatRect {
- return sf.FloatRect.fromCSFML(sf.c.sfText_getGlobalBounds(self.ptr));
+ return sf.FloatRect._fromCSFML(sf.c.sfText_getGlobalBounds(self._ptr));
}
pub const getTransform = @compileError("Function is not implemented yet.");
pub const getInverseTransform = @compileError("Function is not implemented yet.");
/// Pointer to the csfml font
-ptr: *sf.c.sfText,
+_ptr: *sf.c.sfText,
test "text: sane getters and setters" {
const tst = @import("std").testing;
diff --git a/src/sfml/graphics/VertexArray.zig b/src/sfml/graphics/VertexArray.zig
index ea4ccb2..d340600 100644
--- a/src/sfml/graphics/VertexArray.zig
+++ b/src/sfml/graphics/VertexArray.zig
@@ -14,19 +14,23 @@ pub fn createFromSlice(vertex: []const sf.graphics.Vertex, primitive: sf.graphic
sf.c.sfVertexArray_resize(vert, vertex.len);
for (vertex) |v, i|
sf.c.sfVertexArray_getVertex(vert, i).* = @bitCast(sf.c.sfVertex, v);
- return VertexArray{ .ptr = vert };
+ return VertexArray{ ._ptr = vert };
} else return sf.Error.nullptrUnknownReason;
}
/// Destroys a vertex array
-pub fn destroy(self: VertexArray) void {
- sf.c.sfVertexArray_destroy(self.ptr);
+pub fn destroy(self: *VertexArray) void {
+ sf.c.sfVertexArray_destroy(self._ptr);
}
// Draw function
-pub fn sfDraw(self: VertexArray, window: sf.graphics.RenderWindow, states: ?*sf.c.sfRenderStates) void {
- sf.c.sfRenderWindow_drawVertexArray(window.ptr, self.ptr, states);
+pub fn sfDraw(self: VertexArray, window: anytype, states: ?*sf.c.sfRenderStates) void {
+ switch (@TypeOf(window)) {
+ sf.graphics.RenderWindow => sf.c.sfRenderWindow_drawVertexArray(window._ptr, self._ptr, states),
+ sf.graphics.RenderTexture => sf.c.sfRenderTexture_drawVertexArray(window._ptr, self._ptr, states),
+ else => @compileError("window must be a render target"),
+ }
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfVertexArray,
+_ptr: *sf.c.sfVertexArray,
diff --git a/src/sfml/graphics/View.zig b/src/sfml/graphics/View.zig
index 6ce9610..130bb66 100644
--- a/src/sfml/graphics/View.zig
+++ b/src/sfml/graphics/View.zig
@@ -20,22 +20,22 @@ pub fn fromRect(rect: sf.FloatRect) View {
/// Creates a view from a CSFML object
/// This is mainly for the inner workings of this wrapper
-pub fn fromCSFML(view: *const sf.c.sfView) View {
+pub fn _fromCSFML(view: *const sf.c.sfView) View {
var ret: View = undefined;
- ret.center = sf.Vector2f.fromCSFML(sf.c.sfView_getCenter(view));
- ret.size = sf.Vector2f.fromCSFML(sf.c.sfView_getSize(view));
- ret.viewport = sf.FloatRect.fromCSFML(sf.c.sfView_getViewport(view));
+ ret.center = sf.Vector2f._fromCSFML(sf.c.sfView_getCenter(view));
+ ret.size = sf.Vector2f._fromCSFML(sf.c.sfView_getSize(view));
+ ret.viewport = sf.FloatRect._fromCSFML(sf.c.sfView_getViewport(view));
return ret;
}
/// Creates a CSFML view from this view
/// This is mainly for the inner workings of this wrapper
/// The resulting view must be destroyed!
-pub fn toCSFML(self: View) *sf.c.sfView {
+pub fn _toCSFML(self: View) *sf.c.sfView {
var view = sf.c.sfView_create().?;
- sf.c.sfView_setCenter(view, self.center.toCSFML());
- sf.c.sfView_setSize(view, self.size.toCSFML());
- sf.c.sfView_setViewport(view, self.viewport.toCSFML());
+ sf.c.sfView_setCenter(view, self.center._toCSFML());
+ sf.c.sfView_setSize(view, self.size._toCSFML());
+ sf.c.sfView_setViewport(view, self.viewport._toCSFML());
return view;
}
@@ -74,13 +74,13 @@ test "view: from rect" {
// Testing if the view from rect initialization works
var rect = sf.FloatRect.init(10, -15, 700, 600);
- var view = sf.c.sfView_createFromRect(rect.toCSFML());
+ var view = sf.c.sfView_createFromRect(rect._toCSFML());
defer sf.c.sfView_destroy(view);
var view2 = View.fromRect(rect);
- var center = sf.Vector2f.fromCSFML(sf.c.sfView_getCenter(view));
- var size = sf.Vector2f.fromCSFML(sf.c.sfView_getSize(view));
+ var center = sf.Vector2f._fromCSFML(sf.c.sfView_getCenter(view));
+ var size = sf.Vector2f._fromCSFML(sf.c.sfView_getSize(view));
try tst.expectApproxEqAbs(center.x, view2.center.x, 0.00001);
try tst.expectApproxEqAbs(center.y, view2.center.y, 0.00001);
diff --git a/src/sfml/graphics/color.zig b/src/sfml/graphics/color.zig
index 5555c22..bea5666 100644
--- a/src/sfml/graphics/color.zig
+++ b/src/sfml/graphics/color.zig
@@ -6,13 +6,13 @@ const math = @import("std").math;
pub const Color = packed struct {
/// Converts a color from a csfml object
/// For inner workings
- pub fn fromCSFML(col: sf.c.sfColor) Color {
+ pub fn _fromCSFML(col: sf.c.sfColor) Color {
return @bitCast(Color, col);
}
/// Converts this color to a csfml one
/// For inner workings
- pub fn toCSFML(self: Color) sf.c.sfColor {
+ pub fn _toCSFML(self: Color) sf.c.sfColor {
return @bitCast(sf.c.sfColor, self);
}
@@ -55,7 +55,7 @@ pub const Color = packed struct {
}
/// Creates a color with rgba floats from 0 to 1
- pub fn fromFloats(red: f32, green: f32, blue: f32, alpha: f32) Color {
+ fn fromFloats(red: f32, green: f32, blue: f32, alpha: f32) Color {
return Color{
.r = @floatToInt(u8, math.clamp(red, 0.0, 1.0) * 255.0),
.g = @floatToInt(u8, math.clamp(green, 0.0, 1.0) * 255.0),
@@ -97,6 +97,25 @@ pub const Color = packed struct {
};
}
+ /// Get a GLSL float vector for this color (for shaders)
+ pub fn toFVec4(self: Color) sf.graphics.glsl.FVec4 {
+ return .{
+ .x = @intToFloat(f32, self.r) / 255.0,
+ .y = @intToFloat(f32, self.g) / 255.0,
+ .z = @intToFloat(f32, self.b) / 255.0,
+ .w = @intToFloat(f32, self.a) / 255.0
+ };
+ }
+ /// Get a GLSL int vector for this color (for shaders)
+ pub fn toIVec4(self: Color) sf.graphcis.glsl.IVec4 {
+ return .{
+ .x = self.r,
+ .y = self.g,
+ .z = self.b,
+ .w = self.a
+ };
+ }
+
// Colors
/// Black color
pub const Black = Color.fromRGB(0, 0, 0);
@@ -138,7 +157,7 @@ test "color: conversions" {
var csfml_col = sf.c.sfColor_fromInteger(@as(c_uint, code));
- try tst.expectEqual(Color.fromCSFML(csfml_col), col);
+ try tst.expectEqual(Color._fromCSFML(csfml_col), col);
}
test "color: hsv to rgb" {
@@ -153,14 +172,14 @@ test "color: sane from/to CSFML color" {
const tst = @import("std").testing;
const col = Color.fromRGBA(5, 12, 28, 127);
- const ccol = col.toCSFML();
+ const ccol = col._toCSFML();
try tst.expectEqual(col.r, ccol.r);
try tst.expectEqual(col.g, ccol.g);
try tst.expectEqual(col.b, ccol.b);
try tst.expectEqual(col.a, ccol.a);
- const col2 = Color.fromCSFML(ccol);
+ const col2 = Color._fromCSFML(ccol);
try tst.expectEqual(col, col2);
}
diff --git a/src/sfml/graphics/glsl.zig b/src/sfml/graphics/glsl.zig
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/src/sfml/graphics/glsl.zig
@@ -0,0 +1,16 @@
+const sf = @import("../sfml.zig").system;
+
+pub const FVec2 = sf.Vector2(f32);
+pub const FVec3 = sf.Vector3(f32);
+pub const FVec4 = sf.Vector4(f32);
+
+pub const IVec2 = sf.Vector2(c_int);
+pub const IVec3 = sf.Vector3(c_int);
+pub const IVec4 = sf.Vector4(c_int);
+
+pub const BVec2 = sf.Vector2(bool);
+pub const BVec3 = sf.Vector3(bool);
+pub const BVec4 = sf.Vector4(bool);
+
+pub const Mat3 = [3 * 3]f32;
+pub const Mat4 = [4 * 4]f32; \ No newline at end of file
diff --git a/src/sfml/graphics/rect.zig b/src/sfml/graphics/rect.zig
index ace7397..2d7d0ef 100644
--- a/src/sfml/graphics/rect.zig
+++ b/src/sfml/graphics/rect.zig
@@ -29,14 +29,14 @@ pub fn Rect(comptime T: type) type {
/// Makes a CSFML rect with this rect (only if the corresponding type exists)
/// This is mainly for the inner workings of this wrapper
- pub fn toCSFML(self: Self) CsfmlEquivalent {
+ pub fn _toCSFML(self: Self) CsfmlEquivalent {
if (CsfmlEquivalent == void) @compileError("This rectangle type doesn't have a CSFML equivalent.");
return @bitCast(CsfmlEquivalent, self);
}
/// Creates a rect from a CSFML one (only if the corresponding type exists)
/// This is mainly for the inner workings of this wrapper
- pub fn fromCSFML(rect: CsfmlEquivalent) Self {
+ pub fn _fromCSFML(rect: CsfmlEquivalent) Self {
if (CsfmlEquivalent == void) @compileError("This rectangle type doesn't have a CSFML equivalent.");
return @bitCast(Self, rect);
}
@@ -124,11 +124,11 @@ test "rect: intersect" {
var inter1: sf.c.sfIntRect = undefined;
var inter2: sf.c.sfIntRect = undefined;
- try tst.expectEqual(sf.c.sfIntRect_intersects(&r1.toCSFML(), &r2.toCSFML(), &inter1), 1);
- try tst.expectEqual(sf.c.sfIntRect_intersects(&r1.toCSFML(), &r3.toCSFML(), &inter2), 1);
+ try tst.expectEqual(sf.c.sfIntRect_intersects(&r1._toCSFML(), &r2._toCSFML(), &inter1), 1);
+ try tst.expectEqual(sf.c.sfIntRect_intersects(&r1._toCSFML(), &r3._toCSFML(), &inter2), 1);
- try tst.expectEqual(Rect(c_int).fromCSFML(inter1), r1.intersects(r2).?);
- try tst.expectEqual(Rect(c_int).fromCSFML(inter2), r1.intersects(r3).?);
+ try tst.expectEqual(Rect(c_int)._fromCSFML(inter1), r1.intersects(r2).?);
+ try tst.expectEqual(Rect(c_int)._fromCSFML(inter2), r1.intersects(r3).?);
}
test "rect: contains" {
@@ -147,14 +147,14 @@ test "rect: sane from/to CSFML rect" {
inline for ([_]type{ c_int, f32 }) |T| {
const rect = Rect(T).init(1, 3, 5, 10);
- const crect = rect.toCSFML();
+ const crect = rect._toCSFML();
try tst.expectEqual(rect.left, crect.left);
try tst.expectEqual(rect.top, crect.top);
try tst.expectEqual(rect.width, crect.width);
try tst.expectEqual(rect.height, crect.height);
- const rect2 = Rect(T).fromCSFML(crect);
+ const rect2 = Rect(T)._fromCSFML(crect);
try tst.expectEqual(rect, rect2);
}
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());
diff --git a/src/sfml/sfml.zig b/src/sfml/sfml.zig
index da1dc4b..2cf51f2 100644
--- a/src/sfml/sfml.zig
+++ b/src/sfml/sfml.zig
@@ -5,11 +5,15 @@ pub const c = @import("sfml_import.zig").c;
pub const Error = @import("sfml_errors.zig").Error;
pub const system = struct {
- pub const Vector2 = @import("system/vector.zig").Vector2;
+ const vector = @import("system/vector.zig");
+ pub const Vector2 = vector.Vector2;
+ pub const Vector3 = vector.Vector3;
+ pub const Vector4 = vector.Vector4;
pub const Vector2i = Vector2(c_int);
pub const Vector2u = Vector2(c_uint);
pub const Vector2f = Vector2(f32);
- pub const Vector3f = @import("system/vector.zig").Vector3f;
+ pub const Vector3f = Vector3(f32);
+
pub const Time = @import("system/Time.zig");
pub const Clock = @import("system/Clock.zig");
};
@@ -17,27 +21,42 @@ pub const system = struct {
pub const window = struct {
pub const Event = @import("window/event.zig").Event;
pub const Style = @import("window/Style.zig");
+ pub const WindowHandle = c.sfWindowHandle;
+ pub const ContextSettings = @import("window/context_settings.zig").ContextSettings;
pub const keyboard = @import("window/keyboard.zig");
pub const mouse = @import("window/mouse.zig");
};
pub const graphics = struct {
pub const Color = @import("graphics/color.zig").Color;
+
pub const RenderWindow = @import("graphics/RenderWindow.zig");
+ pub const RenderTexture = @import("graphics/RenderTexture.zig");
+
+ pub const View = @import("graphics/View.zig");
+
pub const Image = @import("graphics/Image.zig");
pub const Texture = @import("graphics/texture.zig").Texture;
+
pub const Sprite = @import("graphics/Sprite.zig");
pub const CircleShape = @import("graphics/CircleShape.zig");
pub const RectangleShape = @import("graphics/RectangleShape.zig");
+
+ pub const Vertex = @import("graphics/vertex.zig").Vertex;
+ pub const VertexArray = @import("graphics/VertexArray.zig");
+ pub const PrimitiveType = @import("graphics/primitive_type.zig").PrimitiveType;
+
pub const Rect = @import("graphics/rect.zig").Rect;
pub const IntRect = Rect(c_int);
pub const FloatRect = Rect(f32);
- pub const View = @import("graphics/View.zig");
+
pub const Font = @import("graphics/Font.zig");
pub const Text = @import("graphics/Text.zig");
- pub const Vertex = @import("graphics/vertex.zig").Vertex;
- pub const VertexArray = @import("graphics/VertexArray.zig");
- pub const PrimitiveType = @import("graphics/primitive_type.zig").PrimitiveType;
+
+ pub const glsl = @import("graphics/glsl.zig");
+ pub const Shader = @import("graphics/Shader.zig");
+ pub const BlendMode = @import("graphics/BlendMode.zig");
+ pub const RenderStates = @import("graphics/RenderStates.zig");
};
pub const audio = struct {
@@ -48,15 +67,11 @@ pub const audio = struct {
pub const network = @compileError("network module: to be implemented one day");
+pub const VertexBuffer = @compileError("VertexArray not available yet");
+pub const Transform = @compileError("Transform not available yet");
+
pub const touch = @compileError("touch not available yet");
pub const joystick = @compileError("Joystick not available yet");
pub const sensor = @compileError("Sensor not available yet");
pub const clipboard = @compileError("Clipboard not available yet");
pub const Cursor = @compileError("Cursor not available yet");
-
-pub const VertexBuffer = @compileError("VertexArray not available yet");
-pub const BlendMode = @compileError("BlendMode not available yet");
-pub const RenderStates = @compileError("RenderStates not available yet");
-pub const RenderTexture = @compileError("RenderTexture not available yet");
-pub const Shader = @compileError("Shader not available yet");
-pub const Transform = @compileError("Transform not available yet");
diff --git a/src/sfml/system/Clock.zig b/src/sfml/system/Clock.zig
index d8b174e..74b73ab 100644
--- a/src/sfml/system/Clock.zig
+++ b/src/sfml/system/Clock.zig
@@ -17,29 +17,29 @@ pub fn create() !Clock {
if (clock == null)
return sf.Error.nullptrUnknownReason;
- return Clock{ .ptr = clock.? };
+ return Clock{ ._ptr = clock.? };
}
/// Destroys this clock
-pub fn destroy(self: Clock) void {
- sf.c.sfClock_destroy(self.ptr);
+pub fn destroy(self: *Clock) void {
+ sf.c.sfClock_destroy(self._ptr);
}
// Clock control
/// Gets the elapsed seconds
pub fn getElapsedTime(self: Clock) sf.Time {
- var time = sf.c.sfClock_getElapsedTime(self.ptr).microseconds;
+ var time = sf.c.sfClock_getElapsedTime(self._ptr).microseconds;
return sf.Time{ .us = time };
}
/// Gets the elapsed seconds and restarts the timer
-pub fn restart(self: Clock) sf.Time {
- var time = sf.c.sfClock_restart(self.ptr).microseconds;
+pub fn restart(self: *Clock) sf.Time {
+ var time = sf.c.sfClock_restart(self._ptr).microseconds;
return sf.Time{ .us = time };
}
/// Pointer to the csfml structure
-ptr: *sf.c.sfClock,
+_ptr: *sf.c.sfClock,
test "clock: sleep test" {
const tst = @import("std").testing;
diff --git a/src/sfml/system/Time.zig b/src/sfml/system/Time.zig
index 2e8a34c..ae5152a 100644
--- a/src/sfml/system/Time.zig
+++ b/src/sfml/system/Time.zig
@@ -8,13 +8,13 @@ const Time = @This();
/// Converts a time from a csfml object
/// For inner workings
-pub fn fromCSFML(time: sf.c.sfTime) Time {
+pub fn _fromCSFML(time: sf.c.sfTime) Time {
return Time{ .us = time.microseconds };
}
/// Converts a time to a csfml object
/// For inner workings
-pub fn toCSFML(self: Time) sf.c.sfTime {
+pub fn _toCSFML(self: Time) sf.c.sfTime {
return sf.c.sfTime{ .microseconds = self.us };
}
@@ -54,7 +54,7 @@ pub fn asSeconds(self: Time) f32 {
/// Sleeps the amount of time specified
pub fn sleep(time: Time) void {
- sf.c.sfSleep(time.toCSFML());
+ sf.c.sfSleep(time._toCSFML());
}
/// A time of zero
@@ -75,19 +75,19 @@ pub const TimeSpan = struct {
/// Converts a timespan from a csfml object
/// For inner workings
- pub fn fromCSFML(span: sf.c.sfTimeSpan) TimeSpan {
+ pub fn _fromCSFML(span: sf.c.sfTimeSpan) TimeSpan {
return TimeSpan{
- .offset = Time.fromCSFML(span.offset),
- .length = Time.fromCSFML(span.length),
+ .offset = Time._fromCSFML(span.offset),
+ .length = Time._fromCSFML(span.length),
};
}
/// Converts a timespan to a csfml object
/// For inner workings
- pub fn toCSFML(self: TimeSpan) sf.c.sfTimeSpan {
+ pub fn _toCSFML(self: TimeSpan) sf.c.sfTimeSpan {
return sf.c.sfTimeSpan{
- .offset = self.offset.toCSFML(),
- .length = self.length.toCSFML(),
+ .offset = self.offset._toCSFML(),
+ .length = self.length._toCSFML(),
};
}
diff --git a/src/sfml/system/vector.zig b/src/sfml/system/vector.zig
index 7e3e500..3190d59 100644
--- a/src/sfml/system/vector.zig
+++ b/src/sfml/system/vector.zig
@@ -2,6 +2,7 @@
const sf = @import("../sfml_import.zig");
+/// Template for a 2 dimensional vector
pub fn Vector2(comptime T: type) type {
return packed struct {
const Self = @This();
@@ -16,14 +17,14 @@ pub fn Vector2(comptime T: type) type {
/// Makes a CSFML vector with this vector (only if the corresponding type exists)
/// This is mainly for the inner workings of this wrapper
- pub fn toCSFML(self: Self) CsfmlEquivalent {
+ pub fn _toCSFML(self: Self) CsfmlEquivalent {
if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent.");
return @bitCast(CsfmlEquivalent, self);
}
/// Creates a vector from a CSFML one (only if the corresponding type exists)
/// This is mainly for the inner workings of this wrapper
- pub fn fromCSFML(vec: CsfmlEquivalent) Self {
+ pub fn _fromCSFML(vec: CsfmlEquivalent) Self {
if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent.");
return @bitCast(Self, vec);
}
@@ -50,28 +51,64 @@ pub fn Vector2(comptime T: type) type {
};
}
-pub const Vector3f = struct {
- const Self = @This();
+/// Template for a 3 dimensional vector
+pub fn Vector3(comptime T: type) type {
+ return packed struct {
+ const Self = @This();
- /// Makes a CSFML vector with this vector (only if the corresponding type exists)
- /// This is mainly for the inner workings of this wrapper
- pub fn toCSFML(self: Self) sf.c.sfVector3f {
- return @bitCast(sf.c.sfVector3f, self);
- }
+ /// Makes a CSFML vector with this vector (only if the corresponding type exists)
+ /// This is mainly for the inner workings of this wrapper
+ pub fn _toCSFML(self: Self) sf.c.sfVector3f {
+ if (T != f32) @compileError("This vector type doesn't have a CSFML equivalent.");
+ return @bitCast(sf.c.sfVector3f, self);
+ }
- /// Creates a vector from a CSFML one (only if the corresponding type exists)
- /// This is mainly for the inner workings of this wrapper
- pub fn fromCSFML(vec: sf.c.sfVector3f) Self {
- return @bitCast(Self, vec);
- }
+ /// Creates a vector from a CSFML one (only if the corresponding type exists)
+ /// This is mainly for the inner workings of this wrapper
+ pub fn _fromCSFML(vec: sf.c.sfVector3f) Self {
+ if (T != f32) @compileError("This vector type doesn't have a CSFML equivalent.");
+ return @bitCast(Self, vec);
+ }
+
+ /// Adds two vectors
+ pub fn add(self: Self, other: Self) Self {
+ return Self{ .x = self.x + other.x, .y = self.y + other.y, .z = self.z + other.z };
+ }
+
+ /// Substracts two vectors
+ pub fn substract(self: Self, other: Self) Self {
+ return Self{ .x = self.x - other.x, .y = self.y - other.y, .z = self.z - other.z };
+ }
+
+ /// Scales a vector
+ pub fn scale(self: Self, scalar: T) Self {
+ return Self{ .x = self.x * scalar, .y = self.y * scalar, .z = self.z * scalar };
+ }
+
+ /// x component of the vector
+ x: T,
+ /// y component of the vector
+ y: T,
+ /// z component of the vector
+ z: T
+ };
+}
- /// x component of the vector
- x: f32,
- /// y component of the vector
- y: f32,
- /// z component of the vector
- z: f32,
-};
+/// Template for a 4 dimensional vector
+/// SFML doesn't really have this but as shaders use such vectors it can be here anyways
+pub fn Vector4(comptime T: type) type {
+ return packed struct {
+ const Self = @This();
+ /// x component of the vector
+ x: T,
+ /// y component of the vector
+ y: T,
+ /// z component of the vector
+ z: T,
+ /// w component of the vector
+ w: T
+ };
+}
test "vector: sane from/to CSFML vectors" {
const tst = @import("std").testing;
@@ -79,25 +116,25 @@ test "vector: sane from/to CSFML vectors" {
inline for ([_]type{ c_int, c_uint, f32 }) |T| {
const VecT = Vector2(T);
const vec = VecT{ .x = 1, .y = 3 };
- const cvec = vec.toCSFML();
+ const cvec = vec._toCSFML();
try tst.expectEqual(vec.x, cvec.x);
try tst.expectEqual(vec.y, cvec.y);
- const vec2 = VecT.fromCSFML(cvec);
+ const vec2 = VecT._fromCSFML(cvec);
try tst.expectEqual(vec, vec2);
}
{
- const vec = Vector3f{ .x = 1, .y = 3.5, .z = -12 };
- const cvec = vec.toCSFML();
+ const vec = Vector3(f32){ .x = 1, .y = 3.5, .z = -12 };
+ const cvec = vec._toCSFML();
try tst.expectEqual(vec.x, cvec.x);
try tst.expectEqual(vec.y, cvec.y);
try tst.expectEqual(vec.z, cvec.z);
- const vec2 = Vector3f.fromCSFML(cvec);
+ const vec2 = Vector3(f32)._fromCSFML(cvec);
try tst.expectEqual(vec, vec2);
}
diff --git a/src/sfml/window/context_settings.zig b/src/sfml/window/context_settings.zig
new file mode 100644
index 0000000..19b8f03
--- /dev/null
+++ b/src/sfml/window/context_settings.zig
@@ -0,0 +1,28 @@
+const sf = @import("../sfml.zig");
+
+pub const ContextSettings = packed struct {
+ const PaddingType = @import("std").meta.Int(.unsigned, @bitSizeOf(c_int) - @bitSizeOf(bool));
+
+ depth_bits: c_uint = 0,
+ stencil_bits: c_uint = 0,
+ antialiasing_level: c_uint = 0,
+ major_version: c_uint = 1,
+ minor_version: c_uint = 1,
+ attribute_flags: u32 = 0,
+ srgb_capable: bool = false,
+ _padding: PaddingType = 0,
+
+ pub const Attribute = struct {
+ pub const default: u32 = 0;
+ pub const core: u32 = 1;
+ pub const debug: u32 = 4;
+ };
+
+ pub fn _toCSFML(self: ContextSettings) sf.c.sfContextSettings {
+ return @bitCast(sf.c.sfContextSettings, self);
+ }
+
+ pub fn _fromCSFML(context_settings: sf.c.sfContextSettings) ContextSettings {
+ return @bitCast(ContextSettings, context_settings);
+ }
+}; \ No newline at end of file
diff --git a/src/sfml/window/event.zig b/src/sfml/window/event.zig
index c9694f1..a73c192 100644
--- a/src/sfml/window/event.zig
+++ b/src/sfml/window/event.zig
@@ -35,7 +35,7 @@ pub const Event = union(Event.Type) {
// Big oof
/// Creates this event from a csfml one
- pub fn fromCSFML(event: sf.c.sfEvent) Self {
+ pub fn _fromCSFML(event: sf.c.sfEvent) Self {
return switch (event.type) {
sf.c.sfEvtClosed => .{ .closed = {} },
sf.c.sfEvtResized => .{ .resized = .{ .size = .{ .x = event.size.width, .y = event.size.height } } },
diff --git a/src/sfml/window/mouse.zig b/src/sfml/window/mouse.zig
index c788324..b60ff00 100644
--- a/src/sfml/window/mouse.zig
+++ b/src/sfml/window/mouse.zig
@@ -15,12 +15,12 @@ pub fn isButtonPressed(button: Button) bool {
/// Gets the position of the mouse cursor relative to the window passed or desktop
pub fn getPosition(window: ?sf.graphics.RenderWindow) sf.system.Vector2i {
if (window) |w| {
- return sf.system.Vector2i.fromCSFML(sf.c.sfMouse_getPosition(@ptrCast(*sf.c.sfWindow, w.ptr)));
- } else return sf.system.Vector2i.fromCSFML(sf.c.sfMouse_getPosition(null));
+ return sf.system.Vector2i._fromCSFML(sf.c.sfMouse_getPosition(@ptrCast(*sf.c.sfWindow, w._ptr)));
+ } else return sf.system.Vector2i._fromCSFML(sf.c.sfMouse_getPosition(null));
}
/// Set the position of the mouse cursor relative to the window passed or desktop
pub fn setPosition(position: sf.system.Vector2i, window: ?sf.graphics.RenderWindow) void {
if (window) |w| {
- sf.c.sfMouse_setPosition(position.toCSFML(), @ptrCast(*sf.c.sfWindow, w.ptr));
- } else sf.c.sfMouse_setPosition(position.toCSFML(), null);
+ sf.c.sfMouse_setPosition(position._toCSFML(), @ptrCast(*sf.c.sfWindow, w._ptr));
+ } else sf.c.sfMouse_setPosition(position._toCSFML(), null);
}