Last active
August 29, 2015 14:06
-
-
Save mataneil/4745f7b707f0659b9fc6 to your computer and use it in GitHub Desktop.
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
// | |
// Created by Matan Eilat on 9/21/14. | |
// Copyright 2014 JoyTunes. All rights reserved. | |
// | |
// This program is free software; you can redistribute it and/or modify | |
// it under the terms of the Simplified BSD License. | |
// | |
#import <Foundation/Foundation.h> | |
#import <Sparrow/SPDisplayObject.h> | |
@interface JTLine : SPDisplayObject | |
+ (JTLine *)lineWithLength:(float)length; | |
+ (JTLine *)lineWithLength:(float)length andThickness:(float)thickness; | |
+ (JTLine *)lineWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2; | |
+ (JTLine *)lineWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 andThickness:(float)thickness; | |
@property (nonatomic, assign) float x2; | |
@property (nonatomic, assign) float y2; | |
@property (nonatomic, assign) uint color; | |
@property (nonatomic, assign) uint startColor; | |
@property (nonatomic, assign) uint endColor; | |
@property (nonatomic, assign) float startAlpha; | |
@property (nonatomic, assign) float endAlpha; | |
@property (nonatomic, assign) float thickness; | |
- (JTLine *)initWithSize:(float)length; | |
- (JTLine *)initWithLength:(float)length andThickness:(float)thickness; | |
- (JTLine *)initWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2; | |
- (JTLine *)initWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 andThickness:(float)thickness; | |
@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
// | |
// Created by Matan Eilat on 9/21/14. | |
// Copyright 2014 JoyTunes. All rights reserved. | |
// | |
// This program is free software; you can redistribute it and/or modify | |
// it under the terms of the Simplified BSD License. | |
// | |
#import <Sparrow/SPBaseEffect.h> | |
#import <Sparrow/SPVertexData.h> | |
#import <Sparrow/SPRenderSupport.h> | |
#import <Sparrow/SPPoint.h> | |
#import <Sparrow/SPBlendMode.h> | |
#import <GLKit/GLKit.h> | |
#import "JTLine.h" | |
@interface JTLine () | |
@property (nonatomic, strong) SPBaseEffect *baseEffect; | |
@property (nonatomic, strong) SPVertexData *vertexData; | |
@property (nonatomic, assign) GLuint vertexBufferName; | |
@property (nonatomic, assign) BOOL syncRequired; | |
@end | |
@implementation JTLine | |
- (JTLine *)init { | |
return [self initWithCoords:0:0:50.0f:0 andThickness:1.0f]; | |
} | |
- (JTLine *)initWithSize:(float)length { | |
return [self initWithCoords:0:0:length:0 andThickness:1.0f]; | |
} | |
- (JTLine *)initWithLength:(float)length andThickness:(float)thickness { | |
return [self initWithCoords:0:0:length:0 andThickness:thickness]; | |
} | |
- (JTLine *)initWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 { | |
return [self initWithCoords:x1:y1:x2:y2 andThickness:1.0f]; | |
} | |
- (JTLine *)initWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 andThickness:(float)thickness { | |
self = [super init]; | |
if (self) { | |
self.thickness = thickness; | |
self.baseEffect = [[SPBaseEffect alloc] init]; | |
[self setupBufferDataWithCoords:x1 :y1 :x2 :y2]; | |
self.syncRequired = YES; | |
} | |
return self; | |
} | |
- (void)setupBufferDataWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 { | |
self.vertexData = [[SPVertexData alloc] initWithSize:2 premultipliedAlpha:NO]; | |
[self.vertexData setPositionWithX:x1 y:y1 atIndex:0]; | |
[self.vertexData setPositionWithX:x2 y:y2 atIndex:1]; | |
for (int i = 0; i < self.vertexData.numVertices; ++i) { | |
self.vertexData.vertices[i].color = SPVertexColorMakeWithColorAndAlpha(0xffffff, 1.0f); | |
} | |
} | |
+ (JTLine *)lineWithLength:(float)length { | |
return [[JTLine alloc] initWithSize:length]; | |
} | |
+ (JTLine *)lineWithLength:(float)length andThickness:(float)thickness { | |
return [[JTLine alloc] initWithLength:length andThickness:thickness]; | |
} | |
+ (JTLine *)lineWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 { | |
return [[JTLine alloc] initWithCoords:x1:y1:x2:y2]; | |
} | |
+ (JTLine *)lineWithCoords:(float)x1 :(float)y1 :(float)x2 :(float)y2 andThickness:(float)thickness { | |
return [[JTLine alloc] initWithCoords:x1:y1:x2:y2 andThickness:thickness]; | |
} | |
- (void)dealloc { | |
[self destroyBuffers]; | |
} | |
- (void)render:(SPRenderSupport *)support { | |
if (self.syncRequired) { | |
[self syncBuffers]; | |
} | |
[support finishQuadBatch]; | |
self.baseEffect.mvpMatrix = support.mvpMatrix; | |
self.baseEffect.alpha = support.alpha; | |
[self.baseEffect prepareToDraw]; | |
int attribPosition = self.baseEffect.attribPosition; | |
int attribColor = self.baseEffect.attribColor; | |
[SPBlendMode applyBlendFactorsForBlendMode:support.blendMode | |
premultipliedAlpha:self.vertexData.premultipliedAlpha]; | |
glEnableVertexAttribArray(attribPosition); | |
glEnableVertexAttribArray(attribColor); | |
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferName); | |
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))); | |
glLineWidth(self.thickness); | |
glDrawArrays(GL_LINES, 0, 2); | |
} | |
- (void)syncBuffers { | |
if (!self.vertexBufferName) { | |
[self createBuffers]; | |
} | |
// Bind the buffer object array to the GL_ARRAY_BUFFER target buffer | |
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferName); | |
// Send the line data over to the target buffer in GPU RAM | |
glBufferData( | |
GL_ARRAY_BUFFER, // the target buffer | |
sizeof(SPVertex) * self.vertexData.numVertices, // the number of bytes to put into the buffer | |
self.vertexData.vertices, // a pointer to the data being copied | |
GL_STATIC_DRAW); // the usage pattern of the data | |
self.syncRequired = NO; | |
} | |
- (void)createBuffers { | |
// First, we destory the existing buffers. | |
[self destroyBuffers]; | |
// Have OpenGL generate a buffer name and store it in the buffer object array | |
glGenBuffers(1, &_vertexBufferName); | |
self.syncRequired = YES; | |
} | |
- (void)destroyBuffers { | |
if (_vertexBufferName) { | |
glDeleteBuffers(1, &_vertexBufferName); | |
_vertexBufferName = 0; | |
} | |
} | |
- (SPRectangle *)boundsInSpace:(SPDisplayObject *)targetSpace { | |
SPMatrix *matrix = targetSpace == self ? nil : [self transformationMatrixToSpace:targetSpace]; | |
return [self.vertexData boundsAfterTransformation:matrix atIndex:0 numVertices:2]; | |
} | |
- (void)setX2:(float)x2 { | |
SPPoint *currentPosition = [self.vertexData positionAtIndex:1]; | |
[self.vertexData setPositionWithX:x2 y:currentPosition.y atIndex:1]; | |
self.syncRequired = YES; | |
} | |
- (void)setY2:(float)y2 { | |
SPPoint *currentPosition = [self.vertexData positionAtIndex:1]; | |
[self.vertexData setPositionWithX:currentPosition.x y:y2 atIndex:1]; | |
self.syncRequired = YES; | |
} | |
- (void)setColor:(uint)color { | |
[self.vertexData setColor:color]; | |
self.syncRequired = YES; | |
} | |
- (void)setStartColor:(uint)color { | |
[self.vertexData setColor:color atIndex:0]; | |
self.syncRequired = YES; | |
} | |
- (void)setEndColor:(uint)color { | |
[self.vertexData setColor:color atIndex:0]; | |
self.syncRequired = YES; | |
} | |
- (void)setStartAlpha:(float)alpha { | |
if (alpha < 0) alpha = 0; | |
if (alpha > 1.0f) alpha = 1.0f; | |
[self.vertexData setAlpha:alpha atIndex:0]; | |
self.syncRequired = YES; | |
} | |
- (void)setEndAlpha:(float)alpha { | |
if (alpha < 0) alpha = 0; | |
if (alpha > 1.0f) alpha = 1.0f; | |
[self.vertexData setAlpha:alpha atIndex:1]; | |
self.syncRequired = YES; | |
} | |
- (float)x2 { | |
return [self.vertexData positionAtIndex:1].x; | |
} | |
- (float)y2 { | |
return [self.vertexData positionAtIndex:1].y; | |
} | |
- (uint)color { | |
return self.startColor; | |
} | |
- (uint)startColor { | |
return [self.vertexData colorAtIndex:0]; | |
} | |
- (uint)endColor { | |
return [self.vertexData colorAtIndex:1]; | |
} | |
- (float)startAlpha { | |
return [self.vertexData alphaAtIndex:0]; | |
} | |
- (float)endAlpha { | |
return [self.vertexData alphaAtIndex:1]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment