diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 01c7ee3b95..6fd7f3f98c 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -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; } } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 6f5b9be14f..73d7d5ef3c 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -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) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index d8168bca57..a07cd3401b 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -74,8 +74,10 @@ class FRenderState int mEffectState; int mColormapState; - int glSrcBlend, glDstBlend; float glAlphaThreshold; + bool glClipOn; + + int glSrcBlend, glDstBlend; bool glAlphaTest; int glBlendEquation; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index afc5cf1f29..7c7efc91de 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -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; } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 932451298e..b9965972ca 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -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 diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index f00202fd8e..0b1e885488 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -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); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 0f569d2c42..2209f0bed5 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -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 diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 81f4dd10f5..259f881b45 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -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); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index db414bae62..3b630177ad 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -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) diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 1a2b0b0f9b..d8259c8452 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -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; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index c560574019..a4e4d782b3 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -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 diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index c404268293..e355141f0c 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -65,4 +65,6 @@ void main() #endif gl_Position = ProjectionMatrix * eyeCoordPos; + gl_ClipDistance[0] = worldcoord.y - uClipHeightBottom; + gl_ClipDistance[1] = uClipHeightTop - worldcoord.y; } diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 56e6965b21..2870cf975c 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -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;