- add shader patching to allow running the engine with GLSL 1.2.

- made some initial preparations for the shader-less fallback path.
This commit is contained in:
Christoph Oelckers 2016-04-26 15:01:23 +02:00
parent ee9a40f5e9
commit f066457a48
8 changed files with 108 additions and 26 deletions

View file

@ -138,10 +138,21 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs
// this will only get called if we can't acquire a persistently mapped buffer.
#ifndef CORE_PROFILE
glBegin(primtype);
for (unsigned int i = 0; i < count; i++)
if (gl.compatibility > CMPT_GL2)
{
glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u);
glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x);
for (unsigned int i = 0; i < count; i++)
{
glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u);
glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x);
}
}
else // no shader means no vertex attributes, so use the old stuff instead.
{
for (unsigned int i = 0; i < count; i++)
{
glTexCoord2fv(&map[offset + i].u);
glVertex3fv(&map[offset + i].x);
}
}
glEnd();
#endif

View file

@ -279,7 +279,14 @@ void FRenderState::Apply()
else mVertexBuffer->BindVBO();
mCurrentVertexBuffer = mVertexBuffer;
}
ApplyShader();
if (gl.compatibility > CMPT_GL2)
{
ApplyShader();
}
else
{
//ApplyFixedFunction();
}
}

View file

@ -59,6 +59,44 @@
#include "gl/textures/gl_material.h"
#include "gl/dynlights/gl_lightbuffer.h"
//==========================================================================
//
// patch the shader source to work with
// GLSL 1.2 keywords and identifiers
//
//==========================================================================
void PatchCommon(FString &code)
{
code.Substitute("precision highp int;", "");
code.Substitute("precision highp float;", "");
}
void PatchVertShader(FString &code)
{
PatchCommon(code);
code.Substitute("out vec", "varying vec");
code.Substitute("gl_ClipDistance", "//");
}
void PatchFragShader(FString &code)
{
PatchCommon(code);
code.Substitute("out vec4 FragColor;", "");
code.Substitute("FragColor", "gl_FragColor");
code.Substitute("in vec", "varying vec");
// this patches the switch statement to if's.
code.Substitute("break;", "");
code.Substitute("switch (uFixedColormap)", "int i = uFixedColormap;");
code.Substitute("case 0:", "if (i == 0)");
code.Substitute("case 1:", "else if (i == 1)");
code.Substitute("case 2:", "else if (i == 2)");
code.Substitute("case 3:", "else if (i == 3)");
code.Substitute("case 4:", "else if (i == 4)");
code.Substitute("case 5:", "else if (i == 5)");
code.Substitute("texture(", "texture2D(");
}
//==========================================================================
//
//
@ -95,6 +133,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
{
vp_comb = "#version 130\n";
}
else
{
vp_comb = "#define GLSL12_COMPATIBLE\n";
}
}
else
{
@ -159,6 +201,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
}
}
if (gl.compatibility < CMPT_GL3)
{
PatchVertShader(vp_comb);
PatchFragShader(fp_comb);
}
hVertProg = glCreateShader(GL_VERTEX_SHADER);
hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
@ -391,7 +439,7 @@ static const FEffectShader effectshaders[]=
FShaderManager::FShaderManager()
{
CompileShaders();
if (gl.compatibility > CMPT_GL2) CompileShaders();
}
//==========================================================================
@ -402,7 +450,7 @@ FShaderManager::FShaderManager()
FShaderManager::~FShaderManager()
{
Clean();
if (gl.compatibility > CMPT_GL2) Clean();
}
//==========================================================================
@ -544,25 +592,35 @@ EXTERN_CVAR(Int, gl_fuzztype)
void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
{
for (int i = 0; i < 4; i++)
if (gl.compatibility == CMPT_GL2)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj->get());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view->get());
}
mTextureEffects[4]->ApplyMatrices(proj, view);
if (gl_fuzztype != 0)
else
{
mTextureEffects[4+gl_fuzztype]->ApplyMatrices(proj, view);
for (int i = 0; i < 4; i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
}
mTextureEffects[4]->ApplyMatrices(proj, view);
if (gl_fuzztype != 0)
{
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view);
}
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
}
for (int i = 0; i < MAX_EFFECTS; i++)
{
mEffectShaders[i]->ApplyMatrices(proj, view);
}
if (mActiveShader != NULL) mActiveShader->Bind();
}
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
}
for (int i = 0; i < MAX_EFFECTS; i++)
{
mEffectShaders[i]->ApplyMatrices(proj, view);
}
if (mActiveShader != NULL) mActiveShader->Bind();
}
//==========================================================================

View file

@ -152,7 +152,6 @@ void gl_LoadExtensions()
// 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;
}
@ -161,9 +160,10 @@ void gl_LoadExtensions()
if (Args->CheckParm("-noshader"))
{
gl.version = 2.1f;
gl.compatibility = CMPT_GL2; // force the low end path
}
if (gl.version < 3.0f)
else 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;
@ -172,6 +172,7 @@ void gl_LoadExtensions()
{
if (strstr(gl.vendorstring, "ATI Tech"))
{
gl.version = 2.1f;
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.
}
@ -198,6 +199,7 @@ void gl_LoadExtensions()
}
else
{
gl.version = 3.3f;
gl.compatibility = CMPT_GL3;
}
}

View file

@ -263,6 +263,10 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
if ( inputTexture->bHasCanvas )
return inputBuffer;
// [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time
if (gl.compatibility == CMPT_GL2 && inputTexture->bWarped)
return inputBuffer;
// already scaled?
if (inputTexture->Scale.X >= 2 && inputTexture->Scale.Y >= 2)
return inputBuffer;

View file

@ -424,6 +424,7 @@ int FHardwareTexture::GetDepthBuffer()
void FHardwareTexture::BindToFrameBuffer()
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
}

View file

@ -782,7 +782,6 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample)
if (!SetupPixelFormat(multisample))
{
I_Error ("R_OPENGL: Unabl...\n");
return false;
}

View file

@ -170,7 +170,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel, gl_FragCoord.z);
color.rgb *= newlightlevel;
}
else if (uFogEnabled > 0.0)
else if (uFogEnabled > 0)
{
// brightening around the player for light mode 2
if (fogdist < uLightDist)