Last active
December 16, 2015 01:09
-
-
Save PrimaryFeather/5352978 to your computer and use it in GitHub Desktop.
An example for a custom display object for the Sparrow Framework.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "SPDisplayObject.h" | |
@interface Polygon : SPDisplayObject | |
- (id)initWithRadius:(float)radius numEdges:(int)numEdges color:(uint)color; | |
- (id)initWithRadius:(float)radius numEdges:(int)numEdges; | |
@property (nonatomic, assign) int numEdges; | |
@property (nonatomic, assign) float radius; | |
@property (nonatomic, assign) uint color; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Polygon.h" | |
@implementation Polygon | |
{ | |
float _radius; | |
int _numEdges; | |
uint _color; | |
BOOL _requiresUpdate; | |
SPBaseEffect *_baseEffect; | |
SPVertexData *_vertexData; | |
uint _vertexBufferName; | |
ushort *_indexData; | |
uint _indexBufferName; | |
} | |
@synthesize color = _color; | |
@synthesize radius = _radius; | |
@synthesize numEdges = _numEdges; | |
- (id)initWithRadius:(float)radius numEdges:(int)numEdges color:(uint)color | |
{ | |
if ((self = [super init])) | |
{ | |
_radius = radius; | |
_numEdges = MAX(3, numEdges); | |
_color = color; | |
_vertexData = [[SPVertexData alloc] init]; | |
_baseEffect = [[SPBaseEffect alloc] init]; | |
_requiresUpdate = YES; | |
} | |
return self; | |
} | |
- (id)initWithRadius:(float)radius numEdges:(int)numEdges | |
{ | |
return [self initWithRadius:radius numEdges:numEdges color:SP_WHITE]; | |
} | |
- (id)init | |
{ | |
return [self initWithRadius:32.0f numEdges:5]; | |
} | |
- (void)dealloc | |
{ | |
free(_indexData); | |
} | |
- (void)update | |
{ | |
[self setupVertices]; | |
[self createBuffers]; | |
_requiresUpdate = NO; | |
} | |
- (void)setupVertices | |
{ | |
// set up vertex data | |
_vertexData.numVertices = _numEdges + 1; | |
_vertexData.color = _color; | |
for (int i=0; i<_numEdges; ++i) | |
{ | |
SPPoint *edge = [[SPPoint alloc] initWithPolarLength:_radius angle:i*2*PI / _numEdges]; | |
[_vertexData setPosition:edge atIndex:i]; | |
} | |
[_vertexData setPositionWithX:0.0f y:0.0f atIndex:_numEdges]; // center vertex | |
// set up index data | |
int numIndices = _numEdges * 3; | |
if (!_indexData) _indexData = malloc(sizeof(ushort) * numIndices); | |
else _indexData = realloc(_indexData, sizeof(ushort) * numIndices); | |
for (int i=0; i<_numEdges; ++i) | |
{ | |
_indexData[i*3] = _numEdges; | |
_indexData[i*3+1] = i; | |
_indexData[i*3+2] = (i+1) % _numEdges; | |
} | |
} | |
- (void)createBuffers | |
{ | |
int numVertices = _numEdges + 1; | |
int numIndices = _numEdges * 3; | |
if (_vertexBufferName) glDeleteBuffers(1, &_vertexBufferName); | |
if (_indexBufferName) glDeleteBuffers(1, &_indexBufferName); | |
glGenBuffers(1, &_vertexBufferName); | |
glGenBuffers(1, &_indexBufferName); | |
if (!_vertexBufferName || !_indexBufferName) | |
[NSException raise:SP_EXC_OPERATION_FAILED format:@"could not create vertex buffers"]; | |
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferName); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(SPVertex) * numVertices, _vertexData.vertices, | |
GL_STATIC_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferName); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort) * numIndices, _indexData, GL_STATIC_DRAW); | |
} | |
- (void)render:(SPRenderSupport *)support | |
{ | |
if (_requiresUpdate) [self update]; | |
[support finishQuadBatch]; // finish previously batched quads | |
[support addDrawCalls:1]; // update stats display | |
_baseEffect.mvpMatrix = support.mvpMatrix; | |
_baseEffect.alpha = support.alpha; | |
[_baseEffect prepareToDraw]; | |
[SPBlendMode applyBlendFactorsForBlendMode:support.blendMode | |
premultipliedAlpha:_vertexData.premultipliedAlpha]; | |
int attribPosition = _baseEffect.attribPosition; | |
int attribColor = _baseEffect.attribColor; | |
glEnableVertexAttribArray(attribPosition); | |
glEnableVertexAttribArray(attribColor); | |
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferName); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferName); | |
glVertexAttribPointer(attribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(SPVertex), | |
(void *)(offsetof(SPVertex, position))); | |
glVertexAttribPointer(attribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SPVertex), | |
(void *)(offsetof(SPVertex, color))); | |
int numIndices = _numEdges * 3; | |
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0); | |
} | |
- (SPRectangle*)boundsInSpace:(SPDisplayObject*)targetSpace | |
{ | |
SPMatrix *matrix = [self transformationMatrixToSpace:targetSpace]; | |
return [_vertexData boundsAfterTransformation:matrix]; | |
} | |
- (void)setNumEdges:(int)numEdges | |
{ | |
if (numEdges != _numEdges) | |
{ | |
_numEdges = numEdges; | |
_requiresUpdate = YES; | |
} | |
} | |
- (void)setRadius:(float)radius | |
{ | |
if (radius != _radius) | |
{ | |
_radius = radius; | |
_requiresUpdate = YES; | |
} | |
} | |
- (void)setColor:(uint)color | |
{ | |
if (color != _color) | |
{ | |
_color = color; | |
_requiresUpdate = YES; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment