LCOV - code coverage report
Current view: top level - Core/Entities - OOLightParticleEntity.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 10 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOLightParticleEntity.m
       4             : 
       5             : 
       6             : Oolite
       7             : Copyright (C) 2004-2013 Giles C Williams and contributors
       8             : 
       9             : This program is free software; you can redistribute it and/or
      10             : modify it under the terms of the GNU General Public License
      11             : as published by the Free Software Foundation; either version 2
      12             : of the License, or (at your option) any later version.
      13             : 
      14             : This program is distributed in the hope that it will be useful,
      15             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             : GNU General Public License for more details.
      18             : 
      19             : You should have received a copy of the GNU General Public License
      20             : along with this program; if not, write to the Free Software
      21             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      22             : MA 02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : #import "OOLightParticleEntity.h"
      27             : #import "Universe.h"
      28             : #import "PlayerEntity.h"
      29             : #import "OOTexture.h"
      30             : #import "OOColor.h"
      31             : #import "OOCollectionExtractors.h"
      32             : #import "OOFunctionAttributes.h"
      33             : #import "OOMacroOpenGL.h"
      34             : #import "OOGraphicsResetManager.h"
      35             : #import "MyOpenGLView.h"
      36             : 
      37             : 
      38           0 : #define PARTICLE_DISTANCE_SCALE_LOW             12.0
      39           0 : #define PARTICLE_DISTANCE_SCALE_HIGH    36.0
      40             : 
      41             : 
      42           0 : static OOTexture *sBlobTexture = nil;
      43             : 
      44             : 
      45             : @interface OOLightParticleEntity (Private)
      46             : 
      47           0 : + (void) resetGraphicsState;
      48             : 
      49             : @end
      50             : 
      51             : 
      52             : @implementation OOLightParticleEntity
      53             : 
      54             : - (id) initWithDiameter:(float)diameter
      55             : {
      56             :         if ((self = [super init]))
      57             :         {
      58             :                 _diameter = diameter;
      59             :                 no_draw_distance = pow(diameter / 2.0, M_SQRT2) * NO_DRAW_DISTANCE_FACTOR * NO_DRAW_DISTANCE_FACTOR;
      60             :                 no_draw_distance *= [UNIVERSE reducedDetail] ? PARTICLE_DISTANCE_SCALE_LOW : PARTICLE_DISTANCE_SCALE_HIGH;
      61             :                 
      62             :                 _colorComponents[0] = 1.0f;
      63             :                 _colorComponents[1] = 1.0f;
      64             :                 _colorComponents[2] = 1.0f;
      65             :                 _colorComponents[3] = 1.0f;
      66             :                 
      67             :                 [self setScanClass:CLASS_NO_DRAW];
      68             :                 [self setStatus:STATUS_EFFECT];
      69             :         }
      70             :         
      71             :         return self;
      72             : }
      73             : 
      74             : 
      75             : - (float) diameter
      76             : {
      77             :         return _diameter;
      78             : }
      79             : 
      80             : 
      81             : - (void) setDiameter:(float)diameter
      82             : {
      83             :         _diameter = diameter;
      84             : }
      85             : 
      86             : 
      87             : - (void) setColor:(OOColor *)color
      88             : {
      89             :         [color getRed:&_colorComponents[0] green:&_colorComponents[1] blue:&_colorComponents[2] alpha:&_colorComponents[3]];
      90             : }
      91             : 
      92             : 
      93             : - (void) setColor:(OOColor *)color alpha:(GLfloat)alpha
      94             : {
      95             :         [self setColor:color];
      96             :         _colorComponents[3] = alpha;
      97             : }
      98             : 
      99             : 
     100             : - (void) drawSubEntityImmediate:(bool)immediate translucent:(bool)translucent
     101             : {
     102             :         if (!translucent)  return;
     103             :         
     104             :         /*      TODO: someone will inevitably build a ship so big that individual
     105             :                 zero_distances are necessary for flashers, if they haven't already.
     106             :                 -- Ahruman 2009-09-20
     107             :         */
     108             :         cam_zero_distance = [[self owner] camZeroDistance];
     109             :         if (no_draw_distance <= cam_zero_distance)  return;
     110             :         
     111             :         Entity *father = [self owner];
     112             :         Entity *last = nil;
     113             :         HPVector abspos = position;
     114             : 
     115             :         while (father != nil && father != last && father != NO_TARGET)
     116             :         {
     117             :                 OOMatrix rM = [father drawRotationMatrix];
     118             :                 abspos = HPvector_add(OOHPVectorMultiplyMatrix(abspos, rM), [father position]);
     119             :                 last = father;
     120             :                 
     121             :                 if (![father isSubEntity])  break;
     122             :                 father = [father owner];
     123             :         }
     124             : 
     125             :         OOMatrix temp_matrix = OOGLPopModelView();
     126             :         OOGLPushModelView();
     127             : 
     128             :         /* Flashers are drawn using the absolute view matrix */
     129             :         OOGLLoadModelView([UNIVERSE viewMatrix]);
     130             :         /* ...modified by the aggregate translation calculated above */
     131             :         OOGLTranslateModelView(HPVectorToVector(HPvector_subtract(abspos,[PLAYER viewpointPosition]))); // move to camera-relative position     
     132             :         [self drawImmediate:immediate translucent:translucent];
     133             : 
     134             :         OOGLLoadModelView(temp_matrix);
     135             : }
     136             : 
     137             : 
     138           0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent
     139             : {
     140             :         if (!translucent) return;
     141             :         if ([UNIVERSE breakPatternHide] && ![self isImmuneToBreakPatternHide])
     142             :         {
     143             :                 Entity *father = [self owner];
     144             :                 while (father != nil && father != NO_TARGET)
     145             :                 {
     146             :                         if (![father isSubEntity])  break;
     147             :                         father = [father owner];
     148             :                 }
     149             :                 if (![father isImmuneToBreakPatternHide])
     150             :                 {
     151             :                         return;
     152             :                 }
     153             :         }
     154             :         if (no_draw_distance <= cam_zero_distance)  return;
     155             :         
     156             :         OO_ENTER_OPENGL();
     157             :         OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING);
     158             :         
     159             :         OOGL(glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT));
     160             :         OOGL(glEnable(GL_BLEND));
     161             :         OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE));
     162             :         
     163             :         OOGL(glEnable(GL_TEXTURE_2D));
     164             :         OOGL(glDepthMask(GL_FALSE));
     165             :         
     166             :         GLfloat distanceAttenuation = cam_zero_distance / no_draw_distance;
     167             :         distanceAttenuation = 1.0 - distanceAttenuation;
     168             :         GLfloat components[4] = { _colorComponents[0], _colorComponents[1], _colorComponents[2], _colorComponents[3] * distanceAttenuation };
     169             :         OOGL(glColor4fv(components));
     170             :         
     171             :         OOGL(glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, components));
     172             :         OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND));
     173             :         
     174             :         OOViewID viewDir = [UNIVERSE viewDirection];
     175             :         if (viewDir != VIEW_GUI_DISPLAY)  OOGLMultModelView([PLAYER drawRotationMatrix]);
     176             :         [[self texture] apply];
     177             :         
     178             :         /*      NOTE: nominal diameter is actual radius, because of the black border
     179             :                 in the texture. However, the offset along the view axis is not
     180             :                 affected by the border and needs to be scaled.
     181             :                 -- Ahruman 2009-12-20
     182             :         */
     183             :         float viewOffset = _diameter * 0.5f;
     184             :         
     185             :         OOGLBEGIN(GL_QUADS);
     186             :         switch (viewDir)
     187             :         {
     188             :                 case VIEW_FORWARD:
     189             :                 case VIEW_GUI_DISPLAY:
     190             :                         glTexCoord2f(0.0, 1.0);
     191             :                         glVertex3f(-_diameter, -_diameter, -viewOffset);
     192             :                         
     193             :                         glTexCoord2f(1.0, 1.0);
     194             :                         glVertex3f(_diameter, -_diameter, -viewOffset);
     195             :                         
     196             :                         glTexCoord2f(1.0, 0.0);
     197             :                         glVertex3f(_diameter, _diameter, -viewOffset);
     198             :                         
     199             :                         glTexCoord2f(0.0, 0.0);
     200             :                         glVertex3f(-_diameter, _diameter, -viewOffset);
     201             :                         break;
     202             :                         
     203             :                 case VIEW_AFT:
     204             :                         glTexCoord2f(0.0, 1.0);
     205             :                         glVertex3f(_diameter, -_diameter, viewOffset);
     206             :                         
     207             :                         glTexCoord2f(1.0, 1.0);
     208             :                         glVertex3f(-_diameter, -_diameter, viewOffset);
     209             :                         
     210             :                         glTexCoord2f(1.0, 0.0);
     211             :                         glVertex3f(-_diameter, _diameter, viewOffset);
     212             :                         
     213             :                         glTexCoord2f(0.0, 0.0);
     214             :                         glVertex3f(_diameter, _diameter, viewOffset);
     215             :                         break;
     216             :                         
     217             :                 case VIEW_STARBOARD:
     218             :                         glTexCoord2f(0.0, 1.0);
     219             :                         glVertex3f(-viewOffset, -_diameter, _diameter);
     220             :                         
     221             :                         glTexCoord2f(1.0, 1.0);
     222             :                         glVertex3f(-viewOffset, -_diameter, -_diameter);
     223             :                         
     224             :                         glTexCoord2f(1.0, 0.0);
     225             :                         glVertex3f(-viewOffset, _diameter, -_diameter);
     226             :                         
     227             :                         glTexCoord2f(0.0, 0.0);
     228             :                         glVertex3f(-viewOffset, _diameter, _diameter);
     229             :                         break;
     230             :                         
     231             :                 case VIEW_PORT:
     232             :                         glTexCoord2f(0.0, 1.0);
     233             :                         glVertex3f(viewOffset, -_diameter, -_diameter);
     234             :                         
     235             :                         glTexCoord2f(1.0, 1.0);
     236             :                         glVertex3f(viewOffset, -_diameter, _diameter);
     237             :                         
     238             :                         glTexCoord2f(1.0, 0.0);
     239             :                         glVertex3f(viewOffset, _diameter, _diameter);
     240             :                         
     241             :                         glTexCoord2f(0.0, 0.0);
     242             :                         glVertex3f(viewOffset, _diameter, -_diameter);
     243             :                         break;
     244             :                         
     245             :                 case VIEW_CUSTOM:
     246             :                         {
     247             :                                 PlayerEntity *player = PLAYER;
     248             :                                 Vector vi = [player customViewRightVector];             vi.x *= _diameter;      vi.y *= _diameter;      vi.z *= _diameter;
     249             :                                 Vector vj = [player customViewUpVector];                vj.x *= _diameter;      vj.y *= _diameter;      vj.z *= _diameter;
     250             :                                 Vector vk = [player customViewForwardVector];   vk.x *= viewOffset;     vk.y *= viewOffset;     vk.z *= viewOffset;
     251             :                                 glTexCoord2f(0.0, 1.0);
     252             :                                 glVertex3f(-vi.x -vj.x -vk.x, -vi.y -vj.y -vk.y, -vi.z -vj.z -vk.z);
     253             :                                 glTexCoord2f(1.0, 1.0);
     254             :                                 glVertex3f(+vi.x -vj.x -vk.x, +vi.y -vj.y -vk.y, +vi.z -vj.z -vk.z);
     255             :                                 glTexCoord2f(1.0, 0.0);
     256             :                                 glVertex3f(+vi.x +vj.x -vk.x, +vi.y +vj.y -vk.y, +vi.z +vj.z -vk.z);
     257             :                                 glTexCoord2f(0.0, 0.0);
     258             :                                 glVertex3f(-vi.x +vj.x -vk.x, -vi.y +vj.y -vk.y, -vi.z +vj.z -vk.z);
     259             :                         }
     260             :                         break;
     261             :                         
     262             :                 default:
     263             :                         glTexCoord2f(0.0, 1.0);
     264             :                         glVertex3f(-_diameter, -_diameter, -_diameter);
     265             :                         
     266             :                         glTexCoord2f(1.0, 1.0);
     267             :                         glVertex3f(_diameter, -_diameter, -_diameter);
     268             :                         
     269             :                         glTexCoord2f(1.0, 0.0);
     270             :                         glVertex3f(_diameter, _diameter, -_diameter);
     271             :                         
     272             :                         glTexCoord2f(0.0, 0.0);
     273             :                         glVertex3f(-_diameter, _diameter, -_diameter);
     274             :                         break;
     275             :         }
     276             :         OOGLEND();
     277             :         
     278             :         OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
     279             :         OOGL(glPopAttrib());
     280             :         
     281             :         OOVerifyOpenGLState();
     282             : }
     283             : 
     284             : 
     285             : - (OOTexture *) texture
     286             : {
     287             :         return [OOLightParticleEntity defaultParticleTexture];
     288             : }
     289             : 
     290             : 
     291             : + (void) setUpTexture
     292             : {
     293             :         if (sBlobTexture == nil)
     294             :         {
     295             :                 sBlobTexture = [[OOTexture textureWithName:@"oolite-particle-blur.png"
     296             :                                                                                   inFolder:@"Textures"
     297             :                                                                                    options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
     298             :                                                                                 anisotropy:kOOTextureDefaultAnisotropy / 2.0
     299             :                                                                                    lodBias:0.0] retain];
     300             :                 [[OOGraphicsResetManager sharedManager] registerClient:(id<OOGraphicsResetClient>)[OOLightParticleEntity class]];
     301             :         }
     302             : }
     303             : 
     304             : 
     305             : + (OOTexture *) defaultParticleTexture
     306             : {
     307             :         if (sBlobTexture == nil)  [self setUpTexture];
     308             :         return sBlobTexture;
     309             : }
     310             : 
     311             : 
     312           0 : + (void) resetGraphicsState
     313             : {
     314             :         [sBlobTexture release];
     315             :         sBlobTexture = nil;
     316             : }
     317             : 
     318             : 
     319           0 : - (BOOL) isEffect
     320             : {
     321             :         return YES;
     322             : }
     323             : 
     324             : 
     325           0 : - (BOOL) canCollide
     326             : {
     327             :         return NO;
     328             : }
     329             : 
     330             : 
     331             : 
     332             : #ifndef NDEBUG
     333           0 : - (NSSet *) allTextures
     334             : {
     335             :         return [NSSet setWithObject:[self texture]];
     336             : }
     337             : #endif
     338             : 
     339             : @end

Generated by: LCOV version 1.14