@@ -124,30 +124,55 @@ -(void)enqueueTriangles:(CCRenderer *)renderer transform:(const GLKMatrix4 *)tra
124124
125125@implementation CCRenderer (NoARC)
126126
127+ // Positive offset of the vertex allocation to prevent overlapping a boundary.
128+ static inline NSUInteger
129+ PageOffset (NSUInteger firstVertex, NSUInteger vertexCount)
130+ {
131+ NSCAssert (vertexCount < UINT16_MAX + 1 , @" Too many vertexes for a single draw count." );
132+
133+ // Space remaining on the current vertex page.
134+ NSUInteger remain = (firstVertex | UINT16_MAX) - firstVertex + 1 ;
135+
136+ if (remain >= vertexCount){
137+ // Allocation will not overlap a page boundary.
138+ return 0 ;
139+ } else {
140+ return remain;
141+ }
142+ }
143+
127144-(CCRenderBuffer)enqueueTriangles : (NSUInteger )triangleCount andVertexes : (NSUInteger )vertexCount withState : (CCRenderState *)renderState globalSortOrder : (NSInteger )globalSortOrder ;
128145{
129146 // Need to record the first vertex or element index before pushing more vertexes.
130147 NSUInteger firstVertex = _buffers->_vertexBuffer ->_count ;
131148 NSUInteger firstIndex = _buffers->_indexBuffer ->_count ;
132149
150+ // Value is 0 unless there a page boundary overlap would occur.
151+ NSUInteger vertexPageOffset = PageOffset (firstVertex, vertexCount);
152+
153+ // Split vertexes into pages of 2^16 vertexes since GLES2 requires indexing with shorts.
154+ NSUInteger vertexPage = (firstVertex + vertexPageOffset) >> 16 ;
155+ NSUInteger vertexPageIndex = (firstVertex + vertexPageOffset) & 0xFFFF ;
156+
157+ // Ensure that the buffers have enough storage space.
133158 NSUInteger indexCount = 3 *triangleCount;
134- CCVertex *vertexes = CCGraphicsBufferPushElements (_buffers->_vertexBuffer , vertexCount);
159+ CCVertex *vertexes = CCGraphicsBufferPushElements (_buffers->_vertexBuffer , vertexCount + vertexPageOffset );
135160 uint16_t *elements = CCGraphicsBufferPushElements (_buffers->_indexBuffer , indexCount);
136161
137162 CCRenderCommandDraw *previous = _lastDrawCommand;
138- if (previous && previous->_renderState == renderState && previous->_globalSortOrder == globalSortOrder){
163+ if (previous && previous->_renderState == renderState && previous->_globalSortOrder == globalSortOrder && previous-> _vertexPage == vertexPage ){
139164 // Batch with the previous command.
140165 [previous batch: indexCount];
141166 } else {
142167 // Start a new command.
143- CCRenderCommandDraw *command = [[CCRenderCommandDrawClass alloc ] initWithMode: CCRenderCommandDrawTriangles renderState: renderState first : firstIndex count: indexCount globalSortOrder: globalSortOrder];
168+ CCRenderCommandDraw *command = [[CCRenderCommandDrawClass alloc ] initWithMode: CCRenderCommandDrawTriangles renderState: renderState firstIndex : firstIndex vertexPage: vertexPage count: indexCount globalSortOrder: globalSortOrder];
144169 [_queue addObject: command];
145170 [command release ];
146171
147172 _lastDrawCommand = command;
148173 }
149174
150- return (CCRenderBuffer){vertexes, elements, firstVertex };
175+ return (CCRenderBuffer){vertexes, elements, vertexPageIndex };
151176}
152177
153178-(CCRenderBuffer)enqueueLines : (NSUInteger )lineCount andVertexes : (NSUInteger )vertexCount withState : (CCRenderState *)renderState globalSortOrder : (NSInteger )globalSortOrder ;
@@ -156,32 +181,41 @@ -(CCRenderBuffer)enqueueLines:(NSUInteger)lineCount andVertexes:(NSUInteger)vert
156181 NSUInteger firstVertex = _buffers->_vertexBuffer ->_count ;
157182 NSUInteger firstIndex = _buffers->_indexBuffer ->_count ;
158183
184+ // Value is 0 unless there a page boundary overlap would occur.
185+ NSUInteger vertexPageOffset = PageOffset (firstVertex, vertexCount);
186+
187+ // Split vertexes into pages of 2^16 vertexes since GLES2 requires indexing with shorts.
188+ NSUInteger vertexPage = (firstVertex + vertexPageOffset) >> 16 ;
189+ NSUInteger vertexPageIndex = (firstVertex + vertexPageOffset) & 0xFFFF ;
190+
191+ // Ensure that the buffers have enough storage space.
159192 NSUInteger indexCount = 2 *lineCount;
160- CCVertex *vertexes = CCGraphicsBufferPushElements (_buffers->_vertexBuffer , vertexCount);
193+ CCVertex *vertexes = CCGraphicsBufferPushElements (_buffers->_vertexBuffer , vertexCount + vertexPageOffset );
161194 uint16_t *elements = CCGraphicsBufferPushElements (_buffers->_indexBuffer , indexCount);
162195
163- CCRenderCommandDraw *command = [[CCRenderCommandDrawClass alloc ] initWithMode: CCRenderCommandDrawLines renderState: renderState first : firstIndex count: indexCount globalSortOrder: globalSortOrder];
196+ CCRenderCommandDraw *command = [[CCRenderCommandDrawClass alloc ] initWithMode: CCRenderCommandDrawLines renderState: renderState firstIndex : firstIndex vertexPage: vertexPage count: indexCount globalSortOrder: globalSortOrder];
164197 [_queue addObject: command];
165198 [command release ];
166199
167200 // Line drawing commands are currently intended for debugging and cannot be batched.
168201 _lastDrawCommand = nil ;
169202
170- return (CCRenderBuffer){vertexes, elements, firstVertex };
203+ return (CCRenderBuffer){vertexes, elements, vertexPageIndex };
171204}
172205
173206static inline void
174- CCRendererBindBuffers (CCRenderer *self, BOOL bind)
207+ CCRendererBindBuffers (CCRenderer *self, BOOL bind, NSUInteger vertexPage )
175208{
176- if (bind != self->_buffersBound ){
177- [self ->_buffers bind: bind];
209+ if (bind != self->_buffersBound || vertexPage != self-> _vertexPageBound ){
210+ [self ->_buffers bind: bind vertexPage: vertexPage ];
178211 self->_buffersBound = bind;
212+ self->_vertexPageBound = vertexPage;
179213 }
180214}
181215
182- -(void )bindBuffers : (BOOL )bind
216+ -(void )bindBuffers : (BOOL )bind vertexPage : ( NSUInteger ) vertexPage
183217{
184- CCRendererBindBuffers (self, bind);
218+ CCRendererBindBuffers (self, bind, vertexPage );
185219}
186220
187221
@@ -270,11 +304,11 @@ -(void)invokeOnRenderer:(CCRenderer *)renderer
270304{
271305 CCGL_DEBUG_PUSH_GROUP_MARKER (" CCRendererCommandDraw: Invoke" );
272306
273- CCRendererBindBuffers (renderer, YES );
307+ CCRendererBindBuffers (renderer, YES , _vertexPage );
274308 CCRenderStateGLTransition ((CCRenderStateGL *)_renderState, renderer, (CCRenderStateGL *)renderer->_renderState );
275309 renderer->_renderState = _renderState;
276310
277- glDrawElements (GLDrawModes[_mode], (GLsizei)_count, GL_UNSIGNED_SHORT, (GLvoid *)(_first *sizeof (GLushort)));
311+ glDrawElements (GLDrawModes[_mode], (GLsizei)_count, GL_UNSIGNED_SHORT, (GLvoid *)(_firstIndex *sizeof (GLushort)));
278312 CC_INCREMENT_GL_DRAWS (1 );
279313
280314 CCGL_DEBUG_POP_GROUP_MARKER ();
0 commit comments