- moved around some sky rendering code so that the game independent parts are grouped together.

This commit is contained in:
Christoph Oelckers 2020-04-29 00:14:42 +02:00
parent b1dd1eff50
commit 4b8fb7d48b
16 changed files with 179 additions and 198 deletions

View file

@ -1,4 +1,4 @@
#pragma once
#include "renderstyle.h"
#include "matrix.h"
#include "model.h"

View file

@ -199,7 +199,6 @@ public:
virtual void SetTextureFilterMode() {}
virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; }
virtual void PrecacheMaterial(FMaterial *mat, int translation) {}
virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; }
virtual FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags);
virtual void TextureFilterChanged() {}
virtual void BeginFrame() {}

View file

@ -169,10 +169,8 @@ void OpenGLFrameBuffer::InitializeState()
mSkyData = new FSkyVertexBuffer;
mViewpoints = new HWViewpointBuffer;
mLights = new FLightBuffer();
GLRenderer = new FGLRenderer(this);
GLRenderer->Initialize(GetWidth(), GetHeight());
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
mDebug = std::make_shared<FGLDebug>();
@ -327,11 +325,6 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
FHardwareTexture::UnbindAll();
}
FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli)
{
return new FHWModelRenderer(nullptr, gl_RenderState, mli);
}
IVertexBuffer *OpenGLFrameBuffer::CreateVertexBuffer()
{
return new GLVertexBuffer;

View file

@ -43,7 +43,6 @@ public:
void SetTextureFilterMode() override;
IHardwareTexture *CreateHardwareTexture() override;
void PrecacheMaterial(FMaterial *mat, int translation) override;
FModelRenderer *CreateModelRenderer(int mli) override;
void TextureFilterChanged() override;
void BeginFrame() override;
void SetViewportRects(IntRect *bounds) override;

View file

@ -361,10 +361,6 @@ struct HWSkyPortal : public HWPortal
FSkyVertexBuffer *vertexBuffer;
friend struct HWEEHorizonPortal;
void RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim, int row, bool apply = true);
void RenderBox(HWDrawInfo *di, FRenderState &state, FTextureID texno, FSkyBox * gltex, float x_offset, bool sky2);
void RenderDome(HWDrawInfo *di, FRenderState &state, FGameTexture * tex, float x_offset, float y_offset, bool mirror, int mode);
protected:
virtual void DrawContents(HWDrawInfo *di, FRenderState &state);
virtual void * GetSource() const { return origin; }

View file

@ -53,15 +53,9 @@
**---------------------------------------------------------------------------
**
*/
#include "doomtype.h"
#include "g_level.h"
#include "filesystem.h"
#include "r_state.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include "r_sky.h"
#include "cmdlib.h"
#include "bitmap.h"
#include "skyboxtexture.h"
#include "hw_material.h"
#include "hw_skydome.h"
@ -69,6 +63,13 @@
#include "hw_drawinfo.h"
#include "hwrenderer/data/buffers.h"
// 57 world units roughly represent one sky texel for the glTranslate call.
enum
{
skyoffsetfactor = 57
};
//-----------------------------------------------------------------------------
//
// Shamelessly lifted from Doomsday (written by Jaakko Keränen)
@ -77,6 +78,47 @@
//-----------------------------------------------------------------------------
EXTERN_CVAR(Float, skyoffset)
struct SkyColor
{
FTextureID Texture;
std::pair<PalEntry, PalEntry> Colors;
};
static TArray<SkyColor> SkyColors;
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex)
{
for (auto& sky : SkyColors)
{
if (sky.Texture == tex->GetID()) return sky.Colors;
}
auto itex = tex->GetTexture();
SkyColor sky;
FBitmap bitmap = itex->GetBgraBitmap(nullptr);
int w = bitmap.GetWidth();
int h = bitmap.GetHeight();
const uint32_t* buffer = (const uint32_t*)bitmap.GetPixels();
if (buffer)
{
sky.Colors.first = averageColor((uint32_t*)buffer, w * MIN(30, h), 0);
if (h > 30)
{
sky.Colors.second = averageColor(((uint32_t*)buffer) + (h - 30) * w, w * 30, 0);
}
else sky.Colors.second = sky.Colors.first;
}
sky.Texture = tex->GetID();
SkyColors.Push(sky);
return SkyColors.Last().Colors;
}
//-----------------------------------------------------------------------------
//
//
@ -282,7 +324,7 @@ void FSkyVertexBuffer::CreateDome()
//
//-----------------------------------------------------------------------------
void FSkyVertexBuffer::SetupMatrices(HWDrawInfo *di, FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelMatrix, VSMatrix &textureMatrix)
void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelMatrix, VSMatrix &textureMatrix, bool tiled)
{
float texw = tex->GetDisplayWidth();
float texh = tex->GetDisplayHeight();
@ -293,7 +335,7 @@ void FSkyVertexBuffer::SetupMatrices(HWDrawInfo *di, FGameTexture *tex, float x_
float xscale = texw < 1024.f ? floor(1024.f / float(texw)) : 1.f;
float yscale = 1.f;
auto texskyoffset = tex->GetSkyOffset() + skyoffset;
if (texh <= 128 && (di->Level->flags & LEVEL_FORCETILEDSKY))
if (texh <= 128 && tiled)
{
modelMatrix.translate(0.f, (-40 + texskyoffset)*skyoffsetfactor, 0.f);
modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f);
@ -326,3 +368,115 @@ void FSkyVertexBuffer::SetupMatrices(HWDrawInfo *di, FGameTexture *tex, float x_
textureMatrix.scale(mirror ? -xscale : xscale, yscale, 1.f);
textureMatrix.translate(1.f, y_offset / texh, 1.f);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, bool apply)
{
state.Draw(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled)
{
if (tex)
{
state.SetMaterial(tex, UF_Texture, 0, CLAMP_NONE, 0, -1);
state.EnableModelMatrix(true);
state.EnableTextureMatrix(true);
SetupMatrices(tex, x_offset, y_offset, mirror, mode, state.mModelMatrix, state.mTextureMatrix, tiled);
}
int rc = mRows + 1;
// The caps only get drawn for the main layer but not for the overlay.
if (mode == FSkyVertexBuffer::SKYMODE_MAINLAYER && tex != NULL)
{
auto& col = R_GetSkyCapColor(tex);
state.SetObjectColor(col.first);
state.EnableTexture(false);
RenderRow(state, DT_TriangleFan, 0);
state.SetObjectColor(col.second);
RenderRow(state, DT_TriangleFan, rc);
state.EnableTexture(true);
}
state.SetObjectColor(0xffffffff);
for (int i = 1; i <= mRows; i++)
{
RenderRow(state, DT_TriangleStrip, i, i == 1);
RenderRow(state, DT_TriangleStrip, rc + i, false);
}
state.EnableTextureMatrix(false);
state.EnableModelMatrix(false);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void FSkyVertexBuffer::RenderBox(FRenderState& state, FTextureID texno, FSkyBox* tex, float x_offset, bool sky2, float stretch, const FVector3& skyrotatevector, const FVector3& skyrotatevector2)
{
int faces;
state.EnableModelMatrix(true);
state.mModelMatrix.loadIdentity();
state.mModelMatrix.scale(1, 1 / stretch, 1); // Undo the map's vertical scaling as skyboxes are true cubes.
if (!sky2)
state.mModelMatrix.rotate(-180.0f + x_offset, skyrotatevector.X, skyrotatevector.Z, skyrotatevector.Y);
else
state.mModelMatrix.rotate(-180.0f + x_offset, skyrotatevector2.X, skyrotatevector2.Z, skyrotatevector2.Y);
if (tex->GetSkyFace(5))
{
faces = 4;
// north
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(0), 4);
// east
state.SetMaterial(tex->GetSkyFace(1), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(1), 4);
// south
state.SetMaterial(tex->GetSkyFace(2), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(2), 4);
// west
state.SetMaterial(tex->GetSkyFace(3), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(3), 4);
}
else
{
faces = 1;
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(-1), 10);
}
// top
state.SetMaterial(tex->GetSkyFace(faces), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(tex->GetSkyFlip() ? 6 : 5), 4);
// bottom
state.SetMaterial(tex->GetSkyFace(faces + 1), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, FaceStart(4), 4);
state.EnableModelMatrix(false);
}

View file

@ -3,6 +3,8 @@
#include "v_palette.h"
#include "matrix.h"
#include "hwrenderer/data/buffers.h"
#include "hw_renderstate.h"
#include "skyboxtexture.h"
class FGameTexture;
class FRenderState;
@ -70,7 +72,7 @@ public:
FSkyVertexBuffer();
~FSkyVertexBuffer();
void SetupMatrices(HWDrawInfo *di, FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelmatrix, VSMatrix &textureMatrix);
void SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelmatrix, VSMatrix &textureMatrix, bool tiled);
std::pair<IVertexBuffer *, IIndexBuffer *> GetBufferObjects() const
{
return std::make_pair(mVertexBuffer, nullptr);
@ -82,4 +84,8 @@ public:
else return mSideStart;
}
void RenderRow(FRenderState& state, EDrawType prim, int row, bool apply = true);
void RenderDome(FRenderState& state, FGameTexture* tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled);
void RenderBox(FRenderState& state, FTextureID texno, FSkyBox* tex, float x_offset, bool sky2, float stretch, const FVector3& skyrotatevector, const FVector3& skyrotatevector2);
};

View file

@ -31,119 +31,6 @@
#include "hw_renderstate.h"
#include "skyboxtexture.h"
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void HWSkyPortal::RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim, int row, bool apply)
{
state.Draw(prim, vertexBuffer->mPrimStart[row], vertexBuffer->mPrimStart[row + 1] - vertexBuffer->mPrimStart[row]);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void HWSkyPortal::RenderDome(HWDrawInfo *di, FRenderState &state, FGameTexture * tex, float x_offset, float y_offset, bool mirror, int mode)
{
if (tex)
{
state.SetMaterial(tex, UF_Texture, 0, CLAMP_NONE, 0, -1);
state.EnableModelMatrix(true);
state.EnableTextureMatrix(true);
vertexBuffer->SetupMatrices(di, 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 == FSkyVertexBuffer::SKYMODE_MAINLAYER && tex != NULL)
{
auto &col = R_GetSkyCapColor(tex);
state.SetObjectColor(col.first);
state.EnableTexture(false);
RenderRow(di, state, DT_TriangleFan, 0);
state.SetObjectColor(col.second);
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, FSkyBox * tex, float x_offset, bool sky2)
{
int faces;
state.EnableModelMatrix(true);
state.mModelMatrix.loadIdentity();
state.mModelMatrix.scale(1, 1 / di->Level->info->pixelstretch, 1); // Undo the map's vertical scaling as skyboxes are true cubes.
if (!sky2)
state.mModelMatrix.rotate(-180.0f+x_offset, di->Level->info->skyrotatevector.X, di->Level->info->skyrotatevector.Z, di->Level->info->skyrotatevector.Y);
else
state.mModelMatrix.rotate(-180.0f+x_offset, di->Level->info->skyrotatevector2.X, di->Level->info->skyrotatevector2.Z, di->Level->info->skyrotatevector2.Y);
if (tex->GetSkyFace(5))
{
faces=4;
// north
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(0), 4);
// east
state.SetMaterial(tex->GetSkyFace(1), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(1), 4);
// south
state.SetMaterial(tex->GetSkyFace(2), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(2), 4);
// west
state.SetMaterial(tex->GetSkyFace(3), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(3), 4);
}
else
{
faces=1;
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(-1), 10);
}
// top
state.SetMaterial(tex->GetSkyFace(faces), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(tex->GetSkyFlip() ? 6 : 5), 4);
// bottom
state.SetMaterial(tex->GetSkyFace(faces+1), UF_Texture, 0, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(4), 4);
state.EnableModelMatrix(false);
}
//-----------------------------------------------------------------------------
//
//
@ -175,7 +62,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
auto skybox = origin->texture[0] ? dynamic_cast<FSkyBox*>(origin->texture[0]->GetTexture()) : nullptr;
if (skybox)
{
RenderBox(di, state, origin->skytexno1, skybox, origin->x_offset[0], origin->sky2);
vertexBuffer->RenderBox(state, origin->skytexno1, skybox, origin->x_offset[0], origin->sky2, di->Level->info->pixelstretch, di->Level->info->skyrotatevector, di->Level->info->skyrotatevector2);
}
else
{
@ -184,7 +71,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
if (origin->texture[0])
{
state.SetTextureMode(TM_OPAQUE);
RenderDome(di, state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER);
vertexBuffer->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
state.SetTextureMode(TM_NORMAL);
}
@ -192,7 +79,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
if (origin->doublesky && origin->texture[1])
{
RenderDome(di, state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER);
vertexBuffer->RenderDome(state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
}
if (di->Level->skyfog>0 && !di->isFullbrightScene() && (origin->fadecolor & 0xffffff) != 0)

View file

@ -38,6 +38,7 @@
#include "v_font.h"
#include "texturemanager.h"
#include "modelrenderer.h"
#include "hwrenderer/models/hw_models.h"
#include "d_main.h"
EXTERN_CVAR(Bool, gl_precache)
@ -87,6 +88,7 @@ static void PrecacheSprite(FGameTexture *tex, SpriteHits &hits)
if (gltex) PrecacheList(gltex, hits);
}
//==========================================================================
//
// DFrameBuffer :: Precache
@ -315,7 +317,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
FImageSource::EndPrecaching();
// cache all used models
FModelRenderer *renderer = screen->CreateModelRenderer(-1);
FModelRenderer* renderer = new FHWModelRenderer(nullptr, *screen->RenderState(), -1);
for (unsigned i = 0; i < Models.Size(); i++)
{
if (modellist[i])

View file

@ -321,11 +321,6 @@ IHardwareTexture *PolyFrameBuffer::CreateHardwareTexture()
return new PolyHardwareTexture();
}
FModelRenderer *PolyFrameBuffer::CreateModelRenderer(int mli)
{
return new FHWModelRenderer(nullptr, *GetRenderState(), mli);
}
IVertexBuffer *PolyFrameBuffer::CreateVertexBuffer()
{
return new PolyVertexBuffer();

View file

@ -45,7 +45,6 @@ public:
//void SetSceneRenderTarget(bool useSSAO) override;
IHardwareTexture *CreateHardwareTexture() override;
FModelRenderer *CreateModelRenderer(int mli) override;
IVertexBuffer *CreateVertexBuffer() override;
IIndexBuffer *CreateIndexBuffer() override;
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override;

View file

@ -57,45 +57,6 @@ CUSTOM_CVAR (Int, r_skymode, 2, CVAR_ARCHIVE|CVAR_NOINITCALL)
CVAR(Float, skyoffset, 0, 0) // for testing
struct SkyColor
{
FTextureID Texture;
std::pair<PalEntry, PalEntry> Colors;
};
static TArray<SkyColor> SkyColors;
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex)
{
for (auto& sky : SkyColors)
{
if (sky.Texture == tex->GetID()) return sky.Colors;
}
auto itex = tex->GetTexture();
SkyColor sky;
FBitmap bitmap = itex->GetBgraBitmap(nullptr);
int w = bitmap.GetWidth();
int h = bitmap.GetHeight();
const uint32_t* buffer = (const uint32_t*)bitmap.GetPixels();
if (buffer)
{
sky.Colors.first = averageColor((uint32_t*)buffer, w * MIN(30, h), 0);
if (h > 30)
{
sky.Colors.second = averageColor(((uint32_t*)buffer) + (h - 30) * w, w * 30, 0);
}
else sky.Colors.second = sky.Colors.first;
}
sky.Texture = tex->GetID();
SkyColors.Push(sky);
return SkyColors.Last().Colors;
}
//==========================================================================
//
// R_InitSkyMap

View file

@ -44,11 +44,5 @@ void R_InitSkyMap();
void R_UpdateSky (uint64_t mstime);
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
// 57 world units roughly represent one sky texel for the glTranslate call.
enum
{
skyoffsetfactor = 57
};
#endif //__R_SKY_H__

View file

@ -59,6 +59,8 @@ CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
EXTERN_CVAR(Int, r_skymode)
EXTERN_CVAR(Bool, cl_oldfreelooklimit)
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
namespace swrenderer
{
static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true)

View file

@ -397,11 +397,6 @@ FMaterial* VulkanFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags)
return new VkMaterial(tex, scaleflags);
}
FModelRenderer *VulkanFrameBuffer::CreateModelRenderer(int mli)
{
return new FHWModelRenderer(nullptr, *GetRenderState(), mli);
}
IVertexBuffer *VulkanFrameBuffer::CreateVertexBuffer()
{
return new VKVertexBuffer();

View file

@ -91,7 +91,6 @@ public:
IHardwareTexture *CreateHardwareTexture() override;
FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags) override;
FModelRenderer *CreateModelRenderer(int mli) override;
IVertexBuffer *CreateVertexBuffer() override;
IIndexBuffer *CreateIndexBuffer() override;
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override;