gosu 2.0.0.pre6 → 2.0.0.pre7
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|