Date
: 03/12/00
Author(s) : SpK
Skill(s) : Easy
Source Project(s) : CGame
Revision : 1.0
|
|
|
1) What you'll learn
In this tutorial, we'll see how shaders (scripts that add special
effects to the textures) are handled on the client side. We're going
to add a "quad effect" on all the items around the map.
And yes, this is totally absurd, but this is a great exemple to
explain how to apply a new shader on an entity of the game.
2) Code it !
Open the file called cg_ents.c of your cgame project (make sure
Cgame is your active project) and find the function static
void CG_Item( centity_t *cent ). This function, called on
each frames, runs all the game's items on the client side, and this
is where we'll call our new shader function, in order to add a quad
layer to our items, every frames.
Now copy/paste this code above the CG_Item function
:
void AddQuadLayer (centity_t *cent)
{
refEntity_t re;
gitem_t *item;
if (!cent->currentState.modelindex
||
(cent->currentState.eFlags & EF_NODRAW ))
return;
item = &bg_itemlist[cent->currentState.modelindex];
if (!item)
return;
memset( &re, 0, sizeof(
re ) );
re.reType = RT_MODEL;
re.customShader = cgs.media.quadShader;
re.hModel = cg_items[cent->currentState.modelindex].models[0];
AxisClear( re.axis );
AnglesToAxis( cent->lerpAngles,
re.axis );
if (item->giType == IT_WEAPON)
{
VectorScale( re.axis[0], 1.5, re.axis[0] );
VectorScale( re.axis[1], 1.5, re.axis[1] );
VectorScale( re.axis[2], 1.5, re.axis[2] );
}
VectorCopy( cent->lerpOrigin,
re.origin );
trap_R_AddRefEntityToScene(
&re );
}
So, what are we doing ?
refEntity_t
re;
ref-entities ("render entities") are entities
that are used to render special elements in the scene, such as grapple
trails, and are usually accompanied with a shader call.
memset(
&re, 0, sizeof( re ));
re.reType = RT_MODEL;
The first line resets our "re" refEntity's
memory to 0, so we're sure it won't contain anything else than what
we're gonna add to its content. The second line specify which render
type of we'll be using. In this case, we're using a model
render type, as our quad shader will depend of the model of our
items. reType can takes the following values :
RT_MODEL
RT_POLY
RT_SPRITE
RT_BEAM
RT_RAIL_CORE
RT_RAIL_RINGS
RT_LIGHTNING
RT_PORTALSURFACE
The most commons are RT_SPRITE and RT_BEAM.
re.customShader
= cgs.media.quadShader;
re.hModel = cg_items[es->modelindex].models[0];
Here, we specify the shader we'll use, and the model
it will apply to. The cgs.media.quadShader is defined in cg_main.c
with the following line :
cgs.media.quadShader = trap_R_RegisterShader("powerups/quad"
);
In fact, quadShader is just an index to the quad
shader script.
AxisClear( re.axis );
AnglesToAxis( cent->lerpAngles, re.axis );
Here, we're makking sure that our quad layer will
rotate in the same way as our item, else it won't have a good looking
!
VectorCopy( cent->lerpOrigin, re.origin
);
Here, we're setting our refEntity's origin to the
item's origin, so the quad layer will wrap it up.
trap_R_AddRefEntityToScene(
&re );
That's the most important line of all. If you forget
it, the quad layer will just not be rendered at all. This function
adds our refEntity to the "rendering queue".
Calling our new function
Okay, now we only need to call our new function at the end of the
CG_Item function, so our quad layer will be rendered on each frame
:
static void CG_Item( centity_t
*cent )
{
refEntity_t ent;
entityState_t *es;
gitem_t *item;
...
...
trap_R_AddRefEntityToScene( &ent );
}
}
}
AddQuadLayer
(cent);
}
Now compile your code, and run the game with +set
fs_game <your dir> +set sv_pure 0, and look at all those quaded
items around the map... This is just an exemple of what you can
do with the cgame part of the Q3Dll. But I'll let you discover the
rest :)
|