コード例 #1
0
/**
 * @brief Updates the camera zoom.
 */
static void cam_updatePilotZoom( Pilot *follow, Pilot *target, double dt )
{
   double d, x,y, z,tz, dx, dy;
   double zfar, znear;
   double c;

   /* Must have auto zoom enabled. */
   if (conf.zoom_manual)
      return;

   /* Minimum depends on velocity normally.
    *
    * w*h = A, cte    area constant
    * w/h = K, cte    proportion constant
    * d^2 = A, cte    geometric longitud
    *
    * A_v = A*(1+v/d)   area of view is based on speed
    * A_v / A = (1 + v/d)
    *
    * z = A / A_v = 1. / (1 + v/d)
    */
   d     = sqrt(SCREEN_W*SCREEN_H);
   znear = MIN( conf.zoom_near, 1. / (0.8 + VMOD(follow->solid->vel)/d) );

   /* Maximum is limited by nebulae. */
   if (cur_system->nebu_density > 0.) {
      c     = MIN( SCREEN_W, SCREEN_H ) / 2;
      zfar  = CLAMP( conf.zoom_far, conf.zoom_near, c / nebu_getSightRadius() );
   }
   else
      zfar = conf.zoom_far;
   znear = MAX( znear, zfar );

   /*
    * Set Zoom to pilot target.
    */
   z = cam_getZoom();
   if (target != NULL) {
      /* Get current relative target position. */
      gui_getOffset( &x, &y );
      x += target->solid->pos.x - follow->solid->pos.x;
      y += target->solid->pos.y - follow->solid->pos.y;

      /* Get distance ratio. */
      dx = (SCREEN_W/2.) / (FABS(x) + 2*target->ship->gfx_space->sw);
      dy = (SCREEN_H/2.) / (FABS(y) + 2*target->ship->gfx_space->sh);

      /* Get zoom. */
      tz = MIN( dx, dy );
   }
   else
      tz = znear; /* Aim at in. */

   /* Gradually zoom in/out. */
   d  = CLAMP(-conf.zoom_speed, conf.zoom_speed, tz - z);
   d *= dt / dt_mod; /* Remove dt dependence. */
   if (d < 0) /** Speed up if needed. */
      d *= 2.;
   camera_Z =  CLAMP( zfar, znear, z + d);
}
コード例 #2
0
ファイル: opengl_render.c プロジェクト: zid/naev
/**
 * @brief Blits a sprite interpolating, position is relative to the player.
 *
 * Since position is in "game coordinates" it is subject to all
 * sorts of position transformations.
 *
 * Interpolation is:  sa*inter + sb*1.-inter)
 *
 *    @param sa Sprite A to blit.
 *    @param sb Sprite B to blit.
 *    @param inter Amount to interpolate.
 *    @param bx X position of the texture relative to the player.
 *    @param by Y position of the texture relative to the player.
 *    @param sx X position of the sprite to use.
 *    @param sy Y position of the sprite to use.
 *    @param c Colour to use (modifies texture colour).
 */
void gl_blitSpriteInterpolate( const glTexture* sa, const glTexture *sb,
      double inter, const double bx, const double by,
      const int sx, const int sy, const glColour *c )
{
   double x,y, w,h, tx,ty, cx,cy, gx,gy;

   /* Get parameters. */
   gl_cameraGet( &cx, &cy );
   gui_getOffset( &gx, &gy );

   /* calculate position - we'll use relative coords to player */
   x = (bx - cx - sa->sw/2. + gx) * gl_cameraZ;
   y = (by - cy - sa->sh/2. + gy) * gl_cameraZ;

   /* Scaled sprite dimensions. */
   w = sa->sw*gl_cameraZ;
   h = sa->sh*gl_cameraZ;

   /* check if inbounds */
   if ((fabs(x) > SCREEN_W/2 + w) ||
         (fabs(y) > SCREEN_H/2 + h) )
      return;

   /* texture coords */
   tx = sa->sw*(double)(sx)/sa->rw;
   ty = sa->sh*(sa->sy-(double)sy-1)/sa->rh;

   gl_blitTextureInterpolate( sa, sb, inter, x, y, w, h,
         tx, ty, sa->srw, sa->srh, c );
}
コード例 #3
0
ファイル: opengl_render.c プロジェクト: BariumBlue/naev
/**
 * @brief Converts screen coordinates to ingame coordinates.
 *
 *    @param[out] nx New ingame X coord.
 *    @param[out] ny New ingame Y coord.
 *    @param bx Screen X coord to translate.
 *    @param by Screen Y coord to translate.
 */
void gl_screenToGameCoords( double *nx, double *ny, int bx, int by )
{
   double cx,cy, gx,gy, z;

   /* Get parameters. */
   cam_getPos( &cx, &cy );
   z = cam_getZoom();
   gui_getOffset( &gx, &gy );

   /* calculate position - we'll use relative coords to player */
   *nx = (bx - SCREEN_W/2. - gx) / z + cx;
   *ny = (by - SCREEN_H/2. - gy) / z + cy;
}
コード例 #4
0
ファイル: opengl_render.c プロジェクト: BariumBlue/naev
/**
 * @brief Converts ingame coordinates to screen coordinates.
 *
 *    @param[out] nx New screen X coord.
 *    @param[out] ny New screen Y coord.
 *    @param bx Game X coord to translate.
 *    @param by Game Y coord to translate.
 */
void gl_gameToScreenCoords( double *nx, double *ny, double bx, double by )
{
   double cx,cy, gx,gy, z;

   /* Get parameters. */
   cam_getPos( &cx, &cy );
   z = cam_getZoom();
   gui_getOffset( &gx, &gy );

   /* calculate position - we'll use relative coords to player */
   *nx = (bx - cx) * z + gx + SCREEN_W/2.;
   *ny = (by - cy) * z + gy + SCREEN_H/2.;
}
コード例 #5
0
ファイル: nebula.c プロジェクト: Kinniken/NoxImperii
/**
 * @brief Renders the nebula overlay (hides what player can't see).
 *
 *    @param dt Current delta tick.
 */
void nebu_renderOverlay( const double dt )
{
   (void) dt;
   double gx, gy;
   double ox, oy;
   double z;
   double sx, sy;

   /* Get GUI offsets. */
   gui_getOffset( &gx, &gy );

   /* Get zoom. */
   z = cam_getZoom();

   /*
    * Renders the puffs
    */
   nebu_renderPuffs( 0 );

   /* Prepare the matrix */
   ox = gx;
   oy = gy;
   spfx_getShake( &sx, &sy );
   ox += sx;
   oy += sy;
   gl_matrixPush();
      gl_matrixTranslate( SCREEN_W/2.+ox, SCREEN_H/2.+oy );
      gl_matrixScale( z, z );

   /*
    * Mask for area player can still see (partially)
    */
   glShadeModel(GL_SMOOTH);
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY,
         sizeof(GLfloat)*2*18, 4, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 18 );


   /*
    * Solid nebula for areas the player can't see
    */
   glShadeModel(GL_FLAT);
   /* Colour is shared. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 2*28), 4, GL_FLOAT, 0 );
   /* Top left. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 0*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Top right. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 1*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Bottom right. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 2*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Bottom left. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 3*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );

   gl_vboDeactivate();
   gl_matrixPop();

   /* Reset puff movement. */
   puff_x = 0.;
   puff_y = 0.;

   gl_checkErr();
}
コード例 #6
0
ファイル: nebula.c プロジェクト: Kinniken/NoxImperii
/**
 * @brief Regenerates the overlay.
 */
void nebu_genOverlay (void)
{
   int i;
   GLfloat *data;
   double a;
   double gx, gy;
   double z;

   /* Get GUI offsets. */
   gui_getOffset( &gx, &gy );

   /* Here we calculate outer corners. It should actually be /2. because we
    * are centered around 0,0. However, we treat this extra space as a buffer
    * for when it's shaking. */
   z = 1./conf.zoom_far;

   /* See if need to generate overlay. */
   if (nebu_vboOverlay == NULL) {
      nebu_vboOverlay = gl_vboCreateStatic( sizeof(GLfloat) *
            ((2+4)*18 + 2*28 + 4*7), NULL );

      /* Set colors, those will be pure static. */
      data = gl_vboMap( nebu_vboOverlay );

      /* Alpha overlay. */
      for (i=0; i<18; i++) {
         data[2*18 + 4*i + 0] = cDarkBlue.r;
         data[2*18 + 4*i + 1] = cDarkBlue.g;
         data[2*18 + 4*i + 2] = cDarkBlue.b;
         data[2*18 + 4*i + 3] = cDarkBlue.a;
      }
      data[2*18 + 3] = 0.; /* Origin is transparent. */

      /* Solid overlay. */
      for (i=0; i<7; i++) {
         data[(2+4)*18 + 2*28 + 4*i + 0] = cDarkBlue.r;
         data[(2+4)*18 + 2*28 + 4*i + 1] = cDarkBlue.g;
         data[(2+4)*18 + 2*28 + 4*i + 2] = cDarkBlue.b;
         data[(2+4)*18 + 2*28 + 4*i + 3] = cDarkBlue.a;
      }

      gl_vboUnmap( nebu_vboOverlay );
   }

   /* Generate the main chunk. */
   data = gl_vboMap( nebu_vboOverlay );

   /* Main chunk. */
   data[0] = 0.;
   data[1] = 0.;
   for (i=0; i<17; i++) {
      a = M_PI*2./16. * (double)i;
      data[2*(i+1) + 0] = nebu_view * cos(a);
      data[2*(i+1) + 1] = nebu_view * sin(a);
   }

   /* Top Left */
   data[(2+4)*18+0]  = -SCREEN_W*z-gx;
   data[(2+4)*18+1]  = SCREEN_H*z-gy;
   data[(2+4)*18+2]  = -nebu_view;
   data[(2+4)*18+3]  = 0.;
   data[(2+4)*18+4]  = -nebu_view*COS225;
   data[(2+4)*18+5]  = nebu_view*SIN225;
   data[(2+4)*18+6]  = -nebu_view*ANG45;
   data[(2+4)*18+7]  = nebu_view*ANG45;
   data[(2+4)*18+8]  = -nebu_view*SIN225;
   data[(2+4)*18+9]  = nebu_view*COS225;
   data[(2+4)*18+10] = 0.;
   data[(2+4)*18+11] = nebu_view;
   data[(2+4)*18+12] = SCREEN_W*z-gx;
   data[(2+4)*18+13] = SCREEN_H*z-gy;

   /* Top Right */
   data[(2+4)*18+14] = SCREEN_W*z-gx;
   data[(2+4)*18+15] = SCREEN_H*z-gy;
   data[(2+4)*18+16] = 0.;
   data[(2+4)*18+17] = nebu_view;
   data[(2+4)*18+18] = nebu_view*SIN225;
   data[(2+4)*18+19] = nebu_view*COS225;
   data[(2+4)*18+20] = nebu_view*ANG45;
   data[(2+4)*18+21] = nebu_view*ANG45;
   data[(2+4)*18+22] = nebu_view*COS225;
   data[(2+4)*18+23] = nebu_view*SIN225;
   data[(2+4)*18+24] = nebu_view;
   data[(2+4)*18+25] = 0.;
   data[(2+4)*18+26] = SCREEN_W*z-gx;
   data[(2+4)*18+27] = -SCREEN_H*z-gy;

   /* Bottom Right */
   data[(2+4)*18+28] = SCREEN_W*z-gx;
   data[(2+4)*18+29] = -SCREEN_H*z-gy;
   data[(2+4)*18+30] = nebu_view;
   data[(2+4)*18+31] = 0.;
   data[(2+4)*18+32] = nebu_view*COS225;
   data[(2+4)*18+33] = -nebu_view*SIN225;
   data[(2+4)*18+34] = nebu_view*ANG45;
   data[(2+4)*18+35] = -nebu_view*ANG45;
   data[(2+4)*18+36] = nebu_view*SIN225;
   data[(2+4)*18+37] = -nebu_view*COS225;
   data[(2+4)*18+38] = 0.;
   data[(2+4)*18+39] = -nebu_view;
   data[(2+4)*18+40] = -SCREEN_W*z-gx;
   data[(2+4)*18+41] = -SCREEN_H*z-gy;

   /* Bottom left */
   data[(2+4)*18+42] = -SCREEN_W*z-gx;
   data[(2+4)*18+43] = -SCREEN_H*z-gy;
   data[(2+4)*18+44] = 0.;
   data[(2+4)*18+45] = -nebu_view;
   data[(2+4)*18+46] = -nebu_view*SIN225;
   data[(2+4)*18+47] = -nebu_view*COS225;
   data[(2+4)*18+48] = -nebu_view*ANG45;
   data[(2+4)*18+49] = -nebu_view*ANG45;
   data[(2+4)*18+50] = -nebu_view*COS225;
   data[(2+4)*18+51] = -nebu_view*SIN225;
   data[(2+4)*18+52] = -nebu_view;
   data[(2+4)*18+53] = 0.;
   data[(2+4)*18+54] = -SCREEN_W*z-gx;
   data[(2+4)*18+55] = SCREEN_H*z-gy;

   gl_vboUnmap( nebu_vboOverlay );
}
コード例 #7
0
ファイル: weapon.c プロジェクト: zid/naev
/**
 * @brief Renders an individual weapon.
 *
 *    @param w Weapon to render.
 *    @param dt Current delta tick.
 */
static void weapon_render( Weapon* w, const double dt )
{
   double x,y, cx,cy, gx,gy;
   glTexture *gfx;
   double z;
   glColour c = { .r=1., .g=1., .b=1. };

   switch (w->outfit->type) {
      /* Weapons that use sprites. */
      case OUTFIT_TYPE_AMMO:
      case OUTFIT_TYPE_TURRET_AMMO:
      case OUTFIT_TYPE_BOLT:
      case OUTFIT_TYPE_TURRET_BOLT:
         gfx = outfit_gfx(w->outfit);

         /* Alpha based on strength. */
         c.a = w->strength;

         /* Outfit spins around. */
         if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_SPIN)) {
            /* Check timer. */
            w->anim -= dt;
            if (w->anim < 0.) {
               w->anim = outfit_spin(w->outfit);

               /* Increment sprite. */
               w->sprite++;
               if (w->sprite >= gfx->sx*gfx->sy)
                  w->sprite = 0;
            }

            /* Render. */
            if (outfit_isBolt(w->outfit) && w->outfit->u.blt.gfx_end)
               gl_blitSpriteInterpolate( gfx, w->outfit->u.blt.gfx_end,
                     w->timer / w->life,
                     w->solid->pos.x, w->solid->pos.y,
                     w->sprite % (int)gfx->sx, w->sprite / (int)gfx->sx, &c );
            else
               gl_blitSprite( gfx, w->solid->pos.x, w->solid->pos.y,
                     w->sprite % (int)gfx->sx, w->sprite / (int)gfx->sx, &c );
         }
         /* Outfit faces direction. */
         else {
            if (outfit_isBolt(w->outfit) && w->outfit->u.blt.gfx_end)
               gl_blitSpriteInterpolate( gfx, w->outfit->u.blt.gfx_end,
                     w->timer / w->life,
                     w->solid->pos.x, w->solid->pos.y, w->sx, w->sy, &c );
            else
               gl_blitSprite( gfx, w->solid->pos.x, w->solid->pos.y, w->sx, w->sy, &c );
         }
         break;

      /* Beam weapons. */
      case OUTFIT_TYPE_BEAM:
      case OUTFIT_TYPE_TURRET_BEAM:
         gfx = outfit_gfx(w->outfit);

         /* Zoom. */
         gl_cameraZoomGet( &z );

         /* Position. */
         gl_cameraGet( &cx, &cy );
         gui_getOffset( &gx, &gy );
         x = (w->solid->pos.x - cx)*z + gx;
         y = (w->solid->pos.y - cy)*z + gy;

         /* Set up the matrix. */
         glMatrixMode(GL_PROJECTION);
         glPushMatrix();
            glTranslated( x, y, 0. );
            glRotated( 270. + w->solid->dir / M_PI * 180., 0., 0., 1. );

         /* Preparatives. */
         glEnable(GL_TEXTURE_2D);
         glBindTexture( GL_TEXTURE_2D, gfx->texture);
         glShadeModel(GL_SMOOTH);

         /* Actual rendering. */
         glBegin(GL_QUAD_STRIP);

            /* Start faded. */
            ACOLOUR(cWhite, 0.);

            glTexCoord2d( w->anim, 0. );
            glVertex2d( -gfx->sh/2.*z, 0. );

            glTexCoord2d( w->anim, 1. );
            glVertex2d( +gfx->sh/2.*z, 0. );

            /* Full strength. */
            COLOUR(cWhite);

            glTexCoord2d( w->anim + 10. / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, 10.*z );

            glTexCoord2d( w->anim + 10. / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, 10.*z );

            glTexCoord2d( w->anim + 0.8*w->outfit->u.bem.range / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, 0.8*w->outfit->u.bem.range*z );

            glTexCoord2d( w->anim + 0.8*w->outfit->u.bem.range / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, 0.8*w->outfit->u.bem.range*z );

            /* Fades out. */
            ACOLOUR(cWhite, 0.);

            glTexCoord2d( w->anim + w->outfit->u.bem.range / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, w->outfit->u.bem.range*z );

            glTexCoord2d( w->anim + w->outfit->u.bem.range / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, w->outfit->u.bem.range*z );
         glEnd(); /* GL_QUAD_STRIP */

         /* Do the beam movement. */
         w->anim -= 5. * dt;
         if (w->anim <= -gfx->sw)
            w->anim += gfx->sw;

         /* Clean up. */
         glDisable(GL_TEXTURE_2D);
         glShadeModel(GL_FLAT);
         glPopMatrix(); /* GL_PROJECTION */
         gl_checkErr();
         break;

      default:
         WARN("Weapon of type '%s' has no render implemented yet!",
               w->outfit->name);
         break;
   }
}


/**
 * @brief Checks to see if the weapon can hit the pilot.
 *
 *    @param w Weapon to check if hits pilot.
 *    @param p Pilot to check if is hit by weapon.
 *    @return 1 if can be hit, 0 if can't.
 */
static int weapon_checkCanHit( Weapon* w, Pilot *p )
{
   Pilot *parent;

   /* Can't hit invincible stuff. */
   if (pilot_isFlag(p, PILOT_INVINCIBLE))
      return 0;

   /* Can never hit same faction. */
   if (p->faction == w->faction)
      return 0;

   /* Go "through" dead pilots. */
   if (pilot_isFlag(p, PILOT_DEAD))
      return 0;

   /* Player behaves differently. */
   if (w->faction == FACTION_PLAYER) {

      /* Always hit without safety. */
      if (!weapon_safety)
         return 1;

      /* Always hit target. */
      else if (w->target == p->id)
         return 1;

      /* Always hit hostiles. */
      else if (pilot_isFlag(p, PILOT_HOSTILE))
         return 1;

      /* Always hit unbribed enemies. */
      else if (!pilot_isFlag(p, PILOT_BRIBED) &&
            areEnemies(w->faction, p->faction))
        return 1;

      /* Miss rest - can be neutral/ally. */
      else
         return 0;
   }

   /* Let hostiles hit player. */
   if (p->faction == FACTION_PLAYER) {
      parent = pilot_get(w->parent);
      if (parent != NULL) {
         if (pilot_isFlag(parent, PILOT_BRIBED))
            return 0;
         if (pilot_isFlag(parent, PILOT_HOSTILE))
            return 1;
      }
   }

   /* Hit non-allies. */
   if (areEnemies(w->faction, p->faction))
      return 1;

   return 0;
}