gosu 0.7.38 → 0.7.39

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