mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 14:52:01 +00:00
- draw regular sprites.
Mostly functional, but the projected size is off.
This commit is contained in:
parent
7c991d59ac
commit
fa44d75e98
10 changed files with 462 additions and 196 deletions
|
@ -183,6 +183,11 @@ FRenderViewpoint SetupViewpoint(spritetype* cam, const vec3_t& position, int sec
|
|||
r_viewpoint.HWAngles.Roll = -rollang.asdeg();
|
||||
r_viewpoint.FieldOfView = (float)r_fov;
|
||||
r_viewpoint.RotAngle = angle.asbam();
|
||||
double FocalTangent = tan(r_viewpoint.FieldOfView.Radians() / 2);
|
||||
DAngle an = 270. - r_viewpoint.HWAngles.Yaw.Degrees;
|
||||
r_viewpoint.TanSin = FocalTangent * an.Sin();
|
||||
r_viewpoint.TanCos = FocalTangent * an.Cos();
|
||||
|
||||
return r_viewpoint;
|
||||
}
|
||||
|
||||
|
|
|
@ -328,8 +328,11 @@ void HWDrawInfo::DispatchSprites()
|
|||
switch (tspr->cstat & CSTAT_SPRITE_ALIGNMENT)
|
||||
{
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
// face sprite
|
||||
{
|
||||
HWSprite sprite;
|
||||
sprite.Process(this, tspr, §or[tspr->sectnum], false);
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||
{
|
||||
|
|
|
@ -42,6 +42,8 @@ struct FRenderViewpoint
|
|||
int* SectNums;
|
||||
int SectCount;
|
||||
double TicFrac;
|
||||
double TanCos, TanSin; // needed for calculating a sprite's screen depth.
|
||||
|
||||
};
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -249,7 +249,14 @@ void HWDrawList::SortPlaneIntoPlane(SortNode * head,SortNode * sort)
|
|||
HWFlat * fs= flats[drawitems[sort->itemindex].index];
|
||||
|
||||
if (fh->z == fs->z)
|
||||
head->AddToEqual(sort);
|
||||
{
|
||||
// Make sure we have consistent ordering with two floor sprites of the same distance if they overlap
|
||||
int time1 = fh->sprite ? fh->sprite->time : -1;
|
||||
int time2 = fs->sprite ? fs->sprite->time : -1;
|
||||
if (time1 == time2) head->AddToEqual(sort);
|
||||
else if (time2 < time1)head->AddToLeft(sort);
|
||||
else head->AddToRight(sort);
|
||||
}
|
||||
else if ( (fh->z<fs->z && fh->plane) || (fh->z>fs->z && !fh->plane))
|
||||
head->AddToLeft(sort);
|
||||
else
|
||||
|
@ -397,11 +404,14 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sor
|
|||
|
||||
if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ)
|
||||
{
|
||||
if (ws->type==RENDERWALL_FOGBOUNDARY && wh->type!=RENDERWALL_FOGBOUNDARY)
|
||||
int time1 = wh->sprite ? wh->sprite->time : -1;
|
||||
int time2 = ws->sprite ? ws->sprite->time : -1;
|
||||
|
||||
if ((ws->type==RENDERWALL_FOGBOUNDARY && wh->type!=RENDERWALL_FOGBOUNDARY) || time2 < time1)
|
||||
{
|
||||
head->AddToRight(sort);
|
||||
}
|
||||
else if (ws->type!=RENDERWALL_FOGBOUNDARY && wh->type==RENDERWALL_FOGBOUNDARY)
|
||||
else if ((ws->type!=RENDERWALL_FOGBOUNDARY && wh->type==RENDERWALL_FOGBOUNDARY) || time2 > time1)
|
||||
{
|
||||
head->AddToLeft(sort);
|
||||
}
|
||||
|
|
|
@ -116,20 +116,11 @@ void HWDrawInfo::AddFlat(HWFlat *flat)
|
|||
//==========================================================================
|
||||
void HWDrawInfo::AddSprite(HWSprite *sprite, bool translucent)
|
||||
{
|
||||
#if 0
|
||||
int list;
|
||||
// [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass.
|
||||
if (translucent || ( (!spriteIsModelOrVoxel(sprite->actor) && !(sprite->actor->cstat & CSTAT_SPRITE_ALIGNMENT_MASK))))
|
||||
{
|
||||
list = GLDL_TRANSLUCENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = GLDL_MODELS;
|
||||
}
|
||||
if (translucent || sprite->modelframe == 0) list = GLDL_TRANSLUCENT;
|
||||
else list = GLDL_MODELS;
|
||||
|
||||
auto newsprt = drawlists[list].NewSprite();
|
||||
*newsprt = *sprite;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -251,7 +251,6 @@ public:
|
|||
FGameTexture *texture;
|
||||
|
||||
float z; // the z position of the flat (only valid for non-sloped planes)
|
||||
FColormap Colormap; // light and fog
|
||||
|
||||
PalEntry fade;
|
||||
int shade, palette, visibility;
|
||||
|
@ -287,50 +286,39 @@ public:
|
|||
class HWSprite
|
||||
{
|
||||
public:
|
||||
int lightlevel;
|
||||
uint8_t foglevel;
|
||||
uint8_t hw_styleflags;
|
||||
bool fullbright;
|
||||
bool polyoffset;
|
||||
FColormap Colormap;
|
||||
int modeltype;
|
||||
FRenderStyle RenderStyle;
|
||||
int OverrideShader;
|
||||
|
||||
int translation;
|
||||
spritetype* sprite;
|
||||
PalEntry fade;
|
||||
int shade, palette, visibility;
|
||||
float alpha;
|
||||
FRenderStyle RenderStyle;
|
||||
int modelframe; // : sprite, 1: model, <0:voxel index
|
||||
|
||||
int index;
|
||||
float depth;
|
||||
int vertexindex;
|
||||
|
||||
float topclip;
|
||||
float bottomclip;
|
||||
|
||||
float x,y,z; // needed for sorting!
|
||||
|
||||
float ul,ur;
|
||||
float vt,vb;
|
||||
float x1,y1,z1;
|
||||
float x2,y2,z2;
|
||||
float trans;
|
||||
int dynlightindex;
|
||||
|
||||
FGameTexture *texture;
|
||||
spritetype * actor;
|
||||
//TArray<lightlist_t> *lightlist;
|
||||
DRotator Angles;
|
||||
|
||||
|
||||
void SplitSprite(HWDrawInfo *di, sectortype * frontsector, bool translucent);
|
||||
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
|
||||
bool CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp);
|
||||
void CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp);
|
||||
|
||||
public:
|
||||
|
||||
void CreateVertices(HWDrawInfo* di) {}
|
||||
void CreateVertices(HWDrawInfo* di);
|
||||
void PutSprite(HWDrawInfo *di, bool translucent);
|
||||
void Process(HWDrawInfo *di, AActor* thing,sectortype * sector, int thruportal = false);
|
||||
void Process(HWDrawInfo *di, spritetype* thing,sectortype * sector, int thruportal = false);
|
||||
|
||||
void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent) {}
|
||||
void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -188,11 +188,17 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
}
|
||||
|
||||
// The shade rgb from the tint is ignored here.
|
||||
state.SetColor(PalEntry(255, globalr, globalg, globalb));
|
||||
state.SetColorAlpha(PalEntry(255, globalr, globalg, globalb), alpha);
|
||||
|
||||
if (translucent)
|
||||
{
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
state.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
state.SetRenderStyle(RenderStyle);
|
||||
state.SetTextureMode(RenderStyle);
|
||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
}
|
||||
|
@ -203,6 +209,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
vertexcount += vertcount;
|
||||
|
||||
if (translucent) state.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
||||
state.EnableBrightmap(true);
|
||||
|
||||
//state.SetObjectColor(0xffffffff);
|
||||
//state.SetAddColor(0);
|
||||
//state.ApplyTextureManipulation(nullptr);
|
||||
|
|
|
@ -560,11 +560,15 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
|||
vp.SectNums = nullptr;
|
||||
vp.SectCount = line->sector;
|
||||
|
||||
|
||||
vp.Pos.X = newx / 16.f;
|
||||
vp.Pos.Y = newy / -16.f;
|
||||
vp.HWAngles.Yaw = -90.f + q16ang(newan).asdeg();
|
||||
|
||||
double FocalTangent = tan(vp.FieldOfView.Radians() / 2);
|
||||
DAngle an = 270. - vp.HWAngles.Yaw.Degrees;
|
||||
vp.TanSin = FocalTangent * an.Sin();
|
||||
vp.TanCos = FocalTangent * an.Cos();
|
||||
|
||||
int oldstat = 0;
|
||||
if (vp.CameraSprite)
|
||||
{
|
||||
|
|
|
@ -1,160 +1,419 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_sprite.cpp
|
||||
** Sprite/Particle rendering
|
||||
**
|
||||
*/
|
||||
|
||||
#if 0
|
||||
void polymost_drawsprite(int32_t snum)
|
||||
#include "matrix.h"
|
||||
//#include "models.h"
|
||||
#include "vectors.h"
|
||||
#include "texturemanager.h"
|
||||
#include "basics.h"
|
||||
|
||||
//#include "hw_models.h"
|
||||
#include "hw_drawstructs.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_portal.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "hw_clock.h"
|
||||
#include "hw_material.h"
|
||||
#include "hw_dynlightdata.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "hw_renderstate.h"
|
||||
|
||||
extern PalEntry GlobalMapFog;
|
||||
extern float GlobalFogDensity;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
||||
{
|
||||
bool additivefog = false;
|
||||
bool foglayer = false;
|
||||
auto& vp = di->Viewpoint;
|
||||
|
||||
vec2_t off = { 0, 0 };
|
||||
|
||||
if ((globalorientation & 48) != 48) // only non-voxel sprites should do this
|
||||
if (translucent)
|
||||
{
|
||||
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize;
|
||||
off = { (int32_t)tspr->xoffset + (flag ? TileFiles.tiledata[globalpicnum].h_xoffs : tileLeftOffset(globalpicnum)),
|
||||
(int32_t)tspr->yoffset + (flag ? TileFiles.tiledata[globalpicnum].h_yoffs : tileTopOffset(globalpicnum)) };
|
||||
// The translucent pass requires special setup for the various modes.
|
||||
|
||||
// for special render styles brightmaps would not look good - especially for subtractive.
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
state.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
|
||||
state.SetRenderStyle(RenderStyle);
|
||||
state.SetTextureMode(RenderStyle);
|
||||
|
||||
if (tspr->cstat & 2)
|
||||
method = DAMETH_CLAMPED | ((tspr->cstat & 512) ? DAMETH_TRANS2 : DAMETH_TRANS1);
|
||||
if (!texture || !texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
else state.AlphaFunc(Alpha_Greater, 0.f);
|
||||
|
||||
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
|
||||
if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
{
|
||||
additivefog = true;
|
||||
}
|
||||
}
|
||||
|
||||
drawpoly_alpha = spriteext[spritenum].alpha;
|
||||
drawpoly_blend = tspr->blend;
|
||||
|
||||
sec = (usectorptr_t)§or[tspr->sectnum];
|
||||
if (dynlightindex == -1) // only set if we got no light buffer index. This covers all cases where sprite lighting is used.
|
||||
{
|
||||
float out[3] = {};
|
||||
//di->GetDynSpriteLight(gl_light_sprites ? actor : nullptr, gl_light_particles ? particle : nullptr, out);
|
||||
//state.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
|
||||
vec3_t pos = tspr->pos;
|
||||
if (RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
fade = 0;
|
||||
additivefog = true;
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
if (!modelframe)
|
||||
{
|
||||
// non-black fog with subtractive style needs special treatment
|
||||
if (fade != 0)
|
||||
{
|
||||
foglayer = true;
|
||||
// Due to the two-layer approach we need to force an alpha test that lets everything pass
|
||||
state.AlphaFunc(Alpha_Greater, 0);
|
||||
}
|
||||
}
|
||||
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
|
||||
}
|
||||
|
||||
vec2_t tsiz;
|
||||
|
||||
if (hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize)
|
||||
tsiz = { TileFiles.tiledata[globalpicnum].h_xsize, TileFiles.tiledata[globalpicnum].h_ysize };
|
||||
// Fog must be done before the texture so that the texture selector can override it.
|
||||
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
||||
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
||||
// Disable brightmaps if non-black fog is used.
|
||||
if (ShadeDiv >= 1 / 1000.f && foggy && !foglayer)
|
||||
{
|
||||
state.EnableFog(1);
|
||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
||||
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density);
|
||||
state.SetSoftLightLevel(255);
|
||||
state.SetLightParms(128.f, 1 / 1000.f);
|
||||
}
|
||||
else
|
||||
tsiz = { tileWidth(globalpicnum), tileHeight(globalpicnum) };
|
||||
{
|
||||
state.EnableFog(0);
|
||||
state.SetFog(0, 0);
|
||||
state.SetSoftLightLevel(ShadeDiv >= 1 / 1000.f ? 255 - Scale(shade, 255, numshades) : 255);
|
||||
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
||||
}
|
||||
|
||||
if (tsiz.x <= 0 || tsiz.y <= 0)
|
||||
// The shade rgb from the tint is ignored here.
|
||||
state.SetColorAlpha(PalEntry(255, globalr, globalg, globalb), alpha);
|
||||
|
||||
state.SetMaterial(texture, UF_Texture, 0, 0/*flags & 3*/, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
|
||||
|
||||
|
||||
if (!modelframe)
|
||||
{
|
||||
state.SetNormal(0, 0, 0);
|
||||
|
||||
|
||||
if (screen->BuffersArePersistent())
|
||||
{
|
||||
CreateVertices(di);
|
||||
}
|
||||
state.SetLightIndex(-1);
|
||||
state.Draw(DT_TriangleStrip, vertexindex, 4);
|
||||
|
||||
if (ShadeDiv >= 1 / 1000.f && foggy && foglayer)
|
||||
{
|
||||
// If we get here we know that we have colored fog and no fixed colormap.
|
||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
||||
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density);
|
||||
state.SetTextureMode(TM_FOGLAYER);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.Draw(DT_TriangleStrip, vertexindex, 4);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//FHWModelRenderer renderer(di, state, dynlightindex);
|
||||
//RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac);
|
||||
//state.SetVertexBuffer(screen->mVertexData);
|
||||
}
|
||||
|
||||
if (translucent)
|
||||
{
|
||||
state.EnableBrightmap(true);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
}
|
||||
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.SetAddColor(0);
|
||||
state.EnableTexture(true);
|
||||
state.SetDynLight(0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp)
|
||||
{
|
||||
const auto& HWAngles = di->Viewpoint.HWAngles;
|
||||
|
||||
#if 0 // maybe later, it's a bit more tricky with Build.
|
||||
// [BB] Billboard stuff
|
||||
const bool drawWithXYBillboard = false;
|
||||
const bool drawBillboardFacingCamera = false;
|
||||
|
||||
|
||||
// [Nash] check for special sprite drawing modes
|
||||
if (drawWithXYBillboard || drawBillboardFacingCamera)
|
||||
{
|
||||
// Compute center of sprite
|
||||
float xcenter = (x1 + x2) * 0.5;
|
||||
float ycenter = (y1 + y2) * 0.5;
|
||||
float zcenter = (z1 + z2) * 0.5;
|
||||
float xx = -xcenter + x;
|
||||
float zz = -zcenter + z;
|
||||
float yy = -ycenter + y;
|
||||
Matrix3x4 mat;
|
||||
mat.MakeIdentity();
|
||||
mat.Translate(xcenter, zcenter, ycenter); // move to sprite center
|
||||
|
||||
// Order of rotations matters. Perform yaw rotation (Y, face camera) before pitch (X, tilt up/down).
|
||||
if (drawBillboardFacingCamera)
|
||||
{
|
||||
// [CMB] Rotate relative to camera XY position, not just camera direction,
|
||||
// which is nicer in VR
|
||||
float xrel = xcenter - vp->X;
|
||||
float yrel = ycenter - vp->Y;
|
||||
float absAngleDeg = RAD2DEG(atan2(-yrel, xrel));
|
||||
float counterRotationDeg = 270. - HWAngles.Yaw.Degrees; // counteracts existing sprite rotation
|
||||
float relAngleDeg = counterRotationDeg + absAngleDeg;
|
||||
|
||||
mat.Rotate(0, 1, 0, relAngleDeg);
|
||||
}
|
||||
|
||||
// [fgsfds] calculate yaw vectors
|
||||
float yawvecX = 0, yawvecY = 0, rollDegrees = 0;
|
||||
float angleRad = (270. - HWAngles.Yaw).Radians();
|
||||
|
||||
if (drawWithXYBillboard)
|
||||
{
|
||||
// Rotate the sprite about the vector starting at the center of the sprite
|
||||
// triangle strip and with direction orthogonal to where the player is looking
|
||||
// in the x/y plane.
|
||||
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees);
|
||||
}
|
||||
|
||||
mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center
|
||||
v[0] = mat * FVector3(x1, z1, y1);
|
||||
v[1] = mat * FVector3(x2, z1, y2);
|
||||
v[2] = mat * FVector3(x1, z2, y1);
|
||||
v[3] = mat * FVector3(x2, z2, y2);
|
||||
}
|
||||
else // traditional "Y" billboard mode
|
||||
#endif
|
||||
{
|
||||
v[0] = FVector3(x1, z1, y1);
|
||||
v[1] = FVector3(x2, z1, y2);
|
||||
v[2] = FVector3(x1, z2, y1);
|
||||
v[3] = FVector3(x2, z2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWSprite::CreateVertices(HWDrawInfo* di)
|
||||
{
|
||||
if (modelframe == 0)
|
||||
{
|
||||
FVector3 v[4];
|
||||
CalculateVertices(di, v, &di->Viewpoint.Pos);
|
||||
auto vert = screen->mVertexData->AllocVertices(4);
|
||||
auto vp = vert.first;
|
||||
vertexindex = vert.second;
|
||||
|
||||
vp[0].Set(v[0][0], v[0][1], v[0][2], ul, vt);
|
||||
vp[1].Set(v[1][0], v[1][1], v[1][2], ur, vt);
|
||||
vp[2].Set(v[2][0], v[2][1], v[2][2], ul, vb);
|
||||
vp[3].Set(v[3][0], v[3][1], v[3][2], ur, vb);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline void HWSprite::PutSprite(HWDrawInfo* di, bool translucent)
|
||||
{
|
||||
// That's a lot of checks...
|
||||
/*
|
||||
if (modelframe == 1 && gl_light_sprites)
|
||||
{
|
||||
hw_GetDynModelLight(actor, lightdata);
|
||||
dynlightindex = screen->mLights->UploadLights(lightdata);
|
||||
}
|
||||
else*/
|
||||
dynlightindex = -1;
|
||||
|
||||
vertexindex = -1;
|
||||
if (!screen->BuffersArePersistent())
|
||||
{
|
||||
CreateVertices(di);
|
||||
}
|
||||
di->AddSprite(this, translucent);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int thruportal)
|
||||
{
|
||||
if (spr == nullptr)
|
||||
return;
|
||||
|
||||
vec2f_t const ftsiz = { (float) tsiz.x, (float) tsiz.y };
|
||||
auto tex = tileGetTexture(spr->picnum);
|
||||
if (!tex || !tex->isValid()) return;
|
||||
|
||||
switch ((globalorientation >> 4) & 3)
|
||||
texture = tex;
|
||||
sprite = spr;
|
||||
|
||||
modelframe = 0;
|
||||
dynlightindex = -1;
|
||||
shade = spr->shade;
|
||||
palette = spr->pal;
|
||||
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
||||
visibility = sectorVisibility(sector);
|
||||
|
||||
bool trans = (spr->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
||||
if (trans)
|
||||
{
|
||||
case 0: // Face sprite
|
||||
{
|
||||
// Project 3D to 2D
|
||||
if (globalorientation & 4)
|
||||
off.x = -off.x;
|
||||
// NOTE: yoff not negated not for y flipping, unlike wall and floor
|
||||
// aligned sprites.
|
||||
|
||||
int const ang = (getangle(tspr->x - globalposx, tspr->y - globalposy) + 1024) & 2047;
|
||||
|
||||
float foffs = TSPR_OFFSET(tspr);
|
||||
float foffs2 = TSPR_OFFSET(tspr);
|
||||
if (fabs(foffs2) < fabs(foffs)) foffs = foffs2;
|
||||
|
||||
vec2f_t const offs = { float(bcosf(ang, -6) * foffs), float(bsinf(ang, -6) * foffs) };
|
||||
|
||||
vec2f_t s0 = { (float)(tspr->x - globalposx) + offs.x,
|
||||
(float)(tspr->y - globalposy) + offs.y};
|
||||
|
||||
vec2f_t p0 = { s0.y * gcosang - s0.x * gsinang, s0.x * gcosang2 + s0.y * gsinang2 };
|
||||
|
||||
if (p0.y <= SCISDIST)
|
||||
goto _drawsprite_return;
|
||||
|
||||
float const ryp0 = 1.f / p0.y;
|
||||
s0 = { ghalfx * p0.x * ryp0 + ghalfx, ((float)(pos.z - globalposz)) * gyxscale * ryp0 + ghoriz };
|
||||
|
||||
float const f = ryp0 * fxdimen * (1.0f / 160.f);
|
||||
|
||||
vec2f_t ff = { ((float)tspr->xrepeat) * f,
|
||||
((float)tspr->yrepeat) * f * ((float)yxaspect * (1.0f / 65536.f)) };
|
||||
|
||||
if (tsiz.x & 1)
|
||||
s0.x += ff.x * 0.5f;
|
||||
if (globalorientation & 128 && tsiz.y & 1)
|
||||
s0.y += ff.y * 0.5f;
|
||||
|
||||
s0.x -= ff.x * (float) off.x;
|
||||
s0.y -= ff.y * (float) off.y;
|
||||
|
||||
ff.x *= ftsiz.x;
|
||||
ff.y *= ftsiz.y;
|
||||
|
||||
vec2f_t pxy[4];
|
||||
|
||||
pxy[0].x = pxy[3].x = s0.x - ff.x * 0.5f;
|
||||
pxy[1].x = pxy[2].x = s0.x + ff.x * 0.5f;
|
||||
if (!(globalorientation & 128))
|
||||
{
|
||||
pxy[0].y = pxy[1].y = s0.y - ff.y;
|
||||
pxy[2].y = pxy[3].y = s0.y;
|
||||
RenderStyle = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
||||
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pxy[0].y = pxy[1].y = s0.y - ff.y * 0.5f;
|
||||
pxy[2].y = pxy[3].y = s0.y + ff.y * 0.5f;
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
alpha = 1.f;
|
||||
}
|
||||
|
||||
xtex.d = ytex.d = ytex.u = xtex.v = 0;
|
||||
otex.d = ryp0 * gviewxrange;
|
||||
x = spr->x * (1 / 16.f);
|
||||
z = spr->z * (1 / -256.f);
|
||||
y = spr->y * (1 / -16.f);
|
||||
auto vp = di->Viewpoint;
|
||||
|
||||
if (!(globalorientation & 4))
|
||||
if (modelframe == 0)
|
||||
{
|
||||
xtex.u = ftsiz.x * otex.d / (pxy[1].x - pxy[0].x + .002f);
|
||||
otex.u = -xtex.u * (pxy[0].x - .001f);
|
||||
auto tex = tileGetTexture(spr->picnum);
|
||||
|
||||
|
||||
// abuse the wall sprite function to get the proper coordinates by faking the angle to be facing the camera
|
||||
auto savedang = spr->ang;
|
||||
spr->ang = bamang(di->Viewpoint.RotAngle).asbuild();
|
||||
vec2_t pos[2];
|
||||
GetWallSpritePosition(spr, spr->pos.vec2, pos, true);
|
||||
spr->ang = savedang;
|
||||
|
||||
int height, topofs;
|
||||
if (hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
||||
{
|
||||
height = TileFiles.tiledata[spr->picnum].h_ysize;
|
||||
topofs = (TileFiles.tiledata[spr->picnum].h_yoffs + spr->yoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
xtex.u = ftsiz.x * otex.d / (pxy[0].x - pxy[1].x - .002f);
|
||||
otex.u = -xtex.u * (pxy[1].x + .001f);
|
||||
height = tex->GetTexelHeight();
|
||||
topofs = (tex->GetTexelTopOffset() + spr->yoffset);
|
||||
}
|
||||
|
||||
if (!(globalorientation & 8))
|
||||
if (spr->cstat & CSTAT_SPRITE_YFLIP) topofs = -topofs;
|
||||
|
||||
if (spr->cstat & CSTAT_SPRITE_YFLIP)
|
||||
topofs = -topofs;
|
||||
|
||||
int sprz = spr->z;
|
||||
sprz -= ((topofs * spr->yrepeat) << 2);
|
||||
|
||||
if (spr->cstat & CSTAT_SPRITE_YCENTER)
|
||||
{
|
||||
ytex.v = ftsiz.y * otex.d / (pxy[3].y - pxy[0].y + .002f);
|
||||
otex.v = -ytex.v * (pxy[0].y - .001f);
|
||||
sprz += ((height * spr->yrepeat) << 1);
|
||||
if (height & 1) sprz += (spr->yrepeat << 1); // Odd yspans (taken from polymost as-is)
|
||||
}
|
||||
|
||||
x1 = pos[0].x * (1 / 16.f);
|
||||
y1 = pos[0].y * (1 / -16.f);
|
||||
x2 = pos[1].x * (1 / 16.f);
|
||||
y2 = pos[1].y * (1 / -16.f);
|
||||
z1 = (sprz) * (1 / -256.);
|
||||
z2 = (sprz - ((height * spr->yrepeat) << 2)) * (1 / -256.);
|
||||
ul = (spr->cstat & CSTAT_SPRITE_XFLIP) ? 0.f : 1.f;
|
||||
ur = (spr->cstat & CSTAT_SPRITE_XFLIP) ? 1.f : 0.f;
|
||||
vt = (spr->cstat & CSTAT_SPRITE_YFLIP) ? 0.f : 1.f;
|
||||
vb = (spr->cstat & CSTAT_SPRITE_YFLIP) ? 1.f : 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ytex.v = ftsiz.y * otex.d / (pxy[0].y - pxy[3].y - .002f);
|
||||
otex.v = -ytex.v * (pxy[3].y + .001f);
|
||||
x1 = x2 = x;
|
||||
y1 = y2 = y;
|
||||
z1 = z2 = z;
|
||||
texture = nullptr;
|
||||
}
|
||||
|
||||
// Clip sprites to ceilings/floors when no parallaxing and not sloped
|
||||
if (!(sector[tspr->sectnum].ceilingstat & 3))
|
||||
depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin);
|
||||
|
||||
#if 0 // huh?
|
||||
if ((texture && texture->GetTranslucency()) || (RenderStyle.Flags & STYLEF_RedIsAlpha) || (modelframe && spr->RenderStyle != DefaultRenderStyle()))
|
||||
{
|
||||
s0.y = ((float) (sector[tspr->sectnum].ceilingz - globalposz)) * gyxscale * ryp0 + ghoriz;
|
||||
if (pxy[0].y < s0.y)
|
||||
pxy[0].y = pxy[1].y = s0.y;
|
||||
}
|
||||
|
||||
if (!(sector[tspr->sectnum].floorstat & 3))
|
||||
if (hw_styleflags == STYLEHW_Solid)
|
||||
{
|
||||
s0.y = ((float) (sector[tspr->sectnum].floorz - globalposz)) * gyxscale * ryp0 + ghoriz;
|
||||
if (pxy[2].y > s0.y)
|
||||
pxy[2].y = pxy[3].y = s0.y;
|
||||
RenderStyle.SrcAlpha = STYLEALPHA_Src;
|
||||
RenderStyle.DestAlpha = STYLEALPHA_InvSrc;
|
||||
}
|
||||
|
||||
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
||||
pow2xsplit = 0;
|
||||
polymost_drawpoly(pxy, 4, method, tempsiz);
|
||||
|
||||
drawpoly_srepeat = 0;
|
||||
drawpoly_trepeat = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (automapping == 1 && (unsigned)spritenum < MAXSPRITES)
|
||||
show2dsprite.Set(spritenum);
|
||||
|
||||
_drawsprite_return:
|
||||
;
|
||||
hw_styleflags = STYLEHW_NoAlphaTest;
|
||||
}
|
||||
#endif
|
||||
|
||||
PutSprite(di, alpha < 1.f-FLT_EPSILON || modelframe == 0);
|
||||
rendered_sprites++;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ void HWWall::SetLightAndFog(FRenderState& state)
|
|||
}
|
||||
|
||||
// The shade rgb from the tint is ignored here.
|
||||
state.SetColor(PalEntry(255, globalr, globalg, globalb));
|
||||
state.SetColorAlpha(PalEntry(255, globalr, globalg, globalb), alpha);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -231,11 +231,18 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
|||
|
||||
void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
|
||||
{
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
state.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
state.SetRenderStyle(RenderStyle);
|
||||
state.SetTextureMode(RenderStyle);
|
||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
RenderTexturedWall(di, state, HWWall::RWF_TEXTURED);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.EnableBrightmap(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -392,7 +399,7 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent)
|
|||
if (translucent || (texture && texture->GetTranslucency() && type == RENDERWALL_M2S))
|
||||
{
|
||||
flags |= HWF_TRANSLUCENT;
|
||||
//ViewDistance = (di->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||
ViewDistance = (di->Viewpoint.Pos.XY() - DVector2((glseg.x1 + glseg.x2) * 0.5f, (glseg.y1 + glseg.y2) * 0.5f)).LengthSquared();
|
||||
}
|
||||
|
||||
if (!screen->BuffersArePersistent())
|
||||
|
@ -553,12 +560,6 @@ bool HWWall::DoHorizon(HWDrawInfo* di, walltype* seg, sectortype* fs, DVector2&
|
|||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::ceiling);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetCeilingLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::ceiling];
|
||||
|
||||
if (di->isFullbrightScene()) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
|
@ -574,11 +575,6 @@ bool HWWall::DoHorizon(HWDrawInfo* di, walltype* seg, sectortype* fs, DVector2&
|
|||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::floor);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetFloorLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::floor];
|
||||
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue