gosu 0.9.2.pre1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a1c34fd00bf80dda03420c2469ba363f09790e5
4
- data.tar.gz: eb1a0080a88b5aae6a77731cf7f9b0d5a7ddc221
3
+ metadata.gz: f230854e1ac05d7b61ed5fb830626d5ce35486d9
4
+ data.tar.gz: da67861b37f7f750891d8c082bdfb9ccca29cdf1
5
5
  SHA512:
6
- metadata.gz: c7ebb942e9dd669d8cfb8efd51a1f1e796b042067b88beee7d62a3997c550d1fe0794afd1c82026a5d1ce4a71970b5c67611fd1e24a062dd7b1cc8e451745af3
7
- data.tar.gz: d227fec88ceb822dcd120923e338e49cee87897b0be3e21eeefa1d0355c050bb4c0ec53ef8867394b2c2e30535ff6a332ea1fc2fdca1b221660b527fd40de3c9
6
+ metadata.gz: 7fbf834d22e9d7f37f86e428370c8816e4ad57466402a173a90e2edefa2424696b0f8fcb8afa5d8bea8de2437aad0d18e666782b10c53c8e82751e3ba94c5638
7
+ data.tar.gz: f37312c5e178fc2df0428ce2346c8bea5f2873217baed40578243bef5342138bcf347292ca4eb2dbaa3f5908f6bea258653213103ec1514a8cd9d0237340af15
@@ -4,7 +4,7 @@
4
4
  #define GOSU_MAJOR_VERSION 0
5
5
  #define GOSU_MINOR_VERSION 9
6
6
  #define GOSU_POINT_VERSION 2
7
- #define GOSU_VERSION "0.9.2.pre1"
7
+ #define GOSU_VERSION "0.9.2"
8
8
 
9
9
  #define GOSU_COPYRIGHT_NOTICE \
10
10
  "This software uses the following third-party libraries:\n" \
@@ -28,6 +28,7 @@ BASE_FILES = %w(
28
28
  Graphics/Graphics.cpp
29
29
  Graphics/Image.cpp
30
30
  Graphics/LargeImageData.cpp
31
+ Graphics/Macro.cpp
31
32
  Graphics/Resolution.cpp
32
33
  Graphics/TexChunk.cpp
33
34
  Graphics/Texture.cpp
@@ -8,6 +8,10 @@
8
8
  * interface file instead.
9
9
  * ----------------------------------------------------------------------------- */
10
10
 
11
+ // This file was afterwards patched using the following instructions:
12
+ // http://sourceforge.net/tracker/index.php?func=detail&aid=2034216&group_id=1645&atid=101645
13
+ // (Many thanks to Kevin Burge for that.)
14
+
11
15
  #define SWIGRUBY
12
16
  #define SWIG_DIRECTORS
13
17
 
@@ -844,6 +848,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
844
848
 
845
849
 
846
850
  #include <ruby.h>
851
+ #include <map>
847
852
 
848
853
  /* Ruby 1.9.1 has a "memoisation optimisation" when compiling with GCC which
849
854
  * breaks using rb_intern as an lvalue, as SWIG does. We work around this
@@ -1184,7 +1189,7 @@ extern "C" {
1184
1189
  /* Global Ruby hash table to store Trackings from C/C++
1185
1190
  structs to Ruby Objects.
1186
1191
  */
1187
- static VALUE swig_ruby_trackings = Qnil;
1192
+ static std::map<void*, VALUE> swig_ruby_trackings;
1188
1193
 
1189
1194
  /* Global variable that stores a reference to the ruby
1190
1195
  hash table delete function. */
@@ -1201,34 +1206,18 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
1201
1206
  This is done to allow multiple DSOs to share the same
1202
1207
  tracking table.
1203
1208
  */
1204
- ID trackings_id = rb_intern( "@__trackings__" );
1205
1209
  VALUE verbose = rb_gv_get("VERBOSE");
1206
1210
  rb_gv_set("VERBOSE", Qfalse);
1207
- swig_ruby_trackings = rb_ivar_get( _mSWIG, trackings_id );
1208
1211
  rb_gv_set("VERBOSE", verbose);
1209
1212
 
1210
1213
  /* No, it hasn't. Create one ourselves */
1211
- if ( swig_ruby_trackings == Qnil )
1212
- {
1213
- swig_ruby_trackings = rb_hash_new();
1214
- rb_ivar_set( _mSWIG, trackings_id, swig_ruby_trackings );
1215
- }
1214
+ swig_ruby_trackings.clear();
1216
1215
 
1217
1216
  /* Now store a reference to the hash table delete function
1218
1217
  so that we only have to look it up once.*/
1219
1218
  swig_ruby_hash_delete = rb_intern("delete");
1220
1219
  }
1221
1220
 
1222
- /* Get a Ruby number to reference a pointer */
1223
- SWIGRUNTIME VALUE SWIG_RubyPtrToReference(void* ptr) {
1224
- /* We cast the pointer to an unsigned long
1225
- and then store a reference to it using
1226
- a Ruby number object. */
1227
-
1228
- /* Convert the pointer to a Ruby number */
1229
- return SWIG2NUM(ptr);
1230
- }
1231
-
1232
1221
  /* Get a Ruby number to reference an object */
1233
1222
  SWIGRUNTIME VALUE SWIG_RubyObjectToReference(VALUE object) {
1234
1223
  /* We cast the object to an unsigned long
@@ -1250,39 +1239,16 @@ SWIGRUNTIME VALUE SWIG_RubyReferenceToObject(VALUE reference) {
1250
1239
 
1251
1240
  /* Add a Tracking from a C/C++ struct to a Ruby object */
1252
1241
  SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
1253
- /* In a Ruby hash table we store the pointer and
1254
- the associated Ruby object. The trick here is
1255
- that we cannot store the Ruby object directly - if
1256
- we do then it cannot be garbage collected. So
1257
- instead we typecast it as a unsigned long and
1258
- convert it to a Ruby number object.*/
1259
-
1260
- /* Get a reference to the pointer as a Ruby number */
1261
- VALUE key = SWIG_RubyPtrToReference(ptr);
1262
-
1263
- /* Get a reference to the Ruby object as a Ruby number */
1264
- VALUE value = SWIG_RubyObjectToReference(object);
1265
-
1266
1242
  /* Store the mapping to the global hash table. */
1267
- rb_hash_aset(swig_ruby_trackings, key, value);
1243
+ swig_ruby_trackings[ptr] = object;
1268
1244
  }
1269
1245
 
1270
1246
  /* Get the Ruby object that owns the specified C/C++ struct */
1271
1247
  SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
1272
- /* Get a reference to the pointer as a Ruby number */
1273
- VALUE key = SWIG_RubyPtrToReference(ptr);
1274
-
1275
- /* Now lookup the value stored in the global hash table */
1276
- VALUE value = rb_hash_aref(swig_ruby_trackings, key);
1277
-
1278
- if (value == Qnil) {
1279
- /* No object exists - return nil. */
1248
+ if (swig_ruby_trackings.count(ptr) == 0)
1280
1249
  return Qnil;
1281
- }
1282
- else {
1283
- /* Convert this value to Ruby object */
1284
- return SWIG_RubyReferenceToObject(value);
1285
- }
1250
+ else
1251
+ return swig_ruby_trackings[ptr];
1286
1252
  }
1287
1253
 
1288
1254
  /* Remove a Tracking from a C/C++ struct to a Ruby object. It
@@ -1290,12 +1256,7 @@ SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
1290
1256
  since the same memory address may be reused later to create
1291
1257
  a new object. */
1292
1258
  SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
1293
- /* Get a reference to the pointer as a Ruby number */
1294
- VALUE key = SWIG_RubyPtrToReference(ptr);
1295
-
1296
- /* Delete the object from the hash table by calling Ruby's
1297
- do this we need to call the Hash.delete method.*/
1298
- rb_funcall(swig_ruby_trackings, swig_ruby_hash_delete, 1, key);
1259
+ swig_ruby_trackings.erase(ptr);
1299
1260
  }
1300
1261
 
1301
1262
  /* This is a helper method that unlinks a Ruby object from its
@@ -3101,14 +3062,14 @@ SwigDirector_Window::~SwigDirector_Window() {
3101
3062
  void SwigDirector_Window::update() {
3102
3063
  VALUE result;
3103
3064
 
3104
- result = rb_funcall(swig_get_self(), rb_intern("update"), 0, NULL);
3065
+ result = rb_funcall(swig_get_self(), rb_intern("protected_update"), 0, NULL);
3105
3066
  }
3106
3067
 
3107
3068
 
3108
3069
  void SwigDirector_Window::draw() {
3109
3070
  VALUE result;
3110
3071
 
3111
- result = rb_funcall(swig_get_self(), rb_intern("draw"), 0, NULL);
3072
+ result = rb_funcall(swig_get_self(), rb_intern("protected_draw_2"), 0, NULL);
3112
3073
  }
3113
3074
 
3114
3075
 
@@ -3116,7 +3077,7 @@ bool SwigDirector_Window::needsRedraw() const {
3116
3077
  bool c_result ;
3117
3078
  VALUE result;
3118
3079
 
3119
- result = rb_funcall(swig_get_self(), rb_intern("needs_redraw?"), 0, NULL);
3080
+ result = rb_funcall(swig_get_self(), rb_intern("protected_needs_redraw?"), 0, NULL);
3120
3081
  bool swig_val;
3121
3082
  int swig_res = SWIG_AsVal_bool(result, &swig_val);
3122
3083
  if (!SWIG_IsOK(swig_res)) {
@@ -3131,7 +3092,7 @@ bool SwigDirector_Window::needsCursor() const {
3131
3092
  bool c_result ;
3132
3093
  VALUE result;
3133
3094
 
3134
- result = rb_funcall(swig_get_self(), rb_intern("needs_cursor?"), 0, NULL);
3095
+ result = rb_funcall(swig_get_self(), rb_intern("protected_needs_cursor?"), 0, NULL);
3135
3096
  bool swig_val;
3136
3097
  int swig_res = SWIG_AsVal_bool(result, &swig_val);
3137
3098
  if (!SWIG_IsOK(swig_res)) {
@@ -3145,7 +3106,7 @@ bool SwigDirector_Window::needsCursor() const {
3145
3106
  void SwigDirector_Window::loseFocus() {
3146
3107
  VALUE result;
3147
3108
 
3148
- result = rb_funcall(swig_get_self(), rb_intern("lose_focus"), 0, NULL);
3109
+ result = rb_funcall(swig_get_self(), rb_intern("protected_lose_focus"), 0, NULL);
3149
3110
  }
3150
3111
 
3151
3112
 
@@ -3166,7 +3127,7 @@ void SwigDirector_Window::buttonDown(Gosu::Button arg0) {
3166
3127
  else
3167
3128
  obj0 = LONG2NUM((&arg0)->id());
3168
3129
  }
3169
- result = rb_funcall(swig_get_self(), rb_intern("button_down"), 1,obj0);
3130
+ result = rb_funcall(swig_get_self(), rb_intern("protected_button_down"), 1,obj0);
3170
3131
  }
3171
3132
 
3172
3133
 
@@ -3180,7 +3141,7 @@ void SwigDirector_Window::buttonUp(Gosu::Button arg0) {
3180
3141
  else
3181
3142
  obj0 = LONG2NUM((&arg0)->id());
3182
3143
  }
3183
- result = rb_funcall(swig_get_self(), rb_intern("button_up"), 1,obj0);
3144
+ result = rb_funcall(swig_get_self(), rb_intern("protected_button_up"), 1,obj0);
3184
3145
  }
3185
3146
 
3186
3147
 
@@ -11135,7 +11096,7 @@ SWIGEXPORT void Init_gosu(void) {
11135
11096
  rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
11136
11097
  rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(9)));
11137
11098
  rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(2)));
11138
- rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.9.2.pre1"));
11099
+ rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.9.2"));
11139
11100
  rb_define_const(mGosu, "GOSU_COPYRIGHT_NOTICE", SWIG_FromCharPtr("This software uses the following third-party libraries:\n\nGosu, http://www.libgosu.org, MIT License, http://opensource.org/licenses/MIT\nSDL 2, http://www.libsdl.org, MIT License, http://opensource.org/licenses/MIT\nFreeImage, http://freeimage.sourceforge.net, FreeImage Public License\nlibogg & libvorbis, http://www.xiph.org, BSD License, 3-Clause Version, http://www.xiph.org/licenses/bsd\nlibsndfile, http://www.mega-nerd.com/libsndfile, GNU LGPL 3, http://www.gnu.org/copyleft/lesser.html\nOpenAL Soft, http://kcat.strangesoft.net/openal.html, GNU LGPL 2, http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html\n"));
11140
11101
  rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
11141
11102
  rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
@@ -16,6 +16,7 @@ class Gosu::DrawOpQueue
16
16
  {
17
17
  TransformStack transformStack;
18
18
  ClipRectStack clipRectStack;
19
+ bool rec;
19
20
 
20
21
  typedef std::vector<DrawOp> DrawOps;
21
22
  DrawOps ops;
@@ -23,6 +24,21 @@ class Gosu::DrawOpQueue
23
24
  GLBlocks glBlocks;
24
25
 
25
26
  public:
27
+ DrawOpQueue()
28
+ : rec(false)
29
+ {
30
+ }
31
+
32
+ bool recording() const
33
+ {
34
+ return rec;
35
+ }
36
+
37
+ void setRecording()
38
+ {
39
+ rec = true;
40
+ }
41
+
26
42
  void scheduleDrawOp(DrawOp op)
27
43
  {
28
44
  if (clipRectStack.clippedWorldAway())
@@ -59,6 +75,9 @@ public:
59
75
 
60
76
  void beginClipping(double x, double y, double width, double height, double screenHeight)
61
77
  {
78
+ if (recording())
79
+ throw std::logic_error("Clipping is not allowed while creating a macro yet");
80
+
62
81
  // Apply current transformation.
63
82
 
64
83
  double left = x, right = x + width;
@@ -100,6 +119,9 @@ public:
100
119
 
101
120
  void performDrawOpsAndCode()
102
121
  {
122
+ if (recording())
123
+ throw std::logic_error("Flushing to the screen is not allowed while recording a macro");
124
+
103
125
  // Apply Z-Ordering.
104
126
  std::stable_sort(ops.begin(), ops.end());
105
127
 
@@ -139,7 +161,7 @@ public:
139
161
  void compileTo(VertexArrays& vas)
140
162
  {
141
163
  if (!glBlocks.empty())
142
- throw std::logic_error("Custom code cannot be recorded into a macro");
164
+ throw std::logic_error("Custom OpenGL code cannot be recorded as a macro");
143
165
 
144
166
  std::stable_sort(ops.begin(), ops.end());
145
167
  for (DrawOps::const_iterator op = ops.begin(), end = ops.end(); op != end; ++op)
@@ -1,6 +1,7 @@
1
1
  #include <Gosu/Graphics.hpp>
2
2
  #include "Common.hpp"
3
3
  #include "DrawOp.hpp"
4
+ #include "DrawOpQueue.hpp"
4
5
  #include "Texture.hpp"
5
6
  #include "TexChunk.hpp"
6
7
  #include "LargeImageData.hpp"
@@ -28,6 +29,15 @@ namespace Gosu
28
29
 
29
30
  typedef std::vector<std::tr1::shared_ptr<Texture> > Textures;
30
31
  Textures textures;
32
+
33
+ DrawOpQueueStack queues;
34
+
35
+ DrawOpQueue& currentQueue()
36
+ {
37
+ if (queues.empty())
38
+ throw std::logic_error("There is no rendering queue for this operation");
39
+ return queues.back();
40
+ }
31
41
  }
32
42
  }
33
43
 
@@ -37,7 +47,9 @@ struct Gosu::Graphics::Impl
37
47
  unsigned physWidth, physHeight;
38
48
  double blackWidth, blackHeight;
39
49
  bool fullscreen;
40
- DrawOpQueueStack queues;
50
+ Transform baseTransform;
51
+
52
+ DrawOpQueueStack warmedUpQueues;
41
53
  };
42
54
 
43
55
  Gosu::Graphics::Graphics(unsigned physWidth, unsigned physHeight, bool fullscreen)
@@ -65,9 +77,6 @@ Gosu::Graphics::Graphics(unsigned physWidth, unsigned physHeight, bool fullscree
65
77
  glLoadIdentity();
66
78
 
67
79
  glEnable(GL_BLEND);
68
-
69
- // Create default draw-op queue.
70
- pimpl->queues.resize(1);
71
80
  }
72
81
 
73
82
  Gosu::Graphics::~Graphics()
@@ -108,26 +117,37 @@ void Gosu::Graphics::setResolution(unsigned virtualWidth, unsigned virtualHeight
108
117
 
109
118
  Transform scaleTransform = scale(scaleFactor);
110
119
  Transform translateTransform = translate(pimpl->blackWidth, pimpl->blackHeight);
111
- Transform baseTransform = concat(translateTransform, scaleTransform);
112
-
113
- pimpl->queues.front().setBaseTransform(baseTransform);
120
+ pimpl-> baseTransform = concat(translateTransform, scaleTransform);
114
121
  }
115
122
 
116
123
  bool Gosu::Graphics::begin(Gosu::Color clearWithColor)
117
124
  {
118
- // If recording is in process, cancel it.
119
- assert (pimpl->queues.size() == 1);
120
- pimpl->queues.resize(1);
121
- // Clear leftover transforms, clip rects etc.
122
- pimpl->queues.front().reset();
125
+ if (currentGraphicsPointer != 0)
126
+ throw std::logic_error("Cannot nest calls to Gosu::Graphics::begin()");
127
+
128
+ // Cancel all recording or whatever that might still be in progress...
129
+ queues.clear();
130
+
131
+ if (pimpl->warmedUpQueues.size() == 1)
132
+ {
133
+ // If we already have a "warmed up" queue, use that instead.
134
+ // -> All internals std::vectors will already have a lot of capacity.
135
+ // This helps reduce allocations during normal operation.
136
+ queues.clear();
137
+ queues.swap(pimpl->warmedUpQueues);
138
+ }
139
+ else
140
+ {
141
+ // Create default draw-op queue.
142
+ queues.resize(1);
143
+ }
144
+
145
+ queues.back().setBaseTransform(pimpl->baseTransform);
123
146
 
124
147
  glClearColor(clearWithColor.red() / 255.f, clearWithColor.green() / 255.f,
125
148
  clearWithColor.blue() / 255.f, clearWithColor.alpha() / 255.f);
126
149
  glClear(GL_COLOR_BUFFER_BIT);
127
150
 
128
- if (currentGraphicsPointer != 0)
129
- throw std::logic_error("Cannot nest calls to Gosu::Graphics::begin()");
130
-
131
151
  currentGraphicsPointer = this;
132
152
 
133
153
  return true;
@@ -136,10 +156,12 @@ bool Gosu::Graphics::begin(Gosu::Color clearWithColor)
136
156
  void Gosu::Graphics::end()
137
157
  {
138
158
  // If recording is in process, cancel it.
139
- pimpl->queues.resize(1);
159
+ while (currentQueue().recording()) {
160
+ queues.pop_back();
161
+ }
140
162
 
141
163
  flush();
142
-
164
+
143
165
  if (pimpl->blackHeight || pimpl->blackWidth) {
144
166
  if (pimpl->blackHeight) {
145
167
  drawQuad(0, -pimpl->blackHeight, Color::BLACK,
@@ -165,26 +187,30 @@ void Gosu::Graphics::end()
165
187
  }
166
188
 
167
189
  glFlush();
168
-
190
+
169
191
  currentGraphicsPointer = 0;
192
+
193
+ // Clear leftover transforms, clip rects etc.
194
+ if (queues.size() == 1)
195
+ {
196
+ queues.swap(pimpl->warmedUpQueues);
197
+ pimpl->warmedUpQueues.back().reset();
198
+ }
199
+ else
200
+ {
201
+ queues.clear();
202
+ }
170
203
  }
171
204
 
172
205
  void Gosu::Graphics::flush()
173
206
  {
174
- Graphics& cg = currentGraphics();
175
-
176
- if (cg.pimpl->queues.size() != 1)
177
- throw std::logic_error("Flushing to screen is not allowed while creating a macro");
178
-
179
- cg.pimpl->queues.front().performDrawOpsAndCode();
180
- cg.pimpl->queues.front().clearQueue();
207
+ currentQueue().performDrawOpsAndCode();
208
+ currentQueue().clearQueue();
181
209
  }
182
210
 
183
211
  void Gosu::Graphics::beginGL()
184
212
  {
185
- Graphics& cg = currentGraphics();
186
-
187
- if (cg.pimpl->queues.size() > 1)
213
+ if (currentQueue().recording())
188
214
  throw std::logic_error("Custom OpenGL is not allowed while creating a macro");
189
215
 
190
216
  #ifdef GOSU_IS_OPENGLES
@@ -247,90 +273,71 @@ namespace Gosu
247
273
 
248
274
  functor();
249
275
 
250
- // Does not have to be inlined.
251
- graphics.endGL();
276
+ graphics.endGL();
252
277
  }
253
278
  };
254
279
  }
255
280
 
256
281
  void Gosu::Graphics::scheduleGL(const std::tr1::function<void()>& functor, Gosu::ZPos z)
257
282
  {
258
- Graphics& cg = currentGraphics();
259
-
260
- cg.pimpl->queues.back().scheduleGL(RunGLFunctor(cg, functor), z);
283
+ currentQueue().scheduleGL(RunGLFunctor(currentGraphics(), functor), z);
261
284
  }
262
285
  #endif
263
286
 
264
287
  void Gosu::Graphics::beginClipping(double x, double y, double width, double height)
265
288
  {
266
- Graphics& cg = currentGraphics();
267
-
268
- if (cg.pimpl->queues.size() > 1)
269
- throw std::logic_error("Clipping is not allowed while creating a macro yet");
270
-
271
- cg.pimpl->queues.back().beginClipping(x, y, width, height, cg.pimpl->physHeight);
289
+ double screenHeight = currentGraphics().pimpl->physHeight;
290
+ currentQueue().beginClipping(x, y, width, height, screenHeight);
272
291
  }
273
292
 
274
293
  void Gosu::Graphics::endClipping()
275
294
  {
276
- Graphics& cg = currentGraphics();
277
-
278
- cg.pimpl->queues.back().endClipping();
295
+ currentQueue().endClipping();
279
296
  }
280
297
 
281
298
  void Gosu::Graphics::beginRecording()
282
299
  {
283
- Graphics& cg = currentGraphics();
284
-
285
- cg.pimpl->queues.resize(cg.pimpl->queues.size() + 1);
300
+ queues.resize(queues.size() + 1);
301
+ currentQueue().setRecording();
286
302
  }
287
303
 
288
304
  GOSU_UNIQUE_PTR<Gosu::ImageData> Gosu::Graphics::endRecording(int width, int height)
289
305
  {
290
- Graphics& cg = currentGraphics();
291
-
292
- if (cg.pimpl->queues.size() == 1)
306
+ if (! currentQueue().recording())
293
307
  throw std::logic_error("No macro recording in progress that can be captured");
294
308
 
295
- GOSU_UNIQUE_PTR<ImageData> result(new Macro(cg, cg.pimpl->queues.back(), width, height));
296
- cg.pimpl->queues.pop_back();
309
+ GOSU_UNIQUE_PTR<ImageData> result(new Macro(currentQueue(), width, height));
310
+ queues.pop_back();
297
311
  return result;
298
312
  }
299
313
 
300
314
  void Gosu::Graphics::pushTransform(const Gosu::Transform& transform)
301
315
  {
302
- Graphics& cg = currentGraphics();
303
-
304
- cg.pimpl->queues.back().pushTransform(transform);
316
+ currentQueue().pushTransform(transform);
305
317
  }
306
318
 
307
319
  void Gosu::Graphics::popTransform()
308
320
  {
309
- Graphics& cg = currentGraphics();
310
-
311
- cg.pimpl->queues.back().popTransform();
321
+ currentQueue().popTransform();
312
322
  }
313
323
 
314
324
  void Gosu::Graphics::drawLine(double x1, double y1, Color c1,
315
325
  double x2, double y2, Color c2, ZPos z, AlphaMode mode)
316
326
  {
317
- Graphics& cg = currentGraphics();
318
-
319
327
  DrawOp op;
320
328
  op.renderState.mode = mode;
321
329
  op.verticesOrBlockIndex = 2;
322
330
  op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
323
331
  op.vertices[1] = DrawOp::Vertex(x2, y2, c2);
324
332
  op.z = z;
325
- cg.pimpl->queues.back().scheduleDrawOp(op);
333
+
334
+ currentQueue().scheduleDrawOp(op);
326
335
  }
327
336
 
328
337
  void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
329
338
  double x2, double y2, Color c2, double x3, double y3, Color c3,
330
339
  ZPos z, AlphaMode mode)
331
340
  {
332
- Graphics& cg = currentGraphics();
333
-
334
341
  DrawOp op;
335
342
  op.renderState.mode = mode;
336
343
  op.verticesOrBlockIndex = 3;
@@ -342,15 +349,14 @@ void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
342
349
  op.vertices[3] = op.vertices[2];
343
350
  #endif
344
351
  op.z = z;
345
- cg.pimpl->queues.back().scheduleDrawOp(op);
352
+
353
+ currentQueue().scheduleDrawOp(op);
346
354
  }
347
355
 
348
356
  void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
349
357
  double x2, double y2, Color c2, double x3, double y3, Color c3,
350
358
  double x4, double y4, Color c4, ZPos z, AlphaMode mode)
351
359
  {
352
- Graphics& cg = currentGraphics();
353
-
354
360
  reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
355
361
 
356
362
  DrawOp op;
@@ -367,14 +373,13 @@ void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
367
373
  op.vertices[2] = DrawOp::Vertex(x4, y4, c4);
368
374
  #endif
369
375
  op.z = z;
370
- cg.pimpl->queues.back().scheduleDrawOp(op);
376
+
377
+ currentQueue().scheduleDrawOp(op);
371
378
  }
372
379
 
373
380
  void Gosu::Graphics::scheduleDrawOp(const Gosu::DrawOp &op)
374
381
  {
375
- Graphics& cg = currentGraphics();
376
-
377
- cg.pimpl->queues.back().scheduleDrawOp(op);
382
+ currentQueue().scheduleDrawOp(op);
378
383
  }
379
384
 
380
385
  GOSU_UNIQUE_PTR<Gosu::ImageData> Gosu::Graphics::createImage(
@@ -0,0 +1,234 @@
1
+ #include "Macro.hpp"
2
+ #include "DrawOpQueue.hpp"
3
+ #include <cmath>
4
+ #include <algorithm>
5
+ #include <memory>
6
+ #include <stdexcept>
7
+
8
+ struct Gosu::Macro::Impl
9
+ {
10
+ typedef double Float;
11
+
12
+ VertexArrays vertexArrays;
13
+ int width, height;
14
+
15
+ Transform findTransformForTarget(Float x1, Float y1, Float x2, Float y2, Float x3, Float y3, Float x4, Float y4) const
16
+ {
17
+ // Transformation logic follows a discussion on the ImageMagick mailing
18
+ // list (on which ImageMagick's perspective_transform.pl is based).
19
+
20
+ // To draw a macro at an arbitrary position, we solve the following system:
21
+
22
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
23
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
24
+ // w, 0, 1, 0, 0, 0, -x2w, 0 | x2
25
+ // 0, 0, 0, w, 0, 1, -y2w, 0 | y2
26
+ // 0, h, 1, 0, 0, 0, 0, -x3h | x3
27
+ // 0, 0, 0, 0, h, 1, 0, -y3h | y3
28
+ // w, h, 1, 0, 0, 0, -x4w, -x4h | x4
29
+ // 0, 0, 0, w, h, 1, -y4w, -y4h | y4
30
+
31
+ // Equivalent:
32
+
33
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
34
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
35
+ // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
36
+ // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
37
+ // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
38
+ // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
39
+ // 0, 0, 0, 0, 0, 0, (x2-x4)w, (x3-x4)h | x1-x2-x3+x4
40
+ // 0, 0, 0, 0, 0, 0, (y2-y4)w, (y3-y4)h | y1-y2-y3+y4
41
+
42
+ // Since this matrix is relatively sparse, we unroll all three solving paths.
43
+
44
+ static const Transform nullTransform = {{ 0 }};
45
+
46
+ // Row 7 is completely useless
47
+ if (x2 == x4 && x3 == x4)
48
+ return nullTransform;
49
+ // Row 8 is completely useless
50
+ if (y2 == y3 && y3 == y4)
51
+ return nullTransform;
52
+ // Col 7 is completely useless
53
+ if (x2 == x4 && y2 == y4)
54
+ return nullTransform;
55
+ // Col 8 is completely useless
56
+ if (x3 == x4 && y3 == y4)
57
+ return nullTransform;
58
+
59
+ Float c[8];
60
+
61
+ // Rows 1, 2
62
+ c[2] = x1, c[5] = y1;
63
+
64
+ // The logic below assumes x2 != x4, i.e. row7 can be used to eliminate
65
+ // the leftmost value in row 8 and afterwards the values in rows 3 & 4.
66
+ // If x2 == x4, we need to exchange rows 7 and 8.
67
+
68
+ // TODO: x2==x4 is the normal case where an image is
69
+ // drawn upright; the code should rather swap in the rare case that x3==x4!
70
+
71
+ Float leftCell7 = (x2-x4)*width, rightCell7 = (x3-x4)*height, origRightSide7 = (x1-x2-x3+x4);
72
+ Float leftCell8 = (y2-y4)*width, rightCell8 = (y3-y4)*height, origRightSide8 = (y1-y2-y3+y4);
73
+
74
+ bool swapRows78 = x2 == x4;
75
+ if (swapRows78)
76
+ {
77
+ std::swap(leftCell7, leftCell8);
78
+ std::swap(rightCell7, rightCell8);
79
+ std::swap(origRightSide7, origRightSide8);
80
+ }
81
+
82
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
83
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
84
+ // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
85
+ // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
86
+ // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
87
+ // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
88
+ // 0, 0, 0, 0, 0, 0, leftCell7, rightCell7 | origRightSide7
89
+ // 0, 0, 0, 0, 0, 0, leftCell8, rightCell8 | origRightSide8
90
+
91
+ // Use row 7 to eliminate the left cell in row 8
92
+ // Row8 = Row8 - factor78 * Row7
93
+ Float factor78 = leftCell8 / leftCell7;
94
+ Float remCell8 = rightCell8 - rightCell7 * factor78;
95
+ Float rightSide8 = origRightSide8 - origRightSide7 * factor78;
96
+ c[7] = rightSide8 / remCell8;
97
+
98
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
99
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
100
+ // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
101
+ // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
102
+ // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
103
+ // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
104
+ // 0, 0, 0, 0, 0, 0, leftCell7, rightCell7 | origRightSide7
105
+ // 0, 0, 0, 0, 0, 0, 0, remCell8 | rightSide8
106
+
107
+ // Use the remaining value in row 8 to eliminate the right value in row 7.
108
+ // Row7 = Row7 - factor87 * Row8
109
+ Float factor87 = rightCell7 / remCell8;
110
+ Float remCell7 = leftCell7;
111
+ Float rightSide7 = origRightSide7 - rightSide8 * factor87;
112
+ c[6] = rightSide7 / remCell7;
113
+
114
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
115
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
116
+ // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
117
+ // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
118
+ // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
119
+ // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
120
+ // 0, 0, 0, 0, 0, 0, remCell7, 0 | rightSide7
121
+ // 0, 0, 0, 0, 0, 0, 0, remCell8 | rightSide8
122
+
123
+ // Use the new rows 7 and 8 to calculate c0, c1, c3 & c4.
124
+ // Row3 = Row3 - factor73 * Row7
125
+ Float factor73 = -x2*width / remCell7;
126
+ Float remCell3 = width;
127
+ Float rightSide3 = (x2-x1) - rightSide7 * factor73;
128
+ c[0] = rightSide3 / remCell3;
129
+ // Row4 = Row4 - factor74 * Row7
130
+ Float factor74 = -y2*width / remCell7;
131
+ Float remCell4 = width;
132
+ Float rightSide4 = (y2-y1) - rightSide7 * factor74;
133
+ c[3] = rightSide4 / remCell4;
134
+ // Row5 = Row5 - factor85 * Row7
135
+ Float factor85 = -x3*height / remCell8;
136
+ Float remCell5 = height;
137
+ Float rightSide5 = (x3-x1) - rightSide8 * factor85;
138
+ c[1] = rightSide5 / remCell5;
139
+ // Row6 = Row6 - factor86 * Row8
140
+ Float factor86 = -y3*height / remCell8;
141
+ Float remCell6 = height;
142
+ Float rightSide6 = (y3-y1) - rightSide8 * factor86;
143
+ c[4] = rightSide6 / remCell6;
144
+
145
+ if (swapRows78)
146
+ std::swap(c[6], c[7]);
147
+
148
+ // Let's hope I never have to debug/understand this again! :D
149
+
150
+ Transform result = {{
151
+ c[0], c[3], 0, c[6],
152
+ c[1], c[4], 0, c[7],
153
+ 0, 0, 1, 0,
154
+ c[2], c[5], 0, 1
155
+ }};
156
+ return result;
157
+ }
158
+
159
+ void drawVertexArrays(Float x1, Float y1, Float x2, Float y2, Float x3, Float y3, Float x4, Float y4) const
160
+ {
161
+ // TODO: Macros should not be split up just because they have different transforms! This is insane.
162
+ // They should be premultiplied and have the same transform by definition. Then the transformation
163
+ // only has to be performed once.
164
+
165
+ #ifndef GOSU_IS_OPENGLES
166
+ glEnable(GL_BLEND);
167
+ glMatrixMode(GL_MODELVIEW);
168
+
169
+ Transform transform =
170
+ findTransformForTarget(x1, y1, x2, y2, x3, y3, x4, y4);
171
+
172
+ for (VertexArrays::const_iterator it = vertexArrays.begin(), end = vertexArrays.end(); it != end; ++it)
173
+ {
174
+ glPushMatrix();
175
+ it->renderState.apply();
176
+ glMultMatrixd(&transform[0]);
177
+ glInterleavedArrays(GL_T2F_C4UB_V3F, 0, &it->vertices[0]);
178
+ glDrawArrays(GL_QUADS, 0, (GLsizei)it->vertices.size());
179
+ glPopMatrix();
180
+ }
181
+ #endif
182
+ }
183
+ };
184
+
185
+ Gosu::Macro::Macro(DrawOpQueue& queue, int width, int height)
186
+ : pimpl(new Impl)
187
+ {
188
+ pimpl->width = width;
189
+ pimpl->height = height;
190
+ queue.compileTo(pimpl->vertexArrays);
191
+ }
192
+
193
+ int Gosu::Macro::width() const
194
+ {
195
+ return pimpl->width;
196
+ }
197
+
198
+ int Gosu::Macro::height() const
199
+ {
200
+ return pimpl->height;
201
+ }
202
+
203
+ void Gosu::Macro::draw(double x1, double y1, Color c1,
204
+ double x2, double y2, Color c2,
205
+ double x3, double y3, Color c3,
206
+ double x4, double y4, Color c4,
207
+ ZPos z, AlphaMode mode) const
208
+ {
209
+ if (c1 != Color::WHITE || c2 != Color::WHITE || c3 != Color::WHITE || c4 != Color::WHITE)
210
+ throw std::invalid_argument("Macros cannot be tinted with colors yet");
211
+
212
+ std::tr1::function<void()> f = std::tr1::bind(&Impl::drawVertexArrays, pimpl, x1, y1, x2, y2, x3, y3, x4, y4);
213
+ Gosu::Graphics::scheduleGL(f, z);
214
+ }
215
+
216
+ const Gosu::GLTexInfo* Gosu::Macro::glTexInfo() const
217
+ {
218
+ return 0;
219
+ }
220
+
221
+ Gosu::Bitmap Gosu::Macro::toBitmap() const
222
+ {
223
+ throw std::logic_error("Gosu::Macro cannot be rendered as Gosu::Bitmap yet");
224
+ }
225
+
226
+ GOSU_UNIQUE_PTR<Gosu::ImageData> Gosu::Macro::subimage(int x, int y, int width, int height) const
227
+ {
228
+ return GOSU_UNIQUE_PTR<ImageData>();
229
+ }
230
+
231
+ void Gosu::Macro::insert(const Bitmap& bitmap, int x, int y)
232
+ {
233
+ throw std::logic_error("Gosu::Macro cannot be updated with a Gosu::Bitmap yet");
234
+ }
@@ -6,237 +6,31 @@
6
6
  #include <Gosu/TR1.hpp>
7
7
  #include <Gosu/Platform.hpp>
8
8
  #include "Common.hpp"
9
- #include "DrawOpQueue.hpp"
10
- #include <cmath>
11
- #include <algorithm>
12
- #include <memory>
13
- #include <stdexcept>
14
9
 
15
10
  class Gosu::Macro : public Gosu::ImageData
16
11
  {
17
- typedef double Float;
18
-
19
- Graphics& graphics;
20
- VertexArrays vertexArrays;
21
- int w, h;
22
-
23
- Transform findTransformForTarget(Float x1, Float y1, Float x2, Float y2, Float x3, Float y3, Float x4, Float y4) const
24
- {
25
- // Transformation logic follows a discussion on the ImageMagick mailing
26
- // list (on which ImageMagick's perspective_transform.pl is based).
27
-
28
- // To draw a macro at an arbitrary position, we solve the following system:
29
-
30
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
31
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
32
- // w, 0, 1, 0, 0, 0, -x2w, 0 | x2
33
- // 0, 0, 0, w, 0, 1, -y2w, 0 | y2
34
- // 0, h, 1, 0, 0, 0, 0, -x3h | x3
35
- // 0, 0, 0, 0, h, 1, 0, -y3h | y3
36
- // w, h, 1, 0, 0, 0, -x4w, -x4h | x4
37
- // 0, 0, 0, w, h, 1, -y4w, -y4h | y4
38
-
39
- // Equivalent:
40
-
41
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
42
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
43
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
44
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
45
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
46
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
47
- // 0, 0, 0, 0, 0, 0, (x2-x4)w, (x3-x4)h | x1-x2-x3+x4
48
- // 0, 0, 0, 0, 0, 0, (y2-y4)w, (y3-y4)h | y1-y2-y3+y4
49
-
50
- // Since this matrix is relatively sparse, we unroll all three solving paths.
51
-
52
- static const Transform nullTransform = {{ 0 }};
53
-
54
- // Row 7 is completely useless
55
- if (x2 == x4 && x3 == x4)
56
- return nullTransform;
57
- // Row 8 is completely useless
58
- if (y2 == y3 && y3 == y4)
59
- return nullTransform;
60
- // Col 7 is completely useless
61
- if (x2 == x4 && y2 == y4)
62
- return nullTransform;
63
- // Col 8 is completely useless
64
- if (x3 == x4 && y3 == y4)
65
- return nullTransform;
66
-
67
- Float c[8];
68
-
69
- // Rows 1, 2
70
- c[2] = x1, c[5] = y1;
71
-
72
- // The logic below assumes x2 != x4, i.e. row7 can be used to eliminate
73
- // the leftmost value in row 8 and afterwards the values in rows 3 & 4.
74
- // If x2 == x4, we need to exchange rows 7 and 8.
75
-
76
- // TODO: x2==x4 is the normal case where an image is
77
- // drawn upright; the code should rather swap in the rare case that x3==x4!
78
-
79
- Float leftCell7 = (x2-x4)*w, rightCell7 = (x3-x4)*h, origRightSide7 = (x1-x2-x3+x4);
80
- Float leftCell8 = (y2-y4)*w, rightCell8 = (y3-y4)*h, origRightSide8 = (y1-y2-y3+y4);
81
-
82
- bool swapRows78 = x2 == x4;
83
- if (swapRows78)
84
- {
85
- std::swap(leftCell7, leftCell8);
86
- std::swap(rightCell7, rightCell8);
87
- std::swap(origRightSide7, origRightSide8);
88
- }
89
-
90
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
91
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
92
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
93
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
94
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
95
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
96
- // 0, 0, 0, 0, 0, 0, leftCell7, rightCell7 | origRightSide7
97
- // 0, 0, 0, 0, 0, 0, leftCell8, rightCell8 | origRightSide8
98
-
99
- // Use row 7 to eliminate the left cell in row 8
100
- // Row8 = Row8 - factor78 * Row7
101
- Float factor78 = leftCell8 / leftCell7;
102
- Float remCell8 = rightCell8 - rightCell7 * factor78;
103
- Float rightSide8 = origRightSide8 - origRightSide7 * factor78;
104
- c[7] = rightSide8 / remCell8;
105
-
106
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
107
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
108
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
109
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
110
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
111
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
112
- // 0, 0, 0, 0, 0, 0, leftCell7, rightCell7 | origRightSide7
113
- // 0, 0, 0, 0, 0, 0, 0, remCell8 | rightSide8
114
-
115
- // Use the remaining value in row 8 to eliminate the right value in row 7.
116
- // Row7 = Row7 - factor87 * Row8
117
- Float factor87 = rightCell7 / remCell8;
118
- Float remCell7 = leftCell7;
119
- Float rightSide7 = origRightSide7 - rightSide8 * factor87;
120
- c[6] = rightSide7 / remCell7;
121
-
122
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
123
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
124
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
125
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
126
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
127
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
128
- // 0, 0, 0, 0, 0, 0, remCell7, 0 | rightSide7
129
- // 0, 0, 0, 0, 0, 0, 0, remCell8 | rightSide8
130
-
131
- // Use the new rows 7 and 8 to calculate c0, c1, c3 & c4.
132
- // Row3 = Row3 - factor73 * Row7
133
- Float factor73 = -x2*w / remCell7;
134
- Float remCell3 = w;
135
- Float rightSide3 = (x2-x1) - rightSide7 * factor73;
136
- c[0] = rightSide3 / remCell3;
137
- // Row4 = Row4 - factor74 * Row7
138
- Float factor74 = -y2*w / remCell7;
139
- Float remCell4 = w;
140
- Float rightSide4 = (y2-y1) - rightSide7 * factor74;
141
- c[3] = rightSide4 / remCell4;
142
- // Row5 = Row5 - factor85 * Row7
143
- Float factor85 = -x3*h / remCell8;
144
- Float remCell5 = h;
145
- Float rightSide5 = (x3-x1) - rightSide8 * factor85;
146
- c[1] = rightSide5 / remCell5;
147
- // Row6 = Row6 - factor86 * Row8
148
- Float factor86 = -y3*h / remCell8;
149
- Float remCell6 = h;
150
- Float rightSide6 = (y3-y1) - rightSide8 * factor86;
151
- c[4] = rightSide6 / remCell6;
152
-
153
- if (swapRows78)
154
- std::swap(c[6], c[7]);
155
-
156
- // Let's hope I never have to debug/understand this again! :D
157
-
158
- Transform result = {{
159
- c[0], c[3], 0, c[6],
160
- c[1], c[4], 0, c[7],
161
- 0, 0, 1, 0,
162
- c[2], c[5], 0, 1
163
- }};
164
- return result;
165
- }
166
-
167
- void drawVertexArrays(Float x1, Float y1, Float x2, Float y2, Float x3, Float y3, Float x4, Float y4) const
168
- {
169
- // TODO: Macros should not be split up just because they have different transforms! This is insane.
170
- // They should be premultiplied and have the same transform by definition. Then, the transformation
171
- // only had to be performed here once.
172
-
173
- #ifndef GOSU_IS_OPENGLES
174
- glEnable(GL_BLEND);
175
- glMatrixMode(GL_MODELVIEW);
176
-
177
- Transform transform =
178
- findTransformForTarget(x1, y1, x2, y2, x3, y3, x4, y4);
179
-
180
- for (VertexArrays::const_iterator it = vertexArrays.begin(), end = vertexArrays.end(); it != end; ++it)
181
- {
182
- glPushMatrix();
183
- it->renderState.apply();
184
- glMultMatrixd(&transform[0]);
185
- glInterleavedArrays(GL_T2F_C4UB_V3F, 0, &it->vertices[0]);
186
- glDrawArrays(GL_QUADS, 0, (GLsizei)it->vertices.size());
187
- glPopMatrix();
188
- }
189
- #endif
190
- }
12
+ struct Impl;
13
+ std::tr1::shared_ptr<Impl> pimpl;
191
14
 
192
15
  public:
193
- Macro(Graphics& graphics, DrawOpQueue& queue, int width, int height)
194
- : graphics(graphics), w(width), h(height)
195
- {
196
- queue.compileTo(vertexArrays);
197
- }
198
-
199
- int width() const
200
- {
201
- return w;
202
- }
16
+ Macro(DrawOpQueue& queue, int width, int height);
203
17
 
204
- int height() const
205
- {
206
- return h;
207
- }
18
+ int width() const;
19
+ int height() const;
208
20
 
209
21
  void draw(double x1, double y1, Color c1,
210
22
  double x2, double y2, Color c2,
211
23
  double x3, double y3, Color c3,
212
24
  double x4, double y4, Color c4,
213
- ZPos z, AlphaMode mode) const
214
- {
215
- if (c1 != Color::WHITE || c2 != Color::WHITE || c3 != Color::WHITE || c4 != Color::WHITE)
216
- throw std::invalid_argument("Macros cannot be tinted with colors yet");
217
- std::tr1::function<void()> f = std::tr1::bind(&Macro::drawVertexArrays, this, x1, y1, x2, y2, x3, y3, x4, y4);
218
- graphics.scheduleGL(f, z);
219
- }
25
+ ZPos z, AlphaMode mode) const;
220
26
 
221
- const Gosu::GLTexInfo* glTexInfo() const
222
- {
223
- return 0;
224
- }
27
+ const Gosu::GLTexInfo* glTexInfo() const;
225
28
 
226
- Gosu::Bitmap toBitmap() const
227
- {
228
- throw std::logic_error("Gosu::Macro cannot be rendered as Gosu::Bitmap yet");
229
- }
29
+ Gosu::Bitmap toBitmap() const;
230
30
 
231
- GOSU_UNIQUE_PTR<ImageData> subimage(int x, int y, int width, int height) const
232
- {
233
- return GOSU_UNIQUE_PTR<ImageData>();
234
- }
31
+ GOSU_UNIQUE_PTR<ImageData> subimage(int x, int y, int width, int height) const;
235
32
 
236
- void insert(const Bitmap& bitmap, int x, int y)
237
- {
238
- throw std::logic_error("Gosu::Macro cannot be updated with a Gosu::Bitmap yet");
239
- }
33
+ void insert(const Bitmap& bitmap, int x, int y);
240
34
  };
241
35
 
242
36
  #endif
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: 0.9.2.pre1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Raschke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-23 00:00:00.000000000 Z
11
+ date: 2015-05-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  2D game development library.
@@ -75,6 +75,7 @@ files:
75
75
  - src/Graphics/Graphics.cpp
76
76
  - src/Graphics/Image.cpp
77
77
  - src/Graphics/LargeImageData.cpp
78
+ - src/Graphics/Macro.cpp
78
79
  - src/Graphics/Resolution.cpp
79
80
  - src/Graphics/TexChunk.cpp
80
81
  - src/Graphics/Texture.cpp
@@ -162,9 +163,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
163
  version: 1.8.2
163
164
  required_rubygems_version: !ruby/object:Gem::Requirement
164
165
  requirements:
165
- - - '>'
166
+ - - '>='
166
167
  - !ruby/object:Gem::Version
167
- version: 1.3.1
168
+ version: '0'
168
169
  requirements: []
169
170
  rubyforge_project:
170
171
  rubygems_version: 2.0.14