diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 59dd637a2..4645cfcd5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -310,6 +310,7 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_CXX_FLAGS "${SANITIZER_FLAG} ${CMAKE_CXX_FLAGS}" ) set( CMAKE_C_FLAGS "${SANITIZER_FLAG} ${CMAKE_C_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "${SANITIZER_FLAG} ${CMAKE_EXE_LINKER_FLAGS}" ) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.5") set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" ) diff --git a/src/g_game.cpp b/src/g_game.cpp index 1c5388ac1..a73758f1c 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -82,9 +82,6 @@ static FRandom pr_dmspawn ("DMSpawn"); static FRandom pr_pspawn ("PlayerSpawn"); -const int SAVEPICWIDTH = 216; -const int SAVEPICHEIGHT = 162; - bool G_CheckDemoStatus (void); void G_ReadDemoTiccmd (ticcmd_t *cmd, int player); void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf); diff --git a/src/g_game.h b/src/g_game.h index 2ac019059..7ac49a413 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -102,5 +102,7 @@ class AInventory; extern const AInventory *SendItemUse, *SendItemDrop; extern int SendItemDropAmount; +const int SAVEPICWIDTH = 216; +const int SAVEPICHEIGHT = 162; #endif diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 31b7208bc..8669d7bab 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -54,7 +54,7 @@ VSMatrix FGLModelRenderer::GetViewToWorldMatrix() return objectToWorldMatrix; } -void FGLModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) +void FGLModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) { glDepthFunc(GL_LEQUAL); gl_RenderState.EnableTexture(true); @@ -65,7 +65,7 @@ void FGLModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, con if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) && !(smf->flags & MDL_DONTCULLBACKFACES)) { glEnable(GL_CULL_FACE); - glFrontFace(GL_CW); + glFrontFace((mirrored ^ GLPortal::isMirrored()) ? GL_CCW : GL_CW); } gl_RenderState.mModelMatrix = objectToWorldMatrix; @@ -81,7 +81,7 @@ void FGLModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) glDisable(GL_CULL_FACE); } -void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) +void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored) { glDepthFunc(GL_LEQUAL); @@ -91,7 +91,7 @@ void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectTo if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])) { glEnable(GL_CULL_FACE); - glFrontFace(GLPortal::isMirrored()? GL_CW : GL_CCW); + glFrontFace((mirrored ^ GLPortal::isMirrored()) ? GL_CW : GL_CCW); } gl_RenderState.mModelMatrix = objectToWorldMatrix; diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 821705c34..0fb82f9f4 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -37,13 +37,13 @@ public: FGLModelRenderer(int mli) : modellightindex(mli) {} ModelRendererType GetType() const override { return GLModelRendererType; } - void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; + void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; void SetVertexBuffer(IModelVertexBuffer *buffer) override; void ResetVertexBuffer() override; VSMatrix GetViewToWorldMatrix() override; - void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) override; + void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored) override; void EndDrawHUDModel(AActor *actor) override; void SetInterpolation(double interpolation) override; void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 154fae2d6..c753e261e 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -35,6 +35,7 @@ #include "p_effect.h" #include "d_player.h" #include "a_dynlight.h" +#include "g_game.h" #include "swrenderer/r_swscene.h" #include "hwrenderer/utility/hw_clock.h" @@ -96,6 +97,8 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mLights = nullptr; mTonemapPalette = nullptr; mBuffers = nullptr; + mScreenBuffers = nullptr; + mSaveBuffers = nullptr; mPresentShader = nullptr; mPresent3dCheckerShader = nullptr; mPresent3dColumnShader = nullptr; @@ -122,7 +125,9 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) void FGLRenderer::Initialize(int width, int height) { - mBuffers = new FGLRenderBuffers(); + mScreenBuffers = new FGLRenderBuffers(); + mSaveBuffers = new FGLRenderBuffers(); + mBuffers = mScreenBuffers; mLinearDepthShader = new FLinearDepthShader(); mDepthBlurShader = new FDepthBlurShader(); mSSAOShader = new FSSAOShader(); @@ -400,7 +405,9 @@ void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, in void FGLRenderer::BeginFrame() { - buffersActive = GLRenderer->mBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); + buffersActive = GLRenderer->mScreenBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); + if (buffersActive) + buffersActive = GLRenderer->mSaveBuffers->Setup(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT); } //=========================================================================== diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 7cdf3b01d..22b77acef 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -100,6 +100,8 @@ public: int mOldFBID; FGLRenderBuffers *mBuffers; + FGLRenderBuffers *mScreenBuffers; + FGLRenderBuffers *mSaveBuffers; FLinearDepthShader *mLinearDepthShader; FSSAOShader *mSSAOShader; FDepthBlurShader *mDepthBlurShader; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 91d4e4235..d4aea2768 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -395,7 +395,6 @@ void GLSceneDrawer::RenderTranslucent(FDrawInfo *di) { RenderAll.Clock(); - glDepthMask(false); gl_RenderState.SetCameraPos(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z); // final pass: translucent stuff @@ -404,6 +403,7 @@ void GLSceneDrawer::RenderTranslucent(FDrawInfo *di) gl_RenderState.EnableBrightmap(true); di->drawlists[GLDL_TRANSLUCENTBORDER].Draw(di, GLPASS_TRANSLUCENT); + glDepthMask(false); di->DrawSorted(GLDL_TRANSLUCENT); gl_RenderState.EnableBrightmap(false); @@ -656,7 +656,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix); eye->SetUp(); - screen->SetOutputViewport(bounds); + screen->SetViewportRects(bounds); Set3DViewport(mainview); GLRenderer->mDrawingScene2D = true; GLRenderer->mCurrentFoV = fov; @@ -713,20 +713,24 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { IntRect bounds; + bounds.left = 0; + bounds.top = 0; + bounds.width = width; + bounds.height = height; + + // if GLRenderer->mVBO is persistently mapped we must be sure the GPU finished reading from it before we fill it with new data. + glFinish(); + + // Switch to render buffers dimensioned for the savepic + GLRenderer->mBuffers = GLRenderer->mSaveBuffers; P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. - bounds.left=0; - bounds.top=0; - bounds.width=width; - bounds.height=height; - glFlush(); SetFixedColormap(player); gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); GLRenderer->mVBO->Reset(); if (!gl.legacyMode) GLRenderer->mLights->Clear(); - sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, - r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false); + sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false); glDisable(GL_STENCIL_TEST); gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetSoftLightLevel(-1); @@ -737,12 +741,16 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, screen->Draw2D(); } GLRenderer->CopyToBackbuffer(&bounds, false); - glFlush(); - screen->SetOutputViewport(nullptr); + // strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers + glFinish(); uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3); glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr); M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma); M_Free(scr); + + // Switch back the screen render buffers + screen->SetViewportRects(nullptr); + GLRenderer->mBuffers = GLRenderer->mScreenBuffers; } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 81cbd7eeb..02326afd1 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -136,7 +136,7 @@ void OpenGLFrameBuffer::InitializeState() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLRenderer->Initialize(GetWidth(), GetHeight()); - SetOutputViewport(nullptr); + SetViewportRects(nullptr); } //========================================================================== @@ -164,14 +164,11 @@ void OpenGLFrameBuffer::Update() int clientHeight = ViewportScaledHeight(initialWidth, initialHeight); if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) { - // Do not call Resize here because it's only for software canvases Width = clientWidth; Height = clientHeight; V_OutputResized(Width, Height); GLRenderer->mVBO->OutputResized(Width, Height); } - - SetOutputViewport(nullptr); } //=========================================================================== @@ -392,10 +389,11 @@ bool OpenGLFrameBuffer::RenderBuffersEnabled() return FGLRenderBuffers::IsEnabled(); } -void OpenGLFrameBuffer::SetOutputViewport(IntRect *bounds) +void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds) { - Super::SetOutputViewport(bounds); - s3d::Stereo3DMode::getCurrentMode().AdjustViewports(); + Super::SetViewportRects(bounds); + if (!bounds) + s3d::Stereo3DMode::getCurrentMode().AdjustViewports(); } @@ -431,6 +429,7 @@ void OpenGLFrameBuffer::SetClearColor(int color) void OpenGLFrameBuffer::BeginFrame() { + SetViewportRects(nullptr); if (GLRenderer != nullptr) GLRenderer->BeginFrame(); } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 898820cc9..9a92c1f44 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -42,7 +42,7 @@ public: void ResetFixedColormap() override; void BeginFrame() override; bool RenderBuffersEnabled() override; - void SetOutputViewport(IntRect *bounds) override; + void SetViewportRects(IntRect *bounds) override; void BlurScene(float amount) override; // Retrieves a buffer containing image data for a screenshot. diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 1c7041d46..4393424c1 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -75,21 +75,6 @@ void HWDrawInfo::UnclipSubsector(subsector_t *sub) // //========================================================================== -CVAR(Float, gl_line_distance_cull, 0.0, 0 /*CVAR_ARCHIVE|CVAR_GLOBALCONFIG*/) // this is deactivated, for now - -inline bool IsDistanceCulled(seg_t *line) -{ - double dist3 = gl_line_distance_cull * gl_line_distance_cull; - if (dist3 <= 0.0) - return false; - - double dist1 = (line->v1->fPos() - r_viewpoint.Pos).LengthSquared(); - double dist2 = (line->v2->fPos() - r_viewpoint.Pos).LengthSquared(); - if ((dist1 > dist3) && (dist2 > dist3)) - return true; - return false; -} - void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) { #ifdef _DEBUG @@ -138,8 +123,6 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) uint8_t ispoly = uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ); - if (IsDistanceCulled(seg)) { clipper.SafeAddClipRange(startAngle, endAngle); return; } - if (!seg->backsector) { clipper.SafeAddClipRange(startAngle, endAngle); diff --git a/src/hwrenderer/scene/hw_spritelight.cpp b/src/hwrenderer/scene/hw_spritelight.cpp index 6c98aac3e..c44a3179a 100644 --- a/src/hwrenderer/scene/hw_spritelight.cpp +++ b/src/hwrenderer/scene/hw_spritelight.cpp @@ -25,7 +25,6 @@ ** */ -#include "actorinlines.h" #include "c_dispatch.h" #include "p_local.h" #include "p_effect.h" diff --git a/src/polyrenderer/drawers/poly_buffer.cpp b/src/polyrenderer/drawers/poly_buffer.cpp index 0e24509cc..2506bce7e 100644 --- a/src/polyrenderer/drawers/poly_buffer.cpp +++ b/src/polyrenderer/drawers/poly_buffer.cpp @@ -48,8 +48,7 @@ void PolyZBuffer::Resize(int newwidth, int newheight) { width = newwidth; height = newheight; - int count = BlockWidth() * BlockHeight(); - values.resize(count * 64); + values.resize(width * height); } ///////////////////////////////////////////////////////////////////////////// @@ -64,14 +63,6 @@ void PolyStencilBuffer::Clear(int newwidth, int newheight, uint8_t stencil_value { width = newwidth; height = newheight; - int count = BlockWidth() * BlockHeight(); - values.resize(count * 64); - masks.resize(count); - - uint8_t *v = Values(); - uint32_t *m = Masks(); - for (int i = 0; i < count; i++) - { - m[i] = 0xffffff00 | stencil_value; - } + values.resize(width * height); + memset(Values(), stencil_value, width * height); } diff --git a/src/polyrenderer/drawers/poly_buffer.h b/src/polyrenderer/drawers/poly_buffer.h index df79c6e71..af4a78b3a 100644 --- a/src/polyrenderer/drawers/poly_buffer.h +++ b/src/polyrenderer/drawers/poly_buffer.h @@ -33,8 +33,6 @@ public: void Resize(int newwidth, int newheight); int Width() const { return width; } int Height() const { return height; } - int BlockWidth() const { return (width + 7) / 8; } - int BlockHeight() const { return (height + 7) / 8; } float *Values() { return values.data(); } private: @@ -50,16 +48,10 @@ public: void Clear(int newwidth, int newheight, uint8_t stencil_value = 0); int Width() const { return width; } int Height() const { return height; } - int BlockWidth() const { return (width + 7) / 8; } - int BlockHeight() const { return (height + 7) / 8; } uint8_t *Values() { return values.data(); } - uint32_t *Masks() { return masks.data(); } private: int width; int height; - - // 8x8 blocks of stencil values, plus a mask for each block indicating if values are the same for early out stencil testing std::vector values; - std::vector masks; }; diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 88f174525..2d43ae64f 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -180,8 +180,8 @@ public: void SetTexture(FTexture *texture, FRenderStyle style); void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel); - void SetStyle(RectBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); } - void SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); + void SetStyle(TriBlendMode blendmode, double alpha = 1.0) { mBlendMode = blendmode; mAlpha = (uint32_t)(alpha * 256.0 + 0.5); } + void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1); @@ -191,10 +191,9 @@ public: int TextureHeight() const { return mTextureHeight; } const uint8_t *Translation() const { return mTranslation; } - RectBlendMode BlendMode() const { return mBlendMode; } + TriBlendMode BlendMode() const { return mBlendMode; } uint32_t Color() const { return mColor; } - uint32_t SrcAlpha() const { return mSrcAlpha; } - uint32_t DestAlpha() const { return mDestAlpha; } + uint32_t Alpha() const { return mAlpha; } uint32_t Light() const { return mLight; } const uint8_t *BaseColormap() const { return mColormaps; } @@ -225,11 +224,10 @@ private: int mTextureHeight = 0; const uint8_t *mTranslation = nullptr; const uint8_t *mColormaps = nullptr; - RectBlendMode mBlendMode = RectBlendMode::FillOpaque; + TriBlendMode mBlendMode = TriBlendMode::Fill; uint32_t mLight = 0; uint32_t mColor = 0; - uint32_t mSrcAlpha = 0; - uint32_t mDestAlpha = 0; + uint32_t mAlpha = 0; uint16_t mLightAlpha = 0; uint16_t mLightRed = 0; uint16_t mLightGreen = 0; diff --git a/src/polyrenderer/drawers/poly_drawer32.h b/src/polyrenderer/drawers/poly_drawer32.h deleted file mode 100644 index 4dae396de..000000000 --- a/src/polyrenderer/drawers/poly_drawer32.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -** Polygon Doom software renderer -** Copyright (c) 2016 Magnus Norddahl -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#pragma once - -#include "screen_triangle.h" - -namespace TriScreenDrawerModes -{ - namespace - { - struct BgraColor - { - uint32_t b, g, r, a; - BgraColor() { } - BgraColor(uint32_t c) : b(BPART(c)), g(GPART(c)), r(RPART(c)), a(APART(c)) { } - BgraColor &operator=(uint32_t c) { b = BPART(c); g = GPART(c); r = RPART(c); a = APART(c); return *this; } - operator uint32_t() const { return MAKEARGB(a, r, g, b); } - }; - } - - template - FORCEINLINE unsigned int Sample32(int32_t u, int32_t v, const uint32_t *texPixels, int texWidth, int texHeight, uint32_t oneU, uint32_t oneV, uint32_t color, const uint32_t *translation) - { - uint32_t texel; - if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill || SamplerT::Mode == (int)Samplers::Fuzz || SamplerT::Mode == (int)Samplers::FogBoundary) - { - return color; - } - else if (SamplerT::Mode == (int)Samplers::Translated) - { - const uint8_t *texpal = (const uint8_t *)texPixels; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - return translation[texpal[texelX * texHeight + texelY]]; - } - else if (FilterModeT::Mode == (int)FilterModes::Nearest) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - texel = texPixels[texelX * texHeight + texelY]; - } - else - { - u -= oneU >> 1; - v -= oneV >> 1; - - unsigned int frac_x0 = (((uint32_t)u << 8) >> FRACBITS) * texWidth; - unsigned int frac_x1 = ((((uint32_t)u << 8) + oneU) >> FRACBITS) * texWidth; - unsigned int frac_y0 = (((uint32_t)v << 8) >> FRACBITS) * texHeight; - unsigned int frac_y1 = ((((uint32_t)v << 8) + oneV) >> FRACBITS) * texHeight; - unsigned int x0 = frac_x0 >> FRACBITS; - unsigned int x1 = frac_x1 >> FRACBITS; - unsigned int y0 = frac_y0 >> FRACBITS; - unsigned int y1 = frac_y1 >> FRACBITS; - - unsigned int p00 = texPixels[x0 * texHeight + y0]; - unsigned int p01 = texPixels[x0 * texHeight + y1]; - unsigned int p10 = texPixels[x1 * texHeight + y0]; - unsigned int p11 = texPixels[x1 * texHeight + y1]; - - unsigned int inv_a = (frac_x1 >> (FRACBITS - 4)) & 15; - unsigned int inv_b = (frac_y1 >> (FRACBITS - 4)) & 15; - unsigned int a = 16 - inv_a; - unsigned int b = 16 - inv_b; - - unsigned int sred = (RPART(p00) * (a * b) + RPART(p01) * (inv_a * b) + RPART(p10) * (a * inv_b) + RPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int sgreen = (GPART(p00) * (a * b) + GPART(p01) * (inv_a * b) + GPART(p10) * (a * inv_b) + GPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int sblue = (BPART(p00) * (a * b) + BPART(p01) * (inv_a * b) + BPART(p10) * (a * inv_b) + BPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int salpha = (APART(p00) * (a * b) + APART(p01) * (inv_a * b) + APART(p10) * (a * inv_b) + APART(p11) * (inv_a * inv_b) + 127) >> 8; - - texel = (salpha << 24) | (sred << 16) | (sgreen << 8) | sblue; - } - - if (SamplerT::Mode == (int)Samplers::Skycap) - { - int start_fade = 2; // How fast it should fade out - - int alpha_top = clamp(v >> (16 - start_fade), 0, 256); - int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256); - int a = MIN(alpha_top, alpha_bottom); - int inv_a = 256 - a; - - uint32_t r = RPART(texel); - uint32_t g = GPART(texel); - uint32_t b = BPART(texel); - uint32_t fg_a = APART(texel); - uint32_t bg_red = RPART(color); - uint32_t bg_green = GPART(color); - uint32_t bg_blue = BPART(color); - r = (r * a + bg_red * inv_a + 127) >> 8; - g = (g * a + bg_green * inv_a + 127) >> 8; - b = (b * a + bg_blue * inv_a + 127) >> 8; - return MAKEARGB(fg_a, r, g, b); - } - else - { - return texel; - } - } - - template - FORCEINLINE unsigned int SampleShade32(int32_t u, int32_t v, const uint32_t *texPixels, int texWidth, int texHeight, int x, int y) - { - if (SamplerT::Mode == (int)Samplers::Shaded) - { - const uint8_t *texpal = (const uint8_t *)texPixels; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = texpal[texelX * texHeight + texelY]; - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - return sampleshadeout; - } - else if (SamplerT::Mode == (int)Samplers::Stencil) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - return sampleshadeout; - } - else if (SamplerT::Mode == (int)Samplers::Fuzz) - { - using namespace swrenderer; - - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - - fixed_t fuzzscale = (200 << FRACBITS) / viewheight; - - int scaled_x = (x * fuzzscale) >> FRACBITS; - int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + fuzzpos; - - fixed_t fuzzcount = FUZZTABLE << FRACBITS; - fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; - unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; - - sampleshadeout = (sampleshadeout * alpha) >> 5; - return sampleshadeout; - } - else - { - return 0; - } - } - - FORCEINLINE BgraColor VECTORCALL AddLights(BgraColor material, BgraColor fgcolor, BgraColor dynlight) - { - fgcolor.r = MIN(fgcolor.r + ((material.r * dynlight.r) >> 8), (uint32_t)255); - fgcolor.g = MIN(fgcolor.g + ((material.g * dynlight.g) >> 8), (uint32_t)255); - fgcolor.b = MIN(fgcolor.b + ((material.b * dynlight.b) >> 8), (uint32_t)255); - return fgcolor; - } - - FORCEINLINE BgraColor VECTORCALL CalcDynamicLight(const PolyLight *lights, int num_lights, FVector3 worldpos, FVector3 worldnormal, uint32_t dynlightcolor) - { - BgraColor lit = dynlightcolor; - - for (int i = 0; i != num_lights; i++) - { - FVector3 lightpos = { lights[i].x, lights[i].y, lights[i].z }; - float light_radius = lights[i].radius; - - bool is_attenuated = light_radius < 0.0f; - if (is_attenuated) - light_radius = -light_radius; - - // L = light-pos - // dist = sqrt(dot(L, L)) - // distance_attenuation = 1 - MIN(dist * (1/radius), 1) - FVector3 L = lightpos - worldpos; - float dist2 = L | L; - float rcp_dist = 1.0f / sqrt(dist2); - float dist = dist2 * rcp_dist; - float distance_attenuation = 256.0f - MIN(dist * light_radius, 256.0f); - - // The simple light type - float simple_attenuation = distance_attenuation; - - // The point light type - // diffuse = max(dot(N,normalize(L)),0) * attenuation - float dotNL = worldnormal | (L * rcp_dist); - float point_attenuation = MAX(dotNL, 0.0f) * distance_attenuation; - - uint32_t attenuation = (uint32_t)(is_attenuated ? (int32_t)point_attenuation : (int32_t)simple_attenuation); - - BgraColor light_color = lights[i].color; - lit.r += (light_color.r * attenuation) >> 8; - lit.g += (light_color.g * attenuation) >> 8; - lit.b += (light_color.b * attenuation) >> 8; - } - - lit.r = MIN(lit.r, (uint32_t)256); - lit.g = MIN(lit.g, (uint32_t)256); - lit.b = MIN(lit.b, (uint32_t)256); - return lit; - } - - template - FORCEINLINE BgraColor Shade32(BgraColor fgcolor, BgraColor mlight, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, BgraColor dynlight) - { - BgraColor material = fgcolor; - if (ShadeModeT::Mode == (int)ShadeMode::Simple) - { - fgcolor.r = (fgcolor.r * mlight.r) >> 8; - fgcolor.g = (fgcolor.g * mlight.g) >> 8; - fgcolor.b = (fgcolor.b * mlight.b) >> 8; - } - else if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - uint32_t intensity = ((fgcolor.r * 77 + fgcolor.g * 143 + fgcolor.b * 37) >> 8) * desaturate; - fgcolor.r = (((shade_fade.r + ((fgcolor.r * inv_desaturate + intensity) >> 8) * mlight.r) >> 8) * shade_light.r) >> 8; - fgcolor.g = (((shade_fade.g + ((fgcolor.g * inv_desaturate + intensity) >> 8) * mlight.g) >> 8) * shade_light.g) >> 8; - fgcolor.b = (((shade_fade.b + ((fgcolor.b * inv_desaturate + intensity) >> 8) * mlight.b) >> 8) * shade_light.b) >> 8; - } - return AddLights(material, fgcolor, dynlight); - } - - template - FORCEINLINE BgraColor Blend32(BgraColor fgcolor, BgraColor bgcolor, uint32_t ifgcolor, uint32_t ifgshade, uint32_t srcalpha, uint32_t destalpha) - { - if (BlendT::Mode == (int)BlendModes::Opaque) - { - fgcolor.a = 255; - return fgcolor; - } - else if (BlendT::Mode == (int)BlendModes::Masked) - { - return (ifgcolor == 0) ? bgcolor : fgcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddSrcColorOneMinusSrcColor) - { - uint32_t srcred = fgcolor.r + (fgcolor.r >> 7); - uint32_t srcgreen = fgcolor.g + (fgcolor.g >> 7); - uint32_t srcblue = fgcolor.b + (fgcolor.b >> 7); - uint32_t inv_srcred = 256 - srcred; - uint32_t inv_srcgreen = 256 - srcgreen; - uint32_t inv_srcblue = 256 - srcblue; - - BgraColor outcolor; - outcolor.r = (fgcolor.r * srcred + bgcolor.r * inv_srcred) >> 8; - outcolor.g = (fgcolor.g * srcgreen + bgcolor.g * inv_srcgreen) >> 8; - outcolor.b = (fgcolor.b * srcblue + bgcolor.b * inv_srcblue) >> 8; - outcolor.a = 255; - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::Shaded) - { - uint32_t alpha = ifgshade; - uint32_t inv_alpha = 256 - alpha; - - BgraColor outcolor; - outcolor.r = (fgcolor.r * alpha + bgcolor.r * inv_alpha) >> 8; - outcolor.g = (fgcolor.g * alpha + bgcolor.g * inv_alpha) >> 8; - outcolor.b = (fgcolor.b * alpha + bgcolor.b * inv_alpha) >> 8; - outcolor.a = 255; - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddClampShaded) - { - uint32_t alpha = ifgshade; - BgraColor outcolor; - outcolor.r = ((fgcolor.r * alpha) >> 8) + bgcolor.r; - outcolor.g = ((fgcolor.g * alpha) >> 8) + bgcolor.g; - outcolor.b = ((fgcolor.b * alpha) >> 8) + bgcolor.b; - outcolor.a = 255; - return outcolor; - } - else - { - uint32_t alpha = APART(ifgcolor); - alpha += alpha >> 7; // 255->256 - uint32_t inv_alpha = 256 - alpha; - - uint32_t bgalpha = (destalpha * alpha + (inv_alpha << 8) + 128) >> 8; - uint32_t fgalpha = (srcalpha * alpha + 128) >> 8; - - fgcolor.r *= fgalpha; - fgcolor.g *= fgalpha; - fgcolor.b *= fgalpha; - bgcolor.r *= bgalpha; - bgcolor.g *= bgalpha; - bgcolor.b *= bgalpha; - - BgraColor outcolor; - if (BlendT::Mode == (int)BlendModes::AddClamp) - { - outcolor.r = MIN((fgcolor.r + bgcolor.r) >> 8, 255); - outcolor.g = MIN((fgcolor.g + bgcolor.g) >> 8, 255); - outcolor.b = MIN((fgcolor.b + bgcolor.b) >> 8, 255); - } - else if (BlendT::Mode == (int)BlendModes::SubClamp) - { - outcolor.r = MAX(int32_t(fgcolor.r - bgcolor.r) >> 8, 0); - outcolor.g = MAX(int32_t(fgcolor.g - bgcolor.g) >> 8, 0); - outcolor.b = MAX(int32_t(fgcolor.b - bgcolor.b) >> 8, 0); - } - else if (BlendT::Mode == (int)BlendModes::RevSubClamp) - { - outcolor.r = MAX(int32_t(bgcolor.r - fgcolor.r) >> 8, 0); - outcolor.g = MAX(int32_t(bgcolor.g - fgcolor.g) >> 8, 0); - outcolor.b = MAX(int32_t(bgcolor.b - fgcolor.b) >> 8, 0); - } - outcolor.a = 255; - return outcolor; - } - } -} - -template -class RectScreenDrawer32 -{ -public: - static void Execute(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) - { - using namespace TriScreenDrawerModes; - - if (SamplerT::Mode == (int)Samplers::Fuzz) - { - Loop(destOrg, destWidth, destHeight, destPitch, args, thread); - } - else if (args->SimpleShade()) - { - Loop(destOrg, destWidth, destHeight, destPitch, args, thread); - } - else - { - Loop(destOrg, destWidth, destHeight, destPitch, args, thread); - } - } - -private: - template - FORCEINLINE static void Loop(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) - { - using namespace TriScreenDrawerModes; - - int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth); - int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth); - int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight); - int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight); - - if (x1 <= x0 || y1 <= y0) - return; - - uint32_t srcalpha = args->SrcAlpha(); - uint32_t destalpha = args->DestAlpha(); - - // Setup step variables - float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0()); - float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0()); - uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000); - uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000); - uint32_t stepU = (int32_t)(fstepU * 0x1000000); - uint32_t stepV = (int32_t)(fstepV * 0x1000000); - - // Sampling stuff - uint32_t color = args->Color(); - const uint32_t * RESTRICT translation = (const uint32_t *)args->Translation(); - const uint32_t * RESTRICT texPixels = (const uint32_t *)args->TexturePixels(); - uint32_t texWidth = args->TextureWidth(); - uint32_t texHeight = args->TextureHeight(); - uint32_t oneU, oneV; - if (SamplerT::Mode != (int)Samplers::Fill) - { - oneU = ((0x800000 + texWidth - 1) / texWidth) * 2 + 1; - oneV = ((0x800000 + texHeight - 1) / texHeight) * 2 + 1; - } - else - { - oneU = 0; - oneV = 0; - } - - // Setup light - uint32_t lightpos = args->Light(); - lightpos += lightpos >> 7; // 255 -> 256 - BgraColor mlight; - - BgraColor dynlight = 0; - - // Shade constants - int inv_desaturate; - BgraColor shade_fade_lit, shade_light; - int desaturate; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - uint32_t inv_light = 256 - lightpos; - shade_fade_lit.r = args->ShadeFadeRed() * inv_light; - shade_fade_lit.g = args->ShadeFadeGreen() * inv_light; - shade_fade_lit.b = args->ShadeFadeBlue() * inv_light; - shade_light.r = args->ShadeLightRed(); - shade_light.g = args->ShadeLightGreen(); - shade_light.b = args->ShadeLightBlue(); - desaturate = args->ShadeDesaturate(); - inv_desaturate = 256 - desaturate; - mlight.r = lightpos; - mlight.g = lightpos; - mlight.b = lightpos; - } - else - { - inv_desaturate = 0; - shade_fade_lit.r = 0; - shade_fade_lit.g = 0; - shade_fade_lit.b = 0; - shade_light.r = 0; - shade_light.g = 0; - shade_light.b = 0; - desaturate = 0; - mlight.r = lightpos; - mlight.g = lightpos; - mlight.b = lightpos; - } - - int count = x1 - x0; - - uint32_t posV = startV; - for (int y = y0; y < y1; y++, posV += stepV) - { - int coreBlock = y / 8; - if (coreBlock % thread->num_cores != thread->core) - { - continue; - } - - uint32_t *dest = ((uint32_t*)destOrg) + y * destPitch + x0; - - uint32_t posU = startU; - for (int i = 0; i < count; i++) - { - // Load bgcolor - BgraColor bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - bgcolor = *dest; - else - bgcolor = 0; - - // Sample fgcolor - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = *dest; - unsigned int ifgcolor = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - unsigned int ifgshade = SampleShade32(posU, posV, texPixels, texWidth, texHeight, x0 + i, y); - posU += stepU; - - // Shade and blend - BgraColor fgcolor = Shade32(ifgcolor, mlight, desaturate, inv_desaturate, shade_fade_lit, shade_light, dynlight); - BgraColor outcolor = Blend32(fgcolor, bgcolor, ifgcolor, ifgshade, srcalpha, destalpha); - - // Store result - *dest = outcolor; - dest++; - } - } - } -}; diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h deleted file mode 100644 index 4685dd07c..000000000 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ /dev/null @@ -1,518 +0,0 @@ -/* -** Polygon Doom software renderer -** Copyright (c) 2016 Magnus Norddahl -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#pragma once - -#include "screen_triangle.h" - -namespace TriScreenDrawerModes -{ - template - FORCEINLINE unsigned int VECTORCALL Sample32(int32_t u, int32_t v, const uint32_t *texPixels, int texWidth, int texHeight, uint32_t oneU, uint32_t oneV, uint32_t color, const uint32_t *translation) - { - uint32_t texel; - if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill || SamplerT::Mode == (int)Samplers::Fuzz || SamplerT::Mode == (int)Samplers::FogBoundary) - { - return color; - } - else if (SamplerT::Mode == (int)Samplers::Translated) - { - const uint8_t *texpal = (const uint8_t *)texPixels; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - return translation[texpal[texelX * texHeight + texelY]]; - } - else if (FilterModeT::Mode == (int)FilterModes::Nearest) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - texel = texPixels[texelX * texHeight + texelY]; - } - else - { - u -= oneU >> 1; - v -= oneV >> 1; - - unsigned int frac_x0 = (((uint32_t)u << 8) >> FRACBITS) * texWidth; - unsigned int frac_x1 = ((((uint32_t)u << 8) + oneU) >> FRACBITS) * texWidth; - unsigned int frac_y0 = (((uint32_t)v << 8) >> FRACBITS) * texHeight; - unsigned int frac_y1 = ((((uint32_t)v << 8) + oneV) >> FRACBITS) * texHeight; - unsigned int x0 = frac_x0 >> FRACBITS; - unsigned int x1 = frac_x1 >> FRACBITS; - unsigned int y0 = frac_y0 >> FRACBITS; - unsigned int y1 = frac_y1 >> FRACBITS; - - unsigned int p00 = texPixels[x0 * texHeight + y0]; - unsigned int p01 = texPixels[x0 * texHeight + y1]; - unsigned int p10 = texPixels[x1 * texHeight + y0]; - unsigned int p11 = texPixels[x1 * texHeight + y1]; - - unsigned int inv_a = (frac_x1 >> (FRACBITS - 4)) & 15; - unsigned int inv_b = (frac_y1 >> (FRACBITS - 4)) & 15; - unsigned int a = 16 - inv_a; - unsigned int b = 16 - inv_b; - - unsigned int sred = (RPART(p00) * (a * b) + RPART(p01) * (inv_a * b) + RPART(p10) * (a * inv_b) + RPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int sgreen = (GPART(p00) * (a * b) + GPART(p01) * (inv_a * b) + GPART(p10) * (a * inv_b) + GPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int sblue = (BPART(p00) * (a * b) + BPART(p01) * (inv_a * b) + BPART(p10) * (a * inv_b) + BPART(p11) * (inv_a * inv_b) + 127) >> 8; - unsigned int salpha = (APART(p00) * (a * b) + APART(p01) * (inv_a * b) + APART(p10) * (a * inv_b) + APART(p11) * (inv_a * inv_b) + 127) >> 8; - - texel = (salpha << 24) | (sred << 16) | (sgreen << 8) | sblue; - } - - if (SamplerT::Mode == (int)Samplers::Skycap) - { - int start_fade = 2; // How fast it should fade out - - int alpha_top = clamp(v >> (16 - start_fade), 0, 256); - int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256); - int a = MIN(alpha_top, alpha_bottom); - int inv_a = 256 - a; - - uint32_t r = RPART(texel); - uint32_t g = GPART(texel); - uint32_t b = BPART(texel); - uint32_t fg_a = APART(texel); - uint32_t bg_red = RPART(color); - uint32_t bg_green = GPART(color); - uint32_t bg_blue = BPART(color); - r = (r * a + bg_red * inv_a + 127) >> 8; - g = (g * a + bg_green * inv_a + 127) >> 8; - b = (b * a + bg_blue * inv_a + 127) >> 8; - return MAKEARGB(fg_a, r, g, b); - } - else - { - return texel; - } - } - - template - FORCEINLINE unsigned int VECTORCALL SampleShade32(int32_t u, int32_t v, const uint32_t *texPixels, int texWidth, int texHeight, int x, int y) - { - if (SamplerT::Mode == (int)Samplers::Shaded) - { - const uint8_t *texpal = (const uint8_t *)texPixels; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = texpal[texelX * texHeight + texelY]; - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - return sampleshadeout; - } - else if (SamplerT::Mode == (int)Samplers::Stencil) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - return sampleshadeout; - } - else if (SamplerT::Mode == (int)Samplers::Fuzz) - { - using namespace swrenderer; - - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - - fixed_t fuzzscale = (200 << FRACBITS) / viewheight; - - int scaled_x = (x * fuzzscale) >> FRACBITS; - int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + fuzzpos; - - fixed_t fuzzcount = FUZZTABLE << FRACBITS; - fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; - unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; - - sampleshadeout = (sampleshadeout * alpha) >> 5; - return sampleshadeout; - } - else - { - return 0; - } - } - - FORCEINLINE __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, __m128i dynlight) - { - fgcolor = _mm_add_epi16(fgcolor, _mm_srli_epi16(_mm_mullo_epi16(material, dynlight), 8)); - fgcolor = _mm_min_epi16(fgcolor, _mm_set1_epi16(255)); - return fgcolor; - } - - FORCEINLINE __m128i VECTORCALL CalcDynamicLight(const PolyLight *lights, int num_lights, __m128 worldpos, __m128 worldnormal, uint32_t dynlightcolor) - { - __m128i lit = _mm_unpacklo_epi8(_mm_cvtsi32_si128(dynlightcolor), _mm_setzero_si128()); - lit = _mm_shuffle_epi32(lit, _MM_SHUFFLE(1, 0, 1, 0)); - - for (int i = 0; i != num_lights; i++) - { - __m128 m256 = _mm_set1_ps(256.0f); - __m128 mSignBit = _mm_set1_ps(-0.0f); - - __m128 lightpos = _mm_loadu_ps(&lights[i].x); - __m128 light_radius = _mm_load_ss(&lights[i].radius); - - __m128 is_attenuated = _mm_cmpge_ss(light_radius, _mm_setzero_ps()); - is_attenuated = _mm_shuffle_ps(is_attenuated, is_attenuated, _MM_SHUFFLE(0, 0, 0, 0)); - light_radius = _mm_andnot_ps(mSignBit, light_radius); - - // L = light-pos - // dist = sqrt(dot(L, L)) - // distance_attenuation = 1 - MIN(dist * (1/radius), 1) - __m128 L = _mm_sub_ps(lightpos, worldpos); - __m128 dist2 = _mm_mul_ps(L, L); - dist2 = _mm_add_ss(dist2, _mm_add_ss(_mm_shuffle_ps(dist2, dist2, _MM_SHUFFLE(0, 0, 0, 1)), _mm_shuffle_ps(dist2, dist2, _MM_SHUFFLE(0, 0, 0, 2)))); - __m128 rcp_dist = _mm_rsqrt_ss(dist2); - __m128 dist = _mm_mul_ss(dist2, rcp_dist); - __m128 distance_attenuation = _mm_sub_ss(m256, _mm_min_ss(_mm_mul_ss(dist, light_radius), m256)); - distance_attenuation = _mm_shuffle_ps(distance_attenuation, distance_attenuation, _MM_SHUFFLE(0, 0, 0, 0)); - - // The simple light type - __m128 simple_attenuation = distance_attenuation; - - // The point light type - // diffuse = max(dot(N,normalize(L)),0) * attenuation - __m128 dotNL = _mm_mul_ps(worldnormal, _mm_mul_ps(L, _mm_shuffle_ps(rcp_dist, rcp_dist, _MM_SHUFFLE(0, 0, 0, 0)))); - dotNL = _mm_add_ss(dotNL, _mm_add_ss(_mm_shuffle_ps(dotNL, dotNL, _MM_SHUFFLE(0, 0, 0, 1)), _mm_shuffle_ps(dotNL, dotNL, _MM_SHUFFLE(0, 0, 0, 2)))); - dotNL = _mm_max_ss(dotNL, _mm_setzero_ps()); - __m128 point_attenuation = _mm_mul_ss(dotNL, distance_attenuation); - point_attenuation = _mm_shuffle_ps(point_attenuation, point_attenuation, _MM_SHUFFLE(0, 0, 0, 0)); - - __m128i attenuation = _mm_cvtps_epi32(_mm_or_ps(_mm_and_ps(is_attenuated, simple_attenuation), _mm_andnot_ps(is_attenuated, point_attenuation))); - attenuation = _mm_packs_epi32(_mm_shuffle_epi32(attenuation, _MM_SHUFFLE(0, 0, 0, 0)), _mm_shuffle_epi32(attenuation, _MM_SHUFFLE(1, 1, 1, 1))); - - __m128i light_color = _mm_cvtsi32_si128(lights[i].color); - light_color = _mm_unpacklo_epi8(light_color, _mm_setzero_si128()); - light_color = _mm_shuffle_epi32(light_color, _MM_SHUFFLE(1, 0, 1, 0)); - - lit = _mm_add_epi16(lit, _mm_srli_epi16(_mm_mullo_epi16(light_color, attenuation), 8)); - } - - return _mm_min_epi16(lit, _mm_set1_epi16(256)); - } - - template - FORCEINLINE __m128i VECTORCALL Shade32(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, __m128i dynlight) - { - __m128i material = fgcolor; - if (ShadeModeT::Mode == (int)ShadeMode::Simple) - { - fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, mlight), 8); - } - else if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - int blue0 = BPART(ifgcolor0); - int green0 = GPART(ifgcolor0); - int red0 = RPART(ifgcolor0); - int intensity0 = ((red0 * 77 + green0 * 143 + blue0 * 37) >> 8) * desaturate; - - int blue1 = BPART(ifgcolor1); - int green1 = GPART(ifgcolor1); - int red1 = RPART(ifgcolor1); - int intensity1 = ((red1 * 77 + green1 * 143 + blue1 * 37) >> 8) * desaturate; - - __m128i intensity = _mm_set_epi16(0, intensity1, intensity1, intensity1, 0, intensity0, intensity0, intensity0); - - fgcolor = _mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(fgcolor, inv_desaturate), intensity), 8); - fgcolor = _mm_mullo_epi16(fgcolor, mlight); - fgcolor = _mm_srli_epi16(_mm_add_epi16(shade_fade, fgcolor), 8); - fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, shade_light), 8); - } - - return AddLights(material, fgcolor, dynlight); - } - - template - FORCEINLINE __m128i VECTORCALL Blend32(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, unsigned int ifgshade0, unsigned int ifgshade1, uint32_t srcalpha, uint32_t destalpha) - { - if (BlendT::Mode == (int)BlendModes::Opaque) - { - __m128i outcolor = fgcolor; - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::Masked) - { - __m128i mask = _mm_cmpeq_epi32(_mm_packus_epi16(fgcolor, _mm_setzero_si128()), _mm_setzero_si128()); - mask = _mm_unpacklo_epi8(mask, _mm_setzero_si128()); - __m128i outcolor = _mm_or_si128(_mm_and_si128(mask, bgcolor), _mm_andnot_si128(mask, fgcolor)); - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddSrcColorOneMinusSrcColor) - { - __m128i inv_srccolor = _mm_sub_epi16(_mm_set1_epi16(256), _mm_add_epi16(fgcolor, _mm_srli_epi16(fgcolor, 7))); - __m128i outcolor = _mm_add_epi16(fgcolor, _mm_srli_epi16(_mm_mullo_epi16(bgcolor, inv_srccolor), 8)); - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::Shaded) - { - ifgshade0 = (ifgshade0 * srcalpha + 128) >> 8; - ifgshade1 = (ifgshade1 * srcalpha + 128) >> 8; - __m128i alpha = _mm_set_epi16(ifgshade1, ifgshade1, ifgshade1, ifgshade1, ifgshade0, ifgshade0, ifgshade0, ifgshade0); - __m128i inv_alpha = _mm_sub_epi16(_mm_set1_epi16(256), alpha); - - fgcolor = _mm_mullo_epi16(fgcolor, alpha); - bgcolor = _mm_mullo_epi16(bgcolor, inv_alpha); - __m128i outcolor = _mm_srli_epi16(_mm_add_epi16(fgcolor, bgcolor), 8); - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); - return outcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddClampShaded) - { - ifgshade0 = (ifgshade0 * srcalpha + 128) >> 8; - ifgshade1 = (ifgshade1 * srcalpha + 128) >> 8; - __m128i alpha = _mm_set_epi16(ifgshade1, ifgshade1, ifgshade1, ifgshade1, ifgshade0, ifgshade0, ifgshade0, ifgshade0); - - fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, alpha), 8); - __m128i outcolor = _mm_add_epi16(fgcolor, bgcolor); - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); - return outcolor; - } - else - { - uint32_t alpha0 = APART(ifgcolor0); - uint32_t alpha1 = APART(ifgcolor1); - alpha0 += alpha0 >> 7; // 255->256 - alpha1 += alpha1 >> 7; // 255->256 - uint32_t inv_alpha0 = 256 - alpha0; - uint32_t inv_alpha1 = 256 - alpha1; - - uint32_t bgalpha0 = (destalpha * alpha0 + (inv_alpha0 << 8) + 128) >> 8; - uint32_t bgalpha1 = (destalpha * alpha1 + (inv_alpha1 << 8) + 128) >> 8; - uint32_t fgalpha0 = (srcalpha * alpha0 + 128) >> 8; - uint32_t fgalpha1 = (srcalpha * alpha1 + 128) >> 8; - - __m128i bgalpha = _mm_set_epi16(bgalpha1, bgalpha1, bgalpha1, bgalpha1, bgalpha0, bgalpha0, bgalpha0, bgalpha0); - __m128i fgalpha = _mm_set_epi16(fgalpha1, fgalpha1, fgalpha1, fgalpha1, fgalpha0, fgalpha0, fgalpha0, fgalpha0); - - fgcolor = _mm_mullo_epi16(fgcolor, fgalpha); - bgcolor = _mm_mullo_epi16(bgcolor, bgalpha); - - __m128i fg_lo = _mm_unpacklo_epi16(fgcolor, _mm_setzero_si128()); - __m128i bg_lo = _mm_unpacklo_epi16(bgcolor, _mm_setzero_si128()); - __m128i fg_hi = _mm_unpackhi_epi16(fgcolor, _mm_setzero_si128()); - __m128i bg_hi = _mm_unpackhi_epi16(bgcolor, _mm_setzero_si128()); - - __m128i out_lo, out_hi; - if (BlendT::Mode == (int)BlendModes::AddClamp) - { - out_lo = _mm_add_epi32(fg_lo, bg_lo); - out_hi = _mm_add_epi32(fg_hi, bg_hi); - } - else if (BlendT::Mode == (int)BlendModes::SubClamp) - { - out_lo = _mm_sub_epi32(fg_lo, bg_lo); - out_hi = _mm_sub_epi32(fg_hi, bg_hi); - } - else if (BlendT::Mode == (int)BlendModes::RevSubClamp) - { - out_lo = _mm_sub_epi32(bg_lo, fg_lo); - out_hi = _mm_sub_epi32(bg_hi, fg_hi); - } - - out_lo = _mm_srai_epi32(out_lo, 8); - out_hi = _mm_srai_epi32(out_hi, 8); - __m128i outcolor = _mm_packs_epi32(out_lo, out_hi); - outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); - outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); - return outcolor; - } - } -} - -template -class RectScreenDrawer32 -{ -public: - static void Execute(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) - { - using namespace TriScreenDrawerModes; - - if (args->SimpleShade()) - { - Loop(destOrg, destWidth, destHeight, destPitch, args, thread); - } - else - { - Loop(destOrg, destWidth, destHeight, destPitch, args, thread); - } - } - -private: - template - FORCEINLINE static void VECTORCALL Loop(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) - { - using namespace TriScreenDrawerModes; - - int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth); - int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth); - int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight); - int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight); - - if (x1 <= x0 || y1 <= y0) - return; - - uint32_t srcalpha = args->SrcAlpha(); - uint32_t destalpha = args->DestAlpha(); - - // Setup step variables - float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0()); - float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0()); - uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000); - uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000); - uint32_t stepU = (int32_t)(fstepU * 0x1000000); - uint32_t stepV = (int32_t)(fstepV * 0x1000000); - - // Sampling stuff - uint32_t color = args->Color(); - const uint32_t * RESTRICT translation = (const uint32_t *)args->Translation(); - const uint32_t * RESTRICT texPixels = (const uint32_t *)args->TexturePixels(); - uint32_t texWidth = args->TextureWidth(); - uint32_t texHeight = args->TextureHeight(); - uint32_t oneU, oneV; - if (SamplerT::Mode != (int)Samplers::Fill) - { - oneU = ((0x800000 + texWidth - 1) / texWidth) * 2 + 1; - oneV = ((0x800000 + texHeight - 1) / texHeight) * 2 + 1; - } - else - { - oneU = 0; - oneV = 0; - } - - // Shade constants - __m128i inv_desaturate, shade_fade, shade_light; - int desaturate; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - inv_desaturate = _mm_setr_epi16(256, 256 - args->ShadeDesaturate(), 256 - args->ShadeDesaturate(), 256 - args->ShadeDesaturate(), 256, 256 - args->ShadeDesaturate(), 256 - args->ShadeDesaturate(), 256 - args->ShadeDesaturate()); - shade_fade = _mm_set_epi16(args->ShadeFadeAlpha(), args->ShadeFadeRed(), args->ShadeFadeGreen(), args->ShadeFadeBlue(), args->ShadeFadeAlpha(), args->ShadeFadeRed(), args->ShadeFadeGreen(), args->ShadeFadeBlue()); - shade_light = _mm_set_epi16(args->ShadeLightAlpha(), args->ShadeLightRed(), args->ShadeLightGreen(), args->ShadeLightBlue(), args->ShadeLightAlpha(), args->ShadeLightRed(), args->ShadeLightGreen(), args->ShadeLightBlue()); - desaturate = args->ShadeDesaturate(); - } - else - { - inv_desaturate = _mm_setzero_si128(); - shade_fade = _mm_setzero_si128(); - shade_light = _mm_setzero_si128(); - desaturate = 0; - } - - // Setup light - uint32_t lightpos = args->Light(); - lightpos += lightpos >> 7; // 255 -> 256 - __m128i mlight = _mm_set_epi16(256, lightpos, lightpos, lightpos, 256, lightpos, lightpos, lightpos); - __m128i shade_fade_lit; - if (ShadeModeT::Mode == (int)ShadeMode::Advanced) - { - __m128i inv_light = _mm_sub_epi16(_mm_set_epi16(0, 256, 256, 256, 0, 256, 256, 256), mlight); - shade_fade_lit = _mm_mullo_epi16(shade_fade, inv_light); - } - else - { - shade_fade_lit = _mm_setzero_si128(); - } - - int count = x1 - x0; - int sseCount = count / 2; - - uint32_t posV = startV; - for (int y = y0; y < y1; y++, posV += stepV) - { - int coreBlock = y / 8; - if (coreBlock % thread->num_cores != thread->core) - { - continue; - } - - uint32_t *dest = ((uint32_t*)destOrg) + y * destPitch + x0; - - uint32_t posU = startU; - for (int i = 0; i < sseCount; i++) - { - // Load bgcolor - __m128i bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)dest), _mm_setzero_si128()); - else - bgcolor = _mm_setzero_si128(); - - // Sample fgcolor - unsigned int ifgcolor[2], ifgshade[2]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[0]; - ifgcolor[0] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[0] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, x0 + i * 2, y); - posU += stepU; - - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = dest[1]; - ifgcolor[1] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[1] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, x0 + i * 2 + 1, y); - posU += stepU; - - // Shade and blend - __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); - fgcolor = Shade32(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light, _mm_setzero_si128()); - __m128i outcolor = Blend32(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha); - - // Store result - _mm_storel_epi64((__m128i*)dest, outcolor); - dest += 2; - } - - if (sseCount * 2 != count) - { - // Load bgcolor - __m128i bgcolor; - if (BlendT::Mode != (int)BlendModes::Opaque) - bgcolor = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*dest), _mm_setzero_si128()); - else - bgcolor = _mm_setzero_si128(); - - // Sample fgcolor - unsigned int ifgcolor[2], ifgshade[2]; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = *dest; - ifgcolor[0] = Sample32(posU, posV, texPixels, texWidth, texHeight, oneU, oneV, color, translation); - ifgshade[0] = SampleShade32(posU, posV, texPixels, texWidth, texHeight, x0 + sseCount * 2, y); - ifgcolor[1] = 0; - ifgshade[1] = 0; - posU += stepU; - - // Shade and blend - __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); - fgcolor = Shade32(fgcolor, mlight, ifgcolor[0], ifgcolor[1], desaturate, inv_desaturate, shade_fade_lit, shade_light, _mm_setzero_si128()); - __m128i outcolor = Blend32(fgcolor, bgcolor, ifgcolor[0], ifgcolor[1], ifgshade[0], ifgshade[1], srcalpha, destalpha); - - // Store result - *dest = _mm_cvtsi128_si32(outcolor); - } - } - } -}; diff --git a/src/polyrenderer/drawers/poly_drawer8.h b/src/polyrenderer/drawers/poly_drawer8.h deleted file mode 100644 index 1db272885..000000000 --- a/src/polyrenderer/drawers/poly_drawer8.h +++ /dev/null @@ -1,295 +0,0 @@ -/* -** Polygon Doom software renderer -** Copyright (c) 2016 Magnus Norddahl -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#pragma once - -#include "screen_triangle.h" - -namespace TriScreenDrawerModes -{ - template - FORCEINLINE unsigned int Sample8(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight, uint32_t color, const uint8_t *translation) - { - uint8_t texel; - if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill || SamplerT::Mode == (int)Samplers::Fuzz || SamplerT::Mode == (int)Samplers::FogBoundary) - { - return color; - } - else if (SamplerT::Mode == (int)Samplers::Translated) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - return translation[texPixels[texelX * texHeight + texelY]]; - } - else - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - texel = texPixels[texelX * texHeight + texelY]; - } - - if (SamplerT::Mode == (int)Samplers::Skycap) - { - int start_fade = 2; // How fast it should fade out - - int alpha_top = clamp(v >> (16 - start_fade), 0, 256); - int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256); - int a = MIN(alpha_top, alpha_bottom); - int inv_a = 256 - a; - - if (a == 256) - return texel; - - uint32_t capcolor = GPalette.BaseColors[color].d; - uint32_t texelrgb = GPalette.BaseColors[texel].d; - uint32_t r = RPART(texelrgb); - uint32_t g = GPART(texelrgb); - uint32_t b = BPART(texelrgb); - uint32_t capcolor_red = RPART(capcolor); - uint32_t capcolor_green = GPART(capcolor); - uint32_t capcolor_blue = BPART(capcolor); - r = (r * a + capcolor_red * inv_a + 127) >> 8; - g = (g * a + capcolor_green * inv_a + 127) >> 8; - b = (b * a + capcolor_blue * inv_a + 127) >> 8; - return RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; - } - else - { - return texel; - } - } - - template - FORCEINLINE unsigned int SampleShade8(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight, int x, int y) - { - if (SamplerT::Mode == (int)Samplers::Shaded) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = texPixels[texelX * texHeight + texelY]; - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - return sampleshadeout; - } - else if (SamplerT::Mode == (int)Samplers::Stencil) - { - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - return texPixels[texelX * texHeight + texelY] != 0 ? 256 : 0; - } - else if (SamplerT::Mode == (int)Samplers::Fuzz) - { - using namespace swrenderer; - - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = (texPixels[texelX * texHeight + texelY] != 0) ? 256 : 0; - - fixed_t fuzzscale = (200 << FRACBITS) / viewheight; - - int scaled_x = (x * fuzzscale) >> FRACBITS; - int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + fuzzpos; - - fixed_t fuzzcount = FUZZTABLE << FRACBITS; - fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; - unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; - - sampleshadeout = (sampleshadeout * alpha) >> 5; - return sampleshadeout; - } - else - { - return 0; - } - } - - template - FORCEINLINE uint8_t ShadeAndBlend8(uint8_t fgcolor, uint8_t bgcolor, uint32_t fgshade, uint32_t lightshade, const uint8_t *colormaps, uint32_t srcalpha, uint32_t destalpha) - { - lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00; - uint8_t shadedfg = colormaps[lightshade + fgcolor]; - - if (BlendT::Mode == (int)BlendModes::Opaque) - { - return shadedfg; - } - else if (BlendT::Mode == (int)BlendModes::Masked) - { - return (fgcolor != 0) ? shadedfg : bgcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddSrcColorOneMinusSrcColor) - { - int32_t fg_r = GPalette.BaseColors[shadedfg].r; - int32_t fg_g = GPalette.BaseColors[shadedfg].g; - int32_t fg_b = GPalette.BaseColors[shadedfg].b; - int32_t bg_r = GPalette.BaseColors[bgcolor].r; - int32_t bg_g = GPalette.BaseColors[bgcolor].g; - int32_t bg_b = GPalette.BaseColors[bgcolor].b; - int32_t inv_fg_r = 256 - (fg_r + (fg_r >> 7)); - int32_t inv_fg_g = 256 - (fg_g + (fg_g >> 7)); - int32_t inv_fg_b = 256 - (fg_b + (fg_b >> 7)); - fg_r = MIN(fg_r + ((bg_r * inv_fg_r + 127) >> 8), 255); - fg_g = MIN(fg_g + ((bg_g * inv_fg_g + 127) >> 8), 255); - fg_b = MIN(fg_b + ((bg_b * inv_fg_b + 127) >> 8), 255); - - shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)]; - return (fgcolor != 0) ? shadedfg : bgcolor; - } - else if (BlendT::Mode == (int)BlendModes::Shaded) - { - fgshade = (fgshade * srcalpha + 128) >> 8; - uint32_t alpha = fgshade; - uint32_t inv_alpha = 256 - fgshade; - int32_t fg_r = GPalette.BaseColors[shadedfg].r; - int32_t fg_g = GPalette.BaseColors[shadedfg].g; - int32_t fg_b = GPalette.BaseColors[shadedfg].b; - int32_t bg_r = GPalette.BaseColors[bgcolor].r; - int32_t bg_g = GPalette.BaseColors[bgcolor].g; - int32_t bg_b = GPalette.BaseColors[bgcolor].b; - - fg_r = (fg_r * alpha + bg_r * inv_alpha + 127) >> 8; - fg_g = (fg_g * alpha + bg_g * inv_alpha + 127) >> 8; - fg_b = (fg_b * alpha + bg_b * inv_alpha + 127) >> 8; - - shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)]; - return (alpha != 0) ? shadedfg : bgcolor; - } - else if (BlendT::Mode == (int)BlendModes::AddClampShaded) - { - fgshade = (fgshade * srcalpha + 128) >> 8; - uint32_t alpha = fgshade; - int32_t fg_r = GPalette.BaseColors[shadedfg].r; - int32_t fg_g = GPalette.BaseColors[shadedfg].g; - int32_t fg_b = GPalette.BaseColors[shadedfg].b; - int32_t bg_r = GPalette.BaseColors[bgcolor].r; - int32_t bg_g = GPalette.BaseColors[bgcolor].g; - int32_t bg_b = GPalette.BaseColors[bgcolor].b; - - fg_r = MIN(bg_r + ((fg_r * alpha + 127) >> 8), 255); - fg_g = MIN(bg_g + ((fg_g * alpha + 127) >> 8), 255); - fg_b = MIN(bg_b + ((fg_b * alpha + 127) >> 8), 255); - - shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)]; - - return (alpha != 0) ? shadedfg : bgcolor; - } - else - { - int32_t fg_r = GPalette.BaseColors[shadedfg].r; - int32_t fg_g = GPalette.BaseColors[shadedfg].g; - int32_t fg_b = GPalette.BaseColors[shadedfg].b; - int32_t bg_r = GPalette.BaseColors[bgcolor].r; - int32_t bg_g = GPalette.BaseColors[bgcolor].g; - int32_t bg_b = GPalette.BaseColors[bgcolor].b; - - if (BlendT::Mode == (int)BlendModes::AddClamp) - { - fg_r = MIN(int32_t(fg_r * srcalpha + bg_r * destalpha + 127) >> 8, 255); - fg_g = MIN(int32_t(fg_g * srcalpha + bg_g * destalpha + 127) >> 8, 255); - fg_b = MIN(int32_t(fg_b * srcalpha + bg_b * destalpha + 127) >> 8, 255); - } - else if (BlendT::Mode == (int)BlendModes::SubClamp) - { - fg_r = MAX(int32_t(fg_r * srcalpha - bg_r * destalpha + 127) >> 8, 0); - fg_g = MAX(int32_t(fg_g * srcalpha - bg_g * destalpha + 127) >> 8, 0); - fg_b = MAX(int32_t(fg_b * srcalpha - bg_b * destalpha + 127) >> 8, 0); - } - else if (BlendT::Mode == (int)BlendModes::RevSubClamp) - { - fg_r = MAX(int32_t(bg_r * srcalpha - fg_r * destalpha + 127) >> 8, 0); - fg_g = MAX(int32_t(bg_g * srcalpha - fg_g * destalpha + 127) >> 8, 0); - fg_b = MAX(int32_t(bg_b * srcalpha - fg_b * destalpha + 127) >> 8, 0); - } - - shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)]; - return (fgcolor != 0) ? shadedfg : bgcolor; - } - } -} - -template -class RectScreenDrawer8 -{ -public: - static void Execute(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) - { - using namespace TriScreenDrawerModes; - - int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth); - int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth); - int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight); - int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight); - - if (x1 <= x0 || y1 <= y0) - return; - - auto colormaps = args->BaseColormap(); - uint32_t srcalpha = args->SrcAlpha(); - uint32_t destalpha = args->DestAlpha(); - - // Setup step variables - float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0()); - float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0()); - uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000); - uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000); - uint32_t stepU = (int32_t)(fstepU * 0x1000000); - uint32_t stepV = (int32_t)(fstepV * 0x1000000); - - // Sampling stuff - uint32_t color = args->Color(); - const uint8_t * RESTRICT translation = args->Translation(); - const uint8_t * RESTRICT texPixels = args->TexturePixels(); - uint32_t texWidth = args->TextureWidth(); - uint32_t texHeight = args->TextureHeight(); - - // Setup light - uint32_t lightshade = args->Light(); - lightshade += lightshade >> 7; // 255 -> 256 - if (SamplerT::Mode == (int)Samplers::Fuzz) lightshade = 256; - - int count = x1 - x0; - - uint32_t posV = startV; - for (int y = y0; y < y1; y++, posV += stepV) - { - int coreBlock = y / 8; - if (coreBlock % thread->num_cores != thread->core) - { - continue; - } - - uint8_t *dest = ((uint8_t*)destOrg) + y * destPitch + x0; - - uint32_t posU = startU; - for (int i = 0; i < count; i++) - { - uint8_t bgcolor = *dest; - if (SamplerT::Mode == (int)Samplers::FogBoundary) color = bgcolor; - uint8_t fgcolor = Sample8(posU, posV, texPixels, texWidth, texHeight, color, translation); - uint32_t fgshade = SampleShade8(posU, posV, texPixels, texWidth, texHeight, x0 + i, y); - *dest = ShadeAndBlend8(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha); - - posU += stepU; - dest++; - } - } - } -}; diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index 5661f5c83..992a43d76 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -52,7 +52,7 @@ bool PolyTriangleDrawer::IsBgra() return isBgraRenderTarget; } -void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers) +void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas) { uint8_t *dest = (uint8_t*)canvas->GetPixels(); int dest_width = canvas->GetWidth(); @@ -74,7 +74,7 @@ void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, dest_width = clamp(viewport_x + viewport_width, 0, dest_width - offsetx); dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety); - queue->Push(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra, span_drawers); + queue->Push(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra); } void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip) @@ -99,7 +99,7 @@ void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool ///////////////////////////////////////////////////////////////////////////// -void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, uint8_t *new_dest, int new_dest_width, int new_dest_height, int new_dest_pitch, bool new_dest_bgra, bool new_span_drawers) +void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, uint8_t *new_dest, int new_dest_width, int new_dest_height, int new_dest_pitch, bool new_dest_bgra) { viewport_x = x; viewport_y = y; @@ -110,7 +110,6 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui dest_height = new_dest_height; dest_pitch = new_dest_pitch; dest_bgra = new_dest_bgra; - span_drawers = new_span_drawers; ccw = true; weaponScene = false; } @@ -132,9 +131,7 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs) args.clipbottom = dest_height; args.uniforms = &drawargs; args.destBgra = dest_bgra; - args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth(); - args.stencilValues = PolyStencilBuffer::Instance()->Values(); - args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); + args.stencilbuffer = PolyStencilBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values(); args.depthOffset = weaponScene ? 1.0f : 0.0f; @@ -191,9 +188,7 @@ void PolyTriangleThreadData::DrawArrays(const PolyDrawArgs &drawargs) args.clipbottom = dest_height; args.uniforms = &drawargs; args.destBgra = dest_bgra; - args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth(); - args.stencilValues = PolyStencilBuffer::Instance()->Values(); - args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); + args.stencilbuffer = PolyStencilBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values(); args.depthOffset = weaponScene ? 1.0f : 0.0f; @@ -379,10 +374,7 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo args->v3 = &clippedvert[i - 2]; if (IsFrontfacing(args) == ccw && args->CalculateGradients()) { - if (!span_drawers) - ScreenTriangle::Draw(args, this); - else - ScreenTriangle::DrawSWRender(args, this); + ScreenTriangle::Draw(args, this); } } } @@ -395,10 +387,7 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo args->v3 = &clippedvert[i]; if (IsFrontfacing(args) != ccw && args->CalculateGradients()) { - if (!span_drawers) - ScreenTriangle::Draw(args, this); - else - ScreenTriangle::DrawSWRender(args, this); + ScreenTriangle::Draw(args, this); } } } @@ -631,14 +620,14 @@ void PolySetWeaponSceneCommand::Execute(DrawerThread *thread) ///////////////////////////////////////////////////////////////////////////// -PolySetViewportCommand::PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers) - : x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra), span_drawers(span_drawers) +PolySetViewportCommand::PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra) + : x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra) { } void PolySetViewportCommand::Execute(DrawerThread *thread) { - PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, span_drawers); + PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index b10888455..c1e4871db 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -33,7 +33,7 @@ class PolyTriangleDrawer { public: static void ClearBuffers(DCanvas *canvas); - static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers); + static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas); static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw); static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided); static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable); @@ -47,7 +47,7 @@ class PolyTriangleThreadData public: PolyTriangleThreadData(int32_t core, int32_t num_cores) : core(core), num_cores(num_cores) { } - void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers); + void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra); void SetTransform(const Mat4f *objectToClip); void SetCullCCW(bool value) { ccw = value; } void SetTwoSided(bool value) { twosided = value; } @@ -88,7 +88,6 @@ private: bool twosided = false; bool weaponScene = false; const Mat4f *objectToClip = nullptr; - bool span_drawers = false; enum { max_additional_vertices = 16 }; }; @@ -144,7 +143,7 @@ private: class PolySetViewportCommand : public DrawerCommand { public: - PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers); + PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra); void Execute(DrawerThread *thread) override; FString DebugInfo() override { return "PolySetViewport"; } @@ -159,7 +158,6 @@ private: int dest_height; int dest_pitch; bool dest_bgra; - bool span_drawers; }; class DrawPolyTrianglesCommand : public DrawerCommand diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 036e4a55b..a52d897c2 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -52,9 +52,7 @@ struct TriDrawTriangleArgs ShadedTriVertex *v3; int32_t clipright; int32_t clipbottom; - uint8_t *stencilValues; - uint32_t *stencilMasks; - int32_t stencilPitch; + uint8_t *stencilbuffer; float *zbuffer; const PolyDrawArgs *uniforms; bool destBgra; @@ -138,39 +136,10 @@ enum class TriBlendMode AddShadedTranslated }; -enum class RectBlendMode -{ - TextureOpaque, - TextureMasked, - TextureAdd, - TextureSub, - TextureRevSub, - TextureAddSrcColor, - TranslatedOpaque, - TranslatedMasked, - TranslatedAdd, - TranslatedSub, - TranslatedRevSub, - TranslatedAddSrcColor, - Shaded, - AddShaded, - Stencil, - AddStencil, - FillOpaque, - FillAdd, - FillSub, - FillRevSub, - FillAddSrcColor, - Skycap, - Fuzz, - FogBoundary -}; - class ScreenTriangle { public: static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); - static void DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); @@ -222,35 +191,6 @@ namespace TriScreenDrawerModes struct StyleAddStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; struct StyleAddShadedTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; - enum class BlendModes { Opaque, Masked, AddClamp, SubClamp, RevSubClamp, AddSrcColorOneMinusSrcColor, Shaded, AddClampShaded }; - struct OpaqueBlend { static const int Mode = (int)BlendModes::Opaque; }; - struct MaskedBlend { static const int Mode = (int)BlendModes::Masked; }; - struct AddClampBlend { static const int Mode = (int)BlendModes::AddClamp; }; - struct SubClampBlend { static const int Mode = (int)BlendModes::SubClamp; }; - struct RevSubClampBlend { static const int Mode = (int)BlendModes::RevSubClamp; }; - struct AddSrcColorBlend { static const int Mode = (int)BlendModes::AddSrcColorOneMinusSrcColor; }; - struct ShadedBlend { static const int Mode = (int)BlendModes::Shaded; }; - struct AddClampShadedBlend { static const int Mode = (int)BlendModes::AddClampShaded; }; - - enum class FilterModes { Nearest, Linear }; - struct NearestFilter { static const int Mode = (int)FilterModes::Nearest; }; - struct LinearFilter { static const int Mode = (int)FilterModes::Linear; }; - - enum class ShadeMode { None, Simple, Advanced }; - struct NoShade { static const int Mode = (int)ShadeMode::None; }; - struct SimpleShade { static const int Mode = (int)ShadeMode::Simple; }; - struct AdvancedShade { static const int Mode = (int)ShadeMode::Advanced; }; - - enum class Samplers { Texture, Fill, Shaded, Stencil, Translated, Skycap, Fuzz, FogBoundary }; - struct TextureSampler { static const int Mode = (int)Samplers::Texture; }; - struct FillSampler { static const int Mode = (int)Samplers::Fill; }; - struct ShadedSampler { static const int Mode = (int)Samplers::Shaded; }; - struct StencilSampler { static const int Mode = (int)Samplers::Stencil; }; - struct TranslatedSampler { static const int Mode = (int)Samplers::Translated; }; - struct SkycapSampler { static const int Mode = (int)Samplers::Skycap; }; - struct FuzzSampler { static const int Mode = (int)Samplers::Fuzz; }; - struct FogBoundarySampler { static const int Mode = (int)Samplers::FogBoundary; }; - enum SWOptFlags { SWOPT_DynLights = 1, diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 6fee5d841..76d8a937e 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -201,11 +201,11 @@ void PolyRenderer::SetSceneViewport() height = (screenblocks*SCREENHEIGHT / 10) & ~7; int bottom = SCREENHEIGHT - (height + viewwindowy - ((height - viewheight) / 2)); - PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, RenderTarget, false); + PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, RenderTarget); } else // Rendering to camera texture { - PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, 0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), RenderTarget, false); + PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, 0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), RenderTarget); } } diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index 344749659..1a5aa842f 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -51,7 +51,7 @@ PolyModelRenderer::PolyModelRenderer(PolyRenderThread *thread, const Mat4f &worl { } -void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) +void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) { ModelActor = actor; const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); @@ -59,12 +59,14 @@ void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, co if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !mirrored); } void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) { if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true); ModelActor = nullptr; } @@ -98,7 +100,7 @@ VSMatrix PolyModelRenderer::GetViewToWorldMatrix() return objectToWorld; } -void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) +void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored) { ModelActor = actor; const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); @@ -107,6 +109,7 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); + PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, mirrored); } void PolyModelRenderer::EndDrawHUDModel(AActor *actor) @@ -116,6 +119,7 @@ void PolyModelRenderer::EndDrawHUDModel(AActor *actor) if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); + PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true); } void PolyModelRenderer::SetInterpolation(double interpolation) diff --git a/src/polyrenderer/scene/poly_model.h b/src/polyrenderer/scene/poly_model.h index cbfafce59..6e6ec57bc 100644 --- a/src/polyrenderer/scene/poly_model.h +++ b/src/polyrenderer/scene/poly_model.h @@ -36,13 +36,13 @@ public: ModelRendererType GetType() const override { return PolyModelRendererType; } - void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; + void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; void SetVertexBuffer(IModelVertexBuffer *buffer) override; void ResetVertexBuffer() override; VSMatrix GetViewToWorldMatrix() override; - void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) override; + void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored) override; void EndDrawHUDModel(AActor *actor) override; void SetInterpolation(double interpolation) override; void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override; diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index b8b324524..316281f65 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -94,7 +94,7 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s if (smf->flags & MDL_ROTATING) { - if (smf->rotationSpeed > 0.0000000001) + if (smf->rotationSpeed > 0.0000000001 || smf->rotationSpeed < -0.0000000001) { double turns = (I_GetTime() + I_GetTimeFrac()) / (200.0 / smf->rotationSpeed); turns -= floor(turns); @@ -171,7 +171,9 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / level.info->pixelstretch; objectToWorldMatrix.scale(1, stretch, 1); - BeginDrawModel(actor, smf, objectToWorldMatrix); + float orientation = scaleFactorX * scaleFactorY * scaleFactorZ; + + BeginDrawModel(actor, smf, objectToWorldMatrix, orientation < 0); RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), translation); EndDrawModel(actor, smf); } @@ -207,7 +209,9 @@ void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1); objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); - BeginDrawHUDModel(playermo, objectToWorldMatrix); + float orientation = smf->xscale * smf->yscale * smf->zscale; + + BeginDrawHUDModel(playermo, objectToWorldMatrix, orientation < 0); RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), 0); EndDrawHUDModel(playermo); } diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index b0d0f0230..bb5fb3b84 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -64,7 +64,7 @@ public: virtual ModelRendererType GetType() const = 0; - virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) = 0; + virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0; virtual void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) = 0; virtual IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) = 0; @@ -74,7 +74,7 @@ public: virtual VSMatrix GetViewToWorldMatrix() = 0; - virtual void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) = 0; + virtual void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0; virtual void EndDrawHUDModel(AActor *actor) = 0; virtual void SetInterpolation(double interpolation) = 0; diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp index 9049c949a..8e260daa7 100644 --- a/src/swrenderer/drawers/r_draw.cpp +++ b/src/swrenderer/drawers/r_draw.cpp @@ -272,7 +272,7 @@ namespace swrenderer void Execute(DrawerThread *thread) override { auto zbuffer = PolyZBuffer::Instance(); - int pitch = PolyStencilBuffer::Instance()->BlockWidth() * 8; + int pitch = PolyStencilBuffer::Instance()->Width(); float *values = zbuffer->Values() + y * pitch + x; int cnt = count; @@ -316,7 +316,7 @@ namespace swrenderer return; auto zbuffer = PolyZBuffer::Instance(); - int pitch = PolyStencilBuffer::Instance()->BlockWidth() * 8; + int pitch = PolyStencilBuffer::Instance()->Width(); float *values = zbuffer->Values() + y * pitch; int end = x2; diff --git a/src/v_video.cpp b/src/v_video.cpp index 1441a1966..0f754d4c3 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1005,7 +1005,7 @@ void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, i // //========================================================================== -void DFrameBuffer::SetOutputViewport(IntRect *bounds) +void DFrameBuffer::SetViewportRects(IntRect *bounds) { if (bounds) { diff --git a/src/v_video.h b/src/v_video.h index f88a65e65..66e38fca5 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -501,7 +501,7 @@ public: // Calculate gamma table void CalcGamma(float gamma, uint8_t gammalookup[256]); - virtual void SetOutputViewport(IntRect *bounds); + virtual void SetViewportRects(IntRect *bounds); int ScreenToWindowX(int x); int ScreenToWindowY(int y); diff --git a/src/version.h b/src/version.h index eef1c201b..30513f967 100644 --- a/src/version.h +++ b/src/version.h @@ -48,12 +48,12 @@ const char *GetVersionString(); #ifdef GIT_DESCRIPTION #define VERSIONSTR GIT_DESCRIPTION #else -#define VERSIONSTR "2.1pre" +#define VERSIONSTR "3.3pre" #endif // The version as seen in the Windows resource -#define RC_FILEVERSION 2,1,9999,0 -#define RC_PRODUCTVERSION 2,1,9999,0 +#define RC_FILEVERSION 3,2,9999,0 +#define RC_PRODUCTVERSION 3,2,9999,0 #define RC_PRODUCTVERSION2 VERSIONSTR // These are for content versioning. The current state is '3.3'. #define VER_MAJOR 3 @@ -94,13 +94,13 @@ const char *GetVersionString(); #define SAVEVER 4552 // This is so that derivates can use the same savegame versions without worrying about engine compatibility -#define GAMESIG "QZDOOM" -#define BASEWAD "qzdoom.pk3" +#define GAMESIG "GZDOOM" +#define BASEWAD "gzdoom.pk3" #define OPTIONALWAD "zd_extra.pk3" // More stuff that needs to be different for derivatives. -#define GAMENAME "QZDoom" -#define GAMENAMELOWERCASE "qzdoom" +#define GAMENAME "GZDoom" +#define GAMENAMELOWERCASE "gzdoom" #define FORUM_URL "http://forum.zdoom.org/" #define BUGS_FORUM_URL "http://forum.zdoom.org/viewforum.php?f=2"