diff --git a/CMakeLists.txt b/CMakeLists.txt index babb2715f..c0b8ac9df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,7 +218,7 @@ if( MSVC ) # String pooling # Function-level linking # Disable run-time type information - set( ALL_C_FLAGS "/GF /Gy /permissive- /DHAVE_SOFTPOLY" ) + set( ALL_C_FLAGS "/GF /Gy /permissive-" ) if ( HAVE_VULKAN ) set( ALL_C_FLAGS "${ALL_C_FLAGS} /DHAVE_VULKAN" ) @@ -260,7 +260,7 @@ if( MSVC ) string(REPLACE "/MDd " " " CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} ) else() set( REL_LINKER_FLAGS "" ) - set( ALL_C_FLAGS "-ffp-contract=off -DHAVE_SOFTPOLY" ) + set( ALL_C_FLAGS "-ffp-contract=off" ) if ( HAVE_VULKAN ) set( ALL_C_FLAGS "${ALL_C_FLAGS} -DHAVE_VULKAN" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa2c00f11..d4207606d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required( VERSION 3.1.0 ) +cmake_minimum_required( VERSION 3.1.0 ) include(precompiled_headers) @@ -454,7 +455,7 @@ set( PLAT_WIN32_SOURCES common/platform/win32/base_sysfb.cpp common/platform/win32/win32basevideo.cpp common/platform/win32/win32glvideo.cpp - common/platform/win32/win32polyvideo.cpp) + ) if (HAVE_VULKAN) set (PLAT_WIN32_SOURCES ${PLAT_WIN32_SOURCES} common/platform/win32/win32vulkanvideo.cpp ) @@ -633,10 +634,6 @@ file( GLOB HEADER_FILES common/rendering/gl_load/*.h common/rendering/gles/*.h common/rendering/hwrenderer/data/*.h - common/rendering/polyrenderer/*.h - common/rendering/polyrenderer/math/*.h - common/rendering/polyrenderer/drawers/*.h - common/rendering/polyrenderer/backend/*.h common/rendering/vulkan/*.h common/rendering/vulkan/system/*.h common/rendering/vulkan/renderer/*.h @@ -707,7 +704,6 @@ set ( SWRENDER_SOURCES rendering/swrenderer/things/r_sprite.cpp rendering/swrenderer/things/r_wallsprite.cpp rendering/swrenderer/things/r_decal.cpp - rendering/swrenderer/things/r_model.cpp rendering/swrenderer/plane/r_visibleplane.cpp rendering/swrenderer/plane/r_visibleplanelist.cpp rendering/swrenderer/plane/r_skyplane.cpp @@ -716,21 +712,11 @@ set ( SWRENDER_SOURCES rendering/swrenderer/plane/r_slopeplane.cpp ) -set( POLYRENDER_SOURCES - common/rendering/polyrenderer/drawers/poly_triangle.cpp - common/rendering/polyrenderer/drawers/poly_thread.cpp - common/rendering/polyrenderer/drawers/screen_triangle.cpp - common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp - common/rendering/polyrenderer/drawers/screen_shader.cpp - common/rendering/polyrenderer/drawers/screen_blend.cpp -) - # These files will be flagged as "headers" so that they appear in project files # without being compiled. set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} ${SWRENDER_SOURCES} - ${POLYRENDER_SOURCES} sc_man_scanner.h common/engine/sc_man_scanner.re g_statusbar/sbarinfo_commands.cpp @@ -763,7 +749,6 @@ set( VM_JIT_SOURCES set( FASTMATH_SOURCES rendering/swrenderer/r_all.cpp rendering/swrenderer/r_swscene.cpp - common/rendering/polyrenderer/poly_all.cpp common/textures/hires/hqnx/init.cpp common/textures/hires/hqnx/hq2x.cpp common/textures/hires/hqnx/hq3x.cpp @@ -843,12 +828,6 @@ if (HAVE_VULKAN) set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${VULKAN_SOURCES}) endif() -set (POLYBACKEND_SOURCES - common/rendering/polyrenderer/backend/poly_framebuffer.cpp - common/rendering/polyrenderer/backend/poly_buffers.cpp - common/rendering/polyrenderer/backend/poly_hwtexture.cpp - common/rendering/polyrenderer/backend/poly_renderstate.cpp -) set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${POLYBACKEND_SOURCES}) set (PCH_SOURCES @@ -1337,8 +1316,6 @@ include_directories( . common/rendering/gles/glad/include common/rendering/gles/Mali_OpenGL_ES_Emulator/include common/rendering/vulkan/thirdparty - common/rendering/polyrenderer/backend - common/rendering/polyrenderer/drawers common/scripting/vm common/scripting/jit common/scripting/core @@ -1449,7 +1426,6 @@ endif() if( DEM_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # Need to enable intrinsics for these files. set_property( SOURCE - common/rendering/polyrenderer/poly_all.cpp common/utility/palette.cpp common/utility/x86.cpp rendering/swrenderer/r_all.cpp @@ -1554,9 +1530,6 @@ source_group("Common\\Rendering\\Vulkan Renderer\\Textures" REGULAR_EXPRESSION " source_group("Common\\Rendering\\Vulkan Renderer\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/thirdparty/.+") source_group("Common\\Rendering\\Vulkan Renderer\\Third Party\\Volk" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/thirdparty/volk/.+") source_group("Common\\Rendering\\Vulkan Renderer\\Third Party\\Vk_Mem_Alloc" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/thirdparty/vk_mem_alloc.+") -source_group("Common\\Rendering\\Poly Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/polyrenderer/.+") -source_group("Common\\Rendering\\Poly Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/polyrenderer/drawers/.+") -source_group("Common\\Rendering\\Poly Renderer\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/polyrenderer/backend/.+") source_group("Common\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/models/.+") source_group("Common\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/.+") source_group("Common\\Textures\\Hires" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/hires/.+") diff --git a/src/common/platform/posix/cocoa/i_video.mm b/src/common/platform/posix/cocoa/i_video.mm index 2350ca954..b6c7d97a2 100644 --- a/src/common/platform/posix/cocoa/i_video.mm +++ b/src/common/platform/posix/cocoa/i_video.mm @@ -60,9 +60,6 @@ #ifdef HAVE_VULKAN #include "vulkan/system/vk_framebuffer.h" #endif -#ifdef HAVE_SOFTPOLY -#include "poly_framebuffer.h" -#endif extern bool ToggleFullscreen; @@ -101,7 +98,6 @@ extern bool ToggleFullscreen; EXTERN_CVAR(Bool, vid_hidpi) EXTERN_CVAR(Int, vid_defwidth) EXTERN_CVAR(Int, vid_defheight) -EXTERN_CVAR(Int, vid_preferbackend) EXTERN_CVAR(Bool, vk_debug) CVAR(Bool, mvk_debug, false, 0) @@ -376,7 +372,7 @@ class CocoaVideo : public IVideo public: CocoaVideo() { - ms_isVulkanEnabled = vid_preferbackend == 1 && NSAppKitVersionNumber >= 1404; // NSAppKitVersionNumber10_11 + ms_isVulkanEnabled = V_GetBackend() == 1 && NSAppKitVersionNumber >= 1404; // NSAppKitVersionNumber10_11 } ~CocoaVideo() @@ -450,23 +446,12 @@ public: else #endif -#ifdef HAVE_SOFTPOLY - if (vid_preferbackend == 2) - { - SetupOpenGLView(ms_window, OpenGLProfile::Legacy); - - fb = new PolyFrameBuffer(nullptr, vid_fullscreen); - } - else -#endif - { - SetupOpenGLView(ms_window, OpenGLProfile::Core); - } + SetupOpenGLView(ms_window, OpenGLProfile::Core); if (fb == nullptr) { #ifdef HAVE_GLES2 - if( (Args->CheckParm ("-gles2_renderer")) || (vid_preferbackend == 3) ) + if(V_GetBackend() == 2) fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen); else #endif diff --git a/src/common/platform/posix/sdl/sdlglvideo.cpp b/src/common/platform/posix/sdl/sdlglvideo.cpp index 335dc6206..5f6bc5143 100644 --- a/src/common/platform/posix/sdl/sdlglvideo.cpp +++ b/src/common/platform/posix/sdl/sdlglvideo.cpp @@ -58,10 +58,6 @@ #include "vulkan/system/vk_framebuffer.h" #endif -#ifdef HAVE_SOFTPOLY -#include "poly_framebuffer.h" -#endif - // MACROS ------------------------------------------------------------------ #if defined HAVE_VULKAN @@ -81,7 +77,6 @@ EXTERN_CVAR (Int, vid_adapter) EXTERN_CVAR (Int, vid_displaybits) EXTERN_CVAR (Int, vid_defwidth) EXTERN_CVAR (Int, vid_defheight) -EXTERN_CVAR (Int, vid_preferbackend) EXTERN_CVAR (Bool, cl_capfps) // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -233,157 +228,6 @@ bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface) } #endif -#ifdef HAVE_SOFTPOLY -namespace -{ - SDL_Renderer* polyrendertarget = nullptr; - SDL_Texture* polytexture = nullptr; - int polytexturew = 0; - int polytextureh = 0; - bool polyvsync = false; - bool polyfirstinit = true; -} - -void I_PolyPresentInit() -{ - assert(Priv::softpolyEnabled); - assert(Priv::window != nullptr); - - if (strcmp(vid_sdl_render_driver, "") != 0) - { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, vid_sdl_render_driver); - } -} - -uint8_t *I_PolyPresentLock(int w, int h, bool vsync, int &pitch) -{ - // When vsync changes we need to reinitialize - if (polyrendertarget && polyvsync != vsync) - { - I_PolyPresentDeinit(); - } - - if (!polyrendertarget) - { - polyvsync = vsync; - - polyrendertarget = SDL_CreateRenderer(Priv::window, -1, vsync ? SDL_RENDERER_PRESENTVSYNC : 0); - if (!polyrendertarget) - { - I_FatalError("Could not create render target for softpoly: %s\n", SDL_GetError()); - } - - // Tell the user which render driver is being used, but don't repeat - // outselves if we're just changing vsync. - if (polyfirstinit) - { - polyfirstinit = false; - - SDL_RendererInfo rendererInfo; - if (SDL_GetRendererInfo(polyrendertarget, &rendererInfo) == 0) - { - Printf("Using render driver %s\n", rendererInfo.name); - } - else - { - Printf("Failed to query render driver\n"); - } - } - - // Mask color - SDL_SetRenderDrawColor(polyrendertarget, 0, 0, 0, 255); - } - - if (!polytexture || polytexturew != w || polytextureh != h) - { - if (polytexture) - { - SDL_DestroyTexture(polytexture); - polytexture = nullptr; - polytexturew = polytextureh = 0; - } - if ((polytexture = SDL_CreateTexture(polyrendertarget, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h)) == nullptr) - I_Error("Failed to create %dx%d render target texture.", w, h); - polytexturew = w; - polytextureh = h; - } - - uint8_t* pixels; - SDL_LockTexture(polytexture, nullptr, (void**)&pixels, &pitch); - return pixels; -} - -void I_PolyPresentUnlock(int x, int y, int width, int height) -{ - SDL_UnlockTexture(polytexture); - - int ClientWidth, ClientHeight; - SDL_GetRendererOutputSize(polyrendertarget, &ClientWidth, &ClientHeight); - - SDL_Rect clearrects[4]; - int count = 0; - if (y > 0) - { - clearrects[count].x = 0; - clearrects[count].y = 0; - clearrects[count].w = ClientWidth; - clearrects[count].h = y; - count++; - } - if (y + height < ClientHeight) - { - clearrects[count].x = 0; - clearrects[count].y = y + height; - clearrects[count].w = ClientWidth; - clearrects[count].h = ClientHeight - clearrects[count].y; - count++; - } - if (x > 0) - { - clearrects[count].x = 0; - clearrects[count].y = y; - clearrects[count].w = x; - clearrects[count].h = height; - count++; - } - if (x + width < ClientWidth) - { - clearrects[count].x = x + width; - clearrects[count].y = y; - clearrects[count].w = ClientWidth - clearrects[count].x; - clearrects[count].h = height; - count++; - } - - if (count > 0) - SDL_RenderFillRects(polyrendertarget, clearrects, count); - - SDL_Rect dstrect; - dstrect.x = x; - dstrect.y = y; - dstrect.w = width; - dstrect.h = height; - SDL_RenderCopy(polyrendertarget, polytexture, nullptr, &dstrect); - - SDL_RenderPresent(polyrendertarget); -} - -void I_PolyPresentDeinit() -{ - if (polytexture) - { - SDL_DestroyTexture(polytexture); - polytexture = nullptr; - } - - if (polyrendertarget) - { - SDL_DestroyRenderer(polyrendertarget); - polyrendertarget = nullptr; - } -} -#endif - SDLVideo::SDLVideo () { @@ -399,11 +243,8 @@ SDLVideo::SDLVideo () I_FatalError("Only SDL 2.0.6 or later is supported."); } -#ifdef HAVE_SOFTPOLY - Priv::softpolyEnabled = vid_preferbackend == 2; -#endif #ifdef HAVE_VULKAN - Priv::vulkanEnabled = vid_preferbackend == 1; + Priv::vulkanEnabled = V_GetBackend() == 1; if (Priv::vulkanEnabled) { @@ -415,16 +256,6 @@ SDLVideo::SDLVideo () } } #endif -#ifdef HAVE_SOFTPOLY - if (Priv::softpolyEnabled) - { - Priv::CreateWindow(SDL_WINDOW_HIDDEN); - if (Priv::window == nullptr) - { - I_FatalError("Could not create SoftPoly window:\n%s\n",SDL_GetError()); - } - } -#endif } SDLVideo::~SDLVideo () @@ -461,16 +292,10 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer () } #endif -#ifdef HAVE_SOFTPOLY - if (Priv::softpolyEnabled) - { - fb = new PolyFrameBuffer(nullptr, vid_fullscreen); - } -#endif if (fb == nullptr) { #ifdef HAVE_GLES2 - if( (Args->CheckParm ("-gles2_renderer")) || (vid_preferbackend == 3) ) + if (V_GetBackend() == 2) fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen); else #endif @@ -503,16 +328,6 @@ int SystemBaseFrameBuffer::GetClientWidth() { int width = 0; -#ifdef HAVE_SOFTPOLY - if (Priv::softpolyEnabled) - { - if (polyrendertarget) - SDL_GetRendererOutputSize(polyrendertarget, &width, nullptr); - else - SDL_GetWindowSize(Priv::window, &width, nullptr); - return width; - } -#endif #ifdef HAVE_VULKAN assert(Priv::vulkanEnabled); @@ -526,17 +341,6 @@ int SystemBaseFrameBuffer::GetClientHeight() { int height = 0; -#ifdef HAVE_SOFTPOLY - if (Priv::softpolyEnabled) - { - if (polyrendertarget) - SDL_GetRendererOutputSize(polyrendertarget, nullptr, &height); - else - SDL_GetWindowSize(Priv::window, nullptr, &height); - return height; - } -#endif - #ifdef HAVE_VULKAN assert(Priv::vulkanEnabled); SDL_Vulkan_GetDrawableSize(Priv::window, nullptr, &height); diff --git a/src/common/platform/win32/hardware.cpp b/src/common/platform/win32/hardware.cpp index 31ed03d7c..1933bb521 100644 --- a/src/common/platform/win32/hardware.cpp +++ b/src/common/platform/win32/hardware.cpp @@ -44,9 +44,6 @@ #include "version.h" #include "printf.h" #include "win32glvideo.h" -#ifdef HAVE_SOFTPOLY -#include "win32polyvideo.h" -#endif #ifdef HAVE_VULKAN #include "win32vulkanvideo.h" #endif @@ -54,8 +51,6 @@ #include "i_system.h" #include "i_mainwindow.h" -EXTERN_CVAR(Int, vid_preferbackend) - IVideo *Video; // do not include GL headers here, only declare the necessary functions. @@ -130,15 +125,8 @@ void I_InitGraphics () // are the active app. Huh? } -#ifdef HAVE_SOFTPOLY - if (vid_preferbackend == 2) - { - Video = new Win32PolyVideo(); - } - else -#endif #ifdef HAVE_VULKAN - if (vid_preferbackend == 1) + if (V_GetBackend() == 1) { // first try Vulkan, if that fails OpenGL try @@ -157,10 +145,6 @@ void I_InitGraphics () Video = new Win32GLVideo(); } -#ifdef HAVE_SOFTPOLY - if (Video == NULL) - Video = new Win32PolyVideo(); -#endif // we somehow STILL don't have a display!! if (Video == NULL) I_FatalError ("Failed to initialize display"); diff --git a/src/common/platform/win32/i_system.cpp b/src/common/platform/win32/i_system.cpp index 02cd8ff9e..5459b7458 100644 --- a/src/common/platform/win32/i_system.cpp +++ b/src/common/platform/win32/i_system.cpp @@ -447,12 +447,10 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa vid_fullscreen = SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_GETCHECK, 0, 0 ) == BST_CHECKED; #ifdef HAVE_GLES2 if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN4, BM_GETCHECK, 0, 0) == BST_CHECKED) - vid_preferbackend = 3; + vid_preferbackend = 2; else #endif - if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN3, BM_GETCHECK, 0, 0) == BST_CHECKED) - vid_preferbackend = 2; - else if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN2, BM_GETCHECK, 0, 0) == BST_CHECKED) + if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN2, BM_GETCHECK, 0, 0) == BST_CHECKED) vid_preferbackend = 1; else if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN1, BM_GETCHECK, 0, 0) == BST_CHECKED) vid_preferbackend = 0; diff --git a/src/common/platform/win32/win32glvideo.cpp b/src/common/platform/win32/win32glvideo.cpp index 1d0cbae8b..ebeb13cc9 100644 --- a/src/common/platform/win32/win32glvideo.cpp +++ b/src/common/platform/win32/win32glvideo.cpp @@ -65,7 +65,6 @@ PROC zd_wglGetProcAddress(LPCSTR name); } EXTERN_CVAR(Int, vid_adapter) -EXTERN_CVAR(Int, vid_preferbackend) EXTERN_CVAR(Bool, vid_hdr) CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) @@ -110,7 +109,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer() SystemGLFrameBuffer *fb; #ifdef HAVE_GLES2 - if ((Args->CheckParm("-gles2_renderer")) || (vid_preferbackend == 3) ) + if (V_GetBackend() == 2) fb = new OpenGLESRenderer::OpenGLFrameBuffer(m_hMonitor, vid_fullscreen); else #endif diff --git a/src/common/platform/win32/win32polyvideo.cpp b/src/common/platform/win32/win32polyvideo.cpp deleted file mode 100644 index b6781b4ce..000000000 --- a/src/common/platform/win32/win32polyvideo.cpp +++ /dev/null @@ -1,198 +0,0 @@ - -#include -#include "hardware.h" -#include "engineerrors.h" -#include -#include "i_mainwindow.h" - -#ifdef HAVE_SOFTPOLY - -EXTERN_CVAR(Bool, vid_vsync) - -bool ViewportLinearScale(); - -#include -#pragma comment(lib, "d3d9.lib") - -#ifndef D3DPRESENT_FORCEIMMEDIATE -#define D3DPRESENT_FORCEIMMEDIATE 0x00000100L // MinGW -#endif - -namespace -{ - int SrcWidth = 0; - int SrcHeight = 0; - int ClientWidth = 0; - int ClientHeight = 0; - bool CurrentVSync = false; - - IDirect3D9Ex *d3d9 = nullptr; - IDirect3DDevice9Ex *device = nullptr; - IDirect3DSurface9* surface = nullptr; -} - -void I_PolyPresentInit() -{ - Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9); - if (!d3d9) - { - I_FatalError("Direct3DCreate9 failed"); - } - - RECT rect = {}; - GetClientRect(mainwindow.GetHandle(), &rect); - - ClientWidth = rect.right; - ClientHeight = rect.bottom; - - D3DPRESENT_PARAMETERS pp = {}; - pp.Windowed = true; - pp.SwapEffect = D3DSWAPEFFECT_FLIPEX; - pp.BackBufferWidth = ClientWidth; - pp.BackBufferHeight = ClientHeight; - pp.BackBufferCount = 1; - pp.hDeviceWindow = mainwindow.GetHandle(); - pp.PresentationInterval = CurrentVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; - - HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mainwindow.GetHandle(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, nullptr, &device); - if (FAILED(result)) - { - I_FatalError("IDirect3D9.CreateDevice failed"); - } -} - -uint8_t *I_PolyPresentLock(int w, int h, bool vsync, int &pitch) -{ - HRESULT result; - - RECT rect = {}; - GetClientRect(mainwindow.GetHandle(), &rect); - if (rect.right != ClientWidth || rect.bottom != ClientHeight || CurrentVSync != vsync) - { - if (surface) - { - surface->Release(); - surface = nullptr; - } - - CurrentVSync = vsync; - ClientWidth = rect.right; - ClientHeight = rect.bottom; - - D3DPRESENT_PARAMETERS pp = {}; - pp.Windowed = true; - pp.SwapEffect = D3DSWAPEFFECT_FLIPEX; - pp.BackBufferWidth = ClientWidth; - pp.BackBufferHeight = ClientHeight; - pp.BackBufferCount = 1; - pp.hDeviceWindow = mainwindow.GetHandle(); - pp.PresentationInterval = CurrentVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; - device->Reset(&pp); - } - - if (SrcWidth != w || SrcHeight != h || !surface) - { - if (surface) - { - surface->Release(); - surface = nullptr; - } - - SrcWidth = w; - SrcHeight = h; - result = device->CreateOffscreenPlainSurface(SrcWidth, SrcHeight, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, 0); - if (FAILED(result)) - { - I_FatalError("IDirect3DDevice9.CreateOffscreenPlainSurface failed"); - } - } - - D3DLOCKED_RECT lockrect = {}; - result = surface->LockRect(&lockrect, nullptr, D3DLOCK_DISCARD); - if (FAILED(result)) - { - pitch = 0; - return nullptr; - } - - pitch = lockrect.Pitch; - return (uint8_t*)lockrect.pBits; -} - -void I_PolyPresentUnlock(int x, int y, int width, int height) -{ - surface->UnlockRect(); - - IDirect3DSurface9 *backbuffer = nullptr; - HRESULT result = device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - if (FAILED(result)) - return; - - result = device->BeginScene(); - if (SUCCEEDED(result)) - { - int count = 0; - D3DRECT clearrects[4]; - if (y > 0) - { - clearrects[count].x1 = 0; - clearrects[count].y1 = 0; - clearrects[count].x2 = ClientWidth; - clearrects[count].y2 = y; - count++; - } - if (y + height < ClientHeight) - { - clearrects[count].x1 = 0; - clearrects[count].y1 = y + height; - clearrects[count].x2 = ClientWidth; - clearrects[count].y2 = ClientHeight; - count++; - } - if (x > 0) - { - clearrects[count].x1 = 0; - clearrects[count].y1 = y; - clearrects[count].x2 = x; - clearrects[count].y2 = y + height; - count++; - } - if (x + width < ClientWidth) - { - clearrects[count].x1 = x + width; - clearrects[count].y1 = y; - clearrects[count].x2 = ClientWidth; - clearrects[count].y2 = y + height; - count++; - } - if (count > 0) - device->Clear(count, clearrects, D3DCLEAR_TARGET, 0, 0.0f, 0); - - RECT srcrect = {}, dstrect = {}; - srcrect.right = SrcWidth; - srcrect.bottom = SrcHeight; - dstrect.left = x; - dstrect.top = y; - dstrect.right = x + width; - dstrect.bottom = y + height; - if (ViewportLinearScale()) - device->StretchRect(surface, &srcrect, backbuffer, &dstrect, D3DTEXF_LINEAR); - else - device->StretchRect(surface, &srcrect, backbuffer, &dstrect, D3DTEXF_POINT); - - result = device->EndScene(); - if (SUCCEEDED(result)) - device->PresentEx(nullptr, nullptr, 0, nullptr, CurrentVSync ? 0 : D3DPRESENT_FORCEIMMEDIATE); - } - - backbuffer->Release(); -} - -void I_PolyPresentDeinit() -{ - if (surface) surface->Release(); - if (device) device->Release(); - if (d3d9) d3d9->Release(); -} - -#endif \ No newline at end of file diff --git a/src/common/platform/win32/win32polyvideo.h b/src/common/platform/win32/win32polyvideo.h deleted file mode 100644 index 3a1c36242..000000000 --- a/src/common/platform/win32/win32polyvideo.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "win32basevideo.h" -#include "c_cvars.h" -#include "poly_framebuffer.h" - -EXTERN_CVAR(Bool, vid_fullscreen) - -class Win32PolyVideo : public Win32BaseVideo -{ -public: - void Shutdown() override - { - } - - DFrameBuffer *CreateFrameBuffer() override - { - auto fb = new PolyFrameBuffer(m_hMonitor, vid_fullscreen); - return fb; - } -}; diff --git a/src/common/rendering/polyrenderer/backend/poly_buffers.cpp b/src/common/rendering/polyrenderer/backend/poly_buffers.cpp deleted file mode 100644 index 10ebef0d0..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_buffers.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* -** Softpoly backend -** Copyright (c) 2016-2020 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. -** -*/ - -#include "poly_buffers.h" -#include "poly_framebuffer.h" -#include "poly_renderstate.h" -#include "poly_thread.h" -#include "engineerrors.h" - -PolyBuffer *PolyBuffer::First = nullptr; - -PolyBuffer::PolyBuffer() -{ - Next = First; - First = this; - if (Next) Next->Prev = this; -} - -PolyBuffer::~PolyBuffer() -{ - if (Next) Next->Prev = Prev; - if (Prev) Prev->Next = Next; - else First = Next; - - auto fb = GetPolyFrameBuffer(); - if (fb && !mData.empty()) - fb->FrameDeleteList.Buffers.push_back(std::move(mData)); -} - -void PolyBuffer::ResetAll() -{ - for (PolyBuffer *cur = PolyBuffer::First; cur; cur = cur->Next) - cur->Reset(); -} - -void PolyBuffer::Reset() -{ -} - -void PolyBuffer::SetData(size_t size, const void *data, BufferUsageType usage) -{ - mData.resize(size); - map = mData.data(); - if (data) - memcpy(map, data, size); - buffersize = size; -} - -void PolyBuffer::SetSubData(size_t offset, size_t size, const void *data) -{ - memcpy(static_cast(map) + offset, data, size); -} - -void PolyBuffer::Resize(size_t newsize) -{ - mData.resize(newsize); - buffersize = newsize; - map = mData.data(); -} - -void PolyBuffer::Map() -{ -} - -void PolyBuffer::Unmap() -{ -} - -void *PolyBuffer::Lock(unsigned int size) -{ - if (mData.size() < (size_t)size) - Resize(size); - return map; -} - -void PolyBuffer::Unlock() -{ -} - -///////////////////////////////////////////////////////////////////////////// - -void PolyVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) -{ - VertexFormat = GetPolyFrameBuffer()->GetRenderState()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs); -} - -///////////////////////////////////////////////////////////////////////////// - -void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) -{ - uint8_t* buff = (uint8_t*)vertices; - - // [GEC] finds the right frame. - uint32_t offsets[2] = { static_cast(frame0 * Stride), static_cast(frame1 * Stride) }; - uint8_t* vertexBuffers[2] = { buff + offsets[0], buff + offsets[1] }; - - const uint8_t* vertex = static_cast(vertexBuffers[0]) + mStride * index; - const float* attrVertex = reinterpret_cast(vertex + mOffsets[VATTR_VERTEX]); - - const uint8_t* vertex2 = static_cast(vertexBuffers[1]) + mStride * index; - const float* attrVertex2 = reinterpret_cast(vertex2 + mOffsets[VATTR_VERTEX]); - - const float *attrTexcoord = reinterpret_cast(vertex + mOffsets[VATTR_TEXCOORD]); - const uint8_t *attrColor = reinterpret_cast(vertex + mOffsets[VATTR_COLOR]); - const uint32_t* attrNormal = reinterpret_cast(vertex + mOffsets[VATTR_NORMAL]); - const uint32_t* attrNormal2 = reinterpret_cast(vertex + mOffsets[VATTR_NORMAL2]); - - // [GEC] Apply the formula for model interpolation - - float newVertex[3]; - - float t = thread->mainVertexShader.Data.uInterpolationFactor; - float invt = 1.0f - t; - - newVertex[0] = (invt * attrVertex[0]) + (t * attrVertex2[0]); - newVertex[1] = (invt * attrVertex[1]) + (t * attrVertex2[1]); - newVertex[2] = (invt * attrVertex[2]) + (t * attrVertex2[2]); - - thread->mainVertexShader.aPosition = { newVertex[0], newVertex[1], newVertex[2], 1.0f }; - thread->mainVertexShader.aTexCoord = { attrTexcoord[0], attrTexcoord[1] }; - - if ((UseVertexData & 1) == 0) - { - const auto &c = thread->mainVertexShader.Data.uVertexColor; - thread->mainVertexShader.aColor.X = c.X; - thread->mainVertexShader.aColor.Y = c.Y; - thread->mainVertexShader.aColor.Z = c.Z; - thread->mainVertexShader.aColor.W = c.W; - } - else - { - thread->mainVertexShader.aColor.X = attrColor[0] * (1.0f / 255.0f); - thread->mainVertexShader.aColor.Y = attrColor[1] * (1.0f / 255.0f); - thread->mainVertexShader.aColor.Z = attrColor[2] * (1.0f / 255.0f); - thread->mainVertexShader.aColor.W = attrColor[3] * (1.0f / 255.0f); - } - - if ((UseVertexData & 2) == 0) - { - const auto &n = thread->mainVertexShader.Data.uVertexNormal; - thread->mainVertexShader.aNormal = FVector4(n.X, n.Y, n.Z, 1.0); - thread->mainVertexShader.aNormal2 = thread->mainVertexShader.aNormal; - } - else - { - int n = *attrNormal; - int n2 = *attrNormal2; - float x = ((n << 22) >> 22) / 512.0f; - float y = ((n << 12) >> 22) / 512.0f; - float z = ((n << 2) >> 22) / 512.0f; - float x2 = ((n2 << 22) >> 22) / 512.0f; - float y2 = ((n2 << 12) >> 22) / 512.0f; - float z2 = ((n2 << 2) >> 22) / 512.0f; - thread->mainVertexShader.aNormal = FVector4(x, y, z, 0.0f); - thread->mainVertexShader.aNormal2 = FVector4(x2, y2, z2, 0.0f); - } -} - -///////////////////////////////////////////////////////////////////////////// - -void PolyDataBuffer::BindRange(FRenderState *state, size_t start, size_t length) -{ - static_cast(state)->Bind(this, (uint32_t)start, (uint32_t)length); -} diff --git a/src/common/rendering/polyrenderer/backend/poly_buffers.h b/src/common/rendering/polyrenderer/backend/poly_buffers.h deleted file mode 100644 index c364586fa..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_buffers.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include "hwrenderer/data/buffers.h" -#include "polyrenderer/drawers/poly_triangle.h" -#include "tarray.h" -#include - -#ifdef _MSC_VER -// silence bogus warning C4250: 'PolyVertexBuffer': inherits 'PolyBuffer::PolyBuffer::SetData' via dominance -// According to internet infos, the warning is erroneously emitted in this case. -#pragma warning(disable:4250) -#endif - -class PolyBuffer : virtual public IBuffer -{ -public: - PolyBuffer(); - ~PolyBuffer(); - - static void ResetAll(); - void Reset(); - - void SetData(size_t size, const void *data, BufferUsageType usage) override; - void SetSubData(size_t offset, size_t size, const void *data) override; - void Resize(size_t newsize) override; - - void Map() override; - void Unmap() override; - - void *Lock(unsigned int size) override; - void Unlock() override; - -private: - static PolyBuffer *First; - PolyBuffer *Prev = nullptr; - PolyBuffer *Next = nullptr; - std::vector mData; -}; - -class PolyVertexInputAssembly final : public PolyInputAssembly -{ -public: - size_t mOffsets[VATTR_MAX] = {}; - size_t mStride = 0; - - int NumBindingPoints; - size_t Stride; - std::vector Attrs; - int UseVertexData; - - void Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) override; -}; - -class PolyVertexBuffer : public IVertexBuffer, public PolyBuffer -{ -public: - PolyVertexBuffer() { } - void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override; - - PolyVertexInputAssembly *VertexFormat = nullptr; -}; - -class PolyIndexBuffer : public IIndexBuffer, public PolyBuffer -{ -public: - PolyIndexBuffer() { } -}; - -class PolyDataBuffer : public IDataBuffer, public PolyBuffer -{ -public: - PolyDataBuffer(int bindingpoint, bool ssbo, bool needresize) : bindingpoint(bindingpoint) - { - } - - void BindRange(FRenderState *state, size_t start, size_t length) override; - - int bindingpoint; -}; diff --git a/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp b/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp deleted file mode 100644 index cbe49da6f..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ /dev/null @@ -1,503 +0,0 @@ -/* -** Softpoly backend -** Copyright (c) 2016-2020 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. -** -*/ - -#include "v_video.h" -#include "m_png.h" - -#include "r_videoscale.h" -#include "i_time.h" -#include "v_text.h" -#include "i_video.h" -#include "v_draw.h" - -#include "hw_clock.h" -#include "hw_vrmodes.h" -#include "hw_cvars.h" -#include "hw_skydome.h" -#include "hwrenderer/data/hw_viewpointbuffer.h" -#include "flatvertices.h" -#include "hwrenderer/data/shaderuniforms.h" -#include "hw_lightbuffer.h" -#include "hwrenderer/postprocessing/hw_postprocess.h" - -#include "poly_framebuffer.h" -#include "poly_buffers.h" -#include "poly_renderstate.h" -#include "poly_hwtexture.h" -#include "engineerrors.h" - -void Draw2D(F2DDrawer *drawer, FRenderState &state); - -extern int rendered_commandbuffers; -extern int current_rendered_commandbuffers; - -extern bool gpuStatActive; -extern bool keepGpuStatActive; -extern FString gpuStatOutput; - -PolyFrameBuffer::PolyFrameBuffer(void *hMonitor, bool fullscreen) : Super(hMonitor, fullscreen) -{ - I_PolyPresentInit(); -} - -PolyFrameBuffer::~PolyFrameBuffer() -{ - // screen is already null at this point, but PolyHardwareTexture::ResetAll needs it during clean up. Is there a better way we can do this? - auto tmp = screen; - screen = this; - - PolyHardwareTexture::ResetAll(); - PolyBuffer::ResetAll(); - PPResource::ResetAll(); - - delete mScreenQuad.VertexBuffer; - delete mScreenQuad.IndexBuffer; - - delete mVertexData; - delete mSkyData; - delete mViewpoints; - delete mLights; - mShadowMap.Reset(); - - screen = tmp; - - I_PolyPresentDeinit(); -} - -void PolyFrameBuffer::InitializeState() -{ - vendorstring = "Poly"; - hwcaps = RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE; - glslversion = 4.50f; - uniformblockalignment = 1; - maxuniformblock = 0x7fffffff; - - mRenderState.reset(new PolyRenderState()); - - mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight()); - mSkyData = new FSkyVertexBuffer; - mViewpoints = new HWViewpointBuffer; - mLights = new FLightBuffer(); - - static const FVertexBufferAttribute format[] = - { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(ScreenQuadVertex, x) }, - { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(ScreenQuadVertex, u) }, - { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(ScreenQuadVertex, color0) } - }; - - uint32_t indices[6] = { 0, 1, 2, 1, 3, 2 }; - - mScreenQuad.VertexBuffer = screen->CreateVertexBuffer(); - mScreenQuad.VertexBuffer->SetFormat(1, 3, sizeof(ScreenQuadVertex), format); - - mScreenQuad.IndexBuffer = screen->CreateIndexBuffer(); - mScreenQuad.IndexBuffer->SetData(6 * sizeof(uint32_t), indices, BufferUsageType::Stream); - - CheckCanvas(); -} - -void PolyFrameBuffer::CheckCanvas() -{ - if (!mCanvas || mCanvas->GetWidth() != GetWidth() || mCanvas->GetHeight() != GetHeight()) - { - FlushDrawCommands(); - DrawerThreads::WaitForWorkers(); - - mCanvas.reset(new DCanvas(0, 0, true)); - mCanvas->Resize(GetWidth(), GetHeight(), false); - mDepthStencil.reset(); - mDepthStencil.reset(new PolyDepthStencil(GetWidth(), GetHeight())); - - mRenderState->SetRenderTarget(GetCanvas(), GetDepthStencil(), true); - } -} - -PolyCommandBuffer *PolyFrameBuffer::GetDrawCommands() -{ - if (!mDrawCommands) - { - mDrawCommands.reset(new PolyCommandBuffer(&mFrameMemory)); - mDrawCommands->SetLightBuffer(mLightBuffer->Memory()); - } - return mDrawCommands.get(); -} - -void PolyFrameBuffer::FlushDrawCommands() -{ - mRenderState->EndRenderPass(); - if (mDrawCommands) - { - mDrawCommands->Submit(); - mDrawCommands.reset(); - } -} - -EXTERN_CVAR(Float, vid_brightness) -EXTERN_CVAR(Float, vid_contrast) -EXTERN_CVAR(Float, vid_saturation) - -void PolyFrameBuffer::Update() -{ - twoD.Reset(); - Flush3D.Reset(); - - Flush3D.Clock(); - - Draw2D(); - twod->Clear(); - - Flush3D.Unclock(); - - FlushDrawCommands(); - - if (mCanvas) - { - int w = mCanvas->GetWidth(); - int h = mCanvas->GetHeight(); - int pixelsize = 4; - const uint8_t *src = (const uint8_t*)mCanvas->GetPixels(); - int pitch = 0; - uint8_t *dst = I_PolyPresentLock(w, h, cur_vsync, pitch); - if (dst) - { -#if 1 - // [GEC] with the help of dpJudas a new system of copying and applying gamma in the video buffer - auto copyqueue = std::make_shared(&mFrameMemory); - copyqueue->Push(dst, pitch / pixelsize, src, w, h, w, vid_gamma, vid_contrast, vid_brightness, vid_saturation); - DrawerThreads::Execute(copyqueue); -#else - for (int y = 0; y < h; y++) - { - memcpy(dst + y * pitch, src + y * w * pixelsize, w * pixelsize); - } -#endif - - DrawerThreads::WaitForWorkers(); - I_PolyPresentUnlock(mOutputLetterbox.left, mOutputLetterbox.top, mOutputLetterbox.width, mOutputLetterbox.height); - } - FPSLimit(); - } - - DrawerThreads::WaitForWorkers(); - mFrameMemory.Clear(); - FrameDeleteList.Buffers.clear(); - FrameDeleteList.Images.clear(); - - CheckCanvas(); - - Super::Update(); -} - - -void PolyFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function renderFunc) -{ - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); - - DCanvas *image = BaseLayer->GetImage(tex, 0, 0); - PolyDepthStencil *depthStencil = BaseLayer->GetDepthStencil(tex); - mRenderState->SetRenderTarget(image, depthStencil, false); - - IntRect bounds; - bounds.left = bounds.top = 0; - bounds.width = min(tex->GetWidth(), image->GetWidth()); - bounds.height = min(tex->GetHeight(), image->GetHeight()); - - renderFunc(bounds); - - FlushDrawCommands(); - DrawerThreads::WaitForWorkers(); - mRenderState->SetRenderTarget(GetCanvas(), GetDepthStencil(), true); - - tex->SetUpdated(true); -} - -static uint8_t ToIntColorComponent(float v) -{ - return clamp((int)(v * 255.0f + 0.5f), 0, 255); -} - -void PolyFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) -{ - afterBloomDrawEndScene2D(); - - if (fixedcm >= CM_FIRSTSPECIALCOLORMAP && fixedcm < CM_MAXCOLORMAP) - { - FSpecialColormap* scm = &SpecialColormaps[fixedcm - CM_FIRSTSPECIALCOLORMAP]; - - mRenderState->SetViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); - screen->mViewpoints->Set2D(*mRenderState, screen->GetWidth(), screen->GetHeight()); - - ScreenQuadVertex vertices[4] = - { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { (float)mScreenViewport.width, 0.0f, 1.0f, 0.0f }, - { 0.0f, (float)mScreenViewport.height, 0.0f, 1.0f }, - { (float)mScreenViewport.width, (float)mScreenViewport.height, 1.0f, 1.0f } - }; - mScreenQuad.VertexBuffer->SetData(4 * sizeof(ScreenQuadVertex), vertices, BufferUsageType::Stream); - - mRenderState->SetVertexBuffer(mScreenQuad.VertexBuffer, 0, 0); - mRenderState->SetIndexBuffer(mScreenQuad.IndexBuffer); - - mRenderState->SetObjectColor(PalEntry(255, int(scm->ColorizeStart[0] * 127.5f), int(scm->ColorizeStart[1] * 127.5f), int(scm->ColorizeStart[2] * 127.5f))); - mRenderState->SetAddColor(PalEntry(255, int(scm->ColorizeEnd[0] * 127.5f), int(scm->ColorizeEnd[1] * 127.5f), int(scm->ColorizeEnd[2] * 127.5f))); - - mRenderState->EnableDepthTest(false); - mRenderState->EnableMultisampling(false); - mRenderState->SetCulling(Cull_None); - - mRenderState->SetScissor(-1, -1, -1, -1); - mRenderState->SetColor(1, 1, 1, 1); - mRenderState->AlphaFunc(Alpha_GEqual, 0.f); - mRenderState->EnableTexture(false); - mRenderState->SetColormapShader(true); - mRenderState->DrawIndexed(DT_Triangles, 0, 6); - mRenderState->SetColormapShader(false); - mRenderState->SetObjectColor(0xffffffff); - mRenderState->SetAddColor(0); - mRenderState->SetVertexBuffer(screen->mVertexData); - mRenderState->EnableTexture(true); - mRenderState->ResetColor(); - } -} - - -void PolyFrameBuffer::SetVSync(bool vsync) -{ - cur_vsync = vsync; -} - -FRenderState* PolyFrameBuffer::RenderState() -{ - return mRenderState.get(); -} - - -void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) -{ - if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; - - MaterialLayerInfo* layer; - auto systex = static_cast(mat->GetLayer(0, translation, &layer)); - systex->GetImage(layer->layerTexture, translation, layer->scaleFlags); - - int numLayers = mat->NumLayers(); - for (int i = 1; i < numLayers; i++) - { - auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); // fixme: Upscale flags must be disabled for certain layers. - } -} - -IHardwareTexture *PolyFrameBuffer::CreateHardwareTexture(int numchannels) -{ - return new PolyHardwareTexture(); -} - -IVertexBuffer *PolyFrameBuffer::CreateVertexBuffer() -{ - return new PolyVertexBuffer(); -} - -IIndexBuffer *PolyFrameBuffer::CreateIndexBuffer() -{ - return new PolyIndexBuffer(); -} - -IDataBuffer *PolyFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) -{ - IDataBuffer *buffer = new PolyDataBuffer(bindingpoint, ssbo, needsresize); - if (bindingpoint == LIGHTBUF_BINDINGPOINT) - mLightBuffer = buffer; - return buffer; -} - -void PolyFrameBuffer::SetTextureFilterMode() -{ -} - -void PolyFrameBuffer::BlurScene(float amount) -{ -} - -void PolyFrameBuffer::UpdatePalette() -{ -} - -FTexture *PolyFrameBuffer::WipeStartScreen() -{ - SetViewportRects(nullptr); - - auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1); - auto systex = static_cast(tex->GetSystemTexture()); - - systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeStartScreen"); - - return tex; -} - -FTexture *PolyFrameBuffer::WipeEndScreen() -{ - Draw2D(); - twod->Clear(); - - auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1); - auto systex = static_cast(tex->GetSystemTexture()); - - systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeEndScreen"); - - return tex; -} - -TArray PolyFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) -{ - // [GEC] Really necessary to apply gamma, brightness, contrast and saturation for screenshot - - std::vector gammatablebuf(256); - uint8_t* gammatable = gammatablebuf.data(); - - float InvGamma = 1.0f / clamp(vid_gamma, 0.1f, 4.f); - float Brightness = clamp(vid_brightness, -0.8f, 0.8f); - float Contrast = clamp(vid_contrast, 0.1f, 3.f); - float Saturation = clamp(vid_saturation, -15.0f, 15.f); - - for (int x = 0; x < 256; x++) - { - float ramp = (float)(x / 255.f); - // Apply Contrast - // vec4 finalColor = vec4((((originalColor.rgb - vec3(0.5)) * Contrast) + vec3(0.5)), 1.0); - if(vid_contrast != 1.0f) - ramp = (((ramp - 0.5f) * Contrast) + 0.5f); - - // Apply Brightness - // vec4 finalColor = vec4(originalColor.rgb + Brightness, 1.0); - if (vid_brightness != 0.0f) - ramp += (Brightness / 2.0f); - - // Apply Gamma - // FragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma)); - if (vid_gamma != 1.0f) - ramp = pow(ramp, InvGamma); - - // Clamp ramp - ramp = clamp(ramp, 0.0f, 1.f); - - gammatable[x] = (uint8_t)(ramp * 255); - } - - int w = SCREENWIDTH; - int h = SCREENHEIGHT; - - TArray ScreenshotBuffer(w * h * 3, true); - const uint8_t* pixels = GetCanvas()->GetPixels(); - int dindex = 0; - - // Convert to RGB - for (int y = 0; y < h; y++) - { - int sindex = y * w * 4; - - for (int x = 0; x < w; x++) - { - uint32_t red = pixels[sindex + 2]; - uint32_t green = pixels[sindex + 1]; - uint32_t blue = pixels[sindex]; - - if (vid_saturation != 1.0f) - { - float NewR = (float)(red / 255.f); - float NewG = (float)(green / 255.f); - float NewB = (float)(blue / 255.f); - - // Apply Saturation - // float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750)); - // Out = luma.xxx + Saturation.xxx * (In - luma.xxx); - //float luma = (NewR * 0.2126729f) + (NewG * 0.7151522f) + (NewB * 0.0721750f); // Rec. 709 - float luma = (NewR * 0.299f) + (NewG * 0.587f) + (NewB * 0.114f); //Rec. 601 - NewR = luma + (Saturation * (NewR - luma)); - NewG = luma + (Saturation * (NewG - luma)); - NewB = luma + (Saturation * (NewB - luma)); - - // Clamp All - NewR = clamp(NewR, 0.0f, 1.f); - NewG = clamp(NewG, 0.0f, 1.f); - NewB = clamp(NewB, 0.0f, 1.f); - - red = (uint32_t)(NewR * 255.f); - green = (uint32_t)(NewG * 255.f); - blue = (uint32_t)(NewB * 255.f); - } - - // Apply Contrast / Brightness / Gamma - red = gammatable[red]; - green = gammatable[green]; - blue = gammatable[blue]; - - ScreenshotBuffer[dindex ] = red; - ScreenshotBuffer[dindex + 1] = green; - ScreenshotBuffer[dindex + 2] = blue; - - dindex += 3; - sindex += 4; - } - } - - pitch = w * 3; - color_type = SS_RGB; - gamma = 1.0f; - return ScreenshotBuffer; -} - -void PolyFrameBuffer::BeginFrame() -{ - SetViewportRects(nullptr); - CheckCanvas(); - -#if 0 - swrenderer::R_InitFuzzTable(GetCanvas()->GetPitch()); - static int next_random = 0; - swrenderer::fuzzpos = (swrenderer::fuzzpos + swrenderer::fuzz_random_x_offset[next_random] * FUZZTABLE / 100) % FUZZTABLE; - next_random++; - if (next_random == FUZZ_RANDOM_X_SIZE) - next_random = 0; -#endif -} - -void PolyFrameBuffer::Draw2D() -{ - ::Draw2D(twod, *mRenderState); -} - -unsigned int PolyFrameBuffer::GetLightBufferBlockSize() const -{ - return mLights->GetBlockSize(); -} - -void PolyFrameBuffer::UpdateShadowMap() -{ -} - -void PolyFrameBuffer::AmbientOccludeScene(float m5) -{ - //mPostprocess->AmbientOccludeScene(m5); -} diff --git a/src/common/rendering/polyrenderer/backend/poly_framebuffer.h b/src/common/rendering/polyrenderer/backend/poly_framebuffer.h deleted file mode 100644 index 9be76481f..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_framebuffer.h +++ /dev/null @@ -1,215 +0,0 @@ -#pragma once - -#include "gl_sysfb.h" -#include "r_memory.h" -#include "r_thread.h" -#include "poly_triangle.h" - -struct FRenderViewpoint; -class PolyDataBuffer; -class PolyRenderState; -class SWSceneDrawer; - -class PolyFrameBuffer : public SystemBaseFrameBuffer -{ - typedef SystemBaseFrameBuffer Super; - -public: - RenderMemory *GetFrameMemory() { return &mFrameMemory; } - PolyRenderState *GetRenderState() { return mRenderState.get(); } - DCanvas *GetCanvas() override { return mCanvas.get(); } - PolyDepthStencil *GetDepthStencil() { return mDepthStencil.get(); } - PolyCommandBuffer *GetDrawCommands(); - void FlushDrawCommands(); - - unsigned int GetLightBufferBlockSize() const; - - PolyFrameBuffer(void *hMonitor, bool fullscreen); - ~PolyFrameBuffer(); - int GetShaderCount() override { return 0; } - - void Update() override; - - bool IsPoly() override { return true; } - - void InitializeState() override; - - FRenderState* RenderState() override; - void PrecacheMaterial(FMaterial *mat, int translation) override; - void UpdatePalette() override; - void SetTextureFilterMode() override; - void BeginFrame() override; - void BlurScene(float amount) override; - void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; - void AmbientOccludeScene(float m5) override; - //void SetSceneRenderTarget(bool useSSAO) override; - - IHardwareTexture *CreateHardwareTexture(int numchannels) override; - IVertexBuffer *CreateVertexBuffer() override; - IIndexBuffer *CreateIndexBuffer() override; - IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override; - - FTexture *WipeStartScreen() override; - FTexture *WipeEndScreen() override; - - TArray GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) override; - - void SetVSync(bool vsync) override; - void Draw2D() override; - - struct DeleteList - { - std::vector> Buffers; - std::vector> Images; - } FrameDeleteList; - -private: - void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; - void UpdateShadowMap() override; - - void CheckCanvas(); - - IDataBuffer *mLightBuffer = nullptr; - - std::unique_ptr mRenderState; - std::unique_ptr mCanvas; - std::unique_ptr mDepthStencil; - std::unique_ptr mDrawCommands; - RenderMemory mFrameMemory; - - struct ScreenQuadVertex - { - float x, y, z; - float u, v; - PalEntry color0; - - ScreenQuadVertex() = default; - ScreenQuadVertex(float x, float y, float u, float v) : x(x), y(y), z(1.0f), u(u), v(v), color0(0xffffffff) { } - }; - - struct ScreenQuad - { - IVertexBuffer* VertexBuffer = nullptr; - IIndexBuffer* IndexBuffer = nullptr; - } mScreenQuad; - - bool cur_vsync = false; -}; - -inline PolyFrameBuffer *GetPolyFrameBuffer() { return static_cast(screen); } - -// [GEC] Original code of dpJudas, I add the formulas of gamma, brightness, contrast and saturation. -class CopyAndApplyGammaCommand : public DrawerCommand -{ -public: - CopyAndApplyGammaCommand(void* dest, int destpitch, const void* src, int width, int height, int srcpitch, - float gamma, float contrast, float brightness, float saturation) : dest(dest), src(src), destpitch(destpitch), width(width), height(height), srcpitch(srcpitch), - gamma(gamma), contrast(contrast), brightness(brightness), saturation(saturation) - { - } - - void Execute(DrawerThread* thread) - { - float Saturation = clamp(saturation, -15.0f, 15.f); - - std::vector gammatablebuf(256); - uint8_t* gammatable = gammatablebuf.data(); - InitGammaTable(gammatable); - - int w = width; - int start = thread->skipped_by_thread(0); - int count = thread->count_for_thread(0, height); - int sstep = thread->num_cores * srcpitch; - int dstep = thread->num_cores * destpitch; - uint32_t* d = (uint32_t*)dest + start * destpitch; - const uint32_t* s = (const uint32_t*)src + start * srcpitch; - for (int y = 0; y < count; y++) - { - for (int x = 0; x < w; x++) - { - uint32_t red = RPART(s[x]); - uint32_t green = GPART(s[x]); - uint32_t blue = BPART(s[x]); - uint32_t alpha = APART(s[x]); - - if (saturation != 1.0f) - { - float NewR = (float)(red / 255.f); - float NewG = (float)(green / 255.f); - float NewB = (float)(blue / 255.f); - - // Apply Saturation - // float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750)); - // Out = luma.xxx + Saturation.xxx * (In - luma.xxx); - //float luma = (NewR * 0.2126729f) + (NewG * 0.7151522f) + (NewB * 0.0721750f); // Rec. 709 - float luma = (NewR * 0.299f) + (NewG * 0.587f) + (NewB * 0.114f); //Rec. 601 - NewR = luma + (Saturation * (NewR - luma)); - NewG = luma + (Saturation * (NewG - luma)); - NewB = luma + (Saturation * (NewB - luma)); - - // Clamp All - NewR = clamp(NewR, 0.0f, 1.f); - NewG = clamp(NewG, 0.0f, 1.f); - NewB = clamp(NewB, 0.0f, 1.f); - - red = (uint32_t)(NewR * 255.f); - green = (uint32_t)(NewG * 255.f); - blue = (uint32_t)(NewB * 255.f); - } - - // Apply Contrast / Brightness / Gamma - red = gammatable[red]; - green = gammatable[green]; - blue = gammatable[blue]; - - d[x] = MAKEARGB(alpha, (uint8_t)red, (uint8_t)green, (uint8_t)blue); - } - d += dstep; - s += sstep; - } - } - -private: - void InitGammaTable(uint8_t *gammatable) - { - float InvGamma = 1.0f / clamp(gamma, 0.1f, 4.f); - float Brightness = clamp(brightness, -0.8f, 0.8f); - float Contrast = clamp(contrast, 0.1f, 3.f); - - for (int x = 0; x < 256; x++) - { - float ramp = (float)(x / 255.f); - - // Apply Contrast - // vec4 finalColor = vec4((((originalColor.rgb - vec3(0.5)) * Contrast) + vec3(0.5)), 1.0); - if (contrast != 1.0f) - ramp = (((ramp - 0.5f) * Contrast) + 0.5f); - - // Apply Brightness - // vec4 finalColor = vec4(originalColor.rgb + Brightness, 1.0); - if (brightness != 0.0f) - ramp += (Brightness / 2.0f); - - // Apply Gamma - // FragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma)); - if (gamma != 1.0f) - ramp = pow(ramp, InvGamma); - - // Clamp ramp - ramp = clamp(ramp, 0.0f, 1.f); - - gammatable[x] = (uint8_t)(ramp * 255); - } - } - - void* dest; - const void* src; - int destpitch; - int width; - int height; - int srcpitch; - float gamma; - float contrast; - float brightness; - float saturation; -}; diff --git a/src/common/rendering/polyrenderer/backend/poly_hwtexture.cpp b/src/common/rendering/polyrenderer/backend/poly_hwtexture.cpp deleted file mode 100644 index 3b931aa46..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_hwtexture.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* -** Softpoly backend -** Copyright (c) 2016-2020 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. -** -*/ - - -#include "c_cvars.h" -#include "hw_material.h" -#include "hw_cvars.h" -#include "hw_renderstate.h" -#include "poly_framebuffer.h" -#include "poly_hwtexture.h" - -PolyHardwareTexture *PolyHardwareTexture::First = nullptr; - -PolyHardwareTexture::PolyHardwareTexture() -{ - Next = First; - First = this; - if (Next) Next->Prev = this; -} - -PolyHardwareTexture::~PolyHardwareTexture() -{ - if (Next) Next->Prev = Prev; - if (Prev) Prev->Next = Next; - else First = Next; - - Reset(); -} - -void PolyHardwareTexture::ResetAll() -{ - for (PolyHardwareTexture *cur = PolyHardwareTexture::First; cur; cur = cur->Next) - cur->Reset(); -} - -void PolyHardwareTexture::Reset() -{ - if (auto fb = GetPolyFrameBuffer()) - { - auto &deleteList = fb->FrameDeleteList; - if (mCanvas) deleteList.Images.push_back(std::move(mCanvas)); - } -} - -DCanvas *PolyHardwareTexture::GetImage(FTexture *tex, int translation, int flags) -{ - if (!mCanvas) - CreateImage(tex, translation, flags); - return mCanvas.get(); -} - -PolyDepthStencil *PolyHardwareTexture::GetDepthStencil(FTexture *tex) -{ - if (!mDepthStencil) - { - int w = tex->GetWidth(); - int h = tex->GetHeight(); - mDepthStencil.reset(new PolyDepthStencil(w, h)); - } - return mDepthStencil.get(); -} - -void PolyHardwareTexture::AllocateBuffer(int w, int h, int texelsize) -{ - if (!mCanvas || mCanvas->GetWidth() != w || mCanvas->GetHeight() != h) - { - mCanvas.reset(new DCanvas(0, 0, texelsize == 4)); - mCanvas->Resize(w, h, false); - bufferpitch = mCanvas->GetPitch(); - } -} - -uint8_t *PolyHardwareTexture::MapBuffer() -{ - return mCanvas->GetPixels(); -} - -unsigned int PolyHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) -{ - return 0; -} - -void PolyHardwareTexture::CreateWipeTexture(int w, int h, const char *name) -{ - if (!mCanvas || mCanvas->GetWidth() != w || mCanvas->GetHeight() != h) - { - mCanvas.reset(new DCanvas(0, 0, true)); - mCanvas->Resize(w, h, false); - } - - auto fb = static_cast(screen); - - fb->FlushDrawCommands(); - DrawerThreads::WaitForWorkers(); - - uint32_t* dest = (uint32_t*)mCanvas->GetPixels(); - uint32_t* src = (uint32_t*)fb->GetCanvas()->GetPixels(); - int dpitch = mCanvas->GetPitch(); - int spitch = fb->GetCanvas()->GetPitch(); - int pixelsize = 4; - - for (int y = 0; y < h; y++) - { - memcpy(dest + dpitch * (h - 1 - y), src + spitch * y, w * pixelsize); - } -} - -void PolyHardwareTexture::CreateImage(FTexture *tex, int translation, int flags) -{ - mCanvas.reset(new DCanvas(0, 0, true)); - - if (!tex->isHardwareCanvas()) - { - FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); - mCanvas->Resize(texbuffer.mWidth, texbuffer.mHeight, false); - memcpy(mCanvas->GetPixels(), texbuffer.mBuffer, texbuffer.mWidth * texbuffer.mHeight * 4); - } - else - { - int w = tex->GetWidth(); - int h = tex->GetHeight(); - mCanvas->Resize(w, h, false); - } -} diff --git a/src/common/rendering/polyrenderer/backend/poly_hwtexture.h b/src/common/rendering/polyrenderer/backend/poly_hwtexture.h deleted file mode 100644 index c93f2339d..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_hwtexture.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#ifdef LoadImage -#undef LoadImage -#endif - -#define SHADED_TEXTURE -1 -#define DIRECT_PALETTE -2 - -#include "tarray.h" -#include "hw_ihwtexture.h" -#include "volk/volk.h" - -struct FMaterialState; -class PolyBuffer; - -class PolyHardwareTexture : public IHardwareTexture -{ -public: - PolyHardwareTexture(); - ~PolyHardwareTexture(); - - static void ResetAll(); - void Reset(); - - DCanvas *GetImage(FTexture *tex, int translation, int flags); - PolyDepthStencil *GetDepthStencil(FTexture *tex); - - // Software renderer stuff - void AllocateBuffer(int w, int h, int texelsize) override; - uint8_t *MapBuffer() override; - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) override; - - // Wipe screen - void CreateWipeTexture(int w, int h, const char *name); - -private: - void CreateImage(FTexture *tex, int translation, int flags); - - static PolyHardwareTexture *First; - PolyHardwareTexture *Prev = nullptr; - PolyHardwareTexture *Next = nullptr; - std::unique_ptr mCanvas; - std::unique_ptr mDepthStencil; -}; diff --git a/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp deleted file mode 100644 index 8dbc3fc78..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/* -** Softpoly backend -** Copyright (c) 2016-2020 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. -** -*/ - -#include "polyrenderer/backend/poly_renderstate.h" -#include "polyrenderer/backend/poly_framebuffer.h" -#include "polyrenderer/backend/poly_hwtexture.h" - -#include "hw_skydome.h" -#include "hw_viewpointuniforms.h" -#include "hw_lightbuffer.h" -#include "hw_cvars.h" -#include "hw_clock.h" -#include "flatvertices.h" -#include "hwrenderer/data/hw_viewpointbuffer.h" -#include "hwrenderer/data/shaderuniforms.h" - -static PolyDrawMode dtToDrawMode[] = -{ - PolyDrawMode::Points, - PolyDrawMode::Lines, - PolyDrawMode::Triangles, - PolyDrawMode::TriangleFan, - PolyDrawMode::TriangleStrip, -}; - -PolyRenderState::PolyRenderState() -{ - mIdentityMatrix.loadIdentity(); - Reset(); -} - -void PolyRenderState::ClearScreen() -{ - screen->mViewpoints->Set2D(*this, SCREENWIDTH, SCREENHEIGHT); - SetColor(0, 0, 0); - Draw(DT_TriangleStrip, FFlatVertexBuffer::FULLSCREEN_INDEX, 4, true); -} - -void PolyRenderState::Draw(int dt, int index, int count, bool apply) -{ - if (apply || mNeedApply) - Apply(); - - mDrawCommands->Draw(index, count, dtToDrawMode[dt]); -} - -void PolyRenderState::DrawIndexed(int dt, int index, int count, bool apply) -{ - if (apply || mNeedApply) - Apply(); - - mDrawCommands->DrawIndexed(index, count, dtToDrawMode[dt]); -} - -bool PolyRenderState::SetDepthClamp(bool on) -{ - bool lastValue = mDepthClamp; - mDepthClamp = on; - mNeedApply = true; - return lastValue; -} - -void PolyRenderState::SetDepthMask(bool on) -{ - mDepthMask = on; - mNeedApply = true; -} - -void PolyRenderState::SetDepthFunc(int func) -{ - mDepthFunc = func; - mNeedApply = true; -} - -void PolyRenderState::SetDepthRange(float min, float max) -{ - mDepthRangeMin = min; - mDepthRangeMax = max; - mNeedApply = true; -} - -void PolyRenderState::SetColorMask(bool r, bool g, bool b, bool a) -{ - mColorMask[0] = r; - mColorMask[1] = g; - mColorMask[2] = b; - mColorMask[3] = a; - mNeedApply = true; -} - -void PolyRenderState::SetStencil(int offs, int op, int flags) -{ - mStencilValue = screen->stencilValue + offs; - mStencilOp = op; - mNeedApply = true; - - if (flags != -1) - { - bool cmon = !(flags & SF_ColorMaskOff); - SetColorMask(cmon, cmon, cmon, cmon); // don't write to the graphics buffer - SetDepthMask(!(flags & SF_DepthMaskOff)); - } -} - -void PolyRenderState::SetCulling(int mode) -{ - mCulling = mode; - mNeedApply = true; -} - -void PolyRenderState::EnableClipDistance(int num, bool state) -{ -} - -void PolyRenderState::Clear(int targets) -{ - if (mNeedApply) - Apply(); - - //if (targets & CT_Color) - // mDrawCommands->ClearColor(); - if (targets & CT_Depth) - mDrawCommands->ClearDepth(65535.0f); - if (targets & CT_Stencil) - mDrawCommands->ClearStencil(0); -} - -void PolyRenderState::EnableStencil(bool on) -{ - mStencilEnabled = on; - mNeedApply = true; -} - -void PolyRenderState::SetScissor(int x, int y, int w, int h) -{ - if (w < 0) - { - x = 0; - y = 0; - w = mRenderTarget.Canvas->GetWidth(); - h = mRenderTarget.Canvas->GetHeight(); - } - mScissor.x = x; - mScissor.y = mRenderTarget.Canvas->GetHeight() - y - h; - mScissor.width = w; - mScissor.height = h; - mNeedApply = true; -} - -void PolyRenderState::SetViewport(int x, int y, int w, int h) -{ - auto fb = GetPolyFrameBuffer(); - if (w < 0) - { - x = 0; - y = 0; - w = mRenderTarget.Canvas->GetWidth(); - h = mRenderTarget.Canvas->GetHeight(); - } - mViewport.x = x; - mViewport.y = mRenderTarget.Canvas->GetHeight() - y - h; - mViewport.width = w; - mViewport.height = h; - mNeedApply = true; -} - -void PolyRenderState::EnableDepthTest(bool on) -{ - mDepthTest = on; - mNeedApply = true; -} - -void PolyRenderState::EnableMultisampling(bool on) -{ -} - -void PolyRenderState::EnableLineSmooth(bool on) -{ -} - -void PolyRenderState::EnableDrawBuffers(int count, bool apply) -{ -} - -void PolyRenderState::SetColormapShader(bool enable) -{ - mNeedApply = true; - mColormapShader = enable; -} - -void PolyRenderState::EndRenderPass() -{ - mDrawCommands = nullptr; - mNeedApply = true; - mFirstMatrixApply = true; -} - -void PolyRenderState::Apply() -{ - drawcalls.Clock(); - - if (!mDrawCommands) - { - mDrawCommands = GetPolyFrameBuffer()->GetDrawCommands(); - } - - if (mNeedApply) - { - mDrawCommands->SetViewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height, mRenderTarget.Canvas, mRenderTarget.DepthStencil, mRenderTarget.TopDown); - mDrawCommands->SetScissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height); - mDrawCommands->SetViewpointUniforms(mViewpointUniforms); - mDrawCommands->SetDepthClamp(mDepthClamp); - mDrawCommands->SetDepthMask(mDepthTest && mDepthMask); - mDrawCommands->SetDepthFunc(mDepthTest ? mDepthFunc : DF_Always); - mDrawCommands->SetDepthRange(mDepthRangeMin, mDepthRangeMax); - mDrawCommands->SetStencil(mStencilValue, mStencilOp); - mDrawCommands->EnableStencil(mStencilEnabled); - mDrawCommands->SetCulling(mCulling); - mDrawCommands->SetColorMask(mColorMask[0], mColorMask[1], mColorMask[2], mColorMask[3]); - mNeedApply = false; - } - - int fogset = 0; - if (mFogEnabled) - { - if (mFogEnabled == 2) - { - fogset = -3; // 2D rendering with 'foggy' overlay. - } - else if ((GetFogColor() & 0xffffff) == 0) - { - fogset = gl_fogmode; - } - else - { - fogset = -gl_fogmode; - } - } - - ApplyMaterial(); - - if (!mVertexBuffer) - SetVertexBuffer(screen->mVertexData); - - if (mVertexBuffer) - { - mDrawCommands->SetVertexBuffer(mVertexBuffer->Memory(), mVertexOffsets[0], mVertexOffsets[1]); // [GEC] Add offset params - } - if (mIndexBuffer) mDrawCommands->SetIndexBuffer(mIndexBuffer->Memory()); - mDrawCommands->SetInputAssembly(static_cast(mVertexBuffer)->VertexFormat); - mDrawCommands->SetRenderStyle(mRenderStyle); - - if (mColormapShader) - { - mDrawCommands->SetShader(EFF_NONE, 0, false, true); - } - else if (mSpecialEffect > EFF_NONE) - { - mDrawCommands->SetShader(mSpecialEffect, 0, false, false); - } - else - { - int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0); - mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, false); - } - - if (mMaterial.mMaterial && mMaterial.mMaterial->Source()) - mStreamData.timer = static_cast((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->Source()->GetShaderSpeed() / 1000.); - else - mStreamData.timer = 0.0f; - - PolyPushConstants constants; - constants.uFogEnabled = fogset; - constants.uTextureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode); - constants.uLightDist = mLightParms[0]; - constants.uLightFactor = mLightParms[1]; - constants.uFogDensity = mLightParms[2]; - constants.uLightLevel = mLightParms[3]; - constants.uAlphaThreshold = mAlphaThreshold; - constants.uClipSplit = { mClipSplit[0], mClipSplit[1] }; - constants.uLightIndex = mLightIndex; - constants.uDynLightColor = mStreamData.uDynLightColor; // [GEC] - - mDrawCommands->PushStreamData(mStreamData, constants); - ApplyMatrices(); - - if (mBias.mChanged) - { - mDrawCommands->SetDepthBias(mBias.mUnits, mBias.mFactor); - mBias.mChanged = false; - } - - drawcalls.Unclock(); -} - -void PolyRenderState::ApplyMaterial() -{ - if (mMaterial.mChanged && mMaterial.mMaterial) - { - mTempTM = mMaterial.mMaterial->Source()->isHardwareCanvas() ? TM_OPAQUE : TM_NORMAL; - - if (mMaterial.mMaterial->Source()->isHardwareCanvas()) static_cast(mMaterial.mMaterial->Source()->GetTexture())->NeedUpdate(); - - MaterialLayerInfo* layer; - auto base = static_cast(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation, &layer)); - if (base) - { - DCanvas *texcanvas = base->GetImage(layer->layerTexture, mMaterial.mTranslation, layer->scaleFlags); - mDrawCommands->SetTexture(0, texcanvas->GetPixels(), texcanvas->GetWidth(), texcanvas->GetHeight(), texcanvas->IsBgra()); - - int numLayers = mMaterial.mMaterial->NumLayers(); - for (int i = 1; i < numLayers; i++) - { - auto systex = static_cast(mMaterial.mMaterial->GetLayer(i, 0, &layer)); - - texcanvas = systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); - mDrawCommands->SetTexture(i, texcanvas->GetPixels(), texcanvas->GetWidth(), texcanvas->GetHeight(), texcanvas->IsBgra()); - } - } - - mMaterial.mChanged = false; - } -} - -template -static void BufferedSet(bool &modified, T &dst, const T &src) -{ - if (dst == src) - return; - dst = src; - modified = true; -} - -static void BufferedSet(bool &modified, VSMatrix &dst, const VSMatrix &src) -{ - if (memcmp(dst.get(), src.get(), sizeof(FLOATTYPE) * 16) == 0) - return; - dst = src; - modified = true; -} - -void PolyRenderState::ApplyMatrices() -{ - bool modified = mFirstMatrixApply; - if (mTextureMatrixEnabled) - { - BufferedSet(modified, mMatrices.TextureMatrix, mTextureMatrix); - } - else - { - BufferedSet(modified, mMatrices.TextureMatrix, mIdentityMatrix); - } - - if (mModelMatrixEnabled) - { - BufferedSet(modified, mMatrices.ModelMatrix, mModelMatrix); - if (modified) - mMatrices.NormalModelMatrix.computeNormalMatrix(mModelMatrix); - } - else - { - BufferedSet(modified, mMatrices.ModelMatrix, mIdentityMatrix); - BufferedSet(modified, mMatrices.NormalModelMatrix, mIdentityMatrix); - } - - if (modified) - { - mFirstMatrixApply = false; - mDrawCommands->PushMatrices(mMatrices.ModelMatrix, mMatrices.NormalModelMatrix, mMatrices.TextureMatrix); - } -} - -void PolyRenderState::SetRenderTarget(DCanvas *canvas, PolyDepthStencil *depthStencil, bool topdown) -{ - mRenderTarget.Canvas = canvas; - mRenderTarget.DepthStencil = depthStencil; - mRenderTarget.TopDown = topdown; -} - -void PolyRenderState::Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length) -{ - if (buffer->bindingpoint == VIEWPOINT_BINDINGPOINT) - { - mViewpointUniforms = reinterpret_cast(static_cast(buffer->Memory()) + offset); - mNeedApply = true; - } -} - -PolyVertexInputAssembly *PolyRenderState::GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) -{ - for (size_t i = 0; i < mVertexFormats.size(); i++) - { - auto f = mVertexFormats[i].get(); - if (f->Attrs.size() == (size_t)numAttributes && f->NumBindingPoints == numBindingPoints && f->Stride == stride) - { - bool matches = true; - for (int j = 0; j < numAttributes; j++) - { - if (memcmp(&f->Attrs[j], &attrs[j], sizeof(FVertexBufferAttribute)) != 0) - { - matches = false; - break; - } - } - - if (matches) - return f; - } - } - - auto fmt = std::make_unique(); - fmt->NumBindingPoints = numBindingPoints; - fmt->Stride = stride; - fmt->UseVertexData = 0; - for (int j = 0; j < numAttributes; j++) - { - if (attrs[j].location == VATTR_COLOR) - fmt->UseVertexData |= 1; - else if (attrs[j].location == VATTR_NORMAL) - fmt->UseVertexData |= 2; - fmt->Attrs.push_back(attrs[j]); - } - - for (int j = 0; j < numAttributes; j++) - { - fmt->mOffsets[attrs[j].location] = attrs[j].offset; - } - fmt->mStride = stride; - - mVertexFormats.push_back(std::move(fmt)); - return mVertexFormats.back().get(); -} diff --git a/src/common/rendering/polyrenderer/backend/poly_renderstate.h b/src/common/rendering/polyrenderer/backend/poly_renderstate.h deleted file mode 100644 index f539bc7c2..000000000 --- a/src/common/rendering/polyrenderer/backend/poly_renderstate.h +++ /dev/null @@ -1,99 +0,0 @@ - -#pragma once - -#include "polyrenderer/backend/poly_buffers.h" -#include "poly_triangle.h" - -#include "name.h" - -#include "hw_renderstate.h" -#include "hw_material.h" - -struct HWViewpointUniforms; - -class PolyRenderState final : public FRenderState -{ -public: - PolyRenderState(); - - // Draw commands - void ClearScreen() override; - void Draw(int dt, int index, int count, bool apply = true) override; - void DrawIndexed(int dt, int index, int count, bool apply = true) override; - - // Immediate render state change commands. These only change infrequently and should not clutter the render state. - bool SetDepthClamp(bool on) override; - void SetDepthMask(bool on) override; - void SetDepthFunc(int func) override; - void SetDepthRange(float min, float max) override; - void SetColorMask(bool r, bool g, bool b, bool a) override; - void SetStencil(int offs, int op, int flags = -1) override; - void SetCulling(int mode) override; - void EnableClipDistance(int num, bool state) override; - void Clear(int targets) override; - void EnableStencil(bool on) override; - void SetScissor(int x, int y, int w, int h) override; - void SetViewport(int x, int y, int w, int h) override; - void EnableDepthTest(bool on) override; - void EnableMultisampling(bool on) override; - void EnableLineSmooth(bool on) override; - void EnableDrawBuffers(int count, bool apply) override; - - void SetRenderTarget(DCanvas *canvas, PolyDepthStencil *depthStencil, bool topdown); - void Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length); - PolyVertexInputAssembly *GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs); - void EndRenderPass(); - - void SetColormapShader(bool enable); - -private: - void Apply(); - void ApplyMaterial(); - void ApplyMatrices(); - - struct Matrices - { - VSMatrix ModelMatrix; - VSMatrix NormalModelMatrix; - VSMatrix TextureMatrix; - } mMatrices; - VSMatrix mIdentityMatrix; - bool mFirstMatrixApply = true; - - HWViewpointUniforms *mViewpointUniforms = nullptr; - std::vector> mVertexFormats; - - bool mDepthClamp = true; - int mTempTM = TM_NORMAL; - - struct RenderTarget - { - DCanvas *Canvas = nullptr; - PolyDepthStencil *DepthStencil = nullptr; - bool TopDown = true; - } mRenderTarget; - - struct Rect - { - int x = 0; - int y = 0; - int width = 0; - int height = 0; - } mScissor, mViewport; - - bool mNeedApply = true; - - bool mDepthTest = false; - bool mDepthMask = false; - int mDepthFunc = DF_Always; - float mDepthRangeMin = 0.0f; - float mDepthRangeMax = 1.0f; - bool mStencilEnabled = false; - int mStencilValue = 0; - int mStencilOp = SOP_Keep; - int mCulling = Cull_None; - bool mColorMask[4] = { true, true, true, true }; - bool mColormapShader = false; - - PolyCommandBuffer* mDrawCommands = nullptr; -}; diff --git a/src/common/rendering/polyrenderer/drawers/poly_thread.cpp b/src/common/rendering/polyrenderer/drawers/poly_thread.cpp deleted file mode 100644 index b00c05efa..000000000 --- a/src/common/rendering/polyrenderer/drawers/poly_thread.cpp +++ /dev/null @@ -1,827 +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. -** -*/ - -#include - - -#include "filesystem.h" -#include "v_video.h" -#include "model.h" -#include "poly_thread.h" -#include "screen_triangle.h" - -#ifndef NO_SSE -#include -#endif - -PolyTriangleThreadData::PolyTriangleThreadData(int32_t core, int32_t num_cores, int32_t numa_node, int32_t num_numa_nodes, int numa_start_y, int numa_end_y) - : core(core), num_cores(num_cores), numa_node(numa_node), num_numa_nodes(num_numa_nodes), numa_start_y(numa_start_y), numa_end_y(numa_end_y) -{ -} - -void PolyTriangleThreadData::ClearDepth(float value) -{ - int width = depthstencil->Width(); - int height = depthstencil->Height(); - float *data = depthstencil->DepthValues(); - - int skip = skipped_by_thread(0); - int count = count_for_thread(0, height); - - data += skip * width; - for (int i = 0; i < count; i++) - { - for (int x = 0; x < width; x++) - data[x] = value; - data += num_cores * width; - } -} - -void PolyTriangleThreadData::ClearStencil(uint8_t value) -{ - int width = depthstencil->Width(); - int height = depthstencil->Height(); - uint8_t *data = depthstencil->StencilValues(); - - int skip = skipped_by_thread(0); - int count = count_for_thread(0, height); - - data += skip * width; - for (int i = 0; i < count; i++) - { - memset(data, value, width); - data += num_cores * width; - } -} - -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, PolyDepthStencil *new_depthstencil, bool new_topdown) -{ - viewport_x = x; - viewport_y = y; - viewport_width = width; - viewport_height = height; - dest = new_dest; - dest_width = new_dest_width; - dest_height = new_dest_height; - dest_pitch = new_dest_pitch; - dest_bgra = new_dest_bgra; - depthstencil = new_depthstencil; - topdown = new_topdown; - UpdateClip(); -} - -void PolyTriangleThreadData::SetScissor(int x, int y, int w, int h) -{ - scissor.left = x; - scissor.right = x + w; - scissor.top = y; - scissor.bottom = y + h; - UpdateClip(); -} - -void PolyTriangleThreadData::UpdateClip() -{ - clip.left = max(max(viewport_x, scissor.left), 0); - clip.top = max(max(viewport_y, scissor.top), 0); - clip.right = min(min(viewport_x + viewport_width, scissor.right), dest_width); - clip.bottom = min(min(viewport_y + viewport_height, scissor.bottom), dest_height); -} - -void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPushConstants &constants) -{ - mainVertexShader.Data = data; - mainVertexShader.uClipSplit = constants.uClipSplit; - - PushConstants = &constants; - - AlphaThreshold = clamp((int)(PushConstants->uAlphaThreshold * 255.0f + 0.5f), 0, 255) << 24; - - numPolyLights = 0; - if (constants.uLightIndex >= 0) - { - const FVector4 &lightRange = lights[constants.uLightIndex]; - static_assert(sizeof(FVector4) == 16, "sizeof(FVector4) is not 16 bytes"); - if (lightRange.Y > lightRange.X) - { - int start = constants.uLightIndex + 1; - int modulatedStart = static_cast(lightRange.X) + start; - int modulatedEnd = static_cast(lightRange.Y) + start; - for (int i = modulatedStart; i < modulatedEnd; i += 4) - { - if (numPolyLights == maxPolyLights) - break; - - auto &lightpos = lights[i]; - auto &lightcolor = lights[i + 1]; - //auto &lightspot1 = lights[i + 2]; - //auto &lightspot2 = lights[i + 3]; - uint32_t r = (int)clamp(lightcolor.X * 255.0f, 0.0f, 255.0f); - uint32_t g = (int)clamp(lightcolor.Y * 255.0f, 0.0f, 255.0f); - uint32_t b = (int)clamp(lightcolor.Z * 255.0f, 0.0f, 255.0f); - - auto& polylight = polyLights[numPolyLights++]; - polylight.x = lightpos.X; - polylight.y = lightpos.Y; - polylight.z = lightpos.Z; - polylight.radius = 256.0f / lightpos.W; - polylight.color = (r << 16) | (g << 8) | b; - if (lightcolor.W < 0.0f) - polylight.radius = -polylight.radius; - } - } - } -} - -void PolyTriangleThreadData::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix) -{ - mainVertexShader.ModelMatrix = modelMatrix; - mainVertexShader.NormalModelMatrix = normalModelMatrix; - mainVertexShader.TextureMatrix = textureMatrix; -} - -void PolyTriangleThreadData::SetViewpointUniforms(const HWViewpointUniforms *uniforms) -{ - mainVertexShader.Viewpoint = uniforms; -} - -void PolyTriangleThreadData::SetDepthClamp(bool on) -{ - DepthClamp = on; -} - -void PolyTriangleThreadData::SetDepthMask(bool on) -{ - WriteDepth = on; -} - -void PolyTriangleThreadData::SetDepthFunc(int func) -{ - if (func == DF_LEqual || func == DF_Less) - { - DepthTest = true; - } - else // if (func == DF_Always) - { - DepthTest = false; - } -} - -void PolyTriangleThreadData::SetDepthRange(float min, float max) -{ - DepthRangeStart = min; - DepthRangeScale = max - min; -} - -void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor) -{ - depthbias = (float)(depthBiasConstantFactor / 2500.0); -} - -void PolyTriangleThreadData::SetColorMask(bool r, bool g, bool b, bool a) -{ - WriteColor = r; -} - -void PolyTriangleThreadData::SetStencil(int stencilRef, int op) -{ - StencilTestValue = stencilRef; - if (op == SOP_Increment) - { - StencilWriteValue = min(stencilRef + 1, (int)255); - } - else if (op == SOP_Decrement) - { - StencilWriteValue = max(stencilRef - 1, (int)0); - } - else // SOP_Keep - { - StencilWriteValue = stencilRef; - } - - WriteStencil = StencilTest && (StencilTestValue != StencilWriteValue); -} - -void PolyTriangleThreadData::SetCulling(int mode) -{ - SetTwoSided(mode == Cull_None); - SetCullCCW(mode == Cull_CCW); -} - -void PolyTriangleThreadData::EnableStencil(bool on) -{ - StencilTest = on; - WriteStencil = on && (StencilTestValue != StencilWriteValue); -} - -void PolyTriangleThreadData::SetRenderStyle(FRenderStyle style) -{ - RenderStyle = style; -} - -void PolyTriangleThreadData::SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader) -{ - SpecialEffect = specialEffect; - EffectState = effectState; - AlphaTest = alphaTest; - ColormapShader = colormapShader; -} - -void PolyTriangleThreadData::SetTexture(int unit, const void *pixels, int width, int height, bool bgra) -{ - textures[unit].pixels = pixels; - textures[unit].width = width; - textures[unit].height = height; - textures[unit].bgra = bgra; -} - -void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode drawmode) -{ - if (vcount < 3) - return; - - elements += index; - - ShadedTriVertex vertbuffer[3]; - ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] }; - if (drawmode == PolyDrawMode::Triangles) - { - for (int i = 0; i < vcount / 3; i++) - { - for (int j = 0; j < 3; j++) - *vert[j] = ShadeVertex(*(elements++)); - DrawShadedTriangle(vert, ccw); - } - } - else if (drawmode == PolyDrawMode::TriangleFan) - { - *vert[0] = ShadeVertex(*(elements++)); - *vert[1] = ShadeVertex(*(elements++)); - for (int i = 2; i < vcount; i++) - { - *vert[2] = ShadeVertex(*(elements++)); - DrawShadedTriangle(vert, ccw); - std::swap(vert[1], vert[2]); - } - } - else if (drawmode == PolyDrawMode::TriangleStrip) - { - bool toggleccw = ccw; - *vert[0] = ShadeVertex(*(elements++)); - *vert[1] = ShadeVertex(*(elements++)); - for (int i = 2; i < vcount; i++) - { - *vert[2] = ShadeVertex(*(elements++)); - DrawShadedTriangle(vert, toggleccw); - ShadedTriVertex *vtmp = vert[0]; - vert[0] = vert[1]; - vert[1] = vert[2]; - vert[2] = vtmp; - toggleccw = !toggleccw; - } - } - else if (drawmode == PolyDrawMode::Lines) - { - for (int i = 0; i < vcount / 2; i++) - { - *vert[0] = ShadeVertex(*(elements++)); - *vert[1] = ShadeVertex(*(elements++)); - DrawShadedLine(vert); - } - } - else if (drawmode == PolyDrawMode::Points) - { - for (int i = 0; i < vcount; i++) - { - *vert[0] = ShadeVertex(*(elements++)); - DrawShadedPoint(vert); - } - } -} - -void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode) -{ - if (vcount < 3) - return; - - int vinput = index; - - ShadedTriVertex vertbuffer[3]; - ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] }; - if (drawmode == PolyDrawMode::Triangles) - { - for (int i = 0; i < vcount / 3; i++) - { - for (int j = 0; j < 3; j++) - *vert[j] = ShadeVertex(vinput++); - DrawShadedTriangle(vert, ccw); - } - } - else if (drawmode == PolyDrawMode::TriangleFan) - { - *vert[0] = ShadeVertex(vinput++); - *vert[1] = ShadeVertex(vinput++); - for (int i = 2; i < vcount; i++) - { - *vert[2] = ShadeVertex(vinput++); - DrawShadedTriangle(vert, ccw); - std::swap(vert[1], vert[2]); - } - } - else if (drawmode == PolyDrawMode::TriangleStrip) - { - bool toggleccw = ccw; - *vert[0] = ShadeVertex(vinput++); - *vert[1] = ShadeVertex(vinput++); - for (int i = 2; i < vcount; i++) - { - *vert[2] = ShadeVertex(vinput++); - DrawShadedTriangle(vert, toggleccw); - ShadedTriVertex *vtmp = vert[0]; - vert[0] = vert[1]; - vert[1] = vert[2]; - vert[2] = vtmp; - toggleccw = !toggleccw; - } - } - else if (drawmode == PolyDrawMode::Lines) - { - for (int i = 0; i < vcount / 2; i++) - { - *vert[0] = ShadeVertex(vinput++); - *vert[1] = ShadeVertex(vinput++); - DrawShadedLine(vert); - } - } - else if (drawmode == PolyDrawMode::Points) - { - for (int i = 0; i < vcount; i++) - { - *vert[0] = ShadeVertex(vinput++); - DrawShadedPoint(vert); - } - } -} - -ShadedTriVertex PolyTriangleThreadData::ShadeVertex(int index) -{ - inputAssembly->Load(this, vertices, frame0, frame1, index); - mainVertexShader.SIMPLE = (SpecialEffect == EFF_BURN) || (SpecialEffect == EFF_STENCIL); - mainVertexShader.SPHEREMAP = (SpecialEffect == EFF_SPHEREMAP); - mainVertexShader.main(); - return mainVertexShader; -} - -bool PolyTriangleThreadData::IsDegenerate(const ShadedTriVertex *const* vert) -{ - // A degenerate triangle has a zero cross product for two of its sides. - float ax = vert[1]->gl_Position.X - vert[0]->gl_Position.X; - float ay = vert[1]->gl_Position.Y - vert[0]->gl_Position.Y; - float az = vert[1]->gl_Position.W - vert[0]->gl_Position.W; - float bx = vert[2]->gl_Position.X - vert[0]->gl_Position.X; - float by = vert[2]->gl_Position.Y - vert[0]->gl_Position.Y; - float bz = vert[2]->gl_Position.W - vert[0]->gl_Position.W; - float crossx = ay * bz - az * by; - float crossy = az * bx - ax * bz; - float crossz = ax * by - ay * bx; - float crosslengthsqr = crossx * crossx + crossy * crossy + crossz * crossz; - return crosslengthsqr <= 1.e-8f; -} - -bool PolyTriangleThreadData::IsFrontfacing(TriDrawTriangleArgs *args) -{ - float a = - args->v1->x * args->v2->y - args->v2->x * args->v1->y + - args->v2->x * args->v3->y - args->v3->x * args->v2->y + - args->v3->x * args->v1->y - args->v1->x * args->v3->y; - return a <= 0.0f; -} - -void PolyTriangleThreadData::DrawShadedPoint(const ShadedTriVertex *const* vertex) -{ -} - -void PolyTriangleThreadData::DrawShadedLine(const ShadedTriVertex *const* vert) -{ - static const int numclipdistances = 9; - float clipdistance[numclipdistances * 2]; - float *clipd = clipdistance; - for (int i = 0; i < 2; i++) - { - const auto &v = *vert[i]; - clipd[0] = v.gl_Position.X + v.gl_Position.W; - clipd[1] = v.gl_Position.W - v.gl_Position.X; - clipd[2] = v.gl_Position.Y + v.gl_Position.W; - clipd[3] = v.gl_Position.W - v.gl_Position.Y; - if (DepthClamp) - { - clipd[4] = 1.0f; - clipd[5] = 1.0f; - } - else - { - clipd[4] = v.gl_Position.Z + v.gl_Position.W; - clipd[5] = v.gl_Position.W - v.gl_Position.Z; - } - clipd[6] = v.gl_ClipDistance[0]; - clipd[7] = v.gl_ClipDistance[1]; - clipd[8] = v.gl_ClipDistance[2]; - clipd += numclipdistances; - } - - float t1 = 0.0f; - float t2 = 1.0f; - for (int p = 0; p < numclipdistances; p++) - { - float clipdistance1 = clipdistance[0 * numclipdistances + p]; - float clipdistance2 = clipdistance[1 * numclipdistances + p]; - if (clipdistance1 < 0.0f) t1 = max(-clipdistance1 / (clipdistance2 - clipdistance1), t1); - if (clipdistance2 < 0.0f) t2 = min(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2); - if (t1 >= t2) - return; - } - - float weights[] = { 1.0f - t1, t1, 1.0f - t2, t2 }; - - ScreenTriVertex clippedvert[2]; - for (int i = 0; i < 2; i++) - { - auto &v = clippedvert[i]; - memset(&v, 0, sizeof(ScreenTriVertex)); - for (int w = 0; w < 2; w++) - { - float weight = weights[i * 2 + w]; - v.x += vert[w]->gl_Position.X * weight; - v.y += vert[w]->gl_Position.Y * weight; - v.z += vert[w]->gl_Position.Z * weight; - v.w += vert[w]->gl_Position.W * weight; - } - - // Calculate normalized device coordinates: - v.w = 1.0f / v.w; - v.x *= v.w; - v.y *= v.w; - v.z *= v.w; - - // Apply viewport scale to get screen coordinates: - v.x = viewport_x + viewport_width * (1.0f + v.x) * 0.5f; - if (topdown) - v.y = viewport_y + viewport_height * (1.0f - v.y) * 0.5f; - else - v.y = viewport_y + viewport_height * (1.0f + v.y) * 0.5f; - } - - uint32_t vColorA = (int)(vert[0]->vColor.W * 255.0f + 0.5f); - uint32_t vColorR = (int)(vert[0]->vColor.X * 255.0f + 0.5f); - uint32_t vColorG = (int)(vert[0]->vColor.Y * 255.0f + 0.5f); - uint32_t vColorB = (int)(vert[0]->vColor.Z * 255.0f + 0.5f); - uint32_t color = MAKEARGB(vColorA, vColorR, vColorG, vColorB); - - // Slow and naive implementation. Hopefully fast enough.. - - float x1 = clippedvert[0].x; - float y1 = clippedvert[0].y; - float x2 = clippedvert[1].x; - float y2 = clippedvert[1].y; - float dx = x2 - x1; - float dy = y2 - y1; - float step = (abs(dx) >= abs(dy)) ? abs(dx) : abs(dy); - dx /= step; - dy /= step; - float x = x1; - float y = y1; - int istep = (int)step; - int pixelsize = dest_bgra ? 4 : 1; - for (int i = 0; i <= istep; i++) - { - int scrx = (int)x; - int scry = (int)y; - if (scrx >= clip.left && scrx < clip.right && scry >= clip.top && scry < clip.bottom && !line_skipped_by_thread(scry)) - { - uint8_t *destpixel = dest + (scrx + scry * dest_width) * pixelsize; - if (pixelsize == 4) - { - *reinterpret_cast(destpixel) = color; - } - else - { - *destpixel = color; - } - } - x += dx; - y += dy; - } -} - -void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* vert, bool ccw) -{ - // Reject triangle if degenerate - if (IsDegenerate(vert)) - return; - - // Cull, clip and generate additional vertices as needed - ScreenTriVertex clippedvert[max_additional_vertices]; - int numclipvert = ClipEdge(vert); - - // Convert barycentric weights to actual vertices - for (int i = 0; i < numclipvert; i++) - { - auto &v = clippedvert[i]; - memset(&v, 0, sizeof(ScreenTriVertex)); - for (int w = 0; w < 3; w++) - { - float weight = weights[i * 3 + w]; - v.x += vert[w]->gl_Position.X * weight; - v.y += vert[w]->gl_Position.Y * weight; - v.z += vert[w]->gl_Position.Z * weight; - v.w += vert[w]->gl_Position.W * weight; - v.u += vert[w]->vTexCoord.X * weight; - v.v += vert[w]->vTexCoord.Y * weight; - v.worldX += vert[w]->pixelpos.X * weight; - v.worldY += vert[w]->pixelpos.Y * weight; - v.worldZ += vert[w]->pixelpos.Z * weight; - v.a += vert[w]->vColor.W * weight; - v.r += vert[w]->vColor.X * weight; - v.g += vert[w]->vColor.Y * weight; - v.b += vert[w]->vColor.Z * weight; - v.gradientdistZ += vert[w]->gradientdist.Z * weight; - } - } - -#ifdef NO_SSE - // Map to 2D viewport: - for (int j = 0; j < numclipvert; j++) - { - auto &v = clippedvert[j]; - - // Calculate normalized device coordinates: - v.w = 1.0f / v.w; - v.x *= v.w; - v.y *= v.w; - v.z *= v.w; - - // Apply viewport scale to get screen coordinates: - v.x = viewport_x + viewport_width * (1.0f + v.x) * 0.5f; - if (topdown) - v.y = viewport_y + viewport_height * (1.0f - v.y) * 0.5f; - else - v.y = viewport_y + viewport_height * (1.0f + v.y) * 0.5f; - } -#else - // Map to 2D viewport: - __m128 mviewport_x = _mm_set1_ps((float)viewport_x); - __m128 mviewport_y = _mm_set1_ps((float)viewport_y); - __m128 mviewport_halfwidth = _mm_set1_ps(viewport_width * 0.5f); - __m128 mviewport_halfheight = _mm_set1_ps(viewport_height * 0.5f); - __m128 mone = _mm_set1_ps(1.0f); - int sse_length = (numclipvert + 3) / 4 * 4; - for (int j = 0; j < sse_length; j += 4) - { - __m128 vx = _mm_loadu_ps(&clippedvert[j].x); - __m128 vy = _mm_loadu_ps(&clippedvert[j + 1].x); - __m128 vz = _mm_loadu_ps(&clippedvert[j + 2].x); - __m128 vw = _mm_loadu_ps(&clippedvert[j + 3].x); - _MM_TRANSPOSE4_PS(vx, vy, vz, vw); - - // Calculate normalized device coordinates: - vw = _mm_div_ps(mone, vw); - vx = _mm_mul_ps(vx, vw); - vy = _mm_mul_ps(vy, vw); - vz = _mm_mul_ps(vz, vw); - - // Apply viewport scale to get screen coordinates: - vx = _mm_add_ps(mviewport_x, _mm_mul_ps(mviewport_halfwidth, _mm_add_ps(mone, vx))); - if (topdown) - vy = _mm_add_ps(mviewport_y, _mm_mul_ps(mviewport_halfheight, _mm_sub_ps(mone, vy))); - else - vy = _mm_add_ps(mviewport_y, _mm_mul_ps(mviewport_halfheight, _mm_add_ps(mone, vy))); - - _MM_TRANSPOSE4_PS(vx, vy, vz, vw); - _mm_storeu_ps(&clippedvert[j].x, vx); - _mm_storeu_ps(&clippedvert[j + 1].x, vy); - _mm_storeu_ps(&clippedvert[j + 2].x, vz); - _mm_storeu_ps(&clippedvert[j + 3].x, vw); - } -#endif - - if (!topdown) ccw = !ccw; - - TriDrawTriangleArgs args; - - if (twosided && numclipvert > 2) - { - args.v1 = &clippedvert[0]; - args.v2 = &clippedvert[1]; - args.v3 = &clippedvert[2]; - ccw = !IsFrontfacing(&args); - } - - // Draw screen triangles - if (ccw) - { - for (int i = numclipvert - 1; i > 1; i--) - { - args.v1 = &clippedvert[numclipvert - 1]; - args.v2 = &clippedvert[i - 1]; - args.v3 = &clippedvert[i - 2]; - if (IsFrontfacing(&args) == ccw && args.CalculateGradients()) - { - ScreenTriangle::Draw(&args, this); - } - } - } - else - { - for (int i = 2; i < numclipvert; i++) - { - args.v1 = &clippedvert[0]; - args.v2 = &clippedvert[i - 1]; - args.v3 = &clippedvert[i]; - if (IsFrontfacing(&args) != ccw && args.CalculateGradients()) - { - ScreenTriangle::Draw(&args, this); - } - } - } -} - -int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *const* verts) -{ - // use barycentric weights for clipped vertices - weights = weightsbuffer; - for (int i = 0; i < 3; i++) - { - weights[i * 3 + 0] = 0.0f; - weights[i * 3 + 1] = 0.0f; - weights[i * 3 + 2] = 0.0f; - weights[i * 3 + i] = 1.0f; - } - - // Clip and cull so that the following is true for all vertices: - // -v.w <= v.x <= v.w - // -v.w <= v.y <= v.w - // -v.w <= v.z <= v.w - - // halfspace clip distances - static const int numclipdistances = 9; -#ifdef NO_SSE - float clipdistance[numclipdistances * 3]; - bool needsclipping = false; - float *clipd = clipdistance; - for (int i = 0; i < 3; i++) - { - const auto &v = *verts[i]; - clipd[0] = v.gl_Position.X + v.gl_Position.W; - clipd[1] = v.gl_Position.W - v.gl_Position.X; - clipd[2] = v.gl_Position.Y + v.gl_Position.W; - clipd[3] = v.gl_Position.W - v.gl_Position.Y; - if (DepthClamp) - { - clipd[4] = 1.0f; - clipd[5] = 1.0f; - } - else - { - clipd[4] = v.gl_Position.Z + v.gl_Position.W; - clipd[5] = v.gl_Position.W - v.gl_Position.Z; - } - clipd[6] = v.gl_ClipDistance[0]; - clipd[7] = v.gl_ClipDistance[1]; - clipd[8] = v.gl_ClipDistance[2]; - for (int j = 0; j < 9; j++) - needsclipping = needsclipping || clipd[i]; - clipd += numclipdistances; - } - - // If all halfspace clip distances are positive then the entire triangle is visible. Skip the expensive clipping step. - if (!needsclipping) - { - return 3; - } -#else - __m128 mx = _mm_loadu_ps(&verts[0]->gl_Position.X); - __m128 my = _mm_loadu_ps(&verts[1]->gl_Position.X); - __m128 mz = _mm_loadu_ps(&verts[2]->gl_Position.X); - __m128 mw = _mm_setzero_ps(); - _MM_TRANSPOSE4_PS(mx, my, mz, mw); - __m128 clipd0 = _mm_add_ps(mx, mw); - __m128 clipd1 = _mm_sub_ps(mw, mx); - __m128 clipd2 = _mm_add_ps(my, mw); - __m128 clipd3 = _mm_sub_ps(mw, my); - __m128 clipd4 = DepthClamp ? _mm_set1_ps(1.0f) : _mm_add_ps(mz, mw); - __m128 clipd5 = DepthClamp ? _mm_set1_ps(1.0f) : _mm_sub_ps(mw, mz); - __m128 clipd6 = _mm_setr_ps(verts[0]->gl_ClipDistance[0], verts[1]->gl_ClipDistance[0], verts[2]->gl_ClipDistance[0], 0.0f); - __m128 clipd7 = _mm_setr_ps(verts[0]->gl_ClipDistance[1], verts[1]->gl_ClipDistance[1], verts[2]->gl_ClipDistance[1], 0.0f); - __m128 clipd8 = _mm_setr_ps(verts[0]->gl_ClipDistance[2], verts[1]->gl_ClipDistance[2], verts[2]->gl_ClipDistance[2], 0.0f); - __m128 mneedsclipping = _mm_cmplt_ps(clipd0, _mm_setzero_ps()); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd1, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd2, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd3, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd4, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd5, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd6, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd7, _mm_setzero_ps())); - mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd8, _mm_setzero_ps())); - if (_mm_movemask_ps(mneedsclipping) == 0) - { - return 3; - } - float clipdistance[numclipdistances * 4]; - _mm_storeu_ps(clipdistance, clipd0); - _mm_storeu_ps(clipdistance + 4, clipd1); - _mm_storeu_ps(clipdistance + 8, clipd2); - _mm_storeu_ps(clipdistance + 12, clipd3); - _mm_storeu_ps(clipdistance + 16, clipd4); - _mm_storeu_ps(clipdistance + 20, clipd5); - _mm_storeu_ps(clipdistance + 24, clipd6); - _mm_storeu_ps(clipdistance + 28, clipd7); - _mm_storeu_ps(clipdistance + 32, clipd8); -#endif - - // Clip against each halfspace - float *input = weights; - float *output = weights + max_additional_vertices * 3; - int inputverts = 3; - for (int p = 0; p < numclipdistances; p++) - { - // Clip each edge - int outputverts = 0; - for (int i = 0; i < inputverts; i++) - { - int j = (i + 1) % inputverts; -#ifdef NO_SSE - float clipdistance1 = - clipdistance[0 * numclipdistances + p] * input[i * 3 + 0] + - clipdistance[1 * numclipdistances + p] * input[i * 3 + 1] + - clipdistance[2 * numclipdistances + p] * input[i * 3 + 2]; - - float clipdistance2 = - clipdistance[0 * numclipdistances + p] * input[j * 3 + 0] + - clipdistance[1 * numclipdistances + p] * input[j * 3 + 1] + - clipdistance[2 * numclipdistances + p] * input[j * 3 + 2]; -#else - float clipdistance1 = - clipdistance[0 + p * 4] * input[i * 3 + 0] + - clipdistance[1 + p * 4] * input[i * 3 + 1] + - clipdistance[2 + p * 4] * input[i * 3 + 2]; - - float clipdistance2 = - clipdistance[0 + p * 4] * input[j * 3 + 0] + - clipdistance[1 + p * 4] * input[j * 3 + 1] + - clipdistance[2 + p * 4] * input[j * 3 + 2]; -#endif - - // Clip halfspace - if ((clipdistance1 >= 0.0f || clipdistance2 >= 0.0f) && outputverts + 1 < max_additional_vertices) - { - float t1 = (clipdistance1 < 0.0f) ? max(-clipdistance1 / (clipdistance2 - clipdistance1), 0.0f) : 0.0f; - float t2 = (clipdistance2 < 0.0f) ? min(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), 1.0f) : 1.0f; - - // add t1 vertex - for (int k = 0; k < 3; k++) - output[outputverts * 3 + k] = input[i * 3 + k] * (1.0f - t1) + input[j * 3 + k] * t1; - outputverts++; - - if (t2 != 1.0f && t2 > t1) - { - // add t2 vertex - for (int k = 0; k < 3; k++) - output[outputverts * 3 + k] = input[i * 3 + k] * (1.0f - t2) + input[j * 3 + k] * t2; - outputverts++; - } - } - } - std::swap(input, output); - inputverts = outputverts; - if (inputverts == 0) - break; - } - - weights = input; - return inputverts; -} - -PolyTriangleThreadData *PolyTriangleThreadData::Get(DrawerThread *thread) -{ - if (!thread->poly) - thread->poly = std::make_unique(thread->core, thread->num_cores, thread->numa_node, thread->num_numa_nodes, thread->numa_start_y, thread->numa_end_y); - return thread->poly.get(); -} diff --git a/src/common/rendering/polyrenderer/drawers/poly_thread.h b/src/common/rendering/polyrenderer/drawers/poly_thread.h deleted file mode 100644 index abaa43e32..000000000 --- a/src/common/rendering/polyrenderer/drawers/poly_thread.h +++ /dev/null @@ -1,204 +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 "poly_triangle.h" - -struct PolyLight -{ - uint32_t color; - float x, y, z; - float radius; -}; - -class PolyTriangleThreadData -{ -public: - PolyTriangleThreadData(int32_t core, int32_t num_cores, int32_t numa_node, int32_t num_numa_nodes, int numa_start_y, int numa_end_y); - - void ClearDepth(float value); - void ClearStencil(uint8_t value); - 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, PolyDepthStencil *depthstencil, bool topdown); - - void SetCullCCW(bool value) { ccw = value; } - void SetTwoSided(bool value) { twosided = value; } - - void SetInputAssembly(PolyInputAssembly *input) { inputAssembly = input; } - void SetVertexBuffer(const void *data, int offset0, int offset1) { vertices = data; frame0 = offset0; frame1 = offset1;} //[GEC] Save frame params - void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; } - void SetLightBuffer(const void *data) { lights = (const FVector4 *)data; } - void SetViewpointUniforms(const HWViewpointUniforms *uniforms); - void SetDepthClamp(bool on); - void SetDepthMask(bool on); - void SetDepthFunc(int func); - void SetDepthRange(float min, float max); - void SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor); - void SetColorMask(bool r, bool g, bool b, bool a); - void SetStencil(int stencilRef, int op); - void SetCulling(int mode); - void EnableStencil(bool on); - void SetScissor(int x, int y, int w, int h); - void SetRenderStyle(FRenderStyle style); - void SetTexture(int unit, const void *pixels, int width, int height, bool bgra); - void SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader); - - void UpdateClip(); - - void PushStreamData(const StreamData &data, const PolyPushConstants &constants); - void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix); - - void DrawIndexed(int index, int count, PolyDrawMode mode); - void Draw(int index, int vcount, PolyDrawMode mode); - - int32_t core; - int32_t num_cores; - int32_t numa_node; - int32_t num_numa_nodes; - - int numa_start_y; - int numa_end_y; - - bool line_skipped_by_thread(int line) - { - return line < numa_start_y || line >= numa_end_y || line % num_cores != core; - } - - int skipped_by_thread(int first_line) - { - int clip_first_line = max(first_line, numa_start_y); - int core_skip = (num_cores - (clip_first_line - core) % num_cores) % num_cores; - return clip_first_line + core_skip - first_line; - } - - int count_for_thread(int first_line, int count) - { - count = min(count, numa_end_y - first_line); - int c = (count - skipped_by_thread(first_line) + num_cores - 1) / num_cores; - return max(c, 0); - } - - struct Scanline - { - float W[MAXWIDTH]; - uint16_t U[MAXWIDTH]; - uint16_t V[MAXWIDTH]; - float WorldX[MAXWIDTH]; - float WorldY[MAXWIDTH]; - float WorldZ[MAXWIDTH]; - uint8_t vColorA[MAXWIDTH]; - uint8_t vColorR[MAXWIDTH]; - uint8_t vColorG[MAXWIDTH]; - uint8_t vColorB[MAXWIDTH]; - float GradientdistZ[MAXWIDTH]; - uint32_t FragColor[MAXWIDTH]; - uint32_t lightarray[MAXWIDTH]; - uint8_t discard[MAXWIDTH]; - } scanline; - - static PolyTriangleThreadData *Get(DrawerThread *thread); - - int dest_pitch = 0; - int dest_width = 0; - int dest_height = 0; - bool dest_bgra = false; - uint8_t *dest = nullptr; - PolyDepthStencil *depthstencil = nullptr; - bool topdown = true; - - float depthbias = 0.0f; - - int viewport_y = 0; - - struct ClipRect - { - int left = 0; - int top = 0; - int right = 0; - int bottom = 0; - } clip, scissor; - - FRenderStyle RenderStyle; - int SpecialEffect = EFF_NONE; - int EffectState = 0; - bool AlphaTest = false; - bool ColormapShader = false; - uint32_t AlphaThreshold = 0x7f000000; - const PolyPushConstants* PushConstants = nullptr; - - // [GEC] Add frame params, necessary to project frames and model interpolation correctly - int frame0 = 0; - int frame1 = 0; - - const void *vertices = nullptr; - const unsigned int *elements = nullptr; - const FVector4 *lights = nullptr; - - enum { maxPolyLights = 16 }; - PolyLight polyLights[maxPolyLights]; - int numPolyLights = 0; - - PolyMainVertexShader mainVertexShader; - - struct TextureUnit - { - const void* pixels = nullptr; - int width = 0; - int height = 0; - bool bgra = true; - } textures[16]; - - bool DepthTest = false; - bool StencilTest = true; - bool WriteStencil = true; - bool WriteColor = true; - bool WriteDepth = true; - uint8_t StencilTestValue = 0; - uint8_t StencilWriteValue = 0; - float DepthRangeStart = 0.0f; - float DepthRangeScale = 1.0f; - bool DepthClamp = true; - - void (*FragmentShader)(int x0, int x1, PolyTriangleThreadData* thread) = nullptr; - void (*WriteColorFunc)(int y, int x0, int x1, PolyTriangleThreadData* thread) = nullptr; - -private: - ShadedTriVertex ShadeVertex(int index); - void DrawShadedPoint(const ShadedTriVertex *const* vertex); - void DrawShadedLine(const ShadedTriVertex *const* vertices); - void DrawShadedTriangle(const ShadedTriVertex *const* vertices, bool ccw); - static bool IsDegenerate(const ShadedTriVertex *const* vertices); - static bool IsFrontfacing(TriDrawTriangleArgs *args); - - int ClipEdge(const ShadedTriVertex *const* verts); - - int viewport_x = 0; - int viewport_width = 0; - int viewport_height = 0; - bool ccw = true; - bool twosided = true; - PolyInputAssembly *inputAssembly = nullptr; - - enum { max_additional_vertices = 16 }; - float weightsbuffer[max_additional_vertices * 3 * 2]; - float *weights = nullptr; -}; diff --git a/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp deleted file mode 100644 index 8c142a06d..000000000 --- a/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp +++ /dev/null @@ -1,469 +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. -** -*/ - -#include - - -#include "filesystem.h" -#include "v_video.h" -#include "model.h" -#include "poly_triangle.h" -#include "poly_thread.h" -#include "screen_triangle.h" - -///////////////////////////////////////////////////////////////////////////// - -class PolyDrawerCommand : public DrawerCommand -{ -public: -}; - -class PolySetDepthClampCommand : public PolyDrawerCommand -{ -public: - PolySetDepthClampCommand(bool on) : on(on) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetDepthClamp(on); } - -private: - bool on; -}; - -class PolySetDepthMaskCommand : public PolyDrawerCommand -{ -public: - PolySetDepthMaskCommand(bool on) : on(on) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetDepthMask(on); } - -private: - bool on; -}; - -class PolySetDepthFuncCommand : public PolyDrawerCommand -{ -public: - PolySetDepthFuncCommand(int func) : func(func) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetDepthFunc(func); } - -private: - int func; -}; - -class PolySetDepthRangeCommand : public PolyDrawerCommand -{ -public: - PolySetDepthRangeCommand(float min, float max) : min(min), max(max) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetDepthRange(min, max); } - -private: - float min; - float max; -}; - -class PolySetDepthBiasCommand : public PolyDrawerCommand -{ -public: - PolySetDepthBiasCommand(float depthBiasConstantFactor, float depthBiasSlopeFactor) : depthBiasConstantFactor(depthBiasConstantFactor), depthBiasSlopeFactor(depthBiasSlopeFactor) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetDepthBias(depthBiasConstantFactor, depthBiasSlopeFactor); } - -private: - float depthBiasConstantFactor; - float depthBiasSlopeFactor; -}; - -class PolySetColorMaskCommand : public PolyDrawerCommand -{ -public: - PolySetColorMaskCommand(bool r, bool g, bool b, bool a) : r(r), g(g), b(b), a(a) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetColorMask(r, g, b, a); } - -private: - bool r; - bool g; - bool b; - bool a; -}; - -class PolySetStencilCommand : public PolyDrawerCommand -{ -public: - PolySetStencilCommand(int stencilRef, int op) : stencilRef(stencilRef), op(op) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetStencil(stencilRef, op); } - -private: - int stencilRef; - int op; -}; - -class PolySetCullingCommand : public PolyDrawerCommand -{ -public: - PolySetCullingCommand(int mode) : mode(mode) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetCulling(mode); } - -private: - int mode; -}; - -class PolyEnableStencilCommand : public PolyDrawerCommand -{ -public: - PolyEnableStencilCommand(bool on) : on(on) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->EnableStencil(on); } - -private: - bool on; -}; - -class PolySetScissorCommand : public PolyDrawerCommand -{ -public: - PolySetScissorCommand(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetScissor(x, y, w, h); } - -private: - int x; - int y; - int w; - int h; -}; - -class PolySetRenderStyleCommand : public PolyDrawerCommand -{ -public: - PolySetRenderStyleCommand(FRenderStyle style) : style(style) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetRenderStyle(style); } - -private: - FRenderStyle style; -}; - -class PolySetTextureCommand : public PolyDrawerCommand -{ -public: - PolySetTextureCommand(int unit, void* pixels, int width, int height, bool bgra) : unit(unit), pixels(pixels), width(width), height(height), bgra(bgra) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(unit, pixels, width, height, bgra); } - -private: - int unit; - void* pixels; - int width; - int height; - bool bgra; -}; - -class PolySetShaderCommand : public PolyDrawerCommand -{ -public: - PolySetShaderCommand(int specialEffect, int effectState, bool alphaTest, bool colormapShader) : specialEffect(specialEffect), effectState(effectState), alphaTest(alphaTest), colormapShader(colormapShader) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetShader(specialEffect, effectState, alphaTest, colormapShader); } - -private: - int specialEffect; - int effectState; - bool alphaTest; - bool colormapShader; -}; - -class PolySetVertexBufferCommand : public PolyDrawerCommand -{ -public: - PolySetVertexBufferCommand(const void* vertices, int offset0, int offset1) : vertices(vertices), offset0(offset0), offset1(offset1){ } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetVertexBuffer(vertices, offset0, offset1); } - -private: - const void* vertices; - // [GEC] Add offset params, necessary to project frames and model interpolation correctly - int offset0; - int offset1; -}; - -class PolySetIndexBufferCommand : public PolyDrawerCommand -{ -public: - PolySetIndexBufferCommand(const void* indices) : indices(indices) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetIndexBuffer(indices); } - -private: - const void* indices; -}; - -class PolySetLightBufferCommand : public PolyDrawerCommand -{ -public: - PolySetLightBufferCommand(const void* lights) : lights(lights) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetLightBuffer(lights); } - -private: - const void* lights; -}; - -class PolySetInputAssemblyCommand : public PolyDrawerCommand -{ -public: - PolySetInputAssemblyCommand(PolyInputAssembly* input) : input(input) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetInputAssembly(input); } - -private: - PolyInputAssembly* input; -}; - -class PolyClearDepthCommand : public PolyDrawerCommand -{ -public: - PolyClearDepthCommand(float value) : value(value) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->ClearDepth(value); } - -private: - float value; -}; - -class PolyClearStencilCommand : public PolyDrawerCommand -{ -public: - PolyClearStencilCommand(uint8_t value) : value(value) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->ClearStencil(value); } - -private: - uint8_t value; -}; - -class PolySetViewportCommand : public PolyDrawerCommand -{ -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, PolyDepthStencil* depthstencil, bool topdown) - : 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), depthstencil(depthstencil), topdown(topdown) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, depthstencil, topdown); } - -private: - int x; - int y; - int width; - int height; - uint8_t* dest; - int dest_width; - int dest_height; - int dest_pitch; - bool dest_bgra; - PolyDepthStencil* depthstencil; - bool topdown; -}; - -class PolySetViewpointUniformsCommand : public PolyDrawerCommand -{ -public: - PolySetViewpointUniformsCommand(const HWViewpointUniforms* uniforms) : uniforms(uniforms) {} - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetViewpointUniforms(uniforms); } - -private: - const HWViewpointUniforms* uniforms; -}; - -class PolyPushMatricesCommand : public PolyDrawerCommand -{ -public: - PolyPushMatricesCommand(const VSMatrix& modelMatrix, const VSMatrix& normalModelMatrix, const VSMatrix& textureMatrix) - : modelMatrix(modelMatrix), normalModelMatrix(normalModelMatrix), textureMatrix(textureMatrix) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->PushMatrices(modelMatrix, normalModelMatrix, textureMatrix); } - -private: - VSMatrix modelMatrix; - VSMatrix normalModelMatrix; - VSMatrix textureMatrix; -}; - -class PolyPushStreamDataCommand : public PolyDrawerCommand -{ -public: - PolyPushStreamDataCommand(const StreamData& data, const PolyPushConstants& constants) : data(data), constants(constants) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->PushStreamData(data, constants); } - -private: - StreamData data; - PolyPushConstants constants; -}; - -class PolyDrawCommand : public PolyDrawerCommand -{ -public: - PolyDrawCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->Draw(index, count, mode); } - -private: - int index; - int count; - PolyDrawMode mode; -}; - -class PolyDrawIndexedCommand : public PolyDrawerCommand -{ -public: - PolyDrawIndexedCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->DrawIndexed(index, count, mode); } - -private: - int index; - int count; - PolyDrawMode mode; -}; - -///////////////////////////////////////////////////////////////////////////// - -PolyCommandBuffer::PolyCommandBuffer(RenderMemory* frameMemory) -{ - mQueue = std::make_shared(frameMemory); -} - -void PolyCommandBuffer::SetViewport(int x, int y, int width, int height, DCanvas *canvas, PolyDepthStencil *depthstencil, bool topdown) -{ - uint8_t *dest = (uint8_t*)canvas->GetPixels(); - int dest_width = canvas->GetWidth(); - int dest_height = canvas->GetHeight(); - int dest_pitch = canvas->GetPitch(); - bool dest_bgra = canvas->IsBgra(); - - mQueue->Push(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, depthstencil, topdown); -} - -void PolyCommandBuffer::SetInputAssembly(PolyInputAssembly *input) -{ - mQueue->Push(input); -} - -void PolyCommandBuffer::SetVertexBuffer(const void *vertices, int offset0, int offset1) -{ - mQueue->Push(vertices, offset0, offset1); -} - -void PolyCommandBuffer::SetIndexBuffer(const void *elements) -{ - mQueue->Push(elements); -} - -void PolyCommandBuffer::SetLightBuffer(const void *lights) -{ - mQueue->Push(lights); -} - -void PolyCommandBuffer::SetDepthClamp(bool on) -{ - mQueue->Push(on); -} - -void PolyCommandBuffer::SetDepthMask(bool on) -{ - mQueue->Push(on); -} - -void PolyCommandBuffer::SetDepthFunc(int func) -{ - mQueue->Push(func); -} - -void PolyCommandBuffer::SetDepthRange(float min, float max) -{ - mQueue->Push(min, max); -} - -void PolyCommandBuffer::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor) -{ - mQueue->Push(depthBiasConstantFactor, depthBiasSlopeFactor); -} - -void PolyCommandBuffer::SetColorMask(bool r, bool g, bool b, bool a) -{ - mQueue->Push(r, g, b, a); -} - -void PolyCommandBuffer::SetStencil(int stencilRef, int op) -{ - mQueue->Push(stencilRef, op); -} - -void PolyCommandBuffer::SetCulling(int mode) -{ - mQueue->Push(mode); -} - -void PolyCommandBuffer::EnableStencil(bool on) -{ - mQueue->Push(on); -} - -void PolyCommandBuffer::SetScissor(int x, int y, int w, int h) -{ - mQueue->Push(x, y, w, h); -} - -void PolyCommandBuffer::SetRenderStyle(FRenderStyle style) -{ - mQueue->Push(style); -} - -void PolyCommandBuffer::SetTexture(int unit, void *pixels, int width, int height, bool bgra) -{ - mQueue->Push(unit, pixels, width, height, bgra); -} - -void PolyCommandBuffer::SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader) -{ - mQueue->Push(specialEffect, effectState, alphaTest, colormapShader); -} - -void PolyCommandBuffer::PushStreamData(const StreamData &data, const PolyPushConstants &constants) -{ - mQueue->Push(data, constants); -} - -void PolyCommandBuffer::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix) -{ - mQueue->Push(modelMatrix, normalModelMatrix, textureMatrix); -} - -void PolyCommandBuffer::SetViewpointUniforms(const HWViewpointUniforms *uniforms) -{ - mQueue->Push(uniforms); -} - -void PolyCommandBuffer::ClearDepth(float value) -{ - mQueue->Push(value); -} - -void PolyCommandBuffer::ClearStencil(uint8_t value) -{ - mQueue->Push(value); -} - -void PolyCommandBuffer::Draw(int index, int vcount, PolyDrawMode mode) -{ - mQueue->Push(index, vcount, mode); -} - -void PolyCommandBuffer::DrawIndexed(int index, int count, PolyDrawMode mode) -{ - mQueue->Push(index, count, mode); -} - -void PolyCommandBuffer::Submit() -{ - DrawerThreads::Execute(mQueue); -} diff --git a/src/common/rendering/polyrenderer/drawers/poly_triangle.h b/src/common/rendering/polyrenderer/drawers/poly_triangle.h deleted file mode 100644 index d29b10ba3..000000000 --- a/src/common/rendering/polyrenderer/drawers/poly_triangle.h +++ /dev/null @@ -1,121 +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 "swrenderer/drawers/r_draw.h" -#include "r_thread.h" -#include "polyrenderer/drawers/screen_triangle.h" -#include "polyrenderer/drawers/poly_vertex_shader.h" - -class DCanvas; -class RenderMemory; -class PolyDrawerCommand; -class PolyInputAssembly; -class PolyDepthStencil; -struct PolyPushConstants; - -enum class PolyDrawMode -{ - Points, - Lines, - Triangles, - TriangleFan, - TriangleStrip -}; - -class PolyCommandBuffer -{ -public: - PolyCommandBuffer(RenderMemory* frameMemory); - - void SetViewport(int x, int y, int width, int height, DCanvas *canvas, PolyDepthStencil *depthStencil, bool topdown); - void SetInputAssembly(PolyInputAssembly *input); - void SetVertexBuffer(const void *vertices, int offset0, int offset1); // [GEC] Add offset params - void SetIndexBuffer(const void *elements); - void SetLightBuffer(const void *lights); - void SetViewpointUniforms(const HWViewpointUniforms *uniforms); - void SetDepthClamp(bool on); - void SetDepthMask(bool on); - void SetDepthFunc(int func); - void SetDepthRange(float min, float max); - void SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor); - void SetColorMask(bool r, bool g, bool b, bool a); - void SetStencil(int stencilRef, int op); - void SetCulling(int mode); - void EnableStencil(bool on); - void SetScissor(int x, int y, int w, int h); - void SetRenderStyle(FRenderStyle style); - void SetTexture(int unit, void *pixels, int width, int height, bool bgra); - void SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader); - void PushStreamData(const StreamData &data, const PolyPushConstants &constants); - void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix); - void ClearDepth(float value); - void ClearStencil(uint8_t value); - void Draw(int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles); - void DrawIndexed(int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles); - void Submit(); - -private: - std::shared_ptr mQueue; -}; - -class PolyDepthStencil -{ -public: - PolyDepthStencil(int width, int height) : width(width), height(height), depthbuffer(width * height), stencilbuffer(width * height) { } - - int Width() const { return width; } - int Height() const { return height; } - float *DepthValues() { return depthbuffer.data(); } - uint8_t *StencilValues() { return stencilbuffer.data(); } - -private: - int width; - int height; - std::vector depthbuffer; - std::vector stencilbuffer; -}; - -struct PolyPushConstants -{ - int uTextureMode; - float uAlphaThreshold; - FVector2 uClipSplit; - - // Lighting + Fog - float uLightLevel; - float uFogDensity; - float uLightFactor; - float uLightDist; - int uFogEnabled; - - // dynamic lights - int uLightIndex; - FVector4 uDynLightColor; // [GEC] -}; - -class PolyInputAssembly -{ -public: - virtual void Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) = 0; // [GEC] Add frame params -}; diff --git a/src/common/rendering/polyrenderer/drawers/poly_vertex_shader.h b/src/common/rendering/polyrenderer/drawers/poly_vertex_shader.h deleted file mode 100644 index aaf613d98..000000000 --- a/src/common/rendering/polyrenderer/drawers/poly_vertex_shader.h +++ /dev/null @@ -1,194 +0,0 @@ - -#pragma once - -#include "hw_viewpointuniforms.h" -#include "hw_renderstate.h" - -#ifndef NO_SSE -#include -#endif - -class ShadedTriVertex -{ -public: - FVector4 gl_Position; - float gl_ClipDistance[5]; - FVector4 vTexCoord; - FVector4 vColor; - FVector4 pixelpos; - //FVector3 glowdist; - FVector3 gradientdist; - //FVector4 vEyeNormal; - FVector4 vWorldNormal; -}; - -class PolyMainVertexShader : public ShadedTriVertex -{ -public: - // Input - FVector4 aPosition; - FVector2 aTexCoord; - FVector4 aColor; - FVector4 aVertex2; - FVector4 aNormal; - FVector4 aNormal2; - - // Defines - bool SIMPLE = false; - bool SPHEREMAP = false; - - // Uniforms - VSMatrix ModelMatrix; - VSMatrix NormalModelMatrix; - VSMatrix TextureMatrix; - StreamData Data; - FVector2 uClipSplit; - const HWViewpointUniforms *Viewpoint = nullptr; - - void main() - { - FVector2 parmTexCoord = aTexCoord; - FVector4 parmPosition = aPosition; - - FVector4 worldcoord; - if (SIMPLE) - worldcoord = mul(ModelMatrix, mix(parmPosition, aVertex2, Data.uInterpolationFactor)); - else - worldcoord = mul(ModelMatrix, parmPosition); - - FVector4 eyeCoordPos = mul(Viewpoint->mViewMatrix, worldcoord); - - vColor = aColor; - - if (!SIMPLE) - { - pixelpos.X = worldcoord.X; - pixelpos.Y = worldcoord.Y; - pixelpos.Z = worldcoord.Z; - pixelpos.W = -eyeCoordPos.Z / eyeCoordPos.W; - - /*if (Data.uGlowTopColor.W > 0 || Data.uGlowBottomColor.W > 0) - { - float topatpoint = (Data.uGlowTopPlane.W + Data.uGlowTopPlane.X * worldcoord.X + Data.uGlowTopPlane.Y * worldcoord.Z) * Data.uGlowTopPlane.Z; - float bottomatpoint = (Data.uGlowBottomPlane.W + Data.uGlowBottomPlane.X * worldcoord.X + Data.uGlowBottomPlane.Y * worldcoord.Z) * Data.uGlowBottomPlane.Z; - glowdist.X = topatpoint - worldcoord.Y; - glowdist.Y = worldcoord.Y - bottomatpoint; - glowdist.Z = clamp(glowdist.X / (topatpoint - bottomatpoint), 0.0f, 1.0f); - }*/ - - if (Data.uObjectColor2.a != 0) - { - float topatpoint = (Data.uGradientTopPlane.W + Data.uGradientTopPlane.X * worldcoord.X + Data.uGradientTopPlane.Y * worldcoord.Z) * Data.uGradientTopPlane.Z; - float bottomatpoint = (Data.uGradientBottomPlane.W + Data.uGradientBottomPlane.X * worldcoord.X + Data.uGradientBottomPlane.Y * worldcoord.Z) * Data.uGradientBottomPlane.Z; - gradientdist.X = topatpoint - worldcoord.Y; - gradientdist.Y = worldcoord.Y - bottomatpoint; - gradientdist.Z = clamp(gradientdist.X / (topatpoint - bottomatpoint), 0.0f, 1.0f); - } - - if (Data.uSplitBottomPlane.Z != 0.0f) - { - gl_ClipDistance[3] = ((Data.uSplitTopPlane.W + Data.uSplitTopPlane.X * worldcoord.X + Data.uSplitTopPlane.Y * worldcoord.Z) * Data.uSplitTopPlane.Z) - worldcoord.Y; - gl_ClipDistance[4] = worldcoord.Y - ((Data.uSplitBottomPlane.W + Data.uSplitBottomPlane.X * worldcoord.X + Data.uSplitBottomPlane.Y * worldcoord.Z) * Data.uSplitBottomPlane.Z); - } - - vWorldNormal = mul(NormalModelMatrix, FVector4(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f)); - //vEyeNormal = mul(Viewpoint->mNormalViewMatrix, vWorldNormal); - } - - if (!SPHEREMAP) - { - vTexCoord = mul(TextureMatrix, FVector4(parmTexCoord.X, parmTexCoord.Y, 0.0f, 1.0f)); - } - else - { - FVector3 u = normalize3(eyeCoordPos); - FVector3 n = normalize3(mul(Viewpoint->mNormalViewMatrix, FVector4(parmTexCoord.X, 0.0f, parmTexCoord.Y, 0.0f))); - FVector3 r = reflect(u, n); - float m = 2.0f * sqrtf(r.X*r.X + r.Y*r.Y + (r.Z + 1.0f)*(r.Z + 1.0f)); - vTexCoord.X = r.X / m + 0.5f; - vTexCoord.Y = r.Y / m + 0.5f; - } - - gl_Position = mul(Viewpoint->mProjectionMatrix, eyeCoordPos); - - if (Viewpoint->mClipHeightDirection != 0.0f) // clip planes used for reflective flats - { - gl_ClipDistance[0] = (worldcoord.Y - Viewpoint->mClipHeight) * Viewpoint->mClipHeightDirection; - } - else if (Viewpoint->mClipLine.X > -1000000.0f) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane. - { - gl_ClipDistance[0] = -((worldcoord.Z - Viewpoint->mClipLine.Y) * Viewpoint->mClipLine.Z + (Viewpoint->mClipLine.X - worldcoord.X) * Viewpoint->mClipLine.W) + 1.0f / 32768.0f; // allow a tiny bit of imprecisions for colinear linedefs. - } - else - { - gl_ClipDistance[0] = 1.0f; - } - - // clip planes used for translucency splitting - gl_ClipDistance[1] = worldcoord.Y - uClipSplit.X; - gl_ClipDistance[2] = uClipSplit.Y - worldcoord.Y; - - if (Data.uSplitTopPlane == FVector4(0.0f, 0.0f, 0.0f, 0.0f)) - { - gl_ClipDistance[3] = 1.0f; - gl_ClipDistance[4] = 1.0f; - } - } - -private: - static FVector3 normalize(const FVector3 &a) - { - float rcplen = 1.0f / sqrtf(a.X * a.X + a.Y * a.Y + a.Z * a.Z); - return FVector3(a.X * rcplen, a.Y * rcplen, a.Z * rcplen); - } - - static FVector3 normalize3(const FVector4 &a) - { - float rcplen = 1.0f / sqrtf(a.X * a.X + a.Y * a.Y + a.Z * a.Z); - return FVector3(a.X * rcplen, a.Y * rcplen, a.Z * rcplen); - } - - static FVector4 mix(const FVector4 &a, const FVector4 &b, float t) - { - float invt = 1.0f - t; - return FVector4(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t, a.W * invt + b.W * t); - } - - static FVector3 mix3(const FVector4 &a, const FVector4 &b, float t) - { - float invt = 1.0f - t; - return FVector3(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t); - } - - static FVector3 reflect(const FVector3 &u, const FVector3 &n) - { - float d = 2.0f * (n.X * u.X + n.Y * u.Y + n.Z * u.Z); - return FVector3(u.X - d * n.X, u.Y - d * n.Y, u.Z - d * n.Z); - } - - static FVector4 mul(const VSMatrix &mat, const FVector4 &v) - { - const float *m = mat.get(); - - FVector4 result; -#ifdef NO_SSE - result.X = m[0 * 4 + 0] * v.X + m[1 * 4 + 0] * v.Y + m[2 * 4 + 0] * v.Z + m[3 * 4 + 0] * v.W; - result.Y = m[0 * 4 + 1] * v.X + m[1 * 4 + 1] * v.Y + m[2 * 4 + 1] * v.Z + m[3 * 4 + 1] * v.W; - result.Z = m[0 * 4 + 2] * v.X + m[1 * 4 + 2] * v.Y + m[2 * 4 + 2] * v.Z + m[3 * 4 + 2] * v.W; - result.W = m[0 * 4 + 3] * v.X + m[1 * 4 + 3] * v.Y + m[2 * 4 + 3] * v.Z + m[3 * 4 + 3] * v.W; -#else - __m128 m0 = _mm_loadu_ps(m); - __m128 m1 = _mm_loadu_ps(m + 4); - __m128 m2 = _mm_loadu_ps(m + 8); - __m128 m3 = _mm_loadu_ps(m + 12); - __m128 mv = _mm_loadu_ps(&v.X); - m0 = _mm_mul_ps(m0, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(0, 0, 0, 0))); - m1 = _mm_mul_ps(m1, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(1, 1, 1, 1))); - m2 = _mm_mul_ps(m2, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(2, 2, 2, 2))); - m3 = _mm_mul_ps(m3, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(3, 3, 3, 3))); - mv = _mm_add_ps(_mm_add_ps(_mm_add_ps(m0, m1), m2), m3); - _mm_storeu_ps(&result.X, mv); -#endif - return result; - } -}; diff --git a/src/common/rendering/polyrenderer/drawers/screen_blend.cpp b/src/common/rendering/polyrenderer/drawers/screen_blend.cpp deleted file mode 100644 index 536acb7b0..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_blend.cpp +++ /dev/null @@ -1,627 +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. -** -*/ - -#include "screen_blend.h" - -#ifndef NO_SSE -#include -#endif - -static const int shiftTable[] = { - 0, 0, 0, 0, // STYLEALPHA_Zero - 0, 0, 0, 0, // STYLEALPHA_One - 24, 24, 24, 24, // STYLEALPHA_Src - 24, 24, 24, 24, // STYLEALPHA_InvSrc - 24, 16, 8, 0, // STYLEALPHA_SrcCol - 24, 16, 8, 0, // STYLEALPHA_InvSrcCol - 24, 16, 8, 0, // STYLEALPHA_DstCol - 24, 16, 8, 0 // STYLEALPHA_InvDstCol -}; - -#if 1 //#ifndef USE_AVX2 -template -void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - FRenderStyle style = thread->RenderStyle; - - bool invsrc = style.SrcAlpha & 1; - bool invdst = style.DestAlpha & 1; - - const int* shiftsrc = shiftTable + (style.SrcAlpha << 2); - const int* shiftdst = shiftTable + (style.DestAlpha << 2); - - uint32_t* dest = (uint32_t*)thread->dest; - uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int srcSelect = style.SrcAlpha <= STYLEALPHA_One ? 0 : (style.SrcAlpha >= STYLEALPHA_DstCol ? 1 : 2); - int dstSelect = style.DestAlpha <= STYLEALPHA_One ? 0 : (style.DestAlpha >= STYLEALPHA_DstCol ? 1 : 2); - - uint32_t inputs[3]; - inputs[0] = 0; - - for (int x = x0; x < x1; x++) - { - inputs[1] = line[x]; - inputs[2] = fragcolor[x]; - - uint32_t srcinput = inputs[srcSelect]; - uint32_t dstinput = inputs[dstSelect]; - - uint32_t out[4]; - for (int i = 0; i < 4; i++) - { - // Grab component for scale factors - int32_t src = (srcinput >> shiftsrc[i]) & 0xff; - int32_t dst = (dstinput >> shiftdst[i]) & 0xff; - - // Inverse if needed - if (invsrc) src = 0xff - src; - if (invdst) dst = 0xff - dst; - - // Rescale 0-255 to 0-256 - src = src + (src >> 7); - dst = dst + (dst >> 7); - - // Multiply with input - src = src * ((inputs[2] >> (24 - (i << 3))) & 0xff); - dst = dst * ((inputs[1] >> (24 - (i << 3))) & 0xff); - - // Apply blend operator - int32_t val; - if (OptT::Flags & SWBLEND_Sub) - { - val = src - dst; - } - else if (OptT::Flags & SWBLEND_RevSub) - { - val = dst - src; - } - else - { - val = src + dst; - } - out[i] = clamp((val + 127) >> 8, 0, 255); - } - - line[x] = MAKEARGB(out[0], out[1], out[2], out[3]); - } -} -#else -template -void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - FRenderStyle style = thread->RenderStyle; - - bool invsrc = style.SrcAlpha & 1; - bool invdst = style.DestAlpha & 1; - - __m128i shiftsrc = _mm_loadu_si128((const __m128i*)(shiftTable + (style.SrcAlpha << 2))); - __m128i shiftdst = _mm_loadu_si128((const __m128i*)(shiftTable + (style.DestAlpha << 2))); - - uint32_t* dest = (uint32_t*)thread->dest; - uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int srcSelect = style.SrcAlpha <= STYLEALPHA_One ? 0 : (style.SrcAlpha >= STYLEALPHA_DstCol ? 1 : 2); - int dstSelect = style.DestAlpha <= STYLEALPHA_One ? 0 : (style.DestAlpha >= STYLEALPHA_DstCol ? 1 : 2); - - uint32_t inputs[3]; - inputs[0] = 0; - - __m128i shiftmul = _mm_set_epi32(24, 16, 8, 0); - - for (int x = x0; x < x1; x++) - { - inputs[1] = line[x]; - inputs[2] = fragcolor[x]; - - __m128i srcinput = _mm_set1_epi32(inputs[srcSelect]); - __m128i dstinput = _mm_set1_epi32(inputs[dstSelect]); - - // Grab component for scale factors - __m128i src = _mm_and_si128(_mm_srlv_epi32(srcinput, shiftsrc), _mm_set1_epi32(0xff)); - __m128i dst = _mm_and_si128(_mm_srlv_epi32(dstinput, shiftdst), _mm_set1_epi32(0xff)); - - // Inverse if needed - if (invsrc) src = _mm_sub_epi32(_mm_set1_epi32(0xff), src); - if (invdst) dst = _mm_sub_epi32(_mm_set1_epi32(0xff), dst); - - // Rescale 0-255 to 0-256 - src = _mm_add_epi32(src, _mm_srli_epi32(src, 7)); - dst = _mm_add_epi32(dst, _mm_srli_epi32(dst, 7)); - - // Multiply with input - __m128i mulsrc = _mm_and_si128(_mm_srlv_epi32(_mm_set1_epi32(inputs[2]), shiftmul), _mm_set1_epi32(0xff)); - __m128i muldst = _mm_and_si128(_mm_srlv_epi32(_mm_set1_epi32(inputs[1]), shiftmul), _mm_set1_epi32(0xff)); - __m128i mulresult = _mm_mullo_epi16(_mm_packs_epi32(src, dst), _mm_packs_epi32(mulsrc, muldst)); - src = _mm_unpacklo_epi16(mulresult, _mm_setzero_si128()); - dst = _mm_unpackhi_epi16(mulresult, _mm_setzero_si128()); - - // Apply blend operator - __m128i val; - if (OptT::Flags & SWBLEND_Sub) - { - val = _mm_sub_epi32(src, dst); - } - else if (OptT::Flags & SWBLEND_RevSub) - { - val = _mm_sub_epi32(dst, src); - } - else - { - val = _mm_add_epi32(src, dst); - } - - __m128i out = _mm_srli_epi32(_mm_add_epi32(val, _mm_set1_epi32(127)), 8); - out = _mm_packs_epi32(out, out); - out = _mm_packus_epi16(out, out); - line[x] = _mm_cvtsi128_si32(out); - } -} -#endif - -#ifdef NO_SSE -void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* dest = (uint32_t*)thread->dest; - uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - memcpy(line + x0, fragcolor + x0, (x1 - x0) * sizeof(uint32_t)); -} -#else -void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* dest = (uint32_t*)thread->dest; - uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int ssecount = ((x1 - x0) & ~3); - int sseend = x0 + ssecount; - - for (int x = x0; x < sseend; x += 4) - { - __m128i v = _mm_loadu_si128((__m128i*) & fragcolor[x]); - _mm_storeu_si128((__m128i*) & line[x], v); - } - - for (int x = sseend; x < x1; x++) - { - line[x] = fragcolor[x]; - } -} -#endif - -void BlendColorAdd_Src_InvSrc(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)&line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)&fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = _mm_shufflehi_epi16(_mm_shufflelo_epi16(src, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3)); - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - __m128i dstscale = _mm_sub_epi16(_mm_set1_epi16(256), srcscale); - - __m128i out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_mullo_epi16(dst, dstscale)), _mm_set1_epi16(127)), 8); - _mm_storel_epi64((__m128i*)&line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale = APART(src); - srcscale += srcscale >> 7; - uint32_t dstscale = 256 - srcscale; - - uint32_t a = ((APART(src) * srcscale + APART(dst) * dstscale) + 127) >> 8; - uint32_t r = ((RPART(src) * srcscale + RPART(dst) * dstscale) + 127) >> 8; - uint32_t g = ((GPART(src) * srcscale + GPART(dst) * dstscale) + 127) >> 8; - uint32_t b = ((BPART(src) * srcscale + BPART(dst) * dstscale) + 127) >> 8; - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorAdd_SrcCol_InvSrcCol(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = src; - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - __m128i dstscale = _mm_sub_epi16(_mm_set1_epi16(256), srcscale); - - __m128i out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_mullo_epi16(dst, dstscale)), _mm_set1_epi16(127)), 8); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale_a = APART(src); - uint32_t srcscale_r = RPART(src); - uint32_t srcscale_g = GPART(src); - uint32_t srcscale_b = BPART(src); - srcscale_a += srcscale_a >> 7; - srcscale_r += srcscale_r >> 7; - srcscale_g += srcscale_g >> 7; - srcscale_b += srcscale_b >> 7; - uint32_t dstscale_a = 256 - srcscale_a; - uint32_t dstscale_r = 256 - srcscale_r; - uint32_t dstscale_g = 256 - srcscale_g; - uint32_t dstscale_b = 256 - srcscale_b; - - uint32_t a = ((APART(src) * srcscale_a + APART(dst) * dstscale_a) + 127) >> 8; - uint32_t r = ((RPART(src) * srcscale_r + RPART(dst) * dstscale_r) + 127) >> 8; - uint32_t g = ((GPART(src) * srcscale_g + GPART(dst) * dstscale_g) + 127) >> 8; - uint32_t b = ((BPART(src) * srcscale_b + BPART(dst) * dstscale_b) + 127) >> 8; - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorAdd_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = _mm_shufflehi_epi16(_mm_shufflelo_epi16(src, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3)); - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - - __m128i out = _mm_add_epi16(_mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_set1_epi16(127)), 8), dst); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale = APART(src); - srcscale += srcscale >> 7; - - uint32_t a = min((((APART(src) * srcscale) + 127) >> 8) + APART(dst), 255); - uint32_t r = min((((RPART(src) * srcscale) + 127) >> 8) + RPART(dst), 255); - uint32_t g = min((((GPART(src) * srcscale) + 127) >> 8) + GPART(dst), 255); - uint32_t b = min((((BPART(src) * srcscale) + 127) >> 8) + BPART(dst), 255); - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorAdd_SrcCol_One(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = src; - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - - __m128i out = _mm_add_epi16(_mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_set1_epi16(127)), 8), dst); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale_a = APART(src); - uint32_t srcscale_r = RPART(src); - uint32_t srcscale_g = GPART(src); - uint32_t srcscale_b = BPART(src); - srcscale_a += srcscale_a >> 7; - srcscale_r += srcscale_r >> 7; - srcscale_g += srcscale_g >> 7; - srcscale_b += srcscale_b >> 7; - - uint32_t a = min((((APART(src) * srcscale_a) + 127) >> 8) + APART(dst), 255); - uint32_t r = min((((RPART(src) * srcscale_r) + 127) >> 8) + RPART(dst), 255); - uint32_t g = min((((GPART(src) * srcscale_g) + 127) >> 8) + GPART(dst), 255); - uint32_t b = min((((BPART(src) * srcscale_b) + 127) >> 8) + BPART(dst), 255); - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorAdd_DstCol_Zero(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = dst; - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - - __m128i out = _mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_set1_epi16(127)), 8); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale_a = APART(dst); - uint32_t srcscale_r = RPART(dst); - uint32_t srcscale_g = GPART(dst); - uint32_t srcscale_b = BPART(dst); - srcscale_a += srcscale_a >> 7; - srcscale_r += srcscale_r >> 7; - srcscale_g += srcscale_g >> 7; - srcscale_b += srcscale_b >> 7; - - uint32_t a = (((APART(src) * srcscale_a) + 127) >> 8); - uint32_t r = (((RPART(src) * srcscale_r) + 127) >> 8); - uint32_t g = (((GPART(src) * srcscale_g) + 127) >> 8); - uint32_t b = (((BPART(src) * srcscale_b) + 127) >> 8); - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorAdd_InvDstCol_Zero(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = _mm_sub_epi16(_mm_set1_epi16(255), dst); - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - - __m128i out = _mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_set1_epi16(127)), 8); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale_a = 255 - APART(dst); - uint32_t srcscale_r = 255 - RPART(dst); - uint32_t srcscale_g = 255 - GPART(dst); - uint32_t srcscale_b = 255 - BPART(dst); - srcscale_a += srcscale_a >> 7; - srcscale_r += srcscale_r >> 7; - srcscale_g += srcscale_g >> 7; - srcscale_b += srcscale_b >> 7; - - uint32_t a = (((APART(src) * srcscale_a) + 127) >> 8); - uint32_t r = (((RPART(src) * srcscale_r) + 127) >> 8); - uint32_t g = (((GPART(src) * srcscale_g) + 127) >> 8); - uint32_t b = (((BPART(src) * srcscale_b) + 127) >> 8); - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorRevSub_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - uint32_t* fragcolor = thread->scanline.FragColor; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~1); - sseend = x0 + ssecount; - for (int x = x0; x < sseend; x += 2) - { - __m128i dst = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & line[x]), _mm_setzero_si128()); - __m128i src = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*) & fragcolor[x]), _mm_setzero_si128()); - - __m128i srcscale = _mm_shufflehi_epi16(_mm_shufflelo_epi16(src, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3)); - srcscale = _mm_add_epi16(srcscale, _mm_srli_epi16(srcscale, 7)); - - __m128i out = _mm_sub_epi16(dst, _mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(src, srcscale), _mm_set1_epi16(127)), 8)); - _mm_storel_epi64((__m128i*) & line[x], _mm_packus_epi16(out, out)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - uint32_t src = fragcolor[x]; - - uint32_t srcscale = APART(src); - srcscale += srcscale >> 7; - - uint32_t a = max(APART(dst) - (((APART(src) * srcscale) + 127) >> 8), 0); - uint32_t r = max(RPART(dst) - (((RPART(src) * srcscale) + 127) >> 8), 0); - uint32_t g = max(GPART(dst) - (((GPART(src) * srcscale) + 127) >> 8), 0); - uint32_t b = max(BPART(dst) - (((BPART(src) * srcscale) + 127) >> 8), 0); - - line[x] = MAKEARGB(a, r, g, b); - } -} - -void BlendColorColormap(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch; - - // [GEC] I leave the default floating values. - float startR = thread->mainVertexShader.Data.uObjectColor.r; - float startG = thread->mainVertexShader.Data.uObjectColor.g; - float startB = thread->mainVertexShader.Data.uObjectColor.b; - float rangeR = thread->mainVertexShader.Data.uAddColor.r - startR; - float rangeG = thread->mainVertexShader.Data.uAddColor.g - startG; - float rangeB = thread->mainVertexShader.Data.uAddColor.b - startB; - - int sseend = x0; - for (int x = sseend; x < x1; x++) - { - uint32_t dst = line[x]; - - uint32_t a = APART(dst); - uint32_t r = RPART(dst); - uint32_t g = GPART(dst); - uint32_t b = BPART(dst); - - uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8; - gray += (gray >> 7); // gray*=256/255 - - // [GEC] I use the same method as in shaders using floating values. - // This avoids errors in the invulneravility colormap in Doom and Heretic. - float fgray = (float)(gray / 255.f); - float fr = (startR + (fgray * rangeR)) * 2; - float fg = (startG + (fgray * rangeG)) * 2; - float fb = (startB + (fgray * rangeB)) * 2; - - fr = clamp(fr, 0.0f, 1.0f); - fg = clamp(fg, 0.0f, 1.0f); - fb = clamp(fb, 0.0f, 1.0f); - - r = (uint32_t)(fr * 255.f); - g = (uint32_t)(fg * 255.f); - b = (uint32_t)(fb * 255.f); - - line[x] = MAKEARGB(a, (uint8_t)r, (uint8_t)g, (uint8_t)b); - } -} - -void SelectWriteColorFunc(PolyTriangleThreadData* thread) -{ - FRenderStyle style = thread->RenderStyle; - if (thread->ColormapShader) - { - thread->WriteColorFunc = &BlendColorColormap; - } - else if (style.BlendOp == STYLEOP_Add) - { - if (style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero) - { - thread->WriteColorFunc = &BlendColorOpaque; - } - else if (style.SrcAlpha == STYLEALPHA_Src && style.DestAlpha == STYLEALPHA_InvSrc) - { - thread->WriteColorFunc = &BlendColorAdd_Src_InvSrc; - } - else if (style.SrcAlpha == STYLEALPHA_SrcCol && style.DestAlpha == STYLEALPHA_InvSrcCol) - { - thread->WriteColorFunc = &BlendColorAdd_SrcCol_InvSrcCol; - } - else if (style.SrcAlpha == STYLEALPHA_Src && style.DestAlpha == STYLEALPHA_One) - { - thread->WriteColorFunc = &BlendColorAdd_Src_One; - } - else if (style.SrcAlpha == STYLEALPHA_SrcCol && style.DestAlpha == STYLEALPHA_One) - { - thread->WriteColorFunc = &BlendColorAdd_SrcCol_One; - } - else if (style.SrcAlpha == STYLEALPHA_DstCol && style.DestAlpha == STYLEALPHA_Zero) - { - thread->WriteColorFunc = &BlendColorAdd_DstCol_Zero; - } - else if (style.SrcAlpha == STYLEALPHA_InvDstCol && style.DestAlpha == STYLEALPHA_Zero) - { - thread->WriteColorFunc = &BlendColorAdd_InvDstCol_Zero; - } - else - { - thread->WriteColorFunc = &BlendColor; - } - } - else if (style.BlendOp == STYLEOP_Sub) - { - thread->WriteColorFunc = &BlendColor; - } - else // if (style.BlendOp == STYLEOP_RevSub) - { - if (style.SrcAlpha == STYLEALPHA_Src && style.DestAlpha == STYLEALPHA_One) - { - thread->WriteColorFunc = &BlendColorRevSub_Src_One; - } - else - { - thread->WriteColorFunc = &BlendColor; - } - } -} diff --git a/src/common/rendering/polyrenderer/drawers/screen_blend.h b/src/common/rendering/polyrenderer/drawers/screen_blend.h deleted file mode 100644 index 101c151b0..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_blend.h +++ /dev/null @@ -1,49 +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 - -class PolyTriangleThreadData; - -enum SWBlendColor -{ - SWBLEND_Sub = 1, - SWBLEND_RevSub = 2 -}; - -struct BlendColorOpt_Add { static const int Flags = 0; }; -struct BlendColorOpt_Sub { static const int Flags = 1; }; -struct BlendColorOpt_RevSub { static const int Flags = 2; }; - -template -void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_Src_InvSrc(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_SrcCol_InvSrcCol(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_SrcCol_One(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_DstCol_Zero(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorAdd_InvDstCol_Zero(int y, int x0, int x1, PolyTriangleThreadData* thread); -void BlendColorRevSub_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thread); - -void SelectWriteColorFunc(PolyTriangleThreadData* thread); diff --git a/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp b/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp deleted file mode 100644 index 6cb9ee2cb..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.cpp +++ /dev/null @@ -1,590 +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. -** -*/ - -#include - -#include "poly_thread.h" -#include "screen_scanline_setup.h" -#include - -#ifndef NO_SSE -#include -#endif - -#ifdef NO_SSE -void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - float startX = x0 + (0.5f - args->v1->x); - float startY = y + (0.5f - args->v1->y); - - float posW = args->v1->w + args->gradientX.W * startX + args->gradientY.W * startY; - float stepW = args->gradientX.W; - float* w = thread->scanline.W; - for (int x = x0; x < x1; x++) - { - w[x] = 1.0f / posW; - posW += stepW; - } -} -#else -void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - float startX = x0 + (0.5f - args->v1->x); - float startY = y + (0.5f - args->v1->y); - - float posW = args->v1->w + args->gradientX.W * startX + args->gradientY.W * startY; - float stepW = args->gradientX.W; - float* w = thread->scanline.W; - - int ssecount = ((x1 - x0) & ~3); - int sseend = x0 + ssecount; - - __m128 mstepW = _mm_set1_ps(stepW * 4.0f); - __m128 mposW = _mm_setr_ps(posW, posW + stepW, posW + stepW + stepW, posW + stepW + stepW + stepW); - - for (int x = x0; x < sseend; x += 4) - { - // One Newton-Raphson iteration for 1/posW - __m128 res = _mm_rcp_ps(mposW); - __m128 muls = _mm_mul_ps(mposW, _mm_mul_ps(res, res)); - _mm_storeu_ps(w + x, _mm_sub_ps(_mm_add_ps(res, res), muls)); - mposW = _mm_add_ps(mposW, mstepW); - } - - mstepW = _mm_set_ss(stepW); - for (int x = sseend; x < x1; x++) - { - __m128 res = _mm_rcp_ss(mposW); - __m128 muls = _mm_mul_ss(mposW, _mm_mul_ss(res, res)); - _mm_store_ss(w + x, _mm_sub_ss(_mm_add_ss(res, res), muls)); - mposW = _mm_add_ss(mposW, mstepW); - } -} -#endif - -static void WriteDynLightArray(int x0, int x1, PolyTriangleThreadData* thread) -{ - int num_lights = thread->numPolyLights; - PolyLight* lights = thread->polyLights; - - float worldnormalX = thread->mainVertexShader.vWorldNormal.X; - float worldnormalY = thread->mainVertexShader.vWorldNormal.Y; - float worldnormalZ = thread->mainVertexShader.vWorldNormal.Z; - - uint32_t* lightarray = thread->scanline.lightarray; - float* worldposX = thread->scanline.WorldX; - float* worldposY = thread->scanline.WorldY; - float* worldposZ = thread->scanline.WorldZ; - - int sseend = x0; - -#ifndef NO_SSE - int ssecount = ((x1 - x0) & ~3); - sseend = x0 + ssecount; - - __m128 mworldnormalX = _mm_set1_ps(worldnormalX); - __m128 mworldnormalY = _mm_set1_ps(worldnormalY); - __m128 mworldnormalZ = _mm_set1_ps(worldnormalZ); - - for (int x = x0; x < sseend; x += 4) - { - __m128i lit = _mm_loadu_si128((__m128i*)&lightarray[x]); - __m128i litlo = _mm_unpacklo_epi8(lit, _mm_setzero_si128()); - __m128i lithi = _mm_unpackhi_epi8(lit, _mm_setzero_si128()); - - for (int i = 0; i < num_lights; i++) - { - __m128 lightposX = _mm_set1_ps(lights[i].x); - __m128 lightposY = _mm_set1_ps(lights[i].y); - __m128 lightposZ = _mm_set1_ps(lights[i].z); - __m128 light_radius = _mm_set1_ps(lights[i].radius); - __m128i light_color = _mm_shuffle_epi32(_mm_unpacklo_epi8(_mm_cvtsi32_si128(lights[i].color), _mm_setzero_si128()), _MM_SHUFFLE(1, 0, 1, 0)); - - __m128 is_attenuated = _mm_cmplt_ps(light_radius, _mm_setzero_ps()); - light_radius = _mm_andnot_ps(_mm_set1_ps(-0.0f), light_radius); // clear sign bit - - // L = light-pos - // dist = sqrt(dot(L, L)) - // distance_attenuation = 1 - min(dist * (1/radius), 1) - __m128 Lx = _mm_sub_ps(lightposX, _mm_loadu_ps(&worldposX[x])); - __m128 Ly = _mm_sub_ps(lightposY, _mm_loadu_ps(&worldposY[x])); - __m128 Lz = _mm_sub_ps(lightposZ, _mm_loadu_ps(&worldposZ[x])); - __m128 dist2 = _mm_add_ps(_mm_mul_ps(Lx, Lx), _mm_add_ps(_mm_mul_ps(Ly, Ly), _mm_mul_ps(Lz, Lz))); - __m128 rcp_dist = _mm_rsqrt_ps(dist2); - __m128 dist = _mm_mul_ps(dist2, rcp_dist); - __m128 distance_attenuation = _mm_sub_ps(_mm_set1_ps(256.0f), _mm_min_ps(_mm_mul_ps(dist, light_radius), _mm_set1_ps(256.0f))); - - // The simple light type - __m128 simple_attenuation = distance_attenuation; - - // The point light type - // diffuse = max(dot(N,normalize(L)),0) * attenuation - Lx = _mm_mul_ps(Lx, rcp_dist); - Ly = _mm_mul_ps(Ly, rcp_dist); - Lz = _mm_mul_ps(Lz, rcp_dist); - __m128 dotNL = _mm_add_ps(_mm_add_ps(_mm_mul_ps(mworldnormalX, Lx), _mm_mul_ps(mworldnormalY, Ly)), _mm_mul_ps(mworldnormalZ, Lz)); - __m128 point_attenuation = _mm_mul_ps(_mm_max_ps(dotNL, _mm_setzero_ps()), distance_attenuation); - - __m128i attenuation = _mm_cvtps_epi32(_mm_or_ps(_mm_and_ps(is_attenuated, point_attenuation), _mm_andnot_ps(is_attenuated, simple_attenuation))); - - attenuation = _mm_shufflehi_epi16(_mm_shufflelo_epi16(attenuation, _MM_SHUFFLE(2, 2, 0, 0)), _MM_SHUFFLE(2, 2, 0, 0)); - __m128i attenlo = _mm_shuffle_epi32(attenuation, _MM_SHUFFLE(1, 1, 0, 0)); - __m128i attenhi = _mm_shuffle_epi32(attenuation, _MM_SHUFFLE(3, 3, 2, 2)); - - litlo = _mm_add_epi16(litlo, _mm_srli_epi16(_mm_mullo_epi16(light_color, attenlo), 8)); - lithi = _mm_add_epi16(lithi, _mm_srli_epi16(_mm_mullo_epi16(light_color, attenhi), 8)); - } - - _mm_storeu_si128((__m128i*)&lightarray[x], _mm_packus_epi16(litlo, lithi)); - } -#endif - - for (int x = sseend; x < x1; x++) - { - uint32_t lit_a = APART(lightarray[x]); - uint32_t lit_r = RPART(lightarray[x]); - uint32_t lit_g = GPART(lightarray[x]); - uint32_t lit_b = BPART(lightarray[x]); - - for (int i = 0; i < num_lights; i++) - { - float lightposX = lights[i].x; - float lightposY = lights[i].y; - float lightposZ = lights[i].z; - float light_radius = lights[i].radius; - uint32_t light_color = lights[i].color; - - 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) - float Lx = lightposX - worldposX[x]; - float Ly = lightposY - worldposY[x]; - float Lz = lightposZ - worldposZ[x]; - float dist2 = Lx * Lx + Ly * Ly + Lz * Lz; -#ifdef NO_SSE - //float rcp_dist = 1.0f / sqrt(dist2); - float rcp_dist = 1.0f / (dist2 * 0.01f); -#else - float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(dist2))); -#endif - 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 - Lx *= rcp_dist; - Ly *= rcp_dist; - Lz *= rcp_dist; - float dotNL = worldnormalX * Lx + worldnormalY * Ly + worldnormalZ * Lz; - float point_attenuation = max(dotNL, 0.0f) * distance_attenuation; - - uint32_t attenuation = (uint32_t)(is_attenuated ? (int32_t)point_attenuation : (int32_t)simple_attenuation); - - lit_r += (RPART(light_color) * attenuation) >> 8; - lit_g += (GPART(light_color) * attenuation) >> 8; - lit_b += (BPART(light_color) * attenuation) >> 8; - } - - lit_r = min(lit_r, 255); - lit_g = min(lit_g, 255); - lit_b = min(lit_b, 255); - lightarray[x] = MAKEARGB(lit_a, lit_r, lit_g, lit_b); - - // Palette version: - // dynlights[x] = RGB256k.All[((lit_r >> 2) << 12) | ((lit_g >> 2) << 6) | (lit_b >> 2)]; - } -} - -static void WriteLightArray(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - auto constants = thread->PushConstants; - - auto vColorR = thread->scanline.vColorR; - auto vColorG = thread->scanline.vColorG; - auto vColorB = thread->scanline.vColorB; - auto vColorA = thread->scanline.vColorA; - - if (thread->PushConstants->uLightLevel >= 0.0f) - { - float startX = x0 + (0.5f - args->v1->x); - float startY = y + (0.5f - args->v1->y); - float posW = args->v1->w + args->gradientX.W * startX + args->gradientY.W * startY; - float stepW = args->gradientX.W; - - float globVis = thread->mainVertexShader.Viewpoint->mGlobVis; - - uint32_t light = (int)(constants->uLightLevel * 255.0f); - fixed_t shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); - fixed_t lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); - fixed_t lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); - - fixed_t maxvis = 24 * FRACUNIT / 32; - fixed_t maxlight = 31 * FRACUNIT / 32; - - fixed_t lightend = lightpos + lightstep * (x1 - x0); - if (lightpos < maxvis && shade >= lightpos && shade - lightpos <= maxlight && - lightend < maxvis && shade >= lightend && shade - lightend <= maxlight) - { - lightpos += FRACUNIT - shade; - uint32_t* lightarray = thread->scanline.lightarray; - for (int x = x0; x < x1; x++) - { - uint32_t l = min(lightpos >> 8, 256); - - uint32_t r = vColorR[x]; - uint32_t g = vColorG[x]; - uint32_t b = vColorB[x]; - uint32_t a = vColorA[x]; - - // [GEC] DynLightColor On Sprite - r = (r * l) >> 8; - g = (g * l) >> 8; - b = (b * l) >> 8; - - if (constants->uLightIndex == -1) - { - r += (uint32_t)(constants->uDynLightColor.X * 255.0f); - g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); - b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - - r = min(r, 255); - g = min(g, 255); - b = min(b, 255); - } - - lightarray[x] = MAKEARGB(a, r, g, b); - lightpos += lightstep; - } - } - else - { - uint32_t* lightarray = thread->scanline.lightarray; - for (int x = x0; x < x1; x++) - { - uint32_t l = min((FRACUNIT - clamp(shade - min(maxvis, lightpos), 0, maxlight)) >> 8, 256); - uint32_t r = vColorR[x]; - uint32_t g = vColorG[x]; - uint32_t b = vColorB[x]; - uint32_t a = vColorA[x]; - - // [GEC] DynLightColor On Sprite - r = (r * l) >> 8; - g = (g * l) >> 8; - b = (b * l) >> 8; - - if (constants->uLightIndex == -1) - { - r += (uint32_t)(constants->uDynLightColor.X * 255.0f); - g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); - b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - - r = min(r, 255); - g = min(g, 255); - b = min(b, 255); - } - - lightarray[x] = MAKEARGB(a, r, g, b); - lightpos += lightstep; - } - } - } - else if (constants->uFogEnabled > 0) - { - float uLightDist = constants->uLightDist; - float uLightFactor = constants->uLightFactor; - float* w = thread->scanline.W; - uint32_t* lightarray = thread->scanline.lightarray; - for (int x = x0; x < x1; x++) - { - uint32_t a = thread->scanline.vColorA[x]; - uint32_t r = thread->scanline.vColorR[x]; - uint32_t g = thread->scanline.vColorG[x]; - uint32_t b = thread->scanline.vColorB[x]; - - float fogdist = max(16.0f, w[x]); - float fogfactor = std::exp2(constants->uFogDensity * fogdist); - - // brightening around the player for light mode 2: - if (fogdist < uLightDist) - { - uint32_t l = (int)((uLightFactor - (fogdist / uLightDist) * (uLightFactor - 1.0)) * 256.0f); - r = (r * l) >> 8; - g = (g * l) >> 8; - b = (b * l) >> 8; - } - - // apply light diminishing through fog equation: mix(vec3(0.0, 0.0, 0.0), lightshade.rgb, fogfactor) - uint32_t t = (int)(fogfactor * 256.0f); - r = (r * t) >> 8; - g = (g * t) >> 8; - b = (b * t) >> 8; - - lightarray[x] = MAKEARGB(a, r, g, b); - } - } - else - { - uint32_t* lightarray = thread->scanline.lightarray; - for (int x = x0; x < x1; x++) - { - uint32_t a = thread->scanline.vColorA[x]; - uint32_t r = thread->scanline.vColorR[x]; - uint32_t g = thread->scanline.vColorG[x]; - uint32_t b = thread->scanline.vColorB[x]; - - // [GEC] DynLightColor On Weapon - if (constants->uLightIndex == -1) - { - r += (uint32_t)(constants->uDynLightColor.X * 255.0f); - g += (uint32_t)(constants->uDynLightColor.Y * 255.0f); - b += (uint32_t)(constants->uDynLightColor.Z * 255.0f); - - r = min(r, 255); - g = min(g, 255); - b = min(b, 255); - } - - lightarray[x] = MAKEARGB(a, r, g, b); - } - } -} - -#ifdef NO_SSE -static void WriteVarying(float pos, float step, int x0, int x1, const float* w, float* varying) -{ - for (int x = x0; x < x1; x++) - { - varying[x] = pos * w[x]; - pos += step; - } -} -#else -static void WriteVarying(float pos, float step, int x0, int x1, const float* w, float* varying) -{ - int ssecount = ((x1 - x0) & ~3); - int sseend = x0 + ssecount; - - __m128 mstep = _mm_set1_ps(step * 4.0f); - __m128 mpos = _mm_setr_ps(pos, pos + step, pos + step + step, pos + step + step + step); - - for (int x = x0; x < sseend; x += 4) - { - _mm_storeu_ps(varying + x, _mm_mul_ps(mpos, _mm_loadu_ps(w + x))); - mpos = _mm_add_ps(mpos, mstep); - } - - pos += ssecount * step; - for (int x = sseend; x < x1; x++) - { - varying[x] = pos * w[x]; - pos += step; - } -} -#endif - -#ifdef NO_SSE -static void WriteVaryingWrap(float pos, float step, int x0, int x1, const float* w, uint16_t* varying) -{ - for (int x = x0; x < x1; x++) - { - float value = pos * w[x]; - value = value - std::floor(value); - varying[x] = static_cast(static_cast(value * static_cast(0x1000'0000)) << 4) >> 16; - pos += step; - } -} -#else -static void WriteVaryingWrap(float pos, float step, int x0, int x1, const float* w, uint16_t* varying) -{ - int ssecount = ((x1 - x0) & ~3); - int sseend = x0 + ssecount; - - __m128 mstep = _mm_set1_ps(step * 4.0f); - __m128 mpos = _mm_setr_ps(pos, pos + step, pos + step + step, pos + step + step + step); - - for (int x = x0; x < sseend; x += 4) - { - __m128 value = _mm_mul_ps(mpos, _mm_loadu_ps(w + x)); - __m128 f = value; - __m128 t = _mm_cvtepi32_ps(_mm_cvttps_epi32(f)); - __m128 r = _mm_sub_ps(t, _mm_and_ps(_mm_cmplt_ps(f, t), _mm_set1_ps(1.0f))); - value = _mm_sub_ps(f, r); - - __m128i ivalue = _mm_srli_epi32(_mm_slli_epi32(_mm_cvttps_epi32(_mm_mul_ps(value, _mm_set1_ps(static_cast(0x1000'0000)))), 4), 17); - _mm_storel_epi64((__m128i*)(varying + x), _mm_slli_epi16(_mm_packs_epi32(ivalue, ivalue), 1)); - mpos = _mm_add_ps(mpos, mstep); - } - - pos += ssecount * step; - for (int x = sseend; x < x1; x++) - { - float value = pos * w[x]; - __m128 f = _mm_set_ss(value); - __m128 t = _mm_cvtepi32_ps(_mm_cvttps_epi32(f)); - __m128 r = _mm_sub_ss(t, _mm_and_ps(_mm_cmplt_ps(f, t), _mm_set_ss(1.0f))); - value = _mm_cvtss_f32(_mm_sub_ss(f, r)); - - varying[x] = static_cast(static_cast(value * static_cast(0x1000'0000)) << 4) >> 16; - pos += step; - } -} -#endif - -static void WriteVaryingWarp1(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread) -{ - float pi2 = 3.14159265358979323846f * 2.0f; - float timer = thread->mainVertexShader.Data.timer * 0.125f; - - const float* w = thread->scanline.W; - uint16_t* scanlineU = thread->scanline.U; - uint16_t* scanlineV = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - float u = posU * w[x]; - float v = posV * w[x]; - - v += (float)g_sin(pi2 * (u + timer)) * 0.1f; - u += (float)g_sin(pi2 * (v + timer)) * 0.1f; - - u = u - std::floor(u); - v = v - std::floor(v); - scanlineU[x] = static_cast(static_cast(u * static_cast(0x1000'0000)) << 4) >> 16; - scanlineV[x] = static_cast(static_cast(v * static_cast(0x1000'0000)) << 4) >> 16; - - posU += stepU; - posV += stepV; - } -} - -static void WriteVaryingWarp2(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread) -{ - float pi2 = 3.14159265358979323846f * 2.0f; - float timer = thread->mainVertexShader.Data.timer; - - const float* w = thread->scanline.W; - uint16_t* scanlineU = thread->scanline.U; - uint16_t* scanlineV = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - float u = posU * w[x]; - float v = posV * w[x]; - - v += (0.5f + (float)g_sin(pi2 * (v + timer * 0.61f + 900.f/8192.f)) + (float)g_sin(pi2 * (u * 2.0f + timer * 0.36f + 300.0f/8192.0f))) * 0.025f; - u += (0.5f + (float)g_sin(pi2 * (v + timer * 0.49f + 700.f/8192.f)) + (float)g_sin(pi2 * (u * 2.0f + timer * 0.49f + 1200.0f/8192.0f))) * 0.025f; - - u = u - std::floor(u); - v = v - std::floor(v); - scanlineU[x] = static_cast(static_cast(u * static_cast(0x1000'0000)) << 4) >> 16; - scanlineV[x] = static_cast(static_cast(v * static_cast(0x1000'0000)) << 4) >> 16; - - posU += stepU; - posV += stepV; - } -} - -#ifdef NO_SSE -static void WriteVaryingColor(float pos, float step, int x0, int x1, const float* w, uint8_t* varying) -{ - for (int x = x0; x < x1; x++) - { - varying[x] = clamp(static_cast(pos * w[x] * 255.0f), 0, 255); - pos += step; - } -} -#else -static void WriteVaryingColor(float pos, float step, int x0, int x1, const float* w, uint8_t* varying) -{ - int ssecount = ((x1 - x0) & ~3); - int sseend = x0 + ssecount; - - __m128 mstep = _mm_set1_ps(step * 4.0f); - __m128 mpos = _mm_setr_ps(pos, pos + step, pos + step + step, pos + step + step + step); - - for (int x = x0; x < sseend; x += 4) - { - __m128i value = _mm_cvttps_epi32(_mm_mul_ps(_mm_mul_ps(mpos, _mm_loadu_ps(w + x)), _mm_set1_ps(255.0f))); - value = _mm_packs_epi32(value, value); - value = _mm_packus_epi16(value, value); - *(uint32_t*)(varying + x) = _mm_cvtsi128_si32(value); - mpos = _mm_add_ps(mpos, mstep); - } - - pos += ssecount * step; - for (int x = sseend; x < x1; x++) - { - varying[x] = clamp(static_cast(pos * w[x] * 255.0f), 0, 255); - pos += step; - } -} -#endif - -void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - float startX = x0 + (0.5f - args->v1->x); - float startY = y + (0.5f - args->v1->y); - - void (*useShader)(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread) = nullptr; - - if (thread->EffectState == SHADER_Warp1) - useShader = &WriteVaryingWarp1; - else if (thread->EffectState == SHADER_Warp2) - useShader = &WriteVaryingWarp2; - - if (useShader) - { - useShader( - args->v1->u * args->v1->w + args->gradientX.U * startX + args->gradientY.U * startY, - args->v1->v * args->v1->w + args->gradientX.V * startX + args->gradientY.V * startY, - args->gradientX.U, - args->gradientX.V, - x0, x1, - thread); - } - else - { - WriteVaryingWrap(args->v1->u * args->v1->w + args->gradientX.U * startX + args->gradientY.U * startY, args->gradientX.U, x0, x1, thread->scanline.W, thread->scanline.U); - WriteVaryingWrap(args->v1->v * args->v1->w + args->gradientX.V * startX + args->gradientY.V * startY, args->gradientX.V, x0, x1, thread->scanline.W, thread->scanline.V); - } - WriteVarying(args->v1->worldX * args->v1->w + args->gradientX.WorldX * startX + args->gradientY.WorldX * startY, args->gradientX.WorldX, x0, x1, thread->scanline.W, thread->scanline.WorldX); - WriteVarying(args->v1->worldY * args->v1->w + args->gradientX.WorldY * startX + args->gradientY.WorldY * startY, args->gradientX.WorldY, x0, x1, thread->scanline.W, thread->scanline.WorldY); - WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ); - WriteVarying(args->v1->gradientdistZ * args->v1->w + args->gradientX.GradientdistZ * startX + args->gradientY.GradientdistZ * startY, args->gradientX.GradientdistZ, x0, x1, thread->scanline.W, thread->scanline.GradientdistZ); - WriteVaryingColor(args->v1->a * args->v1->w + args->gradientX.A * startX + args->gradientY.A * startY, args->gradientX.A, x0, x1, thread->scanline.W, thread->scanline.vColorA); - WriteVaryingColor(args->v1->r * args->v1->w + args->gradientX.R * startX + args->gradientY.R * startY, args->gradientX.R, x0, x1, thread->scanline.W, thread->scanline.vColorR); - WriteVaryingColor(args->v1->g * args->v1->w + args->gradientX.G * startX + args->gradientY.G * startY, args->gradientX.G, x0, x1, thread->scanline.W, thread->scanline.vColorG); - WriteVaryingColor(args->v1->b * args->v1->w + args->gradientX.B * startX + args->gradientY.B * startY, args->gradientX.B, x0, x1, thread->scanline.W, thread->scanline.vColorB); - - if (thread->PushConstants->uFogEnabled != -3 && thread->PushConstants->uTextureMode != TM_FOGLAYER) - WriteLightArray(y, x0, x1, args, thread); - - if (thread->numPolyLights > 0) - WriteDynLightArray(x0, x1, thread); -} diff --git a/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.h b/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.h deleted file mode 100644 index 5ea66cf96..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_scanline_setup.h +++ /dev/null @@ -1,29 +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 - -struct TriDrawTriangleArgs; -class PolyTriangleThreadData; - -void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread); -void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread); diff --git a/src/common/rendering/polyrenderer/drawers/screen_shader.cpp b/src/common/rendering/polyrenderer/drawers/screen_shader.cpp deleted file mode 100644 index 66c4e6ffb..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_shader.cpp +++ /dev/null @@ -1,637 +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. -** -*/ - -#include -#include "poly_thread.h" -#include "screen_scanline_setup.h" -#include - -static uint32_t SampleTexture(uint32_t u, uint32_t v, const void* texPixels, int texWidth, int texHeight, bool texBgra) -{ - int texelX = (u * texWidth) >> 16; - int texelY = (v * texHeight) >> 16; - int texelOffset = texelX + texelY * texWidth; - if (texBgra) - { - return static_cast(texPixels)[texelOffset]; - } - else - { - uint32_t c = static_cast(texPixels)[texelOffset]; - return (c << 16) | 0xff000000; - } -} - -static void EffectFogBoundary(int x0, int x1, PolyTriangleThreadData* thread) -{ - float uFogDensity = thread->PushConstants->uFogDensity; - uint32_t fogcolor = MAKEARGB( - 0, - static_cast(clamp(thread->mainVertexShader.Data.uFogColor.r, 0.0f, 1.0f) * 255.0f), - static_cast(clamp(thread->mainVertexShader.Data.uFogColor.g, 0.0f, 1.0f) * 255.0f), - static_cast(clamp(thread->mainVertexShader.Data.uFogColor.b, 0.0f, 1.0f) * 255.0f)); - - uint32_t* fragcolor = thread->scanline.FragColor; - for (int x = x0; x < x1; x++) - { - float fogdist = thread->scanline.W[x]; - float fogfactor = std::exp2(uFogDensity * fogdist); - - // FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor): - uint32_t alpha = static_cast(clamp(1.0f - (1.0f / 255.0f), 0.0f, 1.0f) * 255.0f); - fragcolor[x] = fogcolor | alpha; - } -} - -static void EffectBurn(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - - int tex2Width = thread->textures[1].width; - int tex2Height = thread->textures[1].height; - const void* tex2Pixels = thread->textures[1].pixels; - bool tex2Bgra = thread->textures[1].bgra; - - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - for (int x = x0; x < x1; x++) - { - uint32_t frag_r = thread->scanline.vColorR[x]; - uint32_t frag_g = thread->scanline.vColorG[x]; - uint32_t frag_b = thread->scanline.vColorB[x]; - uint32_t frag_a = thread->scanline.vColorA[x]; - frag_r += frag_r >> 7; // 255 -> 256 - frag_g += frag_g >> 7; // 255 -> 256 - frag_b += frag_b >> 7; // 255 -> 256 - frag_a += frag_a >> 7; // 255 -> 256 - - uint32_t t1 = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - uint32_t t2 = SampleTexture(u[x], 0xffff - v[x], tex2Pixels, tex2Width, tex2Height, tex2Bgra); - - uint32_t r = (frag_r * RPART(t1)) >> 8; - uint32_t g = (frag_g * GPART(t1)) >> 8; - uint32_t b = (frag_b * BPART(t1)) >> 8; - uint32_t a = (frag_a * APART(t2)) >> 8; - - fragcolor[x] = MAKEARGB(a, r, g, b); - } -} - -static void EffectStencil(int x0, int x1, PolyTriangleThreadData* thread) -{ - /*for (int x = x0; x < x1; x++) - { - fragcolor[x] = 0x00ffffff; - }*/ -} - -static void FuncPaletted(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - const uint32_t* lut = (const uint32_t*)thread->textures[1].pixels; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - fragcolor[x] = lut[RPART(SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra))] | 0xff000000; - } -} - -static void FuncNoTexture(int x0, int x1, PolyTriangleThreadData* thread) -{ - auto& streamdata = thread->mainVertexShader.Data; - uint32_t a = (int)(streamdata.uObjectColor.a * 255.0f); - uint32_t r = (int)(streamdata.uObjectColor.r * 255.0f); - uint32_t g = (int)(streamdata.uObjectColor.g * 255.0f); - uint32_t b = (int)(streamdata.uObjectColor.b * 255.0f); - uint32_t texel = MAKEARGB(a, r, g, b); - - if (streamdata.uDesaturationFactor > 0.0f) - { - uint32_t t = (int)(streamdata.uDesaturationFactor * 256.0f); - uint32_t inv_t = 256 - t; - uint32_t gray = (RPART(texel) * 77 + GPART(texel) * 143 + BPART(texel) * 37) >> 8; - texel = MAKEARGB( - APART(texel), - (RPART(texel) * inv_t + gray * t + 127) >> 8, - (GPART(texel) * inv_t + gray * t + 127) >> 8, - (BPART(texel) * inv_t + gray * t + 127) >> 8); - } - - uint32_t* fragcolor = thread->scanline.FragColor; - for (int x = x0; x < x1; x++) - { - fragcolor[x] = texel; - } -} - -static void FuncNormal(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - fragcolor[x] = texel; - } -} - -static void FuncNormal_Stencil(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - fragcolor[x] = texel | 0x00ffffff; - } -} - -static void FuncNormal_Opaque(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - fragcolor[x] = texel | 0xff000000; - } -} - -static void FuncNormal_Inverse(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - fragcolor[x] = MAKEARGB(APART(texel), 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); - } -} - -static void FuncNormal_AlphaTexture(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - uint32_t gray = (RPART(texel) * 77 + GPART(texel) * 143 + BPART(texel) * 37) >> 8; - uint32_t alpha = APART(texel); - alpha += alpha >> 7; - alpha = (alpha * gray + 127) >> 8; - texel = (alpha << 24) | 0x00ffffff; - fragcolor[x] = texel; - } -} - -static void FuncNormal_ClampY(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - fragcolor[x] = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - if (v[x] < 0.0 || v[x] > 1.0) - fragcolor[x] &= 0x00ffffff; - } -} - -static void FuncNormal_InvertOpaque(int x0, int x1, PolyTriangleThreadData* thread) -{ - int texWidth = thread->textures[0].width; - int texHeight = thread->textures[0].height; - const void* texPixels = thread->textures[0].pixels; - bool texBgra = thread->textures[0].bgra; - uint32_t* fragcolor = thread->scanline.FragColor; - uint16_t* u = thread->scanline.U; - uint16_t* v = thread->scanline.V; - - for (int x = x0; x < x1; x++) - { - uint32_t texel = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - fragcolor[x] = MAKEARGB(0xff, 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); - } -} - -static void FuncNormal_AddColor(int x0, int x1, PolyTriangleThreadData* thread) -{ - auto& streamdata = thread->mainVertexShader.Data; - uint32_t r = (int)(streamdata.uAddColor.r * 255.0f); - uint32_t g = (int)(streamdata.uAddColor.g * 255.0f); - uint32_t b = (int)(streamdata.uAddColor.b * 255.0f); - uint32_t* fragcolor = thread->scanline.FragColor; - for (int x = x0; x < x1; x++) - { - uint32_t texel = fragcolor[x]; - fragcolor[x] = MAKEARGB( - APART(texel), - min(r + RPART(texel), (uint32_t)255), - min(g + GPART(texel), (uint32_t)255), - min(b + BPART(texel), (uint32_t)255)); - } -} - -static void FuncNormal_AddObjectColor(int x0, int x1, PolyTriangleThreadData* thread) -{ - auto& streamdata = thread->mainVertexShader.Data; - uint32_t r = (int)(streamdata.uObjectColor.r * 256.0f); - uint32_t g = (int)(streamdata.uObjectColor.g * 256.0f); - uint32_t b = (int)(streamdata.uObjectColor.b * 256.0f); - uint32_t* fragcolor = thread->scanline.FragColor; - for (int x = x0; x < x1; x++) - { - uint32_t texel = fragcolor[x]; - fragcolor[x] = MAKEARGB( - APART(texel), - min((r * RPART(texel)) >> 8, (uint32_t)255), - min((g * GPART(texel)) >> 8, (uint32_t)255), - min((b * BPART(texel)) >> 8, (uint32_t)255)); - } -} - -static void FuncNormal_AddObjectColor2(int x0, int x1, PolyTriangleThreadData* thread) -{ - auto& streamdata = thread->mainVertexShader.Data; - float* gradientdistZ = thread->scanline.GradientdistZ; - uint32_t* fragcolor = thread->scanline.FragColor; - for (int x = x0; x < x1; x++) - { - float t = gradientdistZ[x]; - float inv_t = 1.0f - t; - uint32_t r = (int)((streamdata.uObjectColor.r * inv_t + streamdata.uObjectColor2.r * t) * 256.0f); - uint32_t g = (int)((streamdata.uObjectColor.g * inv_t + streamdata.uObjectColor2.g * t) * 256.0f); - uint32_t b = (int)((streamdata.uObjectColor.b * inv_t + streamdata.uObjectColor2.b * t) * 256.0f); - - uint32_t texel = fragcolor[x]; - fragcolor[x] = MAKEARGB( - APART(texel), - min((r * RPART(texel)) >> 8, (uint32_t)255), - min((g * GPART(texel)) >> 8, (uint32_t)255), - min((b * BPART(texel)) >> 8, (uint32_t)255)); - } -} - -static void FuncNormal_DesaturationFactor(int x0, int x1, PolyTriangleThreadData* thread) -{ - auto& streamdata = thread->mainVertexShader.Data; - uint32_t* fragcolor = thread->scanline.FragColor; - uint32_t t = (int)(streamdata.uDesaturationFactor * 256.0f); - uint32_t inv_t = 256 - t; - for (int x = x0; x < x1; x++) - { - uint32_t texel = fragcolor[x]; - uint32_t gray = (RPART(texel) * 77 + GPART(texel) * 143 + BPART(texel) * 37) >> 8; - fragcolor[x] = MAKEARGB( - APART(texel), - (RPART(texel) * inv_t + gray * t + 127) >> 8, - (GPART(texel) * inv_t + gray * t + 127) >> 8, - (BPART(texel) * inv_t + gray * t + 127) >> 8); - } -} - -static void RunAlphaTest(int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t alphaThreshold = thread->AlphaThreshold; - uint32_t* fragcolor = thread->scanline.FragColor; - uint8_t* discard = thread->scanline.discard; - for (int x = x0; x < x1; x++) - { - discard[x] = fragcolor[x] <= alphaThreshold; - } -} - -static void ProcessMaterial(int x0, int x1, PolyTriangleThreadData* thread) -{ - if (thread->EffectState == SHADER_Paletted) // func_paletted - { - FuncPaletted(x0, x1, thread); - } - else if (thread->EffectState == SHADER_NoTexture) // func_notexture - { - FuncNoTexture(x0, x1, thread); - } - else // func_normal - { - auto constants = thread->PushConstants; - - switch (constants->uTextureMode) - { - default: - case TM_NORMAL: - case TM_FOGLAYER: FuncNormal(x0, x1, thread); break; - case TM_STENCIL: FuncNormal_Stencil(x0, x1, thread); break; - case TM_OPAQUE: FuncNormal_Opaque(x0, x1, thread); break; - case TM_INVERSE: FuncNormal_Inverse(x0, x1, thread); break; - case TM_ALPHATEXTURE: FuncNormal_AlphaTexture(x0, x1, thread); break; - case TM_CLAMPY: FuncNormal_ClampY(x0, x1, thread); break; - case TM_INVERTOPAQUE: FuncNormal_InvertOpaque(x0, x1, thread); break; - } - - if (constants->uTextureMode != TM_FOGLAYER) - { - auto& streamdata = thread->mainVertexShader.Data; - - if (streamdata.uAddColor.r != 0.0f || streamdata.uAddColor.g != 0.0f || streamdata.uAddColor.b != 0.0f) - { - FuncNormal_AddColor(x0, x1, thread); - } - - if (streamdata.uObjectColor2.a == 0.0f) - { - if (streamdata.uObjectColor.r != 1.0f || streamdata.uObjectColor.g != 1.0f || streamdata.uObjectColor.b != 1.0f) - { - FuncNormal_AddObjectColor(x0, x1, thread); - } - } - else - { - FuncNormal_AddObjectColor2(x0, x1, thread); - } - - if (streamdata.uDesaturationFactor > 0.0f) - { - FuncNormal_DesaturationFactor(x0, x1, thread); - } - } - } -} - -static void GetLightColor(int x0, int x1, PolyTriangleThreadData* thread) -{ - uint32_t* fragcolor = thread->scanline.FragColor; - uint32_t* lightarray = thread->scanline.lightarray; - - if (thread->PushConstants->uFogEnabled >= 0) - { - for (int x = x0; x < x1; x++) - { - uint32_t fg = fragcolor[x]; - uint32_t lightshade = lightarray[x]; - - uint32_t mulA = APART(lightshade); - uint32_t mulR = RPART(lightshade); - uint32_t mulG = GPART(lightshade); - uint32_t mulB = BPART(lightshade); - mulA += mulA >> 7; - mulR += mulR >> 7; - mulG += mulG >> 7; - mulB += mulB >> 7; - - uint32_t a = (APART(fg) * mulA + 127) >> 8; - uint32_t r = (RPART(fg) * mulR + 127) >> 8; - uint32_t g = (GPART(fg) * mulG + 127) >> 8; - uint32_t b = (BPART(fg) * mulB + 127) >> 8; - - fragcolor[x] = MAKEARGB(a, r, g, b); - } - } - else - { - uint32_t fogR = (int)((thread->mainVertexShader.Data.uFogColor.r) * 255.0f); - uint32_t fogG = (int)((thread->mainVertexShader.Data.uFogColor.g) * 255.0f); - uint32_t fogB = (int)((thread->mainVertexShader.Data.uFogColor.b) * 255.0f); - float uFogDensity = thread->PushConstants->uFogDensity; - - float* w = thread->scanline.W; - for (int x = x0; x < x1; x++) - { - uint32_t fg = fragcolor[x]; - uint32_t lightshade = lightarray[x]; - - uint32_t mulA = APART(lightshade); - uint32_t mulR = RPART(lightshade); - uint32_t mulG = GPART(lightshade); - uint32_t mulB = BPART(lightshade); - mulA += mulA >> 7; - mulR += mulR >> 7; - mulG += mulG >> 7; - mulB += mulB >> 7; - - float fogdist = max(16.0f, w[x]); - float fogfactor = std::exp2(uFogDensity * fogdist); - - uint32_t a = (APART(fg) * mulA + 127) >> 8; - uint32_t r = (RPART(fg) * mulR + 127) >> 8; - uint32_t g = (GPART(fg) * mulG + 127) >> 8; - uint32_t b = (BPART(fg) * mulB + 127) >> 8; - - uint32_t t = (int)(fogfactor * 256.0f); - uint32_t inv_t = 256 - t; - r = (fogR * inv_t + r * t + 127) >> 8; - g = (fogG * inv_t + g * t + 127) >> 8; - b = (fogB * inv_t + b * t + 127) >> 8; - - fragcolor[x] = MAKEARGB(a, r, g, b); - } - } -} - -static void MainFP(int x0, int x1, PolyTriangleThreadData* thread) -{ - ProcessMaterial(x0, x1, thread); - - if (thread->AlphaTest) - RunAlphaTest(x0, x1, thread); - - auto constants = thread->PushConstants; - if (constants->uFogEnabled != -3) - { - if (constants->uTextureMode != TM_FOGLAYER) - { - GetLightColor(x0, x1, thread); - } - else - { - /*float fogdist = 0.0f; - float fogfactor = 0.0f; - if (constants->uFogEnabled != 0) - { - fogdist = max(16.0f, w[x]); - fogfactor = std::exp2(constants->uFogDensity * fogdist); - } - frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a);*/ - } - } - else // simple 2D (uses the fog color to add a color overlay) - { - uint32_t fogR = (int)((thread->mainVertexShader.Data.uFogColor.r) * 255.0f); - uint32_t fogG = (int)((thread->mainVertexShader.Data.uFogColor.g) * 255.0f); - uint32_t fogB = (int)((thread->mainVertexShader.Data.uFogColor.b) * 255.0f); - - auto vColorR = thread->scanline.vColorR; - auto vColorG = thread->scanline.vColorG; - auto vColorB = thread->scanline.vColorB; - auto vColorA = thread->scanline.vColorA; - uint32_t* fragcolor = thread->scanline.FragColor; - - if (constants->uTextureMode == TM_FIXEDCOLORMAP) - { - // float gray = grayscale(frag); - // vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2; - // frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); - // frag = frag * vColor; - // frag.rgb = frag.rgb + uFogColor.rgb; - - // [GEC] I leave the default floating values. - float startR = thread->mainVertexShader.Data.uObjectColor.r; - float startG = thread->mainVertexShader.Data.uObjectColor.g; - float startB = thread->mainVertexShader.Data.uObjectColor.b; - float rangeR = thread->mainVertexShader.Data.uAddColor.r - startR; - float rangeG = thread->mainVertexShader.Data.uAddColor.g - startG; - float rangeB = thread->mainVertexShader.Data.uAddColor.b - startB; - - for (int x = x0; x < x1; x++) - { - uint32_t a = APART(fragcolor[x]); - uint32_t r = RPART(fragcolor[x]); - uint32_t g = GPART(fragcolor[x]); - uint32_t b = BPART(fragcolor[x]); - - uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8; - gray += (gray >> 7); // gray*=256/255 - - // [GEC] I use the same method as in shaders using floating values. - // This avoids errors in the invulneravility colormap in Doom and Heretic. - float fgray = (float)(gray / 255.f); - float fr = (startR + (fgray * rangeR)) * 2; - float fg = (startG + (fgray * rangeG)) * 2; - float fb = (startB + (fgray * rangeB)) * 2; - - fr = clamp(fr, 0.0f, 1.0f); - fg = clamp(fg, 0.0f, 1.0f); - fb = clamp(fb, 0.0f, 1.0f); - - r = (uint32_t)(fr * 255.f); - g = (uint32_t)(fg * 255.f); - b = (uint32_t)(fb * 255.f); - - fragcolor[x] = MAKEARGB(a, (uint8_t)r, (uint8_t)g, (uint8_t)b); - } - } - else - { - for (int x = x0; x < x1; x++) - { - uint32_t a = vColorA[x]; - uint32_t r = vColorR[x]; - uint32_t g = vColorG[x]; - uint32_t b = vColorB[x]; - a += a >> 7; - r += r >> 7; - g += g >> 7; - b += b >> 7; - - // frag = frag * vColor; - a = (APART(fragcolor[x]) * a + 127) >> 8; - r = (RPART(fragcolor[x]) * r + 127) >> 8; - g = (GPART(fragcolor[x]) * g + 127) >> 8; - b = (BPART(fragcolor[x]) * b + 127) >> 8; - - // frag.rgb = frag.rgb + uFogColor.rgb; - r = min(r + fogR, (uint32_t)255); - g = min(g + fogG, (uint32_t)255); - b = min(b + fogB, (uint32_t)255); - - fragcolor[x] = MAKEARGB(a, r, g, b); - } - } - } -} - -void ColormapFP(int x0, int x1, PolyTriangleThreadData* thread) -{ - // This is implemented in BlendColorColormap. -} - -void SelectFragmentShader(PolyTriangleThreadData* thread) -{ - void (*fragshader)(int x0, int x1, PolyTriangleThreadData * thread); - - if (thread->ColormapShader) - { - fragshader = &ColormapFP; - } - else if (thread->SpecialEffect == EFF_FOGBOUNDARY) // fogboundary.fp - { - fragshader = &EffectFogBoundary; - } - else if (thread->SpecialEffect == EFF_BURN) // burn.fp - { - fragshader = &EffectBurn; - } - else if (thread->SpecialEffect == EFF_STENCIL) // stencil.fp - { - fragshader = &EffectStencil; - } - else - { - fragshader = &MainFP; - } - - thread->FragmentShader = fragshader; -} diff --git a/src/common/rendering/polyrenderer/drawers/screen_shader.h b/src/common/rendering/polyrenderer/drawers/screen_shader.h deleted file mode 100644 index 567b4d6c9..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_shader.h +++ /dev/null @@ -1,27 +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 - -class PolyTriangleThreadData; - -void SelectFragmentShader(PolyTriangleThreadData* thread); diff --git a/src/common/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/common/rendering/polyrenderer/drawers/screen_triangle.cpp deleted file mode 100644 index f30bc8bd2..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_triangle.cpp +++ /dev/null @@ -1,302 +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. -** -*/ - -#include - -#include "filesystem.h" -#include "v_video.h" -#include "poly_triangle.h" -#include "screen_triangle.h" -#include "screen_blend.h" -#include "screen_scanline_setup.h" -#include "screen_shader.h" -#include - -static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - float* line = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y; - - if (thread->DepthRangeScale != 0.0f) - { - float* w = thread->scanline.W; - for (int x = x0; x < x1; x++) - { - line[x] = w[x]; - } - } - else // portal fills always uses DepthRangeStart = 1 and DepthRangeScale = 0 - { - for (int x = x0; x < x1; x++) - { - line[x] = 65536.0f; - } - } -} - -static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread) -{ - uint8_t* line = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y; - uint8_t value = thread->StencilWriteValue; - for (int x = x0; x < x1; x++) - { - line[x] = value; - } -} - -static void RunFragmentShader(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - WriteVaryings(y, x0, x1, args, thread); - thread->FragmentShader(x0, x1, thread); -} - -static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - if (thread->WriteColor || thread->AlphaTest) - RunFragmentShader(y, x0, x1, args, thread); - - if (!thread->AlphaTest) - { - if (thread->WriteColor) - thread->WriteColorFunc(y, x0, x1, thread); - if (thread->WriteDepth) - WriteDepth(y, x0, x1, thread); - if (thread->WriteStencil) - WriteStencil(y, x0, x1, thread); - } - else - { - uint8_t* discard = thread->scanline.discard; - while (x0 < x1) - { - int xstart = x0; - while (!discard[x0] && x0 < x1) x0++; - - if (xstart < x0) - { - if (thread->WriteColor) - thread->WriteColorFunc(y, xstart, x0, thread); - if (thread->WriteDepth) - WriteDepth(y, xstart, x0, thread); - if (thread->WriteStencil) - WriteStencil(y, xstart, x0, thread); - } - - while (discard[x0] && x0 < x1) x0++; - } - } -} - -static void NoTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - WriteW(y, x0, x1, args, thread); - DrawSpan(y, x0, x1, args, thread); -} - -static void DepthTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - WriteW(y, x0, x1, args, thread); - - float* zbufferLine = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y; - float* w = thread->scanline.W; - float depthbias = thread->depthbias; - - int x = x0; - int xend = x1; - while (x < xend) - { - int xstart = x; - - while (zbufferLine[x] >= w[x] + depthbias && x < xend) - x++; - - if (x > xstart) - { - DrawSpan(y, xstart, x, args, thread); - } - - while (zbufferLine[x] < w[x] + depthbias && x < xend) - x++; - } -} - -static void DepthStencilTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - uint8_t* stencilLine = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y; - uint8_t stencilTestValue = thread->StencilTestValue; - - int x = x0; - int xend = x1; - while (x < xend) - { - int xstart = x; - while (stencilLine[x] == stencilTestValue && x < xend) - x++; - - if (x > xstart) - { - DepthTestSpan(y, xstart, x, args, thread); - } - - while (stencilLine[x] != stencilTestValue && x < xend) - x++; - } -} - -static void StencilTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - uint8_t* stencilLine = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y; - uint8_t stencilTestValue = thread->StencilTestValue; - - int x = x0; - int xend = x1; - while (x < xend) - { - int xstart = x; - while (stencilLine[x] == stencilTestValue && x < xend) - x++; - - if (x > xstart) - { - WriteW(y, x0, x1, args, thread); - DrawSpan(y, xstart, x, args, thread); - } - - while (stencilLine[x] != stencilTestValue && x < xend) - x++; - } -} - -static void SortVertices(const TriDrawTriangleArgs* args, ScreenTriVertex** sortedVertices) -{ - sortedVertices[0] = args->v1; - sortedVertices[1] = args->v2; - sortedVertices[2] = args->v3; - - if (sortedVertices[1]->y < sortedVertices[0]->y) - std::swap(sortedVertices[0], sortedVertices[1]); - if (sortedVertices[2]->y < sortedVertices[0]->y) - std::swap(sortedVertices[0], sortedVertices[2]); - if (sortedVertices[2]->y < sortedVertices[1]->y) - std::swap(sortedVertices[1], sortedVertices[2]); -} - -void ScreenTriangle::Draw(const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) -{ - // Sort vertices by Y position - ScreenTriVertex* sortedVertices[3]; - SortVertices(args, sortedVertices); - - int clipleft = thread->clip.left; - int cliptop = max(thread->clip.top, thread->numa_start_y); - int clipright = thread->clip.right; - int clipbottom = min(thread->clip.bottom, thread->numa_end_y); - - int topY = (int)(sortedVertices[0]->y + 0.5f); - int midY = (int)(sortedVertices[1]->y + 0.5f); - int bottomY = (int)(sortedVertices[2]->y + 0.5f); - - topY = max(topY, cliptop); - midY = min(midY, clipbottom); - bottomY = min(bottomY, clipbottom); - - if (topY >= bottomY) - return; - - SelectFragmentShader(thread); - SelectWriteColorFunc(thread); - - void(*testfunc)(int y, int x0, int x1, const TriDrawTriangleArgs * args, PolyTriangleThreadData * thread); - - int opt = 0; - if (thread->DepthTest) opt |= SWTRI_DepthTest; - if (thread->StencilTest) opt |= SWTRI_StencilTest; - testfunc = ScreenTriangle::TestSpanOpts[opt]; - - topY += thread->skipped_by_thread(topY); - int num_cores = thread->num_cores; - - // Find start/end X positions for each line covered by the triangle: - - int y = topY; - - float longDX = sortedVertices[2]->x - sortedVertices[0]->x; - float longDY = sortedVertices[2]->y - sortedVertices[0]->y; - float longStep = longDX / longDY; - float longPos = sortedVertices[0]->x + longStep * (y + 0.5f - sortedVertices[0]->y) + 0.5f; - longStep *= num_cores; - - if (y < midY) - { - float shortDX = sortedVertices[1]->x - sortedVertices[0]->x; - float shortDY = sortedVertices[1]->y - sortedVertices[0]->y; - float shortStep = shortDX / shortDY; - float shortPos = sortedVertices[0]->x + shortStep * (y + 0.5f - sortedVertices[0]->y) + 0.5f; - shortStep *= num_cores; - - while (y < midY) - { - int x0 = (int)shortPos; - int x1 = (int)longPos; - if (x1 < x0) std::swap(x0, x1); - x0 = clamp(x0, clipleft, clipright); - x1 = clamp(x1, clipleft, clipright); - - testfunc(y, x0, x1, args, thread); - - shortPos += shortStep; - longPos += longStep; - y += num_cores; - } - } - - if (y < bottomY) - { - float shortDX = sortedVertices[2]->x - sortedVertices[1]->x; - float shortDY = sortedVertices[2]->y - sortedVertices[1]->y; - float shortStep = shortDX / shortDY; - float shortPos = sortedVertices[1]->x + shortStep * (y + 0.5f - sortedVertices[1]->y) + 0.5f; - shortStep *= num_cores; - - while (y < bottomY) - { - int x0 = (int)shortPos; - int x1 = (int)longPos; - if (x1 < x0) std::swap(x0, x1); - x0 = clamp(x0, clipleft, clipright); - x1 = clamp(x1, clipleft, clipright); - - testfunc(y, x0, x1, args, thread); - - shortPos += shortStep; - longPos += longStep; - y += num_cores; - } - } -} - -void(*ScreenTriangle::TestSpanOpts[])(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) = -{ - &NoTestSpan, - &DepthTestSpan, - &StencilTestSpan, - &DepthStencilTestSpan -}; diff --git a/src/common/rendering/polyrenderer/drawers/screen_triangle.h b/src/common/rendering/polyrenderer/drawers/screen_triangle.h deleted file mode 100644 index db63f2547..000000000 --- a/src/common/rendering/polyrenderer/drawers/screen_triangle.h +++ /dev/null @@ -1,124 +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 -#include -#include -#include "renderstyle.h" -//#include "rendering/swrenderer/drawers/r_draw.h" - -class FString; -class PolyTriangleThreadData; - -struct ScreenTriVertex -{ - float x, y, z, w; - float u, v; - float worldX, worldY, worldZ; - float a, r, g, b; - float gradientdistZ; -}; - -struct ScreenTriangleStepVariables -{ - float W, U, V; - float WorldX, WorldY, WorldZ; - float A, R, G, B; - float GradientdistZ; -}; - -struct TriDrawTriangleArgs -{ - ScreenTriVertex *v1; - ScreenTriVertex *v2; - ScreenTriVertex *v3; - ScreenTriangleStepVariables gradientX; - ScreenTriangleStepVariables gradientY; - - bool CalculateGradients() - { - float bottomX = (v2->x - v3->x) * (v1->y - v3->y) - (v1->x - v3->x) * (v2->y - v3->y); - float bottomY = (v1->x - v3->x) * (v2->y - v3->y) - (v2->x - v3->x) * (v1->y - v3->y); - if ((bottomX >= -FLT_EPSILON && bottomX <= FLT_EPSILON) || (bottomY >= -FLT_EPSILON && bottomY <= FLT_EPSILON)) - return false; - - gradientX.W = FindGradientX(bottomX, 1.0f, 1.0f, 1.0f); - gradientX.U = FindGradientX(bottomX, v1->u, v2->u, v3->u); - gradientX.V = FindGradientX(bottomX, v1->v, v2->v, v3->v); - gradientX.WorldX = FindGradientX(bottomX, v1->worldX, v2->worldX, v3->worldX); - gradientX.WorldY = FindGradientX(bottomX, v1->worldY, v2->worldY, v3->worldY); - gradientX.WorldZ = FindGradientX(bottomX, v1->worldZ, v2->worldZ, v3->worldZ); - gradientX.A = FindGradientX(bottomX, v1->a, v2->a, v3->a); - gradientX.R = FindGradientX(bottomX, v1->r, v2->r, v3->r); - gradientX.G = FindGradientX(bottomX, v1->g, v2->g, v3->g); - gradientX.B = FindGradientX(bottomX, v1->b, v2->b, v3->b); - gradientX.GradientdistZ = FindGradientX(bottomX, v1->gradientdistZ, v2->gradientdistZ, v3->gradientdistZ); - - gradientY.W = FindGradientY(bottomY, 1.0f, 1.0f, 1.0f); - gradientY.U = FindGradientY(bottomY, v1->u, v2->u, v3->u); - gradientY.V = FindGradientY(bottomY, v1->v, v2->v, v3->v); - gradientY.WorldX = FindGradientY(bottomY, v1->worldX, v2->worldX, v3->worldX); - gradientY.WorldY = FindGradientY(bottomY, v1->worldY, v2->worldY, v3->worldY); - gradientY.WorldZ = FindGradientY(bottomY, v1->worldZ, v2->worldZ, v3->worldZ); - gradientY.A = FindGradientY(bottomY, v1->a, v2->a, v3->a); - gradientY.R = FindGradientY(bottomY, v1->r, v2->r, v3->r); - gradientY.G = FindGradientY(bottomY, v1->g, v2->g, v3->g); - gradientY.B = FindGradientY(bottomY, v1->b, v2->b, v3->b); - gradientY.GradientdistZ = FindGradientY(bottomY, v1->gradientdistZ, v2->gradientdistZ, v3->gradientdistZ); - - return true; - } - -private: - float FindGradientX(float bottomX, float c0, float c1, float c2) - { - c0 *= v1->w; - c1 *= v2->w; - c2 *= v3->w; - return ((c1 - c2) * (v1->y - v3->y) - (c0 - c2) * (v2->y - v3->y)) / bottomX; - } - - float FindGradientY(float bottomY, float c0, float c1, float c2) - { - c0 *= v1->w; - c1 *= v2->w; - c2 *= v3->w; - return ((c1 - c2) * (v1->x - v3->x) - (c0 - c2) * (v2->x - v3->x)) / bottomY; - } -}; - -class ScreenTriangle -{ -public: - static void Draw(const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread); - -private: - static void(*TestSpanOpts[])(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread); -}; - -enum SWTestSpan -{ - SWTRI_DepthTest = 1, - SWTRI_StencilTest = 2 -}; diff --git a/src/common/rendering/polyrenderer/poly_all.cpp b/src/common/rendering/polyrenderer/poly_all.cpp deleted file mode 100644 index 64098aa8e..000000000 --- a/src/common/rendering/polyrenderer/poly_all.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "drawers/poly_triangle.cpp" -#include "drawers/poly_thread.cpp" -#include "drawers/screen_triangle.cpp" -#include "drawers/screen_scanline_setup.cpp" -#include "drawers/screen_shader.cpp" -#include "drawers/screen_blend.cpp" diff --git a/src/common/rendering/r_thread.cpp b/src/common/rendering/r_thread.cpp index b9e70d67e..c13ffe8fe 100644 --- a/src/common/rendering/r_thread.cpp +++ b/src/common/rendering/r_thread.cpp @@ -27,9 +27,7 @@ #include "v_video.h" #include "r_thread.h" #include "r_memory.h" -#include "poly_thread.h" #include "printf.h" -#include "polyrenderer/drawers/poly_triangle.h" #include CVAR(Int, r_multithreaded, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); @@ -130,11 +128,6 @@ void DrawerThreads::WorkerMain(DrawerThread *thread) thread->current_queue++; thread->numa_start_y = thread->numa_node * screen->GetHeight() / thread->num_numa_nodes; thread->numa_end_y = (thread->numa_node + 1) * screen->GetHeight() / thread->num_numa_nodes; - if (thread->poly) - { - thread->poly->numa_start_y = thread->numa_start_y; - thread->poly->numa_end_y = thread->numa_end_y; - } start_lock.unlock(); // Do the work: diff --git a/src/common/rendering/r_thread.h b/src/common/rendering/r_thread.h index 33d7c0c0a..4d44972ac 100644 --- a/src/common/rendering/r_thread.h +++ b/src/common/rendering/r_thread.h @@ -34,8 +34,6 @@ // Use multiple threads when drawing EXTERN_CVAR(Int, r_multithreaded) -class PolyTriangleThreadData; - namespace swrenderer { class WallColumnDrawerArgs; } // Worker data for each thread executing drawer commands @@ -64,8 +62,6 @@ public: // Working buffer used by the tilted (sloped) span drawer const uint8_t *tiltlighting[MAXWIDTH]; - std::unique_ptr poly; - size_t debug_draw_pos = 0; // Checks if a line is rendered by this thread diff --git a/src/common/rendering/v_video.cpp b/src/common/rendering/v_video.cpp index 952fa722c..f87efe638 100644 --- a/src/common/rendering/v_video.cpp +++ b/src/common/rendering/v_video.cpp @@ -103,12 +103,10 @@ CUSTOM_CVAR(Int, vid_preferbackend, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_N { #ifdef HAVE_GLES2 case 3: + case 2: Printf("Selecting OpenGLES 2.0 backend...\n"); break; #endif - case 2: - Printf("Selecting SoftPoly backend...\n"); - break; #ifdef HAVE_VULKAN case 1: Printf("Selecting Vulkan backend...\n"); @@ -121,6 +119,14 @@ CUSTOM_CVAR(Int, vid_preferbackend, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_N Printf("Changing the video backend requires a restart for " GAMENAME ".\n"); } +int V_GetBackend() +{ + int v = vid_preferbackend; + if (v == 3) v = 2; + else if (v < 0 || v > 3) v = 0; + return v; +} + CUSTOM_CVAR(Int, uiscale, 0, CVAR_ARCHIVE | CVAR_NOINITCALL) { diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index 55b25c559..aff93435e 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -306,6 +306,7 @@ void V_InitScreen(); void V_Init2 (); void V_Shutdown (); +int V_GetBackend(); inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; } extern bool setsizeneeded, setmodeneeded; diff --git a/src/rendering/swrenderer/drawers/r_draw.cpp b/src/rendering/swrenderer/drawers/r_draw.cpp index 5fd8c5051..3f50fcef8 100644 --- a/src/rendering/swrenderer/drawers/r_draw.cpp +++ b/src/rendering/swrenderer/drawers/r_draw.cpp @@ -53,7 +53,6 @@ #include "r_thread.h" #include "swrenderer/scene/r_light.h" #include "playsim/a_dynlight.h" -#include "polyrenderer/drawers/poly_thread.h" CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); @@ -221,44 +220,6 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - void SWPixelFormatDrawers::DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth) - { - int x, y, count; - - auto rendertarget = args.Viewport()->RenderTarget; - if (rendertarget->IsBgra()) - { - uint32_t* destorg = (uint32_t*)rendertarget->GetPixels(); - destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); - uint32_t* dest = (uint32_t*)args.Dest(); - int offset = (int)(ptrdiff_t)(dest - destorg); - x = offset % rendertarget->GetPitch(); - y = offset / rendertarget->GetPitch(); - } - else - { - uint8_t* destorg = rendertarget->GetPixels(); - destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); - uint8_t* dest = (uint8_t*)args.Dest(); - int offset = (int)(ptrdiff_t)(dest - destorg); - x = offset % rendertarget->GetPitch(); - y = offset / rendertarget->GetPitch(); - } - count = args.Count(); - - auto zbuffer = thread->Poly->depthstencil; - int pitch = zbuffer->Width(); - float* values = zbuffer->DepthValues() + y * pitch + x; - int cnt = count; - - float depth = idepth; - for (int i = 0; i < cnt; i++) - { - *values = depth; - values += pitch; - } - } - void SWPixelFormatDrawers::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs) { bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP); @@ -323,76 +284,4 @@ namespace swrenderer } } - ///////////////////////////////////////////////////////////////////////// - - void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth) - { - int x, y, count; - auto rendertarget = args.Viewport()->RenderTarget; - if (rendertarget->IsBgra()) - { - uint32_t* destorg = (uint32_t*)rendertarget->GetPixels(); - destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); - uint32_t* dest = (uint32_t*)args.Dest(); - int offset = (int)(ptrdiff_t)(dest - destorg); - x = offset % rendertarget->GetPitch(); - y = offset / rendertarget->GetPitch(); - } - else - { - uint8_t* destorg = rendertarget->GetPixels(); - destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); - uint8_t* dest = (uint8_t*)args.Dest(); - int offset = (int)(ptrdiff_t)(dest - destorg); - x = offset % rendertarget->GetPitch(); - y = offset / rendertarget->GetPitch(); - } - count = args.Count(); - - auto zbuffer = thread->Poly->depthstencil; - int pitch = zbuffer->Width(); - float* values = zbuffer->DepthValues() + y * pitch + x; - int cnt = count; - - float depth = idepth; - for (int i = 0; i < cnt; i++) - { - *values = depth; - values += pitch; - } - } - - void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2) - { - int y = args.DestY(); - int x1 = args.DestX1(); - int x2 = args.DestX2(); - - auto zbuffer = thread->Poly->depthstencil; - int pitch = zbuffer->Width(); - float *values = zbuffer->DepthValues() + x1 + y * pitch; - - int count = x2 - x1 + 1; - - if (idepth1 == idepth2) - { - float depth = idepth1; - for (int i = 0; i < count; i++) - { - *values = depth; - values++; - } - } - else - { - float depth = idepth1; - float step = (idepth2 - idepth1) / (x2 - x1 + 1); - for (int i = 0; i < count; i++) - { - *values = depth; - values++; - depth += step; - } - } - } } diff --git a/src/rendering/swrenderer/drawers/r_draw.h b/src/rendering/swrenderer/drawers/r_draw.h index be2619595..133c2b182 100644 --- a/src/rendering/swrenderer/drawers/r_draw.h +++ b/src/rendering/swrenderer/drawers/r_draw.h @@ -94,10 +94,6 @@ namespace swrenderer virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args) = 0; virtual void DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) = 0; - void DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth); - void DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth); - void DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2); - void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs); RenderThread* thread = nullptr; diff --git a/src/rendering/swrenderer/drawers/r_draw_pal.cpp b/src/rendering/swrenderer/drawers/r_draw_pal.cpp index 375053145..22d89cb93 100644 --- a/src/rendering/swrenderer/drawers/r_draw_pal.cpp +++ b/src/rendering/swrenderer/drawers/r_draw_pal.cpp @@ -3060,30 +3060,6 @@ namespace swrenderer wpos += wstepX; curlight += lightstep; } - - if (r_modelscene) - { - for (int x = x1; x < x2; x++) - { - int y1 = uwal[x]; - int y2 = dwal[x]; - if (y2 > y1) - { - int count = y2 - y1; - - float w1 = 1.0f / wallargs.WallC.sz1; - float w2 = 1.0f / wallargs.WallC.sz2; - float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1); - float wcol = w1 * (1.0f - t) + w2 * t; - float zcol = 1.0f / wcol; - float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent); - - wallcolargs.SetDest(x, y1); - wallcolargs.SetCount(count); - DrawDepthColumn(wallcolargs, zbufferdepth); - } - } - } } template diff --git a/src/rendering/swrenderer/drawers/r_draw_rgba.cpp b/src/rendering/swrenderer/drawers/r_draw_rgba.cpp index 0e43daadc..7878e3e5a 100644 --- a/src/rendering/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/rendering/swrenderer/drawers/r_draw_rgba.cpp @@ -956,30 +956,6 @@ namespace swrenderer wpos += wstepX; curlight += lightstep; } - - if (r_modelscene) - { - for (int x = x1; x < x2; x++) - { - int y1 = uwal[x]; - int y2 = dwal[x]; - if (y2 > y1) - { - int count = y2 - y1; - - float w1 = 1.0f / wallargs.WallC.sz1; - float w2 = 1.0f / wallargs.WallC.sz2; - float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1); - float wcol = w1 * (1.0f - t) + w2 * t; - float zcol = 1.0f / wcol; - float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent); - - wallcolargs.SetDest(x, y1); - wallcolargs.SetCount(count); - DrawDepthColumn(wallcolargs, zbufferdepth); - } - } - } } template diff --git a/src/rendering/swrenderer/plane/r_flatplane.cpp b/src/rendering/swrenderer/plane/r_flatplane.cpp index be0313542..fd0a1dd4a 100644 --- a/src/rendering/swrenderer/plane/r_flatplane.cpp +++ b/src/rendering/swrenderer/plane/r_flatplane.cpp @@ -270,8 +270,6 @@ namespace swrenderer drawerargs.SetDestX2(x2); drawerargs.DrawSpan(Thread); - if (r_modelscene) - drawerargs.DrawDepthSpan(Thread, zbufferdepth, zbufferdepth); } ///////////////////////////////////////////////////////////////////////// diff --git a/src/rendering/swrenderer/plane/r_skyplane.cpp b/src/rendering/swrenderer/plane/r_skyplane.cpp index c3ae7bf85..6cd7b18d0 100644 --- a/src/rendering/swrenderer/plane/r_skyplane.cpp +++ b/src/rendering/swrenderer/plane/r_skyplane.cpp @@ -267,8 +267,6 @@ namespace swrenderer else drawerargs.DrawDoubleSkyColumn(Thread); - if (r_modelscene) - drawerargs.DrawDepthSkyColumn(Thread, 1.0f / 65536.0f); } void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) diff --git a/src/rendering/swrenderer/plane/r_slopeplane.cpp b/src/rendering/swrenderer/plane/r_slopeplane.cpp index 279009415..7a00e70ad 100644 --- a/src/rendering/swrenderer/plane/r_slopeplane.cpp +++ b/src/rendering/swrenderer/plane/r_slopeplane.cpp @@ -205,22 +205,5 @@ namespace swrenderer void RenderSlopePlane::RenderLine(int y, int x1, int x2) { drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, lightlevel, foggy, planelightfloat, pviewx, pviewy, basecolormap); - - if (r_modelscene) - { - double viewZ = 1.0; - double viewX1 = Thread->Viewport->ScreenToViewX(x1, viewZ); - double viewX2 = Thread->Viewport->ScreenToViewX(x2 + 1, viewZ); - double viewY = Thread->Viewport->ScreenToViewY(y, viewZ); - - // Find depth values for the span - float zbufferdepth1 = (float)(-planeD / (planeNormal | DVector3(viewX1, viewZ, viewY))); - float zbufferdepth2 = (float)(-planeD / (planeNormal | DVector3(viewX2, viewZ, viewY))); - - drawerargs.SetDestX1(x1); - drawerargs.SetDestX2(x2); - drawerargs.SetDestY(Thread->Viewport.get(), y); - drawerargs.DrawDepthSpan(Thread, 1.0f / zbufferdepth1, 1.0f / zbufferdepth2); - } } } diff --git a/src/rendering/swrenderer/r_all.cpp b/src/rendering/swrenderer/r_all.cpp index 91142a1df..66179cb46 100644 --- a/src/rendering/swrenderer/r_all.cpp +++ b/src/rendering/swrenderer/r_all.cpp @@ -34,7 +34,6 @@ #include "things/r_visiblespritelist.cpp" #include "things/r_voxel.cpp" #include "things/r_wallsprite.cpp" -#include "things/r_model.cpp" #include "viewport/r_drawerargs.cpp" #include "viewport/r_skydrawer.cpp" #include "viewport/r_spandrawer.cpp" diff --git a/src/rendering/swrenderer/r_renderthread.cpp b/src/rendering/swrenderer/r_renderthread.cpp index f19e0bc64..19f016ef9 100644 --- a/src/rendering/swrenderer/r_renderthread.cpp +++ b/src/rendering/swrenderer/r_renderthread.cpp @@ -53,7 +53,6 @@ #include "swrenderer/drawers/r_draw_pal.h" #include "swrenderer/viewport/r_viewport.h" #include "r_memory.h" -#include "common/rendering/polyrenderer/drawers/poly_thread.h" std::pair& R_GetSkyCapColor(FGameTexture* tex); @@ -75,7 +74,6 @@ namespace swrenderer PlaneList.reset(new VisiblePlaneList(this)); DrawSegments.reset(new DrawSegmentList(this)); ClipSegments.reset(new RenderClipSegment()); - Poly.reset(new PolyTriangleThreadData(0, 1, 0, 1, 0, screen->GetHeight())); tc_drawers.reset(new SWTruecolorDrawers(this)); pal_drawers.reset(new SWPalDrawers(this)); } diff --git a/src/rendering/swrenderer/r_renderthread.h b/src/rendering/swrenderer/r_renderthread.h index ba862c775..344b8ee53 100644 --- a/src/rendering/swrenderer/r_renderthread.h +++ b/src/rendering/swrenderer/r_renderthread.h @@ -26,11 +26,9 @@ #include class RenderMemory; -class PolyTriangleThreadData; struct FDynamicLight; EXTERN_CVAR(Bool, r_models); -extern bool r_modelscene; namespace swrenderer { @@ -75,7 +73,6 @@ namespace swrenderer std::unique_ptr ClipSegments; std::unique_ptr Viewport; std::unique_ptr Light; - std::unique_ptr Poly; TArray AddedLightsArray; diff --git a/src/rendering/swrenderer/scene/r_opaque_pass.cpp b/src/rendering/swrenderer/scene/r_opaque_pass.cpp index e598c15ac..09c4344ba 100644 --- a/src/rendering/swrenderer/scene/r_opaque_pass.cpp +++ b/src/rendering/swrenderer/scene/r_opaque_pass.cpp @@ -46,7 +46,6 @@ #include "swrenderer/things/r_wallsprite.h" #include "swrenderer/things/r_voxel.h" #include "swrenderer/things/r_particle.h" -#include "swrenderer/things/r_model.h" #include "swrenderer/segments/r_clipsegment.h" #include "swrenderer/line/r_wallsetup.h" #include "swrenderer/line/r_farclip_line.h" @@ -932,13 +931,7 @@ namespace swrenderer ThingSprite sprite; int spritenum = thing->sprite; bool isPicnumOverride = thing->picnum.isValid(); - FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); - if (r_modelscene && modelframe && (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared() < model_distance_cull) - { - DVector3 pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac); - RenderModel::Project(Thread, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing); - } - else if (GetThingSprite(thing, sprite)) + if (GetThingSprite(thing, sprite)) { int thinglightlevel; if (sec->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies. diff --git a/src/rendering/swrenderer/scene/r_scene.cpp b/src/rendering/swrenderer/scene/r_scene.cpp index d5d6a9d5e..56aa72560 100644 --- a/src/rendering/swrenderer/scene/r_scene.cpp +++ b/src/rendering/swrenderer/scene/r_scene.cpp @@ -65,8 +65,6 @@ EXTERN_CVAR(Int, r_debug_draw) CVAR(Int, r_scene_multithreaded, 1, 0); CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); -bool r_modelscene = false; - namespace swrenderer { cycle_t WallCycles, PlaneCycles, MaskedCycles; @@ -100,18 +98,6 @@ namespace swrenderer ActiveRatio(width, height, &trueratio); viewport->SetViewport(player->camera->Level, MainThread(), width, height, trueratio); - /*r_modelscene = r_models && Models.Size() > 0; - if (r_modelscene) - { - if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight()) - { - DepthStencil.reset(); - DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight())); - } - PolyTriangleDrawer::SetViewport(MainThread()->DrawQueue, 0, 0, viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), viewport->RenderTarget, DepthStencil.get()); - PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0); - }*/ - if (r_clearbuffer != 0 || r_debug_draw != 0) { if (!viewport->RenderTarget->IsBgra()) @@ -158,9 +144,6 @@ namespace swrenderer R_UpdateFuzzPosFrameStart(); - if (r_modelscene) - MainThread()->Viewport->SetupPolyViewport(MainThread()); - FRenderViewpoint origviewpoint = MainThread()->Viewport->viewpoint; ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags; @@ -174,8 +157,6 @@ namespace swrenderer // Mirrors fail to restore the original viewpoint -- we need it for the HUD weapon to draw correctly. MainThread()->Viewport->viewpoint = origviewpoint; - if (r_modelscene) - MainThread()->Viewport->SetupPolyViewport(MainThread()); if (renderPlayerSprites) RenderPSprites(); @@ -259,12 +240,6 @@ namespace swrenderer thread->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible thread->Portal->SetMainPortal(); - /*if (r_modelscene && thread->MainThread) - PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0); - - PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget, DepthStencil.get()); - PolyTriangleDrawer::SetScissor(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight);*/ - // Cull things outside the range seen by this thread VisibleSegmentRenderer visitor; if (thread->X1 > 0) @@ -388,14 +363,6 @@ namespace swrenderer viewwindowy = y; viewactive = true; viewport->SetViewport(actor->Level, MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio); - if (r_modelscene) - { - if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight()) - { - DepthStencil.reset(); - DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight())); - } - } // Render: RenderActorView(actor, false, dontmaplines); diff --git a/src/rendering/swrenderer/scene/r_scene.h b/src/rendering/swrenderer/scene/r_scene.h index c5fa8e959..035d12133 100644 --- a/src/rendering/swrenderer/scene/r_scene.h +++ b/src/rendering/swrenderer/scene/r_scene.h @@ -32,8 +32,6 @@ extern cycle_t FrameCycles; -class PolyDepthStencil; - namespace swrenderer { extern cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; @@ -69,7 +67,6 @@ namespace swrenderer bool dontmaplines = false; int clearcolor = 0; - std::unique_ptr DepthStencil; std::vector> Threads; std::mutex start_mutex; std::condition_variable start_condition; diff --git a/src/rendering/swrenderer/things/r_model.cpp b/src/rendering/swrenderer/things/r_model.cpp deleted file mode 100644 index 4e61e362d..000000000 --- a/src/rendering/swrenderer/things/r_model.cpp +++ /dev/null @@ -1,443 +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. -** -*/ - -#include - -#include "doomdef.h" -#include "sbar.h" -#include "r_data/r_translate.h" -#include "r_model.h" -#include "r_data/r_vanillatrans.h" -#include "actorinlines.h" -#include "i_time.h" -#include "texturemanager.h" -#include "r_memory.h" -#include "swrenderer/r_swcolormaps.h" -#include "swrenderer/viewport/r_viewport.h" -#include "swrenderer/scene/r_light.h" - -namespace swrenderer -{ - void RenderModel::Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) - { - // transform the origin point - double tr_x = x - thread->Viewport->viewpoint.Pos.X; - double tr_y = y - thread->Viewport->viewpoint.Pos.Y; - double tz = tr_x * thread->Viewport->viewpoint.TanCos + tr_y * thread->Viewport->viewpoint.TanSin; - - // thing is behind view plane? - if (tz < MINZ) - return; - - double tx = tr_x * thread->Viewport->viewpoint.Sin - tr_y * thread->Viewport->viewpoint.Cos; - - // Flip for mirrors - if (thread->Portal->MirrorFlags & RF_XFLIP) - { - tx = viewwidth - tx - 1; - } - - // too far off the side? - if (fabs(tx / 64) > fabs(tz)) - return; - - RenderModel *vis = thread->FrameMemory->NewObject(x, y, z, smf, actor, float(1 / tz)); - vis->CurrentPortalUniq = thread->Portal->CurrentPortalUniq; - vis->WorldToClip = thread->Viewport->WorldToClip; - vis->MirrorWorldToClip = !!(thread->Portal->MirrorFlags & RF_XFLIP); - thread->SpriteList->Push(vis); - } - - RenderModel::RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, float idepth) : x(x), y(y), z(z), smf(smf), actor(actor) - { - gpos = { x, y, z }; - this->idepth = idepth; - } - - void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) - { -#if 0 - SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip); - - renderer.sector = actor->Sector; - renderer.RenderStyle = actor->RenderStyle; - renderer.RenderAlpha = (float)actor->Alpha; - if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha)) - return; - - bool foggy = false; - int actualextralight = foggy ? 0 : thread->Viewport->viewpoint.extralight << 4; - bool fullbrightSprite = ((actor->renderflags & RF_FULLBRIGHT) || (actor->flags5 & MF5_BRIGHT)); - renderer.lightlevel = fullbrightSprite ? 255 : actor->Sector->lightlevel + actualextralight; - renderer.visibility = thread->Light->SpriteGlobVis(foggy); - - renderer.fillcolor = actor->fillcolor; - renderer.Translation = actor->Translation; - - renderer.AddLights(actor); - RenderModel(&renderer, x, y, z, smf, actor, r_viewpoint.TicFrac); - PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f); -#endif - } - - ///////////////////////////////////////////////////////////////////////////// - - static bool isBright(DPSprite *psp) - { - if (psp != nullptr && psp->GetState() != nullptr) - { - bool disablefullbright = false; - FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr); - if (lump.isValid()) - { - auto tex = TexMan.GetGameTexture(lump, true); - if (tex) disablefullbright = tex->isFullbrightDisabled(); - } - return psp->GetState()->GetFullbright() && !disablefullbright; - } - return false; - } - - void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy) - { -#if 0 - SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false); - - AActor *playermo = players[consoleplayer].camera; - auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha); - renderer.sector = playermo->Sector; - renderer.RenderStyle = rs.first; - renderer.RenderAlpha = rs.second; - if (psp->Flags & PSPF_FORCEALPHA) renderer.RenderAlpha = 0.0f; - if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha)) - return; - - bool foggy = false; - int actualextralight = foggy ? 0 : thread->Viewport->viewpoint.extralight << 4; - bool fullbrightSprite = isBright(psp); - renderer.lightlevel = fullbrightSprite ? 255 : playermo->Sector->lightlevel + actualextralight; - renderer.visibility = thread->Light->SpriteGlobVis(foggy); - - PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; - ThingColor.a = 255; - - renderer.fillcolor = fullbrightSprite ? ThingColor : ThingColor.Modulate(playermo->Sector->SpecialColors[sector_t::sprites]); - uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0; - if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = playermo->Translation; - renderer.Translation = trans; - - RenderHUDModel(&renderer, psp, ofsx, ofsy); - PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f); -#endif - } - - ///////////////////////////////////////////////////////////////////////////// - -#if 0 - SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip) - : Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip) - { - static PolySWInputAssembly input; - PolyTriangleDrawer::SetInputAssembly(thread->DrawQueue, &input); - } - - void SWModelRenderer::AddLights(AActor *actor) - { - if (r_dynlights && actor) - { - auto &addedLights = Thread->AddedLightsArray; - - addedLights.Clear(); - - float x = (float)actor->X(); - float y = (float)actor->Y(); - float z = (float)actor->Center(); - float actorradius = (float)actor->RenderRadius(); - float radiusSquared = actorradius * actorradius; - - BSPWalkCircle(actor->Level, x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor - { - FLightNode * node = subsector->section->lighthead; - while (node) // check all lights touching a subsector - { - FDynamicLight *light = node->lightsource; - if (light->ShouldLightActor(actor)) - { - int group = subsector->sector->PortalGroup; - DVector3 pos = light->PosRelative(group); - float radius = (float)(light->GetRadius() + actorradius); - double dx = pos.X - x; - double dy = pos.Y - y; - double dz = pos.Z - z; - double distSquared = dx * dx + dy * dy + dz * dz; - if (distSquared < radius * radius) // Light and actor touches - { - if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector - { - addedLights.Push(light); - } - } - } - node = node->nextLight; - } - }); - - NumLights = addedLights.Size(); - Lights = Thread->FrameMemory->AllocMemory(NumLights); - for (int i = 0; i < NumLights; i++) - { - FDynamicLight *lightsource = addedLights[i]; - - bool is_point_light = lightsource->IsAttenuated(); - - uint32_t red = lightsource->GetRed(); - uint32_t green = lightsource->GetGreen(); - uint32_t blue = lightsource->GetBlue(); - - PolyLight &light = Lights[i]; - light.x = (float)lightsource->X(); - light.y = (float)lightsource->Y(); - light.z = (float)lightsource->Z(); - light.radius = 256.0f / lightsource->GetRadius(); - light.color = (red << 16) | (green << 8) | blue; - if (is_point_light) - light.radius = -light.radius; - } - } - } - - void SWModelRenderer::BeginDrawModel(FRenderStyale style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) - { - const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); - - ClipTop = {}; - ClipBottom = {}; - if (Clip3DFloor.clipTop || Clip3DFloor.clipBottom) - { - // Convert 3d floor clipping planes from world to object space - - VSMatrix inverseMat; - const_cast(objectToWorldMatrix).inverseMatrix(inverseMat); - Mat4f worldToObject; - inverseMat.copy(worldToObject.Matrix); - - // Note: Y and Z is swapped here - - Vec4f one = worldToObject * Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - Vec4f zero = worldToObject * Vec4f(0.0f, 0.0f, 0.0f, 1.0f); - Vec4f up = { one.X - zero.X, one.Y - zero.Y, one.Z - zero.Z }; - - if (Clip3DFloor.clipTop) - { - Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipTop, 0.0f, 1.0f); - float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z; - ClipTop = { -up.X, -up.Y, -up.Z, d }; - } - - if (Clip3DFloor.clipBottom) - { - Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipBottom, 0.0f, 1.0f); - float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z; - ClipBottom = { up.X, up.Y, up.Z, -d }; - } - } - - SetTransform(); - - if (style == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); - PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip)); - } - - void SWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) - { - if (style == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES)) - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); - PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true); - } - - IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe) - { - return new SWModelVertexBuffer(needindex, singleframe); - } - - VSMatrix SWModelRenderer::GetViewToWorldMatrix() - { - // Calculate the WorldToView matrix as it would have looked like without yshearing: - const auto &Viewpoint = Thread->Viewport->viewpoint; - auto Level = Thread->Viewport->Level(); - const auto &Viewwindow = Thread->Viewport->viewwindow; - double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); - double angx = cos(radPitch); - double angy = sin(radPitch) * Level->info->pixelstretch; - double alen = sqrt(angx*angx + angy*angy); - float adjustedPitch = (float)asin(angy / alen); - float adjustedViewAngle = (float)(Viewpoint.Angles.Yaw - 90).Radians(); - float ratio = Viewwindow.WidescreenRatio; - float fovratio = (Viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio; - float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(Viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees); - Mat4f altWorldToView = - Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * - Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * - Mat4f::Scale(1.0f, Level->info->pixelstretch, 1.0f) * - Mat4f::SwapYZ() * - Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); - - Mat4f swapYZ = Mat4f::Null(); - swapYZ.Matrix[0 + 0 * 4] = 1.0f; - swapYZ.Matrix[1 + 2 * 4] = 1.0f; - swapYZ.Matrix[2 + 1 * 4] = 1.0f; - swapYZ.Matrix[3 + 3 * 4] = 1.0f; - - VSMatrix worldToView; - worldToView.loadMatrix((altWorldToView * swapYZ).Matrix); - - VSMatrix objectToWorld; - worldToView.inverseMatrix(objectToWorld); - return objectToWorld; - } - - void SWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) - { - const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); - ClipTop = {}; - ClipBottom = {}; - SetTransform(); - PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); - - if (style == LegacyRenderStyles[STYLE_Normal]) - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); - PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip)); - } - - void SWModelRenderer::EndDrawHUDModel(FRenderStyle style) - { - PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false); - - if (style == LegacyRenderStyles[STYLE_Normal]) - PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); - PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true); - } - - void SWModelRenderer::SetInterpolation(double interpolation) - { - InterpolationFactor = (float)interpolation; - } - - void SWModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation) - { - SkinTexture = skin; - } - - void SWModelRenderer::SetTransform() - { - Mat4f swapYZ = Mat4f::Null(); - swapYZ.Matrix[0 + 0 * 4] = 1.0f; - swapYZ.Matrix[1 + 2 * 4] = 1.0f; - swapYZ.Matrix[2 + 1 * 4] = 1.0f; - swapYZ.Matrix[3 + 3 * 4] = 1.0f; - ObjectToWorld = swapYZ * ObjectToWorld; - - PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject((*WorldToClip) * ObjectToWorld), Thread->FrameMemory->NewObject(ObjectToWorld)); - } - - void SWModelRenderer::DrawArrays(int start, int count) - { - PolyDrawArgs args; - auto nc = !!(sector->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING); - args.SetLight(GetSpriteColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], nc), lightlevel, visibility, fullbrightSprite); - args.SetLights(Lights, NumLights); - args.SetNormal(FVector3(0.0f, 0.0f, 0.0f)); - args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite); - args.SetDepthTest(true); - args.SetWriteDepth(true); - args.SetWriteStencil(false); - args.SetClipPlane(0, PolyClipPlane()); - args.SetClipPlane(1, ClipTop); - args.SetClipPlane(2, ClipBottom); - - PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args); - PolyTriangleDrawer::Draw(Thread->DrawQueue, start, count); - } - - void SWModelRenderer::DrawElements(int numIndices, size_t offset) - { - PolyDrawArgs args; - auto nc = !!(sector->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING); - args.SetLight(GetSpriteColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], nc), lightlevel, visibility, fullbrightSprite); - args.SetLights(Lights, NumLights); - args.SetNormal(FVector3(0.0f, 0.0f, 0.0f)); - args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite); - args.SetDepthTest(true); - args.SetWriteDepth(true); - args.SetWriteStencil(false); - args.SetClipPlane(0, PolyClipPlane()); - args.SetClipPlane(1, ClipTop); - args.SetClipPlane(2, ClipBottom); - - PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args); - PolyTriangleDrawer::DrawIndexed(Thread->DrawQueue, static_cast(offset / sizeof(unsigned int)), numIndices); - } - - ///////////////////////////////////////////////////////////////////////////// - - SWModelVertexBuffer::SWModelVertexBuffer(bool needindex, bool singleframe) - { - } - - SWModelVertexBuffer::~SWModelVertexBuffer() - { - } - - FModelVertex *SWModelVertexBuffer::LockVertexBuffer(unsigned int size) - { - mVertexBuffer.Resize(size); - return &mVertexBuffer[0]; - } - - void SWModelVertexBuffer::UnlockVertexBuffer() - { - } - - unsigned int *SWModelVertexBuffer::LockIndexBuffer(unsigned int size) - { - mIndexBuffer.Resize(size); - return &mIndexBuffer[0]; - } - - void SWModelVertexBuffer::UnlockIndexBuffer() - { - } - - void SWModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) - { - SWModelRenderer *swrenderer = (SWModelRenderer *)renderer; - - if (mVertexBuffer.Size() > 0) - PolyTriangleDrawer::SetVertexBuffer(swrenderer->Thread->DrawQueue, &mVertexBuffer[0]); - if (mIndexBuffer.Size() > 0) - PolyTriangleDrawer::SetIndexBuffer(swrenderer->Thread->DrawQueue, &mIndexBuffer[0]); - - PolyTriangleDrawer::SetModelVertexShader(swrenderer->Thread->DrawQueue, frame1, frame2, swrenderer->InterpolationFactor); - } -#endif -} diff --git a/src/rendering/swrenderer/things/r_model.h b/src/rendering/swrenderer/things/r_model.h deleted file mode 100644 index 4c0c5a342..000000000 --- a/src/rendering/swrenderer/things/r_model.h +++ /dev/null @@ -1,120 +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 "polyrenderer/drawers/poly_triangle.h" -#include "matrix.h" -#include "models.h" -#include "swrenderer/r_renderthread.h" -#include "swrenderer/things/r_visiblesprite.h" - -struct PolyLight; - -namespace swrenderer -{ - void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy); - - class RenderModel : public VisibleSprite - { - public: - RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, float idepth); - - static void Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor); - - protected: - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; - bool IsModel() const override { return true; } - - private: - float x, y, z; - FSpriteModelFrame *smf; - AActor *actor; - VSMatrix WorldToClip; - bool MirrorWorldToClip; - }; - -#if 0 - class SWModelRenderer : public FModelRenderer - { - public: - SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip); - - void AddLights(AActor *actor); - - ModelRendererType GetType() const override { return SWModelRendererType; } - - void BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override; - void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override; - IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; - VSMatrix GetViewToWorldMatrix() override; - void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override; - void EndDrawHUDModel(FRenderStyle style) override; - void SetInterpolation(double interpolation) override; - void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override; - void DrawArrays(int start, int count) override; - void DrawElements(int numIndices, size_t offset) override; - - void SetTransform(); - - RenderThread *Thread = nullptr; - Fake3DTranslucent Clip3DFloor; - - FRenderStyle RenderStyle; - float RenderAlpha; - sector_t *sector; - bool fullbrightSprite; - int lightlevel; - double visibility; - uint32_t fillcolor; - uint32_t Translation; - - Mat4f ObjectToWorld; - PolyClipPlane ClipTop, ClipBottom; - FTexture *SkinTexture = nullptr; - float InterpolationFactor = 0.0; - Mat4f *WorldToClip = nullptr; - bool MirrorWorldToClip = false; - PolyLight *Lights = nullptr; - int NumLights = 0; - }; - - class SWModelVertexBuffer : public IModelVertexBuffer - { - public: - SWModelVertexBuffer(bool needindex, bool singleframe); - ~SWModelVertexBuffer(); - - FModelVertex *LockVertexBuffer(unsigned int size) override; - void UnlockVertexBuffer() override; - - unsigned int *LockIndexBuffer(unsigned int size) override; - void UnlockIndexBuffer() override; - - void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) override; - - private: - TArray mVertexBuffer; - TArray mIndexBuffer; - }; -#endif -} diff --git a/src/rendering/swrenderer/things/r_playersprite.cpp b/src/rendering/swrenderer/things/r_playersprite.cpp index a9873d52d..87ae07496 100644 --- a/src/rendering/swrenderer/things/r_playersprite.cpp +++ b/src/rendering/swrenderer/things/r_playersprite.cpp @@ -97,8 +97,6 @@ namespace swrenderer (r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0)) return; - renderHUDModel = r_modelscene && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); - FDynamicColormap *basecolormap; CameraLight *cameraLight = CameraLight::Instance(); auto nc = !!(Thread->Viewport->Level()->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING); @@ -256,12 +254,6 @@ namespace swrenderer sy += wy; } - if (renderHUDModel) - { - RenderHUDModel(Thread, pspr, (float)sx, (float)sy); - return; - } - auto viewport = Thread->Viewport.get(); double pspritexscale = viewport->viewwindow.centerxwide / 160.0; diff --git a/src/rendering/swrenderer/things/r_playersprite.h b/src/rendering/swrenderer/things/r_playersprite.h index 046b4ab7c..b32f0bf8e 100644 --- a/src/rendering/swrenderer/things/r_playersprite.h +++ b/src/rendering/swrenderer/things/r_playersprite.h @@ -97,6 +97,5 @@ namespace swrenderer TArray AcceleratedSprites; sector_t tempsec; - bool renderHUDModel = false; }; } diff --git a/src/rendering/swrenderer/things/r_visiblesprite.cpp b/src/rendering/swrenderer/things/r_visiblesprite.cpp index e4b89453c..1878008cd 100644 --- a/src/rendering/swrenderer/things/r_visiblesprite.cpp +++ b/src/rendering/swrenderer/things/r_visiblesprite.cpp @@ -316,24 +316,6 @@ namespace swrenderer DrawSegmentList *segmentlist = thread->DrawSegments.get(); RenderPortal *renderportal = thread->Portal.get(); - // Render draw segments behind sprite - if (r_modelscene) - { - int subsectordepth = spr->SubsectorDepth; - for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++) - { - DrawSegment *ds = segmentlist->TranslucentSegment(index); - if (ds->drawsegclip.SubsectorDepth >= subsectordepth && ds->drawsegclip.CurrentPortalUniq == renderportal->CurrentPortalUniq) - { - int r1 = max(ds->x1, 0); - int r2 = min(ds->x2, viewwidth - 1); - - RenderDrawSegment renderer(thread); - renderer.Render(ds, r1, r2, clip3DFloor); - } - } - } - else { for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++) { diff --git a/src/rendering/swrenderer/things/r_visiblespritelist.cpp b/src/rendering/swrenderer/things/r_visiblespritelist.cpp index 9f4880640..fb25bb5ea 100644 --- a/src/rendering/swrenderer/things/r_visiblespritelist.cpp +++ b/src/rendering/swrenderer/things/r_visiblespritelist.cpp @@ -83,23 +83,6 @@ namespace swrenderer SortedSprites[i] = Sprites[first + count - i - 1]; } - if (r_modelscene) - { - for (unsigned int i = 0; i < count; i++) - { - FVector2 worldPos = SortedSprites[i]->WorldPos().XY(); - SortedSprites[i]->SubsectorDepth = FindSubsectorDepth(thread, { worldPos.X, worldPos.Y }); - } - - std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool - { - if (a->SubsectorDepth != b->SubsectorDepth) - return a->SubsectorDepth < b->SubsectorDepth; - else - return a->SortDist() > b->SortDist(); - }); - } - else { std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool { diff --git a/src/rendering/swrenderer/viewport/r_skydrawer.cpp b/src/rendering/swrenderer/viewport/r_skydrawer.cpp index 008903498..87088fead 100644 --- a/src/rendering/swrenderer/viewport/r_skydrawer.cpp +++ b/src/rendering/swrenderer/viewport/r_skydrawer.cpp @@ -25,11 +25,6 @@ namespace swrenderer { - void SkyDrawerArgs::DrawDepthSkyColumn(RenderThread *thread, float idepth) - { - thread->Drawers(dc_viewport)->DrawDepthSkyColumn(*this, idepth); - } - void SkyDrawerArgs::DrawSingleSkyColumn(RenderThread *thread) { thread->Drawers(dc_viewport)->DrawSingleSkyColumn(*this); diff --git a/src/rendering/swrenderer/viewport/r_spandrawer.cpp b/src/rendering/swrenderer/viewport/r_spandrawer.cpp index c101ac80c..59b298cd3 100644 --- a/src/rendering/swrenderer/viewport/r_spandrawer.cpp +++ b/src/rendering/swrenderer/viewport/r_spandrawer.cpp @@ -121,11 +121,6 @@ namespace swrenderer } } - void SpanDrawerArgs::DrawDepthSpan(RenderThread *thread, float idepth1, float idepth2) - { - thread->Drawers(ds_viewport)->DrawDepthSpan(*this, idepth1, idepth2); - } - void SpanDrawerArgs::DrawSpan(RenderThread *thread) { (thread->Drawers(ds_viewport)->*spanfunc)(*this); diff --git a/src/rendering/swrenderer/viewport/r_viewport.h b/src/rendering/swrenderer/viewport/r_viewport.h index 54d3090f6..a43da8f25 100644 --- a/src/rendering/swrenderer/viewport/r_viewport.h +++ b/src/rendering/swrenderer/viewport/r_viewport.h @@ -11,8 +11,6 @@ #define MINZ double((2048*4) / double(1 << 20)) -class PolyDepthStencil; - namespace swrenderer { class RenderThread; diff --git a/src/win32/zdoom.rc b/src/win32/zdoom.rc index 0e55d0efe..619fd0904 100644 --- a/src/win32/zdoom.rc +++ b/src/win32/zdoom.rc @@ -228,9 +228,8 @@ BEGIN #ifdef HAVE_VULKAN CONTROL "&Vulkan",IDC_WELCOME_VULKAN2,"Button",BS_AUTORADIOBUTTON,13,176,37,10 #endif - CONTROL "&SoftPoly",IDC_WELCOME_VULKAN3,"Button",BS_AUTORADIOBUTTON,13,185,43,10 #ifdef HAVE_GLES2 - CONTROL "OpenGL &ES",IDC_WELCOME_VULKAN4,"Button",BS_AUTORADIOBUTTON,13,194,53,10 + CONTROL "OpenGL &ES",IDC_WELCOME_VULKAN4,"Button",BS_AUTORADIOBUTTON,13,185,53,10 #endif END