- transitioned voxel rendering to use the backend's implementation.

This commit is contained in:
Christoph Oelckers 2021-03-01 20:48:03 +01:00
parent 8d5682fa97
commit bbd5c0ac8b
15 changed files with 274 additions and 1074 deletions

View file

@ -1021,6 +1021,7 @@ set (PCH_SOURCES
glbackend/glbackend.cpp glbackend/glbackend.cpp
glbackend/gl_palmanager.cpp glbackend/gl_palmanager.cpp
glbackend/gl_texture.cpp glbackend/gl_texture.cpp
glbackend/gl_models.cpp
thirdparty/src/md4.cpp thirdparty/src/md4.cpp
@ -1509,6 +1510,7 @@ source_group("Core\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/2d
source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/console/.+") source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/console/.+")
source_group("Core\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/dobject/.+") source_group("Core\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/dobject/.+")
source_group("Core\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/menu/.+") source_group("Core\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/menu/.+")
source_group("Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/glbackend/.+")
source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/.+") source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/.+")
source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+") source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+")
source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+") source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+")

View file

@ -4,6 +4,7 @@
#ifdef USE_OPENGL #ifdef USE_OPENGL
#include "palette.h" #include "palette.h"
#include "gl_hwtexture.h" #include "gl_hwtexture.h"
#include "model_kvx.h"
#if defined(_M_IX86) || defined(_M_AMD64) || defined(__i386) || defined(__x86_64) #if defined(_M_IX86) || defined(_M_AMD64) || defined(__i386) || defined(__x86_64)
#define SHIFTMOD32(a) (a) #define SHIFTMOD32(a) (a)
@ -18,7 +19,8 @@ class FGameTexture;
struct mdmodel_t struct mdmodel_t
{ {
int32_t mdnum, shadeoff;
int32_t mdnum, shadeoff;
float scale, bscale, zadd, yoffset; float scale, bscale, zadd, yoffset;
FGameTexture *texture; FGameTexture *texture;
@ -188,13 +190,10 @@ typedef struct { vert_t v[4]; } voxrect_t;
struct voxmodel_t : public mdmodel_t struct voxmodel_t : public mdmodel_t
{ {
//VOX specific stuff: FVoxelModel* model = nullptr;
voxrect_t *quad; int32_t qcnt, qfacind[7];
int32_t *mytex, mytexx, mytexy;
vec3_t siz; vec3_t siz;
vec3f_t piv; vec3f_t piv;
int32_t is8bit; int32_t is8bit;
TMap<int, FGameTexture*> *texIds;
}; };
EXTERN mdmodel_t **models; EXTERN mdmodel_t **models;
@ -210,8 +209,7 @@ EXTERN int32_t nextmodelid;
EXTERN voxmodel_t *voxmodels[MAXVOXELS]; EXTERN voxmodel_t *voxmodels[MAXVOXELS];
void voxfree(voxmodel_t *m); void voxfree(voxmodel_t *m);
voxmodel_t *voxload(const char *filnam); voxmodel_t *voxload(int lumpnum);
voxmodel_t *loadkvxfrombuf(const char *buffer, int32_t length);
int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr); int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr);
int md3postload_polymer(md3model_t* m); int md3postload_polymer(md3model_t* m);

View file

@ -1596,8 +1596,8 @@ static mdmodel_t *mdload(const char *filnam)
mdmodel_t *vm; mdmodel_t *vm;
int32_t i; int32_t i;
vm = (mdmodel_t *)voxload(filnam); //vm = (mdmodel_t *)voxload(filnam);
if (vm) return vm; //if (vm) return vm;
auto fil = fileSystem.OpenFileReader(filnam); auto fil = fileSystem.OpenFileReader(filnam);

View file

@ -3596,8 +3596,12 @@ void PolymostProcessVoxels(void)
{ {
if (voxfilenames[i]) if (voxfilenames[i])
{ {
voxmodels[i] = voxload(voxfilenames[i]); int lumpnum = fileSystem.FindFile(voxfilenames[i]);
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f); if (lumpnum >= 0)
{
voxmodels[i] = voxload(lumpnum);
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f);
}
DO_FREE_AND_NULL(voxfilenames[i]); DO_FREE_AND_NULL(voxfilenames[i]);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -306,7 +306,7 @@ void FMD3Model::AddSkins(uint8_t *hitlist)
{ {
for (unsigned i = 0; i < Surfaces.Size(); i++) for (unsigned i = 0; i < Surfaces.Size(); i++)
{ {
if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
{ {
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat; hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat;
} }
@ -357,13 +357,16 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
FGameTexture *surfaceSkin = skin; FGameTexture *surfaceSkin = skin;
if (!surfaceSkin) if (!surfaceSkin)
{ {
if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) if (curSpriteMDLFrame)
{ {
surfaceSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true); if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
} {
else if (surf->numSkins > 0 && surf->Skins[0].isValid()) surfaceSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true);
{ }
surfaceSkin = TexMan.GetGameTexture(surf->Skins[0], true); else if (surf->numSkins > 0 && surf->Skins[0].isValid())
{
surfaceSkin = TexMan.GetGameTexture(surf->Skins[0], true);
}
} }
if (!surfaceSkin) if (!surfaceSkin)

View file

@ -636,7 +636,7 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
OBJSurface *surf = &surfaces[i]; OBJSurface *surf = &surfaces[i];
FGameTexture *userSkin = skin; FGameTexture *userSkin = skin;
if (!userSkin) if (!userSkin && curSpriteMDLFrame)
{ {
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
{ {
@ -669,7 +669,7 @@ void FOBJModel::AddSkins(uint8_t* hitlist)
{ {
for (size_t i = 0; i < surfaces.Size(); i++) for (size_t i = 0; i < surfaces.Size(); i++)
{ {
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) if (curSpriteMDLFrame && i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
{ {
// Precache skins manually reassigned by the user. // Precache skins manually reassigned by the user.
// On OBJs with lots of skins, such as Doom map OBJs exported from GZDB, // On OBJs with lots of skins, such as Doom map OBJs exported from GZDB,

View file

@ -242,7 +242,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int f
FGameTexture *sskin = skin; FGameTexture *sskin = skin;
if ( !sskin ) if ( !sskin )
{ {
if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() ) if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() )
sskin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum], true); sskin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum], true);
if ( !sskin ) if ( !sskin )
{ {
@ -303,7 +303,7 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
void FUE1Model::AddSkins( uint8_t *hitlist ) void FUE1Model::AddSkins( uint8_t *hitlist )
{ {
for ( int i=0; i<numGroups; i++ ) for ( int i=0; i<numGroups; i++ )
if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() ) if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() )
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].GetIndex()] |= FTextureManager::HIT_Flat; hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].GetIndex()] |= FTextureManager::HIT_Flat;
} }

View file

@ -37,6 +37,7 @@
#include "texturemanager.h" #include "texturemanager.h"
#include "palettecontainer.h" #include "palettecontainer.h"
#include "textures.h" #include "textures.h"
#include "imagehelpers.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data #pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data
@ -99,6 +100,7 @@ TArray<uint8_t> FVoxelTexture::CreatePalettedPixels(int conversion)
pe.b = (pp[2] << 2) | (pp[2] >> 4); pe.b = (pp[2] << 2) | (pp[2] >> 4);
// Alphatexture handling is just for completeness, but rather unlikely to be used ever. // Alphatexture handling is just for completeness, but rather unlikely to be used ever.
Pixels[i] = conversion == luminance ? pe.r : ColorMatcher.Pick(pe); Pixels[i] = conversion == luminance ? pe.r : ColorMatcher.Pick(pe);
} }
} }
else else
@ -108,6 +110,7 @@ TArray<uint8_t> FVoxelTexture::CreatePalettedPixels(int conversion)
Pixels[i] = (uint8_t)i; Pixels[i] = (uint8_t)i;
} }
} }
ImageHelpers::FlipSquareBlock(Pixels.Data(), Width);
return Pixels; return Pixels;
} }

View file

@ -101,8 +101,7 @@ void tileProcessGLVoxels(void)
auto index = fileSystem.FindResource(i, "KVX"); auto index = fileSystem.FindResource(i, "KVX");
if (index >= 0) if (index >= 0)
{ {
auto data = fileSystem.ReadFile(index); voxmodels[i] = voxload(index);
voxmodels[i] = loadkvxfrombuf((const char*)data.GetMem(), data.GetSize());
} }
} }
} }

View file

@ -0,0 +1,118 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2005-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/
//
//--------------------------------------------------------------------------
//
/*
** gl_models.cpp
**
** hardware renderer model handling code
**
**/
#include "filesystem.h"
#include "i_time.h"
#include "cmdlib.h"
#include "hw_material.h"
#include "hwrenderer/data/buffers.h"
#include "flatvertices.h"
#include "hw_renderstate.h"
#include "gl_models.h"
//CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE)
VSMatrix FHWModelRenderer::GetViewToWorldMatrix()
{
VSMatrix objectToWorldMatrix(0);
//di->VPUniforms.mViewMatrix.inverseMatrix(objectToWorldMatrix);
return objectToWorldMatrix;
}
void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
{
state.SetDepthFunc(DF_LEqual);
state.EnableTexture(true);
state.SetCulling(mirrored ? Cull_CCW : Cull_CW);
state.mModelMatrix = objectToWorldMatrix;
state.EnableModelMatrix(true);
}
void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
{
state.EnableModelMatrix(false);
state.SetDepthFunc(DF_Less);
state.SetCulling(Cull_None);
}
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored)
{
state.SetDepthFunc(DF_LEqual);
state.SetCulling(mirrored ? Cull_CCW : Cull_CW);
state.mModelMatrix = objectToWorldMatrix;
state.EnableModelMatrix(true);
}
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style)
{
state.EnableModelMatrix(false);
state.SetDepthFunc(DF_Less);
state.SetCulling(Cull_None);
}
IModelVertexBuffer *FHWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
{
return new FModelVertexBuffer(needindex, singleframe);
}
void FHWModelRenderer::SetInterpolation(double inter)
{
state.SetInterpolationFactor((float)inter);
}
void FHWModelRenderer::SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation)
{
state.SetMaterial(skin, UF_Skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1);
state.SetLightIndex(modellightindex);
}
void FHWModelRenderer::DrawArrays(int start, int count)
{
state.Draw(DT_Triangles, start, count);
}
void FHWModelRenderer::DrawElements(int numIndices, size_t offset)
{
state.DrawIndexed(DT_Triangles, int(offset / sizeof(unsigned int)), numIndices);
}
//===========================================================================
//
//
//
//===========================================================================
void FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size)
{
auto mdbuff = static_cast<FModelVertexBuffer*>(model->GetVertexBuffer(GetType()));
state.SetVertexBuffer(mdbuff->vertexBuffer(), frame1, frame2);
if (mdbuff->indexBuffer()) state.SetIndexBuffer(mdbuff->indexBuffer());
}

View file

@ -0,0 +1,58 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2005-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/
//
//--------------------------------------------------------------------------
//
#pragma once
#include "tarray.h"
#include "voxels.h"
#include "hwrenderer/data/buffers.h"
#include "hw_modelvertexbuffer.h"
#include "modelrenderer.h"
class HWSprite;
struct HWDrawInfo;
class FRenderState;
class FHWModelRenderer : public FModelRenderer
{
friend class FModelVertexBuffer;
int modellightindex = -1;
FRenderState &state;
public:
FHWModelRenderer(FRenderState &st, int mli) : modellightindex(mli), state(st)
{}
ModelRendererType GetType() const override { return GLModelRendererType; }
void BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
VSMatrix GetViewToWorldMatrix() override;
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
void EndDrawHUDModel(FRenderStyle style) override;
void SetInterpolation(double interpolation) override;
void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override;
void DrawArrays(int start, int count) override;
void DrawElements(int numIndices, size_t offset) override;
void SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size) override;
};

View file

@ -49,6 +49,7 @@
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "hw_cvars.h" #include "hw_cvars.h"
#include "gamestruct.h" #include "gamestruct.h"
#include "gl_models.h"
CVAR(Bool, gl_texture, true, 0) CVAR(Bool, gl_texture, true, 0)
@ -111,11 +112,28 @@ void GLInstance::DoDraw()
lastState.Flags = ~rendercommands[0].StateFlags; // Force ALL flags to be considered 'changed'. lastState.Flags = ~rendercommands[0].StateFlags; // Force ALL flags to be considered 'changed'.
lastState.DepthFunc = INT_MIN; // Something totally invalid. lastState.DepthFunc = INT_MIN; // Something totally invalid.
screen->RenderState()->EnableMultisampling(true); screen->RenderState()->EnableMultisampling(true);
auto& state = *screen->RenderState();
for (auto& rs : rendercommands) for (auto& rs : rendercommands)
{ {
if (rs.Apply(*screen->RenderState(), lastState)) if (rs.Apply(state, lastState))
screen->RenderState()->Draw(rs.primtype, rs.vindex, rs.vcount); {
if (!rs.model)
{
state.Draw(rs.primtype, rs.vindex, rs.vcount);
}
else
{
FHWModelRenderer mr(*screen->RenderState(), 0);
state.SetDepthFunc(DF_LEqual);
state.EnableTexture(true);
rs.model->BuildVertexBuffer(&mr);
mr.SetupFrame(rs.model, rs.mframes[0], rs.mframes[1], rs.mfactor);
rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation);
state.SetDepthFunc(DF_Less);
state.SetVertexBuffer(screen->mVertexData);
}
}
} }
renderState.Apply(*screen->RenderState(), lastState); // apply any pending change before returning. renderState.Apply(*screen->RenderState(), lastState); // apply any pending change before returning.
rendercommands.Clear(); rendercommands.Clear();

View file

@ -329,6 +329,14 @@ public:
} }
bool SetTexture(FGameTexture* tex, int palette, int sampleroverride, bool notindexed = false); bool SetTexture(FGameTexture* tex, int palette, int sampleroverride, bool notindexed = false);
void SetModel(FModel* model, int frame1, int frame2, float factor)
{
renderState.model = model;
renderState.mframes[0] = frame1;
renderState.mframes[1] = frame2;
renderState.mfactor = factor;
}
}; };
extern GLInstance GLInterface; extern GLInstance GLInterface;

View file

@ -5,6 +5,7 @@
#include "renderstyle.h" #include "renderstyle.h"
struct GLState; struct GLState;
class FMaterial; class FMaterial;
class FModel;
enum EMatrixType enum EMatrixType
{ {
@ -79,6 +80,9 @@ struct PolymostRenderState
short matrixIndex[NUMMATRICES] = { -1 }; short matrixIndex[NUMMATRICES] = { -1 };
FDepthBiasState mBias{ }; FDepthBiasState mBias{ };
PolymostTextureState mMaterial; PolymostTextureState mMaterial;
FModel* model = nullptr;
int mframes[2] = { 0,0 };
float mfactor = 0;
int StateFlags = STF_COLORMASK|STF_DEPTHMASK; int StateFlags = STF_COLORMASK|STF_DEPTHMASK;
FRenderStyle Style{}; FRenderStyle Style{};