@@ -519,8 +519,8 @@ -(NSInteger)globalSortOrder
519
519
520
520
@implementation CCRenderer {
521
521
GLuint _vao;
522
- GLuint _vbo ;
523
- GLuint _ebo ;
522
+ CCGraphicsBuffer _vertexBuffer ;
523
+ CCGraphicsBuffer _elementBuffer ;
524
524
525
525
CCRenderState *_renderState;
526
526
NSDictionary *_blendOptions;
@@ -534,12 +534,6 @@ @implementation CCRenderer {
534
534
NSMutableArray *_queueStack;
535
535
__unsafe_unretained CCRenderCommandDraw *_lastDrawCommand;
536
536
537
- CCVertex *_vertexes;
538
- GLsizei _vertexCount, _vertexCapacity;
539
-
540
- GLushort *_elements;
541
- GLsizei _elementCount, _elementCapacity;
542
-
543
537
NSUInteger _statDrawCommands;
544
538
}
545
539
@@ -556,22 +550,15 @@ -(void)invalidateState
556
550
-(instancetype )init
557
551
{
558
552
if ((self = [super init ])){
559
- glPushGroupMarkerEXT (0 , " CCRenderer: Init" );
560
-
561
- glGenBuffers (1 , &_vbo);
562
- glGenBuffers (1 , &_ebo);
563
-
564
- _vao = [CCShader createVAOforCCVertexBuffer: _vbo elementBuffer: _ebo];
553
+ const NSUInteger CCRENDERER_INITIAL_VERTEX_CAPACITY = 16 *1024 ;
554
+ [self initBuffer: &_vertexBuffer capacity: CCRENDERER_INITIAL_VERTEX_CAPACITY elementSize: sizeof (CCVertex) type: GL_ARRAY_BUFFER];
555
+ [self initBuffer: &_elementBuffer capacity: CCRENDERER_INITIAL_VERTEX_CAPACITY*1.5 elementSize: sizeof (uint16_t ) type: GL_ELEMENT_ARRAY_BUFFER];
565
556
557
+ glPushGroupMarkerEXT (0 , " CCRenderer: Init" );
558
+ _vao = [CCShader createVAOforCCVertexBuffer: (GLuint)_vertexBuffer.data elementBuffer: (GLuint)_elementBuffer.data];
566
559
glPopGroupMarkerEXT ();
567
560
568
561
_queue = [NSMutableArray array ];
569
-
570
- _vertexCapacity = 2 *1024 ;
571
- _vertexes = calloc (_vertexCapacity, sizeof (*_vertexes));
572
-
573
- _elementCapacity = 2 *1024 ;
574
- _elements = calloc (_elementCapacity, sizeof (*_elements));
575
562
}
576
563
577
564
return self;
@@ -580,15 +567,11 @@ -(instancetype)init
580
567
-(void )dealloc
581
568
{
582
569
glPushGroupMarkerEXT (0 , " CCRenderer: Dealloc" );
583
-
584
570
glDeleteVertexArrays (1 , &_vao);
585
- glDeleteBuffers (1 , &_vbo);
586
- glDeleteBuffers (1 , &_ebo);
587
-
588
571
glPopGroupMarkerEXT ();
589
572
590
- free (_vertexes) ;
591
- free (_elements) ;
573
+ [ self destroyBuffer: &_vertexBuffer] ;
574
+ [ self destroyBuffer: &_elementBuffer] ;
592
575
}
593
576
594
577
static NSString *CURRENT_RENDERER_KEY = @" CCRendererCurrent" ;
@@ -704,79 +687,49 @@ -(void)enqueueClear:(GLbitfield)mask color:(GLKVector4)color4 depth:(GLclampf)de
704
687
} globalSortOrder: globalSortOrder debugLabel: @" CCRenderer: Clear" threadSafe: YES ];
705
688
}
706
689
707
- -(CCVertex *)ensureVertexCapacity : (NSUInteger )requestedCount
708
- {
709
- NSAssert (requestedCount > 0 , @" Vertex count must be positive." );
710
-
711
- GLsizei required = _vertexCount + (GLsizei)requestedCount;
712
- if (required > _vertexCapacity){
713
- // Double the size of the buffer until it fits.
714
- while (required >= _vertexCapacity) _vertexCapacity *= 2 ;
715
-
716
- _vertexes = realloc (_vertexes, _vertexCapacity*sizeof (*_vertexes));
717
- }
718
-
719
- // Return the triangle buffer pointer.
720
- return &_vertexes[_vertexCount];
721
- }
722
-
723
- -(GLushort *)ensureElementCapacity : (NSUInteger )requestedCount
690
+ -(CCRenderBuffer)enqueueTriangles : (NSUInteger )triangleCount andVertexes : (NSUInteger )vertexCount withState : (CCRenderState *)renderState globalSortOrder : (NSInteger )globalSortOrder ;
724
691
{
725
- NSAssert (requestedCount > 0 , @" Element count must be positive." );
692
+ // Need to record the first vertex or element index before pushing more vertexes.
693
+ size_t firstVertex = _vertexBuffer.count ;
694
+ size_t firstElement = _elementBuffer.count ;
726
695
727
- GLsizei required = _elementCount + (GLsizei)requestedCount;
728
- if (required > _elementCapacity){
729
- // Double the size of the buffer until it fits.
730
- while (required >= _elementCapacity) _elementCapacity *= 2 ;
731
-
732
- _elements = realloc (_elements, _elementCapacity*sizeof (*_elements));
733
- }
696
+ size_t elementCount = 3 *triangleCount;
697
+ CCVertex *vertexes = CCGraphicsBufferPushElements (&_vertexBuffer, vertexCount, self);
698
+ GLushort *elements = CCGraphicsBufferPushElements (&_elementBuffer, elementCount, self);
734
699
735
- // Return the triangle buffer pointer.
736
- return &_elements[_elementCount];
737
- }
738
-
739
- -(CCRenderBuffer)enqueueTriangles : (NSUInteger )triangleCount andVertexes : (NSUInteger )vertexCount withState : (CCRenderState *)renderState globalSortOrder : (NSInteger )globalSortOrder ;
740
- {
741
700
__unsafe_unretained CCRenderCommandDraw *previous = _lastDrawCommand;
742
- CCVertex *vertexes = [self ensureVertexCapacity: vertexCount];
743
- GLushort *elements = [self ensureElementCapacity: 3 *triangleCount];
744
-
745
701
if (previous && previous->_renderState == renderState && previous->_globalSortOrder == globalSortOrder){
746
702
// Batch with the previous command.
747
- [previous batchElements: (GLsizei)( 3 *triangleCount) ];
703
+ [previous batchElements: (GLsizei)elementCount ];
748
704
} else {
749
705
// Start a new command.
750
- CCRenderCommandDraw *command = [[CCRenderCommandDraw alloc ] initWithMode: GL_TRIANGLES renderState: renderState first: (GLint)_elementCount elements: (GLsizei)( 3 *triangleCount) globalSortOrder: globalSortOrder];
706
+ CCRenderCommandDraw *command = [[CCRenderCommandDraw alloc ] initWithMode: GL_TRIANGLES renderState: renderState first: (GLint)firstElement elements: (GLsizei)elementCount globalSortOrder: globalSortOrder];
751
707
[_queue addObject: command];
752
708
_lastDrawCommand = command;
753
709
}
754
710
755
- CCRenderBuffer buffer = {vertexes, elements, _vertexCount};
756
- _vertexCount += vertexCount;
757
- _elementCount += 3 *triangleCount;
758
-
759
711
_statDrawCommands++;
760
- return buffer ;
712
+ return (CCRenderBuffer){vertexes, elements, firstVertex} ;
761
713
}
762
714
763
715
-(CCRenderBuffer)enqueueLines : (NSUInteger )lineCount andVertexes : (NSUInteger )vertexCount withState : (CCRenderState *)renderState globalSortOrder : (NSInteger )globalSortOrder ;
764
716
{
765
- CCVertex *vertexes = [self ensureVertexCapacity: vertexCount];
766
- GLushort *elements = [self ensureElementCapacity: 2 *lineCount];
717
+ // Need to record the first vertex or element index before pushing more vertexes.
718
+ size_t firstVertex = _vertexBuffer.count ;
719
+ size_t firstElement = _elementBuffer.count ;
720
+
721
+ size_t elementCount = 2 *lineCount;
722
+ CCVertex *vertexes = CCGraphicsBufferPushElements (&_vertexBuffer, vertexCount, self);
723
+ GLushort *elements = CCGraphicsBufferPushElements (&_elementBuffer, elementCount, self);
767
724
768
- CCRenderCommandDraw *command = [[CCRenderCommandDraw alloc ] initWithMode: GL_LINES renderState: renderState first: (GLint)_elementCount elements: (GLsizei)( 2 *lineCount) globalSortOrder: globalSortOrder];
725
+ CCRenderCommandDraw *command = [[CCRenderCommandDraw alloc ] initWithMode: GL_LINES renderState: renderState first: (GLint)firstElement elements: (GLsizei)elementCount globalSortOrder: globalSortOrder];
769
726
[_queue addObject: command];
770
727
771
728
// Line drawing commands are currently intended for debugging and cannot be batched.
772
729
_lastDrawCommand = nil ;
773
730
774
- CCRenderBuffer buffer = {vertexes, elements, _vertexCount};
775
- _vertexCount += vertexCount;
776
- _elementCount += 2 *lineCount;
777
-
778
731
_statDrawCommands++;
779
- return buffer ;
732
+ return (CCRenderBuffer){vertexes, elements, firstVertex} ;
780
733
}
781
734
782
735
-(void )enqueueBlock : (void (^)())block globalSortOrder : (NSInteger )globalSortOrder debugLabel : (NSString *)debugLabel threadSafe : (BOOL )threadsafe
@@ -828,13 +781,8 @@ -(void)flush
828
781
829
782
glInsertEventMarkerEXT (0 , " Buffering" );
830
783
831
- glBindBuffer (GL_ARRAY_BUFFER, _vbo);
832
- glBufferData (GL_ARRAY_BUFFER, _vertexCount*sizeof (*_vertexes), _vertexes, GL_STREAM_DRAW);
833
- glBindBuffer (GL_ARRAY_BUFFER, 0 );
834
-
835
- glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, _ebo);
836
- glBufferData (GL_ELEMENT_ARRAY_BUFFER, _elementCount*sizeof (*_elements), _elements, GL_STREAM_DRAW);
837
- glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0 );
784
+ [self commitBuffer: &_vertexBuffer];
785
+ [self commitBuffer: &_elementBuffer];
838
786
CC_CHECK_GL_ERROR_DEBUG ();
839
787
840
788
SortQueue (_queue);
@@ -843,15 +791,56 @@ -(void)flush
843
791
844
792
// NSLog(@"Draw commands: %d, Draw calls: %d", _statDrawCommands, _queue.count);
845
793
_statDrawCommands = 0 ;
846
- _queue = [[ NSMutableArray alloc ] init ];
794
+ [ _queue removeAllObjects ];
847
795
848
- _vertexCount = 0 ;
849
- _elementCount = 0 ;
796
+ [ self prepareBuffer: &_vertexBuffer] ;
797
+ [ self prepareBuffer: &_elementBuffer] ;
850
798
851
799
glPopGroupMarkerEXT ();
852
800
CC_CHECK_GL_ERROR_DEBUG ();
853
801
854
802
// CC_INCREMENT_GL_DRAWS(1);
855
803
}
856
804
805
+ // MARK: Buffer Management Methods
806
+
807
+ -(void )initBuffer : (CCGraphicsBuffer *)buffer capacity : (NSUInteger )capacity elementSize : (size_t )elementSize type : (intptr_t )type
808
+ {
809
+ buffer->count = 0 ;
810
+ buffer->capacity = capacity;
811
+ buffer->elementSize = elementSize;
812
+
813
+ buffer->ptr = calloc (capacity, elementSize);
814
+
815
+ GLuint glbuffer = 0 ;
816
+ glGenBuffers (1 , &glbuffer);
817
+ buffer->data = (intptr_t )glbuffer;
818
+ buffer->type = type;
819
+ }
820
+
821
+ -(void )resizeBuffer : (CCGraphicsBuffer *)buffer capacity : (size_t )capacity
822
+ {
823
+ buffer->ptr = realloc (buffer->ptr , capacity*buffer->elementSize );
824
+ buffer->capacity = capacity;
825
+ }
826
+
827
+ -(void )destroyBuffer : (CCGraphicsBuffer *)buffer
828
+ {
829
+ free (buffer->ptr );
830
+ glDeleteBuffers (1 , (GLuint *)&buffer->data );
831
+ }
832
+
833
+ -(void )prepareBuffer : (CCGraphicsBuffer *)buffer
834
+ {
835
+ buffer->count = 0 ;
836
+ }
837
+
838
+ -(void )commitBuffer : (CCGraphicsBuffer *)buffer
839
+ {
840
+ GLenum type = (GLenum)buffer->type ;
841
+ glBindBuffer (type, (GLuint)buffer->data );
842
+ glBufferData (type, buffer->count *buffer->elementSize , buffer->ptr , GL_STREAM_DRAW);
843
+ glBindBuffer (type, 0 );
844
+ }
845
+
857
846
@end
0 commit comments