Beispiel #1
0
/**
 * @brief Takes all of the brushes from the current entity and adds them to the world's brush list.
 * @note Used by func_group
 * @note This will only work if the func_group is the last entity currently known. At the moment,
 * this function is only called by ParseMapEntity and this happens directly after the func_group
 * is parsed, so this is OK.
 * @sa MoveModelToWorld
 */
static void MoveBrushesToWorld (entity_t* mapent)
{
	int newbrushes, worldbrushes, i;
	mapbrush_t* temp;

	/* this is pretty gross, because the brushes are expected to be
	 * in linear order for each entity */

	newbrushes = mapent->numbrushes;
	worldbrushes = entities[0].numbrushes;

	if (newbrushes == 0)
		Sys_Error("Empty func_group - clean your map");

	temp = Mem_AllocTypeN(mapbrush_t, newbrushes);
	memcpy(temp, mapbrushes + mapent->firstbrush, newbrushes * sizeof(*temp));

	/* make space to move the brushes (overlapped copy) */
	memmove(mapbrushes + worldbrushes + newbrushes,
		mapbrushes + worldbrushes,
		sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes));

	/* copy the new brushes down */
	memcpy(mapbrushes + worldbrushes, temp, sizeof(*temp) * newbrushes);

	/* fix up indexes */
	entities[0].numbrushes += newbrushes;
	for (i = 1; i < num_entities; i++)
		entities[i].firstbrush += newbrushes;
	Mem_Free(temp);

	mapent->numbrushes = 0;
}
Beispiel #2
0
static void WriteTGA24 (const char* filename, const byte*  data, int width, int height, int offset)
{
	const int size = width * height * 3;
	/* allocate a buffer and set it up */
	byte* buffer = Mem_AllocTypeN(byte, size + TGA_HEADER_SIZE);
	memset(buffer, 0, TGA_HEADER_SIZE);
	buffer[2] = 2;
	buffer[12] = width & 255;
	buffer[13] = width >> 8;
	buffer[14] = height & 255;
	buffer[15] = height >> 8;
	buffer[16] = 24;
	/* create top-down TGA */
	buffer[17] = 32;

	/* swap rgb to bgr */
	for (int i = 0; i < size; i += 3) {
		buffer[i + TGA_HEADER_SIZE] = data[i*2 + offset + 2];	/* blue */
		buffer[i + TGA_HEADER_SIZE + 1] = data[i*2 + offset + 1];	/* green */
		buffer[i + TGA_HEADER_SIZE + 2] = data[i*2 + offset + 0];	/* red */
	}

	/* write it and free the buffer */
	ScopedFile file;
	if (FS_OpenFile(filename, &file, FILE_WRITE) > 0)
		Sys_Error("Unable to open %s for writing", filename);

	FS_Write(buffer, size + TGA_HEADER_SIZE, &file);

	/* close the file */
	Mem_Free(buffer);
}
Beispiel #3
0
void R_InitFBObjects (void)
{
	unsigned int filters[2];
	float scales[DOWNSAMPLE_PASSES];
	int i;

	if (!r_config.frameBufferObject || !r_programs->integer)
		return;

	frameBufferObjectCount = 0;
	OBJZERO(frameBufferObjects);
	OBJZERO(frameBufferTextures);

	r_state.frameBufferObjectsInitialized = true;

	for (i = 0; i < DOWNSAMPLE_PASSES; i++)
		scales[i] = powf(DOWNSAMPLE_SCALE, i + 1);

	/* setup default screen framebuffer */
	screenBuffer.fbo = 0;
	screenBuffer.depth = 0;
	screenBuffer.nTextures = 0;
	screenBuffer.width = viddef.context.width;
	screenBuffer.height = viddef.context.height;
	R_SetupViewport(&screenBuffer, 0, 0, viddef.context.width, viddef.context.height);
	Vector4Clear(screenBuffer.clearColor);

	/* use default framebuffer */
	qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	r_state.activeFramebuffer = &screenBuffer;

	colorAttachments = Mem_AllocTypeN(GLenum, r_config.maxDrawBuffers);
	for (i = 0; i < r_config.maxDrawBuffers; i++)
		colorAttachments[i] = GL_COLOR_ATTACHMENT0_EXT + i;

	filters[0] = GL_NEAREST;
	filters[1] = GL_LINEAR_MIPMAP_LINEAR;

	/* setup main 3D render target */
	r_state.renderBuffer = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 2, true, false, filters);

	/* setup bloom render targets */
	fbo_bloom0 = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 1, false, false, filters);
	fbo_bloom1 = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 1, false, false, filters);

	filters[0] = GL_LINEAR;
	/* setup extra framebuffers */
	for (i = 0; i < DOWNSAMPLE_PASSES; i++) {
		const int h = (int)((float)viddef.context.height / scales[i]);
		const int w = (int)((float)viddef.context.width / scales[i]);
		r_state.buffers0[i] = R_CreateFramebuffer(w, h, 1, false, false, filters);
		r_state.buffers1[i] = R_CreateFramebuffer(w, h, 1, false, false, filters);
		r_state.buffers2[i] = R_CreateFramebuffer(w, h, 1, false, false, filters);

		R_CheckError();
	}
}
/**
 * @brief Called before loading. Used to set default attribute values
 */
void uiGeoscapeNode::onLoading (uiNode_t* node)
{
    Vector4Set(node->color, 1, 1, 1, 1);

    OBJZERO(EXTRADATA(node));
    EXTRADATA(node).angles[YAW] = GLOBE_ROTATE;
    EXTRADATA(node).center[0] = EXTRADATA(node).center[1] = 0.5;
    EXTRADATA(node).zoom = 1.0;
    Vector2Set(EXTRADATA(node).smoothFinal2DGeoscapeCenter, 0.5, 0.5);
    VectorSet(EXTRADATA(node).smoothFinalGlobeAngle, 0, GLOBE_ROTATE, 0);

    /* @todo: allocate this on a per node basis - and remove the global variable geoscapeData */
    EXTRADATA(node).geoscapeData = &geoscapeData;
    /* EXTRADATA(node).geoscapeData = Mem_AllocType(geoscapeData_t); */

    /** this is the data that is used with r_dayandnightTexture */
    EXTRADATA(node).r_dayandnightAlpha = Mem_AllocTypeN(byte, DAN_WIDTH * DAN_HEIGHT);

    r_dayandnightTexture = R_LoadImageData("***r_dayandnighttexture***", nullptr, DAN_WIDTH, DAN_HEIGHT, it_effect);
    r_radarTexture = R_LoadImageData("***r_radarTexture***", nullptr, RADAR_WIDTH, RADAR_HEIGHT, it_effect);
    r_xviTexture = R_LoadImageData("***r_xvitexture***", nullptr, XVI_WIDTH, XVI_HEIGHT, it_effect);
}
Beispiel #5
0
bool Rimp_Init (void)
{
	SDL_version version;
	int attrValue;

	Com_Printf("\n------- video initialization -------\n");

	OBJZERO(r_sdl_config);

	if (r_driver->string[0] != '\0') {
		Com_Printf("using driver: %s\n", r_driver->string);
		SDL_GL_LoadLibrary(r_driver->string);
	}

	Sys_Setenv("SDL_VIDEO_CENTERED", "1");
	Sys_Setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "0");

	if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
		if (SDL_Init(SDL_INIT_VIDEO) < 0)
			Com_Error(ERR_FATAL, "Video SDL_Init failed: %s", SDL_GetError());
	}

	SDL_VERSION(&version)
	Com_Printf("SDL version: %i.%i.%i\n", version.major, version.minor, version.patch);

#if SDL_VERSION_ATLEAST(2,0,0)
	int screen = 0;
	const int modes = SDL_GetNumDisplayModes(screen);
	if (modes > 0) {
		r_sdl_config.modes = Mem_AllocTypeN(rect_t, modes);
		for (int i = 0; i < modes; i++) {
			SDL_DisplayMode displayMode;
			SDL_GetDisplayMode(screen, i, &displayMode);
			r_sdl_config.modes[i][0] = displayMode.w;
			r_sdl_config.modes[i][1] = displayMode.h;
		}
	}
#else
	const SDL_VideoInfo* info = SDL_GetVideoInfo();
	if (info != nullptr) {
		SDL_VideoInfo videoInfo;
		SDL_PixelFormat pixelFormat;
		SDL_Rect** modes;
		Com_Printf("I: desktop depth: %ibpp\n", info->vfmt->BitsPerPixel);
		r_config.videoMemory = info->video_mem;
		Com_Printf("I: video memory: %i\n", r_config.videoMemory);
		memcpy(&pixelFormat, info->vfmt, sizeof(pixelFormat));
		memcpy(&videoInfo, info, sizeof(videoInfo));
		videoInfo.vfmt = &pixelFormat;
		modes = SDL_ListModes(videoInfo.vfmt, SDL_OPENGL | SDL_FULLSCREEN);
		if (modes) {
			if (modes == (SDL_Rect**)-1) {
				Com_Printf("I: Available resolutions: any resolution is supported\n");
				r_sdl_config.modes = nullptr;
			} else {
				for (r_sdl_config.numModes = 0; modes[r_sdl_config.numModes]; r_sdl_config.numModes++) {}

				r_sdl_config.modes = Mem_AllocTypeN(rect_t, r_sdl_config.numModes);
				for (int i = 0; i < r_sdl_config.numModes; i++) {
					r_sdl_config.modes[i][0] = modes[i]->w;
					r_sdl_config.modes[i][1] = modes[i]->h;
				}
			}
		} else {
			Com_Printf("I: Could not get list of available resolutions\n");
		}
	}
	char videoDriverName[MAX_VAR] = "";
	SDL_VideoDriverName(videoDriverName, sizeof(videoDriverName));
	Com_Printf("I: video driver: %s\n", videoDriverName);
#endif
	if (r_sdl_config.numModes > 0) {
		char buf[4096] = "";
		Q_strcat(buf, sizeof(buf), "I: Available resolutions:");
		for (int i = 0; i < r_sdl_config.numModes; i++) {
			Q_strcat(buf, sizeof(buf), " %ix%i", r_sdl_config.modes[i][0], r_sdl_config.modes[i][1]);
		}
		Com_Printf("%s (%i)\n", buf, r_sdl_config.numModes);
	}

	if (!R_SetMode())
		Com_Error(ERR_FATAL, "Video subsystem failed to initialize");

#if !SDL_VERSION_ATLEAST(2,0,0)
	SDL_WM_SetCaption(GAME_TITLE, GAME_TITLE_LONG);

	/* we need this in the renderer because if we issue an vid_restart we have
	 * to set these values again, too */
	SDL_EnableUNICODE(SDL_ENABLE);
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
#endif

	R_SetSDLIcon();

	if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &attrValue))
		Com_Printf("I: got %d bits of stencil\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &attrValue))
		Com_Printf("I: got %d bits of depth buffer\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &attrValue))
		Com_Printf("I: got double buffer\n");
	if (!SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &attrValue))
		Com_Printf("I: got %d bits for red\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &attrValue))
		Com_Printf("I: got %d bits for green\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &attrValue))
		Com_Printf("I: got %d bits for blue\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &attrValue))
		Com_Printf("I: got %d bits for alpha\n", attrValue);
	if (!SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &attrValue))
		Com_Printf("I: got multisample %s\n", attrValue != 0 ? "enabled" : "disabled");
	if (!SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &attrValue))
		Com_Printf("I: got %d multisample buffers\n", attrValue);

	return true;
}
Beispiel #6
0
/**
 * @brief
 * @sa FinalLightFace
 */
void BuildFacelights (unsigned int facenum)
{
	dBspSurface_t* face;
	dBspPlane_t* plane;
	dBspTexinfo_t* tex;
	float* center;
	float* sdir, *tdir;
	vec3_t normal, binormal;
	vec4_t tangent;
	lightinfo_t li;
	float scale;
	int i, j, numsamples;
	facelight_t* fl;
	int* headhints;
	const int grid_type = config.soft ? 1 : 0;

	if (facenum >= MAX_MAP_FACES) {
		Com_Printf("MAX_MAP_FACES hit\n");
		return;
	}

	face = &curTile->faces[facenum];
	plane = &curTile->planes[face->planenum];
	tex = &curTile->texinfo[face->texinfo];

	if (tex->surfaceFlags & SURF_WARP)
		return;		/* non-lit texture */

	sdir = tex->vecs[0];
	tdir = tex->vecs[1];

	/* lighting -extra antialiasing */
	if (config.extrasamples)
		numsamples = config.soft ? SOFT_SAMPLES : MAX_SAMPLES;
	else
		numsamples = 1;

	OBJZERO(li);

	scale = 1.0 / numsamples; /* each sample contributes this much */

	li.face = face;
	li.facedist = plane->dist;
	VectorCopy(plane->normal, li.facenormal);
	/* negate the normal and dist */
	if (face->side) {
		VectorNegate(li.facenormal, li.facenormal);
		li.facedist = -li.facedist;
	}

	/* get the origin offset for rotating bmodels */
	VectorCopy(face_offset[facenum], li.modelorg);

	/* calculate lightmap texture mins and maxs */
	CalcLightinfoExtents(&li);

	/* and the lightmap texture vectors */
	CalcLightinfoVectors(&li);

	/* now generate all of the sample points */
	CalcPoints(&li, 0, 0);

	fl = &facelight[config.compile_for_day][facenum];
	fl->numsamples = li.numsurfpt;
	fl->samples    = Mem_AllocTypeN(vec3_t, fl->numsamples);
	fl->directions = Mem_AllocTypeN(vec3_t, fl->numsamples);

	center = face_extents[facenum].center;  /* center of the face */

	/* Also setup the hints.  Each hint is specific to each light source, including sunlight. */
	headhints = Mem_AllocTypeN(int, (numlights[config.compile_for_day] + 1));

	/* calculate light for each sample */
	for (i = 0; i < fl->numsamples; i++) {
		float* const sample    = fl->samples[i];    /* accumulate lighting here */
		float* const direction = fl->directions[i]; /* accumulate direction here */

		if (tex->surfaceFlags & SURF_PHONG)
			/* interpolated normal */
			SampleNormal(&li, li.surfpt[i], normal);
		else
			/* or just plane normal */
			VectorCopy(li.facenormal, normal);

		for (j = 0; j < numsamples; j++) {  /* with antialiasing */
			vec3_t pos;

			/* add offset for supersampling */
			VectorMA(li.surfpt[i], sampleofs[grid_type][j][0] * li.step, li.textoworld[0], pos);
			VectorMA(pos, sampleofs[grid_type][j][1] * li.step, li.textoworld[1], pos);

			NudgeSamplePosition(pos, normal, center, pos);

			GatherSampleLight(pos, normal, sample, direction, scale, headhints);
		}
		if (VectorNotEmpty(direction)) {
			vec3_t dir;

			/* normalize it */
			VectorNormalize(direction);

			/* finalize the lighting direction for the sample */
			TangentVectors(normal, sdir, tdir, tangent, binormal);

			dir[0] = DotProduct(direction, tangent);
			dir[1] = DotProduct(direction, binormal);
			dir[2] = DotProduct(direction, normal);

			VectorCopy(dir, direction);
		}
	}

	/* Free the hints. */
	Mem_Free(headhints);

	for (i = 0; i < fl->numsamples; i++) {  /* pad them */
		float* const direction = fl->directions[i];
		if (VectorEmpty(direction))
			VectorSet(direction, 0.0, 0.0, 1.0);
	}

	/* free the sample positions for the face */
	Mem_Free(li.surfpt);
}
Beispiel #7
0
/**
 * @brief Fills in texorg, worldtotex. and textoworld
 */
static void CalcLightinfoVectors (lightinfo_t* l)
{
	const dBspTexinfo_t* tex;
	int i;
	vec3_t texnormal;
	vec_t distscale, dist;

	tex = &curTile->texinfo[l->face->texinfo];

	for (i = 0; i < 2; i++)
		VectorCopy(tex->vecs[i], l->worldtotex[i]);

	/* calculate a normal to the texture axis.  points can be moved along this
	 * without changing their S/T */
	texnormal[0] = tex->vecs[1][1] * tex->vecs[0][2]
					- tex->vecs[1][2] * tex->vecs[0][1];
	texnormal[1] = tex->vecs[1][2] * tex->vecs[0][0]
					- tex->vecs[1][0] * tex->vecs[0][2];
	texnormal[2] = tex->vecs[1][0] * tex->vecs[0][1]
					- tex->vecs[1][1] * tex->vecs[0][0];
	VectorNormalize(texnormal);

	/* flip it towards plane normal */
	distscale = DotProduct(texnormal, l->facenormal);
	if (!distscale) {
		Verb_Printf(VERB_EXTRA, "WARNING: Texture axis perpendicular to face\n");
		distscale = 1.0;
	}
	if (distscale < 0.0) {
		distscale = -distscale;
		VectorSubtract(vec3_origin, texnormal, texnormal);
	}

	/* distscale is the ratio of the distance along the texture normal to
	 * the distance along the plane normal */
	distscale = 1.0 / distscale;

	for (i = 0; i < 2; i++) {
		const vec_t len = VectorLength(l->worldtotex[i]);
		const vec_t distance = DotProduct(l->worldtotex[i], l->facenormal) * distscale;
		VectorMA(l->worldtotex[i], -distance, texnormal, l->textoworld[i]);
		VectorScale(l->textoworld[i], (1.0f / len) * (1.0f / len), l->textoworld[i]);
	}

	/* calculate texorg on the texture plane */
	for (i = 0; i < 3; i++)
		l->texorg[i] =
			-tex->vecs[0][3] * l->textoworld[0][i] -
			tex->vecs[1][3] * l->textoworld[1][i];

	/* project back to the face plane */
	dist = DotProduct(l->texorg, l->facenormal) - l->facedist - 1;
	dist *= distscale;
	VectorMA(l->texorg, -dist, texnormal, l->texorg);

	/* compensate for org'd bmodels */
	VectorAdd(l->texorg, l->modelorg, l->texorg);

	/* total sample count */
	l->numsurfpt = l->texsize[0] * l->texsize[1];
	l->surfpt = Mem_AllocTypeN(vec3_t, l->numsurfpt);
	if (!l->surfpt)
		Sys_Error("Surface too large to light (" UFO_SIZE_T ")", l->numsurfpt * sizeof(*l->surfpt));

	/* distance between samples */
	l->step = 1 << config.lightquant;
}