コード例 #1
0
ファイル: r_array.c プロジェクト: jdolan/quetoo
/**
 * @brief Upload data to a sub-position in already-created buffer. You could also use this function to
 * resize an existing buffer without uploading data, although it won't make the
 * buffer smaller.
 * @param data_offset Whether the data pointer should be offset by start or not.
 */
void R_UploadToSubBuffer(r_buffer_t *buffer, const size_t start, const size_t size, const void *data,
                         const _Bool data_offset) {

	assert(buffer->bufnum != 0);

	// Check size. This is benign really, but it's usually a bug.
	if (!size) {
		Com_Warn("Attempted to upload 0 bytes to GPU\n");
		return;
	}

	// Don't allow null ptrs since bufferSubData does not allow it.
	if (!data) {
		Com_Error(ERROR_DROP, "Fatal: attempted to upload null to GPU. bufferSubData does not allow this.\n");
	}

	// offset ptr if requested
	if (start && data && data_offset) {
		data += start;
	}

	R_BindBuffer(buffer);

	// if the buffer isn't big enough to hold what we had already,
	// we have to resize the buffer
	const size_t total_size = start + size;

	if (total_size > buffer->size) {
		// if we passed a "start", the data is offset, so
		// just reset to null. This is an odd edge case and
		// it's fairly rare you'll be editing at the end first,
		// but who knows.
		if (start) {

			glBufferData(buffer->target, total_size, NULL, buffer->hint);
			R_GetError("Partial resize");
			r_view.buffer_stats[buffer->type].num_full_uploads++;
			glBufferSubData(buffer->target, start, size, data);
			R_GetError("Partial update");
			r_view.buffer_stats[buffer->type].num_partial_uploads++;
		} else {
			glBufferData(buffer->target, total_size, data, buffer->hint);
			R_GetError("Full resize");
			r_view.buffer_stats[buffer->type].num_full_uploads++;
		}

		r_state.buffers_total_bytes -= buffer->size;
		r_state.buffers_total_bytes += total_size;

		buffer->size = total_size;
	} else {
		// just update the range we specified
		glBufferSubData(buffer->target, start, size, data);
		R_GetError("Updating existing buffer");
		r_view.buffer_stats[buffer->type].num_partial_uploads++;
	}

	r_view.buffer_stats[buffer->type].size_uploaded += size;
}
コード例 #2
0
ファイル: r_array.c プロジェクト: devilx4/quake2world
/*
 * @brief
 */
static void R_SetVertexBufferState(const r_model_t *mod, uint32_t mask) {

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

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

		if (mask & R_ARRAY_NORMAL)
			R_BindBuffer(GL_NORMAL_ARRAY, GL_FLOAT, mod->normal_buffer);

		if (r_bumpmap->value) {

			if ((mask & R_ARRAY_TANGENT) && mod->tangent_buffer)
				R_BindBuffer(GL_TANGENT_ARRAY, GL_FLOAT, mod->tangent_buffer);
		}
	}

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

	// lightmap texcoords
	if (texunit_lightmap.enabled) {

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

			R_BindBuffer(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->lightmap_texcoord_buffer);

			R_SelectTexture(&texunit_diffuse);
		}
	}
}
コード例 #3
0
ファイル: r_array.c プロジェクト: jdolan/quetoo
/**
 * @brief Upload data to an already-created buffer. You could also use this function to
 * resize an existing buffer without uploading data, although it won't make the
 * buffer smaller.
 */
void R_UploadToBuffer(r_buffer_t *buffer, const size_t size, const void *data) {

	assert(buffer->bufnum != 0);

	// Check size. This is benign really, but it's usually a bug.
	if (!size) {
		Com_Warn("Attempted to upload 0 bytes to GPU");
		return;
	}

	R_BindBuffer(buffer);

	// if the buffer isn't big enough to hold what we had already,
	// we have to resize the buffer

	if (size > buffer->size) {
		r_state.buffers_total_bytes -= buffer->size;
		r_state.buffers_total_bytes += size;

		glBufferData(buffer->target, size, data, buffer->hint);
		R_GetError("Full resize");
		r_view.buffer_stats[buffer->type].num_full_uploads++;

		buffer->size = size;
	} else {
		// just update the range we specified
		if (data) {
			glBufferSubData(buffer->target, 0, size, data);
			r_view.buffer_stats[buffer->type].num_partial_uploads++;

			R_GetError("Updating existing buffer");
		}
	}

	r_view.buffer_stats[buffer->type].size_uploaded += size;
}
コード例 #4
0
ファイル: r_array.c プロジェクト: devilx4/quake2world
/*
 * @brief
 */
void R_ResetArrayState(void) {
	uint32_t arrays, mask;

	mask = 0xffff, arrays = R_ArraysMask(); // resolve the desired arrays mask

	if (r_array_state.model == NULL) {
		const int32_t xor = r_array_state.arrays ^ arrays;

		if (!xor) // no changes, we're done
			return;

		// resolve what's left to turn on
		mask = arrays & xor;
	} else
		// vbo
		R_BindBuffer(0, 0, 0);

	// vertex array
	if (mask & R_ARRAY_VERTEX)
		R_BindDefaultArray(GL_VERTEX_ARRAY);

	// color array
	if (r_state.color_array_enabled) {
		if (mask & R_ARRAY_COLOR)
			R_BindDefaultArray(GL_COLOR_ARRAY);
	}

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

		if (mask & R_ARRAY_NORMAL)
			R_BindDefaultArray(GL_NORMAL_ARRAY);

		if (r_bumpmap->value) {

			if (mask & R_ARRAY_TANGENT)
				R_BindDefaultArray(GL_TANGENT_ARRAY);
		}
	}

	// diffuse texcoords
	if (texunit_diffuse.enabled) {
		if (mask & R_ARRAY_TEX_DIFFUSE)
			R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
	}

	// lightmap texcoords
	if (texunit_lightmap.enabled) {

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

			R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);

			R_SelectTexture(&texunit_diffuse);
		}
	}

	r_array_state.model = NULL;
	r_array_state.arrays = arrays;
}