Created
December 2, 2011 11:01
-
-
Save hiepnd/1422805 to your computer and use it in GitHub Desktop.
GVLoopSprite - Infinite spheral looping sprite
This file contains hidden or 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
// | |
// GVLoopSprite.h | |
// GVScroll | |
// | |
// Created by Ngo Duc Hiep on 10/19/11. | |
// Copyright 2011 Gameville Studios. All rights reserved. | |
// | |
#import "cocos2d.h" | |
#define GVLS_USE_VBO 1 | |
#if GVLS_USE_VBO | |
#define GVLS_VERTICES_VBO 0 | |
#define GVLS_TEXCOORD_VBO 1 | |
#define GVLS_INDICES_VBO 2 | |
#endif | |
@interface GVLoopSprite : CCNode { | |
ccGridSize gridSize; | |
CCTexture2D *texture; | |
GLfloat *vertices; | |
GLfloat *coordinates; | |
GLushort *indices; | |
CGPoint textCoorOrigin; | |
GLfloat cx, cy; | |
#if GVLS_USE_VBO | |
GLuint vboids[3]; | |
#endif | |
} | |
@property(nonatomic, retain) CCTexture2D *texture; | |
- (id) initWithContentSize:(CGSize) size texture:(CCTexture2D *) texture gridSize:(ccGridSize) gridsize; | |
+ (id) loopSpriteWithContentSize:(CGSize) size texture:(CCTexture2D *) texture gridSize:(ccGridSize) gridsize; | |
- (void) setZ:(float) z; | |
- (void) setR:(float) r0 z:(float) z; | |
- (void) moveBy:(CGPoint) move; | |
@end |
This file contains hidden or 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
// | |
// GVLoopSprite.m | |
// GVScroll | |
// | |
// Created by Ngo Duc Hiep on 10/19/11. | |
// Copyright 2011 Gameville Studios. All rights reserved. | |
// | |
#define _LINDEX(i,j) ((i) + (gridSize.x + 1) * (j)) | |
#define _LSET_VERTICE(index,x,y,z) \ | |
vertices[3*(index)] = x; \ | |
vertices[3*(index)+1] = y; \ | |
vertices[3*(index)+2] = z; | |
#define _LGET_VERTICE(o,i,j) \ | |
(o)->x = vertices[3*_LINDEX(i,j)]; \ | |
(o)->y = vertices[3*_LINDEX(i,j)+1]; \ | |
(o)->z = vertices[3*_LINDEX(i,j)+2]; | |
#define _LSET_TEXCOOR(index,x,y) \ | |
coordinates[2*(index)] = x; \ | |
coordinates[2*(index)+1] = y; | |
#import "GVLoopSprite.h" | |
@interface GVLoopSprite(Private) | |
- (void) initVertices; | |
- (void) updateTexCoords; | |
- (void) initIndices; | |
@end | |
@implementation GVLoopSprite(Private) | |
- (void) initVertices{ | |
float dx = contentSizeInPixels_.width / gridSize.x; | |
float dy = contentSizeInPixels_.height / gridSize.y; | |
for (int i = 0; i <= gridSize.x; i++) { | |
for (int j = 0; j <= gridSize.y; j++) { | |
_LSET_VERTICE(_LINDEX(i, j),i * dx - contentSizeInPixels_.width/2,j * dy - contentSizeInPixels_.height/2,0); | |
} | |
} | |
#if GVLS_USE_VBO | |
int n = (gridSize.x + 1) * (gridSize.y + 1); | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_VERTICES_VBO]); | |
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices[0])*n*3, vertices); | |
free(vertices); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
#endif | |
} | |
- (void) updateTexCoords{ | |
for (int i = 0; i <= gridSize.x; i++) { | |
for (int j = 0; j <= gridSize.y; j++) { | |
_LSET_TEXCOOR(_LINDEX(i, j),textCoorOrigin.x + i * cx, textCoorOrigin.y + j * cy); | |
} | |
} | |
#if GVLS_USE_VBO | |
int n = (gridSize.x + 1) * (gridSize.y + 1); | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_TEXCOORD_VBO]); | |
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(coordinates[0])*n*2, coordinates); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
#endif | |
} | |
- (void) initIndices{ | |
int i = 0, j = 0, r = 0; | |
BOOL forward = YES; | |
int c = 0; | |
while (r < 2*gridSize.x*gridSize.y + gridSize.y + 1) { | |
indices[r++] = _LINDEX(i, j); | |
if ((forward && j == c + 1 && i == gridSize.x) || (!forward && j == c + 1 && i == 0)) { | |
c++; | |
j++; | |
forward = !forward; | |
}else{ | |
if (j == c) { | |
j++; | |
}else{ | |
j--; | |
if (forward) { | |
i++; | |
}else{ | |
i--; | |
} | |
} | |
} | |
} | |
#if GVLS_USE_VBO | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboids[GVLS_INDICES_VBO]); | |
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices[0])*(2*gridSize.x*gridSize.y + gridSize.y + 1), indices); | |
free(indices); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
#endif | |
} | |
@end | |
@implementation GVLoopSprite | |
@synthesize texture; | |
+ (id) loopSpriteWithContentSize:(CGSize) size texture:(CCTexture2D *) texture gridSize:(ccGridSize) gridsize{ | |
return [[[self alloc] initWithContentSize:size texture:texture gridSize:gridsize] autorelease]; | |
} | |
- (id) initWithContentSize:(CGSize) size texture:(CCTexture2D *) texture_ gridSize:(ccGridSize) gridsize{ | |
self = [super init]; | |
[self setContentSize:size]; | |
gridSize = gridsize; | |
int n = (gridSize.x + 1) * (gridSize.y + 1); | |
vertices = (GLfloat *) malloc(sizeof(GLfloat)*n*3); | |
indices = (GLushort *) malloc(sizeof(GLushort)*(2*gridSize.x*gridSize.y + gridSize.y + 1)); | |
coordinates = (GLfloat *) malloc(sizeof(GLfloat)*n*2); | |
#if GVLS_USE_VBO | |
glGenBuffers(3, vboids); | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_VERTICES_VBO]); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*(n*3), NULL,GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_TEXCOORD_VBO]); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(coordinates[0])*(n*2), NULL,GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboids[GVLS_INDICES_VBO]); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0])*(2*gridSize.x*gridSize.y + gridSize.y + 1), NULL,GL_STREAM_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
#endif | |
self.texture = texture_; | |
[self initIndices]; | |
return self; | |
} | |
- (void) setTexture:(CCTexture2D *) texture_{ | |
[texture autorelease]; | |
texture = [texture_ retain]; | |
if (texture.maxS < 1 || texture.maxT < 1) { | |
NSLog(@"GVLoopSprite: maxS != 1 or maxT != 1 => Will not display correctly"); | |
} | |
textCoorOrigin = ccp(0,0); | |
float d = contentSizeInPixels_.width / gridSize.x; | |
cx = d / texture.pixelsWide; | |
d = contentSizeInPixels_.height / gridSize.y; | |
cy = d / texture.pixelsHigh; | |
[self updateTexCoords]; | |
[self initVertices]; | |
} | |
- (void) setZ:(float) z{ | |
float r; | |
for (int i = 0; i <= gridSize.x; i++) { | |
for (int j = 0; j <= gridSize.y; j++) { | |
r = (float)((i-gridSize.x/2)*(i-gridSize.x/2) + (j-gridSize.y/2)*(j-gridSize.y/2)) / (gridSize.x*gridSize.x + gridSize.y*gridSize.y)*4; | |
r = gridSize.x*gridSize.x/4 + gridSize.y*gridSize.y/4 - (i-gridSize.x/2)*(i-gridSize.x/2) - (j-gridSize.y/2)*(j-gridSize.y/2); | |
r = sqrtf(r); | |
vertices[3*_LINDEX(i, j) + 2] = (r*z - 600);// * CC_CONTENT_SCALE_FACTOR(); | |
} | |
} | |
} | |
- (void) setR:(float) r0 z:(float) z{ | |
float r; | |
for (int i = 0; i <= gridSize.x; i++) { | |
for (int j = 0; j <= gridSize.y; j++) { | |
r = gridSize.x*gridSize.x/4 + gridSize.y*gridSize.y/4 - (i-gridSize.x/2)*(i-gridSize.x/2) - (j-gridSize.y/2)*(j-gridSize.y/2); | |
vertices[3*_LINDEX(i, j) + 2] = (r*r0 - z);// * CC_CONTENT_SCALE_FACTOR(); | |
} | |
} | |
} | |
- (void) moveBy:(CGPoint) move{ | |
move = ccpMult(move, CC_CONTENT_SCALE_FACTOR()); | |
move.x = move.x / texture.pixelsWide; | |
move.y = move.y / texture.pixelsHigh; | |
textCoorOrigin = ccpAdd(textCoorOrigin, move); | |
[self updateTexCoords]; | |
} | |
- (void) draw{ | |
glBindTexture(GL_TEXTURE_2D, [texture name]); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glDisableClientState(GL_COLOR_ARRAY); | |
#if GVLS_USE_VBO | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_VERTICES_VBO]); | |
glVertexPointer(3, GL_FLOAT, 0, 0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ARRAY_BUFFER, vboids[GVLS_TEXCOORD_VBO]); | |
glTexCoordPointer(2, GL_FLOAT, 0, 0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboids[GVLS_INDICES_VBO]); | |
glDrawElements(GL_TRIANGLE_STRIP, 2*gridSize.x*gridSize.y + gridSize.y + 1, GL_UNSIGNED_SHORT, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
#else | |
glVertexPointer(3, GL_FLOAT, 0, vertices); | |
glTexCoordPointer(2, GL_FLOAT, 0, coordinates); | |
glDrawElements(GL_TRIANGLE_STRIP, 2*gridSize.x*gridSize.y + gridSize.y + 1, GL_UNSIGNED_SHORT, indices); | |
#endif | |
glEnableClientState(GL_COLOR_ARRAY); | |
} | |
- (void) dealloc{ | |
#if GVLS_USE_VBO | |
glDeleteBuffers(3, vboids); | |
#else | |
free(vertices); | |
free(indices); | |
#endif | |
[texture release]; | |
free(coordinates); | |
[super dealloc]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment