diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1977f1e06..591598f1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1043,6 +1043,7 @@ set (PCH_SOURCES g_statusbar/sbar_mugshot.cpp g_statusbar/shared_sbar.cpp gl/compatibility/gl_20.cpp + gl/compatibility/gl_swshader20.cpp gl/data/gl_vertexbuffer.cpp gl/dynlights/gl_lightbuffer.cpp gl/dynlights/gl_shadowmap.cpp diff --git a/src/d_main.cpp b/src/d_main.cpp index 9518be8ee..92086e18b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2637,7 +2637,7 @@ void D_DoomMain (void) } V_Init2(); - gl_PatchMenu(); + gl_PatchMenu(); // removes unapplicable entries for old hardware. This cannot be done in MENUDEF because at the point it gets parsed it doesn't have the needed info. UpdateJoystickMenu(NULL); v = Args->CheckValue ("-loadgame"); diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 0a6a743e0..f2cdd56d4 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -52,7 +52,6 @@ CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) //========================================================================== // @@ -64,7 +63,7 @@ CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) void gl_PatchMenu() { // Radial fog and Doom lighting are not available without full shader support. - if (!gl_legacy_mode) return; + if (!gl.legacyMode) return; FOptionValues **opt = OptionValues.CheckKey("LightingModes"); if (opt != NULL) diff --git a/src/gl/compatibility/gl_swshader20.cpp b/src/gl/compatibility/gl_swshader20.cpp new file mode 100644 index 000000000..93d0ad14b --- /dev/null +++ b/src/gl/compatibility/gl_swshader20.cpp @@ -0,0 +1,218 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2018 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_swshader20.cpp +** +** Implements the shaders used to render the software renderer's +** 3D output to the screen, +** +*/ + +#include "gl/system/gl_system.h" +#include "tarray.h" +#include "doomtype.h" +#include "zstring.h" +#include "i_system.h" +#include "r_utility.h" +#include "w_wad.h" +#include "gl/dynlights/gl_dynlight.h" +#include "gl/renderer/gl_renderer.h" +#include "gl/system/gl_interface.h" +#include "gl/renderer/gl_renderstate.h" + + +class LegacyShader +{ +public: + ~LegacyShader() + { + if (Program != 0) glDeleteProgram(Program); + if (VertexShader != 0) glDeleteShader(VertexShader); + if (FragmentShader != 0) glDeleteShader(FragmentShader); + } + + int Program = 0; + int VertexShader = 0; + int FragmentShader = 0; + + int ConstantLocations[2]; + int ImageLocation = -1; + int PaletteLocation = -1; +}; + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +LegacyShaderContainer::LegacyShaderContainer() +{ + if (!LoadShaders()) + { + Printf("Unable to compile shaders for software rendering\n"); + } +} + +LegacyShaderContainer::~LegacyShaderContainer() +{ + for (auto p : Shaders) if (p) delete p; +} + +LegacyShader* LegacyShaderContainer::CreatePixelShader(const FString& vertexsrc, const FString& fragmentsrc, const FString &defines) +{ + auto shader = new LegacyShader(); + char buffer[10000]; + + shader->Program = glCreateProgram(); + if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + shader->VertexShader = glCreateShader(GL_VERTEX_SHADER); + if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + + { + int lengths[1] = { (int)vertexsrc.Len() }; + const char *sources[1] = { vertexsrc.GetChars() }; + glShaderSource(shader->VertexShader, 1, sources, lengths); + glCompileShader(shader->VertexShader); + } + + { + int lengths[1] = { (int)fragmentsrc.Len() }; + const char *sources[1] = { fragmentsrc.GetChars() }; + glShaderSource(shader->FragmentShader, 1, sources, lengths); + glCompileShader(shader->FragmentShader); + } + + GLint status = 0; + int errorShader = shader->VertexShader; + glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status); + if (status != GL_FALSE) + { + errorShader = shader->FragmentShader; + glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status); + } + if (status == GL_FALSE) + { + GLsizei length = 0; + buffer[0] = 0; + glGetShaderInfoLog(errorShader, 10000, &length, buffer); + Printf("Shader compile failed: %s", buffer); + delete shader; + return nullptr; + } + + glAttachShader(shader->Program, shader->VertexShader); + glAttachShader(shader->Program, shader->FragmentShader); + glLinkProgram(shader->Program); + glGetProgramiv(shader->Program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) + { + GLsizei length = 0; + buffer[0] = 0; + glGetProgramInfoLog(shader->Program, 10000, &length, buffer); + Printf("Shader link failed: %s", buffer); + delete shader; + return nullptr; + } + + shader->ConstantLocations[0] = glGetUniformLocation(shader->Program, "uColor1"); + shader->ConstantLocations[1] = glGetUniformLocation(shader->Program, "uColor2"); + shader->ImageLocation = glGetUniformLocation(shader->Program, "Image"); + shader->PaletteLocation = glGetUniformLocation(shader->Program, "Palette"); + + return shader; +} + +//========================================================================== +// +// SWSceneDrawer :: LoadShaders +// +// Returns true if all required shaders were loaded. (Gamma and burn wipe +// are the only ones not considered "required".) +// +//========================================================================== + +static const char * const ShaderDefines[] = { + "#define PAL_TEX\n", + "#define PAL_TEX\n#define SPECIALCM\n", + "", + "#define SPECIALCM\n", +}; + +bool LegacyShaderContainer::LoadShaders() +{ + int lumpvert = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.vp"); + int lumpfrag = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.fp"); + if (lumpvert < 0 || lumpfrag < 0) + return false; + + FString vertsource = Wads.ReadLump(lumpvert).GetString(); + FString fragsource = Wads.ReadLump(lumpfrag).GetString(); + + FString shaderdir, shaderpath; + unsigned int i; + + for (i = 0; i < NUM_SHADERS; ++i) + { + shaderpath = shaderdir; + Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]); + if (!Shaders[i]) + { + break; + } + + glUseProgram(Shaders[i]->Program); + if (Shaders[i]->ImageLocation != -1) glUniform1i(Shaders[i]->ImageLocation, 0); + if (Shaders[i]->PaletteLocation != -1) glUniform1i(Shaders[i]->PaletteLocation, 1); + glUseProgram(0); + } + if (i == NUM_SHADERS) + { // Success! + return true; + } + // Failure. Release whatever managed to load (which is probably nothing.) + for (i = 0; i < NUM_SHADERS; ++i) + { + if (Shaders[i]) delete Shaders[i]; + } + return false; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void LegacyShaderContainer::BindShader(int num, const float *p1, const float *p2) +{ + if (num >= 0 && num < 4) + { + auto shader = Shaders[num]; + glUseProgram(shader->Program); + glUniform4fv(shader->ConstantLocations[0], 1, p1); + glUniform4fv(shader->ConstantLocations[1], 1, p2); + } +} + diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 27da7b8bd..d8f4890f2 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -163,6 +163,11 @@ void FGLRenderer::Initialize(int width, int height) mShadowMapShader = new FShadowMapShader(); mCustomPostProcessShaders = new FCustomPostProcessShaders(); + if (gl.legacyMode) + { + legacyShaders = new LegacyShaderContainer; + } + GetSpecialTextures(); // needed for the core profile, because someone decided it was a good idea to remove the default VAO. @@ -197,6 +202,7 @@ FGLRenderer::~FGLRenderer() gl_FlushModels(); AActor::DeleteAllAttachedLights(); FMaterial::FlushAll(); + if (legacyShaders) delete legacyShaders; if (mShaderManager != NULL) delete mShaderManager; if (mSamplerManager != NULL) delete mSamplerManager; if (mVBO != NULL) delete mVBO; @@ -830,6 +836,12 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer) auto mat = FMaterial::ValidateTexture(cmd.mTexture, false); if (mat == nullptr) continue; + // This requires very special handling + if (gl.legacyMode && cmd.mTexture->UseType == ETextureType::SWCanvas) + { + gl_RenderState.SetTextureMode(TM_SWCANVAS); + } + if (gltrans == -1 && cmd.mTranslation != nullptr) gltrans = cmd.mTranslation->GetUniqueIndex(); gl_RenderState.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1, cmd.mDrawMode == F2DDrawer::DTM_AlphaTexture); gl_RenderState.EnableTexture(true); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index c44330560..fa87ada0a 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -89,6 +89,29 @@ enum DM_SKYPORTAL }; + +// Helper baggage to draw the paletted software renderer output on old hardware. +// This must be here because the 2D drawer needs to access it, not the scene drawer. +class LegacyShader; +struct LegacyShaderContainer +{ + enum + { + NUM_SHADERS = 4 + }; + + LegacyShader *Shaders[NUM_SHADERS]; + + LegacyShader* CreatePixelShader(const FString& vertexsrc, const FString& fragmentsrc, const FString &defines); + LegacyShaderContainer(); + ~LegacyShaderContainer(); + bool LoadShaders(); + void BindShader(int num, const float *p1, const float *p2); +}; + + + + class FGLRenderer { public: @@ -148,6 +171,7 @@ public: FSkyVertexBuffer *mSkyVBO; FLightBuffer *mLights; SWSceneDrawer *swdrawer = nullptr; + LegacyShaderContainer *legacyShaders = nullptr; GL_IRECT mScreenViewport; GL_IRECT mSceneViewport; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 67d683aa7..1d3524f75 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -80,7 +80,6 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, cl_capfps) EXTERN_CVAR (Bool, r_deathcamera) EXTERN_CVAR (Float, r_visibility) -EXTERN_CVAR (Bool, gl_legacy_mode) EXTERN_CVAR (Bool, r_drawvoxels) //----------------------------------------------------------------------------- diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 661224da7..bdebfff50 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -44,6 +44,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_lightdata.h" #include "gl/textures/gl_hwtexture.h" +#include "gl/textures/gl_samplers.h" #include "gl/utility/gl_clock.h" #include "gl/data/gl_vertexbuffer.h" #include "gl_debug.h" @@ -391,6 +392,11 @@ void OpenGLFrameBuffer::CleanForRestart() GLRenderer->ResetSWScene(); } +void OpenGLFrameBuffer::SetTextureFilterMode() +{ + if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode(); +} + void OpenGLFrameBuffer::UpdatePalette() { if (GLRenderer) diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index fb436c7cc..5c8440f7d 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -53,6 +53,7 @@ public: void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override; void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; void RenderView(player_t *player) override; + void SetTextureFilterMode() override; // Retrieves a buffer containing image data for a screenshot. // Hint: Pitch can be negative for upside-down images, in which case buffer diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 412d96352..94b28712d 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -43,9 +43,6 @@ static TArray m_Extensions; RenderContext gl; static double realglversion; // this is public so the statistics code can access it. -EXTERN_CVAR(Bool, gl_legacy_mode) -CVAR(Bool, gl_riskymodernpath, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - //========================================================================== // // @@ -322,7 +319,6 @@ void gl_LoadExtensions() UCVarValue value; value.Bool = gl.legacyMode; - gl_legacy_mode.ForceSet (value, CVAR_Bool); } //========================================================================== diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index c68e5f6c2..258451701 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -29,6 +29,7 @@ enum RenderFlags enum TexMode { + TM_SWCANVAS = -1, // special case for the legacy renderer, do not use for anything but the SW renderer's canvas. TM_MODULATE = 0, // (r, g, b, a) TM_MASK, // (1, 1, 1, a) TM_OPAQUE, // (r, g, b, 1) diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp index df1d10539..5ca9a8d0b 100644 --- a/src/gl/textures/gl_samplers.cpp +++ b/src/gl/textures/gl_samplers.cpp @@ -94,6 +94,7 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) } else { + int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0; glActiveTexture(GL_TEXTURE0 + texunit); switch (num) { @@ -102,8 +103,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -113,8 +114,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -124,8 +125,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -135,8 +136,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -144,8 +145,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) case CLAMP_XY_NOMIP: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; @@ -160,8 +161,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) case CLAMP_CAMTEX: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; } @@ -176,17 +177,18 @@ void FSamplerManager::SetTextureFilterMode() if (gl.flags & RFL_SAMPLER_OBJECTS) { UnbindAll(); + int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0; for (int i = 0; i < 4; i++) { - glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } - glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); } else { diff --git a/src/v_video.cpp b/src/v_video.cpp index df7784548..51ef13e0a 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -111,6 +111,8 @@ CUSTOM_CVAR(Int, vid_rendermode, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN // [SP] Update pitch limits to the netgame/gamesim. players[consoleplayer].SendPitchLimits(); } + screen->SetTextureFilterMode(); + // No further checks needed. All this changes now is which scene drawer the render backend calls. } diff --git a/src/v_video.h b/src/v_video.h index 5567d1612..7e744a113 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -357,6 +357,7 @@ public: // Delete any resources that need to be deleted after restarting with a different IWAD virtual void CleanForRestart() {} + virtual void SetTextureFilterMode() {} // Begin 2D drawing operations. // Returns true if hardware-accelerated 2D has been entered, false if not. @@ -366,7 +367,6 @@ public: // Returns true if Begin2D has been called and 2D drawing is now active bool HasBegun2D() { return isIn2D; } - // DrawTexture calls after Begin2D use native textures. // Report a game restart virtual void GameRestart();