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

          Line data    Source code
       1           0 : /*
       2             : 
       3             : DustEntity.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "DustEntity.h"
      26             : 
      27             : #import "OOMaths.h"
      28             : #import "Universe.h"
      29             : #import "MyOpenGLView.h"
      30             : #import "OOGraphicsResetManager.h"
      31             : #import "OODebugFlags.h"
      32             : #import "OOMacroOpenGL.h"
      33             : 
      34             : 
      35             : #if OO_SHADERS
      36             : #import "OOMaterial.h"                // For kTangentAttributeIndex
      37             : #import "OOShaderProgram.h"
      38             : #import "OOShaderUniform.h"
      39             : #endif
      40             : 
      41             : #import "PlayerEntity.h"
      42             : 
      43             : 
      44           0 : #define FAR_PLANE               (DUST_SCALE * 0.50f)
      45           0 : #define NEAR_PLANE              (DUST_SCALE * 0.25f)
      46             : 
      47             : 
      48             : // Declare protocol conformance
      49             : @interface DustEntity (Private) <OOGraphicsResetClient>
      50             : 
      51           0 : - (void) checkShaderMode;
      52             : 
      53             : @end
      54             : 
      55             : #if OO_SHADERS
      56             : enum
      57             : {
      58             :         kShaderModeOff,
      59             :         kShaderModeOn,
      60             :         kShaderModeUnknown
      61             : };
      62             : #endif
      63             : 
      64             : 
      65             : @implementation DustEntity
      66             : 
      67           0 : - (id) init
      68             : {
      69             :         int vi;
      70             :         
      71             : // this should be unnecessary
      72             : //      ranrot_srand((uint32_t)[[NSDate date] timeIntervalSince1970]);  // seed randomiser by time
      73             :         
      74             :         self = [super init];
      75             :         
      76             :         for (vi = 0; vi < DUST_N_PARTICLES; vi++)
      77             :         {
      78             :                 vertices[vi].x = (ranrot_rand() % DUST_SCALE) - DUST_SCALE / 2;
      79             :                 vertices[vi].y = (ranrot_rand() % DUST_SCALE) - DUST_SCALE / 2;
      80             :                 vertices[vi].z = (ranrot_rand() % DUST_SCALE) - DUST_SCALE / 2;
      81             :                 
      82             :                 // Set up element index array for warp mode.
      83             :                 indices[vi * 2] = vi;
      84             :                 indices[vi * 2 + 1] = vi + DUST_N_PARTICLES;
      85             :                 
      86             : #if OO_SHADERS
      87             :                 vertices[vi + DUST_N_PARTICLES] = vertices[vi];
      88             :                 warpinessAttr[vi] = 0.0f;
      89             :                 warpinessAttr[vi + DUST_N_PARTICLES] = 1.0f;
      90             : #endif
      91             :         }
      92             :         
      93             : #if OO_SHADERS
      94             :         shaderMode = kShaderModeUnknown;
      95             : #endif
      96             :         
      97             :         drawDust = ![[[NSProcessInfo processInfo] arguments] containsObject:@"-nodust"];
      98             :         
      99             :         dust_color = [[OOColor colorWithRed:0.5 green:1.0 blue:1.0 alpha:1.0] retain];
     100             :         [self setStatus:STATUS_ACTIVE];
     101             : 
     102             :         hasPointSprites = [[OOOpenGLExtensionManager sharedManager] haveExtension:@"GL_ARB_point_sprite"];
     103             :         
     104             :         if (hasPointSprites)
     105             :         {
     106             :                 texture = [[OOTexture textureWithName:@"oolite-particle-dust.png"
     107             :                                                                                                                                  inFolder:@"Textures"
     108             :                                                                                                                                         options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
     109             :                                                                                                                          anisotropy:kOOTextureDefaultAnisotropy / 2.0
     110             :                                                                                                                                         lodBias:0.0] retain];
     111             :         }       
     112             : 
     113             :         collision_radius = DUST_SCALE; // for draw pass calculations
     114             : 
     115             :         [[OOGraphicsResetManager sharedManager] registerClient:self];
     116             : 
     117             :         return self;
     118             : }
     119             : 
     120             : 
     121           0 : - (void) dealloc
     122             : {
     123             :         DESTROY(dust_color);
     124             :         [[OOGraphicsResetManager sharedManager] unregisterClient:self];
     125             : 
     126             :         DESTROY(texture);
     127             : #if OO_SHADERS
     128             :         DESTROY(shader);
     129             :         DESTROY(uniforms);
     130             : #endif
     131             :         
     132             :         [super dealloc];
     133             : }
     134             : 
     135             : 
     136             : - (void) setDustColor:(OOColor *) color
     137             : {
     138             :         if (dust_color) [dust_color release];
     139             :         dust_color = [color retain];
     140             :         [dust_color getRed:&color_fv[0] green:&color_fv[1] blue:&color_fv[2] alpha:&color_fv[3]];
     141             : }
     142             : 
     143             : 
     144             : - (OOColor *) dustColor
     145             : {
     146             :         return dust_color;
     147             : }
     148             : 
     149             : 
     150           0 : - (BOOL) canCollide
     151             : {
     152             :         return NO;
     153             : }
     154             : 
     155             : 
     156           0 : - (void) updateCameraRelativePosition
     157             : {
     158             :         HPVector c_pos = [PLAYER viewpointPosition];
     159             :         cameraRelativePosition = make_vector((OOScalar)-fmod(c_pos.x,DUST_SCALE),(OOScalar)-fmod(c_pos.y,DUST_SCALE),(OOScalar)-fmod(c_pos.z,DUST_SCALE));
     160             : }
     161             : 
     162             : 
     163           0 : - (void) update:(OOTimeDelta) delta_t
     164             : {
     165             :         // [self setPosition:position];
     166             :         zero_distance = 0.0;
     167             :                         
     168             : #if OO_SHADERS
     169             :         if (EXPECT_NOT(shaderMode == kShaderModeUnknown))  [self checkShaderMode];
     170             :         
     171             :         // Shader takes care of repositioning.
     172             :         if (shaderMode == kShaderModeOn)  return;
     173             : #endif
     174             :         
     175             :         Vector offset = vector_flip(cameraRelativePosition);
     176             :         GLfloat  half_scale = DUST_SCALE * 0.50;
     177             :         int vi;
     178             :         for (vi = 0; vi < DUST_N_PARTICLES; vi++)
     179             :         {
     180             :                 while (vertices[vi].x - offset.x < -half_scale)
     181             :                         vertices[vi].x += DUST_SCALE;
     182             :                 while (vertices[vi].x - offset.x > half_scale)
     183             :                         vertices[vi].x -= DUST_SCALE;
     184             :                 
     185             :                 while (vertices[vi].y - offset.y < -half_scale)
     186             :                         vertices[vi].y += DUST_SCALE;
     187             :                 while (vertices[vi].y - offset.y > half_scale)
     188             :                         vertices[vi].y -= DUST_SCALE;
     189             :                 
     190             :                 while (vertices[vi].z - offset.z < -half_scale)
     191             :                         vertices[vi].z += DUST_SCALE;
     192             :                 while (vertices[vi].z - offset.z > half_scale)
     193             :                         vertices[vi].z -= DUST_SCALE;
     194             :         }
     195             : }
     196             : 
     197             : 
     198             : #if OO_SHADERS
     199             : - (OOShaderProgram *) shader
     200             : {
     201             :         if (shader == nil)
     202             :         {
     203             :                 NSString *prefix = [NSString stringWithFormat:
     204             :                                                    @"#define OODUST_SCALE_MAX    (float(%g))\n"
     205             :                                                         "#define OODUST_SCALE_FACTOR (float(%g))\n"
     206             :                                                         "#define OODUST_SIZE         (float(%g))\n",
     207             :                                                         FAR_PLANE / NEAR_PLANE,
     208             :                                                         1.0f / (FAR_PLANE - NEAR_PLANE),
     209             :                                                         (float)DUST_SCALE];
     210             :                 
     211             :                 // Reuse tangent attribute ID for "warpiness", as we don't need a tangent.
     212             :                 NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kTangentAttributeIndex]
     213             :                                                                                                                            forKey:@"aWarpiness"];
     214             :                 
     215             :                 shader = [[OOShaderProgram shaderProgramWithVertexShaderName:@"oolite-dust.vertex"
     216             :                                                                                                   fragmentShaderName:@"oolite-dust.fragment"
     217             :                                                                                                                           prefix:prefix
     218             :                                                                                                    attributeBindings:attributes] retain];
     219             :                 
     220             :                 DESTROY(uniforms);
     221             :                 OOShaderUniform *uWarp = [[OOShaderUniform alloc] initWithName:@"uWarp"
     222             :                                                                                                                  shaderProgram:shader
     223             :                                                                                                                  boundToObject:self
     224             :                                                                                                                           property:@selector(warpVector)
     225             :                                                                                                                 convertOptions:0];
     226             :                 OOShaderUniform *uOffsetPlayerPosition = [[OOShaderUniform alloc] initWithName:@"uOffsetPlayerPosition"
     227             :                                                                                                                                    shaderProgram:shader
     228             :                                                                                                                                    boundToObject:self
     229             :                                                                                                                                                 property:@selector(offsetPlayerPosition)
     230             :                                                                                                                                   convertOptions:0];
     231             :                 
     232             :                 uniforms = [[NSArray alloc] initWithObjects:uWarp, uOffsetPlayerPosition, nil];
     233             :                 [uWarp release];
     234             :                 [uOffsetPlayerPosition release];
     235             :         }
     236             :         
     237             :         return shader;
     238             : }
     239             : 
     240             : - (Vector) offsetPlayerPosition
     241             : {
     242             :         // used as shader uniform, so needs to be low precision
     243             :         HPVector c_pos = [PLAYER viewpointPosition];
     244             :         Vector offset = make_vector((OOScalar)fmod(c_pos.x,DUST_SCALE),(OOScalar)fmod(c_pos.y,DUST_SCALE),(OOScalar)fmod(c_pos.z,DUST_SCALE));
     245             :         return vector_subtract(offset, make_vector(DUST_SCALE * 0.5f, DUST_SCALE * 0.5f, DUST_SCALE * 0.5f));
     246             : }
     247             : 
     248             : 
     249             : - (void) checkShaderMode
     250             : {
     251             :         shaderMode = kShaderModeOff;
     252             :         if ([UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS)
     253             :         {
     254             :                 if ([[OOOpenGLExtensionManager sharedManager] useDustShader])
     255             :                 {
     256             :                         shaderMode = kShaderModeOn;
     257             :                 }
     258             :         }
     259             : }
     260             : #endif
     261             : 
     262             : 
     263           0 : - (Vector) warpVector
     264             : {
     265             :         return vector_multiply_scalar([PLAYER velocity], 1.0f / HYPERSPEED_FACTOR);
     266             : }
     267             : 
     268             : 
     269           0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent
     270             : {
     271             :         if (!drawDust || [UNIVERSE breakPatternHide] || !translucent)  return;  // DON'T DRAW
     272             :         
     273             :         PlayerEntity* player = PLAYER;
     274             :         assert(player != nil);
     275             :         
     276             : #ifndef NDEBUG
     277             :         if (gDebugFlags & DEBUG_NO_DUST)  return;
     278             : #endif
     279             :         
     280             : #if OO_SHADERS
     281             :         if (EXPECT_NOT(shaderMode == kShaderModeUnknown))  [self checkShaderMode];
     282             :         BOOL useShader = (shaderMode == kShaderModeOn);
     283             : #endif
     284             :         
     285             : 
     286             :         GLfloat *fogcolor = [UNIVERSE skyClearColor];
     287             :         float   idealDustSize = [[UNIVERSE gameView] viewSize].width / 800.0f;
     288             :         
     289             :         BOOL    warp_stars = [player atHyperspeed];
     290             :         float   dustIntensity;
     291             :         
     292             :         OO_ENTER_OPENGL();
     293             :         OOSetOpenGLState(OPENGL_STATE_OPAQUE);
     294             :         OOGL(glDisableClientState(GL_NORMAL_ARRAY));
     295             : 
     296             :         if (!warp_stars)
     297             :         {
     298             :                 // Draw points.
     299             :                 float dustPointSize = ceil(idealDustSize);
     300             :                 if (dustPointSize < 1.0f)  dustPointSize = 1.0f;
     301             :                 OOGL(GLScaledPointSize(dustPointSize));
     302             :                 dustIntensity = OOClamp_0_1_f(idealDustSize / dustPointSize);
     303             :         }
     304             :         else
     305             :         {
     306             :                 // Draw lines.
     307             :                 float idealLineSize = idealDustSize * 0.5f;
     308             :                 float dustLineSize = ceil(idealLineSize);
     309             :                 if (dustLineSize < 1.0f)  dustLineSize = 1.0f;
     310             :                 GLScaledLineWidth(dustLineSize);
     311             :                 dustIntensity = OOClamp_0_1_f(idealLineSize / dustLineSize);
     312             :         }
     313             :         if (fogcolor[3] > 0.0)
     314             :         {
     315             :                 // fade out dust when entering atmosphere (issue #100)
     316             :                 dustIntensity = OOClamp_0_1_f(dustIntensity-(fogcolor[3]*3.0));
     317             :         }
     318             : 
     319             : 
     320             :         if (dustIntensity > 0.0)
     321             :         {
     322             : 
     323             :                 float   *color = NULL;
     324             :                 if (player->isSunlit)  color = color_fv;
     325             :                 else  color = UNIVERSE->stars_ambient;
     326             :                 OOGL(glColor4f(color[0], color[1], color[2], dustIntensity));
     327             :         
     328             : #if OO_SHADERS
     329             :                 if (useShader)
     330             :                 {
     331             :                         [[self shader] apply];
     332             :                         [uniforms makeObjectsPerformSelector:@selector(apply)];
     333             :                 }
     334             :                 else
     335             : #endif
     336             :                 {
     337             :                         OOGL(glEnable(GL_FOG));
     338             :                         OOGL(glFogi(GL_FOG_MODE, GL_LINEAR));
     339             :                         OOGL(glFogfv(GL_FOG_COLOR, fogcolor));
     340             :                         OOGL(glHint(GL_FOG_HINT, GL_NICEST));
     341             :                         OOGL(glFogf(GL_FOG_START, NEAR_PLANE));
     342             :                         OOGL(glFogf(GL_FOG_END, FAR_PLANE));
     343             :                 }
     344             : 
     345             :                 OOGL(glEnable(GL_BLEND));
     346             :                 OOGL(glDepthMask(GL_FALSE));
     347             :         
     348             :                 if (warp_stars)
     349             :                 {
     350             :                         OOGL(glDisable(GL_TEXTURE_2D));
     351             : #if OO_SHADERS
     352             :                         if (useShader)
     353             :                         {
     354             :                                 OOGL(glEnableVertexAttribArrayARB(kTangentAttributeIndex));
     355             :                                 OOGL(glVertexAttribPointerARB(kTangentAttributeIndex, 1, GL_FLOAT, GL_FALSE, 0, warpinessAttr));
     356             :                         }
     357             :                         else
     358             : #endif
     359             :                         {
     360             :                                 Vector  warpVector = [self warpVector];
     361             :                                 unsigned vi;
     362             :                                 for (vi = 0; vi < DUST_N_PARTICLES; vi++)
     363             :                                 {
     364             :                                         vertices[vi + DUST_N_PARTICLES] = vector_subtract(vertices[vi], warpVector);
     365             :                                 }
     366             :                         }
     367             :                 
     368             :                         OOGL(glVertexPointer(3, GL_FLOAT, 0, vertices));
     369             :                         OOGL(glDrawElements(GL_LINES, DUST_N_PARTICLES * 2, GL_UNSIGNED_SHORT, indices));
     370             :                 
     371             : #if OO_SHADERS
     372             :                         if (useShader)
     373             :                         {
     374             :                                 OOGL(glDisableVertexAttribArrayARB(kTangentAttributeIndex));
     375             :                         }
     376             : #endif
     377             :                         OOGL(glEnable(GL_TEXTURE_2D));
     378             :         
     379             :                 }
     380             :                 else
     381             :                 {
     382             :                         if (hasPointSprites)
     383             :                         {
     384             : #if OO_SHADERS
     385             :                                 if (!useShader)
     386             : #endif
     387             :                                 {
     388             :                                         OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE));
     389             :                                 }
     390             :                                 OOGL(glEnable(GL_POINT_SPRITE_ARB));
     391             :                                 [texture apply];
     392             :                                 OOGL(glVertexPointer(3, GL_FLOAT, 0, vertices));
     393             :                                 OOGL(glDrawArrays(GL_POINTS, 0, DUST_N_PARTICLES));
     394             :                                 OOGL(glDisable(GL_POINT_SPRITE_ARB));
     395             :                         }
     396             :                         else
     397             :                         {
     398             :                                 OOGL(glDisable(GL_TEXTURE_2D));
     399             :                                 OOGL(glVertexPointer(3, GL_FLOAT, 0, vertices));
     400             :                                 OOGL(glDrawArrays(GL_POINTS, 0, DUST_N_PARTICLES));
     401             :                                 OOGL(glEnable(GL_TEXTURE_2D));
     402             :                         }
     403             :                 }
     404             :         
     405             :                 // reapply normal conditions
     406             : #if OO_SHADERS
     407             :                 if (useShader)
     408             :                 {
     409             :                         [OOShaderProgram applyNone];
     410             :                 }
     411             :                 else
     412             : #endif
     413             :                 {
     414             :                         OOGL(glDisable(GL_FOG));
     415             :                         OOGL(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA));
     416             :                 }
     417             :         
     418             :                 OOGL(glDisable(GL_BLEND));
     419             :                 OOGL(glDepthMask(GL_TRUE));
     420             : 
     421             :         }
     422             :         OOGL(glEnableClientState(GL_NORMAL_ARRAY));
     423             :         
     424             :         OOVerifyOpenGLState();
     425             :         OOCheckOpenGLErrors(@"DustEntity after drawing %@", self);
     426             : }
     427             : 
     428             : 
     429           0 : - (void) resetGraphicsState
     430             : {
     431             : #if OO_SHADERS
     432             :         DESTROY(shader);
     433             :         DESTROY(uniforms);
     434             :         
     435             :         shaderMode = kShaderModeUnknown;
     436             :         
     437             :         /*      Duplicate vertex data. This is only required if we're switching from
     438             :                 non-shader mode to a shader mode, but let's KISS.
     439             :         */
     440             :         memcpy(vertices + DUST_N_PARTICLES, vertices, sizeof *vertices * DUST_N_PARTICLES);
     441             : #endif
     442             : }
     443             : 
     444             : 
     445             : #ifndef NDEBUG
     446           0 : - (NSString *) descriptionForObjDump
     447             : {
     448             :         // Don't include range and visibility flag as they're irrelevant.
     449             :         return [self descriptionForObjDumpBasic];
     450             : }
     451             : #endif
     452             : 
     453             : @end

Generated by: LCOV version 1.14