gosu 2.0.0.pre6 → 2.0.0.pre7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL_assert.h +2 -0
- data/dependencies/SDL/include/SDL_hints.h +11 -0
- data/dependencies/SDL/include/SDL_render.h +1 -1
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_version.h +1 -1
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/ext/gosu-ffi/gosu-ffi.def +1 -0
- data/ffi/Gosu_FFI_internal.h +2 -2
- data/ffi/Gosu_Image.cpp +26 -14
- data/ffi/Gosu_Image.h +8 -2
- data/include/Gosu/Image.hpp +1 -1
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/ffi.rb +2 -1
- data/lib/gosu/image.rb +31 -19
- data/lib64/SDL2.dll +0 -0
- data/src/BinPacker.cpp +1 -1
- data/src/ClipRectStack.cpp +38 -0
- data/src/ClipRectStack.hpp +17 -83
- data/src/DrawOp.hpp +0 -5
- data/src/DrawOpQueue.hpp +24 -30
- data/src/GosuGLView.cpp +1 -7
- data/src/Graphics.cpp +8 -5
- data/src/GraphicsImpl.hpp +0 -23
- data/src/RenderState.hpp +25 -38
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de41d69b5cfd72bea1af496ef95e39cf80d89268d640548c73aeb421d9b05428
|
4
|
+
data.tar.gz: d2196d8e0a7f65e9c0d77fdfe5c56026570a807a15b4c46a7066c16bc296fcb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c809f58dd0e31ec02bd3c596e2dab1de6795d70eee53aa5226389815f8b37089289055222ed3f1a4eed3a1f2e4952e452a42042a14385e97737007adbf1dff78
|
7
|
+
data.tar.gz: 744c254d6ad35c6ceb9acbda0ac26d1d6f4531df389b38c13afea1775bf271be65941076fdc40d707c55a1c1a8a6ac3ae6ed95231c0a7de5bd11dc041bc0cce8
|
@@ -55,6 +55,8 @@ assert can have unique static variables associated with it.
|
|
55
55
|
#define SDL_TriggerBreakpoint() __builtin_debugtrap()
|
56
56
|
#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) )
|
57
57
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
|
58
|
+
#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
|
59
|
+
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
|
58
60
|
#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */
|
59
61
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" )
|
60
62
|
#elif defined(__APPLE__) && defined(__arm__)
|
@@ -1474,6 +1474,17 @@ extern "C" {
|
|
1474
1474
|
*/
|
1475
1475
|
#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
|
1476
1476
|
|
1477
|
+
/**
|
1478
|
+
* \brief A variable controlling whether the Metal render driver select low power device over default one
|
1479
|
+
*
|
1480
|
+
* This variable can be set to the following values:
|
1481
|
+
* "0" - Use the prefered OS device
|
1482
|
+
* "1" - Select a low power one
|
1483
|
+
*
|
1484
|
+
* By default the prefered OS device is used.
|
1485
|
+
*/
|
1486
|
+
#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE"
|
1487
|
+
|
1477
1488
|
/**
|
1478
1489
|
* \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS
|
1479
1490
|
*
|
@@ -1890,7 +1890,7 @@ extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
|
|
1890
1890
|
* Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give
|
1891
1891
|
* SDL a drawable to render to, which might happen if the window is
|
1892
1892
|
* hidden/minimized/offscreen. This doesn't apply to command encoders for
|
1893
|
-
* render targets, just the window's
|
1893
|
+
* render targets, just the window's backbuffer. Check your return values!
|
1894
1894
|
*
|
1895
1895
|
* \param renderer The renderer to query
|
1896
1896
|
* \returns an `id<MTLRenderCommandEncoder>` on success, or NULL if the
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* Generated by updaterev.sh, do not edit */
|
2
2
|
#ifdef SDL_VENDOR_INFO
|
3
|
-
#define SDL_REVISION "SDL-release-2.28.
|
3
|
+
#define SDL_REVISION "SDL-release-2.28.3-0-g8a5ba43d0 (" SDL_VENDOR_INFO ")"
|
4
4
|
#else
|
5
|
-
#define SDL_REVISION "SDL-release-2.28.
|
5
|
+
#define SDL_REVISION "SDL-release-2.28.3-0-g8a5ba43d0"
|
6
6
|
#endif
|
7
7
|
#define SDL_REVISION_NUMBER 0
|
Binary file
|
Binary file
|
data/ext/gosu-ffi/gosu-ffi.def
CHANGED
data/ffi/Gosu_FFI_internal.h
CHANGED
@@ -26,7 +26,7 @@ auto Gosu_translate_exceptions(Functor functor)
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
|
29
|
-
// C-compatible wrapper structs for Gosu classes
|
29
|
+
// C-compatible wrapper structs for Gosu classes. (No inheritance because of missing virtual dtors.)
|
30
30
|
|
31
31
|
struct Gosu_Channel
|
32
32
|
{
|
@@ -48,7 +48,7 @@ struct Gosu_Sample
|
|
48
48
|
Gosu::Sample sample;
|
49
49
|
};
|
50
50
|
|
51
|
-
// Use inheritance where composition is not feasible
|
51
|
+
// Use inheritance where composition is not feasible (because we want to compare pointers).
|
52
52
|
|
53
53
|
struct Gosu_Song : Gosu::Song
|
54
54
|
{
|
data/ffi/Gosu_Image.cpp
CHANGED
@@ -2,9 +2,18 @@
|
|
2
2
|
#include <cstring> // for std::memcpy
|
3
3
|
|
4
4
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create(const char* filename, unsigned image_flags)
|
5
|
+
{
|
6
|
+
return Gosu_translate_exceptions([=] { //
|
7
|
+
return new Gosu_Image { Gosu::Image(filename, image_flags) };
|
8
|
+
});
|
9
|
+
}
|
10
|
+
|
11
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_rect(const char* filename, //
|
12
|
+
int x, int y, int width, int height,
|
13
|
+
unsigned image_flags)
|
5
14
|
{
|
6
15
|
return Gosu_translate_exceptions([=] {
|
7
|
-
return new Gosu_Image{Gosu::Image
|
16
|
+
return new Gosu_Image { Gosu::Image(filename, { x, y, width, height }, image_flags) };
|
8
17
|
});
|
9
18
|
}
|
10
19
|
|
@@ -32,32 +41,35 @@ GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_text(const char* text, const cha
|
|
32
41
|
});
|
33
42
|
}
|
34
43
|
|
35
|
-
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob,
|
36
|
-
int rows,
|
44
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob, size_t byte_count, //
|
45
|
+
int columns, int rows, //
|
46
|
+
int x, int y, int width, int height,
|
47
|
+
unsigned image_flags)
|
37
48
|
{
|
38
49
|
return Gosu_translate_exceptions([=] {
|
39
|
-
|
40
|
-
Gosu::Bitmap bitmap
|
50
|
+
const int pixels = columns * rows * 4;
|
51
|
+
Gosu::Bitmap bitmap;
|
41
52
|
|
42
|
-
if (byte_count ==
|
53
|
+
if (byte_count == pixels) {
|
43
54
|
// 32 bit per pixel, assume R8G8B8A8
|
44
|
-
|
55
|
+
bitmap = Gosu::Bitmap(columns, rows, Gosu::Buffer(blob, byte_count, nullptr));
|
45
56
|
}
|
46
|
-
else if (byte_count ==
|
47
|
-
|
57
|
+
else if (byte_count == pixels * 4UL * sizeof(float)) {
|
58
|
+
bitmap.resize(columns, rows);
|
59
|
+
// 128 bit per channel, assume float/float/float/float RGBA - for Texplay compatibility.
|
48
60
|
const float* in = static_cast<const float*>(blob);
|
49
61
|
Gosu::Color::Channel* out = reinterpret_cast<Gosu::Color::Channel*>(bitmap.data());
|
50
|
-
for (std::size_t i = 0; i <
|
62
|
+
for (std::size_t i = 0; i < pixels; ++i) {
|
51
63
|
out[i] = static_cast<Gosu::Color::Channel>(in[i] * 255);
|
52
64
|
}
|
53
65
|
}
|
54
66
|
else {
|
55
|
-
throw std::invalid_argument
|
56
|
-
"for image of size " + std::to_string(columns) + "x"
|
57
|
-
std::to_string(rows)
|
67
|
+
throw std::invalid_argument("Invalid byte_count " + std::to_string(byte_count)
|
68
|
+
+ " for image of size " + std::to_string(columns) + "x"
|
69
|
+
+ std::to_string(rows));
|
58
70
|
}
|
59
71
|
|
60
|
-
return new Gosu_Image{Gosu::Image
|
72
|
+
return new Gosu_Image { Gosu::Image(bitmap, { x, y, width, height }, image_flags) };
|
61
73
|
});
|
62
74
|
}
|
63
75
|
|
data/ffi/Gosu_Image.h
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "Gosu_FFI.h"
|
4
|
+
#include <stddef.h> // for size_t
|
4
5
|
#include <stdint.h>
|
5
6
|
|
6
7
|
typedef struct Gosu_Image Gosu_Image;
|
@@ -13,8 +14,13 @@ typedef struct Gosu_GLTexInfo
|
|
13
14
|
|
14
15
|
// Constructor
|
15
16
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create(const char* filename, unsigned image_flags);
|
16
|
-
GOSU_FFI_API Gosu_Image*
|
17
|
-
|
17
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_rect(const char* filename, //
|
18
|
+
int x, int y, int width, int height,
|
19
|
+
unsigned image_flags);
|
20
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob, size_t byte_count, //
|
21
|
+
int columns, int rows, //
|
22
|
+
int x, int y, int width, int height,
|
23
|
+
unsigned image_flags);
|
18
24
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_markup(const char* markup, const char* font,
|
19
25
|
double font_height, int width,
|
20
26
|
double spacing, unsigned align,
|
data/include/Gosu/Image.hpp
CHANGED
@@ -24,7 +24,7 @@ namespace Gosu
|
|
24
24
|
/// For more flexibility, use the corresponding constructor that uses a Bitmap object.
|
25
25
|
explicit Image(const std::string& filename, unsigned image_flags = IF_SMOOTH);
|
26
26
|
|
27
|
-
|
27
|
+
/// Loads a portion of the the image at the given filename..
|
28
28
|
///
|
29
29
|
/// A color key of #ff00ff is automatically applied to BMP image files.
|
30
30
|
/// For more flexibility, use the corresponding constructor that uses a Bitmap object.
|
data/lib/SDL2.dll
CHANGED
Binary file
|
data/lib/gosu/ffi.rb
CHANGED
@@ -134,11 +134,12 @@ module GosuFFI
|
|
134
134
|
attach_function :Gosu_Font_set_image, [:pointer, :string, :uint32, :pointer], :void
|
135
135
|
|
136
136
|
attach_function :Gosu_Image_create, [:string, :uint32], :pointer
|
137
|
+
attach_function :Gosu_Image_create_from_rect, [:string, :int, :int, :int, :int, :uint32], :pointer
|
137
138
|
attach_function :Gosu_Image_destroy, [:pointer], :void
|
138
139
|
|
139
140
|
attach_function :Gosu_Image_create_from_markup, [:string, :string, :double, :int, :double, :uint32, :uint32, :uint32], :pointer
|
140
141
|
attach_function :Gosu_Image_create_from_text, [:string, :string, :double, :int, :double, :uint32, :uint32, :uint32], :pointer
|
141
|
-
attach_function :Gosu_Image_create_from_blob, [:pointer, :
|
142
|
+
attach_function :Gosu_Image_create_from_blob, [:pointer, :size_t, :int, :int, :int, :int, :int, :int, :uint32], :pointer
|
142
143
|
attach_function :Gosu_Image_create_from_subimage, [:pointer, :int, :int, :int, :int], :pointer
|
143
144
|
attach_function :Gosu_Image_create_from_tiles, [:string, :int, :int, :_callback_with_image, :pointer, :uint32], :void
|
144
145
|
attach_function :Gosu_Image_create_tiles_from_image, [:pointer, :int, :int, :_callback_with_image, :pointer, :uint32], :void
|
data/lib/gosu/image.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
module Gosu
|
2
2
|
class Image
|
3
|
-
BlobHelper = Struct.new(:columns, :rows, :to_blob)
|
4
|
-
|
5
3
|
def self.from_blob(width, height, rgba = "\0\0\0\0" * (width * height), retro: false, tileable: false)
|
6
|
-
|
4
|
+
@struct ||= Struct.new(:columns, :rows, :to_blob)
|
5
|
+
self.new(@struct.new(width, height, rgba), retro: retro, tileable: tileable)
|
7
6
|
end
|
8
7
|
|
9
8
|
def self.from_text(markup, line_height, font: Gosu.default_font_name, width: -1, spacing: 0, align: :left,
|
@@ -48,25 +47,38 @@ module Gosu
|
|
48
47
|
return images
|
49
48
|
end
|
50
49
|
|
51
|
-
def initialize(object, retro: false, tileable: false)
|
50
|
+
def initialize(object, retro: false, tileable: false, rect: nil)
|
51
|
+
if rect and rect.size != 4
|
52
|
+
raise ArgumentError, "Expected 4-element array as rect"
|
53
|
+
end
|
54
|
+
|
55
|
+
flags = GosuFFI.image_flags(retro: retro, tileable: tileable)
|
56
|
+
|
52
57
|
if object.is_a? String
|
53
|
-
|
58
|
+
if rect
|
59
|
+
__image = GosuFFI.Gosu_Image_create_from_rect(object, *rect, flags)
|
60
|
+
else
|
61
|
+
__image = GosuFFI.Gosu_Image_create(object, flags)
|
62
|
+
end
|
54
63
|
GosuFFI.check_last_error
|
55
64
|
elsif object.is_a?(FFI::Pointer)
|
56
65
|
__image = object
|
57
|
-
elsif object.respond_to?(:to_blob)
|
58
|
-
object.respond_to?(:columns)
|
66
|
+
elsif object.respond_to?(:to_blob) and
|
67
|
+
object.respond_to?(:columns) and
|
59
68
|
object.respond_to?(:rows)
|
60
|
-
|
61
|
-
|
62
|
-
blob.write_array_of_type(:uchar, :put_uchar, blob_bytes)
|
63
|
-
__image = GosuFFI.Gosu_Image_create_from_blob(blob, blob_bytes.size, object.columns, object.rows, GosuFFI.image_flags(retro: retro, tileable: tileable))
|
64
|
-
GosuFFI.check_last_error
|
65
|
-
end
|
69
|
+
|
70
|
+
blob = object.to_blob { self.format = "RGBA"; self.depth = 8 }
|
66
71
|
|
67
|
-
|
72
|
+
# This creates a copy of the Ruby string data, which shouldn't be necessary with CRuby.
|
73
|
+
ptr = FFI::MemoryPointer.from_string(blob)
|
74
|
+
rect ||= [0, 0, object.columns, object.rows]
|
75
|
+
# Do not consider the terminating null byte part of the ptr length.
|
76
|
+
__image = GosuFFI.Gosu_Image_create_from_blob(ptr, ptr.size - 1, object.columns, object.rows, *rect, flags)
|
77
|
+
ptr.free
|
78
|
+
|
79
|
+
GosuFFI.check_last_error
|
68
80
|
else
|
69
|
-
raise ArgumentError
|
81
|
+
raise ArgumentError, "Expected String or RMagick::Image (or a type compatible with it)"
|
70
82
|
end
|
71
83
|
|
72
84
|
@managed_pointer = FFI::AutoPointer.new(__image, GosuFFI.method(:Gosu_Image_destroy))
|
@@ -112,17 +124,17 @@ module Gosu
|
|
112
124
|
end
|
113
125
|
|
114
126
|
def subimage(left, top, width, height)
|
115
|
-
|
127
|
+
__subimage = GosuFFI.Gosu_Image_create_from_subimage(__pointer, left, top, width, height)
|
116
128
|
GosuFFI.check_last_error
|
117
|
-
Gosu::Image.new(
|
129
|
+
Gosu::Image.new(__subimage)
|
118
130
|
end
|
119
131
|
|
120
132
|
def insert(image, x, y)
|
121
133
|
image_ = nil
|
122
134
|
if image.is_a?(Gosu::Image)
|
123
135
|
image_ = image.__pointer
|
124
|
-
elsif image.respond_to?(:to_blob)
|
125
|
-
image.respond_to?(:rows)
|
136
|
+
elsif image.respond_to?(:to_blob) and
|
137
|
+
image.respond_to?(:rows) and
|
126
138
|
image.respond_to?(:columns)
|
127
139
|
image_ = Gosu::Image.new(image).__pointer
|
128
140
|
else
|
data/lib64/SDL2.dll
CHANGED
Binary file
|
data/src/BinPacker.cpp
CHANGED
@@ -136,7 +136,7 @@ void Gosu::BinPacker::merge_neighbors(int index)
|
|
136
136
|
// ┃ ┣━━┻━┫
|
137
137
|
// ┗━┻━━━━┛
|
138
138
|
// In this case, the texture gets stuck in this fragmented state. We assume that this is not an
|
139
|
-
// issue in practice, just like
|
139
|
+
// issue in practice, just like RAM fragmentation has never been problematic for us.
|
140
140
|
|
141
141
|
// Merge any of the other rectangles in the list into the one with the given index if they share
|
142
142
|
// any of their four sides.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#include "ClipRectStack.hpp"
|
2
|
+
#include <stdexcept>
|
3
|
+
|
4
|
+
void Gosu::ClipRectStack::clear()
|
5
|
+
{
|
6
|
+
m_stack.clear();
|
7
|
+
m_effective_rect = std::nullopt;
|
8
|
+
}
|
9
|
+
|
10
|
+
void Gosu::ClipRectStack::push(const Rect& rect)
|
11
|
+
{
|
12
|
+
m_stack.push_back(rect);
|
13
|
+
if (m_effective_rect) {
|
14
|
+
m_effective_rect->clip_to(rect);
|
15
|
+
}
|
16
|
+
else {
|
17
|
+
m_effective_rect = rect;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
void Gosu::ClipRectStack::pop()
|
22
|
+
{
|
23
|
+
if (m_stack.empty()) {
|
24
|
+
throw std::logic_error("ClipRectStack is empty");
|
25
|
+
}
|
26
|
+
m_stack.pop_back();
|
27
|
+
|
28
|
+
// The clip rect is the intersection of all active clip rects (if any).
|
29
|
+
m_effective_rect = std::nullopt;
|
30
|
+
for (const auto& rect : m_stack) {
|
31
|
+
if (m_effective_rect) {
|
32
|
+
m_effective_rect->clip_to(rect);
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
m_effective_rect = rect;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
data/src/ClipRectStack.hpp
CHANGED
@@ -1,90 +1,24 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
+
#include <Gosu/Utility.hpp>
|
3
4
|
#include "GraphicsImpl.hpp"
|
4
|
-
#include <
|
5
|
+
#include <limits>
|
6
|
+
#include <optional>
|
7
|
+
#include <stdexcept>
|
5
8
|
#include <vector>
|
6
9
|
|
7
|
-
|
10
|
+
namespace Gosu
|
8
11
|
{
|
9
|
-
|
10
|
-
bool has_effective_rect; // is effective_rect valid?
|
11
|
-
ClipRect effective_rect;
|
12
|
-
|
13
|
-
void update_effective_rect()
|
12
|
+
class ClipRectStack
|
14
13
|
{
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
result.x = std::max(result.x, rect.x);
|
27
|
-
result.y = std::max(result.y, rect.y);
|
28
|
-
|
29
|
-
if (result.x >= result_right || result.y >= result_bottom) {
|
30
|
-
// We have clipped the world away!
|
31
|
-
has_effective_rect = false;
|
32
|
-
return;
|
33
|
-
}
|
34
|
-
|
35
|
-
result.width = result_right - result.x;
|
36
|
-
result.height = result_bottom - result.y;
|
37
|
-
}
|
38
|
-
|
39
|
-
// On the iPhone, we may have to multiply everything by 2 for Retina displays.
|
40
|
-
// TODO: Doesn't this affect Retina Macs as well?
|
41
|
-
// TODO: This should be handled by a global transform.
|
42
|
-
int fac = clip_rect_base_factor();
|
43
|
-
result.x *= fac;
|
44
|
-
result.y *= fac;
|
45
|
-
result.width *= fac;
|
46
|
-
result.height *= fac;
|
47
|
-
|
48
|
-
// Normal clipping.
|
49
|
-
effective_rect = result;
|
50
|
-
has_effective_rect = true;
|
51
|
-
}
|
52
|
-
|
53
|
-
public:
|
54
|
-
ClipRectStack()
|
55
|
-
: has_effective_rect(false)
|
56
|
-
{
|
57
|
-
}
|
58
|
-
|
59
|
-
void clear()
|
60
|
-
{
|
61
|
-
stack.clear();
|
62
|
-
has_effective_rect = false;
|
63
|
-
}
|
64
|
-
|
65
|
-
void begin_clipping(double x, double y, double width, double height)
|
66
|
-
{
|
67
|
-
ClipRect rect = { x, y, width, height };
|
68
|
-
stack.push_back(rect);
|
69
|
-
update_effective_rect();
|
70
|
-
}
|
71
|
-
|
72
|
-
void end_clipping()
|
73
|
-
{
|
74
|
-
assert (!stack.empty());
|
75
|
-
stack.pop_back();
|
76
|
-
update_effective_rect();
|
77
|
-
}
|
78
|
-
|
79
|
-
const ClipRect* maybe_effective_rect() const
|
80
|
-
{
|
81
|
-
return has_effective_rect ? &effective_rect : 0;
|
82
|
-
}
|
83
|
-
|
84
|
-
bool clipped_world_away() const
|
85
|
-
{
|
86
|
-
// When we have no effective rect but the stack is not empty, we have clipped
|
87
|
-
// the whole world away and don't need to render things.
|
88
|
-
return !has_effective_rect && !stack.empty();
|
89
|
-
}
|
90
|
-
};
|
14
|
+
std::vector<Rect> m_stack;
|
15
|
+
std::optional<Rect> m_effective_rect;
|
16
|
+
|
17
|
+
public:
|
18
|
+
void clear();
|
19
|
+
void push(const Rect& rect);
|
20
|
+
void pop();
|
21
|
+
|
22
|
+
const std::optional<Rect>& effective_rect() const { return m_effective_rect; }
|
23
|
+
};
|
24
|
+
}
|
data/src/DrawOp.hpp
CHANGED
data/src/DrawOpQueue.hpp
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include <cmath>
|
10
10
|
#include <functional>
|
11
11
|
#include <map>
|
12
|
+
#include <utility>
|
12
13
|
#include <vector>
|
13
14
|
|
14
15
|
class Gosu::DrawOpQueue
|
@@ -22,7 +23,7 @@ class Gosu::DrawOpQueue
|
|
22
23
|
std::vector<std::function<void ()>> gl_blocks;
|
23
24
|
|
24
25
|
public:
|
25
|
-
DrawOpQueue(QueueMode mode)
|
26
|
+
explicit DrawOpQueue(QueueMode mode)
|
26
27
|
: queue_mode(mode)
|
27
28
|
{
|
28
29
|
}
|
@@ -34,39 +35,31 @@ public:
|
|
34
35
|
|
35
36
|
void schedule_draw_op(DrawOp op)
|
36
37
|
{
|
37
|
-
|
38
|
-
|
39
|
-
#ifdef GOSU_IS_OPENGLES
|
38
|
+
#ifdef GOSU_IS_OPENGLES
|
40
39
|
// No triangles, no lines supported
|
41
|
-
assert
|
42
|
-
|
40
|
+
assert(op.vertices_or_block_index == 4);
|
41
|
+
#endif
|
43
42
|
|
44
43
|
op.render_state.transform = &transform_stack.current();
|
45
|
-
|
46
|
-
op.render_state.clip_rect = *cr;
|
47
|
-
}
|
44
|
+
op.render_state.clip_rect = clip_rect_stack.effective_rect();
|
48
45
|
ops.push_back(op);
|
49
46
|
}
|
50
47
|
|
51
48
|
void gl(std::function<void ()> gl_block, ZPos z)
|
52
49
|
{
|
53
|
-
// TODO: Document this case: Clipped-away GL blocks are *not* being run.
|
54
|
-
if (clip_rect_stack.clipped_world_away()) return;
|
55
|
-
|
56
50
|
int complement_of_block_index = ~(int)gl_blocks.size();
|
57
|
-
gl_blocks.push_back(gl_block);
|
51
|
+
gl_blocks.push_back(std::move(gl_block));
|
58
52
|
|
59
53
|
DrawOp op;
|
60
54
|
op.vertices_or_block_index = complement_of_block_index;
|
61
55
|
op.render_state.transform = &transform_stack.current();
|
62
|
-
|
63
|
-
op.render_state.clip_rect = *cr;
|
64
|
-
}
|
56
|
+
op.render_state.clip_rect = clip_rect_stack.effective_rect();
|
65
57
|
op.z = z;
|
66
58
|
ops.push_back(op);
|
67
59
|
}
|
68
60
|
|
69
|
-
void begin_clipping(double x, double y, double width, double height,
|
61
|
+
void begin_clipping(double x, double y, double width, double height,
|
62
|
+
std::optional<int> viewport_height)
|
70
63
|
{
|
71
64
|
if (mode() == QM_RECORD_MACRO) {
|
72
65
|
throw std::logic_error("Clipping is not allowed while creating a macro");
|
@@ -80,21 +73,21 @@ public:
|
|
80
73
|
transform_stack.current().apply(left, top);
|
81
74
|
transform_stack.current().apply(right, bottom);
|
82
75
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
76
|
+
Rect clip_rect {
|
77
|
+
.x = static_cast<int>(std::min(left, right)),
|
78
|
+
.y = static_cast<int>(std::min(top, bottom)),
|
79
|
+
.width = static_cast<int>(std::abs(left - right)),
|
80
|
+
.height = static_cast<int>(std::abs(top - bottom)),
|
81
|
+
};
|
88
82
|
// Adjust for OpenGL having the wrong idea of where y=0 is.
|
89
|
-
|
83
|
+
if (viewport_height && mode() == QM_RENDER_TO_SCREEN) {
|
84
|
+
clip_rect.y = *viewport_height - clip_rect.y - clip_rect.height;
|
85
|
+
}
|
90
86
|
|
91
|
-
clip_rect_stack.
|
87
|
+
clip_rect_stack.push(clip_rect);
|
92
88
|
}
|
93
89
|
|
94
|
-
void end_clipping()
|
95
|
-
{
|
96
|
-
clip_rect_stack.end_clipping();
|
97
|
-
}
|
90
|
+
void end_clipping() { clip_rect_stack.pop(); }
|
98
91
|
|
99
92
|
void set_base_transform(const Transform& base_transform)
|
100
93
|
{
|
@@ -118,7 +111,8 @@ public:
|
|
118
111
|
}
|
119
112
|
|
120
113
|
// Apply Z-Ordering.
|
121
|
-
std::stable_sort(ops.begin(), ops.end()
|
114
|
+
std::stable_sort(ops.begin(), ops.end(),
|
115
|
+
[](const DrawOp& lhs, const DrawOp& rhs) { return lhs.z < rhs.z; });
|
122
116
|
|
123
117
|
RenderStateManager manager;
|
124
118
|
|
@@ -156,7 +150,7 @@ public:
|
|
156
150
|
throw std::logic_error("Custom OpenGL code cannot be recorded as a macro");
|
157
151
|
}
|
158
152
|
|
159
|
-
std::stable_sort(ops.begin(), ops.end());
|
153
|
+
std::stable_sort(ops.begin(), ops.end(), [](const DrawOp& lhs, const DrawOp& rhs) { return lhs.z < rhs.z; });
|
160
154
|
for (const auto& op : ops) {
|
161
155
|
op.compile_to(vas);
|
162
156
|
}
|
data/src/GosuGLView.cpp
CHANGED
@@ -28,12 +28,6 @@ namespace Gosu
|
|
28
28
|
{
|
29
29
|
// Don't bother unsetting anything.
|
30
30
|
}
|
31
|
-
|
32
|
-
int clip_rect_base_factor()
|
33
|
-
{
|
34
|
-
static int result = [UIScreen mainScreen].scale;
|
35
|
-
return result;
|
36
|
-
}
|
37
31
|
}
|
38
32
|
|
39
33
|
@implementation GosuGLView
|
@@ -97,7 +91,7 @@ namespace Gosu
|
|
97
91
|
[EAGLContext setCurrentContext:_context];
|
98
92
|
[self destroyFramebuffer];
|
99
93
|
[self createFramebuffer];
|
100
|
-
self.contentScaleFactor =
|
94
|
+
self.contentScaleFactor = [UIScreen mainScreen].scale;
|
101
95
|
}
|
102
96
|
|
103
97
|
- (BOOL)createFramebuffer
|
data/src/Graphics.cpp
CHANGED
@@ -247,17 +247,20 @@ void Gosu::gl(Gosu::ZPos z, const std::function<void()>& f)
|
|
247
247
|
#endif
|
248
248
|
}
|
249
249
|
|
250
|
-
void Gosu::clip_to(double x, double y, double width, double height,
|
251
|
-
const std::function<void()>& f)
|
250
|
+
void Gosu::clip_to(double x, double y, double width, double height, const std::function<void()>& f)
|
252
251
|
{
|
253
|
-
|
254
|
-
|
252
|
+
std::optional<int> viewport_height;
|
253
|
+
if (current_viewport_pointer) {
|
254
|
+
viewport_height = current_viewport_pointer->m_impl->phys_height;
|
255
|
+
}
|
256
|
+
|
257
|
+
current_queue().begin_clipping(x, y, width, height, viewport_height);
|
255
258
|
f();
|
256
259
|
current_queue().end_clipping();
|
257
260
|
}
|
258
261
|
|
259
262
|
Gosu::Image Gosu::render(int width, int height, const std::function<void()>& f,
|
260
|
-
|
263
|
+
unsigned image_flags)
|
261
264
|
{
|
262
265
|
const OpenGLContext current_context;
|
263
266
|
|
data/src/GraphicsImpl.hpp
CHANGED
@@ -13,23 +13,6 @@ namespace Gosu
|
|
13
13
|
struct RenderState;
|
14
14
|
class RenderStateManager;
|
15
15
|
|
16
|
-
const unsigned NO_CLIPPING = 0xffffffff;
|
17
|
-
|
18
|
-
// In various places in Gosu, width==NO_CLIPPING by convention means
|
19
|
-
// that no clipping should happen.
|
20
|
-
struct ClipRect
|
21
|
-
{
|
22
|
-
double x, y, width, height;
|
23
|
-
|
24
|
-
bool operator==(const ClipRect& other) const
|
25
|
-
{
|
26
|
-
// No clipping
|
27
|
-
return (width == NO_CLIPPING && other.width == NO_CLIPPING) ||
|
28
|
-
// Clipping, but same
|
29
|
-
(x == other.x && y == other.y && width == other.width && height == other.height);
|
30
|
-
}
|
31
|
-
};
|
32
|
-
|
33
16
|
enum QueueMode
|
34
17
|
{
|
35
18
|
QM_RENDER_TO_SCREEN,
|
@@ -71,12 +54,6 @@ namespace Gosu
|
|
71
54
|
|
72
55
|
void schedule_draw_op(const DrawOp& op);
|
73
56
|
|
74
|
-
#ifdef GOSU_IS_IPHONE
|
75
|
-
int clip_rect_base_factor();
|
76
|
-
#else
|
77
|
-
inline int clip_rect_base_factor() { return 1; }
|
78
|
-
#endif
|
79
|
-
|
80
57
|
void register_frame();
|
81
58
|
|
82
59
|
inline std::string escape_markup(const std::string& text) {
|
data/src/RenderState.hpp
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include <Gosu/Transform.hpp>
|
4
|
+
#include "ClipRectStack.hpp"
|
4
5
|
#include "GraphicsImpl.hpp"
|
5
6
|
#include "OpenGLContext.hpp"
|
6
7
|
#include "Texture.hpp"
|
8
|
+
#include <optional>
|
7
9
|
|
8
10
|
// Properties that potentially need to be changed between each draw operation.
|
9
11
|
// This does not include the color or vertex data of the actual quads.
|
@@ -11,13 +13,12 @@ struct Gosu::RenderState
|
|
11
13
|
{
|
12
14
|
std::shared_ptr<Texture> texture;
|
13
15
|
const Transform* transform;
|
14
|
-
|
16
|
+
std::optional<Rect> clip_rect;
|
15
17
|
BlendMode mode;
|
16
18
|
|
17
19
|
RenderState()
|
18
20
|
: transform(0), mode(BM_DEFAULT)
|
19
21
|
{
|
20
|
-
clip_rect.width = NO_CLIPPING;
|
21
22
|
}
|
22
23
|
|
23
24
|
bool operator==(const RenderState& rhs) const
|
@@ -54,12 +55,12 @@ struct Gosu::RenderState
|
|
54
55
|
|
55
56
|
void apply_clip_rect() const
|
56
57
|
{
|
57
|
-
if (clip_rect.
|
58
|
-
|
58
|
+
if (clip_rect.has_value()) {
|
59
|
+
glEnable(GL_SCISSOR_TEST);
|
60
|
+
glScissor(clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
|
59
61
|
}
|
60
62
|
else {
|
61
|
-
|
62
|
-
glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
|
63
|
+
glDisable(GL_SCISSOR_TEST);
|
63
64
|
}
|
64
65
|
}
|
65
66
|
|
@@ -76,12 +77,8 @@ struct Gosu::RenderState
|
|
76
77
|
|
77
78
|
// Manages the OpenGL rendering state. It caches the current state, only forwarding the
|
78
79
|
// changes to OpenGL if the new state is really different.
|
79
|
-
class Gosu::RenderStateManager : private Gosu::RenderState
|
80
|
+
class Gosu::RenderStateManager : private Gosu::RenderState, private Gosu::Noncopyable
|
80
81
|
{
|
81
|
-
// Not copyable
|
82
|
-
RenderStateManager(const RenderStateManager&);
|
83
|
-
RenderStateManager& operator=(const RenderStateManager&);
|
84
|
-
|
85
82
|
void apply_transform() const
|
86
83
|
{
|
87
84
|
glMatrixMode(GL_MODELVIEW);
|
@@ -110,9 +107,7 @@ public:
|
|
110
107
|
|
111
108
|
~RenderStateManager()
|
112
109
|
{
|
113
|
-
|
114
|
-
no_clipping.width = NO_CLIPPING;
|
115
|
-
set_clip_rect(no_clipping);
|
110
|
+
set_clip_rect(std::nullopt);
|
116
111
|
set_texture(std::shared_ptr<Texture>());
|
117
112
|
// Return to previous MV matrix
|
118
113
|
glMatrixMode(GL_MODELVIEW);
|
@@ -127,9 +122,11 @@ public:
|
|
127
122
|
set_alpha_mode(rs.mode);
|
128
123
|
}
|
129
124
|
|
130
|
-
void set_texture(std::shared_ptr<Texture
|
125
|
+
void set_texture(const std::shared_ptr<Texture>& new_texture)
|
131
126
|
{
|
132
|
-
if (new_texture == texture)
|
127
|
+
if (new_texture == texture) {
|
128
|
+
return;
|
129
|
+
}
|
133
130
|
|
134
131
|
if (new_texture) {
|
135
132
|
if (!texture) {
|
@@ -146,39 +143,29 @@ public:
|
|
146
143
|
|
147
144
|
void set_transform(const Transform* new_transform)
|
148
145
|
{
|
149
|
-
if (new_transform == transform)
|
146
|
+
if (new_transform == transform) {
|
147
|
+
return;
|
148
|
+
}
|
150
149
|
|
151
150
|
transform = new_transform;
|
152
151
|
apply_transform();
|
153
152
|
}
|
154
153
|
|
155
|
-
void set_clip_rect(const
|
154
|
+
void set_clip_rect(const std::optional<Rect>& new_clip_rect)
|
156
155
|
{
|
157
|
-
if (
|
158
|
-
|
159
|
-
if (clip_rect.width != NO_CLIPPING) {
|
160
|
-
glDisable(GL_SCISSOR_TEST);
|
161
|
-
clip_rect.width = NO_CLIPPING;
|
162
|
-
}
|
163
|
-
}
|
164
|
-
else {
|
165
|
-
// Enable clipping if off
|
166
|
-
if (clip_rect.width == NO_CLIPPING) {
|
167
|
-
glEnable(GL_SCISSOR_TEST);
|
168
|
-
clip_rect = new_clip_rect;
|
169
|
-
glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
|
170
|
-
}
|
171
|
-
// Adjust clipping if necessary
|
172
|
-
else if (!(clip_rect == new_clip_rect)) {
|
173
|
-
clip_rect = new_clip_rect;
|
174
|
-
glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
|
175
|
-
}
|
156
|
+
if (clip_rect == new_clip_rect) {
|
157
|
+
return;
|
176
158
|
}
|
159
|
+
|
160
|
+
clip_rect = new_clip_rect;
|
161
|
+
apply_clip_rect();
|
177
162
|
}
|
178
163
|
|
179
164
|
void set_alpha_mode(BlendMode new_mode)
|
180
165
|
{
|
181
|
-
if (new_mode == mode)
|
166
|
+
if (new_mode == mode) {
|
167
|
+
return;
|
168
|
+
}
|
182
169
|
|
183
170
|
mode = new_mode;
|
184
171
|
apply_alpha_mode();
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gosu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Raschke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -258,6 +258,7 @@ files:
|
|
258
258
|
- src/BitmapIO.cpp
|
259
259
|
- src/Buffer.cpp
|
260
260
|
- src/Channel.cpp
|
261
|
+
- src/ClipRectStack.cpp
|
261
262
|
- src/ClipRectStack.hpp
|
262
263
|
- src/Color.cpp
|
263
264
|
- src/Directories.cpp
|
@@ -336,7 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
336
337
|
- !ruby/object:Gem::Version
|
337
338
|
version: 1.3.1
|
338
339
|
requirements: []
|
339
|
-
rubygems_version: 3.4.
|
340
|
+
rubygems_version: 3.4.10
|
340
341
|
signing_key:
|
341
342
|
specification_version: 4
|
342
343
|
summary: 2D game development library.
|