diff --git a/GNUmakefile b/GNUmakefile index c5dbedb2..0b52d40e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -182,6 +182,7 @@ OOLITE_ENTITY_FILES = \ OOPlasmaShotEntity.m \ OOPlasmaBurstEntity.m \ OOFlashEffectEntity.m \ + OOExplosionCloudEntity.m \ ShipEntityLoadRestore.m \ OOLaserShotEntity.m \ OOQuiriumCascadeEntity.m \ diff --git a/Resources/Binary b/Resources/Binary index ae4c4709..3fd82bb8 160000 --- a/Resources/Binary +++ b/Resources/Binary @@ -1 +1 @@ -Subproject commit ae4c4709ceef2c3b0745e262e2ce5c2ff4e26588 +Subproject commit 3fd82bb81e830e9c9a553ef6142278f042d671d2 diff --git a/src/Core/Entities/OOExplosionCloudEntity.h b/src/Core/Entities/OOExplosionCloudEntity.h new file mode 100644 index 00000000..23c4a214 --- /dev/null +++ b/src/Core/Entities/OOExplosionCloudEntity.h @@ -0,0 +1,41 @@ +/* + +OOExplosionCloudEntity.h + +Cloud effect during explosions + + +Oolite +Copyright (C) 2004-2013 Giles C Williams and contributors + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. + +*/ + +#import "OOParticleSystem.h" + + +@interface OOExplosionCloudEntity: OOParticleSystem +{ +@private + float _growthRate; +} + ++ (instancetype) explosionCloudFromEntity:(Entity *)entity; + ++ (void) setUpTexture; + +@end diff --git a/src/Core/Entities/OOExplosionCloudEntity.m b/src/Core/Entities/OOExplosionCloudEntity.m new file mode 100644 index 00000000..ee8c9e30 --- /dev/null +++ b/src/Core/Entities/OOExplosionCloudEntity.m @@ -0,0 +1,172 @@ +/* + +OOExplosionCloudEntity.m + + +Oolite +Copyright (C) 2004-2013 Giles C Williams and contributors + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. + +*/ + +#import "OOExplosionCloudEntity.h" +#import "Universe.h" +#import "PlayerEntity.h" +#import "OOColor.h" +#import "OOTexture.h" +#import "OOGraphicsResetManager.h" + + +#define kExplosionCloudDuration 0.9f +#define kGrowthRateFactor 1.5f +#define kExplosionCloudAlpha 0.85f + +static OOTexture *sCloudTexture1 = nil; +static OOTexture *sCloudTexture2 = nil; + + +@interface OOExplosionCloudEntity (Private) + ++ (void) resetGraphicsState; + +@end + + +@implementation OOExplosionCloudEntity + +- (id) initExplosionCloudWithPosition:(HPVector)pos velocity:(Vector)vel size:(float)size +{ + unsigned i; + unsigned count = 25; + GLfloat baseColor[4] = {1.0,1.0,1.0,1.0}; + _growthRate = kGrowthRateFactor * size; + + if ((self = [super initWithPosition:pos velocity:vel count:count minSpeed:size*0.8 maxSpeed:size*1.2 duration:kExplosionCloudDuration baseColor:baseColor])) + { + for (i=0;i r) { + r = 1.0f; + } + b = randf(); + if (b > g) { + b = g; + } + _particleColor[i][0] = r; + _particleColor[i][1] = g; + _particleColor[i][2] = b; + _particleColor[i][3] = kExplosionCloudAlpha; + } + } + return self; +} + + ++ (instancetype) explosionCloudFromEntity:(Entity *)entity +{ + return [[[self alloc] initExplosionCloudWithPosition:[entity position] velocity:[entity velocity] size:[entity collisionRadius]*2.5] autorelease]; +} + + +- (void) update:(OOTimeDelta)delta_t +{ + [super update:delta_t]; + + // Fade out. + unsigned i, count = _count; + GLfloat (*particleColor)[4] = _particleColor; + + float newAlpha = kExplosionCloudAlpha * (1-(_timePassed / kExplosionCloudDuration)); + for (i=0;i 0.0) + { + particleColor[i][2] -= delta_t; + if (particleColor[i][2] < 0.0) + { + particleColor[i][2] = 0.0f; + } + } + else if (particleColor[i][1] > 0.0) + { + particleColor[i][1] -= delta_t; + if (particleColor[i][1] < 0.0) + { + particleColor[i][1] = 0.0f; + } + } + else if (particleColor[i][0] > 0.0) + { + particleColor[i][0] -= delta_t; + if (particleColor[i][0] < 0.0) + { + particleColor[i][0] = 0.0f; + } + } + } + +} + + +- (OOTexture *) texture:(NSUInteger)idx +{ + if (sCloudTexture1 == nil) [OOExplosionCloudEntity setUpTexture]; + if (idx < _count/5) + { + return sCloudTexture1; + } + else + { + return sCloudTexture2; + } +} + + ++ (void) setUpTexture +{ + if (sCloudTexture1 == nil) + { + sCloudTexture1 = [[OOTexture textureWithName:@"oolite-particle-cloud.png" + inFolder:@"Textures" + options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask + anisotropy:kOOTextureDefaultAnisotropy + lodBias:0.0] retain]; + sCloudTexture2 = [[OOTexture textureWithName:@"oolite-particle-cloud2.png" + inFolder:@"Textures" + options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask + anisotropy:kOOTextureDefaultAnisotropy + lodBias:0.0] retain]; + [[OOGraphicsResetManager sharedManager] registerClient:(id)[OOExplosionCloudEntity class]]; + } +} + + ++ (void) resetGraphicsState +{ + [sCloudTexture1 release]; + sCloudTexture1 = nil; + [sCloudTexture2 release]; + sCloudTexture2 = nil; +} + +@end diff --git a/src/Core/Entities/OOFlashEffectEntity.h b/src/Core/Entities/OOFlashEffectEntity.h index d84728c2..142094ef 100644 --- a/src/Core/Entities/OOFlashEffectEntity.h +++ b/src/Core/Entities/OOFlashEffectEntity.h @@ -33,6 +33,7 @@ MA 02110-1301, USA. @private float _duration; float _growthRate; + float _alpha; } + (instancetype) explosionFlashFromEntity:(Entity *)entity; diff --git a/src/Core/Entities/OOFlashEffectEntity.m b/src/Core/Entities/OOFlashEffectEntity.m index 4eba13fa..8754720d 100644 --- a/src/Core/Entities/OOFlashEffectEntity.m +++ b/src/Core/Entities/OOFlashEffectEntity.m @@ -36,7 +36,7 @@ MA 02110-1301, USA. #define kGrowthRateFactor 150.0f // if average flashSize is 80 then this is 12000 #define kMinExplosionGrowth 600.0f #define kLaserFlashInitialSize 1.0f - +#define kExplosionFlashAlpha 0.5f static OOTexture *sFlashTexture = nil; @@ -60,6 +60,7 @@ static OOTexture *sFlashTexture = nil; if ((self = [self initWithPosition:pos size:size color:[OOColor whiteColor] duration:kExplosionFlashDuration])) { _growthRate = fmax(_growthRate, kMinExplosionGrowth); + _alpha = kExplosionFlashAlpha; [self setVelocity:vel]; } return self; @@ -71,6 +72,7 @@ static OOTexture *sFlashTexture = nil; if ((self = [self initWithPosition:pos size:kLaserFlashInitialSize color:color duration:kLaserFlashDuration])) { [self setVelocity:vel]; + _alpha = 1.0f; } return self; } @@ -114,7 +116,7 @@ static OOTexture *sFlashTexture = nil; // Fade in and out. OOTimeDelta lifeTime = [self timeElapsedSinceSpawn]; - _colorComponents[3] = (lifeTime < tf) ? (lifeTime / tf) : (_duration - lifeTime) / tf1; + _colorComponents[3] = _alpha * ((lifeTime < tf) ? (lifeTime / tf) : (_duration - lifeTime) / tf1); // Disappear as necessary. if (lifeTime > _duration) [UNIVERSE removeEntity:self]; diff --git a/src/Core/Entities/OOParticleSystem.h b/src/Core/Entities/OOParticleSystem.h index 578ea489..a9421490 100644 --- a/src/Core/Entities/OOParticleSystem.h +++ b/src/Core/Entities/OOParticleSystem.h @@ -64,6 +64,8 @@ enum duration:(OOTimeDelta)duration baseColor:(GLfloat[4])baseColor; +- (OOTexture *) texture:(NSUInteger)idx; + @end diff --git a/src/Core/Entities/OOParticleSystem.m b/src/Core/Entities/OOParticleSystem.m index 2e3fc52d..9e50781a 100644 --- a/src/Core/Entities/OOParticleSystem.m +++ b/src/Core/Entities/OOParticleSystem.m @@ -141,6 +141,9 @@ do { \ - (void) drawImmediate:(bool)immediate translucent:(bool)translucent { if (!translucent || [UNIVERSE breakPatternHide]) return; + + OOTexture *tex = nil; + OOTexture *lastTex = nil; OO_ENTER_OPENGL(); OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING); @@ -148,7 +151,6 @@ do { \ OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT)); OOGL(glEnable(GL_TEXTURE_2D)); - [[OOLightParticleEntity defaultParticleTexture] apply]; OOGL(glEnable(GL_BLEND)); OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); @@ -169,6 +171,12 @@ do { \ OOGLBEGIN(GL_QUADS); for (i = 0; i < count; i++) { + OOTexture *tex = [self texture:i]; + if (tex != lastTex) + { + lastTex = tex; + [tex apply]; + } glColor4fv(particleColor[i]); DrawQuadForView(particlePosition[i].x, particlePosition[i].y, particlePosition[i].z, particleSize[i]); } @@ -192,6 +200,13 @@ do { \ for (i = 0; i < count; i++) { + OOTexture *tex = [self texture:i]; + if (tex != lastTex) + { + lastTex = tex; + [tex apply]; + } + OOGL(glPushMatrix()); GLTranslateOOVector(particlePosition[i]); GLMultOOMatrix(bbMatrix); @@ -242,6 +257,10 @@ do { \ return YES; } +- (OOTexture *) texture:(NSUInteger)idx +{ + return [OOLightParticleEntity defaultParticleTexture]; +} #ifndef NDEBUG - (NSSet *) allTextures diff --git a/src/Core/Entities/ShipEntity.m b/src/Core/Entities/ShipEntity.m index 8a1bf899..fb51118c 100644 --- a/src/Core/Entities/ShipEntity.m +++ b/src/Core/Entities/ShipEntity.m @@ -70,6 +70,7 @@ MA 02110-1301, USA. #import "OOECMBlastEntity.h" #import "OOPlasmaShotEntity.h" #import "OOFlashEffectEntity.h" +#import "OOExplosionCloudEntity.h" #import "ProxyPlayerEntity.h" #import "OOLaserShotEntity.h" #import "OOQuiriumCascadeEntity.h" @@ -7888,9 +7889,10 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context) if (add_debris) { // 1. fast sparks - [UNIVERSE addEntity:[OOSmallFragmentBurstEntity fragmentBurstFromEntity:self]]; +// [UNIVERSE addEntity:[OOSmallFragmentBurstEntity fragmentBurstFromEntity:self]]; // 2. slow clouds - [UNIVERSE addEntity:[OOBigFragmentBurstEntity fragmentBurstFromEntity:self]]; + [UNIVERSE addEntity:[OOExplosionCloudEntity explosionCloudFromEntity:self]]; +// [UNIVERSE addEntity:[OOBigFragmentBurstEntity fragmentBurstFromEntity:self]]; } // 3. flash [UNIVERSE addEntity:[OOFlashEffectEntity explosionFlashFromEntity:self]]; diff --git a/src/Core/Universe.m b/src/Core/Universe.m index 15968bdb..6eb1140c 100644 --- a/src/Core/Universe.m +++ b/src/Core/Universe.m @@ -73,6 +73,7 @@ MA 02110-1301, USA. #import "OORingEffectEntity.h" #import "OOLightParticleEntity.h" #import "OOFlashEffectEntity.h" +#import "OOExplosionCloudEntity.h" #import "OOMusicController.h" #import "OOAsyncWorkManager.h" @@ -347,6 +348,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC // Preload particle effect textures: [OOLightParticleEntity setUpTexture]; [OOFlashEffectEntity setUpTexture]; + [OOExplosionCloudEntity setUpTexture]; player = [PlayerEntity sharedPlayer]; [player deferredInit];