Example #1
0
/*
 * R_DrawSurfacesLines_default
 */
static void R_DrawSurfacesLines_default(const r_bsp_surfaces_t *surfs) {
	unsigned int i;

	R_EnableTexture(&texunit_diffuse, false);

	R_EnableColorArray(true);

	R_SetArrayState(r_world_model);

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	for (i = 0; i < surfs->count; i++) {

		if (surfs->surfaces[i]->frame != r_locals.frame)
			continue;

		R_DrawSurface_default(surfs->surfaces[i]);
	}

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_diffuse, true);
}
Example #2
0
/**
 * @brief Manages state for stages supporting static, dynamic, and per-pixel lighting.
 */
static void R_StageLighting (const mBspSurface_t *surf, const materialStage_t *stage)
{
	/* if the surface has a lightmap, and the stage specifies lighting.. */
	if ((surf->flags & MSURF_LIGHTMAP) &&
			(stage->flags & (STAGE_LIGHTMAP | STAGE_LIGHTING))) {
		R_EnableTexture(&texunit_lightmap, true);
		R_BindLightmapTexture(surf->lightmap_texnum);

		/* hardware lighting */
		/** @todo fix it and enable it back for r_materials 1 */
		if (r_materials->integer > 1) {
			if ((stage->flags & STAGE_LIGHTING)) {
				R_EnableLighting(r_state.world_program, true);
				R_SetSurfaceBumpMappingParameters(surf, stage->image->normalmap, stage->image->specularmap);
			} else {
				R_SetSurfaceBumpMappingParameters(surf, nullptr, nullptr);
				R_EnableLighting(nullptr, false);
			}
		}
	} else {
		if (!r_state.lighting_enabled)
			return;
		R_EnableLighting(nullptr, false);

		R_EnableTexture(&texunit_lightmap, false);
	}
}
Example #3
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;
}
Example #4
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);
}
Example #5
0
/**
 * @brief Developer tool for viewing BSP vertex normals. Only Phong interpolated
 * surfaces show their normals when r_shownormals > 1.
 */
void R_DrawBspNormals (int tile)
{
	int i, j, k;
	const mBspSurface_t* surf;
	const mBspModel_t* bsp;
	const vec4_t color = {1.0, 0.0, 0.0, 1.0};

	if (!r_shownormals->integer)
		return;

	R_EnableTexture(&texunit_diffuse, false);

	R_ResetArrayState();  /* default arrays */

	R_Color(color);

	k = 0;
	bsp = &r_mapTiles[tile]->bsp;
	surf = bsp->surfaces;
	for (i = 0; i < bsp->numsurfaces; i++, surf++) {
		if (surf->frame != r_locals.frame)
			continue; /* not visible */

		if (surf->texinfo->flags & SURF_WARP)
			continue;  /* don't care */

		if (r_shownormals->integer > 1 && !(surf->texinfo->flags & SURF_PHONG))
			continue;  /* don't care */

		/* avoid overflows, draw in batches */
		if (k > r_state.array_size - 512) {
			glDrawArrays(GL_LINES, 0, k / 3);
			k = 0;

			refdef.batchCount++;
		}

		for (j = 0; j < surf->numedges; j++) {
			vec3_t end;
			const GLfloat* vertex = &bsp->verts[(surf->index + j) * 3];
			const GLfloat* normal = &bsp->normals[(surf->index + j) * 3];

			VectorMA(vertex, 12.0, normal, end);

			memcpy(&r_state.vertex_array_3d[k], vertex, sizeof(vec3_t));
			memcpy(&r_state.vertex_array_3d[k + 3], end, sizeof(vec3_t));
			k += sizeof(vec3_t) / sizeof(vec_t) * 2;
			R_ReallocateStateArrays(k);
		}
	}

	glDrawArrays(GL_LINES, 0, k / 3);

	refdef.batchCount++;

	R_EnableTexture(&texunit_diffuse, true);

	R_Color(nullptr);
}
Example #6
0
/*
 * @brief
 */
void R_DrawCoronas(void) {

	if (!r_coronas->value)
		return;

	if (!r_view.num_coronas)
		return;

	R_EnableTexture(&texunit_diffuse, false);

	R_EnableColorArray(true);

	R_ResetArrayState();

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE);

	for (uint16_t i = 0; i < r_view.num_coronas; i++) {

		const r_corona_t *c = &r_view.coronas[i];
		const vec_t f = c->radius * c->flicker * sin(0.09 * r_view.time);

		// use at least 12 verts, more for larger coronas
		const uint16_t num_verts = Clamp(c->radius / 8.0, 12, 64);

		memcpy(&r_state.color_array[0], c->color, sizeof(vec3_t));
		r_state.color_array[3] = r_coronas->value; // set origin color

		// and the corner colors
		memset(&r_state.color_array[4], 0, num_verts * 2 * sizeof(vec4_t));

		memcpy(&r_state.vertex_array_3d[0], c->origin, sizeof(vec3_t));
		uint32_t vert_index = 3; // and the origin

		for (uint16_t j = 0; j <= num_verts; j++) { // now draw the corners
			const vec_t a = j / (vec_t) num_verts * M_PI * 2;

			vec3_t v;
			VectorCopy(c->origin, v);

			VectorMA(v, cos(a) * (c->radius + f), r_view.right, v);
			VectorMA(v, sin(a) * (c->radius + f), r_view.up, v);

			memcpy(&r_state.vertex_array_3d[vert_index], v, sizeof(vec3_t));
			vert_index += 3;
		}

		glDrawArrays(GL_TRIANGLE_FAN, 0, vert_index / 3);
	}

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_diffuse, true);

	R_Color(NULL);
}
Example #7
0
/**
 * @brief Draw all translucent bsp surfaces with multitexture enabled and blend enabled
 */
void R_RenderBlendBspRRefs (void)
{
	assert(r_state.blend_enabled);
	R_EnableTexture(&texunit_lightmap, true);

	R_RenderBspRRefs(R_DrawSurfaces, S_BLEND);

	R_EnableTexture(&texunit_lightmap, false);
}
Example #8
0
/**
 * @brief Draws a circle out of lines
 * @param[in] p The particle definition with origin, radius and color
 * @sa Draw_Circle
 */
static void R_DrawPtlCircle (const ptl_t* p)
{
	const float radius = p->size[0];
	const float thickness = p->size[1];

	R_EnableTexture(&texunit_diffuse, qfalse);

	R_DrawCircle(radius, p->color, thickness, p->s);

	R_EnableTexture(&texunit_diffuse, qtrue);
}
Example #9
0
/**
 * @brief Draw all simple opaque bsp surfaces with multitexture enabled and light enabled
 */
void R_RenderOpaqueBspRRefs (void)
{
	R_EnableTexture(&texunit_lightmap, true);
	R_EnableLighting(r_state.world_program, true);
	R_EnableWorldLights();

	R_RenderBspRRefs(R_DrawSurfaces, S_OPAQUE);

	R_EnableLighting(nullptr, false);
	R_EnableGlowMap(nullptr);
	R_EnableTexture(&texunit_lightmap, false);
}
Example #10
0
/**
 * @brief Re-draws the mesh using the stencil test.  Meshes with stale lighting
 * information, or with a lighting point above our view, are not drawn.
 */
static void R_DrawMeshShadow (entity_t *e, const mAliasMesh_t *mesh)
{
	vec4_t color;
	const bool oldBlend = r_state.blend_enabled;
	const bool lighting = r_state.lighting_enabled;
	r_program_t *program = r_state.active_program;

	if (!r_stencilshadows->integer)
		return;

	if (!r_shadows->value)
		return;

	if (r_wire->integer)
		return;

	if (e->flags & RF_NO_SHADOW)
		return;

	if (e->flags & RF_TRANSLUCENT)
		return;

	if (!R_UpdateShadowOrigin(e))
		return;

	if (e->lighting->shadowOrigin[2] > refdef.viewOrigin[2])
		return;

	Vector4Set(color, 0.0, 0.0, 0.0, r_shadows->value * MESH_SHADOW_ALPHA);
	R_Color(color);
	R_EnableTexture(&texunit_diffuse, false);
	R_EnableBlend(true);
	R_RotateForMeshShadow(e);
	R_EnableStencilTest(true);

	if (lighting)
		R_EnableLighting(NULL, false);
	glDrawArrays(GL_TRIANGLES, 0, mesh->num_tris * 3);
	refdef.batchCount++;
	if (lighting)
		R_EnableLighting(program, true);

	R_EnableStencilTest(false);
	R_RotateForMeshShadow(NULL);
	R_EnableBlend(oldBlend);
	R_EnableTexture(&texunit_diffuse, true);
	R_Color(NULL);
}
Example #11
0
/*
 * R_SetDEfaultState
 *
 * Sets OpenGL state parameters to appropiate defaults.
 */
void R_SetDefaultState(void) {
	int i;
	r_texunit_t *tex;

	// setup vertex array pointers
	glEnableClientState(GL_VERTEX_ARRAY);
	R_BindDefaultArray(GL_VERTEX_ARRAY);

	R_EnableColorArray(true);
	R_BindDefaultArray(GL_COLOR_ARRAY);
	R_EnableColorArray(false);

	glEnableClientState(GL_NORMAL_ARRAY);
	R_BindDefaultArray(GL_NORMAL_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

	// setup texture units
	for (i = 0; i < r_config.max_texunits && i < MAX_GL_TEXUNITS; i++) {

		tex = &r_state.texunits[i];
		tex->texture = GL_TEXTURE0_ARB + i;

		R_EnableTexture(tex, true);

		R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);

		if (i > 0) // turn them off for now
			R_EnableTexture(tex, false);
	}

	R_SelectTexture(&texunit_diffuse);

	// alpha test parameters
	glAlphaFunc(GL_GREATER, 0.25);

	// stencil test parameters
	glStencilFunc(GL_GEQUAL, 1, 0xff);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

	// fog parameters
	glFogi(GL_FOG_MODE, GL_LINEAR);
	glFogf(GL_FOG_DENSITY, 0.0);
	glFogf(GL_FOG_START, FOG_START);
	glFogf(GL_FOG_END, FOG_END);

	// alpha blend parameters
	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
Example #12
0
/*
 * R_DrawBlendSurfaces_default
 */
void R_DrawBlendSurfaces_default(const r_bsp_surfaces_t *surfs) {

	if (!surfs->count)
		return;

	if (r_draw_wireframe->value) { // surface outlines
		R_DrawSurfacesLines_default(surfs);
		return;
	}

	// blend is already enabled when this is called

	R_EnableTexture(&texunit_lightmap, true);

	R_DrawSurfaces_default(surfs);

	R_EnableTexture(&texunit_lightmap, false);
}
Example #13
0
/*
 * R_DrawOpaqueSurfaces_default
 */
void R_DrawOpaqueSurfaces_default(const r_bsp_surfaces_t *surfs) {

	if (!surfs->count)
		return;

	if (r_draw_wireframe->value) { // surface outlines
		R_DrawSurfacesLines_default(surfs);
		return;
	}

	R_EnableTexture(&texunit_lightmap, true);

	R_EnableLighting(r_state.world_program, true);

	R_DrawSurfaces_default(surfs);

	R_EnableLighting(NULL, false);

	R_EnableTexture(&texunit_lightmap, false);
}
Example #14
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);
}
Example #15
0
/**
 * @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);
}
Example #16
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);
}
Example #17
0
/**
 * @brief Gives handle to (and uploads if needed) weather particle texture; also binds it to the active texture unit
 * @return OpenGL handle of texture object
 * @note alas, image_t does not support anything but RGB(A) textures, so we've got to reinvent the wheel
 */
static GLuint wpTexture (void)
{
	static GLuint wpTextureHandle = 0;

	if (wpTextureHandle)
		return wpTextureHandle;

	R_EnableTexture(&texunit_diffuse, true);
	glGenTextures(1, &wpTextureHandle);
	glBindTexture(GL_TEXTURE_2D, wpTextureHandle);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 8, 8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, wpImage);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

	return wpTextureHandle;
}
Example #18
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);
}
Example #19
0
void R_DrawCoronas (void)
{
	int i, j, k;
	vec3_t v;

	if (!r_coronas->integer)
		return;

	if (!refdef.numCoronas)
		return;

	R_EnableTexture(&texunit_diffuse, false);

	R_EnableColorArray(true);

	R_ResetArrayState();

	R_BlendFunc(GL_ONE, GL_ONE);

	for (k = 0; k < refdef.numCoronas; k++) {
		const corona_t *c = &refdef.coronas[k];
		int verts, vertind;

		if (!c->radius)
			continue;

		/* use at least 12 verts, more for larger coronas */
		verts = 12 + c->radius / 8;

		memcpy(&r_state.color_array[0], c->color, sizeof(vec3_t));
		r_state.color_array[3] = 1.0f; /* set origin color */

		/* and the corner colors */
		memset(&r_state.color_array[4], 0, verts * 2 * sizeof(vec4_t));

		memcpy(&r_state.vertex_array_3d[0], c->org, sizeof(vec3_t));
		vertind = 3; /* and the origin */

		for (i = verts; i >= 0; i--) { /* now draw the corners */
			const float a = (M_PI * 2 / verts) * i;

			for (j = 0; j < 3; j++)
				v[j] = c->org[j] + r_locals.right[j] * (float) cos(a) * c->radius + r_locals.up[j] * (float) sin(a)
						* c->radius;

			memcpy(&r_state.vertex_array_3d[vertind], v, sizeof(vec3_t));
			vertind += 3;
		}

		glDrawArrays(GL_TRIANGLE_FAN, 0, vertind / 3);

		refdef.batchCount++;
	}

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_diffuse, true);

	R_Color(nullptr);
}
Example #20
0
/**
 * @brief Iterates the specified surfaces list, updating materials as they are
 * encountered, and rendering all visible stages. State is lazily managed
 * throughout the iteration, so there is a concerted effort to restore the
 * state after all surface stages have been rendered.
 */
void R_DrawMaterialSurfaces (const mBspSurfaces_t *surfs, GLushort *indexPtr)
{
	int i;

	if (!r_materials->integer || r_wire->integer)
		return;

	if (!surfs->count)
		return;

	assert(r_state.blend_enabled);

	/** @todo - integrate BSP lighting with model lighting */
	R_EnableModelLights(nullptr, 0, false, false);

	R_EnableColorArray(true);

	R_ResetArrayState();

	R_EnableColorArray(false);

	R_EnableLighting(nullptr, false);

	R_EnableTexture(&texunit_lightmap, false);

#ifndef GL_VERSION_ES_CM_1_0
	glEnable(GL_POLYGON_OFFSET_FILL);
#endif
	glPolygonOffset(-1.f, -1.f);

	glMatrixMode(GL_TEXTURE);  /* some stages will manipulate texcoords */

	for (i = 0; i < surfs->count; i++) {
		materialStage_t *s;
		mBspSurface_t *surf = surfs->surfaces[i];
		material_t *m = &surf->texinfo->image->material;
		int j = -1;

		if (surf->frame != r_locals.frame)
			continue;

		R_UpdateMaterial(m);

		for (s = m->stages; s; s = s->next, j--) {
			if (!(s->flags & STAGE_RENDER))
				continue;

			R_SetSurfaceStageState(surf, s);

			R_DrawSurfaceStage(surf, s);
		}
	}

	R_Color(nullptr);

	/* polygon offset parameters */
	glPolygonOffset(0.0, 0.0);
#ifndef GL_VERSION_ES_CM_1_0
	glDisable(GL_POLYGON_OFFSET_FILL);
#endif

	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_EnableFog(true);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_lightmap, false);

	R_EnableBumpmap(nullptr);

	R_EnableLighting(nullptr, false);

	R_EnableGlowMap(nullptr);

	R_Color(nullptr);
}