gosu 0.7.25 → 0.7.26

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.
@@ -1,4 +1,4 @@
1
- Copyright (C) 2004-2010 Julian Raschke, Jan Lücker and all contributors.
1
+ Copyright (C) 2004-2011 Julian Raschke, Jan Lücker and all contributors.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a
4
4
  copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,6 @@ namespace Gosu
34
34
  }
35
35
 
36
36
  //! Conversion constructor for literals of the form 0xaarrggbb.
37
- //! (C++ only.)
38
37
  Color(boost::uint32_t argb)
39
38
  {
40
39
  *this = Color((argb >> 24) & 0xff, (argb >> 16) & 0xff,
@@ -52,13 +51,6 @@ namespace Gosu
52
51
  (green << GREEN_OFFSET) | (blue << BLUE_OFFSET);
53
52
  }
54
53
 
55
- static Color fromRGBA(boost::uint32_t rgba)
56
- {
57
- Color result;
58
- result.rep = rgba;
59
- return result;
60
- }
61
-
62
54
  //! Constructs a color from the given hue/saturation/value triple.
63
55
  //! Ranges of these values are given as 0..360, 0..1 and 0..1,
64
56
  //! respectively.
@@ -8,6 +8,7 @@
8
8
  #include <Gosu/Color.hpp>
9
9
  #include <Gosu/GraphicsBase.hpp>
10
10
  #include <boost/array.hpp>
11
+ #include <boost/function.hpp>
11
12
  #include <boost/scoped_ptr.hpp>
12
13
  #include <memory>
13
14
 
@@ -64,6 +65,16 @@ namespace Gosu
64
65
  void beginGL();
65
66
  //! Resets Gosu into its default rendering state.
66
67
  void endGL();
68
+ //! (Experimental)
69
+ //! Schedules a custom GL functor to be executed at a certain Z level.
70
+ //! The functor is called in a clean GL context (as given by beginGL/endGL).
71
+ //! Gosu's rendering up to the Z level may not yet have been glFlush()ed.
72
+ //! Note: Unlike normal drawing operations on the same Z level, the order
73
+ //! of custom GL functors is NOT DEFINED.
74
+ //! Note: You may not call any Gosu rendering functions from within the
75
+ //! functor, and you must schedule it from within Window::draw's call tree.
76
+ void scheduleGL(const boost::function<void()>& functor, ZPos z);
77
+
67
78
  //! Enables clipping to a specified rectangle.
68
79
  void beginClipping(double x, double y, double width, double height);
69
80
  //! Disables clipping.
@@ -17,7 +17,7 @@ namespace Gosu
17
17
  struct GLTexInfo
18
18
  {
19
19
  int texName;
20
- double left, right, top, bottom;
20
+ float left, right, top, bottom;
21
21
  };
22
22
 
23
23
  //! The ImageData class is an abstract base class for drawable images.
@@ -3,7 +3,7 @@
3
3
 
4
4
  #define GOSU_MAJOR_VERSION 0
5
5
  #define GOSU_MINOR_VERSION 7
6
- #define GOSU_POINT_VERSION 25
7
- #define GOSU_VERSION "0.7.25"
6
+ #define GOSU_POINT_VERSION 26
7
+ #define GOSU_VERSION "0.7.26"
8
8
 
9
9
  #endif
@@ -50,10 +50,10 @@ Gosu::Writer Gosu::saveToPNG(const Bitmap& bmp, Writer writer)
50
50
  CGDataProviderCreateWithData(0, bmp.data(), bmp.width() * bmp.height() * 4, 0);
51
51
 
52
52
  static CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
53
-
53
+
54
54
  CGImageRef imageRef =
55
55
  CGImageCreate(bmp.width(), bmp.height(), 8, 32, bmp.width() * 4, colorspace,
56
- kCGImageAlphaFirst, dataProvider, 0, false, kCGRenderingIntentDefault);
56
+ kCGImageAlphaLast, dataProvider, 0, false, kCGRenderingIntentDefault);
57
57
 
58
58
  ObjRef<UIImage> image([[UIImage alloc] initWithCGImage: imageRef]);
59
59
 
@@ -12,35 +12,35 @@ namespace Gosu
12
12
  {
13
13
  struct ArrayVertex
14
14
  {
15
- GLfloat texCoords[2];
15
+ float texCoords[2];
16
16
  boost::uint32_t color;
17
- GLfloat vertices[3];
17
+ float vertices[3];
18
18
  };
19
19
  typedef std::vector<ArrayVertex> VertexArray;
20
20
 
21
21
  struct DrawOp
22
22
  {
23
+ ZPos z;
24
+
23
25
  Gosu::Transform* transform;
24
26
  int clipX, clipY;
25
27
  unsigned clipWidth, clipHeight;
26
-
28
+
27
29
  struct Vertex
28
30
  {
29
- double x, y;
31
+ float x, y;
30
32
  Color c;
31
33
  Vertex() {}
32
- Vertex(double x, double y, Color c) : x(x), y(y), c(c) {}
34
+ Vertex(float x, float y, Color c) : x(x), y(y), c(c) {}
33
35
  };
34
-
35
- ZPos z;
36
+
36
37
  Vertex vertices[4];
37
38
  unsigned usedVertices;
38
39
  const TexChunk* chunk;
39
40
  AlphaMode mode;
40
-
41
+
41
42
  DrawOp(Gosu::Transform& transform)
42
- : transform(&transform), clipWidth(NO_CLIPPING),
43
- usedVertices(0), chunk(0)
43
+ : transform(&transform), clipWidth(NO_CLIPPING), chunk(0)
44
44
  {
45
45
  }
46
46
 
@@ -50,8 +50,8 @@ namespace Gosu
50
50
  static const unsigned MAX_AUTOGROUP = 24;
51
51
 
52
52
  static int spriteCounter = 0;
53
- static GLfloat spriteVertices[12 * MAX_AUTOGROUP];
54
- static GLfloat spriteTexcoords[12 * MAX_AUTOGROUP];
53
+ static float spriteVertices[12 * MAX_AUTOGROUP];
54
+ static float spriteTexcoords[12 * MAX_AUTOGROUP];
55
55
  static boost::uint32_t spriteColors[6 * MAX_AUTOGROUP];
56
56
 
57
57
  // iPhone specific setup
@@ -79,7 +79,7 @@ namespace Gosu
79
79
  current.setTexName(chunk->texName());
80
80
 
81
81
  #ifdef GOSU_IS_IPHONE
82
- double left, top, right, bottom;
82
+ float left, top, right, bottom;
83
83
  chunk->getCoords(left, top, right, bottom);
84
84
  spriteTexcoords[spriteCounter*12 + 0] = left;
85
85
  spriteTexcoords[spriteCounter*12 + 1] = top;
@@ -107,31 +107,30 @@ namespace Gosu
107
107
  else if (usedVertices == 4)
108
108
  glBegin(GL_QUADS);
109
109
 
110
- double left, top, right, bottom;
110
+ float left, top, right, bottom;
111
111
  if (chunk)
112
112
  chunk->getCoords(left, top, right, bottom);
113
113
 
114
114
  for (unsigned i = 0; i < usedVertices; i++)
115
115
  {
116
- glColor4f(vertices[i].c.red() / 255.0, vertices[i].c.green() / 255.0,
117
- vertices[i].c.blue() / 255.0, vertices[i].c.alpha() / 255.0);
116
+ glColor4ubv(reinterpret_cast<const GLubyte*>(&vertices[i].c));
118
117
  if (chunk)
119
118
  switch (i)
120
119
  {
121
120
  case 0:
122
- glTexCoord2d(left, top);
121
+ glTexCoord2f(left, top);
123
122
  break;
124
123
  case 1:
125
- glTexCoord2d(right, top);
124
+ glTexCoord2f(right, top);
126
125
  break;
127
126
  case 2:
128
- glTexCoord2d(right, bottom);
127
+ glTexCoord2f(right, bottom);
129
128
  break;
130
129
  case 3:
131
- glTexCoord2d(left, bottom);
130
+ glTexCoord2f(left, bottom);
132
131
  break;
133
132
  }
134
- glVertex2d(vertices[i].x, vertices[i].y);
133
+ glVertex2f(vertices[i].x, vertices[i].y);
135
134
  }
136
135
 
137
136
  glEnd();
@@ -175,7 +174,7 @@ namespace Gosu
175
174
  result[i].color = vertices[i].c.abgr();
176
175
  }
177
176
 
178
- double left, top, right, bottom;
177
+ float left, top, right, bottom;
179
178
  chunk->getCoords(left, top, right, bottom);
180
179
  result[0].texCoords[0] = left, result[0].texCoords[1] = top;
181
180
  result[1].texCoords[0] = right, result[1].texCoords[1] = top;
@@ -4,14 +4,18 @@
4
4
  #include <GosuImpl/Graphics/Common.hpp>
5
5
  #include <GosuImpl/Graphics/DrawOp.hpp>
6
6
  #include <boost/foreach.hpp>
7
+ #include <boost/function.hpp>
7
8
  #include <boost/optional.hpp>
8
9
  #include <algorithm>
9
- #include <set>
10
+ #include <map>
10
11
  #include <vector>
11
12
 
12
13
  class Gosu::DrawOpQueue
13
14
  {
14
- std::multiset<DrawOp> set;
15
+ typedef std::vector<DrawOp> DrawOps;
16
+ DrawOps ops;
17
+ typedef std::multimap<ZPos, boost::function<void()> > CodeMap;
18
+ CodeMap code;
15
19
 
16
20
  struct ClipRect
17
21
  {
@@ -55,14 +59,15 @@ public:
55
59
  {
56
60
  clipRectStack.swap(other.clipRectStack);
57
61
  std::swap(effectiveRect, other.effectiveRect);
58
- set.swap(other.set);
62
+ ops.swap(other.ops);
63
+ code.swap(other.code);
59
64
  }
60
65
 
61
- void addDrawOp(DrawOp op, ZPos z)
66
+ void scheduleDrawOp(DrawOp op, ZPos z)
62
67
  {
63
68
  #ifdef GOSU_IS_IPHONE
64
69
  // No triangles, no lines supported
65
- assert(op.usedVertices == 4);
70
+ assert (op.usedVertices == 4);
66
71
  #endif
67
72
 
68
73
  if (effectiveRect)
@@ -79,7 +84,12 @@ public:
79
84
  return;
80
85
 
81
86
  op.z = z;
82
- set.insert(op);
87
+ ops.push_back(op);
88
+ }
89
+
90
+ void scheduleGL(boost::function<void()> customCode, ZPos z)
91
+ {
92
+ code.insert(std::make_pair(z, customCode));
83
93
  }
84
94
 
85
95
  void beginClipping(int x, int y, unsigned width, unsigned height)
@@ -95,16 +105,57 @@ public:
95
105
  updateEffectiveRect();
96
106
  }
97
107
 
98
- void performDrawOps() const
108
+ void performDrawOpsAndCode()
99
109
  {
100
- RenderState current;
110
+ // Allows us to make some assumptions.
111
+ if (ops.empty())
112
+ return;
101
113
 
102
- std::multiset<DrawOp>::const_iterator last, cur = set.begin(), end = set.end();
103
- while (cur != end)
114
+ // Apply Z-Ordering.
115
+ std::stable_sort(ops.begin(), ops.end());
116
+
117
+ // We will loop: Drawing DrawOps, execute custom code.
118
+ // This means if there is no code, we just draw one batch
119
+ // of DrawOps, so no performance is sacrified.
120
+ DrawOps::const_iterator current = ops.begin(), last = ops.begin();
121
+ CodeMap::const_iterator it = code.begin();
122
+
123
+ while (true)
104
124
  {
105
- last = cur;
106
- ++cur;
107
- last->perform(current, cur == end ? 0 : &*cur);
125
+ if (it == code.end())
126
+ // Last or only batch of DrawOps:
127
+ // Just draw everything.
128
+ last = ops.end() - 1;
129
+ else
130
+ {
131
+ // There is code waiting:
132
+ // Only draw up to this Z level.
133
+ while (last != ops.end() - 1 && (last + 1)->z < it->first)
134
+ ++last;
135
+ }
136
+
137
+ if (current <= last)
138
+ {
139
+ // Draw DrawOps until next code is due
140
+ RenderState renderState;
141
+ while (current < last)
142
+ {
143
+ DrawOps::const_iterator next = current + 1;
144
+ current->perform(renderState, &*next);
145
+ current = next;
146
+ }
147
+ last->perform(renderState, 0);
148
+ ++current;
149
+ }
150
+
151
+ // Draw next code, or break if there is none
152
+ if (it == code.end())
153
+ break;
154
+ else
155
+ {
156
+ it->second();
157
+ ++it;
158
+ }
108
159
  }
109
160
  }
110
161
 
@@ -113,13 +164,18 @@ public:
113
164
  // Not sure if Graphics::begin() should implicitly do that.
114
165
  //clipRectStack.clear();
115
166
  //effectiveRect.reset();
116
- set.clear();
167
+ code.clear();
168
+ ops.clear();
117
169
  }
118
170
 
119
- void compileTo(VertexArray& va) const
171
+ void compileTo(VertexArray& va)
120
172
  {
121
- va.reserve(set.size());
122
- BOOST_FOREACH (const DrawOp& op, set)
173
+ if (!code.empty())
174
+ throw std::logic_error("Custom code cannot be recorded into a macro");
175
+
176
+ va.reserve(ops.size());
177
+ std::stable_sort(ops.begin(), ops.end());
178
+ BOOST_FOREACH (const DrawOp& op, ops)
123
179
  op.compileTo(va);
124
180
  }
125
181
  };
@@ -179,7 +179,7 @@ void Gosu::Graphics::flush()
179
179
  // If there is a recording in process, cancel it.
180
180
  pimpl->queues.resize(1);
181
181
 
182
- pimpl->queues.at(0).performDrawOps();
182
+ pimpl->queues.at(0).performDrawOpsAndCode();
183
183
  pimpl->queues.at(0).clear();
184
184
  }
185
185
 
@@ -217,6 +217,44 @@ void Gosu::Graphics::endGL()
217
217
  #endif
218
218
  }
219
219
 
220
+ #ifdef GOSU_IS_IPHONE
221
+ void Gosu::Graphics::scheduleGL(const boost::function<void()>& functor, Gosu::ZPos z)
222
+ {
223
+ throw std::logic_error("Custom OpenGL is unsupported on the iPhone");
224
+ }
225
+ #else
226
+ namespace
227
+ {
228
+ struct RunGLFunctor
229
+ {
230
+ Gosu::Graphics& graphics;
231
+ boost::function<void()> functor;
232
+
233
+ RunGLFunctor(Gosu::Graphics& graphics, const boost::function<void()>& functor)
234
+ : graphics(graphics), functor(functor)
235
+ {
236
+ }
237
+
238
+ void operator()() const
239
+ {
240
+ // Inlined beginGL() to avoid flushing.
241
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
242
+ glDisable(GL_BLEND);
243
+
244
+ functor();
245
+
246
+ // Does not have to be inlined.
247
+ graphics.endGL();
248
+ }
249
+ };
250
+ }
251
+
252
+ void Gosu::Graphics::scheduleGL(const boost::function<void()>& functor, Gosu::ZPos z)
253
+ {
254
+ pimpl->queues.back().scheduleGL(RunGLFunctor(*this, functor), z);
255
+ }
256
+ #endif
257
+
220
258
  void Gosu::Graphics::beginClipping(double x, double y, double width, double height)
221
259
  {
222
260
  if (pimpl->queues.size() > 1)
@@ -304,7 +342,7 @@ void Gosu::Graphics::drawLine(double x1, double y1, Color c1,
304
342
  op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
305
343
  op.vertices[1] = DrawOp::Vertex(x2, y2, c2);
306
344
 
307
- pimpl->queues.back().addDrawOp(op, z);
345
+ pimpl->queues.back().scheduleDrawOp(op, z);
308
346
  }
309
347
 
310
348
  void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
@@ -324,7 +362,7 @@ void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
324
362
  op.vertices[3] = op.vertices[2];
325
363
  #endif
326
364
 
327
- pimpl->queues.back().addDrawOp(op, z);
365
+ pimpl->queues.back().scheduleDrawOp(op, z);
328
366
  }
329
367
 
330
368
  void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
@@ -350,7 +388,7 @@ void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
350
388
  op.vertices[2] = DrawOp::Vertex(x4, y4, c4);
351
389
  #endif
352
390
 
353
- pimpl->queues.back().addDrawOp(op, z);
391
+ pimpl->queues.back().scheduleDrawOp(op, z);
354
392
  }
355
393
 
356
394
  std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
@@ -16,7 +16,7 @@ class Gosu::Macro : public Gosu::ImageData
16
16
  unsigned w, h;
17
17
 
18
18
  public:
19
- Macro(const DrawOpQueue& queue)
19
+ Macro(DrawOpQueue& queue)
20
20
  {
21
21
  queue.compileTo(vertexArray);
22
22
  double left = 0, right = 0, top = 0, bottom = 0;
@@ -9,6 +9,11 @@ Gosu::TexChunk::TexChunk(Graphics& graphics, Transforms& transforms, DrawOpQueue
9
9
  : graphics(&graphics), transforms(&transforms), queues(&queues),
10
10
  texture(texture), x(x), y(y), w(w), h(h), padding(padding)
11
11
  {
12
+ info.texName = texture->texName();
13
+ info.left = float(x) / texture->size();
14
+ info.top = float(y) / texture->size();
15
+ info.right = float(x + w) / texture->size();
16
+ info.bottom = float(y + h) / texture->size();
12
17
  }
13
18
 
14
19
  Gosu::TexChunk::~TexChunk()
@@ -16,29 +21,6 @@ Gosu::TexChunk::~TexChunk()
16
21
  texture->free(x - padding, y - padding);
17
22
  }
18
23
 
19
- unsigned int Gosu::TexChunk::width() const
20
- {
21
- return w;
22
- }
23
-
24
- unsigned int Gosu::TexChunk::height() const
25
- {
26
- return h;
27
- }
28
-
29
- GLuint Gosu::TexChunk::texName() const
30
- {
31
- return texture->texName();
32
- }
33
-
34
- void Gosu::TexChunk::getCoords(double& left, double& top, double& right, double& bottom) const
35
- {
36
- left = double(x) / texture->size();
37
- top = double(y) / texture->size();
38
- right = double(x + w) / texture->size();
39
- bottom = double(y + h) / texture->size();
40
- }
41
-
42
24
  void Gosu::TexChunk::draw(double x1, double y1, Color c1,
43
25
  double x2, double y2, Color c2,
44
26
  double x3, double y3, Color c3,
@@ -63,14 +45,11 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1,
63
45
  newDrawOp.chunk = this;
64
46
  newDrawOp.mode = mode;
65
47
 
66
- queues->back().addDrawOp(newDrawOp, z);
48
+ queues->back().scheduleDrawOp(newDrawOp, z);
67
49
  }
68
50
 
69
51
  boost::optional<Gosu::GLTexInfo> Gosu::TexChunk::glTexInfo() const
70
52
  {
71
- Gosu::GLTexInfo info;
72
- info.texName = texName();
73
- getCoords(info.left, info.top, info.right, info.bottom);
74
53
  return info;
75
54
  }
76
55