// //--------------------------------------------------------------------------- // // Copyright(C) 2003-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 "doomtype.h" #include "g_level.h" #include "w_wad.h" #include "r_state.h" #include "r_utility.h" #include "g_levellocals.h" #include "hwrenderer/scene/hw_skydome.h" #include "hwrenderer/scene/hw_portal.h" #include "hwrenderer/scene/hw_renderstate.h" #include "textures/skyboxtexture.h" //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- void HWSkyPortal::RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim, int row, bool apply) { di->Draw(prim, state, vertexBuffer->mPrimStart[row], vertexBuffer->mPrimStart[row + 1] - vertexBuffer->mPrimStart[row]); } //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- void HWSkyPortal::RenderDome(HWDrawInfo *di, FRenderState &state, FMaterial * tex, float x_offset, float y_offset, bool mirror, int mode) { if (tex) { state.SetMaterial(tex, CLAMP_NONE, 0, -1); state.EnableModelMatrix(true); state.EnableTextureMatrix(true); vertexBuffer->SetupMatrices(tex, x_offset, y_offset, mirror, mode, state.mModelMatrix, state.mTextureMatrix); } int rc = vertexBuffer->mRows + 1; // The caps only get drawn for the main layer but not for the overlay. if (mode == FSkyDomeCreator::SKYMODE_MAINLAYER && tex != NULL) { PalEntry pe = tex->tex->GetSkyCapColor(false); state.SetObjectColor(pe); state.EnableTexture(false); RenderRow(di, state, DT_TriangleFan, 0); pe = tex->tex->GetSkyCapColor(true); state.SetObjectColor(pe); RenderRow(di, state, DT_TriangleFan, rc); state.EnableTexture(true); } state.SetObjectColor(0xffffffff); for (int i = 1; i <= vertexBuffer->mRows; i++) { RenderRow(di, state, DT_TriangleStrip, i, i == 1); RenderRow(di, state, DT_TriangleStrip, rc + i, false); } state.EnableTextureMatrix(false); state.EnableModelMatrix(false); } //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- void HWSkyPortal::RenderBox(HWDrawInfo *di, FRenderState &state, FTextureID texno, FMaterial * gltex, float x_offset, bool sky2) { FSkyBox * sb = static_cast(gltex->tex); int faces; FMaterial * tex; state.EnableModelMatrix(true); state.mModelMatrix.loadIdentity(); if (!sky2) state.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector.X, level.info->skyrotatevector.Z, level.info->skyrotatevector.Y); else state.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector2.X, level.info->skyrotatevector2.Z, level.info->skyrotatevector2.Y); if (sb->faces[5]) { faces=4; // north tex = FMaterial::ValidateTexture(sb->faces[0], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(0), 4); // east tex = FMaterial::ValidateTexture(sb->faces[1], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(1), 4); // south tex = FMaterial::ValidateTexture(sb->faces[2], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(2), 4); // west tex = FMaterial::ValidateTexture(sb->faces[3], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(3), 4); } else { faces=1; tex = FMaterial::ValidateTexture(sb->faces[0], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(-1), 10); } // top tex = FMaterial::ValidateTexture(sb->faces[faces], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(sb->fliptop ? 6 : 5), 4); // bottom tex = FMaterial::ValidateTexture(sb->faces[faces+1], false); state.SetMaterial(tex, CLAMP_XY, 0, -1); di->Draw(DT_TriangleStrip, state, vertexBuffer->FaceStart(4), 4); state.EnableModelMatrix(false); } //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) { bool drawBoth = false; auto &vp = di->Viewpoint; // We have no use for Doom lighting special handling here, so disable it for this function. int oldlightmode = ::level.lightmode; if (::level.lightmode == 8) { ::level.lightmode = 2; state.SetSoftLightLevel(-1); } state.ResetColor(); state.EnableFog(false); state.AlphaFunc(Alpha_GEqual, 0.f); state.SetRenderStyle(STYLE_Translucent); bool oldClamp = di->SetDepthClamp(true); di->SetupView(0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1)); state.SetVertexBuffer(FRenderState::VB_Sky); if (origin->texture[0] && origin->texture[0]->tex->bSkybox) { RenderBox(di, state, origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); } else { if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false; if (origin->texture[0]) { state.SetTextureMode(TM_OPAQUE); RenderDome(di, state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyDomeCreator::SKYMODE_MAINLAYER); state.SetTextureMode(TM_NORMAL); } state.AlphaFunc(Alpha_Greater, 0.f); if (origin->doublesky && origin->texture[1]) { RenderDome(di, state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyDomeCreator::SKYMODE_SECONDLAYER); } if (::level.skyfog>0 && !di->isFullbrightScene() && (origin->fadecolor & 0xffffff) != 0) { PalEntry FadeColor = origin->fadecolor; FadeColor.a = clamp(::level.skyfog, 0, 255); state.EnableTexture(false); state.SetObjectColor(FadeColor); di->Draw(DT_Triangles, state, 0, 12); state.EnableTexture(true); state.SetObjectColor(0xffffffff); } } state.SetVertexBuffer(FRenderState::VB_Default); ::level.lightmode = oldlightmode; di->SetDepthClamp(oldClamp); } const char *HWSkyPortal::GetName() { return "Sky"; }