- voxel rendering.

The stock voxels of Blood and SW seem to work so far, but not all edge cases have been tested.
This commit is contained in:
Christoph Oelckers 2021-04-02 18:20:07 +02:00
parent c8a75a8664
commit 638f19172a
9 changed files with 153 additions and 26 deletions

View file

@ -1023,7 +1023,6 @@ 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
@ -1073,6 +1072,7 @@ set (PCH_SOURCES
core/gi.cpp core/gi.cpp
core/rendering/hw_entrypoint.cpp core/rendering/hw_entrypoint.cpp
core/rendering/hw_models.cpp
core/rendering/scene/hw_clipper.cpp core/rendering/scene/hw_clipper.cpp
core/rendering/scene/hw_walls.cpp core/rendering/scene/hw_walls.cpp
core/rendering/scene/hw_flats.cpp core/rendering/scene/hw_flats.cpp

View file

@ -12,7 +12,7 @@
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "texturemanager.h" #include "texturemanager.h"
#include "voxels.h" #include "voxels.h"
#include "glbackend/gl_models.h" #include "hw_models.h"
#include "printf.h" #include "printf.h"
#include "palette.h" #include "palette.h"

View file

@ -33,9 +33,7 @@ class VSMatrix {
public: public:
VSMatrix() VSMatrix() = default;
{
}
VSMatrix(int) VSMatrix(int)
{ {

View file

@ -6,7 +6,7 @@
// //
// This program is free software: you can redistribute it and/or modify // 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 // 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 // the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
@ -33,7 +33,7 @@
#include "hwrenderer/data/buffers.h" #include "hwrenderer/data/buffers.h"
#include "flatvertices.h" #include "flatvertices.h"
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "gl_models.h" #include "hw_models.h"
//CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) //CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE)

View file

@ -6,7 +6,7 @@
// //
// This program is free software: you can redistribute it and/or modify // 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 // 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 // the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,

View file

@ -303,14 +303,14 @@ void HWDrawInfo::DispatchSprites()
{ {
if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]])
{ {
//HWSprite hwsprite; HWSprite hwsprite;
//if (hwsprite.ProcessVoxel(voxmodels[tiletovox[tspr->picnum]], tspr)) return; if (hwsprite.ProcessVoxel(this, voxmodels[tiletovox[tspr->picnum]], tspr, &sector[tspr->sectnum])) return;
break; break;
} }
else if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum]) else if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
{ {
//HWSprite hwsprite; HWSprite hwsprite;
//hwsprite.ProcessVoxel(voxmodels[tspr->picnum], tspr); hwsprite.ProcessVoxel(this, voxmodels[tspr->picnum], tspr, &sector[tspr->sectnum]);
break; break;
} }
} }

View file

@ -10,6 +10,7 @@
#include "build.h" #include "build.h"
#include "gamefuncs.h" #include "gamefuncs.h"
#include "render.h" #include "render.h"
#include "matrix.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4244) #pragma warning(disable:4244)
@ -292,7 +293,8 @@ public:
int shade, palette, visibility; int shade, palette, visibility;
float alpha; float alpha;
FRenderStyle RenderStyle; FRenderStyle RenderStyle;
int modelframe; // : sprite, 1: model, <0:voxel index int modelframe; // : sprite, 1: model, -1:voxel
voxmodel_t* voxel;
int index; int index;
float depth; float depth;
@ -300,10 +302,17 @@ public:
float x,y,z; // needed for sorting! float x,y,z; // needed for sorting!
float ul,ur; union
float vt,vb; {
float x1,y1,z1; struct
float x2,y2,z2; {
float ul, ur;
float vt, vb;
float x1, y1, z1;
float x2, y2, z2;
};
VSMatrix rotmat;
};
int dynlightindex; int dynlightindex;
FGameTexture *texture; FGameTexture *texture;
@ -317,6 +326,7 @@ public:
void CreateVertices(HWDrawInfo* di); void CreateVertices(HWDrawInfo* di);
void PutSprite(HWDrawInfo *di, bool translucent); void PutSprite(HWDrawInfo *di, bool translucent);
void Process(HWDrawInfo *di, spritetype* thing,sectortype * sector, int thruportal = false); void Process(HWDrawInfo *di, spritetype* thing,sectortype * sector, int thruportal = false);
bool ProcessVoxel(HWDrawInfo* di, voxmodel_t* voxel, spritetype* tspr, sectortype* sector);
void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent); void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent);
}; };

View file

@ -42,6 +42,8 @@
#include "hw_dynlightdata.h" #include "hw_dynlightdata.h"
#include "hw_lightbuffer.h" #include "hw_lightbuffer.h"
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "hw_models.h"
#include "hw_viewpointbuffer.h"
extern PalEntry GlobalMapFog; extern PalEntry GlobalMapFog;
extern float GlobalFogDensity; extern float GlobalFogDensity;
@ -142,11 +144,9 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
// The shade rgb from the tint is ignored here. // The shade rgb from the tint is ignored here.
state.SetColorAlpha(color, alpha); state.SetColorAlpha(color, alpha);
state.SetMaterial(texture, UF_Texture, 0, CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1); if (modelframe == 0)
if (!modelframe)
{ {
state.SetMaterial(texture, UF_Texture, 0, CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
state.SetNormal(0, 0, 0); state.SetNormal(0, 0, 0);
@ -170,9 +170,27 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
} }
else else
{ {
//FHWModelRenderer renderer(di, state, dynlightindex); state.EnableModelMatrix(true);
//RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac); state.mModelMatrix = rotmat;
//state.SetVertexBuffer(screen->mVertexData); FHWModelRenderer mr(state, dynlightindex);
if (modelframe < 0)
{
auto model = voxel->model;
state.SetDepthFunc(DF_LEqual);
state.EnableTexture(true);
model->BuildVertexBuffer(&mr);
mr.SetupFrame(model, 0, 0, 0);
model->RenderFrame(&mr, TexMan.GetGameTexture(model->GetPaletteTexture()), 0, 0, 0.f, TRANSLATION(Translation_Remap + curbasepal, palette));
state.SetDepthFunc(DF_Less);
state.SetVertexBuffer(screen->mVertexData);
}
else
{
//RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac);
}
state.SetVertexBuffer(screen->mVertexData);
state.EnableModelMatrix(false);
} }
if (translucent) if (translucent)
@ -443,3 +461,104 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
rendered_sprites++; rendered_sprites++;
} }
//==========================================================================
//
//
//
//==========================================================================
bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, sectortype* sector)
{
sprite = spr;
texture = nullptr;
modelframe = -1;
dynlightindex = -1;
shade = spr->shade;
palette = spr->pal;
fade = lookups.getFade(sector->floorpal); // fog is per sector.
visibility = sectorVisibility(sector);
voxel = vox;
if (!vox || (spr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return false;
bool trans = (spr->cstat & CSTAT_SPRITE_TRANSLUCENT);
if (trans)
{
RenderStyle = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
}
else
{
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = 1.f;
}
auto sprext = &spriteext[spr->owner];
FVector3 scalevec = { voxel->scale, voxel->scale, voxel->scale };
FVector3 translatevec = { 0, 0, voxel->zadd * voxel->scale };
float basescale = voxel->bscale / 64.f;
float sprxscale = (float)spr->xrepeat * (256.f / 320.f) * basescale;
if ((::sprite[spr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL)
{
sprxscale *= 1.25f;
translatevec.Y -= spr->xoffset * bcosf(sprext->angoff, -20);
translatevec.X += spr->xoffset * bsinf(sprext->angoff, -20);
}
if (spr->cstat & CSTAT_SPRITE_YFLIP)
{
scalevec.Z = -scalevec.Z;
translatevec.Z = -translatevec.Z;
}
if (spr->cstat & CSTAT_SPRITE_XFLIP)
{
scalevec.X = -scalevec.X;
translatevec.X = -translatevec.X;
translatevec.Y = -translatevec.Y;
}
scalevec.X *= sprxscale;
translatevec.X *= sprxscale;
scalevec.Y *= sprxscale;
translatevec.Y *= sprxscale;
float sprzscale = (float)spr->yrepeat * basescale;
scalevec.Z *= sprzscale;
translatevec.Z *= sprzscale;
float zpos = (float)(spr->z + sprext->position_offset.z);
float zscale = ((spr->cstat & CSTAT_SPRITE_YFLIP) && (::sprite[spr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) != 0) ? -4.f : 4.f;
zpos -= (spr->yoffset * spr->yrepeat) * zscale * voxel->bscale;
x = (spr->x + sprext->position_offset.x) * (1 / 16.f);
z = zpos * (1 / -256.f);
y = (spr->y + sprext->position_offset.y) * (1 / -16.f);
float zoff = voxel->siz.z * .5f;
if (!(spr->cstat & CSTAT_SPRITE_YCENTER))
zoff += voxel->piv.z;
else if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB)
{
zoff += voxel->piv.z;
zoff -= voxel->siz.z * .5f;
}
if (spr->cstat & CSTAT_SPRITE_YFLIP) zoff = voxel->siz.z - zoff;
rotmat.loadIdentity();
rotmat.translate(x + translatevec.X, z - translatevec.Z, y - translatevec.Y);
rotmat.rotate(buildang(spr->ang).asdeg() - 90.f, 0, 1, 0);
rotmat.scale(scalevec.X, scalevec.Z, scalevec.Y);
// Apply pivot last
rotmat.translate(-voxel->piv.x, zoff, voxel->piv.y);
auto vp = di->Viewpoint;
depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin);
PutSprite(di, alpha < 1.f - FLT_EPSILON);
rendered_sprites++;
return true;
}

View file

@ -49,7 +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" #include "hw_models.h"
#include "gamefuncs.h" #include "gamefuncs.h"
CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering") CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering")
@ -136,7 +136,7 @@ void GLInstance::DoDraw()
state.SetDepthFunc(DF_LEqual); state.SetDepthFunc(DF_LEqual);
state.EnableTexture(true); state.EnableTexture(true);
rs.model->BuildVertexBuffer(&mr); rs.model->BuildVertexBuffer(&mr);
mr.SetupFrame(rs.model, rs.mframes[0], rs.mframes[1], rs.mfactor); mr.SetupFrame(rs.model, rs.mframes[0], rs.mframes[1], 0);
rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation); rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation);
state.SetDepthFunc(DF_Less); state.SetDepthFunc(DF_Less);
state.SetVertexBuffer(screen->mVertexData); state.SetVertexBuffer(screen->mVertexData);