mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- updated gl_interface to deal with older GL versions.
- added the framework for allowing multipass textured dynamic lights again.
This commit is contained in:
parent
8b5c741358
commit
090d13b915
8 changed files with 151 additions and 33 deletions
|
@ -109,7 +109,8 @@ void FGLRenderer::Initialize()
|
|||
|
||||
mVBO = new FFlatVertexBuffer;
|
||||
mSkyVBO = new FSkyVertexBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
if (gl.lightmethod != LM_SOFTWARE) mLights = new FLightBuffer();
|
||||
else mLights = NULL;
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
mFBID = 0;
|
||||
SetupLevel();
|
||||
|
|
|
@ -309,7 +309,7 @@ void FRenderState::ApplyMatrices()
|
|||
|
||||
void FRenderState::ApplyLightIndex(int index)
|
||||
{
|
||||
if (GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER && index > -1)
|
||||
if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER)
|
||||
{
|
||||
index = GLRenderer->mLights->BindUBO(index);
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ void GLFlat::DrawSubsector(subsector_t * sub)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// this is only used by LM_DEFERRED
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -399,7 +399,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
|||
switch (pass)
|
||||
{
|
||||
case GLPASS_PLAIN: // Single-pass rendering
|
||||
case GLPASS_ALL:
|
||||
case GLPASS_ALL: // Same, but also creates the dynlight data.
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
if (sector->special != GLSector_Skybox)
|
||||
|
@ -473,6 +473,7 @@ inline void GLFlat::PutFlat(bool fog)
|
|||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS;
|
||||
}
|
||||
dynlightindex = -1; // make sure this is always initialized to something proper.
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
}
|
||||
|
||||
|
|
|
@ -351,7 +351,8 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
|
||||
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
||||
// so that we don't have to do repeated map/unmap calls on the buffer.
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE))
|
||||
bool haslights = mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights;
|
||||
if (gl.lightmethod == LM_DEFERRED && haslights)
|
||||
{
|
||||
GLRenderer->mLights->Begin();
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(GLPASS_LIGHTSONLY);
|
||||
|
@ -371,12 +372,20 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
|
||||
int pass;
|
||||
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE))
|
||||
if (!haslights || gl.lightmethod == LM_DEFERRED)
|
||||
{
|
||||
pass = GLPASS_PLAIN;
|
||||
}
|
||||
else if (gl.lightmethod == LM_DIRECT)
|
||||
{
|
||||
pass = GLPASS_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo: Draw lights with multipass rendering.
|
||||
// RenderMultpassStuff();
|
||||
|
||||
// The remaining stuff which is unaffected by dynamic lights is just processed as normal.
|
||||
pass = GLPASS_PLAIN;
|
||||
}
|
||||
|
||||
|
@ -418,6 +427,10 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
|
||||
// this is the only geometry type on which decals can possibly appear
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals();
|
||||
if (gl.lightmethod == LM_SOFTWARE)
|
||||
{
|
||||
// also process the render lists with walls and dynamic lights
|
||||
}
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
@ -870,7 +883,7 @@ void FGLRenderer::RenderView (player_t* player)
|
|||
|
||||
P_FindParticleSubsectors ();
|
||||
|
||||
GLRenderer->mLights->Clear();
|
||||
if (gl.lightmethod != LM_SOFTWARE) GLRenderer->mLights->Clear();
|
||||
|
||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||
bool saved_niv = NoInterpolateView;
|
||||
|
@ -925,7 +938,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
|
|||
SetFixedColormap(player);
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
GLRenderer->mVBO->Reset();
|
||||
GLRenderer->mLights->Clear();
|
||||
if (gl.lightmethod != LM_SOFTWARE) GLRenderer->mLights->Clear();
|
||||
|
||||
// Check if there's some lights. If not some code can be skipped.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
|
|
|
@ -1422,7 +1422,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
glseg.y2 = v2->fY();
|
||||
Colormap = frontsector->ColorMap;
|
||||
flags = 0;
|
||||
dynlightindex = UINT_MAX;
|
||||
dynlightindex = -1;
|
||||
lightlist = NULL;
|
||||
|
||||
int rel = 0;
|
||||
|
@ -1681,7 +1681,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
|
|||
bottomflat = frontsector->GetTexture(sector_t::floor);
|
||||
topplane = frontsector->ceilingplane;
|
||||
bottomplane = frontsector->floorplane;
|
||||
dynlightindex = UINT_MAX;
|
||||
dynlightindex = -1;
|
||||
|
||||
zfloor[0] = zfloor[1] = ffh;
|
||||
|
||||
|
|
|
@ -87,25 +87,37 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
//
|
||||
// The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break!
|
||||
//
|
||||
unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType();
|
||||
unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize();
|
||||
|
||||
FString vp_comb;
|
||||
|
||||
if (lightbuffertype == GL_UNIFORM_BUFFER)
|
||||
if (gl.lightmethod == LM_SOFTWARE)
|
||||
{
|
||||
if (gl.glslversion < 1.4f || gl.version < 3.1f)
|
||||
if (gl.compatibility >= CMPT_GL3)
|
||||
{
|
||||
vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_comb.Format("#version 140\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
|
||||
vp_comb = "#version 130\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n";
|
||||
assert(GLRenderer->mLights != NULL);
|
||||
// On the shader side there is no difference between LM_DEFERRED and LM_DIRECT, it only matters which buffer type is used by the light buffer.
|
||||
unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType();
|
||||
unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize();
|
||||
if (lightbuffertype == GL_UNIFORM_BUFFER)
|
||||
{
|
||||
// This differentiation is for some Intel drivers which fail on #extension, so use of #version 140 is necessary
|
||||
if (gl.glslversion < 1.4f || gl.version < 3.1f)
|
||||
{
|
||||
vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_comb.Format("#version 140\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n";
|
||||
}
|
||||
}
|
||||
|
||||
vp_comb << defines << i_data.GetString().GetChars();
|
||||
|
|
|
@ -107,35 +107,77 @@ static void InitContext()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
#define FUDGE_FUNC(name, ext) if (_ptrc_##name == NULL) _ptrc_##name = _ptrc_##name##ext;
|
||||
|
||||
|
||||
void gl_LoadExtensions()
|
||||
{
|
||||
InitContext();
|
||||
CollectExtensions();
|
||||
|
||||
const char *version = Args->CheckValue("-glversion");
|
||||
if (version == NULL) version = (const char*)glGetString(GL_VERSION);
|
||||
else Printf("Emulating OpenGL v %s\n", version);
|
||||
const char *glversion = (const char*)glGetString(GL_VERSION);
|
||||
|
||||
if (version == NULL)
|
||||
{
|
||||
version = glversion;
|
||||
}
|
||||
else
|
||||
{
|
||||
double v1 = strtod(version, NULL);
|
||||
double v2 = strtod(glversion, NULL);
|
||||
if (v2 < v1) version = glversion;
|
||||
else Printf("Emulating OpenGL v %s\n", version);
|
||||
}
|
||||
|
||||
gl.version = strtod(version, NULL) + 0.01f;
|
||||
|
||||
// Don't even start if it's lower than 3.0
|
||||
if (strcmp(version, "3.0") < 0)
|
||||
if ((gl.version < 2.0 || !CheckExtension("GL_EXT_framebuffer_object")) && gl.version < 3.0)
|
||||
{
|
||||
I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.0 is required to run " GAMENAME ".\n");
|
||||
I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 2.0 with framebuffer support is required to run " GAMENAME ".\n");
|
||||
}
|
||||
|
||||
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
|
||||
gl.version = strtod(version, NULL) + 0.01f;
|
||||
gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f;
|
||||
|
||||
gl.vendorstring = (char*)glGetString(GL_VENDOR);
|
||||
gl.lightmethod = LM_SOFTWARE;
|
||||
|
||||
if (gl.version >= 3.3f || CheckExtension("GL_ARB_sampler_objects"))
|
||||
{
|
||||
gl.flags |= RFL_SAMPLER_OBJECTS;
|
||||
}
|
||||
|
||||
// Buffer lighting is only feasible with GLSL 1.3 and higher, even if 1.2 supports the extension.
|
||||
if (gl.version > 3.0f && (gl.version >= 3.3f || CheckExtension("GL_ARB_uniform_buffer_object")))
|
||||
{
|
||||
gl.flags |= RFL_SAMPLER_OBJECTS;
|
||||
gl.lightmethod = LM_DEFERRED;
|
||||
}
|
||||
|
||||
if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION;
|
||||
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC;
|
||||
if (!Args->CheckParm("-gl3"))
|
||||
if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION;
|
||||
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC;
|
||||
|
||||
if (Args->CheckParm("-noshader"))
|
||||
{
|
||||
gl.compatibility = CMPT_GL2; // force the low end path
|
||||
}
|
||||
if (gl.version < 3.0f)
|
||||
{
|
||||
if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.compatibility = CMPT_GL2_SHADER; // for pre-3.0 drivers that support capable hardware. Needed for Apple.
|
||||
else gl.compatibility = CMPT_GL2;
|
||||
}
|
||||
else if (gl.version < 4.f)
|
||||
{
|
||||
if (strstr(gl.vendorstring, "ATI Tech"))
|
||||
{
|
||||
gl.compatibility = CMPT_GL2_SHADER; // most of these drivers are irreperably broken with GLSL 1.3 and higher.
|
||||
gl.lightmethod = LM_SOFTWARE; // do not use uniform buffers with the fallback shader, it may cause problems.
|
||||
}
|
||||
else gl.compatibility = CMPT_GL3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't use GL 4.x features when running in GL 3 emulation mode.
|
||||
if (CheckExtension("GL_ARB_buffer_storage"))
|
||||
|
@ -151,9 +193,22 @@ void gl_LoadExtensions()
|
|||
}
|
||||
}
|
||||
gl.flags |= RFL_BUFFER_STORAGE;
|
||||
gl.compatibility = CMPT_GL4;
|
||||
gl.lightmethod = LM_DIRECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.compatibility = CMPT_GL3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *lm = Args->CheckValue("-lightmethod");
|
||||
if (lm != NULL)
|
||||
{
|
||||
if (!stricmp(lm, "deferred") && gl.lightmethod == LM_DIRECT) gl.lightmethod = LM_DEFERRED;
|
||||
if (!stricmp(lm, "textured")) gl.lightmethod = LM_SOFTWARE;
|
||||
}
|
||||
|
||||
int v;
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v);
|
||||
gl.maxuniforms = v;
|
||||
|
@ -161,9 +216,26 @@ void gl_LoadExtensions()
|
|||
gl.maxuniformblock = v;
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v);
|
||||
gl.uniformblockalignment = v;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize);
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
|
||||
#include "basictypes.h"
|
||||
|
||||
enum GLCompat
|
||||
{
|
||||
CMPT_GL2,
|
||||
CMPT_GL2_SHADER,
|
||||
CMPT_GL3,
|
||||
CMPT_GL4
|
||||
};
|
||||
|
||||
enum RenderFlags
|
||||
{
|
||||
// [BB] Added texture compression flags.
|
||||
|
@ -11,7 +19,7 @@ enum RenderFlags
|
|||
|
||||
RFL_SHADER_STORAGE_BUFFER = 4,
|
||||
RFL_BUFFER_STORAGE = 8,
|
||||
RFL_SAMPLER_OBJECTS = 16
|
||||
RFL_SAMPLER_OBJECTS = 16,
|
||||
};
|
||||
|
||||
enum TexMode
|
||||
|
@ -22,6 +30,15 @@ enum TexMode
|
|||
TM_INVERSE, // (1-r, 1-g, 1-b, a)
|
||||
TM_REDTOALPHA, // (1, 1, 1, r)
|
||||
TM_CLAMPY, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0)
|
||||
|
||||
TM_INVERTOPAQUE, // used by GL 2.x fallback code.
|
||||
};
|
||||
|
||||
enum ELightMethod
|
||||
{
|
||||
LM_SOFTWARE = 0, // multi-pass texturing
|
||||
LM_DEFERRED = 1, // calculate lights up front in a separate pass
|
||||
LM_DIRECT = 2, // calculate lights on the fly along with the render data
|
||||
};
|
||||
|
||||
struct RenderContext
|
||||
|
@ -30,6 +47,8 @@ struct RenderContext
|
|||
unsigned int maxuniforms;
|
||||
unsigned int maxuniformblock;
|
||||
unsigned int uniformblockalignment;
|
||||
int lightmethod;
|
||||
int compatibility;
|
||||
float version;
|
||||
float glslversion;
|
||||
int max_texturesize;
|
||||
|
|
Loading…
Reference in a new issue