- removal of all code to handle OpenGL 2. From this commit on the main build of GZDoom will be OpenGL 3.3 or higher.

# Conflicts:
#	src/gl/renderer/gl_renderer.cpp
#	src/gl/shaders/gl_shader.cpp
#	src/gl/system/gl_framebuffer.cpp
#	src/gl_load/gl_interface.cpp
This commit is contained in:
Christoph Oelckers 2018-06-08 19:12:06 +02:00
parent 1455111ddc
commit 8ab68264c1
33 changed files with 222 additions and 2079 deletions

View file

@ -1010,8 +1010,6 @@ set (PCH_SOURCES
g_statusbar/sbarinfo.cpp g_statusbar/sbarinfo.cpp
g_statusbar/sbar_mugshot.cpp g_statusbar/sbar_mugshot.cpp
g_statusbar/shared_sbar.cpp g_statusbar/shared_sbar.cpp
gl/compatibility/gl_20.cpp
gl/compatibility/gl_swshader20.cpp
gl/data/gl_vertexbuffer.cpp gl/data/gl_vertexbuffer.cpp
gl/data/gl_uniformbuffer.cpp gl/data/gl_uniformbuffer.cpp
gl/dynlights/gl_lightbuffer.cpp gl/dynlights/gl_lightbuffer.cpp

View file

@ -116,7 +116,6 @@ extern void M_SetDefaultMode ();
extern void G_NewInit (); extern void G_NewInit ();
extern void SetupPlayerClasses (); extern void SetupPlayerClasses ();
extern void HUD_InitHud(); extern void HUD_InitHud();
void gl_PatchMenu(); // remove modern OpenGL options on old hardware.
void DeinitMenus(); void DeinitMenus();
const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad); const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
@ -2635,7 +2634,6 @@ void D_DoomMain (void)
} }
V_Init2(); V_Init2();
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); UpdateJoystickMenu(NULL);
v = Args->CheckValue ("-loadgame"); v = Args->CheckValue ("-loadgame");

File diff suppressed because it is too large Load diff

View file

@ -1,216 +0,0 @@
//
//---------------------------------------------------------------------------
//
// 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_load/gl_system.h"
#include "tarray.h"
#include "doomtype.h"
#include "r_utility.h"
#include "w_wad.h"
#include "gl/renderer/gl_renderer.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& vertex, const FString& fragment, 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; }
{
FString vertexsrc = defines + vertex;
int lengths[1] = { (int)vertexsrc.Len() };
const char *sources[1] = { vertexsrc.GetChars() };
glShaderSource(shader->VertexShader, 1, sources, lengths);
glCompileShader(shader->VertexShader);
}
{
FString fragmentsrc = defines + fragment;
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\n", 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\n", buffer);
delete shader;
return nullptr;
}
shader->ConstantLocations[0] = glGetUniformLocation(shader->Program, "uColor1");
shader->ConstantLocations[1] = glGetUniformLocation(shader->Program, "uColor2");
shader->ImageLocation = glGetUniformLocation(shader->Program, "tex");
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);
}
}

View file

@ -59,51 +59,25 @@ FVertexBuffer::~FVertexBuffer()
void FSimpleVertexBuffer::BindVBO() void FSimpleVertexBuffer::BindVBO()
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (!gl.legacyMode) glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->x);
{ glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->u);
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->x); glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &VSiO->color);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->u); glEnableVertexAttribArray(VATTR_VERTEX);
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &VSiO->color); glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_COLOR);
glEnableVertexAttribArray(VATTR_TEXCOORD); glDisableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
else
{
glVertexPointer(3, GL_FLOAT, sizeof(FSimpleVertex), &VSiO->x);
glTexCoordPointer(2, GL_FLOAT, sizeof(FSimpleVertex), &VSiO->u);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSimpleVertex), &VSiO->color);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
}
} }
void FSimpleVertexBuffer::EnableColorArray(bool on) void FSimpleVertexBuffer::EnableColorArray(bool on)
{ {
if (on) if (on)
{ {
if (!gl.legacyMode) glEnableVertexAttribArray(VATTR_COLOR);
{
glEnableVertexAttribArray(VATTR_COLOR);
}
else
{
glEnableClientState(GL_COLOR_ARRAY);
}
} }
else else
{ {
if (!gl.legacyMode) glDisableVertexAttribArray(VATTR_COLOR);
{
glDisableVertexAttribArray(VATTR_COLOR);
}
else
{
glDisableClientState(GL_COLOR_ARRAY);
}
} }
} }
@ -123,38 +97,25 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
//========================================================================== //==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
: FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height) : FVertexBuffer(true), FFlatVertexGenerator(width, height)
{ {
ibo_id = 0; ibo_id = 0;
if (gl.buffermethod != BM_LEGACY) glGenBuffers(1, &ibo_id); glGenBuffers(1, &ibo_id);
switch (gl.buffermethod) if (gl.buffermethod == BM_PERSISTENT)
{
case BM_PERSISTENT:
{ {
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
DPrintf(DMSG_NOTIFY, "Using persistent buffer\n"); DPrintf(DMSG_NOTIFY, "Using persistent buffer\n");
break;
} }
else
case BM_DEFERRED:
{ {
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW);
map = nullptr; map = nullptr;
DPrintf(DMSG_NOTIFY, "Using deferred buffer\n"); DPrintf(DMSG_NOTIFY, "Using deferred buffer\n");
break;
}
default:
{
map = new FFlatVertex[BUFFER_SIZE];
DPrintf(DMSG_NOTIFY, "Using client array buffer\n");
break;
}
} }
mIndex = mCurIndex = 0; mIndex = mCurIndex = 0;
mNumReserved = NUM_RESERVED; mNumReserved = NUM_RESERVED;
@ -178,10 +139,6 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ibo_id); glDeleteBuffers(1, &ibo_id);
} }
if (gl.legacyMode)
{
delete[] map;
}
map = nullptr; map = nullptr;
} }
@ -197,24 +154,13 @@ void FFlatVertexBuffer::BindVBO()
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
if (!gl.legacyMode) glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
{ glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glEnableVertexAttribArray(VATTR_VERTEX);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX); glDisableVertexAttribArray(VATTR_COLOR);
glEnableVertexAttribArray(VATTR_TEXCOORD); glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
else
{
glVertexPointer(3, GL_FLOAT, sizeof(FFlatVertex), &map->x);
glTexCoordPointer(2, GL_FLOAT, sizeof(FFlatVertex), &map->u);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
} }
void FFlatVertexBuffer::Map() void FFlatVertexBuffer::Map()

View file

@ -157,7 +157,7 @@ void FGLModelRenderer::DrawElements(int numIndices, size_t offset)
//=========================================================================== //===========================================================================
FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe)
: FVertexBuffer(singleframe || !gl.legacyMode) : FVertexBuffer(true)
{ {
vbo_ptr = nullptr; vbo_ptr = nullptr;
ibo_id = 0; ibo_id = 0;
@ -177,20 +177,11 @@ void FModelVertexBuffer::BindVBO()
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (!gl.legacyMode) glEnableVertexAttribArray(VATTR_VERTEX);
{ glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_NORMAL);
glEnableVertexAttribArray(VATTR_VERTEX2); glDisableVertexAttribArray(VATTR_COLOR);
glEnableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_COLOR);
}
else
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
} }
//=========================================================================== //===========================================================================
@ -223,10 +214,7 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size)
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, size * sizeof(FModelVertex), nullptr, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, size * sizeof(FModelVertex), nullptr, GL_STATIC_DRAW);
if (!gl.legacyMode) return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
else
return (FModelVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
} }
else else
{ {
@ -264,10 +252,7 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(unsigned int), NULL, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(unsigned int), NULL, GL_STATIC_DRAW);
if (!gl.legacyMode) return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
else
return (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
} }
else else
{ {
@ -304,19 +289,10 @@ void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (vbo_id > 0) if (vbo_id > 0)
{ {
if (!gl.legacyMode) glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x);
{ glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u);
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u); glVertexAttribPointer(VATTR_NORMAL, 4, GL_INT_2_10_10_10_REV, true, sizeof(FModelVertex), &VMO[frame2].packedNormal);
glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x);
glVertexAttribPointer(VATTR_NORMAL, 4, GL_INT_2_10_10_10_REV, true, sizeof(FModelVertex), &VMO[frame2].packedNormal);
}
else
{
// only used for single frame models so there is no vertex2 here, which has no use without a shader.
glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].u);
}
} }
else if (frame1 == frame2 || size == 0 || gl_RenderState.GetInterpolationFactor() == 0.f) else if (frame1 == frame2 || size == 0 || gl_RenderState.GetInterpolationFactor() == 0.f)
{ {

View file

@ -73,13 +73,10 @@ void FGLPostProcessState::SaveTextureBindings(unsigned int numUnits)
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
textureBinding.Push(texture); textureBinding.Push(texture);
if (gl.flags & RFL_SAMPLER_OBJECTS) GLint sampler;
{ glGetIntegerv(GL_SAMPLER_BINDING, &sampler);
GLint sampler; glBindSampler(i, 0);
glGetIntegerv(GL_SAMPLER_BINDING, &sampler); samplerBinding.Push(sampler);
glBindSampler(i, 0);
samplerBinding.Push(sampler);
}
} }
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }

View file

@ -928,7 +928,7 @@ void FGLRenderBuffers::BindOutputFB()
bool FGLRenderBuffers::IsEnabled() bool FGLRenderBuffers::IsEnabled()
{ {
return BuffersActive && !gl.legacyMode && !FailedCreate; return BuffersActive && !FailedCreate;
} }
bool FGLRenderBuffers::FailedCreate = false; bool FGLRenderBuffers::FailedCreate = false;

View file

@ -151,24 +151,14 @@ void FGLRenderer::Initialize(int width, int height)
mShadowMapShader = new FShadowMapShader(); mShadowMapShader = new FShadowMapShader();
mCustomPostProcessShaders = new FCustomPostProcessShaders(); mCustomPostProcessShaders = new FCustomPostProcessShaders();
if (gl.legacyMode)
{
legacyShaders = new LegacyShaderContainer;
}
// needed for the core profile, because someone decided it was a good idea to remove the default VAO. // needed for the core profile, because someone decided it was a good idea to remove the default VAO.
if (!gl.legacyMode) glGenVertexArrays(1, &mVAOID);
{ glBindVertexArray(mVAOID);
glGenVertexArrays(1, &mVAOID); FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
glBindVertexArray(mVAOID);
FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
}
else mVAOID = 0;
mVBO = new FFlatVertexBuffer(width, height); mVBO = new FFlatVertexBuffer(width, height);
mSkyVBO = new FSkyVertexBuffer; mSkyVBO = new FSkyVertexBuffer;
if (!gl.legacyMode) mLights = new FLightBuffer(); mLights = new FLightBuffer();
else mLights = NULL;
gl_RenderState.SetVertexBuffer(mVBO); gl_RenderState.SetVertexBuffer(mVBO);
mFBID = 0; mFBID = 0;
mOldFBID = 0; mOldFBID = 0;
@ -187,7 +177,6 @@ FGLRenderer::~FGLRenderer()
FlushModels(); FlushModels();
AActor::DeleteAllAttachedLights(); AActor::DeleteAllAttachedLights();
FMaterial::FlushAll(); FMaterial::FlushAll();
if (legacyShaders) delete legacyShaders;
if (mShaderManager != NULL) delete mShaderManager; if (mShaderManager != NULL) delete mShaderManager;
if (mSamplerManager != NULL) delete mSamplerManager; if (mSamplerManager != NULL) delete mSamplerManager;
if (mVBO != NULL) delete mVBO; if (mVBO != NULL) delete mVBO;
@ -313,7 +302,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
P_FindParticleSubsectors(); P_FindParticleSubsectors();
if (!gl.legacyMode) mLights->Clear(); mLights->Clear();
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
bool saved_niv = NoInterpolateView; bool saved_niv = NoInterpolateView;
@ -359,17 +348,8 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
int width = gltex->TextureWidth(); int width = gltex->TextureWidth();
int height = gltex->TextureHeight(); int height = gltex->TextureHeight();
if (gl.legacyMode) StartOffscreen();
{ gltex->BindToFrameBuffer();
// In legacy mode, fail if the requested texture is too large.
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
glFlush();
}
else
{
StartOffscreen();
gltex->BindToFrameBuffer();
}
IntRect bounds; IntRect bounds;
bounds.left = bounds.top = 0; bounds.left = bounds.top = 0;
@ -381,16 +361,7 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false); drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
if (gl.legacyMode) EndOffscreen();
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
EndOffscreen();
}
tex->SetUpdated(); tex->SetUpdated();
} }
@ -460,8 +431,6 @@ public:
// //
//=========================================================================== //===========================================================================
void LegacyColorOverlay(F2DDrawer *drawer, F2DDrawer::RenderCommand & cmd);
int LegacyDesaturation(F2DDrawer::RenderCommand &cmd);
CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE) CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
void FGLRenderer::Draw2D(F2DDrawer *drawer) void FGLRenderer::Draw2D(F2DDrawer *drawer)
@ -550,28 +519,12 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
{ {
auto index = cmd.mSpecialColormap - &SpecialColormaps[0]; auto index = cmd.mSpecialColormap - &SpecialColormaps[0];
if (index < 0 || (unsigned)index >= SpecialColormaps.Size()) index = 0; // if it isn't in the table FBitmap cannot use it. Shouldn't happen anyway. if (index < 0 || (unsigned)index >= SpecialColormaps.Size()) index = 0; // if it isn't in the table FBitmap cannot use it. Shouldn't happen anyway.
if (!gl.legacyMode || cmd.mTexture->UseType == ETextureType::SWCanvas) gl_RenderState.SetFixedColormap(CM_FIRSTSPECIALCOLORMAPFORCED + int(index));
{
gl_RenderState.SetFixedColormap(CM_FIRSTSPECIALCOLORMAPFORCED + int(index));
}
else
{
// map the special colormap to a translation for the legacy renderer.
// This only gets used on the software renderer's weapon sprite.
gltrans = STRange_Specialcolormap + index;
}
} }
else else
{ {
if (!gl.legacyMode)
{
gl_RenderState.SetFog(cmd.mColor1, 0); gl_RenderState.SetFog(cmd.mColor1, 0);
gl_RenderState.SetFixedColormap(CM_PLAIN2D); gl_RenderState.SetFixedColormap(CM_PLAIN2D);
}
else if (cmd.mDesaturate > 0)
{
gltrans = LegacyDesaturation(cmd);
}
} }
gl_RenderState.SetColor(1, 1, 1, 1, cmd.mDesaturate); gl_RenderState.SetColor(1, 1, 1, 1, cmd.mDesaturate);
@ -583,12 +536,6 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
auto mat = FMaterial::ValidateTexture(cmd.mTexture, false); auto mat = FMaterial::ValidateTexture(cmd.mTexture, false);
if (mat == nullptr) continue; 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(); 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.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1, cmd.mDrawMode == F2DDrawer::DTM_AlphaTexture);
gl_RenderState.EnableTexture(true); gl_RenderState.EnableTexture(true);
@ -612,11 +559,6 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
{ {
case F2DDrawer::DrawTypeTriangles: case F2DDrawer::DrawTypeTriangles:
glDrawElements(GL_TRIANGLES, cmd.mIndexCount, GL_UNSIGNED_INT, (const void *)(cmd.mIndexIndex * sizeof(unsigned int))); glDrawElements(GL_TRIANGLES, cmd.mIndexCount, GL_UNSIGNED_INT, (const void *)(cmd.mIndexIndex * sizeof(unsigned int)));
if (gl.legacyMode && cmd.mColor1 != 0)
{
// Draw the overlay as a separate operation.
LegacyColorOverlay(drawer, cmd);
}
break; break;
case F2DDrawer::DrawTypeLines: case F2DDrawer::DrawTypeLines:

View file

@ -60,29 +60,6 @@ enum
DM_SKYPORTAL 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 class FGLRenderer
{ {
public: public:
@ -135,7 +112,6 @@ public:
FSkyVertexBuffer *mSkyVBO; FSkyVertexBuffer *mSkyVBO;
FLightBuffer *mLights; FLightBuffer *mLights;
SWSceneDrawer *swdrawer = nullptr; SWSceneDrawer *swdrawer = nullptr;
LegacyShaderContainer *legacyShaders = nullptr;
bool mDrawingScene2D = false; bool mDrawingScene2D = false;
bool buffersActive = false; bool buffersActive = false;

View file

@ -348,14 +348,7 @@ void FRenderState::Apply()
else mVertexBuffer->BindVBO(); else mVertexBuffer->BindVBO();
mCurrentVertexBuffer = mVertexBuffer; mCurrentVertexBuffer = mVertexBuffer;
} }
if (!gl.legacyMode) ApplyShader();
{
ApplyShader();
}
else
{
ApplyFixedFunction();
}
} }
@ -385,38 +378,22 @@ void FRenderState::ApplyMatrices()
void FRenderState::ApplyLightIndex(int index) void FRenderState::ApplyLightIndex(int index)
{ {
if (!gl.legacyMode) if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER)
{ {
if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER) index = GLRenderer->mLights->BindUBO(index);
{
index = GLRenderer->mLights->BindUBO(index);
}
activeShader->muLightIndex.Set(index);
} }
activeShader->muLightIndex.Set(index);
} }
void FRenderState::SetClipHeight(float height, float direction) void FRenderState::SetClipHeight(float height, float direction)
{ {
mClipHeight = height; mClipHeight = height;
mClipHeightDirection = direction; mClipHeightDirection = direction;
#if 1
// This still doesn't work... :(
if (gl.flags & RFL_NO_CLIP_PLANES) return; if (gl.flags & RFL_NO_CLIP_PLANES) return;
#endif
if (direction != 0.f) if (direction != 0.f)
{ {
/*
if (gl.flags & RFL_NO_CLIP_PLANES)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(mViewMatrix.get());
// Plane mirrors never are slopes.
double d[4] = { 0, direction, 0, -direction * height };
glClipPlane(GL_CLIP_PLANE0, d);
glPopMatrix();
}
*/
glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE0);
} }
else else

View file

@ -148,9 +148,6 @@ public:
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
{ {
// alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations.
if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture;
if (mat->tex->bHasCanvas) if (mat->tex->bHasCanvas)
{ {
mTempTM = TM_OPAQUE; mTempTM = TM_OPAQUE;

View file

@ -173,15 +173,10 @@ void FDrawInfoList::Release(FDrawInfo * di)
FDrawInfo::FDrawInfo() FDrawInfo::FDrawInfo()
{ {
next = NULL; next = NULL;
if (gl.legacyMode)
{
dldrawlists = new HWDrawList[GLLDL_TYPES];
}
} }
FDrawInfo::~FDrawInfo() FDrawInfo::~FDrawInfo()
{ {
if (dldrawlists != NULL) delete[] dldrawlists;
ClearBuffers(); ClearBuffers();
} }
@ -214,10 +209,6 @@ void FDrawInfo::StartScene()
next = gl_drawinfo; next = gl_drawinfo;
gl_drawinfo = this; gl_drawinfo = this;
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset(); for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
if (dldrawlists != NULL)
{
for (int i = 0; i < GLLDL_TYPES; i++) dldrawlists[i].Reset();
}
decals[0].Clear(); decals[0].Clear();
decals[1].Clear(); decals[1].Clear();
hudsprites.Clear(); hudsprites.Clear();
@ -233,10 +224,6 @@ void FDrawInfo::EndDrawInfo()
FDrawInfo * di = gl_drawinfo; FDrawInfo * di = gl_drawinfo;
for(int i=0;i<GLDL_TYPES;i++) di->drawlists[i].Reset(); for(int i=0;i<GLDL_TYPES;i++) di->drawlists[i].Reset();
if (di->dldrawlists != NULL)
{
for (int i = 0; i < GLLDL_TYPES; i++) di->dldrawlists[i].Reset();
}
gl_drawinfo=di->next; gl_drawinfo=di->next;
di_list.Release(di); di_list.Release(di);
if (gl_drawinfo == nullptr) if (gl_drawinfo == nullptr)

View file

@ -25,41 +25,12 @@ enum DrawListType
GLDL_TYPES, GLDL_TYPES,
}; };
// more lists for handling of dynamic lights
enum DLDrawListType
{
// These are organized so that the various multipass rendering modes have to be set as few times as possible
GLLDL_WALLS_PLAIN, // dynamic lights on normal walls
GLLDL_WALLS_MASKED, // dynamic lights on masked midtextures
GLLDL_FLATS_PLAIN, // dynamic lights on normal flats
GLLDL_FLATS_MASKED, // dynamic lights on masked flats
GLLDL_WALLS_FOG, // lights on fogged walls
GLLDL_WALLS_FOGMASKED, // lights on fogged masked midtextures
GLLDL_FLATS_FOG, // lights on fogged walls
GLLDL_FLATS_FOGMASKED, // lights on fogged masked midtextures
GLLDL_TYPES,
};
enum Drawpasses enum Drawpasses
{ {
GLPASS_ALL, // Main pass with dynamic lights GLPASS_ALL, // Main pass with dynamic lights
GLPASS_LIGHTSONLY, // only collect dynamic lights GLPASS_LIGHTSONLY, // only collect dynamic lights
GLPASS_DECALS, // Draws a decal GLPASS_DECALS, // Draws a decal
GLPASS_TRANSLUCENT, // Draws translucent objects GLPASS_TRANSLUCENT, // Draws translucent objects
// these are only used with texture based dynamic lights
GLPASS_BASE, // untextured base for dynamic lights
GLPASS_BASE_MASKED, // same but with active texture
GLPASS_LIGHTTEX, // lighttexture pass
GLPASS_TEXONLY, // finishing texture pass
GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive)
GLPASS_LIGHTTEX_FOGGY, // lighttexture pass on foggy surfaces (forces all lights to be additive)
}; };
struct FDrawInfo : public HWDrawInfo struct FDrawInfo : public HWDrawInfo
@ -70,7 +41,6 @@ struct FDrawInfo : public HWDrawInfo
HWDrawList drawlists[GLDL_TYPES]; HWDrawList drawlists[GLDL_TYPES];
TArray<HUDSprite> hudsprites; // These may just be stored by value. TArray<HUDSprite> hudsprites; // These may just be stored by value.
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass. TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
HWDrawList *dldrawlists = NULL; // only gets allocated when needed.
FDrawInfo(); FDrawInfo();
~FDrawInfo(); ~FDrawInfo();

View file

@ -213,11 +213,6 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
gl_RenderState.Apply(); gl_RenderState.Apply();
auto iboindex = flat->iboindex; auto iboindex = flat->iboindex;
if (gl.legacyMode)
{
processlights = false;
iboindex = -1;
}
if (iboindex >= 0) if (iboindex >= 0)
{ {
@ -391,25 +386,12 @@ void FDrawInfo::DrawFlat(GLFlat *flat, int pass, bool trans) // trans only has m
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false); gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false);
gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture); gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture);
DrawSubsectors(flat, pass, !gl.legacyMode && (gl.lightmethod == LM_DIRECT || flat->dynlightindex > -1), true); DrawSubsectors(flat, pass, (gl.lightmethod == LM_DIRECT || flat->dynlightindex > -1), true);
gl_RenderState.EnableTextureMatrix(false); gl_RenderState.EnableTextureMatrix(false);
} }
if (flat->renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (flat->renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetObjectColor(0xffffffff);
break; break;
case GLPASS_LIGHTTEX:
case GLPASS_LIGHTTEX_ADDITIVE:
case GLPASS_LIGHTTEX_FOGGY:
DrawLightsCompat(flat, pass);
break;
case GLPASS_TEXONLY:
gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false);
gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture);
DrawSubsectors(flat, pass, false, false);
gl_RenderState.EnableTextureMatrix(false);
break;
} }
} }
@ -426,10 +408,6 @@ void FDrawInfo::AddFlat(GLFlat *flat, bool fog)
{ {
int list; int list;
if (gl.legacyMode)
{
if (PutFlatCompat(flat, fog)) return;
}
if (flat->renderstyle != STYLE_Translucent || flat->alpha < 1.f - FLT_EPSILON || fog || flat->gltexture == nullptr) if (flat->renderstyle != STYLE_Translucent || flat->alpha < 1.f - FLT_EPSILON || fog || flat->gltexture == nullptr)
{ {
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list. // translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.

View file

@ -306,20 +306,7 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
int pass; int pass = GLPASS_ALL;
if (!level.HasDynamicLights || !gl.legacyMode)
{
pass = GLPASS_ALL;
}
else // GL 2.x legacy mode
{
// process everything that needs to handle textured dynamic lights.
if (level.HasDynamicLights) RenderMultipassStuff(di);
// The remaining lists which are unaffected by dynamic lights are just processed as normal.
pass = GLPASS_ALL;
}
gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableTexture(gl_texture);
gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableBrightmap(true);
@ -529,11 +516,6 @@ void GLSceneDrawer::DrawEndScene2D(FDrawInfo *di, sector_t * viewsector)
di->DrawPlayerSprites(false); di->DrawPlayerSprites(false);
if (gl.legacyMode)
{
gl_RenderState.DrawColormapOverlay();
}
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1); gl_RenderState.SetSoftLightLevel(-1);
@ -728,7 +710,7 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
SetFixedColormap(player); SetFixedColormap(player);
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
GLRenderer->mVBO->Reset(); GLRenderer->mVBO->Reset();
if (!gl.legacyMode) GLRenderer->mLights->Clear(); GLRenderer->mLights->Clear();
sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false); sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);

View file

@ -54,26 +54,14 @@ FSkyVertexBuffer::FSkyVertexBuffer()
void FSkyVertexBuffer::BindVBO() void FSkyVertexBuffer::BindVBO()
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (!gl.legacyMode) glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x);
{ glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u);
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x); glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u); glEnableVertexAttribArray(VATTR_VERTEX);
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color); glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_COLOR);
glEnableVertexAttribArray(VATTR_TEXCOORD); glDisableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
else
{
glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x);
glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSkyVertex), &VSO->color);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -111,11 +99,6 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode)
gl_RenderState.Apply(); gl_RenderState.Apply();
RenderRow(GL_TRIANGLE_FAN, rc); RenderRow(GL_TRIANGLE_FAN, rc);
gl_RenderState.EnableTexture(true); gl_RenderState.EnableTexture(true);
// The color array can only be activated now if this is drawn without shader
if (gl.legacyMode)
{
glEnableClientState(GL_COLOR_ARRAY);
}
} }
gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetObjectColor(0xffffffff);
gl_RenderState.Apply(); gl_RenderState.Apply();

View file

@ -67,25 +67,18 @@ void FDrawInfo::RenderFogBoundary(GLWall *wall)
{ {
if (gl_fogmode && mDrawer->FixedColormap == 0) if (gl_fogmode && mDrawer->FixedColormap == 0)
{ {
if (!gl.legacyMode) int rel = wall->rellight + getExtraLight();
{ mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, false);
int rel = wall->rellight + getExtraLight(); gl_RenderState.EnableDrawBuffers(1);
mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, false); gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.EnableDrawBuffers(1); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY); glEnable(GL_POLYGON_OFFSET_FILL);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); glPolygonOffset(-1.0f, -128.0f);
glEnable(GL_POLYGON_OFFSET_FILL); RenderWall(wall, GLWall::RWF_BLANK);
glPolygonOffset(-1.0f, -128.0f); glPolygonOffset(0.0f, 0.0f);
RenderWall(wall, GLWall::RWF_BLANK); glDisable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.0f, 0.0f); gl_RenderState.SetEffect(EFF_NONE);
glDisable(GL_POLYGON_OFFSET_FILL); gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
}
else
{
RenderFogBoundaryCompat(wall);
}
} }
} }
@ -99,17 +92,9 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
{ {
if (!TexMan.mirrorTexture.isValid()) return; if (!TexMan.mirrorTexture.isValid()) return;
if (!gl.legacyMode) // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
{ gl_RenderState.EnableTextureMatrix(true);
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
gl_RenderState.EnableTextureMatrix(true);
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
}
else
{
FVector3 v = wall->glseg.Normal();
glNormal3fv(&v[0]);
}
// Use sphere mapping for this // Use sphere mapping for this
gl_RenderState.SetEffect(EFF_SPHEREMAP); gl_RenderState.SetEffect(EFF_SPHEREMAP);
@ -258,7 +243,7 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
{ {
if (screen->hwcaps & RFL_BUFFER_STORAGE) if (screen->hwcaps & RFL_BUFFER_STORAGE)
{ {
if (level.HasDynamicLights && FixedColormap == CM_DEFAULT && wall->gltexture != nullptr && !(screen->hwcaps & RFL_NO_SHADERS)) if (level.HasDynamicLights && FixedColormap == CM_DEFAULT && wall->gltexture != nullptr)
{ {
wall->SetupLights(this, lightdata); wall->SetupLights(this, lightdata);
} }
@ -289,17 +274,6 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
break; break;
} }
break; break;
case GLPASS_LIGHTTEX:
case GLPASS_LIGHTTEX_ADDITIVE:
case GLPASS_LIGHTTEX_FOGGY:
RenderLightsCompat(wall, pass);
break;
case GLPASS_TEXONLY:
gl_RenderState.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1, false);
RenderWall(wall, GLWall::RWF_TEXTURED);
break;
} }
} }
@ -318,11 +292,6 @@ void FDrawInfo::AddWall(GLWall *wall)
} }
else else
{ {
if (gl.legacyMode)
{
if (PutWallCompat(wall, GLWall::passflag[wall->type])) return;
}
bool masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked()); bool masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked());
int list; int list;

View file

@ -179,9 +179,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize(); unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize();
if (lightbuffertype == GL_UNIFORM_BUFFER) if (lightbuffertype == GL_UNIFORM_BUFFER)
{ {
if (gl.es)
{ {
vp_comb.Format("#version 300 es\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
} }
else else
{ {
@ -360,7 +358,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix"); normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix");
quadmode_index = glGetUniformLocation(hShader, "uQuadMode"); quadmode_index = glGetUniformLocation(hShader, "uQuadMode");
if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
{ {
int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO");
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT);
@ -422,7 +420,6 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP
FString defines; FString defines;
defines += shaderdefines; defines += shaderdefines;
// this can't be in the shader code due to ATI strangeness. // this can't be in the shader code due to ATI strangeness.
if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
if (!usediscard) defines += "#define NO_ALPHATEST\n"; if (!usediscard) defines += "#define NO_ALPHATEST\n";
if (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n"; if (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n";
@ -518,30 +515,17 @@ static const FEffectShader effectshaders[]=
FShaderManager::FShaderManager() FShaderManager::FShaderManager()
{ {
if (!gl.legacyMode) for (int passType = 0; passType < MAX_PASS_TYPES; passType++)
{ mPassShaders.Push(new FShaderCollection((EPassType)passType));
if (gl.es) // OpenGL ES does not support multiple fragment shader outputs. As a result, no GBUFFER passes are possible.
{
mPassShaders.Push(new FShaderCollection(NORMAL_PASS));
}
else
{
for (int passType = 0; passType < MAX_PASS_TYPES; passType++)
mPassShaders.Push(new FShaderCollection((EPassType)passType));
}
}
} }
FShaderManager::~FShaderManager() FShaderManager::~FShaderManager()
{ {
if (!gl.legacyMode) glUseProgram(0);
{ mActiveShader = NULL;
glUseProgram(0);
mActiveShader = NULL;
for (auto collection : mPassShaders) for (auto collection : mPassShaders)
delete collection; delete collection;
}
} }
void FShaderManager::SetActiveShader(FShader *sh) void FShaderManager::SetActiveShader(FShader *sh)
@ -571,21 +555,11 @@ FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passT
void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view, EPassType passType) void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view, EPassType passType)
{ {
if (gl.legacyMode) if (passType < mPassShaders.Size())
{ mPassShaders[passType]->ApplyMatrices(proj, view);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj->get());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view->get());
}
else
{
if (passType < mPassShaders.Size())
mPassShaders[passType]->ApplyMatrices(proj, view);
if (mActiveShader) if (mActiveShader)
mActiveShader->Bind(); mActiveShader->Bind();
}
} }
void FShaderManager::ResetFixedColormap() void FShaderManager::ResetFixedColormap()

View file

@ -224,10 +224,7 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const
// If we have 4.2, always use it because it adds important new syntax. // If we have 4.2, always use it because it adds important new syntax.
if (maxGlslVersion < 420 && gl.glslversion >= 4.2f) maxGlslVersion = 420; if (maxGlslVersion < 420 && gl.glslversion >= 4.2f) maxGlslVersion = 420;
int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion); int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion);
if (gl.es) patchedCode.AppendFormat("#version %d\n", shaderVersion);
patchedCode.AppendFormat("#version %d es\n", shaderVersion);
else
patchedCode.AppendFormat("#version %d\n", shaderVersion);
// TODO: Find some way to add extension requirements to the patching // TODO: Find some way to add extension requirements to the patching
// //

View file

@ -62,8 +62,6 @@ void Stereo3DMode::setCurrentMode(const Stereo3DMode& mode) {
/* static */ /* static */
const Stereo3DMode& Stereo3DMode::getCurrentMode() const Stereo3DMode& Stereo3DMode::getCurrentMode()
{ {
if (gl.legacyMode) vr_mode = 0; // GL 2 does not support this feature.
// NOTE: Ensure that these vr_mode values correspond to the ones in wadsrc/static/menudef.z // NOTE: Ensure that these vr_mode values correspond to the ones in wadsrc/static/menudef.z
switch (vr_mode) switch (vr_mode)
{ {

View file

@ -86,7 +86,6 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int
// Move some state to the framebuffer object for easier access. // Move some state to the framebuffer object for easier access.
hwcaps = gl.flags; hwcaps = gl.flags;
if (gl.legacyMode) hwcaps |= RFL_NO_SHADERS;
glslversion = gl.glslversion; glslversion = gl.glslversion;
} }
@ -134,7 +133,6 @@ void OpenGLFrameBuffer::InitializeState()
glEnable(GL_BLEND); glEnable(GL_BLEND);
glEnable(GL_DEPTH_CLAMP); glEnable(GL_DEPTH_CLAMP);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
if (gl.legacyMode) glEnable(GL_TEXTURE_2D);
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -243,12 +241,8 @@ uint32_t OpenGLFrameBuffer::GetCaps()
RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL; RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL;
if (r_drawvoxels) if (r_drawvoxels)
FlagSet |= RFF_VOXELS; FlagSet |= RFF_VOXELS;
if (gl.legacyMode)
{ if (!RenderBuffersEnabled())
// legacy mode always has truecolor because palette tonemap is not available
FlagSet |= RFF_TRUECOLOR;
}
else if (!RenderBuffersEnabled())
{ {
// truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible // truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible
FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP; FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP;

View file

@ -133,10 +133,6 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
GLRenderer->mBuffers->BindCurrentFB(); GLRenderer->mBuffers->BindCurrentFB();
copyPixels(); copyPixels();
} }
else if (gl.legacyMode)
{
copyPixels();
}
else else
{ {
GLint readbuffer = 0; GLint readbuffer = 0;

View file

@ -233,23 +233,11 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
if (glTextureBytes > 0) if (glTextureBytes > 0)
{ {
if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (gl.legacyMode) static const int ITypes[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
{ static const int STypes[] = { GL_RED, GL_RG, GL_BGR, GL_BGRA };
// Do not use 2 and 3 here. They won't do anything useful!!!
static const int ITypes[] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 };
static const int STypes[] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA };
texformat = ITypes[glTextureBytes - 1]; texformat = ITypes[glTextureBytes - 1];
sourcetype = STypes[glTextureBytes - 1]; sourcetype = STypes[glTextureBytes - 1];
}
else
{
static const int ITypes[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
static const int STypes[] = { GL_RED, GL_RG, GL_BGR, GL_BGRA };
texformat = ITypes[glTextureBytes - 1];
sourcetype = STypes[glTextureBytes - 1];
}
} }
else else
{ {
@ -539,7 +527,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
bool needmipmap = (clampmode <= CLAMP_XY); bool needmipmap = (clampmode <= CLAMP_XY);
// Texture has become invalid // Texture has become invalid
if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified(DefaultRenderStyle())) if (!tex->bHasCanvas && !tex->bWarped && tex->CheckModified(DefaultRenderStyle()))
{ {
Clean(true); Clean(true);
} }
@ -555,7 +543,6 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
if (!tex->bHasCanvas) if (!tex->bHasCanvas)
{ {
if (gl.legacyMode) flags |= CTF_MaybeWarped;
buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData); buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData);
} }
else else

View file

@ -35,163 +35,66 @@ extern TexFilter_s TexFilter[];
FSamplerManager::FSamplerManager() FSamplerManager::FSamplerManager()
{ {
if (gl.flags & RFL_SAMPLER_OBJECTS) glGenSamplers(7, mSamplers);
SetTextureFilterMode();
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
for (int i = 0; i < 7; i++)
{ {
glGenSamplers(7, mSamplers); FString name;
SetTextureFilterMode(); name.Format("mSamplers[%d]", i);
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST); FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name.GetChars());
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
for (int i = 0; i < 7; i++)
{
FString name;
name.Format("mSamplers[%d]", i);
FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name.GetChars());
}
} }
} }
FSamplerManager::~FSamplerManager() FSamplerManager::~FSamplerManager()
{ {
if (gl.flags & RFL_SAMPLER_OBJECTS) UnbindAll();
{ glDeleteSamplers(7, mSamplers);
UnbindAll();
glDeleteSamplers(7, mSamplers);
}
} }
void FSamplerManager::UnbindAll() void FSamplerManager::UnbindAll()
{ {
if (gl.flags & RFL_SAMPLER_OBJECTS) for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++)
{ {
for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++) glBindSampler(i, 0);
{
glBindSampler(i, 0);
}
} }
} }
uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) uint8_t FSamplerManager::Bind(int texunit, int num, int lastval)
{ {
if (gl.flags & RFL_SAMPLER_OBJECTS) unsigned int samp = mSamplers[num];
{ glBindSampler(texunit, samp);
unsigned int samp = mSamplers[num]; return 255;
glBindSampler(texunit, samp);
return 255;
}
else
{
int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0;
glActiveTexture(GL_TEXTURE0 + texunit);
switch (num)
{
case CLAMP_NONE:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (lastval >= CLAMP_XY_NOMIP)
{
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;
case CLAMP_X:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (lastval >= CLAMP_XY_NOMIP)
{
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;
case CLAMP_Y:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
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[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;
case CLAMP_XY:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
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[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;
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[filter].magfilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
case CLAMP_NOFILTER:
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, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
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[filter].magfilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
}
glActiveTexture(GL_TEXTURE0);
return num;
}
} }
void FSamplerManager::SetTextureFilterMode() void FSamplerManager::SetTextureFilterMode()
{ {
if (gl.flags & RFL_SAMPLER_OBJECTS) UnbindAll();
{ int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0;
UnbindAll();
int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{
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[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
{ {
GLRenderer->FlushTextures(); 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[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);
} }

View file

@ -35,7 +35,6 @@
#include "gl_load/gl_interface.h" #include "gl_load/gl_interface.h"
#include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/utility/hw_cvars.h"
void gl_PatchMenu();
static TArray<FString> m_Extensions; static TArray<FString> m_Extensions;
RenderContext gl; RenderContext gl;
static double realglversion; // this is public so the statistics code can access it. static double realglversion; // this is public so the statistics code can access it.
@ -129,13 +128,6 @@ void gl_LoadExtensions()
CollectExtensions(); CollectExtensions();
const char *glversion = (const char*)glGetString(GL_VERSION); const char *glversion = (const char*)glGetString(GL_VERSION);
gl.es = false;
if (glversion && strlen(glversion) > 10 && memcmp(glversion, "OpenGL ES ", 10) == 0)
{
glversion += 10;
gl.es = true;
}
const char *version = Args->CheckValue("-glversion"); const char *version = Args->CheckValue("-glversion");
realglversion = strtod(glversion, NULL); realglversion = strtod(glversion, NULL);
@ -148,138 +140,96 @@ void gl_LoadExtensions()
else else
{ {
double v1 = strtod(version, NULL); double v1 = strtod(version, NULL);
if (v1 >= 3.0 && v1 < 3.3) v1 = 3.3; // promote '3' to 3.3 to avoid falling back to the legacy path. if (v1 >= 3.0 && v1 < 3.3)
{
v1 = 3.3; // promote '3' to 3.3 to avoid falling back to the legacy path.
version = "3.3";
}
if (realglversion < v1) version = glversion; if (realglversion < v1) version = glversion;
else Printf("Emulating OpenGL v %s\n", version); else Printf("Emulating OpenGL v %s\n", version);
} }
float gl_version = (float)strtod(version, NULL) + 0.01f; float gl_version = (float)strtod(version, NULL) + 0.01f;
if (gl.es) // Don't even start if it's lower than 2.0 or no framebuffers are available (The framebuffer extension is needed for glGenerateMipmapsEXT!)
if (gl_version < 3.3f)
{ {
if (gl_version < 2.0f) I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.3 with framebuffer support is required to run " GAMENAME ".\nFor older versions of OpenGL please download the vintage build of " GAMENAME ".\n");
{ }
I_FatalError("Unsupported OpenGL ES version.\nAt least OpenGL ES 2.0 is required to run " GAMENAME ".\n");
}
const char *glslversion = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
if (glslversion && strlen(glslversion) > 18 && memcmp(glslversion, "OpenGL ES GLSL ES ", 10) == 0)
{
glslversion += 18;
}
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
gl.glslversion = strtod(glslversion, NULL) + 0.01f;
gl.vendorstring = (char*)glGetString(GL_VENDOR);
// Use the slowest/oldest modern path for now
gl.legacyMode = false; // add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
gl.lightmethod = LM_DEFERRED; gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f;
gl.buffermethod = BM_DEFERRED;
gl.flags |= RFL_NO_CLIP_PLANES; gl.vendorstring = (char*)glGetString(GL_VENDOR);
// first test for optional features
if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION;
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC;
gl.lightmethod = LM_DEFERRED;
gl.buffermethod = BM_DEFERRED;
if (gl_version < 4.f)
{
#ifdef _WIN32
if (strstr(gl.vendorstring, "ATI Tech"))
{
gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows. (TBD: Relegate to vintage build? Maybe after the next survey.)
}
#endif
gl.glslversion = 3.31f; // Force GLSL down to 3.3.
}
else if (gl_version < 4.5f)
{
// don't use GL 4.x features when running a GL 3.x context.
if (CheckExtension("GL_ARB_buffer_storage"))
{
// work around a problem with older AMD drivers: Their implementation of shader storage buffer objects is piss-poor and does not match uniform buffers even closely.
// Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension.
if (CheckExtension("GL_ARB_shader_storage_buffer_object"))
{
// Intel's GLSL compiler is a bit broken with extensions, so unlock the feature only if not on Intel or having GL 4.3.
if (strstr(gl.vendorstring, "Intel") == NULL || gl_version >= 4.3f)
{
// Mesa implements shader storage only for fragment shaders.
// Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects.
int v;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
if (v > 0)
gl.flags |= RFL_SHADER_STORAGE_BUFFER;
}
}
gl.flags |= RFL_BUFFER_STORAGE;
gl.lightmethod = LM_DIRECT;
gl.buffermethod = BM_PERSISTENT;
}
} }
else else
{ {
// Don't even start if it's lower than 2.0 or no framebuffers are available (The framebuffer extension is needed for glGenerateMipmapsEXT!) // Assume that everything works without problems on GL 4.5 drivers where these things are core features.
if ((gl_version < 2.0f || !CheckExtension("GL_EXT_framebuffer_object")) && gl_version < 3.0f) gl.flags |= RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE;
{ gl.lightmethod = LM_DIRECT;
I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 2.0 with framebuffer support is required to run " GAMENAME ".\n"); gl.buffermethod = BM_PERSISTENT;
} }
gl.es = false;
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version if (gl_version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER;
gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f; if (gl_version >= 4.3f || CheckExtension("GL_KHR_debug")) gl.flags |= RFL_DEBUG;
gl.vendorstring = (char*)glGetString(GL_VENDOR); const char *lm = Args->CheckValue("-lightmethod");
if (lm != NULL)
{
if (!stricmp(lm, "deferred") && gl.lightmethod == LM_DIRECT) gl.lightmethod = LM_DEFERRED;
}
// first test for optional features lm = Args->CheckValue("-buffermethod");
if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; if (lm != NULL)
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC; {
if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED;
if ((gl_version >= 3.3f || CheckExtension("GL_ARB_sampler_objects")) && !Args->CheckParm("-nosampler"))
{
gl.flags |= RFL_SAMPLER_OBJECTS;
}
// The minimum requirement for the modern render path is GL 3.3.
// Although some GL 3.1 or 3.2 solutions may theoretically work they are usually too broken or too slow.
if (gl_version < 3.3f)
{
gl.legacyMode = true;
gl.lightmethod = LM_LEGACY;
gl.buffermethod = BM_LEGACY;
gl.glslversion = 0;
gl.flags |= RFL_NO_CLIP_PLANES;
}
else
{
gl.legacyMode = false;
gl.lightmethod = LM_DEFERRED;
gl.buffermethod = BM_DEFERRED;
if (gl_version < 4.f)
{
#ifdef _WIN32
if (strstr(gl.vendorstring, "ATI Tech"))
{
gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows.
}
#endif
gl.glslversion = 3.31f; // Force GLSL down to 3.3.
}
else if (gl_version < 4.5f)
{
// don't use GL 4.x features when running a GL 3.x context.
if (CheckExtension("GL_ARB_buffer_storage"))
{
// work around a problem with older AMD drivers: Their implementation of shader storage buffer objects is piss-poor and does not match uniform buffers even closely.
// Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension.
if (CheckExtension("GL_ARB_shader_storage_buffer_object"))
{
// Intel's GLSL compiler is a bit broken with extensions, so unlock the feature only if not on Intel or having GL 4.3.
if (strstr(gl.vendorstring, "Intel") == NULL || gl_version >= 4.3f)
{
// Mesa implements shader storage only for fragment shaders.
// Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects.
int v;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
if (v > 0)
gl.flags |= RFL_SHADER_STORAGE_BUFFER;
}
}
gl.flags |= RFL_BUFFER_STORAGE;
gl.lightmethod = LM_DIRECT;
gl.buffermethod = BM_PERSISTENT;
}
}
else
{
// Assume that everything works without problems on GL 4.5 drivers where these things are core features.
gl.flags |= RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE;
gl.lightmethod = LM_DIRECT;
gl.buffermethod = BM_PERSISTENT;
}
if (gl_version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER;
if (gl_version >= 4.3f || CheckExtension("GL_KHR_debug")) gl.flags |= RFL_DEBUG;
const char *lm = Args->CheckValue("-lightmethod");
if (lm != NULL)
{
if (!stricmp(lm, "deferred") && gl.lightmethod == LM_DIRECT) gl.lightmethod = LM_DEFERRED;
}
lm = Args->CheckValue("-buffermethod");
if (lm != NULL)
{
if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED;
}
}
} }
int v; int v;
if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
{ {
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v);
gl.maxuniforms = v; gl.maxuniforms = v;
@ -294,34 +244,10 @@ void gl_LoadExtensions()
gl.maxuniformblock = 0; gl.maxuniformblock = 0;
gl.uniformblockalignment = 0; gl.uniformblockalignment = 0;
} }
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (gl.legacyMode)
{
// fudge a bit with the framebuffer stuff to avoid redundancies in the main code. Some of the older cards do not have the ARB stuff but the calls are nearly identical.
FUDGE_FUNC(glGenerateMipmap, EXT);
FUDGE_FUNC(glGenFramebuffers, EXT);
FUDGE_FUNC(glBindFramebuffer, EXT);
FUDGE_FUNC(glDeleteFramebuffers, EXT);
FUDGE_FUNC(glFramebufferTexture2D, EXT);
FUDGE_FUNC(glGenerateMipmap, EXT);
FUDGE_FUNC(glGenFramebuffers, EXT);
FUDGE_FUNC(glBindFramebuffer, EXT);
FUDGE_FUNC(glDeleteFramebuffers, EXT);
FUDGE_FUNC(glFramebufferTexture2D, EXT);
FUDGE_FUNC(glFramebufferRenderbuffer, EXT);
FUDGE_FUNC(glGenRenderbuffers, EXT);
FUDGE_FUNC(glDeleteRenderbuffers, EXT);
FUDGE_FUNC(glRenderbufferStorage, EXT);
FUDGE_FUNC(glBindRenderbuffer, EXT);
FUDGE_FUNC(glCheckFramebufferStatus, EXT);
}
UCVarValue value;
value.Bool = gl.legacyMode;
} }
//========================================================================== //==========================================================================
@ -333,7 +259,7 @@ void gl_LoadExtensions()
void gl_PrintStartupLog() void gl_PrintStartupLog()
{ {
int v = 0; int v = 0;
if (!gl.legacyMode) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v);
Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
@ -352,7 +278,7 @@ void gl_PrintStartupLog()
glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); glGetIntegerv(GL_MAX_VARYING_FLOATS, &v);
Printf ("Max. varying: %d\n", v); Printf ("Max. varying: %d\n", v);
if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
{ {
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v);
Printf ("Max. uniform block size: %d\n", v); Printf ("Max. uniform block size: %d\n", v);

View file

@ -3,17 +3,8 @@
#include "basictypes.h" #include "basictypes.h"
enum GLCompat
{
CMPT_GL2,
CMPT_GL2_SHADER,
CMPT_GL3,
CMPT_GL4
};
enum TexMode 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_MODULATE = 0, // (r, g, b, a)
TM_MASK, // (1, 1, 1, a) TM_MASK, // (1, 1, 1, a)
TM_OPAQUE, // (r, g, b, 1) TM_OPAQUE, // (r, g, b, 1)
@ -26,14 +17,12 @@ enum TexMode
enum ELightMethod enum ELightMethod
{ {
LM_LEGACY = 0, // placeholder for legacy mode (textured lights), should not be checked anywhere in the code!
LM_DEFERRED = 1, // calculate lights up front in a separate pass LM_DEFERRED = 1, // calculate lights up front in a separate pass
LM_DIRECT = 2, // calculate lights on the fly along with the render data LM_DIRECT = 2, // calculate lights on the fly along with the render data
}; };
enum EBufferMethod enum EBufferMethod
{ {
BM_LEGACY = 0, // placeholder for legacy mode (client arrays), should not be checked anywhere in the code!
BM_DEFERRED = 1, // use a temporarily mapped buffer, for GL 3.x core profile BM_DEFERRED = 1, // use a temporarily mapped buffer, for GL 3.x core profile
BM_PERSISTENT = 2 // use a persistently mapped buffer BM_PERSISTENT = 2 // use a persistently mapped buffer
}; };
@ -50,13 +39,6 @@ struct RenderContext
float glslversion; float glslversion;
int max_texturesize; int max_texturesize;
char * vendorstring; char * vendorstring;
bool legacyMode;
bool es;
int MaxLights() const
{
return maxuniforms>=2048? 128:64;
}
}; };
extern RenderContext gl; extern RenderContext gl;

View file

@ -219,7 +219,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v)
inline void GLSprite::PutSprite(HWDrawInfo *di, bool translucent) inline void GLSprite::PutSprite(HWDrawInfo *di, bool translucent)
{ {
// That's a lot of checks... // That's a lot of checks...
if (modelframe && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && level.HasDynamicLights && di->FixedColormap == CM_DEFAULT && !fullbright && !(screen->hwcaps & RFL_NO_SHADERS)) if (modelframe && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && level.HasDynamicLights && di->FixedColormap == CM_DEFAULT && !fullbright)
{ {
hw_GetDynModelLight(actor, lightdata); hw_GetDynModelLight(actor, lightdata);
dynlightindex = di->UploadLights(lightdata); dynlightindex = di->UploadLights(lightdata);
@ -709,7 +709,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
RenderStyle.CheckFuzz(); RenderStyle.CheckFuzz();
if (RenderStyle.BlendOp == STYLEOP_Fuzz) if (RenderStyle.BlendOp == STYLEOP_Fuzz)
{ {
if (gl_fuzztype != 0 && !(screen->hwcaps & RFL_NO_SHADERS) && !(RenderStyle.Flags & STYLEF_InvertSource)) if (gl_fuzztype != 0 && !(RenderStyle.Flags & STYLEF_InvertSource))
{ {
RenderStyle = LegacyRenderStyles[STYLE_Translucent]; RenderStyle = LegacyRenderStyles[STYLE_Translucent];
OverrideShader = SHADER_NoTexture + gl_fuzztype; OverrideShader = SHADER_NoTexture + gl_fuzztype;

View file

@ -50,7 +50,6 @@ void GLWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
{ {
lightdata.Clear(); lightdata.Clear();
if (screen->hwcaps & RFL_NO_SHADERS) return; // useless in OpenGL 2.
if (RenderStyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces. if (RenderStyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces.
// check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.) // check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.)
@ -185,7 +184,7 @@ void GLWall::PutWall(HWDrawInfo *di, bool translucent)
if (!(screen->hwcaps & RFL_BUFFER_STORAGE)) if (!(screen->hwcaps & RFL_BUFFER_STORAGE))
{ {
if (level.HasDynamicLights && di->FixedColormap == CM_DEFAULT && gltexture != nullptr && !(screen->hwcaps & RFL_NO_SHADERS)) if (level.HasDynamicLights && di->FixedColormap == CM_DEFAULT && gltexture != nullptr)
{ {
SetupLights(di, lightdata); SetupLights(di, lightdata);
} }

View file

@ -467,7 +467,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area)
// set the lighting parameters // set the lighting parameters
if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && level.HasDynamicLights && FixedColormap == CM_DEFAULT && gl_light_sprites) if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && level.HasDynamicLights && FixedColormap == CM_DEFAULT && gl_light_sprites)
{ {
if (!hudModelStep || (screen->hwcaps & RFL_NO_SHADERS)) if (!hudModelStep)
{ {
GetDynSpriteLight(playermo, nullptr, hudsprite.dynrgb); GetDynSpriteLight(playermo, nullptr, hudsprite.dynrgb);
} }

View file

@ -1371,7 +1371,7 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int
int isTransparent = -1; int isTransparent = -1;
if ((flags & CTF_CheckHires) && translation != STRange_AlphaTexture) if (flags & CTF_CheckHires)
{ {
buffer = LoadHiresTexture(&w, &h); buffer = LoadHiresTexture(&w, &h);
if (buffer != nullptr) if (buffer != nullptr)
@ -1389,37 +1389,11 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int
FBitmap bmp(buffer, W * 4, W, H); FBitmap bmp(buffer, W * 4, W, H);
if (translation <= 0 || translation >= STRange_Min) if (translation <= 0)
{ {
// Allow creation of desaturated or special-colormapped textures for the legacy renderer. int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, nullptr);
FCopyInfo inf = { OP_COPY, BLEND_NONE,{ 0 }, 0, 0 };
if (translation >= STRange_Desaturate && translation < STRange_Desaturate + 31) // there are 31 ranges of desaturations available
{
inf.blend = (EBlend)(BLEND_DESATURATE1 + translation - STRange_Desaturate);
}
else if (translation >= STRange_Specialcolormap && translation < STRange_Specialcolormap + (int)SpecialColormaps.Size())
{
inf.blend = (EBlend)(BLEND_SPECIALCOLORMAP1 + translation - STRange_Specialcolormap);
}
int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, translation >= STRange_Min ? &inf : nullptr);
CheckTrans(buffer, W*H, trans); CheckTrans(buffer, W*H, trans);
isTransparent = bTranslucent; isTransparent = bTranslucent;
// alpha texture for legacy mode
if (translation == STRange_AlphaTexture)
{
for (int i = 0; i < W*H; i++)
{
int b = buffer[4 * i];
int g = buffer[4 * i + 1];
int r = buffer[4 * i + 2];
int gray = Luminance(r, g, b);
buffer[4 * i] = 255;
buffer[4 * i + 1] = 255;
buffer[4 * i + 2] = 255;
buffer[4 * i + 3] = (buffer[4 * i + 3] * gray) >> 8;
}
}
} }
else else
{ {
@ -1430,26 +1404,11 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int
// This is not conclusive for setting the texture's transparency info. // This is not conclusive for setting the texture's transparency info.
} }
// [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. if (flags & CTF_ProcessData)
// [BB] Potentially upsample the buffer.
if ((flags & CTF_MaybeWarped) && bWarped && w*h <= 256 * 256) // do not software-warp larger textures, especially on the old systems that still need this fallback.
{ {
// need to do software warping buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent);
FWarpTexture *wt = static_cast<FWarpTexture*>(this);
unsigned char *warpbuffer = new unsigned char[w*h * 4];
WarpBuffer((uint32_t*)warpbuffer, (const uint32_t*)buffer, w, h, wt->WidthOffsetMultiplier, wt->HeightOffsetMultiplier, screen->FrameTime, wt->Speed, bWarped);
delete[] buffer;
buffer = warpbuffer;
wt->GenTime[0] = screen->FrameTime;
}
else
{
if (flags & CTF_ProcessData)
buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent);
}
if (flags & CTF_ProcessData)
ProcessData(buffer, w, h, false); ProcessData(buffer, w, h, false);
}
return buffer; return buffer;
} }

View file

@ -90,21 +90,11 @@ struct FloatRect
} }
}; };
// Special translation values for CreateTexBuffer
enum ESpecialTranslations : int32_t
{
STRange_Min = 0x10000000,
STRange_Desaturate = 0x10000000,
STRange_Specialcolormap = 0x20000000,
STRange_AlphaTexture = 0x30000000
};
enum ECreateTexBufferFlags enum ECreateTexBufferFlags
{ {
CTF_CheckHires = 1, // use external hires replacement if found CTF_CheckHires = 1, // use external hires replacement if found
CTF_Expand = 2, // create buffer with a one-pixel wide border CTF_Expand = 2, // create buffer with a one-pixel wide border
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
CTF_MaybeWarped = 8 // may be warped if needed
}; };

View file

@ -55,13 +55,11 @@ enum EHWCaps
RFL_SHADER_STORAGE_BUFFER = 4, RFL_SHADER_STORAGE_BUFFER = 4,
RFL_BUFFER_STORAGE = 8, RFL_BUFFER_STORAGE = 8,
RFL_SAMPLER_OBJECTS = 16,
RFL_NO_CLIP_PLANES = 32, RFL_NO_CLIP_PLANES = 32,
RFL_INVALIDATE_BUFFER = 64, RFL_INVALIDATE_BUFFER = 64,
RFL_DEBUG = 128, RFL_DEBUG = 128,
RFL_NO_SHADERS = 256
}; };
struct IntRect struct IntRect