- 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/sbar_mugshot.cpp
g_statusbar/shared_sbar.cpp
gl/compatibility/gl_20.cpp
gl/compatibility/gl_swshader20.cpp
gl/data/gl_vertexbuffer.cpp
gl/data/gl_uniformbuffer.cpp
gl/dynlights/gl_lightbuffer.cpp

View file

@ -116,7 +116,6 @@ extern void M_SetDefaultMode ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
extern void HUD_InitHud();
void gl_PatchMenu(); // remove modern OpenGL options on old hardware.
void DeinitMenus();
const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
@ -2635,7 +2634,6 @@ void D_DoomMain (void)
}
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);
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()
{
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_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &VSiO->color);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_COLOR);
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);
}
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->u);
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &VSiO->color);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_COLOR);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
void FSimpleVertexBuffer::EnableColorArray(bool on)
{
if (on)
{
if (!gl.legacyMode)
{
glEnableVertexAttribArray(VATTR_COLOR);
}
else
{
glEnableClientState(GL_COLOR_ARRAY);
}
glEnableVertexAttribArray(VATTR_COLOR);
}
else
{
if (!gl.legacyMode)
{
glDisableVertexAttribArray(VATTR_COLOR);
}
else
{
glDisableClientState(GL_COLOR_ARRAY);
}
glDisableVertexAttribArray(VATTR_COLOR);
}
}
@ -123,38 +97,25 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
//==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
: FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height)
: FVertexBuffer(true), FFlatVertexGenerator(width, height)
{
ibo_id = 0;
if (gl.buffermethod != BM_LEGACY) glGenBuffers(1, &ibo_id);
switch (gl.buffermethod)
{
case BM_PERSISTENT:
glGenBuffers(1, &ibo_id);
if (gl.buffermethod == BM_PERSISTENT)
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
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);
DPrintf(DMSG_NOTIFY, "Using persistent buffer\n");
break;
}
case BM_DEFERRED:
else
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW);
map = nullptr;
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;
mNumReserved = NUM_RESERVED;
@ -178,10 +139,6 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ibo_id);
}
if (gl.legacyMode)
{
delete[] map;
}
map = nullptr;
}
@ -197,24 +154,13 @@ void FFlatVertexBuffer::BindVBO()
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_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);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glDisableVertexAttribArray(VATTR_COLOR);
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);
}
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glDisableVertexAttribArray(VATTR_COLOR);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
void FFlatVertexBuffer::Map()

View file

@ -157,7 +157,7 @@ void FGLModelRenderer::DrawElements(int numIndices, size_t offset)
//===========================================================================
FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe)
: FVertexBuffer(singleframe || !gl.legacyMode)
: FVertexBuffer(true)
{
vbo_ptr = nullptr;
ibo_id = 0;
@ -177,20 +177,11 @@ void FModelVertexBuffer::BindVBO()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (!gl.legacyMode)
{
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_COLOR);
}
else
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_COLOR);
}
//===========================================================================
@ -223,10 +214,7 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size)
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
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);
else
return (FModelVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
else
{
@ -264,10 +252,7 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
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);
else
return (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
else
{
@ -304,19 +289,10 @@ void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
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_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);
}
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_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 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);
textureBinding.Push(texture);
if (gl.flags & RFL_SAMPLER_OBJECTS)
{
GLint sampler;
glGetIntegerv(GL_SAMPLER_BINDING, &sampler);
glBindSampler(i, 0);
samplerBinding.Push(sampler);
}
GLint sampler;
glGetIntegerv(GL_SAMPLER_BINDING, &sampler);
glBindSampler(i, 0);
samplerBinding.Push(sampler);
}
glActiveTexture(GL_TEXTURE0);
}

View file

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

View file

@ -151,24 +151,14 @@ void FGLRenderer::Initialize(int width, int height)
mShadowMapShader = new FShadowMapShader();
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.
if (!gl.legacyMode)
{
glGenVertexArrays(1, &mVAOID);
glBindVertexArray(mVAOID);
FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
}
else mVAOID = 0;
glGenVertexArrays(1, &mVAOID);
glBindVertexArray(mVAOID);
FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
mVBO = new FFlatVertexBuffer(width, height);
mSkyVBO = new FSkyVertexBuffer;
if (!gl.legacyMode) mLights = new FLightBuffer();
else mLights = NULL;
mLights = new FLightBuffer();
gl_RenderState.SetVertexBuffer(mVBO);
mFBID = 0;
mOldFBID = 0;
@ -187,7 +177,6 @@ FGLRenderer::~FGLRenderer()
FlushModels();
AActor::DeleteAllAttachedLights();
FMaterial::FlushAll();
if (legacyShaders) delete legacyShaders;
if (mShaderManager != NULL) delete mShaderManager;
if (mSamplerManager != NULL) delete mSamplerManager;
if (mVBO != NULL) delete mVBO;
@ -313,7 +302,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
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.
bool saved_niv = NoInterpolateView;
@ -359,17 +348,8 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
if (gl.legacyMode)
{
// 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();
}
StartOffscreen();
gltex->BindToFrameBuffer();
IntRect bounds;
bounds.left = bounds.top = 0;
@ -381,16 +361,7 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
if (gl.legacyMode)
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
EndOffscreen();
}
EndOffscreen();
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)
void FGLRenderer::Draw2D(F2DDrawer *drawer)
@ -550,28 +519,12 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
{
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 (!gl.legacyMode || cmd.mTexture->UseType == ETextureType::SWCanvas)
{
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;
}
gl_RenderState.SetFixedColormap(CM_FIRSTSPECIALCOLORMAPFORCED + int(index));
}
else
{
if (!gl.legacyMode)
{
gl_RenderState.SetFog(cmd.mColor1, 0);
gl_RenderState.SetFixedColormap(CM_PLAIN2D);
}
else if (cmd.mDesaturate > 0)
{
gltrans = LegacyDesaturation(cmd);
}
gl_RenderState.SetFixedColormap(CM_PLAIN2D);
}
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);
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);
@ -612,11 +559,6 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
{
case F2DDrawer::DrawTypeTriangles:
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;
case F2DDrawer::DrawTypeLines:

View file

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

View file

@ -348,14 +348,7 @@ void FRenderState::Apply()
else mVertexBuffer->BindVBO();
mCurrentVertexBuffer = mVertexBuffer;
}
if (!gl.legacyMode)
{
ApplyShader();
}
else
{
ApplyFixedFunction();
}
ApplyShader();
}
@ -385,38 +378,22 @@ void FRenderState::ApplyMatrices()
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);
}
activeShader->muLightIndex.Set(index);
index = GLRenderer->mLights->BindUBO(index);
}
activeShader->muLightIndex.Set(index);
}
void FRenderState::SetClipHeight(float height, float direction)
{
mClipHeight = height;
mClipHeightDirection = direction;
#if 1
// This still doesn't work... :(
if (gl.flags & RFL_NO_CLIP_PLANES) return;
#endif
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);
}
else

View file

@ -148,9 +148,6 @@ public:
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)
{
mTempTM = TM_OPAQUE;

View file

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

View file

@ -25,41 +25,12 @@ enum DrawListType
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
{
GLPASS_ALL, // Main pass with dynamic lights
GLPASS_LIGHTSONLY, // only collect dynamic lights
GLPASS_DECALS, // Draws a decal
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
@ -70,7 +41,6 @@ struct FDrawInfo : public HWDrawInfo
HWDrawList drawlists[GLDL_TYPES];
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.
HWDrawList *dldrawlists = NULL; // only gets allocated when needed.
FDrawInfo();
~FDrawInfo();

View file

@ -213,11 +213,6 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
gl_RenderState.Apply();
auto iboindex = flat->iboindex;
if (gl.legacyMode)
{
processlights = false;
iboindex = -1;
}
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);
gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false);
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);
}
if (flat->renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.SetObjectColor(0xffffffff);
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;
if (gl.legacyMode)
{
if (PutFlatCompat(flat, fog)) return;
}
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.

View file

@ -306,20 +306,7 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
glDisable(GL_POLYGON_OFFSET_FILL);
int pass;
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;
}
int pass = GLPASS_ALL;
gl_RenderState.EnableTexture(gl_texture);
gl_RenderState.EnableBrightmap(true);
@ -529,11 +516,6 @@ void GLSceneDrawer::DrawEndScene2D(FDrawInfo *di, sector_t * viewsector)
di->DrawPlayerSprites(false);
if (gl.legacyMode)
{
gl_RenderState.DrawColormapOverlay();
}
gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1);
@ -728,7 +710,7 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
SetFixedColormap(player);
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
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);
glDisable(GL_STENCIL_TEST);

View file

@ -54,26 +54,14 @@ FSkyVertexBuffer::FSkyVertexBuffer()
void FSkyVertexBuffer::BindVBO()
{
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_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_COLOR);
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);
}
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u);
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_COLOR);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
//-----------------------------------------------------------------------------
@ -111,11 +99,6 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode)
gl_RenderState.Apply();
RenderRow(GL_TRIANGLE_FAN, rc);
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.Apply();

View file

@ -67,25 +67,18 @@ void FDrawInfo::RenderFogBoundary(GLWall *wall)
{
if (gl_fogmode && mDrawer->FixedColormap == 0)
{
if (!gl.legacyMode)
{
int rel = wall->rellight + getExtraLight();
mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, false);
gl_RenderState.EnableDrawBuffers(1);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
RenderWall(wall, GLWall::RWF_BLANK);
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
}
else
{
RenderFogBoundaryCompat(wall);
}
int rel = wall->rellight + getExtraLight();
mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, false);
gl_RenderState.EnableDrawBuffers(1);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
RenderWall(wall, GLWall::RWF_BLANK);
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
}
}
@ -99,17 +92,9 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
{
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);
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
}
else
{
FVector3 v = wall->glseg.Normal();
glNormal3fv(&v[0]);
}
// 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);
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
// Use sphere mapping for this
gl_RenderState.SetEffect(EFF_SPHEREMAP);
@ -258,7 +243,7 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
{
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);
}
@ -289,17 +274,6 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
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
{
if (gl.legacyMode)
{
if (PutWallCompat(wall, GLWall::passflag[wall->type])) return;
}
bool masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked());
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();
if (lightbuffertype == GL_UNIFORM_BUFFER)
{
if (gl.es)
{
vp_comb.Format("#version 300 es\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
}
else
{
@ -360,7 +358,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix");
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");
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT);
@ -422,7 +420,6 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP
FString defines;
defines += shaderdefines;
// 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 (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n";
@ -518,30 +515,17 @@ static const FEffectShader effectshaders[]=
FShaderManager::FShaderManager()
{
if (!gl.legacyMode)
{
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));
}
}
for (int passType = 0; passType < MAX_PASS_TYPES; passType++)
mPassShaders.Push(new FShaderCollection((EPassType)passType));
}
FShaderManager::~FShaderManager()
{
if (!gl.legacyMode)
{
glUseProgram(0);
mActiveShader = NULL;
glUseProgram(0);
mActiveShader = NULL;
for (auto collection : mPassShaders)
delete collection;
}
for (auto collection : mPassShaders)
delete collection;
}
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)
{
if (gl.legacyMode)
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj->get());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view->get());
}
else
{
if (passType < mPassShaders.Size())
mPassShaders[passType]->ApplyMatrices(proj, view);
if (passType < mPassShaders.Size())
mPassShaders[passType]->ApplyMatrices(proj, view);
if (mActiveShader)
mActiveShader->Bind();
}
if (mActiveShader)
mActiveShader->Bind();
}
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 (maxGlslVersion < 420 && gl.glslversion >= 4.2f) maxGlslVersion = 420;
int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion);
if (gl.es)
patchedCode.AppendFormat("#version %d es\n", shaderVersion);
else
patchedCode.AppendFormat("#version %d\n", shaderVersion);
patchedCode.AppendFormat("#version %d\n", shaderVersion);
// TODO: Find some way to add extension requirements to the patching
//

View file

@ -62,8 +62,6 @@ void Stereo3DMode::setCurrentMode(const Stereo3DMode& mode) {
/* static */
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
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.
hwcaps = gl.flags;
if (gl.legacyMode) hwcaps |= RFL_NO_SHADERS;
glslversion = gl.glslversion;
}
@ -134,7 +133,6 @@ void OpenGLFrameBuffer::InitializeState()
glEnable(GL_BLEND);
glEnable(GL_DEPTH_CLAMP);
glDisable(GL_DEPTH_TEST);
if (gl.legacyMode) glEnable(GL_TEXTURE_2D);
glDisable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -243,12 +241,8 @@ uint32_t OpenGLFrameBuffer::GetCaps()
RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL;
if (r_drawvoxels)
FlagSet |= RFF_VOXELS;
if (gl.legacyMode)
{
// legacy mode always has truecolor because palette tonemap is not available
FlagSet |= RFF_TRUECOLOR;
}
else if (!RenderBuffersEnabled())
if (!RenderBuffersEnabled())
{
// truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible
FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP;

View file

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

View file

@ -233,23 +233,11 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
if (glTextureBytes > 0)
{
if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (gl.legacyMode)
{
// 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 };
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
{
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];
}
texformat = ITypes[glTextureBytes - 1];
sourcetype = STypes[glTextureBytes - 1];
}
else
{
@ -539,7 +527,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
bool needmipmap = (clampmode <= CLAMP_XY);
// Texture has become invalid
if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified(DefaultRenderStyle()))
if (!tex->bHasCanvas && !tex->bWarped && tex->CheckModified(DefaultRenderStyle()))
{
Clean(true);
}
@ -555,7 +543,6 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
if (!tex->bHasCanvas)
{
if (gl.legacyMode) flags |= CTF_MaybeWarped;
buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData);
}
else

View file

@ -35,163 +35,66 @@ extern TexFilter_s TexFilter[];
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);
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++)
{
FString name;
name.Format("mSamplers[%d]", i);
FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name.GetChars());
}
FString name;
name.Format("mSamplers[%d]", i);
FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name.GetChars());
}
}
FSamplerManager::~FSamplerManager()
{
if (gl.flags & RFL_SAMPLER_OBJECTS)
{
UnbindAll();
glDeleteSamplers(7, mSamplers);
}
UnbindAll();
glDeleteSamplers(7, mSamplers);
}
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)
{
if (gl.flags & RFL_SAMPLER_OBJECTS)
{
unsigned int samp = mSamplers[num];
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;
}
unsigned int samp = mSamplers[num];
glBindSampler(texunit, samp);
return 255;
}
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++)
{
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
for (int i = 0; i < 4; i++)
{
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 "hwrenderer/utility/hw_cvars.h"
void gl_PatchMenu();
static TArray<FString> m_Extensions;
RenderContext gl;
static double realglversion; // this is public so the statistics code can access it.
@ -129,13 +128,6 @@ void gl_LoadExtensions()
CollectExtensions();
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");
realglversion = strtod(glversion, NULL);
@ -148,138 +140,96 @@ void gl_LoadExtensions()
else
{
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;
else Printf("Emulating OpenGL v %s\n", version);
}
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 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);
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");
}
// Use the slowest/oldest modern path for now
gl.legacyMode = false;
gl.lightmethod = LM_DEFERRED;
gl.buffermethod = BM_DEFERRED;
gl.flags |= RFL_NO_CLIP_PLANES;
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f;
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
{
// 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 < 2.0f || !CheckExtension("GL_EXT_framebuffer_object")) && gl_version < 3.0f)
{
I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 2.0 with framebuffer support is required to run " GAMENAME ".\n");
}
gl.es = false;
// 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;
}
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f;
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;
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
if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION;
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC;
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;
}
}
lm = Args->CheckValue("-buffermethod");
if (lm != NULL)
{
if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED;
}
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);
gl.maxuniforms = v;
@ -294,34 +244,10 @@ void gl_LoadExtensions()
gl.maxuniformblock = 0;
gl.uniformblockalignment = 0;
}
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize);
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()
{
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_RENDERER: %s\n", glGetString(GL_RENDERER));
@ -352,7 +278,7 @@ void gl_PrintStartupLog()
glGetIntegerv(GL_MAX_VARYING_FLOATS, &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);
Printf ("Max. uniform block size: %d\n", v);

View file

@ -3,17 +3,8 @@
#include "basictypes.h"
enum GLCompat
{
CMPT_GL2,
CMPT_GL2_SHADER,
CMPT_GL3,
CMPT_GL4
};
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)
@ -26,14 +17,12 @@ enum TexMode
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_DIRECT = 2, // calculate lights on the fly along with the render data
};
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_PERSISTENT = 2 // use a persistently mapped buffer
};
@ -50,13 +39,6 @@ struct RenderContext
float glslversion;
int max_texturesize;
char * vendorstring;
bool legacyMode;
bool es;
int MaxLights() const
{
return maxuniforms>=2048? 128:64;
}
};
extern RenderContext gl;

View file

@ -219,7 +219,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v)
inline void GLSprite::PutSprite(HWDrawInfo *di, bool translucent)
{
// 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);
dynlightindex = di->UploadLights(lightdata);
@ -709,7 +709,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
RenderStyle.CheckFuzz();
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];
OverrideShader = SHADER_NoTexture + gl_fuzztype;

View file

@ -50,7 +50,6 @@ void GLWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
{
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.
// 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 (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);
}

View file

@ -467,7 +467,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area)
// set the lighting parameters
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);
}

View file

@ -1371,7 +1371,7 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int
int isTransparent = -1;
if ((flags & CTF_CheckHires) && translation != STRange_AlphaTexture)
if (flags & CTF_CheckHires)
{
buffer = LoadHiresTexture(&w, &h);
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);
if (translation <= 0 || translation >= STRange_Min)
if (translation <= 0)
{
// Allow creation of desaturated or special-colormapped textures for the legacy renderer.
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);
int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, nullptr);
CheckTrans(buffer, W*H, trans);
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
{
@ -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.
}
// [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it.
// [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.
if (flags & CTF_ProcessData)
{
// need to do software warping
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)
buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent);
ProcessData(buffer, w, h, false);
}
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
{
CTF_CheckHires = 1, // use external hires replacement if found
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_MaybeWarped = 8 // may be warped if needed
};

View file

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