//========================================================================== // // 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); } } }
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; }
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; }
static void ClearStatusbar() { DrawPlayScreen(); FTexture *borderTex = TexMan(levelInfo->GetBorderTexture()); VWB_DrawFill(borderTex, statusbarx, statusbary2+CleanYfac, screenWidth-statusbarx, screenHeight); }
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); } } }
FTexture *FImageCollection::operator[] (int index) const { if ((unsigned int)index >= ImageMap.Size()) { return NULL; } return ImageMap[index].Exists()? TexMan(ImageMap[index]) : NULL; }
//========================================================================== // // 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); }
/* ================= = = 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(); }
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 (); }
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); }
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); } }
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; }
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); } }
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); } } }
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; } }
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); }
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; }
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; } }
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); } } }
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); }
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); } }
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); } } }
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); }
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()); } }
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); } }
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; }
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate) { return ValidateTexture(translate? TexMan(no) : TexMan[no], expand); }
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(); }
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); }