Beispiel #1
0
/*
 * @brief
 */
static void R_DrawLines(void) {

	if (!r_draw.line_arrays.vert_index)
		return;

	R_EnableTexture(&texunit_diffuse, false);

	R_EnableColorArray(true);

	// alter the array pointers
	R_BindArray(GL_VERTEX_ARRAY, GL_SHORT, r_draw.line_arrays.verts);
	R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_draw.line_arrays.colors);

	glDrawArrays(GL_LINES, 0, r_draw.line_arrays.vert_index / 2);

	// and restore them
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_COLOR_ARRAY);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_diffuse, true);

	r_draw.line_arrays.vert_index = r_draw.line_arrays.color_index = 0;
}
Beispiel #2
0
void R_DrawChars (void)
{
	if (!r_char_arrays.vert_index)
		return;

	R_BindTexture(draw_chars->texnum);

	R_EnableColorArray(true);

	/* alter the array pointers */
	R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_char_arrays.colors);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, r_char_arrays.texcoords);
	glVertexPointer(2, GL_SHORT, 0, r_char_arrays.verts);

	glDrawArrays(GL_QUADS, 0, r_char_arrays.vert_index / 2);

	refdef.batchCount++;

	r_char_arrays.color_index = 0;
	r_char_arrays.texcoord_index = 0;
	r_char_arrays.vert_index = 0;

	/* and restore them */
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_COLOR_ARRAY);

	R_EnableColorArray(false);
}
Beispiel #3
0
/**
 * @brief Draws a marker on the ground to indicate pathing CL_AddPathingBox
 * @sa CL_AddPathing
 * @sa RF_BOX
 */
static void R_DrawFloor (const entity_t * e)
{
	image_t *cellIndicator = R_FindImage("pics/sfx/cell", it_pic);
	const float dx = PLAYER_WIDTH * 2;
	const vec4_t color = {e->color[0], e->color[1], e->color[2], e->alpha};
	const float size = 4.0;
	/** @todo use default_texcoords */
	const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } };
	const vec3_t points[] = { { e->origin[0] - size, e->origin[1] + dx + size, e->origin[2] }, { e->origin[0] + dx
			+ size, e->origin[1] + dx + size, e->origin[2] }, { e->origin[0] + dx + size, e->origin[1] - size,
			e->origin[2] }, { e->origin[0] - size, e->origin[1] - size, e->origin[2] } };

	glDisable(GL_DEPTH_TEST);

	R_Color(color);
	R_BindTexture(cellIndicator->texnum);

	/* circle points */
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount++;

	glEnable(GL_DEPTH_TEST);

	R_Color(NULL);
}
Beispiel #4
0
/*
 * @brief
 */
static void R_DrawChars(void) {
	uint16_t i;

	for (i = 0; i < r_draw.num_fonts; i++) {
		r_char_arrays_t *chars = &r_draw.char_arrays[i];

		if (!chars->vert_index)
			continue;

		R_BindTexture(r_draw.fonts[i].image->texnum);

		R_EnableColorArray(true);

		// alter the array pointers
		R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, chars->colors);
		R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, chars->texcoords);
		R_BindArray(GL_VERTEX_ARRAY, GL_SHORT, chars->verts);

		glDrawArrays(GL_QUADS, 0, chars->vert_index / 2);

		chars->color_index = 0;
		chars->texcoord_index = 0;
		chars->vert_index = 0;
	}

	// restore array pointers
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_COLOR_ARRAY);

	R_EnableColorArray(false);

	// restore draw color
	R_Color(NULL);
}
/**
 * @sa R_DrawParticles
 */
static void R_DrawSprite (const ptl_t * p)
{
	const ptl_t *q;
	vec3_t up, right;
	vec3_t nup, nright;
	vec3_t pos;
	float texcoords[8];

	/* load texture set up coordinates */
	assert(p->pic);
	R_BindTexture(p->pic->art.image->texnum);

	/* calculate main position and normalised up and right vectors */
	q = p->parent ? p->parent : p;
	R_GetSpriteVectors(q, right, up);

	/* Calculate normalised */
	VectorCopy(up, nup);
	VectorCopy(right, nright);
	VectorNormalizeFast(nup);
	VectorNormalizeFast(nright);

	/* offset */
	VectorCopy(q->s, pos);
	VectorMA(pos, q->offset[0], nup, pos);
	VectorMA(pos, q->offset[1], nright, pos);

	if (p->parent) {
		/* if this is a child then calculate our own up and right vectors and offsets */
		R_GetSpriteVectors(p, right, up);

		/* but offset by our parent's nup and nright */
		VectorMA(pos, p->offset[0], nup, pos);
		VectorMA(pos, p->offset[1], nright, pos);
	}

	/* center image */
	VectorMA(pos, -0.5, up, pos);
	VectorMA(pos, -0.5, right, pos);

	R_SpriteTexcoords(p, texcoords);

	R_Color(p->color);
	{
		/* draw it */
		const vec3_t points[] = { { pos[0], pos[1], pos[2] }, { pos[0] + up[0], pos[1] + up[1], pos[2] + up[2] }, { pos[0]
				+ up[0] + right[0], pos[1] + up[1] + right[1], pos[2] + up[2] + right[2] }, { pos[0] + right[0], pos[1]
				+ right[1], pos[2] + right[2] } };

		R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
		R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
		R_BindDefaultArray(GL_VERTEX_ARRAY);
		R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);

		refdef.batchCount++;
	}
}
Beispiel #6
0
/**
 * @brief Static model render function
 * @sa R_DrawAliasFrameLerp
 */
static void R_DrawAliasStatic (const mAliasMesh_t *mesh, const vec4_t shellColor)
{
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, mesh->verts);
	R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, mesh->normals);
	if (r_state.active_normalmap || r_state.dynamic_lighting_enabled)
		R_BindArray(GL_TANGENT_ARRAY, GL_FLOAT, mesh->tangents);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mesh->texcoords);

	glDrawArrays(GL_TRIANGLES, 0, mesh->num_tris * 3);

	refdef.batchCount++;

	R_DrawMeshModelShell(mesh, shellColor);
}
Beispiel #7
0
void R_DrawFills (void)
{
	if (!r_fill_arrays.vert_index)
		return;

	R_EnableTexture(&texunit_diffuse, false);

	R_EnableColorArray(true);

	/* alter the array pointers */
	R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_fill_arrays.colors);
	glVertexPointer(2, GL_SHORT, 0, r_fill_arrays.verts);

	glDrawArrays(GL_QUADS, 0, r_fill_arrays.vert_index / 2);

	refdef.batchCount++;

	/* and restore them */
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_COLOR_ARRAY);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_diffuse, true);

	r_fill_arrays.vert_index = r_fill_arrays.color_index = 0;

	R_Color(NULL);
}
Beispiel #8
0
/**
 * @brief Draws an arrow between two points
 * @sa CL_AddArrow
 * @sa RF_BOX
 */
static void R_DrawArrow (const entity_t* e)
{
	const vec3_t upper = { e->origin[0] + 2, e->origin[1], e->origin[2] };
	const vec3_t mid = { e->origin[0], e->origin[1] + 2, e->origin[2] };
	const vec3_t lower = { e->origin[0], e->origin[1], e->origin[2] + 2 };
	const vec4_t color = { e->color[0], e->color[1], e->color[2], e->alpha };
	const vec3_t points[] = { { e->oldorigin[0], e->oldorigin[1], e->oldorigin[2] }, { upper[0], upper[1], upper[2] },
			{ mid[0], mid[1], mid[2] }, { lower[0], lower[1], lower[2] } };

	R_Color(color);

	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LINE_SMOOTH);

	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount++;

	glDisable(GL_LINE_SMOOTH);
	glEnable(GL_TEXTURE_2D);

	R_Color(nullptr);
}
Beispiel #9
0
void R_DrawBoundingBoxes (void)
{
	int i;
	const int step = 3 * 8;
	const int bboxes = r_bbox_array.bboxes_index / step;
	const glIndex indexes[] = { 2, 1, 0, 1, 4, 5, 1, 7, 3, 2, 7, 6, 2, 4, 0 };
	const glIndex indexes2[] = { 4, 6, 7 };

	if (!r_bbox_array.bboxes_index)
		return;

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	R_Color(NULL);

	for (i = 0; i < bboxes; i++) {
		const float *bbox = &r_bbox_array.bboxes[i * step];
		R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, bbox);
		/* Draw top and sides */
		glDrawElements(GL_TRIANGLE_FAN, 15, GLINDEX, indexes);
		/* Draw bottom */
		glDrawElements(GL_TRIANGLE_FAN, 3, GLINDEX, indexes2);
	}

	R_BindDefaultArray(GL_VERTEX_ARRAY);

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	r_bbox_array.bboxes_index = 0;
}
Beispiel #10
0
/**
 * @brief "Clean up" the depth buffer into a rect
 * @note we use a big value (but not too big) to set the depth buffer, then it is not really a clean up
 * @todo can we fix bigZ with a value come from glGet?
 */
void R_CleanupDepthBuffer (int x, int y, int width, int height)
{
	const int nx = x * viddef.rx;
	const int ny = y * viddef.ry;
	const int nwidth = width * viddef.rx;
	const int nheight = height * viddef.ry;
	const GLboolean hasDepthTest = glIsEnabled(GL_DEPTH_TEST);
	const GLdouble bigZ = 2000;
	const vec3_t points [] = { { nx, ny, bigZ }, { nx + nwidth, ny, bigZ }, { nx + nwidth, ny + nheight, bigZ }, { nx, ny + nheight, bigZ } };

	GLint depthFunc;
	glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);

	/* we want to overwrite depth buffer not to have his constraints */
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_ALWAYS);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount++;

	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	if (!hasDepthTest)
		glDisable(GL_DEPTH_TEST);
	glDepthFunc(depthFunc);
}
Beispiel #11
0
void R_DrawCircle (float radius, const vec4_t color, float thickness, const vec3_t shift)
{
	vec3_t points[16];
	const size_t steps = lengthof(points);
	unsigned int i;

	glEnable(GL_LINE_SMOOTH);
	glLineWidth(thickness);

	R_Color(color);

	for (i = 0; i < steps; i++) {
		const float a = 2.0f * M_PI * (float) i / (float) steps;
		VectorSet(points[i], shift[0] + radius * cos(a), shift[1] + radius * sin(a), shift[2]);
	}

	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_LINE_LOOP, 0, steps);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount++;

	R_Color(NULL);

	glLineWidth(1.0f);
	glDisable(GL_LINE_SMOOTH);
}
Beispiel #12
0
/*
 * @brief Draws all particles for the current frame.
 */
void R_DrawParticles(const r_element_t *e, const size_t count) {
	size_t i, j;

	R_EnableColorArray(true);

	R_ResetArrayState();

	// alter the array pointers
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, r_particle_state.verts);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, r_particle_state.texcoords);
	R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_particle_state.colors);

	const GLuint base = (uintptr_t) e->data;

	for (i = j = 0; i < count; i++, e++) {
		const r_particle_t *p = (const r_particle_t *) e->element;

		// bind the particle's texture
		if (p->image->texnum != texunit_diffuse.texnum) {

			if (i > j) { // draw pending particles
				glDrawArrays(GL_QUADS, (base + j) * 4, (i - j) * 4);
				j = i;
			}

			R_BindTexture(p->image->texnum);
			R_BlendFunc(GL_SRC_ALPHA, p->blend);
		}
	}

	if (i > j) { // draw any remaining particles
		glDrawArrays(GL_QUADS, (base + j) * 4, (i - j) * 4);
	}

	// restore array pointers
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_COLOR_ARRAY);

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_EnableColorArray(false);

	R_Color(NULL);
}
Beispiel #13
0
/**
 * @brief Draws the field marker entity is specified in CL_AddTargeting
 * @sa CL_AddTargeting
 * @sa RF_BOX
 */
static void R_DrawBox (const entity_t* e)
{
	const vec4_t color = {e->color[0], e->color[1], e->color[2], e->alpha};

	if (e->texture) {
		R_Color(color);
		R_BindTexture(e->texture->texnum);
		if (VectorNotEmpty(e->eBox.mins) && VectorNotEmpty(e->eBox.maxs)) {
			R_DrawTexturedBox(e->eBox.mins, e->eBox.maxs);
		} else {
			R_DrawTexturedBox(e->oldorigin, e->origin);
		}
		R_Color(nullptr);
		return;
	}

	glDisable(GL_TEXTURE_2D);

	R_Color(color);

	if (VectorNotEmpty(e->eBox.mins) && VectorNotEmpty(e->eBox.maxs)) {
		R_DrawBoundingBox(e->eBox);
	} else {
		vec3_t points[] = { { e->oldorigin[0], e->oldorigin[1], e->oldorigin[2] }, { e->oldorigin[0], e->origin[1],
				e->oldorigin[2] }, { e->origin[0], e->origin[1], e->oldorigin[2] }, { e->origin[0], e->oldorigin[1],
				e->oldorigin[2] } };

		glLineWidth(2.0f);
		R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);

		/** @todo fill one array */
		glDrawArrays(GL_LINE_LOOP, 0, 4);
		refdef.batchCount++;
		points[0][2] = e->origin[2];
		points[1][2] = e->origin[2];
		points[2][2] = e->origin[2];
		points[3][2] = e->origin[2];
		glDrawArrays(GL_LINE_LOOP, 0, 4);
		refdef.batchCount++;
		points[0][2] = e->oldorigin[2];
		points[1][1] = e->oldorigin[1];
		points[2][2] = e->oldorigin[2];
		points[3][1] = e->origin[1];
		glDrawArrays(GL_LINES, 0, 4);
		refdef.batchCount++;
		points[0][0] = e->origin[0];
		points[1][0] = e->origin[0];
		points[2][0] = e->oldorigin[0];
		points[3][0] = e->oldorigin[0];
		glDrawArrays(GL_LINES, 0, 4);
		refdef.batchCount++;
		R_BindDefaultArray(GL_VERTEX_ARRAY);
	}
	glEnable(GL_TEXTURE_2D);

	R_Color(nullptr);
}
Beispiel #14
0
void R_DrawGrass ()
{
	if (clumpTriangleCount <= 0)
		return;

	R_BindTexture(R_FindImage("models/objects/vegi/plants2/plant_skin3", it_pic)->texnum);

	R_EnableAlphaTest(true);

	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, gfv_texcoord);
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, gfv_pos);
	glDrawArrays(GL_TRIANGLES, 0, clumpTrianglesForLevel[refdef.worldlevel] * 3);
	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);

	R_EnableAlphaTest(false);

	refdef.batchCount++;
}
Beispiel #15
0
/**
 * @brief Draws the textured box, the caller should bind the texture
 * @sa R_DrawBox
 */
void R_DrawTexturedBox (const vec3_t a0, const vec3_t a1)
{
	const GLfloat texcoords[] = { 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, };
	const vec3_t bbox[] = {
					{ a0[0], a0[1], a0[2] }, { a0[0], a0[1], a1[2] }, { a1[0], a0[1], a1[2] }, { a1[0], a0[1], a0[2] },
					{ a1[0], a1[1], a0[2] }, { a1[0], a1[1], a1[2] }, { a0[0], a1[1], a1[2] }, { a0[0], a1[1], a0[2] },
					{ a0[0], a0[1], a0[2] }, { a0[0], a0[1], a1[2] }, { a1[0], a0[1], a1[2] }, { a1[0], a0[1], a0[2] },
					{ a1[0], a1[1], a0[2] }, { a1[0], a1[1], a1[2] }, { a0[0], a1[1], a1[2] }, { a0[0], a1[1], a0[2] } };
	const glIndex indexes[] = { 0, 1, 2, 1, 2, 3, 4, 5, 6, 6, 7, 4, 2 + 8, 3 + 8, 4 + 8, 2 + 8, 5 + 8, 4 + 8, 6 + 8, 7 + 8,
			0 + 8, 0 + 8, 1 + 8, 6 + 8, };

	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, bbox);

	/* Draw sides only */
	glDrawElements(GL_TRIANGLES, 8 * 3, GLINDEX, indexes);

	R_BindDefaultArray(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
}
Beispiel #16
0
/*
 * R_BindDefaultArray
 *
 * Binds the appropriate shared vertex array to the specified target.
 */
void R_BindDefaultArray(GLenum target) {

	switch (target) {
	case GL_VERTEX_ARRAY:
		if (r_state.ortho)
			R_BindArray(target, GL_SHORT, r_state.vertex_array_2d);
		else
			R_BindArray(target, GL_FLOAT, r_state.vertex_array_3d);
		break;
	case GL_TEXTURE_COORD_ARRAY:
		R_BindArray(target, GL_FLOAT, r_state.active_texunit->texcoord_array);
		break;
	case GL_COLOR_ARRAY:
		R_BindArray(target, GL_FLOAT, r_state.color_array);
		break;
	case GL_NORMAL_ARRAY:
		R_BindArray(target, GL_FLOAT, r_state.normal_array);
		break;
	case GL_TANGENT_ARRAY:
		R_BindArray(target, GL_FLOAT, r_state.tangent_array);
		break;
	default:
		break;
	}
}
Beispiel #17
0
/*
 * R_BindBuffer
 */
void R_BindBuffer(GLenum target, GLenum type, GLuint id) {

	if (!qglBindBuffer)
		return;

	if (!r_vertex_buffers->value)
		return;

	qglBindBuffer(GL_ARRAY_BUFFER, id);

	if (type && id) // assign the array pointer as well
		R_BindArray(target, type, NULL);
}
Beispiel #18
0
/**
 * @brief Draws a marker on the ground to indicate pathing CL_AddPathingBox
 * @sa CL_AddPathing
 * @sa RF_BOX
 */
static void R_DrawFloor (const entity_t* e)
{
	GLint oldDepthFunc;
	glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc);

	image_t* cellIndicator = R_FindImage("pics/sfx/cell", it_pic);
	const float dx = PLAYER_WIDTH * 2;
	const vec4_t color = {e->color[0], e->color[1], e->color[2], e->alpha};
	const float size = 4.0;
	/** @todo use default_texcoords */
	const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } };
	const vec3_t points[] = { { e->origin[0] - size, e->origin[1] + dx + size, e->origin[2] }, { e->origin[0] + dx
			+ size, e->origin[1] + dx + size, e->origin[2] }, { e->origin[0] + dx + size, e->origin[1] - size,
			e->origin[2] }, { e->origin[0] - size, e->origin[1] - size, e->origin[2] } };

	/* Draw it twice, with and without depth check, so it will still be visible if obscured by a wall */
	R_Color(color);
	R_BindTexture(cellIndicator->texnum);

	/* circle points */
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	glDepthFunc(GL_GREATER);
	glColor4f(color[0], color[1], color[2], color[3] * 0.25f);

	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	glDepthFunc(oldDepthFunc);

	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount += 2;

	R_Color(nullptr);
}
Beispiel #19
0
static void R_DrawAliasTags (const mAliasModel_t *mod)
{
	int i;
	const uint32_t color[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000};
	glEnable(GL_LINE_SMOOTH);
	R_EnableTexture(&texunit_diffuse, false);
	R_EnableColorArray(true);

	for (i = 0; i < mod->num_tags; i++) {
		int j;
		const mAliasTag_t *tag = &mod->tags[i];
		for (j = 0; j < 3; j++) {
			vec3_t out;
			const mAliasTagOrientation_t *o = &tag->orient[mod->curFrame];
			VectorMA(o->origin, 5, o->axis[j], out);
			const vec3_t points[] = { { o->origin[0], o->origin[1], o->origin[2] }, { out[0], out[1], out[2] } };
			GLbyte colorArray[8];

			memcpy(&colorArray[0], &color[j], 4);
			memcpy(&colorArray[4], &color[j], 4);

			R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, colorArray);
			R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
			glDrawArrays(GL_LINE_STRIP, 0, 2);

			refdef.batchCount++;
		}
	}

	/* restore default array bindings */
	R_BindDefaultArray(GL_COLOR_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	R_EnableColorArray(false);
	R_EnableTexture(&texunit_diffuse, true);
	glDisable(GL_LINE_SMOOTH);
}
Beispiel #20
0
/*
 * @brief
 */
static void R_SetVertexArrayState(const r_model_t *mod, uint32_t mask) {

	// vertex array
	if (mask & R_ARRAY_VERTEX)
		R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, mod->verts);

	// normals and tangents
	if (r_state.lighting_enabled) {

		if (mask & R_ARRAY_NORMAL)
			R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, mod->normals);

		if (r_bumpmap->value) {

			if (mask & R_ARRAY_TANGENT && mod->tangents)
				R_BindArray(GL_TANGENT_ARRAY, GL_FLOAT, mod->tangents);
		}
	}

	// diffuse texcoords
	if (texunit_diffuse.enabled) {
		if (mask & R_ARRAY_TEX_DIFFUSE)
			R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->texcoords);
	}

	// lightmap coords
	if (texunit_lightmap.enabled) {

		if (mask & R_ARRAY_TEX_LIGHTMAP) {
			R_SelectTexture(&texunit_lightmap);

			R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->lightmap_texcoords);

			R_SelectTexture(&texunit_diffuse);
		}
	}
}
Beispiel #21
0
/**
 * @brief Draw the current texture on a quad the size of the renderbuffer
 */
static inline void R_DrawQuad (void)
{
	/** @todo use default_texcoords */
	const vec2_t texcoord[] = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
	const vec2_t verts[] = { { 0.0f, 0.0f }, Vector2FromInt(fbo_render->width, 0.0f), Vector2FromInt(fbo_render->width, fbo_render->height), Vector2FromInt(0.0f, fbo_render->height) };

	glVertexPointer(2, GL_FLOAT, 0, verts);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoord);

	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	refdef.batchCount++;

	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);
}
Beispiel #22
0
/**
 * @brief Draws the model bounding box
 * @sa R_EntityComputeBoundingBox
 */
void R_DrawBoundingBox (const vec3_t absmins, const vec3_t absmaxs)
{
	vec3_t bbox[8];
	const glIndex indexes[] = { 2, 1, 0, 1, 4, 5, 1, 7, 3, 2, 7, 6, 2, 4, 0 };
	const glIndex indexes2[] = { 4, 6, 7 };

	R_ComputeBoundingBox(absmins, absmaxs, bbox);

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, bbox);
	/* Draw top and sides */
	glDrawElements(GL_TRIANGLE_STRIP, 15, GLINDEX, indexes);
	/* Draw bottom */
	glDrawElements(GL_TRIANGLE_STRIP, 3, GLINDEX, indexes2);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
Beispiel #23
0
const image_t *R_DrawImageArray (const vec2_t texcoords[4], const vec2_t verts[4], const image_t *image)
{
	/* alter the array pointers */
	glVertexPointer(2, GL_FLOAT, 0, verts);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);

	if (image != NULL)
		R_BindTexture(image->texnum);

	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	refdef.batchCount++;

	/* and restore them */
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	return image;
}
Beispiel #24
0
/**
 * @brief Draw replacement model (e.g. when model wasn't found)
 * @sa R_DrawNullEntities
 */
static void R_DrawNullModel (const entity_t* e)
{
	int i;
	vec3_t points[6];

	R_EnableTexture(&texunit_diffuse, false);

	glPushMatrix();
	glMultMatrixf(e->transform.matrix);

	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);

	VectorSet(points[0], 0, 0, -16);
	for (i = 0; i <= 4; i++) {
		points[i + 1][0] = 16 * cos(i * (M_PI / 2));
		points[i + 1][1] = 16 * sin(i * (M_PI / 2));
		points[i + 1][2] = 0;
	}
	glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

	refdef.batchCount++;

	VectorSet(points[0], 0, 0, 16);
	for (i = 4; i >= 0; i--) {
		points[i + 1][0] = 16 * cos(i * (M_PI / 2));
		points[i + 1][1] = 16 * sin(i * (M_PI / 2));
		points[i + 1][2] = 0;
	}
	glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

	refdef.batchCount++;

	R_BindDefaultArray(GL_VERTEX_ARRAY);

	glPopMatrix();

	R_EnableTexture(&texunit_diffuse, true);
}
/**
 * @sa R_DrawParticles
 */
static void R_DrawPtlLine (const ptl_t * p)
{
	const vec3_t points[] = { { p->s[0], p->s[1], p->s[2] }, { p->v[0], p->v[1], p->v[2] } };

	R_EnableTexture(&texunit_diffuse, qfalse);

	glEnable(GL_LINE_SMOOTH);

	R_Color(p->color);

	/* draw line from s to v */
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
	glDrawArrays(GL_LINE_STRIP, 0, 2);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	refdef.batchCount++;

	R_Color(NULL);

	glDisable(GL_LINE_SMOOTH);

	R_EnableTexture(&texunit_diffuse, qtrue);
}
Beispiel #26
0
/**
 * @brief Draws weather effects
 */
void Weather::render (void)
{
	/* Don't play the weather particles if the user doesn't want them */
	if (!Cvar_GetInteger("cl_particleweather")) {
		return;
	}

	GLfloat prtPos[3 * 4 * Weather::MAX_PARTICLES];
	GLfloat prtTexcoord[2 * 4 * Weather::MAX_PARTICLES];
	GLushort prtIndex[3 * 2 * Weather::MAX_PARTICLES];
	size_t prtCount = 0;
	//const float splashTimeScale = 0.001f / splashTime; /* from msec to 1/sec units, so division is done only once per frame */
	/** @todo shadowcasting at least for the sunlight */
#if 0 // disabled because of bizarre colors
	vec4_t prtColor = {color[0] * (refdef.ambientColor[0] + refdef.sunDiffuseColor[0]),
		color[1] * (refdef.ambientColor[1] + refdef.sunDiffuseColor[1]),
		color[2] * (refdef.ambientColor[2] + refdef.sunDiffuseColor[2]),
		color[3]};
#else
	vec_t prtBrightness = VectorLength(refdef.ambientColor) + VectorLength(refdef.sunDiffuseColor); /** @todo proper color to brightness mapping */
	vec4_t prtColor = {color[0] * prtBrightness, color[1] * prtBrightness, color[2] * prtBrightness, color[3]}; /* alpha is not to be scaled */
#endif

	for (size_t i = 0; i < Weather::MAX_PARTICLES; i++) {
		Weather::particle &prt = particles[i];

		if (prt.ttl < 0)
			continue;

		/* if particle is alive, construct a camera-facing quad */
		GLfloat x, y, z;
		GLfloat dx, dy, dz;
		GLfloat thisParticleSize = particleSize;
		if (prt.vz == 0 && splashTime > 0) {
			/* splash particle, do zoom and other things */
			/** @todo alpha decay */
			const float splashFactor = prt.ttl / 500.0f;//1.0f - prt.ttl * splashTimeScale;
			thisParticleSize *= (splashSize - 1.0f) * splashFactor  + 1.0f;
			dx = dy = thisParticleSize;
		} else {
			dx = i & 1 ? thisParticleSize* 2 : thisParticleSize; dy = i & 1 ? thisParticleSize : thisParticleSize * 2 ; /** @todo make a proper projection instead of this hack */
		}

		x = prt.x; y = prt.y; z = prt.z;
		dz = smearLength * prt.vz * 0.5; /** @todo should use proper velocity vector ... or maybe not */
		/* construct a particle geometry; */
		GLfloat *pos = &prtPos[3 * 4 * prtCount];
		GLfloat *texcoord = &prtTexcoord[2 * 4 * prtCount];
		GLushort *idx = &prtIndex[3 * 2 * prtCount];

		/** @todo actually rotate billboard in the correct position */
		pos[0] = x - dx; pos[1] = y - dy; pos[2] = z + dz * 2;
		pos[3] = x + dx; pos[4] = y - dy; pos[5] = z + dz *2;
		pos[6] = x + dx; pos[7] = y + dy; pos[8] = z;
		pos[9] = x - dx; pos[10] = y + dy; pos[11] = z;

		texcoord[0] = 0; texcoord[1] = 0; /* upper left vertex */
		texcoord[2] = 1.0f; texcoord[3] = 0; /* upper right vertex */
		texcoord[4] = 1.0f; texcoord[5] = 1.0f; /* bottom right vertex */
		texcoord[6] = 0; texcoord[7] = 1.0f; /* bottom left vertex */

		idx[0] = 4 * prtCount; idx[1] = 4 * prtCount + 1; idx[2] = 4 * prtCount + 2;
		idx[3] = 4 * prtCount + 2; idx[4] = 4 * prtCount + 3; idx[5] = 4 * prtCount;

		prtCount++;
	}

	if (prtCount < 1)
		return;

	/* draw the generated array */
	R_Color(prtColor);
	glBindTexture(GL_TEXTURE_2D, wpTexture());
	R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, prtPos);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, prtTexcoord);
	R_EnableBlend(true);
	glDrawElements(GL_TRIANGLES, prtCount * 3 * 2, GL_UNSIGNED_SHORT, prtIndex);
	R_EnableBlend(false);
	R_ResetArrayState();
	R_Color(nullptr);

	refdef.batchCount++;
}
Beispiel #27
0
/**
 * @brief Draws shadow and highlight effects for the entities (actors)
 * @note The origins are already transformed
 */
void R_DrawEntityEffects (void)
{
	const int mask = r_stencilshadows->integer ? RF_BLOOD : (RF_SHADOW | RF_BLOOD);
	GLint oldDepthFunc;
	glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc);

	R_EnableBlend(true);

	if (actorIndicator == nullptr) {
		selectedActorIndicator = R_FindImage("pics/sfx/actor_selected", it_effect);
		actorIndicator = R_FindImage("pics/sfx/actor", it_effect);
	}

	for (int i = 0; i < refdef.numEntities; i++) {
		const entity_t* e = &r_entities[i];

		if (e->flags <= RF_BOX)
			continue;

		glPushMatrix();
		glMultMatrixf(e->transform.matrix);

		if (e->flags & mask) {
			const vec3_t points[] = { { -18.0, 14.0, -28.5 }, { 10.0, 14.0, -28.5 }, { 10.0, -14.0, -28.5 }, { -18.0,
					-14.0, -28.5 } };
			/** @todo use default_texcoords */
			const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } };

			if (e->flags & RF_SHADOW) {
				R_BindTexture(shadow->texnum);
			} else {
				assert(e->texture);
				R_BindTexture(e->texture->texnum);
			}

			R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
			R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
			glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
			R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
			R_BindDefaultArray(GL_VERTEX_ARRAY);

			refdef.batchCount++;
		}

		if (e->flags & RF_ACTOR) {
			const float size = 15.0;
			int texnum;
			/* draw the circles for team-members and allied troops */
			vec4_t color = {1, 1, 1, 1};
			const vec3_t points[] = { { -size, size, -SELECTION_DELTA }, { size, size, -SELECTION_DELTA }, { size, -size,
					-SELECTION_DELTA }, { -size, -size, -SELECTION_DELTA } };
			/** @todo use default_texcoords */
			const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } };

			if (e->flags & RF_SELECTED)
				Vector4Set(color, 0, 1, 0, 0.5);
			else if (e->flags & RF_MEMBER)
				Vector4Set(color, 0, 0.8, 0, 0.5);
			else if (e->flags & RF_ALLIED)
				Vector4Set(color, 0, 1, 0.5, 0.5);
			else if (e->flags & RF_NEUTRAL)
				Vector4Set(color, 1, 1, 0, 0.5);
			else if (e->flags & RF_OPPONENT)
				Vector4Set(color, 1, 0, 0, 0.5);
			else
				Vector4Set(color, 0.3, 0.3, 0.3, 0.5);

			if (e->flags & RF_SELECTED)
				texnum = selectedActorIndicator->texnum;
			else
				texnum = actorIndicator->texnum;

			R_BindTexture(texnum);
			R_Color(color);
			R_EnableDrawAsGlow(true);

			/* circle points */
			R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
			R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);

			glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

			refdef.batchCount++;

			/* add transparency when something is in front of the circle */
			color[3] *= 0.25;
			R_Color(color);
			glDepthFunc(GL_GREATER);
			glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
			glDepthFunc(oldDepthFunc);

			refdef.batchCount++;

			R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
			R_BindDefaultArray(GL_VERTEX_ARRAY);

			R_Color(nullptr);
			R_EnableDrawAsGlow(false);
		}
		glPopMatrix();
	}
}
Beispiel #28
0
/**
 * @brief Draw the day and night images of a flat geoscape
 * multitexture feature is used to blend the images
 * @sa R_Draw3DGlobe
 * @param[in] p The horizontal shift of the night map
 * @param[in] cx The x texture coordinate
 * @param[in] cy The y texture coordinate
 * @param[in] iz The zoomlevel of the geoscape - see ccs.zoom
 * @param[in] map The geoscape map to draw (can be changed in the campaign definition)
 * @param[in] overlayNation,overlayXVI,overlayRadar Whether these overlays should be drawn or not
 */
void R_DrawFlatGeoscape (const vec2_t nodePos, const vec2_t nodeSize, float p, float cx, float cy, float iz, const char *map, bool overlayNation, bool overlayXVI, bool overlayRadar, image_t *r_dayandnightTexture, image_t *r_xviTexture, image_t *r_radarTexture)
{
	image_t *gl;
	float geoscape_texcoords[4 * 2];
	short geoscape_verts[4 * 2];

	/* normalize */
	const float nx = nodePos[0] * viddef.rx;
	const float ny = nodePos[1] * viddef.ry;
	const float nw = nodeSize[0] * viddef.rx;
	const float nh = nodeSize[1] * viddef.ry;

	/* load day image */
	gl = R_FindImage(va("pics/geoscape/%s_day", map), it_wrappic);
	if (gl == r_noTexture)
		Com_Error(ERR_FATAL, "Could not load geoscape day image");

	/* alter the array pointers */
	glVertexPointer(2, GL_SHORT, 0, geoscape_verts);
	R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords);

	geoscape_texcoords[0] = cx - iz;
	geoscape_texcoords[1] = cy - iz;
	geoscape_texcoords[2] = cx + iz;
	geoscape_texcoords[3] = cy - iz;
	geoscape_texcoords[4] = cx + iz;
	geoscape_texcoords[5] = cy + iz;
	geoscape_texcoords[6] = cx - iz;
	geoscape_texcoords[7] = cy + iz;

	geoscape_verts[0] = nx;
	geoscape_verts[1] = ny;
	geoscape_verts[2] = nx + nw;
	geoscape_verts[3] = ny;
	geoscape_verts[4] = nx + nw;
	geoscape_verts[5] = ny + nh;
	geoscape_verts[6] = nx;
	geoscape_verts[7] = ny + nh;

	/* draw day image */
	R_BindTexture(gl->texnum);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	refdef.batchCount++;

	/* draw night map */
	gl = R_FindImage(va("pics/geoscape/%s_night", map), it_wrappic);
	/* maybe the campaign map doesn't have a night image */
	if (gl != r_noTexture) {
		float geoscape_nighttexcoords[4 * 2];

		R_BindTexture(gl->texnum);
		R_EnableTexture(&texunit_lightmap, true);
		R_SelectTexture(&texunit_lightmap);

		geoscape_nighttexcoords[0] = geoscape_texcoords[0] + p;
		geoscape_nighttexcoords[1] = geoscape_texcoords[1];
		geoscape_nighttexcoords[2] = geoscape_texcoords[2] + p;
		geoscape_nighttexcoords[3] = geoscape_texcoords[3];
		geoscape_nighttexcoords[4] = geoscape_texcoords[4] + p;
		geoscape_nighttexcoords[5] = geoscape_texcoords[5];
		geoscape_nighttexcoords[6] = geoscape_texcoords[6] + p;
		geoscape_nighttexcoords[7] = geoscape_texcoords[7];

		R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_nighttexcoords);

		R_BindTexture(r_dayandnightTexture->texnum);

		R_SelectTexture(&texunit_diffuse);
		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

		refdef.batchCount++;

		R_SelectTexture(&texunit_lightmap);
		R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords);

		R_EnableTexture(&texunit_lightmap, false);
	}

	/* draw nation overlay */
	if (overlayNation) {
		gl = R_FindImage(va("pics/geoscape/%s_nations_overlay", map), it_wrappic);
		if (gl == r_noTexture)
			Com_Error(ERR_FATAL, "Could not load geoscape nation overlay image");

		/* draw day image */
		R_BindTexture(gl->texnum);
		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

		refdef.batchCount++;
	}

	/* draw XVI image */
	if (overlayXVI) {
		gl = R_FindImage(va("pics/geoscape/%s_xvi_overlay", map), it_wrappic);
		if (gl == r_noTexture)
			Com_Error(ERR_FATAL, "Could not load xvi overlay image");

		R_BindTexture(gl->texnum);

		R_EnableTexture(&texunit_lightmap, true);
		R_BindLightmapTexture(r_xviTexture->texnum);

		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

		refdef.batchCount++;

		R_EnableTexture(&texunit_lightmap, false);
	}

	/* draw radar image */
	if (overlayRadar) {
		R_BindTexture(r_radarTexture->texnum);
		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

		refdef.batchCount++;
	}

	/* and restore them */
	R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);
}