mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 07:57:52 +00:00
- 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:
parent
1455111ddc
commit
8ab68264c1
33 changed files with 222 additions and 2079 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
//
|
//
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue