示例#1
0
//==========================================================================
//
//  Upper Skies on two sided walls
//
//==========================================================================
void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
{
	if (fs->GetTexture(sector_t::ceiling)==skyflatnum)
	{
		if ((bs->special&0xff) == NoSkyDraw) return;
		if (bs->GetTexture(sector_t::ceiling)==skyflatnum) 
		{
			// if the back sector is closed the sky must be drawn!
			if (bs->ceilingplane.ZatPoint(v1) > bs->floorplane.ZatPoint(v1) ||
				bs->ceilingplane.ZatPoint(v2) > bs->floorplane.ZatPoint(v2) || bs->transdoor)
					return;

			// one more check for some ugly transparent door hacks
			if (bs->floorplane.a==0 && bs->floorplane.b==0 && fs->floorplane.a==0 && fs->floorplane.b==0 &&
				bs->GetPlaneTexZ(sector_t::floor)==fs->GetPlaneTexZ(sector_t::floor)+FRACUNIT)
			{
				FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom));
				if (!tex || tex->UseType==FTexture::TEX_Null) return;
			}
		}

		ztop[0]=ztop[1]=32768.0f;

		FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::top));
		if (/*tex && tex->UseType!=FTexture::TEX_Null &&*/ bs->GetTexture(sector_t::ceiling) != skyflatnum)

		{
			zbottom[0]=zceil[0];
			zbottom[1]=zceil[1];
		}
		else
		{
			zbottom[0]=TO_GL(bs->ceilingplane.ZatPoint(v1));
			zbottom[1]=TO_GL(bs->ceilingplane.ZatPoint(v2));
			flags|=GLWF_SKYHACK;	// mid textures on such lines need special treatment!
		}

		SkyTexture(fs->sky,fs->CeilingSkyBox, true);
	}
	else 
	{
		bool ceilingsky = (fs->CeilingSkyBox && fs->CeilingSkyBox->bAlways && fs->CeilingSkyBox!=bs->CeilingSkyBox); 
		if (ceilingsky || fs->ceiling_reflect)
		{
			// stacked sectors
			fixed_t fsc1=fs->ceilingplane.ZatPoint(v1);
			fixed_t fsc2=fs->ceilingplane.ZatPoint(v2);

			ztop[0]=ztop[1]=32768.0f;
			zbottom[0]=TO_GL(fsc1);
			zbottom[1]=TO_GL(fsc2);
			if (ceilingsky)	SkyTexture(fs->sky,fs->CeilingSkyBox, true);
			else MirrorPlane(&fs->ceilingplane, true);
		}
	}
}
示例#2
0
static bool ShowText(const FString exitText, const FString flat, const FString music, ClusterInfo::ExitType type)
{
    // Use cluster background if set.
    if(!flat.IsEmpty())
        backgroundFlat = TexMan(flat);
    if(!backgroundFlat) // Get default if needed
        backgroundFlat = TexMan(gameinfo.FinaleFlat);

    switch(type)
    {
    case ClusterInfo::EXIT_MESSAGE:
        SD_PlaySound ("misc/1up");

        Message (exitText);

        IN_ClearKeysDown ();
        IN_Ack ();
        return false;

    case ClusterInfo::EXIT_LUMP:
    {
        int lumpNum = Wads.CheckNumForName(exitText, ns_global);
        if(lumpNum != -1)
        {
            FWadLump lump = Wads.OpenLumpNum(lumpNum);
            char* text = new char[Wads.LumpLength(lumpNum)];
            lump.Read(text, Wads.LumpLength(lumpNum));

            if(!music.IsEmpty())
                StartCPMusic(music);
            ShowArticle(text, !!(IWad::GetGame().Flags & IWad::HELPHACK));

            delete[] text;
        }

        break;
    }

    default:
        if(!music.IsEmpty())
            StartCPMusic(music);
        ShowArticle(exitText, !!(IWad::GetGame().Flags & IWad::HELPHACK));
        break;
    }

    IN_ClearKeysDown();
    if (MousePresent && IN_IsInputGrabbed())
        IN_CenterMouse();  // Clear accumulated mouse movement
    return true;
}
示例#3
0
FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX)
{
	const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
	flipX = false;

	if (thing->renderflags & RF_FLATSPRITE)
		return nullptr;	// do not draw flat sprites.

	if (thing->picnum.isValid())
	{
		FTexture *tex = TexMan(thing->picnum);
		if (tex->UseType == ETextureType::Null)
		{
			return nullptr;
		}

		if (tex->Rotations != 0xFFFF)
		{
			// choose a different rotation based on player view
			spriteframe_t *sprframe = &SpriteFrames[tex->Rotations];
			DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac);
			pos.Z += thing->GetBobOffset(viewpoint.TicFrac);
			DAngle ang = (pos - viewpoint.Pos).Angle();
			angle_t rot;
			if (sprframe->Texture[0] == sprframe->Texture[1])
			{
				rot = (ang - thing->Angles.Yaw + 45.0 / 2 * 9).BAMs() >> 28;
			}
示例#4
0
static void ClearStatusbar()
{
	DrawPlayScreen();

	FTexture *borderTex = TexMan(levelInfo->GetBorderTexture());
	VWB_DrawFill(borderTex, statusbarx, statusbary2+CleanYfac, screenWidth-statusbarx, screenHeight);
}
示例#5
0
void WI_slamBackground ()
{
	if (background)
	{
		screen->DrawTexture (background, 0, 0,
			DTA_VirtualWidth, background->GetWidth(),
			DTA_VirtualHeight, background->GetHeight(),
			DTA_Masked, false,
			TAG_DONE);
		screen->FillBorder (NULL);
		if (DrawFoM)
		{
			screen->DrawTexture (anims[1][7].p[2], anims[1][7].loc.x, anims[1][7].loc.y, DTA_320x200, true, TAG_DONE);
		}
	}
	else if (state != NoState)
	{
		int picnum = TexMan.CheckForTexture ("FLOOR16", FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
		if (picnum >= 0)
		{
			screen->FlatFill (0, 0, SCREENWIDTH, SCREENHEIGHT, TexMan(picnum));
		}
		else
		{
			screen->Clear (0, 0, SCREENWIDTH, SCREENHEIGHT, 0);
		}
	}
}
示例#6
0
FTexture *FImageCollection::operator[] (int index) const
{
	if ((unsigned int)index >= ImageMap.Size())
	{
		return NULL;
	}
	return ImageMap[index].Exists()? TexMan(ImageMap[index]) : NULL;
}
示例#7
0
//==========================================================================
//
//  Lower Skies on two sided walls
//
//==========================================================================
void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
{
	if (fs->GetTexture(sector_t::floor)==skyflatnum)
	{
		if ((bs->special&0xff) == NoSkyDraw) return;
		FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom));
		
		// For lower skies the normal logic only applies to walls with no lower texture!
		if (tex->UseType==FTexture::TEX_Null)
		{
			if (bs->GetTexture(sector_t::floor)==skyflatnum)
			{
				// if the back sector is closed the sky must be drawn!
				if (bs->ceilingplane.ZatPoint(v1) > bs->floorplane.ZatPoint(v1) ||
					bs->ceilingplane.ZatPoint(v2) > bs->floorplane.ZatPoint(v2))
						return;

			}
			else
			{
				// Special hack for Vrack2b
				if (bs->floorplane.ZatPoint(viewx, viewy) > viewz) return;
			}
		}
		zbottom[0]=zbottom[1]=-32768.0f;

		if ((tex && tex->UseType!=FTexture::TEX_Null) || bs->GetTexture(sector_t::floor)!=skyflatnum)
		{
			ztop[0]=zfloor[0];
			ztop[1]=zfloor[1];
		}
		else
		{
			ztop[0]=TO_GL(bs->floorplane.ZatPoint(v1));
			ztop[1]=TO_GL(bs->floorplane.ZatPoint(v2));
			flags|=GLWF_SKYHACK;	// mid textures on such lines need special treatment!
		}

		SkyTexture(fs->sky,fs->FloorSkyBox, false);
	}
	else 
	{
		bool floorsky = (fs->FloorSkyBox && fs->FloorSkyBox->bAlways && fs->FloorSkyBox!=bs->FloorSkyBox);
		if (floorsky || fs->floor_reflect)
		{
			// stacked sectors
			fixed_t fsc1=fs->floorplane.ZatPoint(v1);
			fixed_t fsc2=fs->floorplane.ZatPoint(v2);

			zbottom[0]=zbottom[1]=-32768.0f;
			ztop[0]=TO_GL(fsc1);
			ztop[1]=TO_GL(fsc2);

			if (floorsky) SkyTexture(fs->sky,fs->FloorSkyBox, false);
			else MirrorPlane(&fs->floorplane, false);
		}
	}
}
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, F3DFloor *fakeFloor)
{
	FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
	FTexture *tex = TexMan(picnum);
	if (tex->UseType == FTexture::TEX_Null)
		return;

	int lightlevel = 255;
	if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
	{
		lightlist_t *light = P_GetPlaneLight(sub->sector, &sub->sector->ceilingplane, false);
		basecolormap = light->extra_colormap;
		lightlevel = *light->p_lightlevel;
	}

	TriUniforms uniforms;
	uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f);
	if (fixedlightlev >= 0 || fixedcolormap)
		uniforms.light = 256;
	uniforms.flags = 0;
	uniforms.subsectorDepth = subsectorDepth;

	TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
	if (!vertices)
		return;

	if (ceiling)
	{
		for (uint32_t i = 0; i < sub->numlines; i++)
		{
			seg_t *line = &sub->firstline[i];
			vertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, fakeFloor->bottom.plane->ZatPoint(line->v1));
		}
	}
	else
	{
		for (uint32_t i = 0; i < sub->numlines; i++)
		{
			seg_t *line = &sub->firstline[i];
			vertices[i] = PlaneVertex(line->v1, fakeFloor->top.plane->ZatPoint(line->v1));
		}
	}

	PolyDrawArgs args;
	args.uniforms = uniforms;
	args.objectToClip = &worldToClip;
	args.vinput = vertices;
	args.vcount = sub->numlines;
	args.mode = TriangleDrawMode::Fan;
	args.ccw = true;
	args.stenciltestvalue = 0;
	args.stencilwritevalue = 1;
	args.SetTexture(tex);
	args.SetColormap(sub->sector->ColorMap);
	PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
	PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
}
示例#9
0
/*
=================
=
= HelpScreens
=
=================
*/
void HelpScreens (void)
{
    int lumpNum = Wads.CheckNumForName("HELPART", ns_global);
    if(lumpNum != -1)
    {
        FMemLump lump = Wads.ReadLump(lumpNum);

        backgroundFlat = TexMan(gameinfo.FinaleFlat);
        ShowArticle((char*)lump.GetMem());
    }

    VW_FadeOut();
}
示例#10
0
void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked)
{
	if (pl->left >= pl->right)
		return;

	if (r_drawflat)
	{ // [RH] no texture mapping
		ds_color += 4;
		R_MapVisPlane (pl, R_MapColoredPlane);
	}
	else if (pl->picnum == skyflatnum)
	{ // sky flat
		R_DrawSkyPlane (pl);
	}
	else
	{ // regular flat
		FTexture *tex = TexMan(pl->picnum, true);

		if (tex->UseType == FTexture::TEX_Null)
		{
			return;
		}

		if (!masked && !additive)
		{ // If we're not supposed to see through this plane, draw it opaque.
			alpha = OPAQUE;
		}
		else if (!tex->bMasked)
		{ // Don't waste time on a masked texture if it isn't really masked.
			masked = false;
		}
		R_SetupSpanBits(tex);
		double xscale = pl->xform.xScale * tex->Scale.X;
		double yscale = pl->xform.yScale * tex->Scale.Y;
		R_SetSpanSource(tex);

		basecolormap = pl->colormap;
		planeshade = LIGHT2SHADE(pl->lightlevel);

		if (r_drawflat || (!pl->height.isSlope() && !tilt))
		{
			R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked);
		}
		else
		{
			R_DrawTiltedPlane(pl, xscale, yscale, alpha, additive, masked);
		}
	}
	NetUpdate ();
}
示例#11
0
void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation)
{
	if (frameno>=numFrames || frameno2>=numFrames) return;

	gl_RenderState.SetInterpolationFactor((float)inter);
	for(int i=0;i<numSurfaces;i++)
	{
		MD3Surface * surf = &surfaces[i];

		// [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface.
		// Note: Each surface may have a different skin.
		FTexture *surfaceSkin = skin;
		if (!surfaceSkin)
		{
			if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
			{
				surfaceSkin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i]);
			}
			else if(surf->numSkins > 0 && surf->skins[0].isValid())
			{
				surfaceSkin = TexMan(surf->skins[0]);
			}

			if (!surfaceSkin) return;
		}

		FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false);

		gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false);

		gl_RenderState.Apply();
		if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex);
		mVBuf->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices);
		glDrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, (void*)(intptr_t)(surf->iindex * sizeof(unsigned int)));
	}
	gl_RenderState.SetInterpolationFactor(0.f);
}
示例#12
0
void DIntermissionScreenCast::Drawer ()
{
	spriteframe_t*		sprframe;
	FTexture*			pic;

	Super::Drawer();

	const char *name = mName;
	if (name != NULL)
	{
		if (*name == '$') name = GStrings(name+1);
		screen->DrawText (SmallFont, CR_UNTRANSLATED,
			(SCREENWIDTH - SmallFont->StringWidth (name) * CleanXfac)/2,
			(SCREENHEIGHT * 180) / 200,
			name,
			DTA_CleanNoMove, true, TAG_DONE);
	}

	// draw the current frame in the middle of the screen
	if (caststate != NULL)
	{
		int castsprite = caststate->sprite;

		if (!(mDefaults->flags4 & MF4_NOSKIN) &&
			mDefaults->SpawnState != NULL && caststate->sprite == mDefaults->SpawnState->sprite &&
			mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)) &&
			skins != NULL)
		{
			// Only use the skin sprite if this class has not been removed from the
			// PlayerClasses list.
			for (unsigned i = 0; i < PlayerClasses.Size(); ++i)
			{
				if (PlayerClasses[i].Type == mClass)
				{
					castsprite = skins[players[consoleplayer].userinfo.GetSkin()].sprite;
				}
			}
		}

		sprframe = &SpriteFrames[sprites[castsprite].spriteframes + caststate->GetFrame()];
		pic = TexMan(sprframe->Texture[0]);

		screen->DrawTexture (pic, 160, 170,
			DTA_320x200, true,
			DTA_FlipX, sprframe->Flip & 1,
			DTA_Translation, casttranslation,
			TAG_DONE);
	}
}
示例#13
0
bool APowerup::DrawPowerup (int x, int y)
{
	if (!Icon.isValid())
	{
		return false;
	}
	if (EffectTics > BLINKTHRESHOLD || !(EffectTics & 16))
	{
		FTexture *pic = TexMan(Icon);
		screen->DrawTexture (pic, x, y,
			DTA_HUDRules, HUD_Normal,
//			DTA_TopOffset, pic->GetHeight()/2,
//			DTA_LeftOffset, pic->GetWidth()/2,
			TAG_DONE);
	}
	return true;
}
示例#14
0
void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight)
{
	const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;

	FTextureID picnum = fakeflat.FrontSector->GetTexture(ceiling ? sector_t::ceiling : sector_t::floor);
	if (picnum != skyflatnum)
	{
		FTexture *tex = TexMan(picnum);
		if (!tex || tex->UseType == FTexture::TEX_Null)
			return;

		PolyPlaneUVTransform transform = PolyPlaneUVTransform(ceiling ? fakeflat.FrontSector->planes[sector_t::ceiling].xform : fakeflat.FrontSector->planes[sector_t::floor].xform, tex);
		TriVertex *vertices = CreatePlaneVertices(thread, fakeflat.Subsector, transform, ceiling ? fakeflat.FrontSector->ceilingplane : fakeflat.FrontSector->floorplane);

		PolyDrawArgs args;
		SetLightLevel(thread, args, fakeflat, ceiling);
		SetDynLights(thread, args, fakeflat.Subsector, ceiling);
		args.SetTransform(&worldToClip);
		args.SetFaceCullCCW(true);
		args.SetStencilTestValue(stencilValue);
		args.SetWriteStencil(true, stencilValue + 1);
		args.SetClipPlane(0, clipPlane);
		args.SetTexture(tex);
		args.SetStyle(TriBlendMode::TextureOpaque);
		args.DrawArray(thread, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan);
	}
	else
	{
		TriVertex *vertices = CreateSkyPlaneVertices(thread, fakeflat.Subsector, skyHeight);

		PolyDrawArgs args;
		args.SetTransform(&worldToClip);
		args.SetFaceCullCCW(true);
		args.SetStencilTestValue(stencilValue);
		args.SetWriteStencil(true, stencilValue + 1);
		args.SetClipPlane(0, clipPlane);
		args.SetWriteStencil(true, 255);
		args.SetWriteColor(false);
		args.SetWriteDepth(false);
		args.DrawArray(thread, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan);

		RenderSkyWalls(thread, args, fakeflat.Subsector, nullptr, ceiling, skyHeight);
	}
}
示例#15
0
文件: menu.cpp 项目: nano-bot/zdoom
void DMenu::Drawer ()
{
    if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse)
    {
        FTexture *tex = TexMan(gameinfo.mBackButton);
        int w = tex->GetScaledWidth() * CleanXfac;
        int h = tex->GetScaledHeight() * CleanYfac;
        int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w;
        int y = (!(m_show_backbutton&2))? 0:screen->GetHeight() - h;
        if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1))
        {
            screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE);
        }
        else
        {
            screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_AlphaF, BackbuttonAlpha, TAG_DONE);
        }
    }
}
示例#16
0
void FMaterial::Bind(int clampmode, int translation)
{
	// avoid rebinding the same texture multiple times.
	if (this == last && lastclamp == clampmode && translation == lasttrans) return;
	last = this;
	lastclamp = clampmode;
	lasttrans = translation;

	int usebright = false;
	int maxbound = 0;
	bool allowhires = tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY && !mExpanded;

	if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX;
	else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;

	const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL);
	if (gltexture != NULL)
	{
		for(unsigned i=0;i<mTextureLayers.Size();i++)
		{
			FTexture *layer;
			if (mTextureLayers[i].animated)
			{
				FTextureID id = mTextureLayers[i].texture->id;
				layer = TexMan(id);
				ValidateSysTexture(layer, mExpanded);
			}
			else
			{
				layer = mTextureLayers[i].texture;
			}
			layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL);
			maxbound = i+1;
		}
	}
	// unbind everything from the last texture that's still active
	for(int i=maxbound+1; i<=mMaxBound;i++)
	{
		FHardwareTexture::Unbind(i);
		mMaxBound = maxbound;
	}
}
示例#17
0
void TimedPicCommand (bool helphack)
{
    ParseTimedCommand (helphack);

    //
    // update the screen, and wait for time delay
    //
    VW_UpdateScreen ();

    //
    // wait for time
    //
    Delay(picdelay);

    //
    // draw pic
    //
    if(picnum.isValid())
        VWB_DrawGraphic (TexMan(picnum), picx&~7, picy, MENU_CENTER);
}
示例#18
0
文件: menu.cpp 项目: nano-bot/zdoom
bool DMenu::MouseEventBack(int type, int x, int y)
{
    if (m_show_backbutton >= 0)
    {
        FTexture *tex = TexMan(gameinfo.mBackButton);
        if (tex != NULL)
        {
            if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac;
            if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac;
            mBackbuttonSelected = ( x >= 0 && x < tex->GetScaledWidth() * CleanXfac &&
                                    y >= 0 && y < tex->GetScaledHeight() * CleanYfac);
            if (mBackbuttonSelected && type == MOUSE_Release)
            {
                if (m_use_mouse == 2) mBackbuttonSelected = false;
                MenuEvent(MKEY_Back, true);
            }
            return mBackbuttonSelected;
        }
    }
    return false;
}
示例#19
0
void WI_DrawDoomBack ()
{
	char name[9];

	if ((gamemode == commercial) ||
		(gamemode == retail && epsd >= 3))
		strcpy (name, "INTERPIC");
	else 
		sprintf (name, "WIMAP%d", epsd);

	// background
	background = TexMan (name);
	if (FindLevelInfo ("E2M9")->flags & LEVEL_VISITED && epsd == 1)
	{ // [RH] Add the Fortress of Mystery if it has been visited
		DrawFoM = true;
		// anims[1][7].data = 800;	// Don't animate it again if the user uses changemap E2M9
	}
	else
	{
		DrawFoM = false;
		anims[1][7].data = 8;
	}
}
示例#20
0
void GL_RecalcSubsector(subsector_t *subSec, sector_t *sector)
{
   seg_t *seg;
   int polyIndex = subSec->index * 2;
   unsigned long i, vindex, tindex, firstLine, maxLine;
   gl_poly_t *poly1, *poly2;
   float sox, soy, fsx, fsy, csx, csy;
   FTexture *ctex, *ftex;
   bool recalc;

   firstLine = subSec->firstline;
   maxLine = firstLine + subSec->numlines;
   poly1 = &gl_polys[polyIndex];
   poly2 = &gl_polys[polyIndex + 1];

   recalc = GL_ShouldRecalcPoly(poly1, sector) || GL_ShouldRecalcPoly(poly2, sector);

   if (!recalc)
   {
      // just check the segs for changed textures
      for (i = firstLine; i < maxLine; i++)
      {
         seg = segs + i;

         if (seg->linedef && (GL_SegGeometryChanged(seg) || GL_SegTextureChanged(seg)))
         {
            GL_RecalcSeg(seg, sector);
         }
      }

      if (subSec->poly)
      {
         maxLine = subSec->poly->numsegs;
         for (i = 0; i < maxLine; i++)
         {
            seg = subSec->poly->segs[i];
            GL_RecalcSeg(seg, sector); // always recalc polyobjects for now
         }
      }

      return;
   }

   // recalc all the geometry in the subsector since the either the floor or ceiling sector has moved

   if (!poly1->initialized) GL_InitPolygon(poly1);
   if (!poly2->initialized) GL_InitPolygon(poly2);

   poly1->lastUpdate = frameStartMS;
   poly2->lastUpdate = frameStartMS;

   // sector offsets so rotations happen around sector center
   sox = -subSec->sector->CenterX * MAP_SCALE;
   soy = subSec->sector->CenterY * MAP_SCALE;

   ctex = TexMan(sector->ceilingpic);
   ftex = TexMan(sector->floorpic);
   fsx = fsy = csx = csy = 1.f;

   if (ftex->ScaleX) fsx = 8.f / ftex->ScaleX;
   if (ftex->ScaleY) fsy = 8.f / ftex->ScaleY;
   if (ctex->ScaleX) csx = 8.f / ctex->ScaleX;
   if (ctex->ScaleY) csy = 8.f / ctex->ScaleY;

   for (i = firstLine; i < maxLine; i++)
   {
      seg = segs + i;

      vindex = (maxLine - 1 - i) * 3;
      tindex = (maxLine - 1 - i) * 2;

      poly1->vertices[vindex + 0] = -seg->v2->x * MAP_SCALE;
      poly1->vertices[vindex + 1] = sector->floorplane.ZatPoint(seg->v2) * MAP_SCALE;
      poly1->vertices[vindex + 2] = seg->v2->y * MAP_SCALE;
      poly1->texCoords[tindex + 0] = -poly1->vertices[vindex + 0] / (ftex->GetWidth() * fsx) * MAP_COEFF;
      poly1->texCoords[tindex + 1] = -poly1->vertices[vindex + 2] / (ftex->GetHeight() * fsy) * MAP_COEFF;
      poly1->rotationX = sox / (ftex->GetWidth() * fsx) * MAP_COEFF;
      poly1->rotationY = soy / (ftex->GetHeight() * fsy) * MAP_COEFF;

      vindex = (i - firstLine) * 3;
      tindex = (i - firstLine) * 2;

      poly2->vertices[vindex + 0] = -seg->v2->x * MAP_SCALE;
      poly2->vertices[vindex + 1] = sector->ceilingplane.ZatPoint(seg->v2) * MAP_SCALE;
      poly2->vertices[vindex + 2] = seg->v2->y * MAP_SCALE;
      poly2->texCoords[tindex + 0] = -poly2->vertices[vindex + 0] / (ctex->GetWidth() * csx) * MAP_COEFF;
      poly2->texCoords[tindex + 1] = -poly2->vertices[vindex + 2] / (ctex->GetHeight() * csy) * MAP_COEFF;
      poly2->rotationX = sox / (ctex->GetWidth() * csx) * MAP_COEFF;
      poly2->rotationY = soy / (ctex->GetHeight() * csy) * MAP_COEFF;

      if (seg->linedef) GL_RecalcSeg(seg, sector);

      // update the subsector bounding box for the frustum checks
      // also add check for highest/lowest point for the surrounding lines...
      if (i == firstLine)
      {
         subSec->bbox[0][0] = poly2->vertices[vindex + 0];
         subSec->bbox[1][0] = poly2->vertices[vindex + 0];
         subSec->bbox[0][2] = poly2->vertices[vindex + 2];
         subSec->bbox[1][2] = poly2->vertices[vindex + 2];
         subSec->bbox[0][1] = poly1->vertices[((maxLine - 1 - i) * 3) + 1];
         subSec->bbox[1][1] = poly2->vertices[vindex + 1];
      }
      else
      {
         subSec->bbox[0][0] = MIN<float>(poly2->vertices[vindex + 0], subSec->bbox[0][0]);
         subSec->bbox[1][0] = MAX<float>(poly2->vertices[vindex + 0], subSec->bbox[1][0]);
         subSec->bbox[0][2] = MIN<float>(poly2->vertices[vindex + 2], subSec->bbox[0][2]);
         subSec->bbox[1][2] = MAX<float>(poly2->vertices[vindex + 2], subSec->bbox[1][2]);
         subSec->bbox[0][1] = MIN<float>(poly1->vertices[((maxLine - 1 - i) * 3) + 1], subSec->bbox[0][1]);
         subSec->bbox[1][1] = MAX<float>(poly2->vertices[vindex + 1], subSec->bbox[1][1]);
      }
   }

   if (subSec->poly)
   {
      maxLine = subSec->poly->numsegs;
      for (i = 0; i < maxLine; i++)
      {
         seg = subSec->poly->segs[i];
         if (seg->linedef) GL_RecalcSeg(seg, sector);
      }
   }
}
示例#21
0
void Render3DFloorPlane::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
{
	FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
	FTexture *tex = TexMan(picnum);
	if (tex->UseType == FTexture::TEX_Null)
		return;

	PolyCameraLight *cameraLight = PolyCameraLight::Instance();

	int lightlevel = 255;
	bool foggy = false;
	if (cameraLight->FixedLightLevel() < 0 && sub->sector->e->XFloor.lightlist.Size())
	{
		lightlist_t *light = P_GetPlaneLight(sub->sector, &sub->sector->ceilingplane, false);
		//basecolormap = light->extra_colormap;
		lightlevel = *light->p_lightlevel;
	}

	int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
	lightlevel = clamp(lightlevel + actualextralight, 0, 255);

	PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);

	TriVertex *vertices = thread->FrameMemory->AllocMemory<TriVertex>(sub->numlines);
	if (ceiling)
	{
		for (uint32_t i = 0; i < sub->numlines; i++)
		{
			seg_t *line = &sub->firstline[i];
			vertices[sub->numlines - 1 - i] = xform.GetVertex(line->v1, fakeFloor->bottom.plane->ZatPoint(line->v1));
		}
	}
	else
	{
		for (uint32_t i = 0; i < sub->numlines; i++)
		{
			seg_t *line = &sub->firstline[i];
			vertices[i] = xform.GetVertex(line->v1, fakeFloor->top.plane->ZatPoint(line->v1));
		}
	}

	PolyDrawArgs args;
	args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
	args.SetTransform(&worldToClip);
	if (!Masked)
	{
		args.SetStyle(TriBlendMode::TextureOpaque);
	}
	else
	{
		double srcalpha = MIN(Alpha, 1.0);
		double destalpha = Additive ? 1.0 : 1.0 - srcalpha;
		args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha);
		args.SetDepthTest(true);
		args.SetWriteDepth(true);
		args.SetWriteStencil(false);
	}
	args.SetFaceCullCCW(true);
	args.SetStencilTestValue(stencilValue);
	args.SetWriteStencil(true, stencilValue + 1);
	args.SetTexture(tex);
	args.SetClipPlane(0, clipPlane);
	args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan);
}
示例#22
0
static void DrawConversationMenu ()
{
	int i, x, y, linesize;

	assert (DialogueLines != NULL);
	assert (CurNode != NULL);

	if (CurNode == NULL)
	{
		M_ClearMenus ();
		return;
	}

	if (ConversationPauseTic < gametic)
	{
		menuactive = MENU_On;
	}

	if (CurNode->Backdrop >= 0)
	{
		screen->DrawTexture (TexMan(CurNode->Backdrop), 0, 0, DTA_320x200, true, TAG_DONE);
	}
	x = 16 * screen->GetWidth() / 320;
	y = 16 * screen->GetHeight() / 200;
	linesize = 10 * CleanYfac;

	// Dim the screen behind the dialogue (but only if there is no backdrop).
	if (CurNode->Backdrop <= 0)
	{
		for (i = 0; DialogueLines[i].width != -1; ++i)
		{ }
		screen->Dim (0, 0.45f, 14 * screen->GetWidth() / 320, 13 * screen->GetHeight() / 200,
			308 * screen->GetWidth() / 320 - 14 * screen->GetWidth () / 320,
			CurNode->SpeakerName == NULL ? linesize * i + 6 * CleanYfac
			: linesize * i + 6 * CleanYfac + linesize * 3/2);
	}

	// Dim the screen behind the PC's choices.
	screen->Dim (0, 0.45f, (24-160) * CleanXfac + screen->GetWidth()/2,
		(ConversationMenu.y - 2 - 100) * CleanYfac + screen->GetHeight()/2,
		272 * CleanXfac,
		MIN(ConversationMenu.numitems * (gameinfo.gametype & GAME_Raven ? 9 : 8) + 4,
		200 - ConversationMenu.y) * CleanYfac);

	if (CurNode->SpeakerName != NULL)
	{
		screen->DrawText (CR_WHITE, x, y, CurNode->SpeakerName,
			DTA_CleanNoMove, true, TAG_DONE);
		y += linesize * 3 / 2;
	}
	x = 24 * screen->GetWidth() / 320;
	for (i = 0; DialogueLines[i].width >= 0; ++i)
	{
		screen->DrawText (CR_UNTRANSLATED, x, y, DialogueLines[i].string,
			DTA_CleanNoMove, true, TAG_DONE);
		y += linesize;
	}

	if (ShowGold)
	{
		AInventory *coin = ConversationPC->FindInventory (RUNTIME_CLASS(ACoin));
		char goldstr[32];

		sprintf (goldstr, "%d", coin != NULL ? coin->Amount : 0);
		screen->DrawText (CR_GRAY, 21, 191, goldstr, DTA_320x200, true,
			DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
		screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
			3, 190, DTA_320x200, true,
			DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
		screen->DrawText (CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE);
		screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
			2, 189, DTA_320x200, true, TAG_DONE);
	}
}
示例#23
0
void gl_RenderFrameModels( const FSpriteModelFrame *smf,
						   const FState *curState,
						   const int curTics,
						   const PClass *ti,
						   Matrix3x4 *normaltransform,
						   int translation)
{
	// [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation
	// and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame.
	FSpriteModelFrame * smfNext = nullptr;
	double inter = 0.;
	if( gl_interpolate_model_frames && !(smf->flags & MDL_NOINTERPOLATION) )
	{
		FState *nextState = curState->GetNextState( );
		if( curState != nextState && nextState )
		{
			// [BB] To interpolate at more than 35 fps we take tic fractions into account.
			float ticFraction = 0.;
			// [BB] In case the tic counter is frozen we have to leave ticFraction at zero.
			if ( ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN) )
			{
				float time = GetTimeFloat();
				ticFraction = (time - static_cast<int>(time));
			}
			inter = static_cast<double>(curState->Tics - curTics - ticFraction)/static_cast<double>(curState->Tics);

			// [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics.
			// In this case inter is negative and we need to set it to zero.
			if ( inter < 0. )
				inter = 0.;
			else
			{
				// [BB] Workaround for actors that use the same frame twice in a row.
				// Most of the standard Doom monsters do this in their see state.
				if ( (smf->flags & MDL_INTERPOLATEDOUBLEDFRAMES) )
				{
					const FState *prevState = curState - 1;
					if ( (curState->sprite == prevState->sprite) && ( curState->Frame == prevState->Frame) )
					{
						inter /= 2.;
						inter += 0.5;
					}
					if ( (curState->sprite == nextState->sprite) && ( curState->Frame == nextState->Frame) )
					{
						inter /= 2.;
						nextState = nextState->GetNextState( );
					}
				}
				if ( inter != 0.0 )
					smfNext = gl_FindModelFrame(ti, nextState->sprite, nextState->Frame, false);
			}
		}
	}

	for(int i=0; i<MAX_MODELS_PER_FRAME; i++)
	{
		if (smf->modelIDs[i] != -1)
		{
			FModel * mdl = Models[smf->modelIDs[i]];
			FTexture *tex = smf->skinIDs[i].isValid()? TexMan(smf->skinIDs[i]) : nullptr;
			mdl->BuildVertexBuffer();
			gl_RenderState.SetVertexBuffer(mdl->mVBuf);

			mdl->PushSpriteMDLFrame(smf, i);

			if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] )
				mdl->RenderFrame(tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation);
			else
				mdl->RenderFrame(tex, smf->modelframes[i], smf->modelframes[i], 0.f, translation);

			gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
		}
	}
}
示例#24
0
	void DrawPopScreen (int bottom)
	{
		char buff[64];
		const char *label;
		int i;
		AInventory *item;
		int xscale, yscale, left, top;
		int bars = (CurrentPop == POP_Status) ? imgINVPOP : imgINVPOP2;
		int back = (CurrentPop == POP_Status) ? imgINVPBAK : imgINVPBAK2;
		// Extrapolate the height of the popscreen for smoother movement
		int height = clamp<int> (PopHeight + FixedMul (r_TicFrac, PopHeightChange), -POP_HEIGHT, 0);

		xscale = CleanXfac;
		yscale = CleanYfac;
		left = screen->GetWidth()/2 - 160*CleanXfac;
		top = bottom + height * yscale;

		screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, FRACUNIT*3/4, TAG_DONE);
		screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE);
		screen->SetFont (SmallFont2);

		switch (CurrentPop)
		{
		case POP_Log:
			// Draw the latest log message.
			sprintf (buff, "%02d:%02d:%02d",
				(level.time/TICRATE)/3600,
				((level.time/TICRATE)%3600)/60,
				(level.time/TICRATE)%60);

			screen->DrawText (CR_UNTRANSLATED, left+210*xscale, top+8*yscale, buff,
				DTA_CleanNoMove, true, TAG_DONE);

			if (CPlayer->LogText != NULL)
			{
				brokenlines_t *lines = V_BreakLines (272, CPlayer->LogText);
				for (i = 0; lines[i].width >= 0; ++i)
				{
					screen->DrawText (CR_UNTRANSLATED, left+24*xscale, top+(18+i*12)*yscale,
						lines[i].string, DTA_CleanNoMove, true, TAG_DONE);
				}
				V_FreeBrokenLines (lines);
			}
			break;

		case POP_Keys:
			// List the keys the player has.
			int pos, endpos, leftcol;
			int clipleft, clipright;
			
			pos = KeyPopPos;
			endpos = pos + 10;
			leftcol = 20;
			clipleft = left + 17*xscale;
			clipright = left + (320-17)*xscale;
			if (KeyPopScroll > 0)
			{
				// Extrapolate the scroll position for smoother scrolling
				int scroll = MAX<int> (0,KeyPopScroll - FixedMul (r_TicFrac, 280/KEY_TIME));
				pos -= 10;
				leftcol = leftcol - 280 + scroll;
			}
			for (i = 0, item = CPlayer->mo->Inventory;
				i < endpos && item != NULL;
				item = item->Inventory)
			{
				if (!item->IsKindOf (RUNTIME_CLASS(AKey)))
					continue;
				
				if (i < pos)
				{
					i++;
					continue;
				}

				label = item->GetClass()->Meta.GetMetaString (AMETA_StrifeName);
				if (label == NULL)
				{
					label = item->GetClass()->Name + 1;
				}

				int colnum = ((i-pos) / 5) & (KeyPopScroll > 0 ? 3 : 1);
				int rownum = (i % 5) * 18;

				screen->DrawTexture (TexMan(item->Icon),
					left + (colnum * 140 + leftcol)*xscale,
					top + (6 + rownum)*yscale,
					DTA_CleanNoMove, true,
					DTA_ClipLeft, clipleft,
					DTA_ClipRight, clipright,
					TAG_DONE);
				screen->DrawText (CR_UNTRANSLATED,
					left + (colnum * 140 + leftcol + 17)*xscale,
					top + (11 + rownum)*yscale,
					label,
					DTA_CleanNoMove, true,
					DTA_ClipLeft, clipleft,
					DTA_ClipRight, clipright,
					TAG_DONE);
				i++;
			}
			break;

		case POP_Status:
			// Show miscellaneous status items.
			
			// Print stats
			DrINumber2 (CPlayer->accuracy, left+268*xscale, top+28*yscale, 7*xscale, imgFONY0);
			DrINumber2 (CPlayer->stamina, left+268*xscale, top+52*yscale, 7*xscale, imgFONY0);

			// How many keys does the player have?
			for (i = 0, item = CPlayer->mo->Inventory;
				item != NULL;
				item = item->Inventory)
			{
				if (item->IsKindOf (RUNTIME_CLASS(AKey)))
				{
					i++;
				}
			}
			DrINumber2 (i, left+268*xscale, top+76*yscale, 7*xscale, imgFONY0);

			// Does the player have a communicator?
			item = CPlayer->mo->FindInventory (RUNTIME_CLASS(ACommunicator));
			if (item != NULL)
			{
				screen->DrawTexture (TexMan(item->Icon),
					left + 280*xscale,
					top + 74*yscale,
					DTA_CleanNoMove, true, TAG_DONE);
			}

			// How much ammo does the player have?
			static const struct
			{
				const TypeInfo *AmmoType;
				int Y;
			} AmmoList[7] =
			{
				{ RUNTIME_CLASS(AClipOfBullets),			19 },
				{ RUNTIME_CLASS(APoisonBolts),				35 },
				{ RUNTIME_CLASS(AElectricBolts),			43 },
				{ RUNTIME_CLASS(AHEGrenadeRounds),			59 },
				{ RUNTIME_CLASS(APhosphorusGrenadeRounds),	67 },
				{ RUNTIME_CLASS(AMiniMissiles),				75 },
				{ RUNTIME_CLASS(AEnergyPod),				83 }
			};
			for (i = 0; i < 7; ++i)
			{
				item = CPlayer->mo->FindInventory (AmmoList[i].AmmoType);

				if (item == NULL)
				{
					DrINumber2 (0, left+206*xscale, top+AmmoList[i].Y*yscale, 7*xscale, imgFONY0);
					DrINumber2 (((AInventory *)GetDefaultByType (AmmoList[i].AmmoType))->MaxAmount,
						left+239*xscale, top+AmmoList[i].Y*yscale, 7*xscale, imgFONY0);
				}
				else
				{
					DrINumber2 (item->Amount, left+206*xscale, top+AmmoList[i].Y*yscale, 7*xscale, imgFONY0);
					DrINumber2 (item->MaxAmount, left+239*xscale, top+AmmoList[i].Y*yscale, 7*xscale, imgFONY0);
				}
			}

			// What weapons does the player have?
			static const struct
			{
				const char *TypeName;
				int X, Y;
			} WeaponList[6] =
			{
				{ "StrifeCrossbow",			23, 19 },
				{ "AssaultGun",				21, 41 },
				{ "FlameThrower",			57, 50 },
				{ "MiniMissileLauncher",	20, 64 },
				{ "StrifeGrenadeLauncher",	55, 20 },
				{ "Mauler",					52, 75 },
			};
			for (i = 0; i < 6; ++i)
			{
				item = CPlayer->mo->FindInventory (TypeInfo::FindType (WeaponList[i].TypeName));

				if (item != NULL)
				{
					screen->DrawTexture (TexMan(item->Icon),
						left + WeaponList[i].X*xscale,
						top + WeaponList[i].Y*yscale,
						DTA_CleanNoMove, true,
						DTA_LeftOffset, 0,
						DTA_TopOffset, 0,
						TAG_DONE);
				}
			}
			break;
		}

		screen->SetFont (SmallFont);
	}
示例#25
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());
		}
	}
示例#26
0
	void DrawMainBar ()
	{
		AInventory *item;
		int i;

		// Pop screen (log, keys, and status)
		if (CurrentPop != POP_None && PopHeight < 0)
		{
			DrawPopScreen (Scaled ? (ST_Y - 8) * screen->GetHeight() / 200 : ST_Y - 8);
		}

		DrawImage (Images[imgINVBACK], 0, 0);
		DrawImage (Images[imgINVTOP], 0, -8);

		// Health
		DrINumber (CPlayer->health, 79, -6, imgFONG0);
		if (CPlayer->cheats & CF_GODMODE)
		{
			HealthBar.SetVial (999);
		}
		else
		{
			HealthBar.SetVial (CPlayer->health);
		}
		DrawImage (&HealthBar, 49, 4);
		DrawImage (&HealthBar, 49, 7);

		// Armor
		item = CPlayer->mo->FindInventory<ABasicArmor>();
		if (item != NULL && item->Amount > 0)
		{
			DrawImage (TexMan(item->Icon), 2, 9);
			DrINumber (item->Amount, 27, 23, imgFONY0);
		}

		// Ammo
		AAmmo *ammo1, *ammo2;
		int ammocount1, ammocount2;

		GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
		if (ammo1 != NULL)
		{
			DrINumber (ammo1->Amount, 311, -6, imgFONG0);
			DrawImage (TexMan(ammo1->Icon), 290, 13);
			if (ammo2 != NULL)
			{
/*				int y = MIN (-5 - BigHeight, -5 - TexMan(ammo1->Icon)->GetHeight());
				screen->DrawTexture (TexMan(ammo2->Icon), -14, y,
					DTA_HUDRules, HUD_Normal,
					DTA_CenterBottomOffset, true,
					TAG_DONE);
				DrBNumberOuterFont (ammo2->Amount, -67, y - BigHeight);
*/			}
		}

		// Sigil
		item = CPlayer->mo->FindInventory<ASigil>();
		if (item != NULL)
		{
			DrawImage (TexMan(item->Icon), 253, 7);
		}

		// Inventory
		CPlayer->InvFirst = ValidateInvFirst (6);
		for (item = CPlayer->InvFirst, i = 0; item != NULL && i < 6; item = item->NextInv(), ++i)
		{
			if (item == CPlayer->InvSel)
			{
				screen->DrawTexture (Images[CursorImage],
					42 + 35*i + ST_X, 12 + ST_Y,
					DTA_320x200, Scaled,
					DTA_Alpha, FRACUNIT - ItemFlash,
					TAG_DONE);
			}
			if (item->Icon != 0)
			{
				DrawImage (TexMan(item->Icon), 48 + 35*i, 14);
			}
			DrINumber (item->Amount, 74 + 35*i, 23, imgFONY0);
		}
	}
示例#27
0
bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsector)
{
	line_t *linedef = sidedef->linedef;
	fixed_t bs_floorheight1;
	fixed_t bs_floorheight2;
	fixed_t bs_ceilingheight1;
	fixed_t bs_ceilingheight2;
	fixed_t fs_floorheight1;
	fixed_t fs_floorheight2;
	fixed_t fs_ceilingheight1;
	fixed_t fs_ceilingheight2;

	// Mirrors and horizons always block the view
	//if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true;

	// Lines with stacked sectors must never block!

	if (backsector->portals[sector_t::ceiling] != NULL || backsector->portals[sector_t::floor] != NULL ||
		frontsector->portals[sector_t::ceiling] != NULL || frontsector->portals[sector_t::floor] != NULL)
	{
		return false;
	}

	// on large levels this distinction can save some time
	// That's a lot of avoided multiplications if there's a lot to see!

	if (frontsector->ceilingplane.a | frontsector->ceilingplane.b)
	{
		fs_ceilingheight1=frontsector->ceilingplane.ZatPoint(linedef->v1);
		fs_ceilingheight2=frontsector->ceilingplane.ZatPoint(linedef->v2);
	}
	else
	{
		fs_ceilingheight2=fs_ceilingheight1=frontsector->ceilingplane.d;
	}

	if (frontsector->floorplane.a | frontsector->floorplane.b)
	{
		fs_floorheight1=frontsector->floorplane.ZatPoint(linedef->v1);
		fs_floorheight2=frontsector->floorplane.ZatPoint(linedef->v2);
	}
	else
	{
		fs_floorheight2=fs_floorheight1=-frontsector->floorplane.d;
	}
	
	if (backsector->ceilingplane.a | backsector->ceilingplane.b)
	{
		bs_ceilingheight1=backsector->ceilingplane.ZatPoint(linedef->v1);
		bs_ceilingheight2=backsector->ceilingplane.ZatPoint(linedef->v2);
	}
	else
	{
		bs_ceilingheight2=bs_ceilingheight1=backsector->ceilingplane.d;
	}

	if (backsector->floorplane.a | backsector->floorplane.b)
	{
		bs_floorheight1=backsector->floorplane.ZatPoint(linedef->v1);
		bs_floorheight2=backsector->floorplane.ZatPoint(linedef->v2);
	}
	else
	{
		bs_floorheight2=bs_floorheight1=-backsector->floorplane.d;
	}

	// now check for closed sectors!
	if (bs_ceilingheight1<=fs_floorheight1 && bs_ceilingheight2<=fs_floorheight2) 
	{
		FTexture * tex = TexMan(sidedef->GetTexture(side_t::top));
		if (!tex || tex->UseType==FTexture::TEX_Null) return false;
		if (backsector->GetTexture(sector_t::ceiling)==skyflatnum && 
			frontsector->GetTexture(sector_t::ceiling)==skyflatnum) return false;
		return true;
	}

	if (fs_ceilingheight1<=bs_floorheight1 && fs_ceilingheight2<=bs_floorheight2) 
	{
		FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom));
		if (!tex || tex->UseType==FTexture::TEX_Null) return false;

		// properly render skies (consider door "open" if both floors are sky):
		if (backsector->GetTexture(sector_t::ceiling)==skyflatnum && 
			frontsector->GetTexture(sector_t::ceiling)==skyflatnum) return false;
		return true;
	}

	if (bs_ceilingheight1<=bs_floorheight1 && bs_ceilingheight2<=bs_floorheight2)
	{
		// preserve a kind of transparent door/lift special effect:
		if (bs_ceilingheight1 < fs_ceilingheight1 || bs_ceilingheight2 < fs_ceilingheight2) 
		{
			FTexture * tex = TexMan(sidedef->GetTexture(side_t::top));
			if (!tex || tex->UseType==FTexture::TEX_Null) return false;
		}
		if (bs_floorheight1 > fs_floorheight1 || bs_floorheight2 > fs_floorheight2)
		{
			FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom));
			if (!tex || tex->UseType==FTexture::TEX_Null) return false;
		}
		if (backsector->GetTexture(sector_t::ceiling)==skyflatnum && 
			frontsector->GetTexture(sector_t::ceiling)==skyflatnum) return false;
		if (backsector->GetTexture(sector_t::floor)==skyflatnum && frontsector->GetTexture(sector_t::floor)
			==skyflatnum) return false;
		return true;
	}

	return false;
}
示例#28
0
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate)
{
	return ValidateTexture(translate? TexMan(no) : TexMan[no], expand);
}
示例#29
0
static void AddLine (seg_t *seg,sector_t * sector,subsector_t * polysub)
{
	angle_t startAngle, endAngle;
	sector_t * backsector = NULL;
	sector_t bs;

	ClipWall.Clock();
	if (GLPortal::mirrorline)
	{
		// this seg is completely behind the mirror!
		if (P_PointOnLineSide(seg->v1->x, seg->v1->y, GLPortal::mirrorline) &&
			P_PointOnLineSide(seg->v2->x, seg->v2->y, GLPortal::mirrorline)) 
		{
			ClipWall.Unclock();
			return;
		}
	}

	startAngle = seg->v2->GetViewAngle();
	endAngle = seg->v1->GetViewAngle();

	// Back side, i.e. backface culling	- read: endAngle >= startAngle!
	if (startAngle-endAngle<ANGLE_180 || !seg->linedef)  
	{
		ClipWall.Unclock();
		return;
	}

	if (!clipper.SafeCheckRange(startAngle, endAngle)) 
	{
		ClipWall.Unclock();
		return;
	}

	if (!seg->backsector)
	{
		clipper.SafeAddClipRange(startAngle, endAngle);
	}
	else if (!polysub)	// Two-sided polyobjects never obstruct the view
	{
		if (sector->sectornum == seg->backsector->sectornum)
		{
			FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::mid));
			if (!tex || tex->UseType==FTexture::TEX_Null) 
			{
				// nothing to do here!
				ClipWall.Unclock();
				seg->linedef->validcount=validcount;
				return;
			}
			backsector=sector;
		}
		else
		{
			// clipping checks are only needed when the backsector is not the same as the front sector
			gl_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);

			backsector = gl_FakeFlat(seg->backsector, &bs, true);

			if (gl_CheckClip(seg->sidedef, sector, backsector))
			{
				clipper.SafeAddClipRange(startAngle, endAngle);
			}
		}
	}
	else 
	{
		// Backsector for polyobj segs is always the containing sector itself
		backsector = sector;
	}

	seg->linedef->flags |= ML_MAPPED;
	ClipWall.Unclock();

	if (!gl_render_segs)
	{
		// rendering per linedef as opposed per seg is significantly more efficient
		// so mark the linedef as rendered here and render it completely.
		if (seg->linedef->validcount!=validcount) seg->linedef->validcount=validcount;
		else return;
	}

	GLWall wall;

	SetupWall.Clock();

	wall.Process(seg, sector, backsector, polysub, gl_render_segs);
	rendered_lines++;

	SetupWall.Unclock();
}
示例#30
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);
}