Пример #1
0
/**
 * @brief Consume raw lightmap and deluxemap RGB/XYZ data from the surface samples,
 * writing processed lightmap and deluxemap RGB to the specified destinations.
 *
 * @param in The beginning of the surface lightmap [and deluxemap] data.
 * @param sout The destination for processed lightmap data.
 * @param dout The destination for processed deluxemap data.
 */
static void R_BuildLightmap(const r_bsp_model_t *bsp, const r_bsp_surface_t *surf, const byte *in,
                            byte *lout, byte *dout, size_t stride) {

	const uint32_t smax = surf->lightmap_size[0];
	const uint32_t tmax = surf->lightmap_size[1];

	const size_t size = smax * tmax;
	stride -= (smax * 3);

	byte *lightmap = (byte *) Mem_TagMalloc(size * 3, MEM_TAG_RENDERER);
	byte *lm = lightmap;

	byte *deluxemap = (byte *) Mem_TagMalloc(size * 3, MEM_TAG_RENDERER);
	byte *dm = deluxemap;

	// convert the raw lightmap samples to RGBA for softening
	for (size_t i = 0; i < size; i++) {
		*lm++ = *in++;
		*lm++ = *in++;
		*lm++ = *in++;

		// read in directional samples for per-pixel lighting as well
		if (bsp->version == BSP_VERSION_QUETOO) {
			*dm++ = *in++;
			*dm++ = *in++;
			*dm++ = *in++;
		} else {
			*dm++ = 127;
			*dm++ = 127;
			*dm++ = 255;
		}
	}

	// apply modulate, contrast, saturation, etc..
	R_FilterLightmap(smax, tmax, lightmap);

	// the lightmap is uploaded to the card via the strided block

	lm = lightmap;
	dm = deluxemap;

	for (uint32_t t = 0; t < tmax; t++, lout += stride, dout += stride) {
		for (uint32_t s = 0; s < smax; s++) {

			// copy the lightmap and deluxemap to the strided block
			*lout++ = *lm++;
			*lout++ = *lm++;
			*lout++ = *lm++;

			*dout++ = *dm++;
			*dout++ = *dm++;
			*dout++ = *dm++;
		}
	}

	Mem_Free(lightmap);
	Mem_Free(deluxemap);
}
Пример #2
0
/**
 * @brief
 */
static void Cm_LoadBspSurfaces(void) {

    const int32_t num_texinfo = cm_bsp.bsp.num_texinfo;
    const bsp_texinfo_t *in = cm_bsp.bsp.texinfo;

    cm_bsp_texinfo_t *out = cm_bsp.texinfos = Mem_TagMalloc(sizeof(cm_bsp_texinfo_t) * num_texinfo, MEM_TAG_CMODEL);

    for (int32_t i = 0; i < num_texinfo; i++, in++, out++) {

        g_strlcpy(out->name, in->texture, sizeof(out->name));
        out->flags = in->flags;
        out->value = in->value;

        char material_name[MAX_QPATH];
        g_snprintf(material_name, sizeof(material_name), "textures/%s", out->name);
        Cm_MaterialName(material_name, material_name, sizeof(material_name));

        for (cm_material_t *material = cm_bsp.materials; material; material = material->next) {

            if (!g_strcmp0(material->base, material_name)) {
                out->material = material;
                break;
            }
        }
    }
}
Пример #3
0
/**
 * @brief
 */
static void Cm_LoadBspBrushSides(void) {

    static cm_bsp_texinfo_t null_texinfo;

    const int32_t num_brush_sides = cm_bsp.bsp.num_brush_sides;
    const bsp_brush_side_t *in = cm_bsp.bsp.brush_sides;

    cm_bsp_brush_side_t *out = cm_bsp.brush_sides = Mem_TagMalloc(sizeof(cm_bsp_brush_side_t) * (num_brush_sides + 6), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_brush_sides; i++, in++, out++) {

        const int32_t p = in->plane_num;

        if (p >= cm_bsp.bsp.num_planes) {
            Com_Error(ERROR_DROP, "Brush side %d has invalid plane %d\n", i, p);
        }

        out->plane = &cm_bsp.planes[p];

        const int32_t s = in->surf_num;

        if (s == USHRT_MAX) {
            out->surface = &null_texinfo;
        } else {
            // NOTE: "surface" and "texinfo" are used interchangably here. yuck.
            if (s >= cm_bsp.bsp.num_texinfo) {
                Com_Error(ERROR_DROP, "Brush side %d has invalid surface %d\n", i, s);
            }

            out->surface = &cm_bsp.texinfos[s];
        }
    }
}
Пример #4
0
/*
 * @brief Returns a newly allocated s_media_t with the specified name.
 *
 * @param size_t size The number of bytes to allocate for the media.
 *
 * @return The newly initialized media.
 */
s_media_t *S_AllocMedia(const char *name, size_t size) {

	if (!name || !*name) {
		Com_Error(ERR_DROP, "NULL name\n");
	}

	s_media_t *media = Mem_TagMalloc(size, MEM_TAG_SOUND);

	g_strlcpy(media->name, name, sizeof(media->name));

	return media;
}
Пример #5
0
/**
 * @brief
 */
static cl_server_info_t *Cl_AddServer(const net_addr_t *addr) {
	cl_server_info_t *s;

	s = (cl_server_info_t *) Mem_TagMalloc(sizeof(*s), MEM_TAG_CLIENT);

	s->addr = *addr;
	g_strlcpy(s->hostname, Net_NetaddrToString(&s->addr), sizeof(s->hostname));

	cls.servers = g_list_prepend(cls.servers, s);

	return s;
}
Пример #6
0
/**
 * @brief
 */
static void Cm_LoadBspLeafBrushes(void) {

    const int32_t num_leaf_brushes = cm_bsp.bsp.num_leaf_brushes;
    const uint16_t *in = cm_bsp.bsp.leaf_brushes;

    uint16_t *out = cm_bsp.leaf_brushes = Mem_TagMalloc(sizeof(uint16_t) * (num_leaf_brushes + 1), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_leaf_brushes; i++, in++, out++) {

        *out = *in;
    }
}
Пример #7
0
/**
 * @brief
 */
winding_t *AllocWinding(int32_t points) {

	if (debug) {
		SDL_SemPost(semaphores.active_windings);
		uint32_t active_windings = SDL_SemValue(semaphores.active_windings);

		if (active_windings > c_peak_windings) {
			c_peak_windings = active_windings;
		}
	}

	return Mem_TagMalloc(sizeof(int32_t) + sizeof(vec3_t) * points, MEM_TAG_WINDING);
}
Пример #8
0
/**
 * @brief
 */
static void Cm_LoadBspBrushes(void) {

    const int32_t num_brushes = cm_bsp.bsp.num_brushes;
    const bsp_brush_t *in = cm_bsp.bsp.brushes;

    cm_bsp_brush_t *out = cm_bsp.brushes = Mem_TagMalloc(sizeof(cm_bsp_brush_t) * (num_brushes + 1), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_brushes; i++, in++, out++) {

        out->first_brush_side = in->first_brush_side;
        out->num_sides = in->num_sides;
        out->contents = in->contents;
    }
}
Пример #9
0
/**
 * @brief
 */
static void Cm_LoadBspAreas(void) {

    const int32_t num_areas = cm_bsp.bsp.num_areas;
    const bsp_area_t *in = cm_bsp.bsp.areas;

    cm_bsp_area_t *out = cm_bsp.areas = Mem_TagMalloc(sizeof(cm_bsp_area_t) * num_areas, MEM_TAG_CMODEL);

    for (int32_t i = 0; i < num_areas; i++, in++, out++) {

        out->num_area_portals = in->num_area_portals;
        out->first_area_portal = in->first_area_portal;
        out->flood_valid = 0;
        out->flood_num = 0;
    }
}
Пример #10
0
/**
 * @brief
 */
static void Cm_LoadBspNodes(void) {

    const int32_t num_nodes = cm_bsp.bsp.num_nodes;
    const bsp_node_t *in = cm_bsp.bsp.nodes;

    cm_bsp_node_t *out = cm_bsp.nodes = Mem_TagMalloc(sizeof(cm_bsp_node_t) * (num_nodes + 6), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_nodes; i++, in++, out++) {

        out->plane = cm_bsp.planes + in->plane_num;

        for (int32_t j = 0; j < 2; j++) {
            out->children[j] = in->children[j];
        }
    }
}
Пример #11
0
/**
 * @brief
 */
static void Cm_LoadBspInlineModels(void) {

    const int32_t num_models = cm_bsp.bsp.num_models;
    const bsp_model_t *in = cm_bsp.bsp.models;

    cm_bsp_model_t *out = cm_bsp.models = Mem_TagMalloc(sizeof(cm_bsp_model_t) * num_models, MEM_TAG_CMODEL);

    for (int32_t i = 0; i < num_models; i++, in++, out++) {

        for (int32_t j = 0; j < 3; j++) {
            out->mins[j] = in->mins[j] - 1.0;
            out->maxs[j] = in->maxs[j] + 1.0;
            out->origin[j] = in->origin[j];
        }

        out->head_node = in->head_node;
    }
}
Пример #12
0
/**
 * @brief
 */
static void Cm_LoadBspPlanes(void) {

    const int32_t num_planes = cm_bsp.bsp.num_planes;
    const bsp_plane_t *in = cm_bsp.bsp.planes;

    cm_bsp_plane_t *out = cm_bsp.planes = Mem_TagMalloc(sizeof(cm_bsp_plane_t) * (num_planes + 12), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_planes; i++, in++, out++) {

        // copied from bsp_
        VectorCopy(in->normal, out->normal);
        out->dist = in->dist;
        out->type = in->type;

        // local to cm_
        out->sign_bits = Cm_SignBitsForPlane(out);
        out->num = (i >> 1) + 1;
    }
}
Пример #13
0
/**
 * @brief
 */
static void Cm_LoadBspLeafs(void) {

    const int32_t num_leafs = cm_bsp.bsp.num_leafs;
    const bsp_leaf_t *in = cm_bsp.bsp.leafs;

    cm_bsp_leaf_t *out = cm_bsp.leafs = Mem_TagMalloc(sizeof(cm_bsp_leaf_t) * (num_leafs + 1), MEM_TAG_CMODEL); // extra for box hull

    for (int32_t i = 0; i < num_leafs; i++, in++, out++) {

        out->contents = in->contents;
        out->cluster = in->cluster;
        out->area = in->area;
        out->first_leaf_brush = in->first_leaf_brush;
        out->num_leaf_brushes = in->num_leaf_brushes;
    }

    if (cm_bsp.leafs[0].contents != CONTENTS_SOLID) {
        Com_Error(ERROR_DROP, "Map leaf 0 is not CONTENTS_SOLID\n");
    }
}
Пример #14
0
/**
 * @brief
 */
void R_InitProgram_default(r_program_t *program) {

	r_default_program_t *p = &r_default_program;

	p->program = program;

	R_ProgramVariable(&program->attributes[R_ARRAY_POSITION], R_ATTRIBUTE, "POSITION", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_COLOR], R_ATTRIBUTE, "COLOR", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_DIFFUSE], R_ATTRIBUTE, "TEXCOORD0", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_LIGHTMAP], R_ATTRIBUTE, "TEXCOORD1", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_NORMAL], R_ATTRIBUTE, "NORMAL", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_TANGENT], R_ATTRIBUTE, "TANGENT", true);

	R_ProgramVariable(&program->attributes[R_ARRAY_NEXT_POSITION], R_ATTRIBUTE, "NEXT_POSITION", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_NEXT_NORMAL], R_ATTRIBUTE, "NEXT_NORMAL", true);
	R_ProgramVariable(&program->attributes[R_ARRAY_NEXT_TANGENT], R_ATTRIBUTE, "NEXT_TANGENT", true);

	R_ProgramVariable(&p->diffuse, R_UNIFORM_INT, "DIFFUSE", true);
	R_ProgramVariable(&p->lightmap, R_UNIFORM_INT, "LIGHTMAP", true);
	R_ProgramVariable(&p->normalmap, R_UNIFORM_INT, "NORMALMAP", true);
	R_ProgramVariable(&p->glossmap, R_UNIFORM_INT, "GLOSSMAP", true);

	R_ProgramVariable(&p->bump, R_UNIFORM_FLOAT, "BUMP", true);
	R_ProgramVariable(&p->parallax, R_UNIFORM_FLOAT, "PARALLAX", true);
	R_ProgramVariable(&p->hardness, R_UNIFORM_FLOAT, "HARDNESS", true);
	R_ProgramVariable(&p->specular, R_UNIFORM_FLOAT, "SPECULAR", true);

	R_ProgramVariable(&p->sampler0, R_SAMPLER_2D, "SAMPLER0", true);
	R_ProgramVariable(&p->sampler1, R_SAMPLER_2D, "SAMPLER1", true);
	R_ProgramVariable(&p->sampler2, R_SAMPLER_2D, "SAMPLER2", true);
	R_ProgramVariable(&p->sampler3, R_SAMPLER_2D, "SAMPLER3", true);
	R_ProgramVariable(&p->sampler4, R_SAMPLER_2D, "SAMPLER4", true);

	R_ProgramVariable(&p->fog.start, R_UNIFORM_FLOAT, "FOG.START", true);
	R_ProgramVariable(&p->fog.end, R_UNIFORM_FLOAT, "FOG.END", true);
	R_ProgramVariable(&p->fog.color, R_UNIFORM_VEC3, "FOG.COLOR", true);
	R_ProgramVariable(&p->fog.density, R_UNIFORM_FLOAT, "FOG.DENSITY", true);

	if (r_state.max_active_lights) {
		p->lights = Mem_TagMalloc(sizeof(r_uniform_light_t) * r_state.max_active_lights, MEM_TAG_RENDERER);

		for (int32_t i = 0; i < r_state.max_active_lights; ++i) {
			R_ProgramVariable(&p->lights[i].origin, R_UNIFORM_VEC3, va("LIGHTS.ORIGIN[%i]", i), true);
			R_ProgramVariable(&p->lights[i].color, R_UNIFORM_VEC3, va("LIGHTS.COLOR[%i]", i), true);
			R_ProgramVariable(&p->lights[i].radius, R_UNIFORM_FLOAT, va("LIGHTS.RADIUS[%i]", i), true);
		}

		R_ProgramParameter1f(&p->lights[0].radius, 0.0);
	} else {
		p->lights = NULL;
	}

	R_ProgramVariable(&p->caustic.enable, R_UNIFORM_INT, "CAUSTIC.ENABLE", true);
	R_ProgramVariable(&p->caustic.color, R_UNIFORM_VEC3, "CAUSTIC.COLOR", true);

	R_ProgramVariable(&p->normal_mat, R_UNIFORM_MAT4, "NORMAL_MAT", true);

	R_ProgramVariable(&p->alpha_threshold, R_UNIFORM_FLOAT, "ALPHA_THRESHOLD", true);

	R_ProgramVariable(&p->time_fraction, R_UNIFORM_FLOAT, "TIME_FRACTION", true);
	R_ProgramVariable(&p->time, R_UNIFORM_FLOAT, "TIME", true);

	R_ProgramParameter1i(&p->lightmap, 0);
	R_ProgramParameter1i(&p->normalmap, 0);
	R_ProgramParameter1i(&p->glossmap, 0);

	R_ProgramParameter1f(&p->bump, 1.0);
	R_ProgramParameter1f(&p->parallax, 1.0);
	R_ProgramParameter1f(&p->hardness, 1.0);
	R_ProgramParameter1f(&p->specular, 1.0);

	R_ProgramParameter1i(&p->sampler0, R_TEXUNIT_DIFFUSE);
	R_ProgramParameter1i(&p->sampler1, R_TEXUNIT_LIGHTMAP);
	R_ProgramParameter1i(&p->sampler2, R_TEXUNIT_DELUXEMAP);
	R_ProgramParameter1i(&p->sampler3, R_TEXUNIT_NORMALMAP);
	R_ProgramParameter1i(&p->sampler4, R_TEXUNIT_SPECULARMAP);

	R_ProgramParameter1f(&p->fog.density, 0.0);
	R_ProgramParameter1f(&p->alpha_threshold, ALPHA_TEST_DISABLED_THRESHOLD);

	R_ProgramParameter1i(&p->caustic.enable, 0);

	R_ProgramParameter1f(&p->time_fraction, 0.0f);
	R_ProgramParameter1f(&p->time, 0.0f);
}
Пример #15
0
/**
 * @brief If the variable already exists, the value will not be modified. The
 * default value, flags, and description will, however, be updated. This way,
 * variables set at the command line can receive their meta data through the
 * various subsystem initialization routines.
 */
cvar_t *Cvar_Add(const char *name, const char *value, uint32_t flags, const char *description) {

	assert(name);
	assert(value);

	if (flags & (CVAR_USER_INFO | CVAR_SERVER_INFO)) {
		if (!Cvar_InfoValidate(name)) {
			Com_Print("Invalid variable name: %s\n", name);
			return NULL;
		}
		if (!Cvar_InfoValidate(value)) {
			Com_Print("Invalid variable value: %s\n", value);
			return NULL;
		}
	}

	// update existing variables with meta data from owning subsystem
	cvar_t *var = Cvar_Get(name);
	if (var) {
		if (value) {
			if (var->default_string) {
				Mem_Free((void *) var->default_string);
			}
			var->default_string = Mem_Link(Mem_TagCopyString(value, MEM_TAG_CVAR), var);
		}
		var->flags |= flags;
		if (description) {
			if (var->description) {
				Mem_Free((void *) var->description);
			}
			var->description = Mem_Link(Mem_TagCopyString(description, MEM_TAG_CVAR), var);
		}
		return var;
	}

	// create a new variable
	var = Mem_TagMalloc(sizeof(*var), MEM_TAG_CVAR);
	assert(var);
	
	var->name = Mem_Link(Mem_TagCopyString(name, MEM_TAG_CVAR), var);
	var->default_string = Mem_Link(Mem_TagCopyString(value, MEM_TAG_CVAR), var);
	var->string = Mem_Link(Mem_TagCopyString(value, MEM_TAG_CVAR), var);
	var->value = strtof(var->string, NULL);
	var->integer = (int32_t) strtol(var->string, NULL, 0);
	var->modified = true;
	var->flags = flags;

	if (description) {
		var->description = Mem_Link(Mem_TagCopyString(description, MEM_TAG_CVAR), var);
	}

	gpointer key = (gpointer) var->name;
	GQueue *queue = (GQueue *) g_hash_table_lookup(cvar_vars, key);

	if (!queue) {
		queue = g_queue_new();
		g_hash_table_insert(cvar_vars, key, queue);
	}

	g_queue_push_head(queue, var);
	return var;
}
Пример #16
0
/**
 * @brief
 */
static void Cm_LoadBspAreaPortals(void) {

    const int32_t num_area_portals = cm_bsp.bsp.num_area_portals;

    cm_bsp.portal_open = Mem_TagMalloc(sizeof(bool) * num_area_portals, MEM_TAG_CMODEL);
}