From 5f44bc4d5fada75fcd6449c5f947fd083f61c0b0 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 27 Mar 2017 10:55:51 +0300 Subject: [PATCH 1/5] Fixed crash in line portal setup https://mantis.zdoom.org/view.php?id=488 --- src/portal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portal.cpp b/src/portal.cpp index 1ec92799f4..acf6e022de 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -167,7 +167,7 @@ static void BuildBlockmap() void FLinePortalTraverse::AddLineIntercepts(int bx, int by) { - if (by < 0 || by >= PortalBlockmap.dx || bx < 0 || bx >= PortalBlockmap.dy) return; + if (by < 0 || by >= PortalBlockmap.dy || bx < 0 || bx >= PortalBlockmap.dx) return; FPortalBlock &block = PortalBlockmap(bx, by); From ad992d2ffd1d1fd1edd17204061d9fc5a827694d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 27 Mar 2017 10:12:57 +0200 Subject: [PATCH 2/5] - add support for choosing the particle style in the software renderer --- src/swrenderer/drawers/r_draw.cpp | 11 ++++++++--- src/swrenderer/drawers/r_draw.h | 3 ++- src/swrenderer/drawers/r_draw_pal.cpp | 4 +++- src/swrenderer/drawers/r_draw_rgba.cpp | 3 ++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp index a4467266e3..1f7b2d560d 100644 --- a/src/swrenderer/drawers/r_draw.cpp +++ b/src/swrenderer/drawers/r_draw.cpp @@ -64,7 +64,7 @@ namespace swrenderer int fuzzpos; int fuzzviewheight; - uint32_t particle_texture[PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE]; + uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE]; short zeroarray[MAXWIDTH]; short screenheightarray[MAXWIDTH]; @@ -139,6 +139,8 @@ namespace swrenderer void R_InitParticleTexture() { + static_assert(NUM_PARTICLE_TEXTURES == 3, "R_InitParticleTexture must be updated if NUM_PARTICLE_TEXTURES is changed"); + double center = PARTICLE_TEXTURE_SIZE * 0.5f; for (int y = 0; y < PARTICLE_TEXTURE_SIZE; y++) { @@ -147,9 +149,12 @@ namespace swrenderer double dx = (center - x - 0.5f) / center; double dy = (center - y - 0.5f) / center; double dist2 = dx * dx + dy * dy; - double alpha = clamp(1.1f - dist2 * 1.1f, 0.0f, 1.0f); + double round_alpha = clamp(1.7f - dist2 * 1.7f, 0.0f, 1.0f); + double smooth_alpha = clamp(1.1f - dist2 * 1.1f, 0.0f, 1.0f); - particle_texture[x + y * PARTICLE_TEXTURE_SIZE] = (int)(alpha * 128.0f + 0.5f); + particle_texture[0][x + y * PARTICLE_TEXTURE_SIZE] = 128; + particle_texture[1][x + y * PARTICLE_TEXTURE_SIZE] = (int)(round_alpha * 128.0f + 0.5f); + particle_texture[2][x + y * PARTICLE_TEXTURE_SIZE] = (int)(smooth_alpha * 128.0f + 0.5f); } } } diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index 5c37873c85..e9b893aba6 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -44,8 +44,9 @@ namespace swrenderer extern int fuzzpos; extern int fuzzviewheight; + #define NUM_PARTICLE_TEXTURES 3 #define PARTICLE_TEXTURE_SIZE 64 - extern uint32_t particle_texture[PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE]; + extern uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE]; class SWPixelFormatDrawers { diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index 522eb51b15..3f75a30ac8 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -48,6 +48,7 @@ // [SP] r_blendmethod - false = rgb555 matching (ZDoom classic), true = rgb666 (refactored) CVAR(Bool, r_blendmethod, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) +EXTERN_CVAR(Int, gl_particles_style) /* [RH] This translucency algorithm is based on DOSDoom 0.65's, but uses @@ -2946,7 +2947,8 @@ namespace swrenderer uint8_t *dest = thread->dest_for_thread(_dest_y, pitch, _dest); pitch = pitch * thread->num_cores; - const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE]; + int particle_texture_index = MIN(gl_particles_style, NUM_PARTICLE_TEXTURES - 1); + const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE]; uint32_t particle_alpha = _alpha; uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count; diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp index 453071eaef..3dbd38f46b 100644 --- a/src/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/swrenderer/drawers/r_draw_rgba.cpp @@ -780,7 +780,8 @@ namespace swrenderer uint32_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest); int pitch = _pitch * thread->num_cores; - const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE]; + int particle_texture_index = MIN(gl_particles_style, NUM_PARTICLE_TEXTURES - 1); + const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE]; uint32_t particle_alpha = _alpha; uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count; From bed559f763110e0e7bc6c27ccf7b065547d87b4c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 27 Mar 2017 11:55:17 +0300 Subject: [PATCH 3/5] Fixed compilation with GCC/Clang src/g_statusbar/sbar.h:399:23: error: extra qualification on member 'DrawString' --- src/g_statusbar/sbar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index cdb191354c..aee9f7c16a 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -396,7 +396,7 @@ public: uint32_t GetTranslation() const; void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY); - void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY); + void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY); void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); From e865ba60f59f03711558cbd33f3f3bbbbef137c7 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 27 Mar 2017 11:33:16 +0200 Subject: [PATCH 4/5] - support particle styles in softpoly --- src/polyrenderer/drawers/poly_draw_args.cpp | 8 ++++++ src/polyrenderer/drawers/poly_draw_args.h | 1 + src/polyrenderer/scene/poly_particle.cpp | 32 ++++++++++++++++++++- src/polyrenderer/scene/poly_particle.h | 9 ++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index eaa812dc91..64fe7a882a 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -45,6 +45,14 @@ void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane) mClipPlane[3] = plane.D; } +void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height) +{ + mTexturePixels = texels; + mTextureWidth = width; + mTextureHeight = height; + mTranslation = nullptr; +} + void PolyDrawArgs::SetTexture(FTexture *texture) { mTextureWidth = texture->GetWidth(); diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 20c73ec583..87cd6a1915 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -49,6 +49,7 @@ class PolyDrawArgs { public: void SetClipPlane(const PolyClipPlane &plane); + void SetTexture(const uint8_t *texels, int width, int height); void SetTexture(FTexture *texture); void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed); diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index d4a49334b9..53079b6dd3 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -29,6 +29,8 @@ #include "polyrenderer/poly_renderer.h" #include "polyrenderer/scene/poly_light.h" +EXTERN_CVAR(Int, gl_particles_style) + void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) { DVector3 pos = particle->Pos; @@ -76,12 +78,40 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan args.SetSubsectorDepth(subsectorDepth); args.SetSubsectorDepthTest(true); args.SetColor(particle->color | 0xff000000, particle->color >> 24); - args.SetStyle(TriBlendMode::AlphaBlend, particle->alpha, 1.0 - particle->alpha); + args.SetStyle(TriBlendMode::Shaded, particle->alpha, 1.0 - particle->alpha); args.SetTransform(&worldToClip); args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(false); args.SetWriteSubsectorDepth(false); args.SetClipPlane(clipPlane); + args.SetTexture(GetParticleTexture(), ParticleTextureSize, ParticleTextureSize); args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } + +uint8_t *RenderPolyParticle::GetParticleTexture() +{ + static uint8_t particle_texture[NumParticleTextures][ParticleTextureSize * ParticleTextureSize]; + static bool first_call = true; + if (first_call) + { + double center = ParticleTextureSize * 0.5f; + for (int y = 0; y < ParticleTextureSize; y++) + { + for (int x = 0; x < ParticleTextureSize; x++) + { + double dx = (center - x - 0.5f) / center; + double dy = (center - y - 0.5f) / center; + double dist2 = dx * dx + dy * dy; + double round_alpha = clamp(1.7f - dist2 * 1.7f, 0.0f, 1.0f); + double smooth_alpha = clamp(1.1f - dist2 * 1.1f, 0.0f, 1.0f); + + particle_texture[0][x + y * ParticleTextureSize] = 255; + particle_texture[1][x + y * ParticleTextureSize] = (int)(round_alpha * 255.0f + 0.5f); + particle_texture[2][x + y * ParticleTextureSize] = (int)(smooth_alpha * 255.0f + 0.5f); + } + } + first_call = false; + } + return particle_texture[MIN(gl_particles_style, NumParticleTextures)]; +} diff --git a/src/polyrenderer/scene/poly_particle.h b/src/polyrenderer/scene/poly_particle.h index e91174591c..a5cc3d0d04 100644 --- a/src/polyrenderer/scene/poly_particle.h +++ b/src/polyrenderer/scene/poly_particle.h @@ -29,4 +29,13 @@ class RenderPolyParticle { public: void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); + +private: + static uint8_t *GetParticleTexture(); + + enum + { + NumParticleTextures = 3, + ParticleTextureSize = 64 + }; }; From 020c34abfa17e78c085deea6027bd1cdbf1d1481 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 27 Mar 2017 15:09:01 +0300 Subject: [PATCH 5/5] Added workaround for undefined isnan() All our continuous integration targets have no problems with C99 isnan() macro but on Ubuntu 16.04 compilation fails It appeared that some implementation of C++ Standard Library may undefine bunch of C macros to avoid conflicts with own declarations --- src/swrenderer/line/r_walldraw.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index bf8d856e9d..d315d5a016 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -42,6 +42,13 @@ #include "swrenderer/r_renderthread.h" #include "swrenderer/r_memory.h" +#ifndef isnan +// Fallback to C++ function if C99 isnan() macro is not undefined +// Most likely it was undefined in C++ library header to avoid conflicts with own function +#include +using std::isnan; +#endif // !isnan + namespace swrenderer { WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FTexture *texture)