diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 328d4844e..29df810d6 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1082,6 +1082,7 @@ set (PCH_SOURCES core/rendering/scene/hw_bunchdrawer.cpp core/rendering/scene/hw_portal.cpp core/rendering/scene/hw_skyportal.cpp + core/rendering/scene/hw_sky.cpp core/console/c_notifybuffer.cpp core/console/d_event.cpp diff --git a/source/build/include/build.h b/source/build/include/build.h index 6b49ec136..851b54339 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -299,6 +299,11 @@ static inline psky_t *getpskyidx(int32_t picnum) EXTERN psky_t * tileSetupSky(int32_t tilenum); psky_t* defineSky(int32_t const tilenum, int horiz, int lognumtiles, const uint16_t* tileofs, int yoff = 0); +// Get properties of parallaxed sky to draw. +// Returns: pointer to tile offset array. Sets-by-pointer the other three. +const int16_t* getpsky(int32_t picnum, int32_t* dapyscale, int32_t* dapskybits, int32_t* dapyoffs, int32_t* daptileyscale); + + EXTERN char parallaxtype; EXTERN int32_t parallaxyoffs_override, parallaxyscale_override; extern int16_t pskybits_override; diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 533c120ba..94095cb9f 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -53,10 +53,6 @@ static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr) return (tspr->owner < 0 || (unsigned)tspr->picnum >= MAXTILES); } -// Get properties of parallaxed sky to draw. -// Returns: pointer to tile offset array. Sets-by-pointer the other three. -const int16_t* getpsky(int32_t picnum, int32_t* dapyscale, int32_t* dapskybits, int32_t* dapyoffs, int32_t* daptileyscale); - inline void set_globalpos(int32_t const x, int32_t const y, int32_t const z) { globalposx = x, fglobalposx = (float)x; diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.cpp b/source/common/rendering/hwrenderer/data/hw_skydome.cpp index 52bdc4d36..ebd0d35bc 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.cpp +++ b/source/common/rendering/hwrenderer/data/hw_skydome.cpp @@ -324,7 +324,7 @@ void FSkyVertexBuffer::CreateDome() // //----------------------------------------------------------------------------- -void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelMatrix, VSMatrix &textureMatrix, bool tiled) +void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelMatrix, VSMatrix &textureMatrix, bool tiled, float xscale, float yscale) { float texw = tex->GetDisplayWidth(); float texh = tex->GetDisplayHeight(); @@ -332,37 +332,44 @@ void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_ modelMatrix.loadIdentity(); modelMatrix.rotate(-180.0f + x_offset, 0.f, 1.f, 0.f); - float xscale = texw < 1024.f ? floorf(1024.f / float(texw)) : 1.f; - float yscale = 1.f; + if (xscale == 0) xscale = texw < 1024.f ? floorf(1024.f / float(texw)) : 1.f; auto texskyoffset = tex->GetSkyOffset() + skyoffset; - if (texh <= 128 && tiled) + if (yscale == 0) { - modelMatrix.translate(0.f, (-40 + texskyoffset)*skyoffsetfactor, 0.f); - modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); - yscale = 240.f / texh; - } - else if (texh < 128) - { - // smaller sky textures must be tiled. We restrict it to 128 sky pixels, though - modelMatrix.translate(0.f, -1250.f, 0.f); - modelMatrix.scale(1.f, 128 / 230.f, 1.f); - yscale = float(128 / texh); // intentionally left as integer. - } - else if (texh < 200) - { - modelMatrix.translate(0.f, -1250.f, 0.f); - modelMatrix.scale(1.f, texh / 230.f, 1.f); - } - else if (texh <= 240) - { - modelMatrix.translate(0.f, (200 - texh + texskyoffset)*skyoffsetfactor, 0.f); - modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f); + if (texh <= 128 && tiled) + { + modelMatrix.translate(0.f, (-40 + texskyoffset) * skyoffsetfactor, 0.f); + modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); + yscale = 240.f / texh; + } + else if (texh < 128) + { + // smaller sky textures must be tiled. We restrict it to 128 sky pixels, though + modelMatrix.translate(0.f, -1250.f, 0.f); + modelMatrix.scale(1.f, 128 / 230.f, 1.f); + yscale = float(128 / texh); // intentionally left as integer. + } + else if (texh < 200) + { + modelMatrix.translate(0.f, -1250.f, 0.f); + modelMatrix.scale(1.f, texh / 230.f, 1.f); + } + else if (texh <= 240) + { + modelMatrix.translate(0.f, (200 - texh + texskyoffset) * skyoffsetfactor, 0.f); + modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f); + } + else + { + modelMatrix.translate(0.f, (-40 + texskyoffset) * skyoffsetfactor, 0.f); + modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); + yscale = 240.f / texh; + } } else { - modelMatrix.translate(0.f, (-40 + texskyoffset)*skyoffsetfactor, 0.f); + modelMatrix.translate(0.f, (-40 + texskyoffset) * skyoffsetfactor, 0.f); modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); - yscale = 240.f / texh; } textureMatrix.loadIdentity(); textureMatrix.scale(mirror ? -xscale : xscale, yscale, 1.f); diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.h b/source/common/rendering/hwrenderer/data/hw_skydome.h index 7cbd37948..f095458a2 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.h +++ b/source/common/rendering/hwrenderer/data/hw_skydome.h @@ -71,7 +71,7 @@ public: FSkyVertexBuffer(); ~FSkyVertexBuffer(); - void SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelmatrix, VSMatrix &textureMatrix, bool tiled); + void SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelmatrix, VSMatrix &textureMatrix, bool tiled, float xscale = 0, float vertscale = 0); std::pair GetBufferObjects() const { return std::make_pair(mVertexBuffer, nullptr); diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 34cc77f95..e37abb3a1 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -296,10 +296,8 @@ void HWDrawInfo::CreateScene() angle_t a1 = FrustumAngle(); mClipper->SafeAddClipRangeRealAngles(vp.RotAngle + a1, vp.RotAngle - a1); -#if 0 // reset the portal manager portalState.StartFrame(); -#endif ProcessAll.Clock(); @@ -528,9 +526,8 @@ void HWDrawInfo::DrawScene(int drawmode) auto& RenderState = *screen->RenderState(); RenderState.SetDepthMask(true); -#if 0 + if (!gl_no_skyclear) portalState.RenderFirstSkyPortal(recursion, this, RenderState); -#endif RenderScene(RenderState); @@ -543,9 +540,7 @@ void HWDrawInfo::DrawScene(int drawmode) // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; -#if 0 portalState.EndFrame(this, RenderState); -#endif recursion--; RenderTranslucent(RenderState); } @@ -559,28 +554,6 @@ void HWDrawInfo::DrawScene(int drawmode) void HWDrawInfo::ProcessScene(bool toscreen) { -#if 0 portalState.BeginScene(); -#endif DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); } - -//========================================================================== -// -// -// -//========================================================================== -/* -void HWDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *ptg, subsector_t *sub) -{ - auto portal = FindPortal(ptg); - if (!portal) - { - portal = new HWSectorStackPortal(&portalState, ptg); - Portals.Push(portal); - } - auto ptl = static_cast(portal); - ptl->AddSubsector(sub); -} -*/ - diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index ea6bd3d2d..9d1636cac 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -173,7 +173,7 @@ public: HWSkyInfo * sky; // for normal sky //HWHorizonInfo * horizon; // for horizon information PortalDesc * portal; // stacked sector portals - //secplane_t * planemirror; // for plane mirrors + int * planemirror; // for plane mirrors spritetype* teleport; // SW's teleport-views }; @@ -202,9 +202,9 @@ public: void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror); void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line); - void SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2) {} - void SkyTop(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) {} - void SkyBottom(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) {} + void SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2); + void SkyTop(HWDrawInfo* di, walltype* seg, sectortype* fs, sectortype* bs, FVector2& v1, FVector2& v2); + void SkyBottom(HWDrawInfo* di, walltype* seg, sectortype* fs, sectortype* bs, FVector2& v1, FVector2& v2); bool DoHorizon(HWDrawInfo *di, walltype * seg,sectortype * fs, DVector2& v1, DVector2& v2); diff --git a/source/core/rendering/scene/hw_portal.cpp b/source/core/rendering/scene/hw_portal.cpp index efd329ccb..d868e1e71 100644 --- a/source/core/rendering/scene/hw_portal.cpp +++ b/source/core/rendering/scene/hw_portal.cpp @@ -36,12 +36,6 @@ EXTERN_CVAR(Int, r_mirror_recursions) EXTERN_CVAR(Bool, gl_portals) -enum -{ - plane_floor, - plane_ceiling -}; - //----------------------------------------------------------------------------- // // StartFrame diff --git a/source/core/rendering/scene/hw_portal.h b/source/core/rendering/scene/hw_portal.h index d1e6cdc9d..d6581eff6 100644 --- a/source/core/rendering/scene/hw_portal.h +++ b/source/core/rendering/scene/hw_portal.h @@ -9,15 +9,22 @@ class FSkyBox; +enum +{ + plane_floor, + plane_ceiling +}; + + + struct HWSkyInfo { - float x_offset[2]; + float x_offset; float y_offset; // doubleskies don't have a y-offset - FGameTexture * texture[2]; + float y_scale; + int shade; + FGameTexture * texture; FTextureID skytexno1; - bool mirrored; - bool doublesky; - bool sky2; PalEntry fadecolor; bool operator==(const HWSkyInfo & inf) @@ -28,7 +35,6 @@ struct HWSkyInfo { return !!memcmp(this, &inf, sizeof(*this)); } - void init(HWDrawInfo *di, int sky1, PalEntry fadecolor); }; struct HWHorizonInfo diff --git a/source/core/rendering/scene/hw_sky.cpp b/source/core/rendering/scene/hw_sky.cpp new file mode 100644 index 000000000..a9e377404 --- /dev/null +++ b/source/core/rendering/scene/hw_sky.cpp @@ -0,0 +1,241 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2002-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// + +#include "texturemanager.h" +#include "hw_drawinfo.h" +#include "hw_drawstructs.h" +#include "hw_portal.h" +//#include "hw_lighting.h" +#include "hw_material.h" +#include "gamefuncs.h" +#include "build.h" +#include "cmdlib.h" + +CVAR(Bool,gl_noskyboxes, false, 0) +FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap); + +//========================================================================== +// +// Set up the skyinfo struct +// +//========================================================================== + +void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane, PalEntry FadeColor) +{ + int picnum = plane == plane_ceiling ? sector->ceilingpicnum : sector->floorpicnum; + float xpanning = plane == plane_ceiling ? sector->ceilingxpan_ : sector->floorxpan_; + float ypanning = plane == plane_ceiling ? sector->ceilingypan_ : sector->floorypan_; + + int32_t dapyscale = 0, dapskybits = 0, dapyoffs = 0, daptileyscale = 0; + FGameTexture* skytex = nullptr; + int realskybits = 0; + // todo: check for skybox replacement. + if (!skytex) + { + int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); + skytex = GetSkyTexture(picnum, dapskybits, dapskyoff); + realskybits = dapskybits; + if (skytex) dapskybits = 0; + else skytex = tileGetTexture(picnum); + } + + float t = (float)((1 << (sizeToBits(tileWidth(picnum)))) << dapskybits); + int ti = (1 << (sizeToBits(tileHeight(picnum)))); if (ti != tileHeight(picnum)) ti += ti; + + // dapyscale is not relvant for a sky dome. + sky->y_scale = FixedToFloat(daptileyscale); + sky->y_offset = FixedToFloat(dapyoffs) + ypanning * (float)ti * (1.f / 256.f); + sky->x_offset = xpanning / (1 << (realskybits - dapskybits)); + sky->fadecolor = FadeColor; + sky->shade = plane == plane_ceiling ? sector->ceilingshade : sector->floorshade; + sky->texture = skytex; +} + + +//========================================================================== +// +// Calculate sky texture for ceiling or floor +// +//========================================================================== + +void HWWall::SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowreflect) +{ + int ptype; + + if (sector->portalflags == PORTAL_SECTOR_CEILING || sector->portalflags == PORTAL_SECTOR_FLOOR) + { + if (screen->instack[1 - plane]) return; + portal = &allPortals[sector->portalnum]; + PutPortal(di, PORTALTYPE_SECTORSTACK, plane); + } + else if (sector->portalflags == PORTAL_SECTOR_CEILING_REFLECT || sector->portalflags == PORTAL_SECTOR_FLOOR_REFLECT) + { + ptype = PORTALTYPE_PLANEMIRROR; + if (plane == plane_ceiling && (sector->ceilingstat & CSTAT_SECTOR_SLOPE)) return; + if (plane == plane_floor && (sector->floorstat & CSTAT_SECTOR_SLOPE)) return; + planemirror = plane == plane_floor ? §or->floorz : §or->ceilingz; + PutPortal(di, PORTALTYPE_PLANEMIRROR, plane); + } + else + { + ptype = PORTALTYPE_SKY; + HWSkyInfo skyinfo; + initSkyInfo(di, &skyinfo, sector, plane, fade); + ptype = PORTALTYPE_SKY; + sky = &skyinfo; + PutPortal(di, ptype, plane); + } +} + + +//========================================================================== +// +// Skies on one sided walls +// +//========================================================================== + +void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2) +{ + ztop[0] = ztop[1] = 32768.0f; + zbottom[0] = zceil[0]; + zbottom[1] = zceil[1]; + SkyPlane(di, fs, plane_ceiling, true); + + ztop[0] = zfloor[0]; + ztop[1] = zfloor[1]; + zbottom[0] = zbottom[1] = -32768.0f; + SkyPlane(di, fs, plane_floor, true); +} + +//========================================================================== +// +// Upper Skies on two sided walls +// +//========================================================================== + +void HWWall::SkyTop(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) +{ + if (fs->portalflags == PORTAL_SECTOR_CEILING || fs->portalflags == PORTAL_SECTOR_CEILING_REFLECT) + { + if (fs->portalflags == PORTAL_SECTOR_CEILING_REFLECT) + { + + /* + float backreflect = bs->GetReflect(sectortype::ceiling); + if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD() && !bs->isClosed()) + { + // Don't add intra-portal line to the portal. + return; + } + */ + } + else + { + if (bs->portalflags == PORTAL_SECTOR_CEILING && bs->portalnum == fs->portalnum) + { + return; + } + } + // stacked sectors + ztop[0] = ztop[1] = 32768.0f; + PlanesAtPoint(fs, v1.X*16.f, v1.Y*-16.f, &zbottom[0], nullptr); + PlanesAtPoint(fs, v2.X * 16.f, v2.Y * -16.f, &zbottom[1], nullptr); + } + else if (fs->ceilingstat & CSTAT_SECTOR_SKY) + { + float c1, c2, f1, f2; + PlanesAtPoint(bs, v1.X * 16.f, v1.Y * -16.f, &c1, &f1); + PlanesAtPoint(bs, v2.X * 16.f, v2.Y * -16.f, &c2, &f2); + + if (bs->ceilingstat & CSTAT_SECTOR_SKY) + { + // if the back sector is closed the sky must be drawn! + if (c1 > f1 || c2 > f2) return; + } + + ztop[0]=ztop[1]=32768.0f; + + zbottom[0] = c1; + zbottom[1] = c2; + flags|=HWF_SKYHACK; // mid textures on such lines need special treatment! + } + + SkyPlane(di, fs, plane_ceiling, true); +} + + +//========================================================================== +// +// Lower Skies on two sided walls +// +//========================================================================== + +void HWWall::SkyBottom(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) +{ + if (fs->portalflags == PORTAL_SECTOR_FLOOR || fs->portalflags == PORTAL_SECTOR_FLOOR_REFLECT) + { + if (fs->portalflags == PORTAL_SECTOR_FLOOR_REFLECT) + { + + /* + float backreflect = bs->GetReflect(sectortype::floor); + if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD() && !bs->isClosed()) + { + // Don't add intra-portal line to the portal. + return; + } + */ + } + else + { + if (bs->portalflags == PORTAL_SECTOR_FLOOR && bs->portalnum == fs->portalnum) + { + return; + } + } + // stacked sectors + zbottom[0] = zbottom[1] = -32768.0f; + PlanesAtPoint(fs, v1.X * 16.f, v1.Y * -16.f, nullptr, &ztop[0]); + PlanesAtPoint(fs, v2.X * 16.f, v2.Y * -16.f, nullptr, &ztop[0]); + } + else if (fs->ceilingstat & CSTAT_SECTOR_SKY) + { + float c1, c2, f1, f2; + PlanesAtPoint(bs, v1.X * 16.f, v1.Y * -16.f, &c1, &f1); + PlanesAtPoint(bs, v2.X * 16.f, v2.Y * -16.f, &c2, &f2); + + if (bs->ceilingstat & CSTAT_SECTOR_SKY) + { + // if the back sector is closed the sky must be drawn! + if (c1 > f1 || c2 > f2) return; + } + + zbottom[0] = zbottom[1] = -32768.0f; + + zbottom[0] = f1; + zbottom[1] = f2; + flags |= HWF_SKYHACK; // mid textures on such lines need special treatment! + } + + SkyPlane(di, fs, plane_floor, true); +} + diff --git a/source/core/rendering/scene/hw_skyportal.cpp b/source/core/rendering/scene/hw_skyportal.cpp index b70571c66..1c3ae10c6 100644 --- a/source/core/rendering/scene/hw_skyportal.cpp +++ b/source/core/rendering/scene/hw_skyportal.cpp @@ -42,7 +42,6 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) state.SetNoSoftLightLevel(); } - state.ResetColor(); state.EnableFog(false); state.AlphaFunc(Alpha_GEqual, 0.f); @@ -52,42 +51,27 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) di->SetupView(state, 0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1)); state.SetVertexBuffer(vertexBuffer); - auto skybox = origin->texture[0] ? dynamic_cast(origin->texture[0]->GetTexture()) : nullptr; + auto skybox = origin->texture ? dynamic_cast(origin->texture->GetTexture()) : nullptr; if (skybox) { - vertexBuffer->RenderBox(state, origin->skytexno1, skybox, origin->x_offset[0], origin->sky2, /*di->Level->info->pixelstretch*/1, { 0, 0, 1 }, { 0, 0, 1 }); + vertexBuffer->RenderBox(state, origin->skytexno1, skybox, origin->x_offset, false, /*di->Level->info->pixelstretch*/1, { 0, 0, 1 }, { 0, 0, 1 }); } else { - if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false; - - if (origin->texture[0]) - { - state.SetTextureMode(TM_OPAQUE); - vertexBuffer->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, false); - state.SetTextureMode(TM_NORMAL); - } - - state.AlphaFunc(Alpha_Greater, 0.f); - - if (origin->doublesky && origin->texture[1]) - { - vertexBuffer->RenderDome(state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER, false); - } - - int skyfog = 0; - if (skyfog>0 && /*!di->isFullbrightScene() &&*/ (origin->fadecolor & 0xffffff) != 0) - { - PalEntry FadeColor = origin->fadecolor; - FadeColor.a = clamp(skyfog, 0, 255); - - state.EnableTexture(false); - state.SetObjectColor(FadeColor); - state.Draw(DT_Triangles, 0, 12); - state.EnableTexture(true); - state.SetObjectColor(0xffffffff); - } + state.SetTextureMode(TM_OPAQUE); + vertexBuffer->RenderDome(state, origin->texture, origin->x_offset, origin->y_offset, false, FSkyVertexBuffer::SKYMODE_MAINLAYER, false); + state.SetTextureMode(TM_NORMAL); } + if (origin->fadecolor & 0xffffff) + { + PalEntry FadeColor = origin->fadecolor; + state.EnableTexture(false); + state.SetObjectColor(FadeColor); + state.Draw(DT_Triangles, 0, 12); + state.EnableTexture(true); + state.SetObjectColor(0xffffffff); + } + //di->lightmode = oldlightmode; state.SetDepthClamp(oldClamp); }