Exemplo n.º 1
0
bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
{
	const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
	DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac);

	bool flipTextureX = false;
	FTexture *tex = GetSpriteTexture(thing, flipTextureX);
	if (tex == nullptr)
		return false;

	DVector2 spriteScale = thing->Scale;
	double thingxscalemul = spriteScale.X / tex->Scale.X;
	double thingyscalemul = spriteScale.Y / tex->Scale.Y;

	double spriteWidth = thingxscalemul * tex->GetWidth();
	double spriteHeight = thingyscalemul * tex->GetHeight();

	double offsetX;
	if (flipTextureX)
		offsetX = (tex->GetWidth() - tex->GetLeftOffsetPo()) * thingxscalemul;
	else
		offsetX = tex->GetLeftOffsetPo() * thingxscalemul;

	left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX);
	right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth);
	return true;
}
Exemplo n.º 2
0
static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon)
{
	int trans;

	// Powered up weapons and inherited sister weapons are not displayed.
	if (weapon->WeaponFlags & WIF_POWERED_UP) return;
	if (weapon->SisterWeapon && weapon->IsKindOf(weapon->SisterWeapon->GetClass())) return;

	trans=0x6666;
	if (CPlayer->ReadyWeapon)
	{
		if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999;
	}

	FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST);

	if (picnum.isValid())
	{
		FTexture * tex = TexMan[picnum];
		int w = tex->GetWidth();
		int h = tex->GetHeight();
		int rh;
		if (w>h) rh=8;
		else rh=16,y-=8;		// don't draw tall sprites too small!
		DrawImageToBox(tex, x-24, y, 20, rh, trans);
		y-=10;
	}
}
Exemplo n.º 3
0
void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, fixed_t x, fixed_t y, fixed_t z, F3DFloor * ffloor)
{
	FTexture *tex;
	vertex_t *v1;
	fixed_t rorg, ldx, ldy;

	GetWallStuff (wall, v1, ldx, ldy);
	rorg = Length (x - v1->x, y - v1->y);

	tex = TexMan[PicNum];
	int dwidth = tex->GetWidth ();

	DecalWidth = dwidth * ScaleX;
	DecalLeft = tex->LeftOffset * ScaleX;
	DecalRight = DecalWidth - DecalLeft;
	SpreadSource = this;
	SpreadTemplate = tpl;
	SpreadZ = z;

	// Try spreading left first
	SpreadLeft (rorg - DecalLeft, v1, wall, ffloor);
	SpreadStack.Clear ();

	// Then try spreading right
	SpreadRight (rorg + DecalRight, wall,
			Length (wall->linedef->dx, wall->linedef->dy), ffloor);
	SpreadStack.Clear ();
}
Exemplo n.º 4
0
void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor)
{
	FTexture *tex;
	vertex_t *v1;
	double rorg, ldx, ldy;

	GetWallStuff (wall, v1, ldx, ldy);
	rorg = Length (x - v1->fX(), y - v1->fY());

	if ((tex = TexMan[PicNum]) == NULL)
	{
		return;
	}

	int dwidth = tex->GetWidth ();

	DecalWidth = dwidth * ScaleX;
	DecalLeft = tex->LeftOffset * ScaleX;
	DecalRight = DecalWidth - DecalLeft;
	SpreadSource = this;
	SpreadTemplate = tpl;
	SpreadZ = z;

	// Try spreading left first
	SpreadLeft (rorg - DecalLeft, v1, wall, ffloor);
	SpreadStack.Clear ();

	// Then try spreading right
	SpreadRight (rorg + DecalRight, wall,
			Length (wall->linedef->Delta().X, wall->linedef->Delta().Y), ffloor);
	SpreadStack.Clear ();
}
Exemplo n.º 5
0
int WI_drawNum (int x, int y, int n, int digits, bool leadingzeros = true)
{
	// if non-number, do not draw it
	if (n == 1994)
		return 0;

	int fontwidth = num[3]->GetWidth();
	int xofs;
	char text[8];
	char *text_p;

	if (leadingzeros)
	{
		sprintf (text, "%07d", n);
	}
	else
	{
		sprintf (text, "%7d", n);
		if (digits < 0)
		{
			text_p = strrchr (text, ' ');
			digits = (text_p == NULL) ? 7 : 6 - (int)(text_p - text);
			x -= digits * fontwidth;
		}
	}

	text_p = strchr (text, '-');
	if (text_p == NULL || text_p - text > 7 - digits)
	{
		text_p = text + 7 - digits;
	}

	xofs = x;

	if (*text_p == '-')
	{
		x -= fontwidth;
		WI_DrawCharPatch (wiminus, x, y);
	}

	// draw the new number
	while (*text_p)
	{
		if (*text_p >= '0' && *text_p <= '9')
		{
			FTexture *p = num[*text_p - '0'];
			WI_DrawCharPatch (p, xofs + (fontwidth - p->GetWidth())/2, y);
		}
		text_p++;
		xofs += fontwidth;
	}
	return x;

}
Exemplo n.º 6
0
// Examines the lump contents to decide what type of texture to create,
// and creates the texture.
FTexture * FTexture::CreateTexture (int lumpnum, int usetype)
{
	static TexCreateInfo CreateInfo[]={
		{ IMGZTexture_TryCreate,		TEX_Any },
		{ PNGTexture_TryCreate,			TEX_Any },
		{ JPEGTexture_TryCreate,		TEX_Any },
		{ DDSTexture_TryCreate,			TEX_Any },
		{ PCXTexture_TryCreate,			TEX_Any },
		{ TGATexture_TryCreate,			TEX_Any },
		{ RawPageTexture_TryCreate,		TEX_MiscPatch },
		{ FlatTexture_TryCreate,		TEX_Flat },
		{ PatchTexture_TryCreate,		TEX_Any },
		{ EmptyTexture_TryCreate,		TEX_Any },
		{ AutomapTexture_TryCreate,		TEX_MiscPatch },
	};

	if (lumpnum == -1) return NULL;

	FWadLump data = Wads.OpenLumpNum (lumpnum);

	for(size_t i = 0; i < countof(CreateInfo); i++)
	{
		if ((CreateInfo[i].usetype == usetype || CreateInfo[i].usetype == TEX_Any))
		{
			FTexture * tex = CreateInfo[i].TryCreate(data, lumpnum);
			if (tex != NULL) 
			{
				tex->UseType = usetype;
				if (usetype == FTexture::TEX_Flat) 
				{
					int w = tex->GetWidth();
					int h = tex->GetHeight();

					// Auto-scale flats with dimensions 128x128 and 256x256.
					// In hindsight, a bad idea, but RandomLag made it sound better than it really is.
					// Now we're stuck with this stupid behaviour.
					if (w==128 && h==128) 
					{
						tex->xScale = tex->yScale = 2*FRACUNIT;
						tex->bWorldPanning = true;
					}
					else if (w==256 && h==256) 
					{
						tex->xScale = tex->yScale = 4*FRACUNIT;
						tex->bWorldPanning = true;
					}
				}
				return tex;
			}
		}
	}
	return NULL;
}
Exemplo n.º 7
0
static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon)
{
	int trans;
	FTextureID picnum;

	// Powered up weapons and inherited sister weapons are not displayed.
	if (weapon->WeaponFlags & WIF_POWERED_UP) return;
	if (weapon->SisterWeapon && weapon->IsKindOf(RUNTIME_TYPE(weapon->SisterWeapon))) return;

	trans=0x6666;
	if (CPlayer->ReadyWeapon)
	{
		if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999;
	}

	FState * state=NULL, *ReadyState;
	
	FTextureID AltIcon = GetHUDIcon(weapon->GetClass());
	picnum = !AltIcon.isNull()? AltIcon : weapon->Icon;

	if (picnum.isNull())
	{
		if (weapon->SpawnState && weapon->SpawnState->sprite!=0)
		{
			state = weapon->SpawnState;
		}
		// no spawn state - now try the ready state
		else if ((ReadyState = weapon->FindState(NAME_Ready)) && ReadyState->sprite!=0)
		{
			state = ReadyState;
		}
		if (state &&  (unsigned)state->sprite < (unsigned)sprites.Size ())
		{
			spritedef_t * sprdef = &sprites[state->sprite];
			spriteframe_t * sprframe = &SpriteFrames[sprdef->spriteframes + state->GetFrame()];

			picnum = sprframe->Texture[0];
		}
	}

	if (picnum.isValid())
	{
		FTexture * tex = TexMan[picnum];
		int w = tex->GetWidth();
		int h = tex->GetHeight();
		int rh;
		if (w>h) rh=8;
		else rh=16,y-=8;		// don't draw tall sprites too small!
		DrawImageToBox(tex, x-24, y, 20, rh, trans);
		y-=10;
	}
}
Exemplo n.º 8
0
void FSingleLumpFont::CreateFontFromPic (int picnum)
{
	FTexture *pic = TexMan[picnum];

	FontHeight = pic->GetHeight ();
	SpaceWidth = pic->GetWidth ();
	GlobalKerning = 0;

	FirstChar = LastChar = 'A';
	Chars = new CharData[1];
	Chars->Pic = pic;

	// Only one color range. Don't bother with the others.
	ActiveColors = 0;
}
Exemplo n.º 9
0
	void DrawFullScreenStuff ()
	{
		// Draw health
		DrINumberOuter (CPlayer->health, 4, -10, false, 7);
		screen->DrawTexture (Images[imgMEDI], 14, -17,
			DTA_HUDRules, HUD_Normal,
			DTA_CenterBottomOffset, true,
			TAG_DONE);

		// Draw armor
		ABasicArmor *armor = CPlayer->mo->FindInventory<ABasicArmor>();
		if (armor != NULL && armor->Amount != 0)
		{
			DrINumberOuter (armor->Amount, 35, -10, false, 7);
			screen->DrawTexture (TexMan(armor->Icon), 45, -17,
				DTA_HUDRules, HUD_Normal,
				DTA_CenterBottomOffset, true,
				TAG_DONE);
		}

		// Draw ammo
		AAmmo *ammo1, *ammo2;
		int ammocount1, ammocount2;

		GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
		if (ammo1 != NULL)
		{
			// Draw primary ammo in the bottom-right corner
			DrINumberOuter (ammo1->Amount, -23, -10, false, 7);
			screen->DrawTexture (TexMan(ammo1->Icon), -14, -17,
				DTA_HUDRules, HUD_Normal,
				DTA_CenterBottomOffset, true,
				TAG_DONE);
			if (ammo2 != NULL)
			{
				// Draw secondary ammo just above the primary ammo
				DrINumberOuter (ammo2->Amount, -23, -48, false, 7);
				screen->DrawTexture (TexMan(ammo2->Icon), -14, -55,
					DTA_HUDRules, HUD_Normal,
					DTA_CenterBottomOffset, true,
					TAG_DONE);
			}
		}

		if (deathmatch)
		{ // Draw frags (in DM)
			DrBNumberOuterFont (CPlayer->fragcount, -44, 1);
		}

		// Draw inventory
		if (CPlayer->inventorytics == 0)
		{
			if (CPlayer->InvSel != 0)
			{
				if (ItemFlash > 0)
				{
					FTexture *cursor = Images[CursorImage];
					screen->DrawTexture (cursor, -28, -15,
						DTA_HUDRules, HUD_Normal,
						DTA_LeftOffset, cursor->GetWidth(),
						DTA_TopOffset, cursor->GetHeight(),
						DTA_Alpha, ItemFlash,
						TAG_DONE);
				}
				DrINumberOuter (CPlayer->InvSel->Amount, -51, -10, false, 7);
				screen->DrawTexture (TexMan(CPlayer->InvSel->Icon), -42, -17,
					DTA_HUDRules, HUD_Normal,
					DTA_CenterBottomOffset, true,
					TAG_DONE);
			}
		}
		else
		{
			CPlayer->InvFirst = ValidateInvFirst (6);
			int i = 0;
			AInventory *item;
			if (CPlayer->InvFirst != NULL)
			{
				for (item = CPlayer->InvFirst; item != NULL && i < 6; item = item->NextInv(), ++i)
				{
					if (item == CPlayer->InvSel)
					{
						screen->DrawTexture (Images[CursorImage], -100+i*35, -21,
							DTA_HUDRules, HUD_HorizCenter,
							DTA_Alpha, TRANSLUC75,
							TAG_DONE);
					}
					if (item->Icon != 0)
					{
						screen->DrawTexture (TexMan(item->Icon), -94 + i*35, -19,
							DTA_HUDRules, HUD_HorizCenter,
							TAG_DONE);
					}
					DrINumberOuter (item->Amount, -89 + i*35, -10, true, 7);
				}
			}
		}

		// Draw pop screen (log, keys, and status)
		if (CurrentPop != POP_None && PopHeight < 0)
		{
			DrawPopScreen (screen->GetHeight());
		}
	}
Exemplo n.º 10
0
void GL_RecalcLowerWall(seg_t *seg, sector_t *frontSector, gl_poly_t *poly)
{
   FTexture *tex = TexMan(seg->sidedef->bottomtexture);
   float txScale, tyScale, yOffset, xOffset, dist, texHeight;
   float v1[5], v2[5], v3[5], v4[5];
   float upperHeight, lowerHeight;
   texcoord_t ll, ul, lr, ur;
   sector_t *backSector, ts2;
   vertex_t *vert1, *vert2;
   fixed_t h1, h2;

   if (!poly->initialized) GL_InitPolygon(poly);
   poly->lastUpdate = frameStartMS;
   poly->initialized = true;

   vert1 = seg->v1;
   vert2 = seg->v2;
   dist = seg->length;

   backSector = R_FakeFlat(seg->backsector, &ts2, NULL, NULL, false);

   h1 = (backSector->floorplane.ZatPoint(vert1) - frontSector->floorplane.ZatPoint(vert1));
   h2 = (backSector->floorplane.ZatPoint(vert2) - frontSector->floorplane.ZatPoint(vert2));

   v1[0] = v3[0] = -vert1->x * MAP_SCALE;
   v1[2] = v3[2] = vert1->y * MAP_SCALE;
   v2[0] = v4[0] = -vert2->x * MAP_SCALE;
   v2[2] = v4[2] = vert2->y * MAP_SCALE;

   v1[1] = (float)frontSector->floorplane.ZatPoint(vert1);
   v2[1] = (float)frontSector->floorplane.ZatPoint(vert2);
   v3[1] = v1[1] + h1;
   v4[1] = v2[1] + h2;

   // texscale: 8 = 1.0, 16 = 2.0, 4 = 0.5
   txScale = tex->ScaleX ? tex->ScaleX / 8.f : 1.f;
   tyScale = tex->ScaleY ? tex->ScaleY / 8.f : 1.f;

   xOffset = (seg->offset * txScale) * INV_FRACUNIT;

   ll.x = xOffset / tex->GetWidth();
   ul.x = ll.x;
   lr.x = ll.x + (dist / tex->GetWidth() * txScale);
   ur.x = lr.x;

   ul.y = ur.y = 1.f;
   ll.y = lr.y = 0.f;

   if (tex)
   {
      texHeight = tex->GetHeight() / tyScale;

      lowerHeight = frontSector->floortexz * INV_FRACUNIT;
      upperHeight = backSector->floortexz * INV_FRACUNIT;

      if (seg->linedef->flags & ML_DONTPEGBOTTOM)
      {
         yOffset = (frontSector->ceilingtexz - backSector->floortexz) * INV_FRACUNIT;
      }
      else
      {
         yOffset = 0.f;
      }

      ul.y = ur.y = (yOffset + upperHeight - lowerHeight) / texHeight;
      ll.y = lr.y = yOffset / texHeight;

      // scale the coordinates
      //ul.y *= tyScale;
      //ur.y *= tyScale;
      //ll.y *= tyScale;
      //lr.y *= tyScale;

      // adjust for slopes
      ul.y -= ((v1[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ur.y -= ((v2[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ll.y += (upperHeight - (v3[1] * INV_FRACUNIT)) / texHeight;
      lr.y += (upperHeight - (v4[1] * INV_FRACUNIT)) / texHeight;
   }

   v1[1] *= MAP_SCALE;
   v2[1] *= MAP_SCALE;
   v3[1] *= MAP_SCALE;
   v4[1] *= MAP_SCALE;

   v1[3] = ul.x; v1[4] = ul.y;
   v2[3] = ur.x; v2[4] = ur.y;
   v3[3] = ll.x; v3[4] = ll.y;
   v4[3] = lr.x; v4[4] = lr.y;

   memcpy(poly->vertices + (0 * 3), v3, sizeof(float) * 3);
   memcpy(poly->vertices + (1 * 3), v1, sizeof(float) * 3);
   memcpy(poly->vertices + (2 * 3), v2, sizeof(float) * 3);
   memcpy(poly->vertices + (3 * 3), v4, sizeof(float) * 3);

   memcpy(poly->texCoords + (0 * 2), v3 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (1 * 2), v1 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (2 * 2), v2 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (3 * 2), v4 + 3, sizeof(float) * 2);
}
Exemplo n.º 11
0
void GL_RecalcMidWall(seg_t *seg, sector_t *frontSector, gl_poly_t *poly)
{
   float height1, height2, v1[5], v2[5], v3[5], v4[5], txScale, tyScale;
   float yOffset1, yOffset2, yOffset, xOffset;
   float upperHeight, lowerHeight;
   float tmpOffset = seg->sidedef->rowoffset * INV_FRACUNIT;
   long offset = 0;
   int texHeight;
   FTexture *tex = NULL;
   texcoord_t ll, ul, lr, ur;
   sector_t *backSector, ts2;
   vertex_t *vert1, *vert2;

   if (!poly->initialized) GL_InitPolygon(poly);
   poly->lastUpdate = frameStartMS;
   poly->initialized = true;

   tex = TexMan(seg->sidedef->midtexture);

   vert1 = seg->v1;
   vert2 = seg->v2;

   backSector = R_FakeFlat(seg->backsector, &ts2, NULL, NULL, false);

   v1[0] = -vert1->x * MAP_SCALE;
   v1[2] = vert1->y * MAP_SCALE;
   v2[0] = -vert2->x * MAP_SCALE;
   v2[2] = vert2->y * MAP_SCALE;
   v1[1] = (float)frontSector->floorplane.ZatPoint(seg->v1);
   v2[1] = (float)frontSector->floorplane.ZatPoint(seg->v2);

   if ((seg->linedef->special == Line_Mirror && seg->backsector == NULL) || tex == NULL)
   {
      if (backSector)
      {
         height1 = (float)backSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)backSector->ceilingplane.ZatPoint(vert2);
      }
      else
      {
         height1 = (float)frontSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)frontSector->ceilingplane.ZatPoint(vert2);
      }
   }
   else
   {
      //yOffset = seg->sidedef->rowoffset * INV_FRACUNIT;
      yOffset = 0.f;
      tmpOffset = 0.f;
      offset = seg->sidedef->rowoffset;
      yOffset1 = yOffset2 = yOffset;

      // texscale: 8 = 1.0, 16 = 2.0, 4 = 0.5
      txScale = tex->ScaleX ? tex->ScaleX / 8.f : 1.f;
      tyScale = tex->ScaleY ? tex->ScaleY / 8.f : 1.f;

      xOffset = (seg->offset * txScale) * INV_FRACUNIT;
   
      texHeight = (int)(tex->GetHeight() / tyScale);
      textureList.GetTexture(seg->sidedef->midtexture, true);

      ll.x = xOffset / tex->GetWidth();
      ul.x = ll.x;
      lr.x = ll.x + (seg->length / tex->GetWidth() * txScale);
      ur.x = lr.x;

      if (backSector)
      {
         height1 = (float)MIN(frontSector->ceilingplane.ZatPoint(vert1), backSector->ceilingplane.ZatPoint(vert1));
         height2 = (float)MIN(frontSector->ceilingplane.ZatPoint(vert2), backSector->ceilingplane.ZatPoint(vert2));
      }
      else
      {
         height1 = (float)frontSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)frontSector->ceilingplane.ZatPoint(vert2);
      }

      if (backSector && (textureList.IsTransparent() || seg->linedef->flags & ML_TWOSIDED))
      {
         int h = texHeight;

#if 0
         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            if (backSector)
            {
               v1[1] = MAX (frontSector->floortexz, backSector->floortexz) + offset;
               v2[1] = MAX (frontSector->floortexz, backSector->floortexz) + offset;
            }
            else
            {
               v1[1] = frontSector->floortexz + offset;
               v2[1] = frontSector->floortexz + offset;
            }
         }
         else
         {
            if (backSector)
            {
               v1[1] = MIN (frontSector->ceilingtexz, backSector->ceilingtexz) + offset - (h << FRACBITS);
               v2[1] = MIN (frontSector->ceilingtexz, backSector->ceilingtexz) + offset - (h << FRACBITS);
            }
            else
            {
               v1[1] = frontSector->ceilingtexz + offset - (h << FRACBITS);
               v2[1] = frontSector->ceilingtexz + offset - (h << FRACBITS);
            }
         }

         height1 = (h << FRACBITS) + v1[1];
         height2 = (h << FRACBITS) + v2[1];
#else
         float rbceil = (float)backSector->ceilingtexz,
				rbfloor = (float)backSector->floortexz,
				rfceil = (float)frontSector->ceilingtexz,
				rffloor = (float)frontSector->floortexz;
			float gaptop, gapbottom;

         yOffset = (float)seg->sidedef->rowoffset;
         height1 = gaptop = MIN(rbceil, rfceil);
         v1[1] = gapbottom = MAX(rbfloor, rffloor);

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            v1[1] += yOffset;
            height1 = v1[1] + (tex->GetHeight() * FRACUNIT);
         }
         else
         {
            height1 += yOffset;
            v1[1] = height1 - (tex->GetHeight() * FRACUNIT);
         }

         height2 = height1;
         v2[1] = v1[1];
#endif
      }
   }

   // make sure to clip the geometry to the back sector...
   if (backSector)
   {
      if (seg->sidedef->bottomtexture)
      {
         v1[1] = MAX(v1[1], backSector->floorplane.ZatPoint(seg->v1));
         v2[1] = MAX(v2[1], backSector->floorplane.ZatPoint(seg->v2));
      }
      if (seg->sidedef->toptexture)
      {
         height1 = MIN(height1, backSector->ceilingplane.ZatPoint(seg->v1));
         height2 = MIN(height2, backSector->ceilingplane.ZatPoint(seg->v2));
      }
   }

   memcpy(v3, v1, sizeof(float) * 3);
   memcpy(v4, v2, sizeof(float) * 3);

   ul.y = ur.y = 1.f;
   ll.y = lr.y = 0.f;

   if (tex)
   {
      yOffset = 0.f;

      // code borrowed from Legacy ;)
      // damn pegged/unpegged/two sided lines!
      if (backSector)
      {
         float worldHigh = backSector->ceilingtexz * INV_FRACUNIT;
         float worldLow = backSector->floortexz * INV_FRACUNIT;
         float polyBottom, polyTop;

         lowerHeight = frontSector->floortexz * INV_FRACUNIT;
         upperHeight = frontSector->ceilingtexz * INV_FRACUNIT;

         float openTop = upperHeight < worldHigh ? upperHeight : worldHigh;
         float openBottom = lowerHeight > worldLow ? lowerHeight : worldLow;

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            polyBottom = openBottom + seg->sidedef->rowoffset * INV_FRACUNIT;
            polyTop = polyBottom + texHeight;

            upperHeight = MIN(openTop, polyTop);
            lowerHeight = MAX(openBottom, polyBottom);

            yOffset = lowerHeight + texHeight - upperHeight + polyBottom - lowerHeight;
         }
         else
         {
            polyTop = openTop + seg->sidedef->rowoffset * INV_FRACUNIT;
            polyBottom = polyTop - texHeight;

            yOffset = polyTop - upperHeight;
         }
      }
      else
      {
         lowerHeight = frontSector->floortexz * INV_FRACUNIT;
         upperHeight = frontSector->ceilingtexz * INV_FRACUNIT;
         yOffset = 0.f;

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            yOffset += lowerHeight + texHeight - upperHeight;
         }
      }

      ll.y = lr.y = yOffset / texHeight;
      ul.y = ur.y = ll.y + ((upperHeight - lowerHeight) / texHeight);

      // scale the coordinates
      //ul.y *= tyScale;
      //ur.y *= tyScale;
      //ll.y *= tyScale;
      //lr.y *= tyScale;

      // clip to slopes
      ul.y -= ((v1[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ur.y -= ((v2[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ll.y += (upperHeight - (height1 * INV_FRACUNIT)) / texHeight;
      lr.y += (upperHeight - (height2 * INV_FRACUNIT)) / texHeight;
   }

   v1[1] *= MAP_SCALE;
   v2[1] *= MAP_SCALE;
   v3[1] = height1 * MAP_SCALE;
   v4[1] = height2 * MAP_SCALE;

   v1[3] = ul.x; v1[4] = ul.y;
   v2[3] = ur.x; v2[4] = ur.y;
   v3[3] = ll.x; v3[4] = ll.y;
   v4[3] = lr.x; v4[4] = lr.y;

   memcpy(poly->vertices + (0 * 3), v3, sizeof(float) * 3);
   memcpy(poly->vertices + (1 * 3), v1, sizeof(float) * 3);
   memcpy(poly->vertices + (2 * 3), v2, sizeof(float) * 3);
   memcpy(poly->vertices + (3 * 3), v4, sizeof(float) * 3);

   memcpy(poly->texCoords + (0 * 2), v3 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (1 * 2), v1 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (2 * 2), v2 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (3 * 2), v4 + 3, sizeof(float) * 2);
}
Exemplo n.º 12
0
void GL_DrawSky()
{
   float angle;
   FTexture *tex;
   bool drawBoth = false;

   int sky1tex, sky2tex;
   int s1p, s2p;

   drawBoth = !((level.flags & LEVEL_SWAPSKIES) || (sky2texture == sky1texture));

	if ((level.flags & LEVEL_SWAPSKIES) || (sky2texture == sky1texture))
	{
		sky1tex = sky2texture;
      s1p = sky2pos;
		sky2tex = sky1texture;
      s2p = sky1pos;
	}
	else
	{
		sky1tex = sky1texture;
      s1p = sky1pos;
		sky2tex = sky2texture;
      s2p = sky2pos;
	}

   glDepthMask(GL_FALSE);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_FOG);
   glDisable(GL_ALPHA_TEST);

   glPushMatrix();

   angle = s2p * 1.f / (FRACUNIT * 2.f);
   glRotatef(-angle, 0.f, 1.f, 0.f);

   textureList.BindTexture(sky2tex, true);
   tex = TexMan(sky2tex);
   texw = tex->GetWidth();
   texh = tex->GetHeight();
   tx = ty = 1.f;
   yMult = 1.f;

   GL_RenderSkyHemisphere(SKYHEMI_UPPER);
   GL_RenderSkyHemisphere(SKYHEMI_LOWER);

   if (drawBoth)
   {
      angle = (s1p * 1.f / (FRACUNIT * 2.f)) - angle;
      glRotatef(-angle, 0.f, 1.f, 0.f);
      tex = TexMan(sky1tex);
      textureList.BindTexture(sky1tex, true);
      texw = tex->GetWidth();
      texh = tex->GetHeight();
      if (level.flags & LEVEL_DOUBLESKY && texh <= 128)
      {
         yMult = 2.f;
      }
      tx = ty = 1.f;
      GL_RenderSkyHemisphere(SKYHEMI_UPPER);
      GL_RenderSkyHemisphere(SKYHEMI_LOWER);
   }

   glPopMatrix();

   glEnable(GL_DEPTH_TEST);
   glEnable(GL_ALPHA_TEST);
   glFogf(GL_FOG_MODE, GL_EXP);
   glDepthMask(GL_TRUE);
   if (gl_depthfog && !Player->fixedcolormap)
   {
      glEnable(GL_FOG);
   }
}
Exemplo n.º 13
0
	void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass)
	{
		DVector2 decal_left, decal_right, decal_pos;
		int x1, x2;
		double yscale;
		uint8_t flipx;
		double zpos;
		int needrepeat = 0;
		sector_t *back;
		bool calclighting;
		bool rereadcolormap;
		FDynamicColormap *usecolormap;
		float light = 0;
		const short *mfloorclip;
		const short *mceilingclip;

		if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
			return;

		// Determine actor z
		zpos = decal->Z;
		back = (curline->backsector != NULL) ? curline->backsector : curline->frontsector;

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

		switch (decal->RenderFlags & RF_RELMASK)
		{
		default:
			zpos = decal->Z;
			break;
		case RF_RELUPPER:
			if (curline->linedef->flags & ML_DONTPEGTOP)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
			else
			{
				zpos = decal->Z + back->GetPlaneTexZ(sector_t::ceiling);
			}
			break;
		case RF_RELLOWER:
			if (curline->linedef->flags & ML_DONTPEGBOTTOM)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
			else
			{
				zpos = decal->Z + back->GetPlaneTexZ(sector_t::floor);
			}
			break;
		case RF_RELMID:
			if (curline->linedef->flags & ML_DONTPEGBOTTOM)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::floor);
			}
			else
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
		}

		FTexture *WallSpriteTile = TexMan(decal->PicNum, true);
		flipx = (uint8_t)(decal->RenderFlags & RF_XFLIP);

		if (WallSpriteTile == NULL || WallSpriteTile->UseType == ETextureType::Null)
		{
			return;
		}

		// Determine left and right edges of sprite. Since this sprite is bound
		// to a wall, we use the wall's angle instead of the decal's. This is
		// pretty much the same as what R_AddLine() does.

		double edge_right = WallSpriteTile->GetWidth();
		double edge_left = WallSpriteTile->GetLeftOffset(0);	// decals should not use renderer-specific offsets.
		edge_right = (edge_right - edge_left) * decal->ScaleX;
		edge_left *= decal->ScaleX;

		double dcx, dcy;
		decal->GetXY(wall, dcx, dcy);
		decal_pos = { dcx, dcy };

		DVector2 angvec = (curline->v2->fPos() - curline->v1->fPos()).Unit();
		float maskedScaleY;

		decal_left = decal_pos - edge_left * angvec - thread->Viewport->viewpoint.Pos;
		decal_right = decal_pos + edge_right * angvec - thread->Viewport->viewpoint.Pos;

		CameraLight *cameraLight;
		double texturemid;

		FWallCoords WallC;
		if (WallC.Init(thread, decal_left, decal_right, TOO_CLOSE_Z))
			return;

		x1 = WallC.sx1;
		x2 = WallC.sx2;

		if (x1 >= clipper->x2 || x2 <= clipper->x1)
			return;

		FWallTmapVals WallT;
		WallT.InitFromWallCoords(thread, &WallC);

		if (drawsegPass)
		{
			uint32_t clipMode = decal->RenderFlags & RF_CLIPMASK;
			if (clipMode != RF_CLIPMID && clipMode != RF_CLIPFULL)
				return;

			// Clip decal to stay within the draw segment wall
			mceilingclip = walltop;
			mfloorclip = wallbottom;

			// Rumor has it that if RT_CLIPMASK is specified then the decal should be clipped according
			// to the full drawsegment visibility, as implemented in the remarked section below.
			//
			// This is problematic because not all 3d floors may have been drawn yet at this point. The
			// code below might work ok for cases where there is only one 3d floor.

			/*if (clipMode == RF_CLIPFULL)
			{
				mceilingclip = clipper->sprtopclip - clipper->x1;
				mfloorclip = clipper->sprbottomclip - clipper->x1;
			}*/
		}
		else
		{
			// Get the top and bottom clipping arrays
			switch (decal->RenderFlags & RF_CLIPMASK)
			{
			default:
				// keep GCC quiet.
				return;

			case RF_CLIPFULL:
				if (curline->backsector == NULL)
				{
					mceilingclip = walltop;
					mfloorclip = wallbottom;
				}
				else
				{
					mceilingclip = walltop;
					mfloorclip = thread->OpaquePass->ceilingclip;
					needrepeat = 1;
				}
				break;

			case RF_CLIPUPPER:
				mceilingclip = walltop;
				mfloorclip = thread->OpaquePass->ceilingclip;
				break;

			case RF_CLIPMID:
				return;

			case RF_CLIPLOWER:
				mceilingclip = thread->OpaquePass->floorclip;
				mfloorclip = wallbottom;
				break;
			}
		}

		yscale = decal->ScaleY;
		texturemid = WallSpriteTile->GetTopOffset(0) + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale;

		// Clip sprite to drawseg
		x1 = MAX<int>(clipper->x1, x1);
		x2 = MIN<int>(clipper->x2, x2);
		if (x1 >= x2)
		{
			return;
		}

		ProjectedWallTexcoords walltexcoords;
		walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT);

		if (flipx)
		{
			int i;
			int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1;

			for (i = x1; i < x2; i++)
			{
				walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
			}
		}

		// Prepare lighting
		calclighting = false;
		usecolormap = basecolormap;
		rereadcolormap = true;

		// Decals that are added to the scene must fade to black.
		if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
		{
			usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
			rereadcolormap = false;
		}

		light = lightleft + (x1 - savecoord.sx1) * lightstep;

		cameraLight = CameraLight::Instance();

		// Draw it
		bool sprflipvert;
		if (decal->RenderFlags & RF_YFLIP)
		{
			sprflipvert = true;
			yscale = -yscale;
			texturemid -= WallSpriteTile->GetHeight();
		}
		else
		{
			sprflipvert = false;
		}

		maskedScaleY = float(1 / yscale);
		do
		{
			int x = x1;

			SpriteDrawerArgs drawerargs;

			if (cameraLight->FixedLightLevel() >= 0)
				drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, cameraLight->FixedLightLevelShade());
			else if (cameraLight->FixedColormap() != NULL)
				drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
			else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
				drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
			else
				calclighting = true;

			bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, basecolormap);

			// R_SetPatchStyle can modify basecolormap.
			if (rereadcolormap)
			{
				usecolormap = basecolormap;
			}

			if (visible)
			{
				thread->PrepareTexture(WallSpriteTile, decal->RenderStyle);
				while (x < x2)
				{
					if (calclighting)
					{ // calculate lighting
						drawerargs.SetLight(usecolormap, light, wallshade);
					}
					DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
					light += lightstep;
					x++;
				}
			}

			// If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will
			// be set 1 if we need to draw on the lower wall. In all other cases,
			// needrepeat will be 0, and the while will fail.
			mceilingclip = thread->OpaquePass->floorclip;
			mfloorclip = wallbottom;
		} while (needrepeat--);
	}