/libs/cocos2d/CCPointParticleSystem.m
Objective C | 200 lines | 119 code | 40 blank | 41 comment | 15 complexity | 1ce879774660616320a33ee5dc862350 MD5 | raw file
Possible License(s): Apache-2.0
1/* 2 * cocos2d for iPhone: http://www.cocos2d-iphone.org 3 * 4 * Copyright (c) 2008-2010 Ricardo Quesada 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 * 24 */ 25 26 27// opengl 28#import <OpenGLES/ES1/gl.h> 29 30// cocos2d 31#import "CCPointParticleSystem.h" 32#import "CCTextureCache.h" 33#import "ccMacros.h" 34 35// support 36#import "Support/OpenGL_Internal.h" 37#import "Support/CGPointExtension.h" 38 39@implementation CCPointParticleSystem 40 41-(id) initWithTotalParticles:(int) numberOfParticles 42{ 43 if( (self=[super initWithTotalParticles:numberOfParticles]) ) { 44 45 vertices = malloc( sizeof(ccPointSprite) * totalParticles ); 46 47 if( ! vertices ) { 48 NSLog(@"cocos2d: Particle system: not enough memory"); 49 [self release]; 50 return nil; 51 } 52 53#if CC_USES_VBO 54 glGenBuffers(1, &verticesID); 55 56 // initial binding 57 glBindBuffer(GL_ARRAY_BUFFER, verticesID); 58 glBufferData(GL_ARRAY_BUFFER, sizeof(ccPointSprite)*totalParticles, vertices, GL_DYNAMIC_DRAW); 59 glBindBuffer(GL_ARRAY_BUFFER, 0); 60#endif 61 } 62 63 return self; 64} 65 66-(void) dealloc 67{ 68 free(vertices); 69#if CC_USES_VBO 70 glDeleteBuffers(1, &verticesID); 71#endif 72 73 [super dealloc]; 74} 75 76-(void) updateQuadWithParticle:(tCCParticle*)p newPosition:(CGPoint)newPos 77{ 78 // place vertices and colos in array 79 vertices[particleIdx].pos = newPos; 80 vertices[particleIdx].size = p->size; 81 vertices[particleIdx].colors = p->color; 82} 83 84-(void) postStep 85{ 86#if CC_USES_VBO 87 glBindBuffer(GL_ARRAY_BUFFER, verticesID); 88 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(ccPointSprite)*particleCount, vertices); 89 glBindBuffer(GL_ARRAY_BUFFER, 0); 90#endif 91} 92 93-(void) draw 94{ 95 if (particleIdx==0) 96 return; 97 98 // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY 99 // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY 100 // Unneeded states: GL_TEXTURE_COORD_ARRAY 101 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 102 103 glBindTexture(GL_TEXTURE_2D, texture_.name); 104 105 glEnable(GL_POINT_SPRITE_OES); 106 glTexEnvi( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE ); 107 108#define kPointSize sizeof(vertices[0]) 109 110#if CC_USES_VBO 111 glBindBuffer(GL_ARRAY_BUFFER, verticesID); 112 113 glVertexPointer(2,GL_FLOAT, kPointSize, 0); 114 115 glColorPointer(4, GL_FLOAT, kPointSize, (GLvoid*) offsetof(ccPointSprite, colors) ); 116 117 glEnableClientState(GL_POINT_SIZE_ARRAY_OES); 118 glPointSizePointerOES(GL_FLOAT, kPointSize, (GLvoid*) offsetof(ccPointSprite, size) ); 119#else // Uses Vertex Array List 120 int offset = (int)vertices; 121 glVertexPointer(2,GL_FLOAT, kPointSize, (GLvoid*) offset); 122 123 int diff = offsetof(ccPointSprite, colors); 124 glColorPointer(4, GL_FLOAT, kPointSize, (GLvoid*) (offset+diff)); 125 126 glEnableClientState(GL_POINT_SIZE_ARRAY_OES); 127 diff = offsetof(ccPointSprite, size); 128 glPointSizePointerOES(GL_FLOAT, kPointSize, (GLvoid*) (offset+diff)); 129#endif 130 131 BOOL newBlend = NO; 132 if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) { 133 newBlend = YES; 134 glBlendFunc( blendFunc_.src, blendFunc_.dst ); 135 } 136 137 138 glDrawArrays(GL_POINTS, 0, particleIdx); 139 140 // restore blend state 141 if( newBlend ) 142 glBlendFunc( CC_BLEND_SRC, CC_BLEND_DST); 143 144 145#if CC_USES_VBO 146 // unbind VBO buffer 147 glBindBuffer(GL_ARRAY_BUFFER, 0); 148#endif 149 150 glDisableClientState(GL_POINT_SIZE_ARRAY_OES); 151 glDisable(GL_POINT_SPRITE_OES); 152 153 // restore GL default state 154 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 155} 156 157#pragma mark Non supported properties 158 159// 160// SPIN IS NOT SUPPORTED 161// 162-(void) setStartSpin:(float)a 163{ 164 NSAssert(a == 0, @"PointParticleSystem doesn't support spinning"); 165 [super setStartSpin:a]; 166} 167-(void) setStartSpinVar:(float)a 168{ 169 NSAssert(a == 0, @"PointParticleSystem doesn't support spinning"); 170 [super setStartSpin:a]; 171} 172-(void) setEndSpin:(float)a 173{ 174 NSAssert(a == 0, @"PointParticleSystem doesn't support spinning"); 175 [super setStartSpin:a]; 176} 177-(void) setEndSpinVar:(float)a 178{ 179 NSAssert(a == 0, @"PointParticleSystem doesn't support spinning"); 180 [super setStartSpin:a]; 181} 182 183// 184// SIZE > 64 IS NOT SUPPORTED 185// 186-(void) setStartSize:(float)size 187{ 188 NSAssert(size >= 0 && size <= CC_MAX_PARTICLE_SIZE, @"PointParticleSystem only supports 0 <= size <= 64"); 189 [super setStartSize:size]; 190} 191 192-(void) setEndSize:(float)size 193{ 194 NSAssert( (size == kCCParticleStartSizeEqualToEndSize) || 195 ( size >= 0 && size <= CC_MAX_PARTICLE_SIZE), @"PointParticleSystem only supports 0 <= size <= 64"); 196 [super setEndSize:size]; 197} 198@end 199 200