gosu 0.7.25 → 0.7.26

Sign up to get free protection for your applications and to get access to all the features.
@@ -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