| Shell Effects | |
| New Texture | |
|
We need to define a variable to hold our new texture. We'll do it where the particle texture is defined in gl_rmain.c | |
image_t *r_notexture; // use for bad textures image_t *r_particletexture; image_t *r_shelltexture; // c14 added shell texture | |
| Also we'll make a global definition for it in gl_local.h | |
extern image_t *r_notexture; extern image_t *r_particletexture; extern image_t *r_shelltexture; // c14 added shell texture extern entity_t *currententity; extern model_t *currentmodel; | |
|
We need to load a nice texture in gl_rmisc.c The code below assumes that you've already done something to load tga textures or some such. | |
for (x=0 ; x<8 ; x++)
{
for (y=0 ; y<8 ; y++)
{
data[y][x][0] = 255;
data[y][x][1] = 255;
data[y][x][2] = 255;
data[y][x][3] = dottexture[x][y] * 255;
}
}
r_particletexture = GL_LoadPic ("***particle***", (byte *)data, 8, 8, it_sprite, 32);
// c14 add from here
r_shelltexture = Draw_FindPic("particle/shell");
if (!r_shelltexture) {
r_shelltexture = GL_LoadPic ("***shell***", (byte *)data, 8, 8, it_sprite, 32);
}
// c14 to here
| |
| Make sure that the shell texture is not unloaded between games in gl_image.c | |
// never free r_notexture or particle texture
r_notexture->registration_sequence = registration_sequence;
r_particletexture->registration_sequence = registration_sequence;
r_shelltexture->registration_sequence = registration_sequence; // c14 added shell texture
| |
| Rendering | |
| All of the rendering work is done in the function GL_DrawAliasFrameLerp in gl_mesh.c | |
| In the vanilla code, textures on shells are disabled. | |
if (currententity->flags & RF_TRANSLUCENT)
alpha = currententity->alpha;
else
alpha = 1.0;
// PMM - added double shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
// qglDisable( GL_TEXTURE_2D ); // c14 comment out this line
GL_Bind(r_shelltexture->texnum); // add this line
| |
| Force the alpha back up to 1, because the alpha channel of the texture will give us our transparency. | |
qglEnableClientState( GL_VERTEX_ARRAY );
qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); // padded for SIMD
// if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
// PMM - added double damage shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
{
// qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha ); // c14 comment out this line
qglColor4f( shadelight[0], shadelight[1], shadelight[2], 1.0 ); // c14 add this line
}
| |
| Now add in texture coordinates. Here I have based the horizontal coordinates on a combination of the x and y of the model vertex, and the vertical coordinate is the z of the vertex modified by the time, so that the textures flows upwards. | |
// PMM - added double damage shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
{
do
{
index_xyz = order[2];
order += 3;
// c14 added the line below
qglTexCoord2f ((s_lerped[index_xyz][1] + s_lerped[index_xyz][0]) / 40.0, s_lerped[index_xyz][2] / 40.0 - r_newrefdef.time / 2.0);
qglVertex3fv( s_lerped[index_xyz] );
} while (--count);
}
| |
| Both of the above changes, also need to be done a little further down, just in case you're not using gl_vertex_arrays. | |
// c14 The line below seems to be a bug. It looks like PMM should have modified this line when the new shell types were added.
// if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) // c14 comment out this line
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) // c14 added this line.
{
do
{
index_xyz = order[2];
order += 3;
// qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha); // c14 comment out this line
qglColor4f( shadelight[0], shadelight[1], shadelight[2], 1.0); // c14 add this line
// c14 added the line below
qglTexCoord2f ((s_lerped[index_xyz][1] + s_lerped[index_xyz][0]) / 40.0, s_lerped[index_xyz][2] / 40.0 - r_newrefdef.time / 2.0);
qglVertex3fv (s_lerped[index_xyz]);
} while (--count);
}
else
| |
|
That's it. I think. Give it a try. I've added a couple more features because somebody asked about them. They're in a separate tutorial. Here is the texture that I use, you can have it in TGA or PNG format. |
![]() |
| Here is another texture that I use, you can have it in TGA or PNG format. | ![]() |