Exemple #1
0
/**
 * @brief Resets the stainmaps that we have loaded, for level changes. This is kind of a
 * slow function, so be careful calling this one.
 */
void R_ResetStainmap(void) {

    GHashTable *hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, Mem_Free);

    for (uint32_t s = 0; s < r_model_state.world->bsp->num_surfaces; s++) {
        r_bsp_surface_t *surf = r_model_state.world->bsp->surfaces + s;

        // skip if we don't have a stainmap or we weren't stained
        if (!surf->stainmap || !surf->stainmap_dirty) {
            continue;
        }

        byte *lightmap = (byte *) g_hash_table_lookup(hash, surf->stainmap);
        if (!lightmap) {

            lightmap = Mem_Malloc(surf->lightmap->width * surf->lightmap->height * 3);

            R_BindDiffuseTexture(surf->lightmap->texnum);
            glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap);

            R_BindDiffuseTexture(surf->stainmap->texnum);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surf->lightmap->width, surf->lightmap->height,
                         0, GL_RGB, GL_UNSIGNED_BYTE, lightmap);

            g_hash_table_insert(hash, surf->stainmap, lightmap);
        }

        const size_t offset = (surf->lightmap_t * surf->lightmap->width + surf->lightmap_s) * 3;
        const size_t stride = surf->lightmap->width * 3;

        byte *lm = lightmap + offset;
        byte *sm = surf->stainmap_buffer;

        for (int16_t t = 0; t < surf->lightmap_size[1]; t++) {

            memcpy(sm, lm, surf->lightmap_size[0] * 3);

            sm += surf->lightmap_size[0] * 3;
            lm += stride;
        }

        surf->stainmap_dirty = false;
    }

    g_hash_table_destroy(hash);
}
Exemple #2
0
/**
 * @brief Draws a place-holder "white diamond" prism for the specified entity.
 */
static void R_DrawNullModel(const r_entity_t *e) {

	R_BindDiffuseTexture(r_image_state.null->texnum);

	R_RotateForEntity(e);

	R_DrawArrays(GL_TRIANGLES, 0, (GLsizei) r_model_state.null_elements_count);

	R_RotateForEntity(NULL);
}
Exemple #3
0
/**
 * @brief
 */
static void R_AddStains_UploadSurfaces(gpointer key, gpointer value, gpointer userdata) {

    r_bsp_surface_t *surf = (r_bsp_surface_t *) value;

    R_BindDiffuseTexture(surf->stainmap->texnum);
    glTexSubImage2D(GL_TEXTURE_2D, 0,
                    surf->lightmap_s, surf->lightmap_t,
                    surf->lightmap_size[0], surf->lightmap_size[1],
                    GL_RGB,
                    GL_UNSIGNED_BYTE, surf->stainmap_buffer);

    R_GetError(surf->texinfo->name);

    // mark the surface as having been modified, so reset knows it's resettable
    surf->stainmap_dirty = true;
}
Exemple #4
0
/**
 * @brief Draws bounding boxes for all non-linked entities in `ents`.
 */
static void R_DrawEntityBounds(const r_entities_t *ents, const vec4_t color) {

	if (!r_draw_entity_bounds->value) {
		return;
	}

	if (ents->count == 0) {
		return;
	}

	R_BindDiffuseTexture(r_image_state.null->texnum);

	R_EnableColorArray(true);

	R_BindAttributeInterleaveBuffer(&r_model_state.bound_vertice_buffer, R_ARRAY_MASK_ALL);
	R_BindAttributeBuffer(R_ARRAY_ELEMENTS, &r_model_state.bound_element_buffer);

	u8vec4_t bc;
	ColorDecompose(color, bc);

	for (int32_t i = 0; i < 8; ++i) {
		Vector4Set(r_model_state.bound_vertices[i].color, bc[0], bc[1], bc[2], bc[3]);
	}

	static matrix4x4_t mat, modelview;

	R_GetMatrix(R_MATRIX_MODELVIEW, &modelview);

	for (size_t i = 0; i < ents->count; i++) {
		const r_entity_t *e = ents->entities[i];

		if (e->parent || (e->effects & EF_WEAPON) || !IS_MESH_MODEL(e->model)) {
			continue;
		}

		VectorSet(r_model_state.bound_vertices[0].position, e->mins[0], e->mins[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[1].position, e->maxs[0], e->mins[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[2].position, e->maxs[0], e->maxs[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[3].position, e->mins[0], e->maxs[1], e->mins[2]);

		VectorSet(r_model_state.bound_vertices[4].position, e->mins[0], e->mins[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[5].position, e->maxs[0], e->mins[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[6].position, e->maxs[0], e->maxs[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[7].position, e->mins[0], e->maxs[1], e->maxs[2]);

		R_UploadToBuffer(&r_model_state.bound_vertice_buffer, sizeof(r_bound_interleave_vertex_t) * 8,
		                 r_model_state.bound_vertices);

		// draw box
		const vec_t *origin;

		if (e->effects & EF_BOB) {
			origin = e->termination;
		} else {
			origin = e->origin;
		}

		Matrix4x4_CreateFromEntity(&mat, origin, vec3_origin, e->scale);

		Matrix4x4_Concat(&mat, &modelview, &mat);

		R_SetMatrix(R_MATRIX_MODELVIEW, &mat);

		R_DrawArrays(GL_LINES, 0, (GLint) r_model_state.bound_element_count - 6);

		// draw origin
		Matrix4x4_CreateFromEntity(&mat, origin, e->angles, e->scale);

		Matrix4x4_Concat(&mat, &modelview, &mat);

		R_SetMatrix(R_MATRIX_MODELVIEW, &mat);

		R_DrawArrays(GL_LINES, (GLint) r_model_state.bound_element_count - 6, 6);
	}

	R_SetMatrix(R_MATRIX_MODELVIEW, &modelview);

	R_UnbindAttributeBuffer(R_ARRAY_ELEMENTS);

	R_EnableColorArray(false);

	R_Color(NULL);
}