- reactivate compatibility profile so that immediate mode drawing can be used on older hardware not supporting persistently mapped buffers.

- reactivate alpha testing per fixed function pipeline
- use the 'modern' way to define clip planes (GL_CLIP_DISTANCE). This is far more portable than the old glClipPlane method and a lot more robust than checking this in the fragment shader.
This commit is contained in:
Christoph Oelckers 2014-07-17 02:37:18 +02:00
parent 6b9d6787d9
commit eb9d2d9917
13 changed files with 110 additions and 48 deletions

View file

@ -136,24 +136,29 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
//
//==========================================================================
CVAR(Bool, gl_testbuffer, false, 0)
CUSTOM_CVAR(Int, gl_rendermethod, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
}
void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count)
{
#if 0
if (!gl_testbuffer) // todo: remove the immediate mode calls once the uniform array method has been tested.
switch (gl_rendermethod)
{
glBegin(primtype);
for (unsigned int i = 0; i < count; i++)
case 0:
#ifndef CORE_PROFILE
if (!(gl.flags & RFL_COREPROFILE))
{
glTexCoord2fv(&map[offset + i].u);
glVertex3fv(&map[offset + i].x);
glBegin(primtype);
for (unsigned int i = 0; i < count; i++)
{
glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u);
glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x);
}
glEnd();
break;
}
glEnd();
}
else
#endif
{
case 1:
if (count > 20)
{
int start = offset;
@ -186,6 +191,14 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs
glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x);
glDrawArrays(primtype, 0, count);
}
break;
case 2:
// glBufferSubData
case 3:
// glMapBufferRange
break;
}
}

View file

@ -149,7 +149,29 @@ bool FRenderState::ApplyShader()
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeightTop.Set(mClipHeightTop);
activeShader->muClipHeightBottom.Set(mClipHeightBottom);
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
#ifndef CORE_PROFILE
if (!(gl.flags & RFL_COREPROFILE))
{
if (mAlphaThreshold != glAlphaThreshold)
{
glAlphaThreshold = mAlphaThreshold;
if (mAlphaThreshold < 0.f)
{
glDisable(GL_ALPHA_TEST);
}
else
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, mAlphaThreshold);
}
}
}
else
#endif
{
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
}
if (mGlowEnabled)
{

View file

@ -74,8 +74,10 @@ class FRenderState
int mEffectState;
int mColormapState;
int glSrcBlend, glDstBlend;
float glAlphaThreshold;
bool glClipOn;
int glSrcBlend, glDstBlend;
bool glAlphaTest;
int glBlendEquation;

View file

@ -286,8 +286,10 @@ bool GLPortal::Start(bool usestencil, bool doquery)
}
planestack.Push(gl_RenderState.GetClipHeightTop());
planestack.Push(gl_RenderState.GetClipHeightBottom());
gl_RenderState.SetClipHeightTop(65536.f);
glDisable(GL_CLIP_DISTANCE0);
glDisable(GL_CLIP_DISTANCE1);
gl_RenderState.SetClipHeightBottom(-65536.f);
gl_RenderState.SetClipHeightTop(65536.f);
// save viewpoint
savedviewx=viewx;
@ -351,8 +353,10 @@ void GLPortal::End(bool usestencil)
float f;
planestack.Pop(f);
gl_RenderState.SetClipHeightBottom(f);
if (f > -65535.f) glEnable(GL_CLIP_DISTANCE0);
planestack.Pop(f);
gl_RenderState.SetClipHeightTop(f);
if (f < 65535.f) glEnable(GL_CLIP_DISTANCE1);
if (usestencil)
{
@ -790,15 +794,27 @@ void GLPlaneMirrorPortal::DrawContents()
validcount++;
float f = FIXED2FLOAT(planez);
if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling
else gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor
PlaneMirrorFlag++;
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
ClearClipper();
float f = FIXED2FLOAT(planez);
if (PlaneMirrorMode < 0)
{
gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling
glEnable(GL_CLIP_DISTANCE1);
}
else
{
gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor
glEnable(GL_CLIP_DISTANCE0);
}
GLRenderer->DrawScene();
glDisable(GL_CLIP_DISTANCE0);
glDisable(GL_CLIP_DISTANCE1);
gl_RenderState.SetClipHeightBottom(-65536.f);
gl_RenderState.SetClipHeightTop(65536.f);
PlaneMirrorFlag--;
PlaneMirrorMode=old_pm;
}

View file

@ -186,14 +186,7 @@ void GLWall::RenderWall(int textured, unsigned int *store)
if (!(textured & RWF_NORENDER))
{
// disable the clip plane if it isn't needed (which can be determined by a simple check.)
float ct = gl_RenderState.GetClipHeightTop();
float cb = gl_RenderState.GetClipHeightBottom();
if (ztop[0] <= ct && ztop[1] <= ct) gl_RenderState.SetClipHeightTop(65536.f);
if (zbottom[0] >= cb && zbottom[1] >= cb) gl_RenderState.SetClipHeightBottom(-65536.f);
gl_RenderState.Apply();
gl_RenderState.SetClipHeightTop(ct);
gl_RenderState.SetClipHeightBottom(cb);
}
// the rest of the code is identical for textured rendering and lights

View file

@ -134,6 +134,7 @@ void gl_LoadExtensions()
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC;
if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE;
if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS;
if (!CheckExtension("GL_ARB_compatibility")) gl.flags |= RFL_COREPROFILE;
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize);

View file

@ -13,6 +13,7 @@ enum RenderFlags
RFL_BUFFER_STORAGE = 8, // allows persistently mapped buffers, which are the only efficient way to actually use a dynamic vertex buffer. If this isn't present, a workaround with uniform arrays is used.
RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer
RFL_BASEINDEX = 32, // currently unused
RFL_COREPROFILE = 64,
};
enum TexMode

View file

@ -63,7 +63,6 @@ private:
bool bHasColorkey; // only for hires
bool bExpand;
float AlphaThreshold;
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture);

View file

@ -17,6 +17,7 @@
#include "i_system.h"
#include "doomstat.h"
#include "v_text.h"
#include "m_argv.h"
//#include "gl_defs.h"
#include "gl/renderer/gl_renderer.h"
@ -739,21 +740,42 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample)
m_hRC = NULL;
if (myWglCreateContextAttribsARB != NULL)
{
// let's try to get the best version possible.
static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 };
#ifndef CORE_PROFILE
bool core = !!Args->CheckParm("-core");
#else
bool core = true;
#endif
if (core)
{
// let's try to get the best version possible.
static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 };
for (int i = 0; versions[i] > 0; i++)
for (int i = 0; versions[i] > 0; i++)
{
int ctxAttribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10,
WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10,
WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs);
if (m_hRC != NULL) break;
}
}
else
{
int ctxAttribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10,
WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10,
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0
};
m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs);
if (m_hRC != NULL) break;
}
}
if (m_hRC == 0)

View file

@ -10,12 +10,6 @@ out vec4 FragColor;
void main()
{
#ifndef NO_DISCARD
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
if (pixelpos.y > uClipHeightTop) discard;
if (pixelpos.y < uClipHeightBottom) discard;
#endif
float fogdist;
float fogfactor;

View file

@ -220,16 +220,10 @@ vec4 applyFog(vec4 frag, float fogfactor)
void main()
{
#ifndef NO_DISCARD
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
if (pixelpos.y > uClipHeightTop) discard;
if (pixelpos.y < uClipHeightBottom) discard;
#endif
vec4 frag = ProcessTexel();
#ifndef NO_DISCARD
// alpha testing
#ifdef CORE_PROFILE
// alpha testing - only for the core profile, in compatibility mode we use the alpha test.
if (frag.a <= uAlphaThreshold) discard;
#endif

View file

@ -65,4 +65,6 @@ void main()
#endif
gl_Position = ProjectionMatrix * eyeCoordPos;
gl_ClipDistance[0] = worldcoord.y - uClipHeightBottom;
gl_ClipDistance[1] = uClipHeightTop - worldcoord.y;
}

View file

@ -1,10 +1,13 @@
// This file contains common data definitions for both vertex and fragment shader
uniform vec4 uCameraPos;
uniform int uTextureMode;
uniform float uClipHeightTop, uClipHeightBottom;
uniform int uTextureMode;
#ifdef CORE_PROFILE
uniform float uAlphaThreshold;
#endif
// colors
uniform vec4 uObjectColor;