/** * @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(); }
/** * @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(); }