gosu 0.7.38 → 0.7.39

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.
@@ -67,8 +67,6 @@ namespace Gosu
67
67
  //! Schedules a custom GL functor to be executed at a certain Z level.
68
68
  //! The functor is called in a clean GL context (as given by beginGL/endGL).
69
69
  //! Gosu's rendering up to the Z level may not yet have been glFlush()ed.
70
- //! Note: Unlike normal drawing operations on the same Z level, the order
71
- //! of custom GL functors is NOT DEFINED.
72
70
  //! Note: You may not call any Gosu rendering functions from within the
73
71
  //! functor, and you must schedule it from within Window::draw's call tree.
74
72
  void scheduleGL(const std::tr1::function<void()>& functor, ZPos z);
@@ -81,8 +79,11 @@ namespace Gosu
81
79
  //! Starts recording a macro. Cannot be nested.
82
80
  void beginRecording();
83
81
  //! Finishes building the macro and returns it as a drawable object.
82
+ //! The width and height affect nothing about the recording process,
83
+ //! the resulting macro will simply return these values when you ask
84
+ //! it.
84
85
  //! Most usually, the return value is passed to Image::Image().
85
- std::auto_ptr<Gosu::ImageData> endRecording();
86
+ std::auto_ptr<Gosu::ImageData> endRecording(int width, int height);
86
87
 
87
88
  //! Pushes one transformation onto the transformation stack.
88
89
  void pushTransform(const Transform& transform);
@@ -87,7 +87,7 @@ namespace Gosu
87
87
  //! \param tileHeight See tileWidth.
88
88
  //! \param appendTo STL container to which the images will be appended.
89
89
  //! Must provide a push_back member function; vector<tr1::shared_ptr<Image>>
90
- //! or std::tr1::ptr_vector<Image> are good choices.
90
+ //! or boost::ptr_vector<Image> are good choices.
91
91
  template<typename Container>
92
92
  void imagesFromTiledBitmap(Graphics& graphics, const std::wstring& filename,
93
93
  int tileWidth, int tileHeight, bool tileable, Container& appendTo)
@@ -104,7 +104,7 @@ namespace Gosu
104
104
  //! \param tileHeight See tileWidth.
105
105
  //! \param appendTo STL container to which the images will be appended.
106
106
  //! Must provide a push_back member function; std::vector<std::tr1::shared_ptr<Image>>
107
- //! or std::tr1::ptr_vector<Image> are good choices.
107
+ //! or boost::ptr_vector<Image> are good choices.
108
108
  template<typename Container>
109
109
  void imagesFromTiledBitmap(Graphics& graphics, const Bitmap& bmp,
110
110
  int tileWidth, int tileHeight, bool tileable, Container& appendTo)
@@ -38,8 +38,8 @@ namespace Gosu
38
38
  {
39
39
  }
40
40
 
41
- virtual unsigned width() const = 0;
42
- virtual unsigned height() const = 0;
41
+ virtual int width() const = 0;
42
+ virtual int height() const = 0;
43
43
 
44
44
  virtual void draw(double x1, double y1, Color c1,
45
45
  double x2, double y2, Color c2,
@@ -3,8 +3,8 @@
3
3
 
4
4
  #define GOSU_MAJOR_VERSION 0
5
5
  #define GOSU_MINOR_VERSION 7
6
- #define GOSU_POINT_VERSION 38
7
- #define GOSU_VERSION "0.7.38"
6
+ #define GOSU_POINT_VERSION 39
7
+ #define GOSU_VERSION "0.7.39"
8
8
 
9
9
  #define GOSU_COPYRIGHT_NOTICE \
10
10
  " " \
@@ -382,7 +382,6 @@ public:
382
382
  {
383
383
  if (alChannelManagement.get())
384
384
  {
385
- stop();
386
385
  alDeleteBuffers(2, buffers);
387
386
  }
388
387
  }
@@ -4,7 +4,6 @@
4
4
  #include <GosuImpl/Audio/AudioFile.hpp>
5
5
  #include <Gosu/IO.hpp>
6
6
  #include <vorbis/vorbisfile.h>
7
- #include <cassert>
8
7
  #include <algorithm>
9
8
  #include <stdexcept>
10
9
 
@@ -91,14 +90,12 @@ namespace Gosu
91
90
  result = ov_read(&file_, ptr + size, length - size,
92
91
  OGG_ENDIANNESS, 2 /* 16-bit */,
93
92
  1 /* signed */, &section);
94
- assert(section == 0);
95
93
  if (result > 0)
96
94
  size += result;
95
+ else if (result < 0)
96
+ throw std::runtime_error("error reading vorbis stream");
97
97
  else
98
- if (result < 0)
99
- throw std::runtime_error("error reading vorbis stream");
100
- else
101
- break;
98
+ break;
102
99
  }
103
100
 
104
101
  return size;
@@ -0,0 +1,88 @@
1
+ #ifndef GOSUIMPL_GRAPHICS_CLIPRECTSTACK_HPP
2
+ #define GOSUIMPL_GRAPHICS_CLIPRECTSTACK_HPP
3
+
4
+ class Gosu::ClipRectStack
5
+ {
6
+ std::vector<ClipRect> stack;
7
+ bool hasEffectiveRect; // is effectiveRect valid?
8
+ ClipRect effectiveRect;
9
+
10
+ void updateEffectiveRect()
11
+ {
12
+ // Nothing to do, no clipping in place.
13
+ if (stack.empty())
14
+ {
15
+ hasEffectiveRect = false;
16
+ return;
17
+ }
18
+
19
+ ClipRect result = { 0, 0, 0x7fffffff, 0x7fffffff };
20
+ for (int i = 0, end = stack.size(); i < end; ++i)
21
+ {
22
+ const ClipRect& rect = stack[i];
23
+ int resultRight = std::min(result.x + result.width, rect.x + rect.width);
24
+ int resultBottom = std::min(result.y + result.height, rect.y + rect.height);
25
+ result.x = std::max(result.x, rect.x);
26
+ result.y = std::max(result.y, rect.y);
27
+
28
+ if (result.x >= resultRight || result.y >= resultBottom)
29
+ {
30
+ // We have clipped the world away!
31
+ hasEffectiveRect = false;
32
+ return;
33
+ }
34
+
35
+ result.width = resultRight - result.x;
36
+ result.height = resultBottom - result.y;
37
+ }
38
+
39
+ // On the iPhone, we may have to multiple everything by 2 for retina displays.
40
+ // TODO: This should be handled by a global transform.
41
+ int fac = clipRectBaseFactor();
42
+ result.x *= fac, result.y *= fac, result.width *= fac, result.height *= fac;
43
+
44
+ // Normal clipping.
45
+ effectiveRect = result;
46
+ hasEffectiveRect = true;
47
+ }
48
+
49
+ public:
50
+ ClipRectStack()
51
+ : hasEffectiveRect(false)
52
+ {
53
+ }
54
+
55
+ void beginClipping(int x, int y, int width, int height)
56
+ {
57
+ ClipRect rect = { x, y, width, height };
58
+ stack.push_back(rect);
59
+ updateEffectiveRect();
60
+ }
61
+
62
+ void endClipping()
63
+ {
64
+ stack.pop_back();
65
+ updateEffectiveRect();
66
+ }
67
+
68
+ void swap(ClipRectStack& other)
69
+ {
70
+ stack.swap(other.stack); // don't trust ADL :/
71
+ std::swap(hasEffectiveRect, other.hasEffectiveRect);
72
+ std::swap(effectiveRect, other.effectiveRect);
73
+ }
74
+
75
+ const ClipRect* maybeEffectiveRect() const
76
+ {
77
+ return hasEffectiveRect ? &effectiveRect : 0;
78
+ }
79
+
80
+ bool clippedWorldAway() const
81
+ {
82
+ // When we have no effective rect but the stack is not empty, we have clipped
83
+ // the whole world away and don't need to render things.
84
+ return !hasEffectiveRect && !stack.empty();
85
+ }
86
+ };
87
+
88
+ #endif
@@ -24,19 +24,54 @@
24
24
  #include <list>
25
25
  #include <vector>
26
26
 
27
+ namespace Gosu
28
+ {
29
+ struct RenderState;
30
+ class RenderStateManager;
31
+
32
+ const GLuint NO_TEXTURE = static_cast<GLuint>(-1);
33
+ const unsigned NO_CLIPPING = 0xffffffff;
34
+
35
+ // In various places in Gosu, width==NO_CLIPPING conventionally means
36
+ // that no clipping should happen.
37
+ struct ClipRect
38
+ {
39
+ int x, y, width, height;
40
+
41
+ bool operator==(const ClipRect& other) const
42
+ {
43
+ // No clipping
44
+ return (width == NO_CLIPPING && other.width == NO_CLIPPING) ||
45
+ // Clipping, but same
46
+ (x == other.x && y == other.y && width == other.width && height == other.height);
47
+ }
48
+ };
49
+ }
50
+
51
+ #include <GosuImpl/Graphics/RenderState.hpp>
52
+
27
53
  namespace Gosu
28
54
  {
29
55
  class Texture;
30
56
  class TexChunk;
31
- class RenderState;
57
+ class ClipRectStack;
32
58
  struct DrawOp;
33
59
  class DrawOpQueue;
34
60
  typedef std::list<Transform> Transforms;
35
61
  typedef std::vector<DrawOpQueue> DrawOpQueueStack;
36
62
  class Macro;
37
-
38
- const GLuint NO_TEXTURE = static_cast<GLuint>(-1);
39
- const unsigned NO_CLIPPING = 0xffffffff;
63
+ struct ArrayVertex
64
+ {
65
+ GLfloat texCoords[2];
66
+ GLuint color;
67
+ GLfloat vertices[3];
68
+ };
69
+ struct VertexArray
70
+ {
71
+ RenderState renderState;
72
+ std::vector<ArrayVertex> vertices;
73
+ };
74
+ typedef std::list<VertexArray> VertexArrays;
40
75
 
41
76
  template<typename T>
42
77
  bool isPToTheLeftOfAB(T xa, T ya,
@@ -5,26 +5,20 @@
5
5
  #include <Gosu/Color.hpp>
6
6
  #include <GosuImpl/Graphics/Common.hpp>
7
7
  #include <GosuImpl/Graphics/TexChunk.hpp>
8
- #include <GosuImpl/Graphics/RenderState.hpp>
8
+ #include <cassert>
9
9
 
10
10
  namespace Gosu
11
11
  {
12
- struct ArrayVertex
13
- {
14
- float texCoords[2];
15
- unsigned color;
16
- float vertices[3];
17
- };
18
- typedef std::vector<ArrayVertex> VertexArray;
19
-
20
12
  struct DrawOp
21
13
  {
14
+ // For sorting before drawing the queue.
22
15
  ZPos z;
23
-
24
- Gosu::Transform* transform;
25
- int clipX, clipY;
26
- unsigned clipWidth, clipHeight;
27
16
 
17
+ RenderState renderState;
18
+ // Only valid if renderState.texName != NO_TEXTURE
19
+ GLfloat top, left, bottom, right;
20
+
21
+ // TODO: Merge with Gosu::ArrayVertex.
28
22
  struct Vertex
29
23
  {
30
24
  float x, y;
@@ -32,19 +26,17 @@ namespace Gosu
32
26
  Vertex() {}
33
27
  Vertex(float x, float y, Color c) : x(x), y(y), c(c) {}
34
28
  };
35
-
36
29
  Vertex vertices[4];
37
- unsigned usedVertices;
38
- const TexChunk* chunk;
39
- AlphaMode mode;
40
30
 
41
- DrawOp(Gosu::Transform& transform)
42
- : transform(&transform), clipWidth(NO_CLIPPING), chunk(0)
43
- {
44
- }
31
+ // Number of vertices used, or: complement index of code block
32
+ int verticesOrBlockIndex;
45
33
 
46
- void perform(RenderState& current, const DrawOp* next) const
34
+ void perform(const DrawOp* next) const
47
35
  {
36
+ // This should not be called on GL code ops.
37
+ assert (verticesOrBlockIndex >= 2);
38
+ assert (verticesOrBlockIndex <= 4);
39
+
48
40
  #ifdef GOSU_IS_IPHONE
49
41
  static const unsigned MAX_AUTOGROUP = 24;
50
42
 
@@ -70,17 +62,9 @@ namespace Gosu
70
62
  }
71
63
  #endif
72
64
 
73
- current.setClipRect(clipX, clipY, clipWidth, clipHeight);
74
- current.setTransform(transform);
75
- current.setAlphaMode(mode);
76
-
77
- if (chunk)
65
+ #ifdef GOSU_IS_IPHONE
66
+ if (renderState.texName != NO_TEXTURE)
78
67
  {
79
- current.setTexName(chunk->texName());
80
-
81
- #ifdef GOSU_IS_IPHONE
82
- float left, top, right, bottom;
83
- chunk->getCoords(left, top, right, bottom);
84
68
  spriteTexcoords[spriteCounter*12 + 0] = left;
85
69
  spriteTexcoords[spriteCounter*12 + 1] = top;
86
70
  spriteTexcoords[spriteCounter*12 + 2] = right;
@@ -94,27 +78,21 @@ namespace Gosu
94
78
  spriteTexcoords[spriteCounter*12 + 9] = bottom;
95
79
  spriteTexcoords[spriteCounter*12 + 10] = right;
96
80
  spriteTexcoords[spriteCounter*12 + 11] = bottom;
97
- #endif
98
81
  }
99
- else
100
- current.setTexName(NO_TEXTURE);
101
-
82
+ #endif
83
+
102
84
  #ifndef GOSU_IS_IPHONE
103
- if (usedVertices == 2)
85
+ if (verticesOrBlockIndex == 2)
104
86
  glBegin(GL_LINES);
105
- else if (usedVertices == 3)
87
+ else if (verticesOrBlockIndex == 3)
106
88
  glBegin(GL_TRIANGLES);
107
- else if (usedVertices == 4)
89
+ else // if (verticesOrBlockIndex == 4)
108
90
  glBegin(GL_QUADS);
109
-
110
- float left, top, right, bottom;
111
- if (chunk)
112
- chunk->getCoords(left, top, right, bottom);
113
91
 
114
- for (unsigned i = 0; i < usedVertices; i++)
92
+ for (unsigned i = 0; i < verticesOrBlockIndex; i++)
115
93
  {
116
94
  glColor4ubv(reinterpret_cast<const GLubyte*>(&vertices[i].c));
117
- if (chunk)
95
+ if (renderState.texName != NO_TEXTURE)
118
96
  switch (i)
119
97
  {
120
98
  case 0:
@@ -149,10 +127,7 @@ namespace Gosu
149
127
  }
150
128
 
151
129
  ++spriteCounter;
152
- if (spriteCounter == MAX_AUTOGROUP or next == 0 or
153
- chunk == 0 or next->chunk == 0 or next->transform != transform or
154
- next->chunk->texName() != chunk->texName() or next->mode != mode or
155
- clipWidth != NO_CLIPPING or next->clipWidth != NO_CLIPPING)
130
+ if (spriteCounter == MAX_AUTOGROUP || next == 0 || !(next->renderState == renderState))
156
131
  {
157
132
  glDrawArrays(GL_TRIANGLES, 0, 6 * spriteCounter);
158
133
  //if (spriteCounter > 1)
@@ -162,10 +137,15 @@ namespace Gosu
162
137
  #endif
163
138
  }
164
139
 
165
- void compileTo(VertexArray& va) const
140
+ void compileTo(VertexArrays& vas) const
166
141
  {
167
- ArrayVertex result[4];
142
+ if (vas.empty() || !(vas.back().renderState == renderState))
143
+ {
144
+ vas.push_back(VertexArray());
145
+ vas.back().renderState = renderState;
146
+ }
168
147
 
148
+ ArrayVertex result[4];
169
149
  for (int i = 0; i < 4; ++i)
170
150
  {
171
151
  result[i].vertices[0] = vertices[i].x;
@@ -173,15 +153,12 @@ namespace Gosu
173
153
  result[i].vertices[2] = 0;
174
154
  result[i].color = vertices[i].c.abgr();
175
155
  }
176
-
177
- float left, top, right, bottom;
178
- chunk->getCoords(left, top, right, bottom);
179
- result[0].texCoords[0] = left, result[0].texCoords[1] = top;
156
+ result[0].texCoords[0] = left, result[0].texCoords[1] = top;
180
157
  result[1].texCoords[0] = right, result[1].texCoords[1] = top;
181
158
  result[2].texCoords[0] = right, result[2].texCoords[1] = bottom;
182
- result[3].texCoords[0] = left, result[3].texCoords[1] = bottom;
183
-
184
- va.insert(va.end(), result, result + 4);
159
+ result[3].texCoords[0] = left, result[3].texCoords[1] = bottom;
160
+
161
+ vas.back().vertices.insert(vas.back().vertices.end(), result, result + 4);
185
162
  }
186
163
 
187
164
  bool operator<(const DrawOp& other) const
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <Gosu/TR1.hpp>
5
5
  #include <GosuImpl/Graphics/Common.hpp>
6
+ #include <GosuImpl/Graphics/ClipRectStack.hpp>
6
7
  #include <GosuImpl/Graphics/DrawOp.hpp>
7
8
  #include <cassert>
8
9
  #include <algorithm>
@@ -11,184 +12,120 @@
11
12
 
12
13
  class Gosu::DrawOpQueue
13
14
  {
15
+ ClipRectStack clipRectStack;
16
+
14
17
  typedef std::vector<DrawOp> DrawOps;
15
18
  DrawOps ops;
16
- typedef std::multimap<ZPos, std::tr1::function<void()> > CodeMap;
17
- CodeMap code;
18
-
19
- struct ClipRect
20
- {
21
- int x, y;
22
- unsigned width, height;
23
- };
24
- std::vector<ClipRect> clipRectStack;
25
- ClipRect effectiveRect;
26
- bool haveEffectiveRect; // is effectiveRect valid?
19
+ typedef std::vector<std::tr1::function<void()> > GLBlocks;
20
+ GLBlocks glBlocks;
27
21
 
28
- void updateEffectiveRect()
29
- {
30
- if (clipRectStack.empty())
31
- {
32
- haveEffectiveRect = false;
33
- return;
34
- }
35
-
36
- ClipRect result = { 0, 0, 0x7fffffff, 0x7fffffff };
37
- for (int i = 0; i < clipRectStack.size(); ++i)
38
- {
39
- const ClipRect& rect = clipRectStack[i];
40
- int right = std::min<int>(result.x + result.width, rect.x + rect.width);
41
- int bottom = std::min<int>(result.y + result.height, rect.y + rect.height);
42
- result.x = std::max<int>(result.x, rect.x);
43
- result.y = std::max<int>(result.y, rect.y);
44
-
45
- if (result.x >= right || result.y >= bottom)
46
- {
47
- haveEffectiveRect = false;
48
- return;
49
- }
50
-
51
- result.width = right - result.x;
52
- result.height = bottom - result.y;
53
- }
54
-
55
- int fac = clipRectBaseFactor();
56
- result.x *= fac, result.y *= fac, result.width *= fac, result.height *= fac;
57
-
58
- effectiveRect = result;
59
- haveEffectiveRect = true;
60
- }
61
-
62
22
  public:
63
- DrawOpQueue() : haveEffectiveRect(false) {}
64
-
65
23
  // I really wish I would trust ADL. :|
66
24
  void swap(DrawOpQueue& other)
67
25
  {
68
26
  clipRectStack.swap(other.clipRectStack);
69
- std::swap(effectiveRect, other.effectiveRect);
70
- std::swap(haveEffectiveRect, other.haveEffectiveRect);
71
27
  ops.swap(other.ops);
72
- code.swap(other.code);
28
+ glBlocks.swap(other.glBlocks);
73
29
  }
74
30
 
75
- void scheduleDrawOp(DrawOp op, ZPos z)
31
+ void scheduleDrawOp(DrawOp op)
76
32
  {
33
+ if (clipRectStack.clippedWorldAway())
34
+ return;
35
+
77
36
  #ifdef GOSU_IS_IPHONE
78
37
  // No triangles, no lines supported
79
- assert (op.usedVertices == 4);
38
+ assert (op.verticesOrBlockIndex == 4);
80
39
  #endif
81
40
 
82
- if (haveEffectiveRect)
83
- {
84
- op.clipX = effectiveRect.x;
85
- op.clipY = effectiveRect.y;
86
- op.clipWidth = effectiveRect.width;
87
- op.clipHeight = effectiveRect.height;
88
- }
89
- else if (!clipRectStack.empty())
90
- // When we have no effect rect but the stack is not empty, we have clipped
91
- // the whole world away and don't need to render things.
92
- return;
93
-
94
- op.z = z;
41
+ if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
42
+ op.renderState.clipRect = *cr;
95
43
  ops.push_back(op);
96
44
  }
97
45
 
98
- void scheduleGL(std::tr1::function<void()> customCode, ZPos z)
46
+ void scheduleGL(Transform& transform, std::tr1::function<void()> glBlock, ZPos z)
99
47
  {
100
- code.insert(std::make_pair(z, customCode));
48
+ // TODO: Document this case: Clipped-away GL blocks are *not* being run.
49
+ if (clipRectStack.clippedWorldAway())
50
+ return;
51
+
52
+ int complementOfBlockIndex = ~(int)glBlocks.size();
53
+ glBlocks.push_back(glBlock);
54
+
55
+ DrawOp op;
56
+ op.renderState.transform = &transform;
57
+ op.verticesOrBlockIndex = complementOfBlockIndex;
58
+ if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
59
+ op.renderState.clipRect = *cr;
60
+ op.z = z;
61
+ ops.push_back(op);
101
62
  }
102
63
 
103
- void beginClipping(int x, int y, unsigned width, unsigned height)
64
+ void beginClipping(int x, int y, int width, int height)
104
65
  {
105
- ClipRect rect = { x, y, width, height };
106
- clipRectStack.push_back(rect);
107
- updateEffectiveRect();
66
+ clipRectStack.beginClipping(x, y, width, height);
108
67
  }
109
68
 
110
69
  void endClipping()
111
70
  {
112
- clipRectStack.pop_back();
113
- updateEffectiveRect();
71
+ clipRectStack.endClipping();
114
72
  }
115
73
 
116
74
  void performDrawOpsAndCode()
117
75
  {
118
- // Allows us to make some assumptions.
119
- if (ops.empty())
120
- {
121
- for (CodeMap::iterator it = code.begin(), end = code.end(); it != end; ++it)
122
- it->second();
123
- return;
124
- }
125
-
126
76
  // Apply Z-Ordering.
127
77
  std::stable_sort(ops.begin(), ops.end());
128
78
 
129
- // We will loop: Drawing DrawOps, execute custom code.
130
- // This means if there is no code, we just draw one batch
131
- // of DrawOps, so no performance is sacrified.
132
- DrawOps::const_iterator current = ops.begin(), last = ops.begin();
133
- CodeMap::const_iterator it = code.begin();
79
+ RenderStateManager manager;
80
+ #ifdef GOSU_IS_IPHONE
81
+ if (ops.empty())
82
+ return;
134
83
 
135
- while (true)
84
+ DrawOps::const_iterator current = ops.begin(), last = ops.end() - 1;
85
+ for (; current != last; ++current)
136
86
  {
137
- if (it == code.end())
138
- // Last or only batch of DrawOps:
139
- // Just draw everything.
140
- last = ops.end() - 1;
141
- else
142
- {
143
- // There is code waiting:
144
- // Only draw up to this Z level.
145
- while (last != ops.end() - 1 && (last + 1)->z < it->first)
146
- ++last;
147
- }
148
-
149
- if (current <= last)
87
+ manager.setRenderState(current->renderState);
88
+ current->perform(&*(current + 1));
89
+ }
90
+ manager.setRenderState(last->renderState);
91
+ last->perform(0);
92
+ #else
93
+ for (DrawOps::const_iterator current = ops.begin(), last = ops.end();
94
+ current != last; ++current)
95
+ {
96
+ manager.setRenderState(current->renderState);
97
+ if (current->verticesOrBlockIndex >= 0)
150
98
  {
151
- // Draw DrawOps until next code is due
152
- RenderState renderState;
153
- while (current < last)
154
- {
155
- DrawOps::const_iterator next = current + 1;
156
- current->perform(renderState, &*next);
157
- current = next;
158
- }
159
- last->perform(renderState, 0);
160
- ++current;
99
+ // Normal DrawOp, no GL code
100
+ current->perform(0); // next unused on desktop
161
101
  }
162
-
163
- // Draw next code, or break if there is none
164
- if (it == code.end())
165
- break;
166
102
  else
167
103
  {
168
- it->second();
169
- ++it;
104
+ // GL code
105
+ int blockIndex = ~current->verticesOrBlockIndex;
106
+ assert (blockIndex >= 0);
107
+ assert (blockIndex < glBlocks.size());
108
+ glBlocks[blockIndex]();
109
+ manager.enforceAfterUntrustedGL();
170
110
  }
171
111
  }
112
+ #endif
172
113
  }
173
114
 
174
115
  void clear()
175
116
  {
176
- // Not sure if Graphics::begin() should implicitly do that.
177
- //clipRectStack.clear();
178
- //effectiveRect.reset();
179
- code.clear();
117
+ glBlocks.clear();
180
118
  ops.clear();
181
119
  }
182
120
 
183
- void compileTo(VertexArray& va)
121
+ void compileTo(VertexArrays& vas)
184
122
  {
185
- if (!code.empty())
123
+ if (!glBlocks.empty())
186
124
  throw std::logic_error("Custom code cannot be recorded into a macro");
187
125
 
188
- va.reserve(ops.size());
189
126
  std::stable_sort(ops.begin(), ops.end());
190
127
  for (DrawOps::const_iterator op = ops.begin(), end = ops.end(); op != end; ++op)
191
- op->compileTo(va);
128
+ op->compileTo(vas);
192
129
  }
193
130
  };
194
131