예제 #1
0
	bool GetIntersection(FCoverageVertex *v1, FCoverageVertex *v2, node_t *bsp, FCoverageVertex *v)
	{
		double frac;
		double num;
		double den;

		double v2x = (double)v1->x;
		double v2y = (double)v1->y;
		double v2dx = (double)(v2->x - v1->x);
		double v2dy = (double)(v2->y - v1->y);
		double v1x = (double)bsp->x;
		double v1y = (double)bsp->y;
		double v1dx = (double)bsp->dx;
		double v1dy = (double)bsp->dy;
			
		den = v1dy*v2dx - v1dx*v2dy;

		if (den == 0)
			return false;		// parallel
		
		num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx;
		frac = num / den;

		if (frac < 0. || frac > 1.) return false;

		v->x = xs_RoundToInt(v2x + frac * v2dx);
		v->y = xs_RoundToInt(v2y + frac * v2dy);
		return true;
	}
예제 #2
0
파일: r_bsp.cpp 프로젝트: FlameNeon/gzdoom
//
// FWallCoords :: Init
//
// Transform and clip coordinates. Returns true if it was clipped away
//
bool FWallCoords::Init(const DVector2 &pt1, const DVector2 &pt2, double too_close)
{
	tleft.X =  float(pt1.X * ViewSin - pt1.Y * ViewCos);
	tright.X = float(pt2.X * ViewSin - pt2.Y * ViewCos);

	tleft.Y =  float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin);
	tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin);

	if (MirrorFlags & RF_XFLIP)
	{
		float t = -tleft.X;
		tleft.X = -tright.X;
		tright.X = t;
		swapvalues(tleft.Y, tright.Y);
	}

	if (tleft.X >= -tleft.Y)
	{
		if (tleft.X > tleft.Y) return true;	// left edge is off the right side
		if (tleft.Y == 0) return true;
		sx1 = xs_RoundToInt(CenterX + tleft.X * CenterX / tleft.Y);
		sz1 = tleft.Y;
	}
	else
	{
		if (tright.X < -tright.Y) return true;	// wall is off the left side
		float den = tleft.X - tright.X - tright.Y + tleft.Y;
		if (den == 0) return true;
		sx1 = 0;
		sz1 = tleft.Y + (tright.Y - tleft.Y) * (tleft.X + tleft.Y) / den;
	}

	if (sz1 < too_close)
		return true;

	if (tright.X <= tright.Y)
	{
		if (tright.X < -tright.Y) return true;	// right edge is off the left side
		if (tright.Y == 0) return true;
		sx2 = xs_RoundToInt(CenterX + tright.X * CenterX / tright.Y);
		sz2 = tright.Y;
	}
	else
	{
		if (tleft.X > tleft.Y) return true;	// wall is off the right side
		float den = tright.Y - tleft.Y - tright.X + tleft.X;
		if (den == 0) return true;
		sx2 = viewwidth;
		sz2 = tleft.Y + (tright.Y - tleft.Y) * (tleft.X - tleft.Y) / den;
	}

	if (sz2 < too_close || sx2 <= sx1)
		return true;

	return false;
}
예제 #3
0
void DIntermissionScreenFader::Drawer ()
{
	if (!mFlatfill && mBackground.isValid())
	{
		double factor = clamp(double(mTicker) / mDuration, 0., 1.);
		if (mType == FADE_In) factor = 1.0 - factor;
		int color = MAKEARGB(xs_RoundToInt(factor*255), 0,0,0);

		if (screen->Begin2D(false))
		{
			screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, DTA_ColorOverlay, color, TAG_DONE);
			for (unsigned i=0; i < mOverlays.Size(); i++)
			{
				if (CheckOverlay(i))
					screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, DTA_ColorOverlay, color, TAG_DONE);
			}
			screen->FillBorder (NULL);
		}
		else
		{
			V_SetBlend (0,0,0,int(256*factor));
			Super::Drawer();
		}
	}
}
예제 #4
0
static bool Configure(SoundTemplate &self, const tinyxml2::XMLElement *element, unsigned int id)
{
	// get sound length
	float length;
	element->QueryFloatAttribute("length", &length);
	size_t count = xs_CeilToInt(length * AUDIO_FREQUENCY);

	// reserve space
	self.Reserve(count);

	// get expression
	std::vector<unsigned int> buffer;
	Expression::Loader<float>::ConfigureRoot(element, buffer, sScalarNames, sScalarDefault);

	// set up a context
	EntityContext context(&buffer[0], buffer.size(), 0, id);

	// for each sample...
	for (size_t i = 0; i < count; ++i, context.Restart())
	{
		// evaluate the expression
		context.mParam = float(i) / AUDIO_FREQUENCY;
		float value = Expression::Evaluate<float>(context);

		// add a sample
		self.Append(short(Clamp(xs_RoundToInt(value * SHRT_MAX), SHRT_MIN, SHRT_MAX)));
	}

	return true;
}
예제 #5
0
static int segcmp(const void *a, const void *b)
{
    seg_t *A = *(seg_t**)a;
    seg_t *B = *(seg_t**)b;
    return xs_RoundToInt(FRACUNIT*(A->sidefrac - B->sidefrac));
}
예제 #6
0
파일: gl_decal.cpp 프로젝트: 1Akula1/gzdoom
//==========================================================================
//
//
//
//==========================================================================
void GLWall::DrawDecal(DBaseDecal *decal)
{
	line_t * line=seg->linedef;
	side_t * side=seg->sidedef;
	int i;
	fixed_t zpos;
	int light;
	int rel;
	float a;
	bool flipx, flipy, loadAlpha;
	DecalVertex dv[4];
	FTextureID decalTile;
	

	if (decal->RenderFlags & RF_INVISIBLE) return;
	if (type==RENDERWALL_FFBLOCK && gltexture->isMasked()) return;	// No decals on 3D floors with transparent textures.

	//if (decal->sprite != 0xffff)
	{
		decalTile = decal->PicNum;
		flipx = !!(decal->RenderFlags & RF_XFLIP);
		flipy = !!(decal->RenderFlags & RF_YFLIP);
	}
	/*
	else
	{
	decalTile = SpriteFrames[sprites[decal->sprite].spriteframes + decal->frame].lump[0];
	flipx = SpriteFrames[sprites[decal->sprite].spriteframes + decal->frame].flip & 1;
	}
	*/

	FTexture *texture = TexMan[decalTile];
	if (texture == NULL) return;

	FMaterial *tex;


	if (texture->UseType == FTexture::TEX_MiscPatch)
	{
		// We need to create a clone of this texture where we can force the
		// texture filtering offset in.
		if (texture->gl_info.DecalTexture == NULL)
		{
			texture->gl_info.DecalTexture = new FCloneTexture(texture, FTexture::TEX_Decal);
		}
		tex = FMaterial::ValidateTexture(texture->gl_info.DecalTexture);
	}
	else tex = FMaterial::ValidateTexture(texture);


	// the sectors are only used for their texture origin coordinates
	// so we don't need the fake sectors for deep water etc.
	// As this is a completely split wall fragment no further splits are
	// necessary for the decal.
	sector_t *frontsector;

	// for 3d-floor segments use the model sector as reference
	if ((decal->RenderFlags&RF_CLIPMASK)==RF_CLIPMID) frontsector=decal->Sector;
	else frontsector=seg->frontsector;

	switch (decal->RenderFlags & RF_RELMASK)
	{
	default:
		// No valid decal can have this type. If one is encountered anyway
		// it is in some way invalid so skip it.
		return;
		//zpos = decal->z;
		//break;

	case RF_RELUPPER:
		if (type!=RENDERWALL_TOP) return;
		if (line->flags & ML_DONTPEGTOP)
		{
			zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
		}
		else
		{
			zpos = decal->Z + seg->backsector->GetPlaneTexZ(sector_t::ceiling);
		}
		break;
	case RF_RELLOWER:
		if (type!=RENDERWALL_BOTTOM) return;
		if (line->flags & ML_DONTPEGBOTTOM)
		{
			zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
		}
		else
		{
			zpos = decal->Z + seg->backsector->GetPlaneTexZ(sector_t::floor);
		}
		break;
	case RF_RELMID:
		if (type==RENDERWALL_TOP || type==RENDERWALL_BOTTOM) return;
		if (line->flags & ML_DONTPEGBOTTOM)
		{
			zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::floor);
		}
		else
		{
			zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
		}
	}
	
	if (decal->RenderFlags & RF_FULLBRIGHT)
	{
		light = 255;
		rel = 0;
	}
	else
	{
		light = lightlevel;
		rel = rellight + getExtraLight();
	}
	
	int r = RPART(decal->AlphaColor);
	int g = GPART(decal->AlphaColor);
	int b = BPART(decal->AlphaColor);
	FColormap p = Colormap;
	
	if (glset.nocoloredspritelighting)
	{
		int v = (Colormap.LightColor.r * 77 + Colormap.LightColor.g*143 + Colormap.LightColor.b*35)/255;
		p.LightColor = PalEntry(p.colormap, v, v, v);
	}
	
	float red, green, blue;
	
	if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
	{
		loadAlpha = true;
		p.colormap=CM_SHADE;

		if (glset.lightmode != 8)
		{
			gl_GetLightColor(light, rel, &p, &red, &green, &blue);
		}
		else
		{
			gl_GetLightColor(lightlevel, rellight, &p, &red, &green, &blue);
		}
		
		if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites)
		{
			float result[3];
			fixed_t x, y;
			decal->GetXY(seg->sidedef, x, y);
			gl_GetSpriteLight(NULL, x, y, zpos, sub, Colormap.colormap-CM_DESAT0, result, line, side == line->sidedef[0]? 0:1);
			if (glset.lightmode != 8)
			{
				red = clamp<float>(result[0]+red, 0, 1.0f);
				green = clamp<float>(result[1]+green, 0, 1.0f);
				blue = clamp<float>(result[2]+blue, 0, 1.0f);
			}
			else
			{
				gl_RenderState.SetDynLight(result[0], result[1], result[2]);
			}
		}

		BYTE R = xs_RoundToInt(r * red);
		BYTE G = xs_RoundToInt(g * green);
		BYTE B = xs_RoundToInt(b * blue);

		gl_ModifyColor(R,G,B, Colormap.colormap);

		red = R/255.f;
		green = G/255.f;
		blue = B/255.f;
	}	
	else
	{
		loadAlpha = false;
		
		red = 1.f;
		green = 1.f;
		blue = 1.f;
	}
	
	
	a = FIXED2FLOAT(decal->Alpha);
	
	// now clip the decal to the actual polygon
	float decalwidth = tex->TextureWidth(GLUSE_PATCH)  * FIXED2FLOAT(decal->ScaleX);
	float decalheight= tex->TextureHeight(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY);
	float decallefto = tex->GetLeftOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX);
	float decaltopo  = tex->GetTopOffset(GLUSE_PATCH)  * FIXED2FLOAT(decal->ScaleY);

	
	float leftedge = glseg.fracleft * side->TexelLength;
	float linelength = glseg.fracright * side->TexelLength - leftedge;

	// texel index of the decal's left edge
	float decalpixpos = (float)side->TexelLength * decal->LeftDistance / (1<<30) - (flipx? decalwidth-decallefto : decallefto) - leftedge;

	float left,right;
	float lefttex,righttex;

	// decal is off the left edge
	if (decalpixpos < 0)
	{
		left = 0;
		lefttex = -decalpixpos;
	}
	else
	{
		left = decalpixpos;
		lefttex = 0;
	}
	
	// decal is off the right edge
	if (decalpixpos + decalwidth > linelength)
	{
		right = linelength;
		righttex = right - decalpixpos;
	}
	else
	{
		right = decalpixpos + decalwidth;
		righttex = decalwidth;
	}
	if (right<=left) return;	// nothing to draw

	// one texture unit on the wall as vector
	float vx=(glseg.x2-glseg.x1)/linelength;
	float vy=(glseg.y2-glseg.y1)/linelength;
		
	dv[1].x=dv[0].x=glseg.x1+vx*left;
	dv[1].y=dv[0].y=glseg.y1+vy*left;

	dv[3].x=dv[2].x=glseg.x1+vx*right;
	dv[3].y=dv[2].y=glseg.y1+vy*right;
		
	zpos+= FRACUNIT*(flipy? decalheight-decaltopo : decaltopo);

	tex->BindPatch(p.colormap, decal->Translation);

	dv[1].z=dv[2].z = FIXED2FLOAT(zpos);
	dv[0].z=dv[3].z = dv[1].z - decalheight;
	dv[1].v=dv[2].v = tex->GetVT();

	dv[1].u=dv[0].u = tex->GetU(lefttex / FIXED2FLOAT(decal->ScaleX));
	dv[3].u=dv[2].u = tex->GetU(righttex / FIXED2FLOAT(decal->ScaleX));
	dv[0].v=dv[3].v = tex->GetVB();


	// now clip to the top plane
	float vzt=(ztop[1]-ztop[0])/linelength;
	float topleft=this->ztop[0]+vzt*left;
	float topright=this->ztop[0]+vzt*right;

	// completely below the wall
	if (topleft<dv[0].z && topright<dv[3].z) 
		return;

	if (topleft<dv[1].z || topright<dv[2].z)
	{
		// decal has to be clipped at the top
		// let texture clamping handle all extreme cases
		dv[1].v=(dv[1].z-topleft)/(dv[1].z-dv[0].z)*dv[0].v;
		dv[2].v=(dv[2].z-topright)/(dv[2].z-dv[3].z)*dv[3].v;
		dv[1].z=topleft;
		dv[2].z=topright;
	}

	// now clip to the bottom plane
	float vzb=(zbottom[1]-zbottom[0])/linelength;
	float bottomleft=this->zbottom[0]+vzb*left;
	float bottomright=this->zbottom[0]+vzb*right;

	// completely above the wall
	if (bottomleft>dv[1].z && bottomright>dv[2].z) 
		return;

	if (bottomleft>dv[0].z || bottomright>dv[3].z)
	{
		// decal has to be clipped at the bottom
		// let texture clamping handle all extreme cases
		dv[0].v=(dv[1].z-bottomleft)/(dv[1].z-dv[0].z)*(dv[0].v-dv[1].v) + dv[1].v;
		dv[3].v=(dv[2].z-bottomright)/(dv[2].z-dv[3].z)*(dv[3].v-dv[2].v) + dv[2].v;
		dv[0].z=bottomleft;
		dv[3].z=bottomright;
	}


	if (flipx)
	{
		float ur = tex->GetUR();
		for(i=0;i<4;i++) dv[i].u=ur-dv[i].u;
	}
	if (flipy)
	{
		float vb = tex->GetVB();
		for(i=0;i<4;i++) dv[i].v=vb-dv[i].v;
	}
	// fog is set once per wall in the calling function and not per decal!

	if (loadAlpha)
	{
		glColor4f(red, green, blue, a);

		if (glset.lightmode == 8)
		{
			if (gl_fixedcolormap)
				glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
			else
				glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(light, rel, false) / 255.0);
		}
	}
	else
	{
		if (glset.lightmode == 8)
		{
			gl_SetColor(light, rel, &p, a, extralight); // Korshun.
		}
		else
		{
			gl_SetColor(light, rel, &p, a);
		}
	}

	PalEntry fc = gl_RenderState.GetFogColor();
	if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
	{
		gl_RenderState.SetFog(0,-1);
	}


	gl_SetRenderStyle(decal->RenderStyle, false, false);

	// If srcalpha is one it looks better with a higher alpha threshold
	if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
	else gl_RenderState.AlphaFunc(GL_GREATER, 0.f);

	gl_RenderState.Apply();
	glBegin(GL_TRIANGLE_FAN);
	for(i=0;i<4;i++)
	{
		glTexCoord2f(dv[i].u,dv[i].v);
		glVertex3f(dv[i].x,dv[i].z,dv[i].y);
	}
	glEnd();
	rendered_decals++;
	gl_RenderState.SetFog(fc,-1);
	gl_RenderState.SetDynLight(0,0,0);
}
예제 #7
0
void ShellMenuAudioEnter()
{
	shellmenuaudiosoundchannelsonenter = SOUND_CHANNELS;
	VarItem *varsoundchannels = VarItem::CreateInteger("shell.menu.audio.channels", SOUND_CHANNELS, 1);
	TIXML_SNPRINTF(shellmenuaudiosoundchannelstext, sizeof(shellmenuaudiosoundchannelstext), "%d", varsoundchannels->GetInteger());

	shellmenuaudiosoundvolumeeffectonenter = SOUND_VOLUME_EFFECT;
	VarItem *varsoundvolumeeffect = VarItem::CreateInteger("shell.menu.audio.volume.effect", xs_RoundToInt(SOUND_VOLUME_EFFECT * 10), 0, 20);
	TIXML_SNPRINTF(shellmenuaudiosoundvolumeeffecttext, sizeof(shellmenuaudiosoundvolumeeffecttext), "%d%%", varsoundvolumeeffect->GetInteger() * 10);

	shellmenuaudiosoundvolumemusiconenter = SOUND_VOLUME_MUSIC;
	VarItem *varsoundvolumemusic = VarItem::CreateInteger("shell.menu.audio.volume.music", xs_RoundToInt(SOUND_VOLUME_MUSIC * 10), 0, 20);
	TIXML_SNPRINTF(shellmenuaudiosoundvolumemusictext, sizeof(shellmenuaudiosoundvolumemusictext), "%d%%", varsoundvolumemusic->GetInteger() * 10);
}
예제 #8
0
void ShellMenuVideoEnter()
{
	ShellMenuVideoUpdateResolutionList();

	shellmenuvideoresolutionindex = 0;
	for (int i = 0; i < shellmenuvideoresolutioncount; ++i)
	{
		if (SCREEN_WIDTH >= shellmenuvideoresolutionlist[i].w &&
			SCREEN_HEIGHT >= shellmenuvideoresolutionlist[i].h)
			shellmenuvideoresolutionindex = i;
	}
	ShellMenuVideoUpdateResolutionText();

	VarItem::CreateInteger("shell.menu.video.fullscreen", SCREEN_FULLSCREEN, 0, 1);
	VarItem::CreateInteger("shell.menu.video.verticalsync", OPENGL_SWAPCONTROL, 0, 1);

	VarItem *varmultisample = VarItem::CreateInteger("shell.menu.video.multisample", OPENGL_MULTISAMPLE, 1, 16);
	TIXML_SNPRINTF(shellmenuvideomultisampletext, sizeof(shellmenuvideomultisampletext), "%dx", varmultisample->GetInteger());

	VarItem *varmotionblursteps = VarItem::CreateInteger("shell.menu.video.motionblur", MOTIONBLUR_STEPS, 1);
	TIXML_SNPRINTF(shellmenuvideomotionblurstepstext, sizeof(shellmenuvideomotionblurstepstext), "%d", varmotionblursteps->GetInteger());

	VarItem *varmotionblurtime = VarItem::CreateInteger("shell.menu.video.motionblurtime", xs_RoundToInt(MOTIONBLUR_TIME * 600), 0, 10);
	TIXML_SNPRINTF(shellmenuvideomotionblurtimetext, sizeof(shellmenuvideomotionblurtimetext), "%d%%", varmotionblurtime->GetInteger() * 10);
}
예제 #9
0
// draw title
void ShellTitle::Render(unsigned int aId, float aTime, const Transform2 &aTransform)
{
//#define USE_TITLE_VERTEX_ARRAY
#ifdef USE_TITLE_VERTEX_ARRAY
	static Vector2 vertexarray[32768];
	static unsigned int colorarray[32768];
	Vector2 *vertexptr = vertexarray;
	unsigned int *colorptr = colorarray;
#else
	glBegin(GL_QUADS);
#endif

	// draw title bar
	for (int row = 0; row < SDL_arraysize(titlemap); ++row)
	{
		float y0 = titley + row * titleh, y1 = y0 + titleh;

#ifdef USE_TITLE_VERTEX_ARRAY
		unsigned int color = (xs_RoundToInt(255*baralpha[row]) << 24) | 0x00505050;
		*colorptr++ = color;
		*colorptr++ = color;
		*colorptr++ = color;
		*colorptr++ = color;
		*vertexptr++ = Vector2(0, y0);
		*vertexptr++ = Vector2(640, y0);
		*vertexptr++ = Vector2(640, y1);
		*vertexptr++ = Vector2(0, y1);
#else
		glColor4f(0.3f, 0.3f, 0.3f, baralpha[row]);
		glVertex2f(0, y0);
		glVertex2f(640, y0);
		glVertex2f(640, y1);
		glVertex2f(0, y1);
#endif
	}

	// draw title body
	unsigned short *titlefillptr = titlefill;

#if 1
#ifdef USE_TITLE_MIRROR_WATER_EFFECT
	// starting mirror properties
	float mirror_y0 = MirrorWaveY(titley - titleh);
	float mirror_d0 = MirrorWaveX(mirror_y0);
	float mirror_a0 = mirroralphastart + mirroralphadelta * mirror_y0;
#endif

	for (int row = -1; row < (int)SDL_arraysize(titlemap) + 1; ++row)
	{
		float y = titley + row * titleh;

#ifdef USE_TITLE_MIRROR_WATER_EFFECT
		// row mirror properties
		float mirror_y1 = MirrorWaveY(y + titleh);
		float mirror_yd = (mirror_y1 - mirror_y0) / titleh;
		float mirror_d1 = MirrorWaveX(mirror_y1);
		float mirror_dd = (mirror_d1 - mirror_d0) / titleh;
		float mirror_a1 = mirroralphastart + mirroralphadelta * mirror_y1;
		float mirror_ad = (mirror_a1 - mirror_a0) / titleh;
#endif

		for (int col = -1; col < (int)SDL_arraysize(titlemap[0]); ++col)
		{
			float x = titlex + col * titlew;

			if (*titlefillptr != 0)
			{
				int phase = *titlefillptr >> 9;
				int fill = *titlefillptr & 0x1FF;

				// get block color
				float R, G, B;
				float h = BlockHue(col, row);
				bool border = (fill & ~(1<<4)) != 0;
				HSV2RGB(h + phase * 0.5f + border * 0.5f, 1.0f, 1.0f - 0.25f * border, R, G, B);

				// for each block...
				for (int i = 0; i < 9; ++i)
				{
					// if the block is filled
					if (fill & (1 << i))
					{
						// block borders
						float x0 = x + block[i][0][0];
						float x1 = x + block[i][0][1];
						float y0 = y + block[i][1][0];
						float y1 = y + block[i][1][1];

						// upright
#ifdef USE_TITLE_VERTEX_ARRAY
						unsigned int color = 0xFF000000 | (xs_RoundToInt(B * 255) << 16) | (xs_RoundToInt(G * 255) << 8) | (xs_RoundToInt(R * 255) );
						*colorptr++ = color;
						*colorptr++ = color;
						*colorptr++ = color;
						*colorptr++ = color;
						*vertexptr++ = Vector2(x0, y0);
						*vertexptr++ = Vector2(x1, y0);
						*vertexptr++ = Vector2(x1, y1);
						*vertexptr++ = Vector2(x0, y1);
#else
						glColor4f(R, G, B, 1.0f);
						glVertex2f(x0, y0);
						glVertex2f(x1, y0);
						glVertex2f(x1, y1);
						glVertex2f(x0, y1);
#endif

#ifdef USE_TITLE_MIRROR_WATER_EFFECT
						if (mirror_a0 > 0.0f || mirror_a1 > 0.0f)
						{
							// mirrored
							float m0 = y0 - y;
							float m1 = y1 - y;
							float a0 = std::max(mirror_a0 + mirror_ad * m0, 0.0f);
							float a1 = std::max(mirror_a0 + mirror_ad * m1, 0.0f);
							float dx0 = mirror_d0 + mirror_dd * m0;
							float dx1 = mirror_d0 + mirror_dd * m1;
							float yy0 = mirror_y0 + mirror_yd * m0;
							float yy1 = mirror_y0 + mirror_yd * m1;
#ifdef USE_TITLE_VERTEX_ARRAY
							color &= 0x00FFFFFF;
							color |= xs_RoundToInt(a1 * a1 * 255) << 24;
							*colorptr++ = color;
							*colorptr++ = color;
							*vertexptr++ = Vector2(x0 + dx1, yy1);
							*vertexptr++ = Vector2(x1 + dx1, yy1);
							color &= 0x00FFFFFF;
							color |= xs_RoundToInt(a0 * a0 * 255) << 24;
							*colorptr++ = color;
							*colorptr++ = color;
							*vertexptr++ = Vector2(x1 + dx0, yy0);
							*vertexptr++ = Vector2(x0 + dx0, yy0);
#else
							glColor4f(R, G, B, a1 * a1);
							glVertex2f(x0 + dx1, yy1);
							glVertex2f(x1 + dx1, yy1);
							glColor4f(R, G, B, a0 * a0);
							glVertex2f(x1 + dx0, yy0);
							glVertex2f(x0 + dx0, yy0);
#endif
						}
#endif
					}
				}
			}

			++titlefillptr;
		}

#ifdef USE_TITLE_MIRROR_WATER_EFFECT
		// mirror shift row
		mirror_y0 = mirror_y1;
		mirror_d0 = mirror_d1;
		mirror_a0 = mirror_a1;
#endif
	}
예제 #10
0
파일: r_bsp.cpp 프로젝트: FlameNeon/gzdoom
static bool R_CheckBBox (fixed_t *bspcoord)	// killough 1/28/98: static
{
	int 				boxx;
	int 				boxy;
	int 				boxpos;

	double	 			x1, y1, x2, y2;
	double				rx1, ry1, rx2, ry2;
	int					sx1, sx2;
	
	cliprange_t*		start;

	// Find the corners of the box
	// that define the edges from current viewpoint.
	if (ViewPos.X <= FIXED2DBL(bspcoord[BOXLEFT]))
		boxx = 0;
	else if (ViewPos.X < FIXED2DBL(bspcoord[BOXRIGHT]))
		boxx = 1;
	else
		boxx = 2;

	if (ViewPos.Y >= FIXED2DBL(bspcoord[BOXTOP]))
		boxy = 0;
	else if (ViewPos.Y > FIXED2DBL(bspcoord[BOXBOTTOM]))
		boxy = 1;
	else
		boxy = 2;

	boxpos = (boxy<<2)+boxx;
	if (boxpos == 5)
		return true;

	x1 = FIXED2DBL(bspcoord[checkcoord[boxpos][0]]) - ViewPos.X;
	y1 = FIXED2DBL(bspcoord[checkcoord[boxpos][1]]) - ViewPos.Y;
	x2 = FIXED2DBL(bspcoord[checkcoord[boxpos][2]]) - ViewPos.X;
	y2 = FIXED2DBL(bspcoord[checkcoord[boxpos][3]]) - ViewPos.Y;

	// check clip list for an open space

	// Sitting on a line?
	if (y1 * (x1 - x2) + x1 * (y2 - y1) >= -EQUAL_EPSILON)
		return true;

	rx1 = x1 * ViewSin - y1 * ViewCos;
	rx2 = x2 * ViewSin - y2 * ViewCos;
	ry1 = x1 * ViewTanCos + y1 * ViewTanSin;
	ry2 = x2 * ViewTanCos + y2 * ViewTanSin;

	if (MirrorFlags & RF_XFLIP)
	{
		double t = -rx1;
		rx1 = -rx2;
		rx2 = t;
		swapvalues(ry1, ry2);
	}

	if (rx1 >= -ry1)
	{
		if (rx1 > ry1) return false;	// left edge is off the right side
		if (ry1 == 0) return false;
		sx1 = xs_RoundToInt(CenterX + rx1 * CenterX / ry1);
	}
	else
	{
		if (rx2 < -ry2) return false;	// wall is off the left side
		if (rx1 - rx2 - ry2 + ry1 == 0) return false;	// wall does not intersect view volume
		sx1 = 0;
	}

	if (rx2 <= ry2)
	{
		if (rx2 < -ry2) return false;	// right edge is off the left side
		if (ry2 == 0) return false;
		sx2 = xs_RoundToInt(CenterX + rx2 * CenterX / ry2);
	}
	else
	{
		if (rx1 > ry1) return false;	// wall is off the right side
		if (ry2 - ry1 - rx2 + rx1 == 0) return false;	// wall does not intersect view volume
		sx2 = viewwidth;
	}

	// Find the first clippost that touches the source post
	//	(adjacent pixels are touching).

	// Does not cross a pixel.
	if (sx2 <= sx1)
		return false;

	start = solidsegs;
	while (start->last < sx2)
		start++;

	if (sx1 >= start->first && sx2 <= start->last)
	{
		// The clippost contains the new span.
		return false;
	}

	return true;
}