Beispiel #1
0
/**
 * @brief Prepares the rendering for the special effects.
 *
 * Should be called at the beginning of the rendering loop.
 *
 *    @param dt Current delta tick.
 *    @param real_dt Real delta tick.
 */
void spfx_begin( const double dt, const double real_dt )
{
   double ddt;

   /* Defaults. */
   shake_set = 0;
   if (shake_off)
      return;

#if SDL_VERSION_ATLEAST(1,3,0)
   /* Decrement the haptic timer. */
   if (haptic_lastUpdate > 0.)
      haptic_lastUpdate -= real_dt; /* Based on real delta-tick. */
#else /* SDL_VERSION_ATLEAST(1,3,0) */
   (void) real_dt; /* Avoid warning. */
#endif /* SDL_VERSION_ATLEAST(1,3,0) */

   /* Micro basic simple control loop. */
   if (dt > shake_fps_min) {
      ddt = dt;
      while (ddt > shake_fps_min) {
         spfx_updateShake( shake_fps_min );
         ddt -= shake_fps_min;
      }
      spfx_updateShake( ddt ); /* Leftover. */
   }
   else
      spfx_updateShake( dt );

   /* set the new viewport */
   gl_matrixTranslate( shake_pos.x, shake_pos.y );
   shake_set = 1;
}
Beispiel #2
0
Datei: font.c Projekt: nenau/naev
/**
 * @brief Starts the rendering engine.
 */
static void gl_fontRenderStart( const glFontStash* font, double x, double y, const glColour *c )
{
   double a;

   /* Enable textures. */
   glEnable(GL_TEXTURE_2D);

   /* Set up matrix. */
   gl_matrixMode(GL_MODELVIEW);
   gl_matrixPush();
      gl_matrixTranslate( round(x), round(y) );

   /* Handle colour. */
   if (font_restoreLast) {
      a   = (c==NULL) ? 1. : c->a;
      ACOLOUR(*font_lastCol,a);
   }
   else {
      if (c==NULL)
         glColor4d( 1., 1., 1., 1. );
      else
         COLOUR(*c);
   }
   font_restoreLast = 0;

   /* Activate the appropriate VBOs. */
   gl_vboActivateOffset( font->vbo_tex,  GL_TEXTURE_COORD_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( font->vbo_vert, GL_VERTEX_ARRAY, 0, 2, GL_SHORT, 0 );
}
Beispiel #3
0
Datei: font.c Projekt: nenau/naev
/**
 * @brief Renders a character.
 */
static int gl_fontRenderGlyph( glFontStash* stsh, uint32_t ch, const glColour *c, int state )
{
   GLushort ind[6];
   double a;
   const glColour *col;
   int vbo_id;

   /* Handle escape sequences. */
   if (ch == '\a') {/* Start sequence. */
      return 1;
   }
   if (state == 1) {
      col = gl_fontGetColour( ch );
      a   = (c==NULL) ? 1. : c->a;
      if (col == NULL) {
         if (c==NULL)
            glColor4d( 1., 1., 1., 1. );
         else
            COLOUR(*c);
      }
      else
         ACOLOUR(*col,a);
      font_lastCol = col;
      return 0;
   }

   /* Unicode goes here.
    * First try to find the glyph. */
   glFontGlyph *glyph;
   glyph = gl_fontGetGlyph( stsh, ch );
   if (glyph == NULL) {
      WARN(_("Unable to find glyph '%d'!"), ch );
      return -1;
   }

   /* Activate texture. */
   glBindTexture(GL_TEXTURE_2D, glyph->tex->id);

   /* VBO indices. */
   vbo_id = glyph->vbo_id;
   ind[0] = vbo_id + 0;
   ind[1] = vbo_id + 1;
   ind[2] = vbo_id + 3;
   ind[3] = vbo_id + 1;
   ind[4] = vbo_id + 3;
   ind[5] = vbo_id + 2;

   /* Draw the element. */
   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, ind );

   /* Translate matrix. */
   gl_matrixTranslate( glyph->adv_x, glyph->adv_y );

   return 0;
}
Beispiel #4
0
/**
 * @brief Sets the opengl viewport.
 */
void gl_viewport( int x, int y, int w, int h )
{
   gl_matrixMode(GL_PROJECTION);
   gl_matrixIdentity();
   gl_matrixOrtho( 0., /* Left edge. */
            gl_screen.nw, /* Right edge. */
            0., /* Bottom edge. */
            gl_screen.nh, /* Top edge. */
            -1., /* near */
            1. ); /* far */

   /* Take into account possible translation. */
   gl_screen.x = x;
   gl_screen.y = y;
   gl_matrixTranslate( x, y );

   /* Set screen size. */
   gl_screen.w = w;
   gl_screen.h = h;

   /* Take into account possible scaling. */
   if (gl_screen.scale != 1.)
      gl_matrixScale( gl_screen.wscale, gl_screen.hscale );
}
Beispiel #5
0
/**
 * @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();
}
Beispiel #6
0
/**
 * @brief Renders the nebula using the multitexture approach.
 *
 *    @param dt Current delta tick.
 */
static void nebu_renderMultitexture( const double dt )
{
   GLfloat col[4];
   int temp;
   double sx, sy;

   /* calculate frame to draw */
   nebu_timer -= dt;
   if (nebu_timer < 0.) { /* Time to change. */
      temp         = cur_nebu[0] - cur_nebu[1];
      cur_nebu[1]  = cur_nebu[0];
      cur_nebu[0] += temp;

      if (cur_nebu[0] >= NEBULA_Z)
         cur_nebu[0] = cur_nebu[1] - 1;
      else if (cur_nebu[0] < 0)
         cur_nebu[0] = cur_nebu[1] + 1;

      /* Change timer. */
      nebu_timer += nebu_dt;

      /* Case it hasn't rendered in a while so it doesn't go crazy. */
      if (nebu_timer < 0)
         nebu_timer = nebu_dt;
   }

   /* Set the colour */
   col[0] = cBlue.r;
   col[1] = cBlue.g;
   col[2] = cBlue.b;
   col[3] = (nebu_dt - nebu_timer) / nebu_dt;

   /* Set up the targets */
   /* Texture 0 */
   nglActiveTexture( GL_TEXTURE0 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, nebu_textures[cur_nebu[1]]);
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
   /* Texture 1 */
   nglActiveTexture( GL_TEXTURE1 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, nebu_textures[cur_nebu[0]]);

   /* Prepare it */
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_REPLACE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_INTERPOLATE );
   /* Colour */
   glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col );

   /* Arguments */
   /* Arg0 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB,    GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,  GL_TEXTURE );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
   /* Arg1 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,  GL_PREVIOUS );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
   /* Arg2 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,  GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA );

   /* Compensate possible rumble */
   spfx_getShake( &sx, &sy );
   gl_matrixPush();
      gl_matrixTranslate( -sx, -sy );

   /* Now render! */
   gl_vboActivateOffset( nebu_vboBG, GL_VERTEX_ARRAY,
         sizeof(GL_FLOAT) * 0*2*4, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboBG, GL_TEXTURE0,
         sizeof(GL_FLOAT) * 1*2*4, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboBG, GL_TEXTURE1,
         sizeof(GL_FLOAT) * 2*2*4, 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
   gl_vboDeactivate();

   gl_matrixPop();

   /* Set values to defaults */
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
   glDisable(GL_TEXTURE_2D);
   nglActiveTexture( GL_TEXTURE0 );
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
   glDisable(GL_TEXTURE_2D);

   /* Anything failed? */
   gl_checkErr();
}
Beispiel #7
0
/**
 * @brief Renders the starry background.
 *
 *    @param dt Current delta tick.
 */
void background_renderStars( const double dt )
{
   (void) dt;
   unsigned int i;
   GLfloat hh, hw, h, w;
   GLfloat x, y, m, b;
   GLfloat brightness;
   double z;
   double sx, sy;
   int shade_mode;
   int j, n;


   /*
    * gprof claims it's the slowest thing in the game!
    */

   /* Do some scaling for now. */
   z = cam_getZoom();
   z = 1. * (1. - conf.zoom_stars) + z * conf.zoom_stars;
   gl_matrixPush();
      gl_matrixTranslate( SCREEN_W/2., SCREEN_H/2. );
      gl_matrixScale( z, z );

   if (!paused && (player.p != NULL) && !player_isFlag(PLAYER_DESTROYED) &&
         !player_isFlag(PLAYER_CREATING)) { /* update position */

      /* Calculate some dimensions. */
      w  = (SCREEN_W + 2.*STAR_BUF);
      w += conf.zoom_stars * (w / conf.zoom_far - 1.);
      h  = (SCREEN_H + 2.*STAR_BUF);
      h += conf.zoom_stars * (h / conf.zoom_far - 1.);
      hw = w/2.;
      hh = h/2.;

      if ((star_x > SCREEN_W) || (star_y > SCREEN_H)) {
         sx = ceil( star_x / SCREEN_W );
         sy = ceil( star_y / SCREEN_H );
         n  = MAX( sx, sy );
         star_x /= (double)n;
         star_y /= (double)n;
      }
      else
         n = 1;

      /* Calculate new star positions. */
      for (j=0; j < n; j++) {
         for (i=0; i < nstars; i++) {

            /* calculate new position */
            b = 1./(9. - 10.*star_colour[8*i+3]);
            star_vertex[4*i+0] = star_vertex[4*i+0] + star_x*b;
            star_vertex[4*i+1] = star_vertex[4*i+1] + star_y*b;

            /* check boundaries */
            if (star_vertex[4*i+0] > hw)
               star_vertex[4*i+0] -= w;
            else if (star_vertex[4*i+0] < -hw)
               star_vertex[4*i+0] += w;
            if (star_vertex[4*i+1] > hh)
               star_vertex[4*i+1] -= h;
            else if (star_vertex[4*i+1] < -hh)
               star_vertex[4*i+1] += h;
         }
      }

      /* Upload the data. */
      gl_vboSubData( star_vertexVBO, 0, nstars * 4 * sizeof(GLfloat), star_vertex );
   }

   /* Decide on shade mode. */
   shade_mode = 0;
   if ((player.p != NULL) && !player_isFlag(PLAYER_DESTROYED) &&
         !player_isFlag(PLAYER_CREATING)) {

      if (pilot_isFlag(player.p,PILOT_HYPERSPACE) && /* hyperspace fancy effects */
            (player.p->ptimer < HYPERSPACE_STARS_BLUR)) {

         glShadeModel(GL_SMOOTH);
         shade_mode = 1;

         /* lines will be based on velocity */
         m  = HYPERSPACE_STARS_BLUR-player.p->ptimer;
         m /= HYPERSPACE_STARS_BLUR;
         m *= HYPERSPACE_STARS_LENGTH;
         x = m*cos(VANGLE(player.p->solid->vel));
         y = m*sin(VANGLE(player.p->solid->vel));
      }
      else if (dt_mod > 3.) {

         glShadeModel(GL_SMOOTH);
         shade_mode = 1;

         /* lines will be based on velocity */
         m = (dt_mod-3.)*VMOD(player.p->solid->vel)/10.;
         x = m*cos(VANGLE(player.p->solid->vel));
         y = m*sin(VANGLE(player.p->solid->vel));
      }

      if (shade_mode) {
         /* Generate lines. */
         for (i=0; i < nstars; i++) {
            brightness = star_colour[8*i+3];
            star_vertex[4*i+2] = star_vertex[4*i+0] + x*brightness;
            star_vertex[4*i+3] = star_vertex[4*i+1] + y*brightness;
         }

         /* Upload new data. */
         gl_vboSubData( star_vertexVBO, 0, nstars * 4 * sizeof(GLfloat), star_vertex );
      }
   }

   /* Render. */
   gl_vboActivate( star_vertexVBO, GL_VERTEX_ARRAY, 2, GL_FLOAT, 2 * sizeof(GLfloat) );
   gl_vboActivate( star_colourVBO, GL_COLOR_ARRAY,  4, GL_FLOAT, 4 * sizeof(GLfloat) );
   if (shade_mode) {
      glDrawArrays( GL_LINES, 0, nstars );
      glDrawArrays( GL_POINTS, 0, nstars ); /* This second pass is when the lines are very short that they "lose" intensity. */
      glShadeModel(GL_FLAT);
   }
   else {
      glDrawArrays( GL_POINTS, 0, nstars );
   }

   /* Clear star movement. */
   star_x = 0.;
   star_y = 0.;

   /* Disable vertex array. */
   gl_vboDeactivate();

   /* Pop matrix. */
   gl_matrixPop();

   /* Check for errors. */
   gl_checkErr();
}
Beispiel #8
0
/**
 * @brief Renders the overlay map.
 *
 *    @param dt Current delta tick.
 */
void ovr_render( double dt )
{
   (void) dt;
   int i, j;
   Pilot **pstk;
   int n;
   double w, h, res;
   double x,y;
   glColour c = { .r=0., .g=0., .b=0., .a=0.5 };

   /* Must be open. */
   if (!ovr_open)
      return;

   /* Player must be alive. */
   if (player_isFlag( PLAYER_DESTROYED ) || (player.p == NULL))
      return;

   /* Default values. */
   w     = SCREEN_W;
   h     = SCREEN_H;
   res   = ovr_res;

   /* First render the background overlay. */
   gl_renderRect( 0., 0., w, h, &c );

   /* We need to center in the image first. */
   gl_matrixPush();
      gl_matrixTranslate( w/2., h/2. );

   /* Render planets. */
   for (i=0; i<cur_system->nplanets; i++)
      if ((cur_system->planets[ i ]->real == ASSET_REAL) && (i != player.p->nav_planet))
         gui_renderPlanet( i, RADAR_RECT, w, h, res, 1 );
   if (player.p->nav_planet > -1)
      gui_renderPlanet( player.p->nav_planet, RADAR_RECT, w, h, res, 1 );

   /* Render jump points. */
   for (i=0; i<cur_system->njumps; i++)
      if (i != player.p->nav_hyperspace)
         gui_renderJumpPoint( i, RADAR_RECT, w, h, res, 1 );
   if (player.p->nav_hyperspace > -1)
      gui_renderJumpPoint( player.p->nav_hyperspace, RADAR_RECT, w, h, res, 1 );

   /* Render pilots. */
   pstk  = pilot_getAll( &n );
   j     = 0;
   for (i=0; i<n; i++) {
      if (pstk[i]->id == PLAYER_ID) /* Skip player. */
         continue;
      if (pstk[i]->id == player.p->target)
         j = i;
      else
         gui_renderPilot( pstk[i], RADAR_RECT, w, h, res, 1 );
   }
   /* Render the targetted pilot */
   if (j!=0)
      gui_renderPilot( pstk[j], RADAR_RECT, w, h, res, 1 );

   /* Check if player has goto target. */
   if (player_isFlag(PLAYER_AUTONAV) && (player.autonav == AUTONAV_POS_APPROACH)) {
      x = player.autonav_pos.x / res;
      y = player.autonav_pos.y / res;
      gl_renderCross( x, y, 5., &cRadar_hilight );
      gl_printRaw( &gl_smallFont, x+10., y-gl_smallFont.h/2., &cRadar_hilight, "GOTO" );
   }
   
   /* Render the player. */
   gui_renderPlayer( res, 1 );

   /* Render markers. */
   ovr_mrkRenderAll( res );

   /* Pop the matrix. */
   gl_matrixPop();
}


/**
 * @brief Renders all the markers.
 *
 *    @param res Resolution to render at.
 */
static void ovr_mrkRenderAll( double res )
{
   int i;
   ovr_marker_t *mrk;
   double x, y;

   if (ovr_markers == NULL)
      return;

   for (i=0; i<array_size(ovr_markers); i++) {
      mrk = &ovr_markers[i];

      x = mrk->u.pt.x / res;
      y = mrk->u.pt.y / res;
      gl_renderCross( x, y, 5., &cRadar_hilight );

      if (mrk->text != NULL)
         gl_printRaw( &gl_smallFont, x+10., y-gl_smallFont.h/2., &cRadar_hilight, mrk->text );
   }
}