ent_decal (ENTITY*, BMAP*, var size, var angle)
Attaches a decal to an arbitrarily shaped surface of the level, a terrain, or a model. A decal is a bitmap image that looks as if painted onto the surface and bends around corners. It can be used for bullet holes, scorch marks, footprints, ground shadows and so on.
||Entity to place the decal onto, or NULL for putting it at a level surface. By default the decal is placed at the hit position of a preceding c_trace.
||Bitmap to serve as decal image; must have an alpha channel, a square power of 2 size (f.i. 64x64, 256x256...)
and transparent border.
||Diameter of the decal in quants, or 0 for using the bitmap size.
||Rotation of the decal
about the hit surface normal (hit.nx)
in degrees, relative to the orientation of the target entity.
PARTICLE* pointer to the created decal particle.
The border of a decal bitmap, i.e. the alpha channel of the first and last pixel of every row and column, must be 100% transparent.
- The SCAN_TEXTURE parameter must be used by the preceding c_trace call to place the decal.
- For placing a decal to an entity without c_trace, set the following parameters of the global hit struct: hit.x at the decal position; hit.nx at the decal surface normal (usually either the normal of the hit surface, or the direction from the decal position towards the camera); hit.chunk at the number of the mesh to place the decal onto (if the entity consists of many meshes, f.i. chunked terrain); and hit.model at NULL. These hit parameters are otherwise set up by c_trace(...SCAN_TEXTURE).
For giving decals a rotation independent of the target entity - like for shadows on ground entities - rotate them back by the target entity angle, f.i. ent_decal(you, shadow_sprite, my.scale*100, my.pan-your.pan); .
- The level must be compiled in mesh mode for placing decals on level surfaces.
An entity must exist and be visible for at least 1 frame before decals can be placed on it.
Decals can not be placed on invisible entities or blocks,
or on surfaces that have no texture.
Every decal consumes a particle. Set max_particles accordingly when you need many decals. If more decals are used than particles are available, the oldest decals are removed and re-used for new decals. Decals are, like particles, not saved with game_save.
- The lifespan parameter of the returned decal particle can be used to limit the life time of a decal. By default the life time is unlimited. When lifespan is set to 0.001, the decal only exists for one frame, which can be used for moving a decal over a surface by permanently placing it anew.
- The alpha parameter and TRANSLUCENT flag of the decal particle can be used to control the transparency of the decal. When TRANSLUCENT is set, the decal's alpha parameter overrides the entities' alpha parameter and allows intransparent decals to be placed on transparent objects, or vice versa.
- A particle event function can change the alpha parameter for fading in or fading out the decal, or the bmap parameter for animating the decal. The particle parameters skill_x, skill_y, skill_z are internally used for the decal and must not be used by the particle function.
variable determines how decals are rendered. If particle_mode is
below 4 (default), decals use the entity mesh on animated entities
or entities with internal LOD meshes, and use their own mesh otherwise
. Using the entity mesh has the advantage that decals animate together with the entity, but the disadvantage that anisotropy filtering should be activated for preventing that the the empty polygon area around the decal appears tinted under acute angles. Using an own decal mesh that is cut out of the entity mesh prevents anisotropy artifacts, but also prevents decal animation. If particle_mode is at 4, decals always use the entity mesh; at 8 they always use their own mesh.
- The decal_clip variable (default = 85, range = 0..89) determines the maximum surface angle that can be covered by a decal. Surface polygons that are turned away from the decal normal (hit.nx, see above) by more than the given angle are not covered by the decal.
The d3d_near_decals factor (default = 0.99) determines the distance of the decal compared to its surface. Reduce this factor when decals show z-beating artifacts on a high clip_near/clip_far range; increase it (f.i. to 0.999) for putting decals closer to their surface.
The time for placing a decal on a mesh surface depends on the number of polygons of the mesh, and on the size of the decal.
The bigger the decal, the more vertices its mesh consists of and the slower is creation and rendering. Decal meshes are displayed by pressing [F11] twice.
- Decals do normally not exceed the boundaries of the meshes they are attached to, with one exception: On chunked terrain, decals are automatically spread over adjacent chunks.
- Decals are not rendered on LOD level 3.
If a model has several LOD models, only the main model is rendered when a decal is attached. This restriction does not apply to model with internal LOD meshes.
Decals are rendered with the surface material and shader unless they have an own material. The decal texture can be accessed through entSkin1 in a shader.
If the shader is not suited for a decal - f.i. when entSkin1 is used for a color mask on a multitexture shader,
or when the alpha channel is not used for transparency
- assign a decal material without a shader, such as mat_model or mat_terrain dependent on which object the decal is attached to.
- The ent_purge function removes all decals from the purged entity.
BMAP* bmMark = "blood.dds";
SOUND* sndShot = "bullet.wav";
// control a decal-placing gun with the camera
// calculate the target vector
vec_set(trace_target,vector(5000,0,0)); // the weapon has a firing range of 5000 quants
// display a red spot at the target position
if (c_trace(camera.x,trace_target, IGNORE_PASSABLE | USE_POLYGON| SCAN_TEXTURE) > 0) // hit something?
// fire and then place a decal at the hit position
if (key_ctrl) // fire
if (HIT_TARGET) // target hit?
PARTICLE* p = ent_decal(you,bmMark,7+random(3),random(360)); // place a random sized decal at the hit entity
p.lifespan = 1600; // remove decal after 100 seconds
p.material = mat_model; // assign a decal material
snd_play (sndShot,100,0); // play the shot sound at a volume of 100
wait(-0.5); // reload