Beispiel #1
0
void R_DrawLightningBeams(void)
{
	int i;
	beam_t *b;

	if (!cl_beams_polygons.integer)
		return;

	beamrepeatscale = 1.0f / r_lightningbeam_repeatdistance.value;
	for (i = 0, b = cl.beams;i < cl.num_beams;i++, b++)
	{
		if (b->model && b->lightning)
		{
			vec3_t org, start, end, dir;
			vec_t dist;
			CL_Beam_CalculatePositions(b, start, end);
			// calculate the nearest point on the line (beam) for depth sorting
			VectorSubtract(end, start, dir);
			dist = (DotProduct(r_refdef.view.origin, dir) - DotProduct(start, dir)) / (DotProduct(end, dir) - DotProduct(start, dir));
			dist = bound(0, dist, 1);
			VectorLerp(start, dist, end, org);
			// now we have the nearest point on the line, so sort with it
			R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, org, R_DrawLightningBeam_TransparentCallback, NULL, i, NULL);
		}
	}
}
Beispiel #2
0
static void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
{
	int surfacelistindex;
	float vertex3f[12*3];
	float texcoord2f[12*2];

	RSurf_ActiveCustomEntity(&identitymatrix, &identitymatrix, 0, 0, r_lightningbeam_color_red.value, r_lightningbeam_color_green.value, r_lightningbeam_color_blue.value, 1, 12, vertex3f, texcoord2f, NULL, NULL, NULL, NULL, 6, r_lightningbeamelement3i, r_lightningbeamelement3s, false, false);

	if (r_lightningbeam_qmbtexture.integer && r_lightningbeamqmbtexture == NULL)
		r_lightningbeams_setupqmbtexture();
	if (!r_lightningbeam_qmbtexture.integer && r_lightningbeamtexture == NULL)
		r_lightningbeams_setuptexture();

	for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
	{
		const beam_t *b = cl.beams + surfacelist[surfacelistindex];
		vec3_t beamdir, right, up, offset, start, end;
		float length, t1, t2;

		CL_Beam_CalculatePositions(b, start, end);

		// calculate beam direction (beamdir) vector and beam length
		// get difference vector
		VectorSubtract(end, start, beamdir);
		// find length of difference vector
		length = sqrt(DotProduct(beamdir, beamdir));
		// calculate scale to make beamdir a unit vector (normalized)
		t1 = 1.0f / length;
		// scale beamdir so it is now normalized
		VectorScale(beamdir, t1, beamdir);

		// calculate up vector such that it points toward viewer, and rotates around the beamdir
		// get direction from start of beam to viewer
		VectorSubtract(r_refdef.view.origin, start, up);
		// remove the portion of the vector that moves along the beam
		// (this leaves only a vector pointing directly away from the beam)
		t1 = -DotProduct(up, beamdir);
		VectorMA(up, t1, beamdir, up);
		// generate right vector from forward and up, the result is unnormalized
		CrossProduct(beamdir, up, right);
		// now normalize the right vector and up vector
		VectorNormalize(right);
		VectorNormalize(up);

		// calculate T coordinate scrolling (start and end texcoord along the beam)
		t1 = r_refdef.scene.time * -r_lightningbeam_scroll.value;// + beamrepeatscale * DotProduct(start, beamdir);
		t1 = t1 - (int) t1;
		t2 = t1 + beamrepeatscale * length;

		// the beam is 3 polygons in this configuration:
		//  *   2
		//   * *
		// 1******
		//   * *
		//  *   3
		// they are showing different portions of the beam texture, creating an
		// illusion of a beam that appears to curl around in 3D space
		// (and realize that the whole polygon assembly orients itself to face
		//  the viewer)

		// polygon 1, verts 0-3
		VectorScale(right, r_lightningbeam_thickness.value, offset);
		R_CalcLightningBeamPolygonVertex3f(vertex3f + 0, start, end, offset);
		// polygon 2, verts 4-7
		VectorAdd(right, up, offset);
		VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset);
		R_CalcLightningBeamPolygonVertex3f(vertex3f + 12, start, end, offset);
		// polygon 3, verts 8-11
		VectorSubtract(right, up, offset);
		VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset);
		R_CalcLightningBeamPolygonVertex3f(vertex3f + 24, start, end, offset);
		R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 0, t1, t2);
		R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 8, t1 + 0.33, t2 + 0.33);
		R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 16, t1 + 0.66, t2 + 0.66);

		// draw the 3 polygons as one batch of 6 triangles using the 12 vertices
		R_DrawCustomSurface(r_lightningbeam_qmbtexture.integer ? r_lightningbeamqmbtexture : r_lightningbeamtexture, &identitymatrix, MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE, 0, 12, 0, 6, false, false);
	}
}
void CL_Beam_AddPolygons(const beam_t *b)
{
	vec3_t beamdir, right, up, offset, start, end;
	vec_t beamscroll = r_refdef.scene.time * -r_lightningbeam_scroll.value;
	vec_t beamrepeatscale = 1.0f / r_lightningbeam_repeatdistance.value;
	float length, t1, t2;
	dp_model_t *mod;
	msurface_t *surf;

	if (r_lightningbeam_qmbtexture.integer && cl_beams_externaltexture.currentskinframe == NULL)
		CL_Beams_SetupExternalTexture();
	if (!r_lightningbeam_qmbtexture.integer && cl_beams_builtintexture.currentskinframe == NULL)
		CL_Beams_SetupBuiltinTexture();

	// calculate beam direction (beamdir) vector and beam length
	// get difference vector
	CL_Beam_CalculatePositions(b, start, end);
	VectorSubtract(end, start, beamdir);
	// find length of difference vector
	length = sqrt(DotProduct(beamdir, beamdir));
	// calculate scale to make beamdir a unit vector (normalized)
	t1 = 1.0f / length;
	// scale beamdir so it is now normalized
	VectorScale(beamdir, t1, beamdir);

	// calculate up vector such that it points toward viewer, and rotates around the beamdir
	// get direction from start of beam to viewer
	VectorSubtract(r_refdef.view.origin, start, up);
	// remove the portion of the vector that moves along the beam
	// (this leaves only a vector pointing directly away from the beam)
	t1 = -DotProduct(up, beamdir);
	VectorMA(up, t1, beamdir, up);
	// generate right vector from forward and up, the result is unnormalized
	CrossProduct(beamdir, up, right);
	// now normalize the right vector and up vector
	VectorNormalize(right);
	VectorNormalize(up);

	// calculate T coordinate scrolling (start and end texcoord along the beam)
	t1 = beamscroll;
	t1 = t1 - (int)t1;
	t2 = t1 + beamrepeatscale * length;

	// the beam is 3 polygons in this configuration:
	//  *   2
	//   * *
	// 1*****
	//   * *
	//  *   3
	// they are showing different portions of the beam texture, creating an
	// illusion of a beam that appears to curl around in 3D space
	// (and realize that the whole polygon assembly orients itself to face
	//  the viewer)

	mod = &cl_meshentitymodels[MESH_PARTICLES];
	surf = Mod_Mesh_AddSurface(mod, r_lightningbeam_qmbtexture.integer ? &cl_beams_externaltexture : &cl_beams_builtintexture, false);
	// polygon 1
	VectorM(r_lightningbeam_thickness.value, right, offset);
	CL_Beam_AddQuad(mod, surf, start, end, offset, t1, t2);
	// polygon 2
	VectorMAM(r_lightningbeam_thickness.value * 0.70710681f, right, r_lightningbeam_thickness.value * 0.70710681f, up, offset);
	CL_Beam_AddQuad(mod, surf, start, end, offset, t1 + 0.33f, t2 + 0.33f);
	// polygon 3
	VectorMAM(r_lightningbeam_thickness.value * 0.70710681f, right, r_lightningbeam_thickness.value * -0.70710681f, up, offset);
	CL_Beam_AddQuad(mod, surf, start, end, offset, t1 + 0.66f, t2 + 0.66f);
}