Пример #1
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();
}
Пример #2
0
/**
 * @brief Texture blitting backend for interpolated texture.
 *
 * Value blitted is  ta*inter + tb*(1.-inter).
 *
 *    @param ta Texture A to blit.
 *    @param tb Texture B to blit.
 *    @param inter Amount of interpolation to do.
 *    @param x X position of the texture on the screen.
 *    @param y Y position of the texture on the screen.
 *    @param tx X position within the texture.
 *    @param ty Y position within the texture.
 *    @param tw Texture width.
 *    @param th Texture height.
 *    @param c Colour to use (modifies texture colour).
 */
static void gl_blitTextureInterpolate(  const glTexture* ta,
      const glTexture* tb, const double inter,
      const double x, const double y,
      const double w, const double h,
      const double tx, const double ty,
      const double tw, const double th, const glColour *c )
{
   GLfloat vertex[4*2], tex[4*2], col[4*4];
   GLfloat mcol[4] = { 0., 0., 0. };

   /* No interpolation. */
   if (!conf.interpolate || (tb == NULL)) {
      gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c );
      return;
   }

   /* Corner cases. */
   if (inter == 1.) {
      gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c );
      return;
   }
   else if (inter == 0.) {
      gl_blitTexture( tb, x, y, w, h, tx, ty, tw, th, c );
      return;
   }

   /* No multitexture. */
   if (nglActiveTexture == NULL) {
      if (inter > 0.5)
         gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c );
      else
         gl_blitTexture( tb, x, y, w, h, tx, ty, tw, th, c );
   }

   /* Set default colour. */
   if (c == NULL)
      c = &cWhite;

   /* Bind the textures. */
   /* Texture 0. */
   nglActiveTexture( GL_TEXTURE0 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, ta->texture);

   /* Set the mode. */
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );

   /* Interpolate texture and alpha. */
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_INTERPOLATE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_INTERPOLATE );
   mcol[3] = inter;
   glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mcol );

   /* Arguments. */
   /* Arg0. */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB,    GL_TEXTURE0 );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,  GL_TEXTURE0 );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
   /* Arg1. */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB,    GL_TEXTURE1 );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,  GL_TEXTURE1 );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
   /* Arg2. */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB,    GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB,   GL_SRC_ALPHA );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,  GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA );

   /* Texture 1. */
   nglActiveTexture( GL_TEXTURE1 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, tb->texture);

   /* Set the mode. */
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );

   /* Interpolate texture and alpha. */
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_MODULATE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_MODULATE );

   /* Arguments. */
   /* Arg0. */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB,    GL_PREVIOUS );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,  GL_PREVIOUS );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
   /* Arg1. */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB,    GL_PRIMARY_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,  GL_PRIMARY_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );

   /* Set the colour. */
   col[0] = c->r;
   col[1] = c->g;
   col[2] = c->b;
   col[3] = c->a;
   col[4] = col[0];
   col[5] = col[1];
   col[6] = col[2];
   col[7] = col[3];
   col[8] = col[0];
   col[9] = col[1];
   col[10] = col[2];
   col[11] = col[3];
   col[12] = col[0];
   col[13] = col[1];
   col[14] = col[2];
   col[15] = col[3];
   gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset, 4*4*sizeof(GLfloat), col );
   gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY,
         gl_renderVBOcolOffset, 4, GL_FLOAT, 0 );

   /* Set the vertex. */
   vertex[0] = (GLfloat)x;
   vertex[4] = vertex[0];
   vertex[2] = vertex[0] + (GLfloat)w;
   vertex[6] = vertex[2];
   vertex[1] = (GLfloat)y;
   vertex[3] = vertex[1];
   vertex[5] = vertex[1] + (GLfloat)h;
   vertex[7] = vertex[5];
   gl_vboSubData( gl_renderVBO, 0, 4*2*sizeof(GLfloat), vertex );
   gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );

   /* Set the texture. */
   tex[0] = (GLfloat)tx;
   tex[4] = tex[0];
   tex[2] = tex[0] + (GLfloat)tw;
   tex[6] = tex[2];
   tex[1] = (GLfloat)ty;
   tex[3] = tex[1];
   tex[5] = tex[1] + (GLfloat)th;
   tex[7] = tex[5];
   gl_vboSubData( gl_renderVBO, gl_renderVBOtexOffset, 4*2*sizeof(GLfloat), tex );
   gl_vboActivateOffset( gl_renderVBO, GL_TEXTURE0,
         gl_renderVBOtexOffset, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( gl_renderVBO, GL_TEXTURE1,
         gl_renderVBOtexOffset, 2, GL_FLOAT, 0 );

   /* Draw. */
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );

   /* Clear state. */
   gl_vboDeactivate();
   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();
}