[iortcw] 59/89: All: Rend2: Use an OpenGL 3.2 core context if available

Simon McVittie smcv at debian.org
Fri Sep 8 10:44:28 UTC 2017


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to tag 1.51b
in repository iortcw.

commit d75aec11805b8b46006f76c05633683eda722308
Author: MAN-AT-ARMS <M4N4T4RMS at gmail.com>
Date:   Thu Jul 20 14:58:23 2017 -0400

    All: Rend2: Use an OpenGL 3.2 core context if available
---
 MP/code/rend2/glsl/dlight_fp.glsl     |  22 +++++-
 MP/code/rend2/glsl/generic_fp.glsl    |  23 +++++-
 MP/code/rend2/glsl/lightall_fp.glsl   |  21 +++++-
 MP/code/rend2/glsl/shadowmask_fp.glsl |  28 ++++----
 MP/code/rend2/qgl.h                   | 127 ++++++----------------------------
 MP/code/rend2/tr_backend.c            |  37 ----------
 MP/code/rend2/tr_dsa.c                |  46 ++++++------
 MP/code/rend2/tr_extensions.c         |  99 ++++++++------------------
 MP/code/rend2/tr_fbo.c                | 124 +++++++++++++++------------------
 MP/code/rend2/tr_glsl.c               |  13 +++-
 MP/code/rend2/tr_image.c              |  10 +--
 MP/code/rend2/tr_init.c               |  22 ++++--
 MP/code/rend2/tr_local.h              |   4 +-
 MP/code/rend2/tr_shade.c              |  26 +++++++
 MP/code/rend2/tr_shader.c             |   4 +-
 MP/code/rend2/tr_sky.c                |   6 ++
 MP/code/rend2/tr_surface.c            |   2 +
 MP/code/renderer/qgl.h                | 127 ++++++----------------------------
 MP/code/renderer/tr_init.c            |   2 +-
 MP/code/renderer/tr_local.h           |   2 +-
 MP/code/sdl/sdl_glimp.c               |  51 +++++++++++---
 SP/code/rend2/glsl/dlight_fp.glsl     |  22 +++++-
 SP/code/rend2/glsl/generic_fp.glsl    |  23 +++++-
 SP/code/rend2/glsl/lightall_fp.glsl   |  21 +++++-
 SP/code/rend2/glsl/shadowmask_fp.glsl |  28 ++++----
 SP/code/rend2/qgl.h                   | 127 ++++++----------------------------
 SP/code/rend2/tr_backend.c            |  37 ----------
 SP/code/rend2/tr_dsa.c                |  46 ++++++------
 SP/code/rend2/tr_extensions.c         |  99 ++++++++------------------
 SP/code/rend2/tr_fbo.c                | 124 +++++++++++++++------------------
 SP/code/rend2/tr_glsl.c               |  13 +++-
 SP/code/rend2/tr_image.c              |  10 +--
 SP/code/rend2/tr_init.c               |  22 ++++--
 SP/code/rend2/tr_local.h              |   4 +-
 SP/code/rend2/tr_shade.c              |  26 +++++++
 SP/code/rend2/tr_shader.c             |   4 +-
 SP/code/rend2/tr_sky.c                |   4 ++
 SP/code/rend2/tr_surface.c            |   2 +
 SP/code/renderer/qgl.h                | 127 ++++++----------------------------
 SP/code/renderer/tr_init.c            |   2 +-
 SP/code/renderer/tr_local.h           |   2 +-
 SP/code/sdl/sdl_glimp.c               |  51 +++++++++++---
 42 files changed, 680 insertions(+), 910 deletions(-)

diff --git a/MP/code/rend2/glsl/dlight_fp.glsl b/MP/code/rend2/glsl/dlight_fp.glsl
index 8ffca5b..41be049 100644
--- a/MP/code/rend2/glsl/dlight_fp.glsl
+++ b/MP/code/rend2/glsl/dlight_fp.glsl
@@ -1,5 +1,7 @@
 uniform sampler2D u_DiffuseMap;
 
+uniform int       u_AlphaTest;
+
 varying vec2      var_Tex1;
 varying vec4      var_Color;
 
@@ -8,5 +10,23 @@ void main()
 {
 	vec4 color = texture2D(u_DiffuseMap, var_Tex1);
 
-	gl_FragColor = color * var_Color;
+	float alpha = color.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
+	
+	gl_FragColor.rgb = color.rgb * var_Color.rgb;
+	gl_FragColor.a = alpha;
 }
diff --git a/MP/code/rend2/glsl/generic_fp.glsl b/MP/code/rend2/glsl/generic_fp.glsl
index 50db078..c0a4940 100644
--- a/MP/code/rend2/glsl/generic_fp.glsl
+++ b/MP/code/rend2/glsl/generic_fp.glsl
@@ -1,5 +1,7 @@
 uniform sampler2D u_DiffuseMap;
 
+uniform int       u_AlphaTest;
+
 varying vec2      var_DiffuseTex;
 
 varying vec4      var_Color;
@@ -8,5 +10,24 @@ varying vec4      var_Color;
 void main()
 {
 	vec4 color  = texture2D(u_DiffuseMap, var_DiffuseTex);
-	gl_FragColor = color * var_Color;
+
+	float alpha = color.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
+	
+	gl_FragColor.rgb = color.rgb * var_Color.rgb;
+	gl_FragColor.a = alpha;
 }
diff --git a/MP/code/rend2/glsl/lightall_fp.glsl b/MP/code/rend2/glsl/lightall_fp.glsl
index 5cb8233..8e7c9b4 100644
--- a/MP/code/rend2/glsl/lightall_fp.glsl
+++ b/MP/code/rend2/glsl/lightall_fp.glsl
@@ -45,6 +45,8 @@ uniform vec4      u_CubeMapInfo;
 #endif
 #endif
 
+uniform int       u_AlphaTest;
+
 varying vec4      var_TexCoords;
 
 varying vec4      var_Color;
@@ -228,6 +230,23 @@ void main()
 #endif
 
 	vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
+	
+	float alpha = diffuse.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
 
 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
 	L = var_LightDir.xyz;
@@ -406,5 +425,5 @@ void main()
 
 #endif
 
-	gl_FragColor.a = diffuse.a * var_Color.a;
+	gl_FragColor.a = alpha;
 }
diff --git a/MP/code/rend2/glsl/shadowmask_fp.glsl b/MP/code/rend2/glsl/shadowmask_fp.glsl
index 053907c..2b57e3b 100644
--- a/MP/code/rend2/glsl/shadowmask_fp.glsl
+++ b/MP/code/rend2/glsl/shadowmask_fp.glsl
@@ -52,10 +52,10 @@ float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
 	offset.y += offset.x;
 	if (offset.y > 1.1) offset.y = 0.0;
 	
-	mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5,  0.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5,  0.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist)).r;
+	mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5,  0.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5,  0.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist));
 	 
 	mult *= 0.25;
 #endif
@@ -66,23 +66,23 @@ float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
 	float cosr = cos(r) * scale;
 	mat2 rmat = mat2(cosr, sinr, -sinr, cosr);
 
-	mult =  shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist)).r;
+	mult =  shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist));
   #if defined(USE_SHADOW_FILTER2)
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist)).r;
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist));
 
 	mult *= 0.11111;
   #else
     mult *= 0.33333;
   #endif
 #else
-	mult = shadow2D(shadowmap, vec3(st, dist)).r;
+	mult = shadow2D(shadowmap, vec3(st, dist));
 #endif
 
 	return mult;
diff --git a/MP/code/rend2/qgl.h b/MP/code/rend2/qgl.h
index edec10d..93fb8e6 100644
--- a/MP/code/rend2/qgl.h
+++ b/MP/code/rend2/qgl.h
@@ -464,6 +464,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 
 // OpenGL 1.3, was GL_ARB_texture_compression
 #define QGL_1_3_PROCS \
+	GLE(void, ActiveTexture, GLenum texture) \
 	GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
 	GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
 
@@ -561,97 +562,25 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_HALF_FLOAT_ARB                   0x140B
 #endif
 
-// GL_EXT_framebuffer_object
-#define QGL_EXT_framebuffer_object_PROCS \
-	GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
-	GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
-	GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
-	GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
-	GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
-	GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
-	GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
-	GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
-	GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
-	GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
-	GLE(void, GenerateMipmapEXT, GLenum target) \
-
-#ifndef GL_EXT_framebuffer_object
-#define GL_EXT_framebuffer_object
-#define GL_FRAMEBUFFER_EXT                     0x8D40
-#define GL_RENDERBUFFER_EXT                    0x8D41
-#define GL_STENCIL_INDEX1_EXT                  0x8D46
-#define GL_STENCIL_INDEX4_EXT                  0x8D47
-#define GL_STENCIL_INDEX8_EXT                  0x8D48
-#define GL_STENCIL_INDEX16_EXT                 0x8D49
-#define GL_RENDERBUFFER_WIDTH_EXT              0x8D42
-#define GL_RENDERBUFFER_HEIGHT_EXT             0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT    0x8D44
-#define GL_RENDERBUFFER_RED_SIZE_EXT           0x8D50
-#define GL_RENDERBUFFER_GREEN_SIZE_EXT         0x8D51
-#define GL_RENDERBUFFER_BLUE_SIZE_EXT          0x8D52
-#define GL_RENDERBUFFER_ALPHA_SIZE_EXT         0x8D53
-#define GL_RENDERBUFFER_DEPTH_SIZE_EXT         0x8D54
-#define GL_RENDERBUFFER_STENCIL_SIZE_EXT       0x8D55
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT            0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT  0x8CD3
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     0x8CD4
-#define GL_COLOR_ATTACHMENT0_EXT                0x8CE0
-#define GL_COLOR_ATTACHMENT1_EXT                0x8CE1
-#define GL_COLOR_ATTACHMENT2_EXT                0x8CE2
-#define GL_COLOR_ATTACHMENT3_EXT                0x8CE3
-#define GL_COLOR_ATTACHMENT4_EXT                0x8CE4
-#define GL_COLOR_ATTACHMENT5_EXT                0x8CE5
-#define GL_COLOR_ATTACHMENT6_EXT                0x8CE6
-#define GL_COLOR_ATTACHMENT7_EXT                0x8CE7
-#define GL_COLOR_ATTACHMENT8_EXT                0x8CE8
-#define GL_COLOR_ATTACHMENT9_EXT                0x8CE9
-#define GL_COLOR_ATTACHMENT10_EXT               0x8CEA
-#define GL_COLOR_ATTACHMENT11_EXT               0x8CEB
-#define GL_COLOR_ATTACHMENT12_EXT               0x8CEC
-#define GL_COLOR_ATTACHMENT13_EXT               0x8CED
-#define GL_COLOR_ATTACHMENT14_EXT               0x8CEE
-#define GL_COLOR_ATTACHMENT15_EXT               0x8CEF
-#define GL_DEPTH_ATTACHMENT_EXT                 0x8D00
-#define GL_STENCIL_ATTACHMENT_EXT               0x8D20
-#define GL_FRAMEBUFFER_COMPLETE_EXT                          0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT             0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT     0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT             0x8CD9
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT                0x8CDA
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT            0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT            0x8CDC
-#define GL_FRAMEBUFFER_UNSUPPORTED_EXT                       0x8CDD
-#define GL_FRAMEBUFFER_BINDING_EXT             0x8CA6
-#define GL_RENDERBUFFER_BINDING_EXT            0x8CA7
-#define GL_MAX_COLOR_ATTACHMENTS_EXT           0x8CDF
-#define GL_MAX_RENDERBUFFER_SIZE_EXT           0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT   0x0506
-#endif
-
-// GL_EXT_framebuffer_blit
-#define QGL_EXT_framebuffer_blit_PROCS \
-	GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
-
-#ifndef GL_EXT_framebuffer_blit
-#define GL_EXT_framebuffer_blit
-#define GL_READ_FRAMEBUFFER_EXT                0x8CA8
-#define GL_DRAW_FRAMEBUFFER_EXT                0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_EXT        0x8CA6
-#define GL_READ_FRAMEBUFFER_BINDING_EXT        0x8CAA
-#endif
-
-// GL_EXT_framebuffer_multisample
-#define QGL_EXT_framebuffer_multisample_PROCS \
-	GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
-
-#ifndef GL_EXT_framebuffer_multisample
-#define GL_EXT_framebuffer_multisample
-#define GL_RENDERBUFFER_SAMPLES_EXT                0x8CAB
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT  0x8D56
-#define GL_MAX_SAMPLES_EXT                         0x8D57
-#endif
+// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+#define QGL_3_0_PROCS \
+	GLE(const GLubyte *, GetStringi, GLenum name, GLuint index) \
+	GLE(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) \
+	GLE(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) \
+	GLE(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) \
+	GLE(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindFramebuffer, GLenum target, GLuint framebuffer) \
+	GLE(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) \
+	GLE(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) \
+	GLE(GLenum, CheckFramebufferStatus, GLenum target) \
+	GLE(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
+	GLE(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
+	GLE(void, GenerateMipmap, GLenum target) \
+	GLE(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
+	GLE(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindVertexArray, GLuint array) \
+	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
+	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
 
 #ifndef GL_ARB_texture_compression_rgtc
 #define GL_ARB_texture_compression_rgtc
@@ -679,17 +608,6 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_TEXTURE_CUBE_MAP_SEAMLESS               0x884F
 #endif
 
-// GL_ARB_vertex_array_object
-#define QGL_ARB_vertex_array_object_PROCS \
-	GLE(void, BindVertexArray, GLuint array) \
-	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
-	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
-
-#ifndef GL_ARB_vertex_array_object
-#define GL_ARB_vertex_array_object
-#define GL_VERTEX_ARRAY_BINDING_ARB                0x85B5
-#endif
-
 // GL_EXT_direct_state_access
 #define QGL_EXT_direct_state_access_PROCS \
 	GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
@@ -718,10 +636,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
diff --git a/MP/code/rend2/tr_backend.c b/MP/code/rend2/tr_backend.c
index 7744a02..be9d348 100644
--- a/MP/code/rend2/tr_backend.c
+++ b/MP/code/rend2/tr_backend.c
@@ -257,43 +257,6 @@ void GL_State( unsigned long stateBits ) {
 		}
 	}
 
-	//
-	// alpha test
-	//
-	if ( diff & GLS_ATEST_BITS ) {
-		uint32_t oldState = glState.glStateBits & GLS_ATEST_BITS;
-		uint32_t newState = stateBits & GLS_ATEST_BITS;
-		uint32_t storedState = glState.storedGlState & GLS_ATEST_BITS;
-
-		if (oldState == 0)
-		{
-			qglEnable(GL_ALPHA_TEST);
-		}
-		else if (newState == 0)
-		{
-			qglDisable(GL_ALPHA_TEST);
-		}
-
-		if (newState != 0 && storedState != newState)
-		{
-			glState.storedGlState &= ~GLS_ATEST_BITS;
-			glState.storedGlState |= newState;
-
-			switch ( newState )
-			{
-			case GLS_ATEST_GT_0:
-				qglAlphaFunc( GL_GREATER, 0.0f );
-				break;
-			case GLS_ATEST_LT_80:
-				qglAlphaFunc( GL_LESS, 0.5f );
-				break;
-			case GLS_ATEST_GE_80:
-				qglAlphaFunc( GL_GEQUAL, 0.5f );
-				break;
-			}
-		}
-	}
-
 	glState.glStateBits = stateBits;
 }
 
diff --git a/MP/code/rend2/tr_dsa.c b/MP/code/rend2/tr_dsa.c
index 8fde841..a9d0756 100644
--- a/MP/code/rend2/tr_dsa.c
+++ b/MP/code/rend2/tr_dsa.c
@@ -43,7 +43,7 @@ void GL_BindNullTextures()
 	{
 		for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
 		{
-			qglBindMultiTextureEXT(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0);
+			qglBindMultiTextureEXT(GL_TEXTURE0 + i, GL_TEXTURE_2D, 0);
 			glDsaState.textures[i] = 0;
 		}
 	}
@@ -51,19 +51,19 @@ void GL_BindNullTextures()
 	{
 		for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
 		{
-			qglActiveTextureARB(GL_TEXTURE0_ARB + i);
+			qglActiveTexture(GL_TEXTURE0 + i);
 			qglBindTexture(GL_TEXTURE_2D, 0);
 			glDsaState.textures[i] = 0;
 		}
 
-		qglActiveTextureARB(GL_TEXTURE0_ARB);
-		glDsaState.texunit = GL_TEXTURE0_ARB;
+		qglActiveTexture(GL_TEXTURE0);
+		glDsaState.texunit = GL_TEXTURE0;
 	}
 }
 
 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture)
 {
-	GLuint tmu = texunit - GL_TEXTURE0_ARB;
+	GLuint tmu = texunit - GL_TEXTURE0;
 
 	if (glDsaState.textures[tmu] == texture)
 		return 0;
@@ -80,7 +80,7 @@ GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint
 {
 	if (glDsaState.texunit != texunit)
 	{
-		qglActiveTextureARB(texunit);
+		qglActiveTexture(texunit);
 		glDsaState.texunit = texunit;
 	}
 
@@ -138,7 +138,7 @@ GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum targ
 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target)
 {
 	GL_BindMultiTexture(glDsaState.texunit, target, texture);
-	qglGenerateMipmapEXT(target);
+	qglGenerateMipmap(target);
 }
 
 void GL_BindNullProgram()
@@ -207,9 +207,9 @@ GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
 
 void GL_BindNullFramebuffers()
 {
-	qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+	qglBindFramebuffer(GL_FRAMEBUFFER, 0);
 	glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0;
-	qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+	qglBindRenderbuffer(GL_RENDERBUFFER, 0);
 	glDsaState.renderbuffer = 0;
 }
 
@@ -217,26 +217,26 @@ void GL_BindFramebuffer(GLenum target, GLuint framebuffer)
 {
 	switch (target)
 	{
-		case GL_FRAMEBUFFER_EXT:
+		case GL_FRAMEBUFFER:
 			if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer;
 			}
 			break;
 
-		case GL_DRAW_FRAMEBUFFER_EXT:
+		case GL_DRAW_FRAMEBUFFER:
 			if (framebuffer != glDsaState.drawFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.drawFramebuffer = framebuffer;
 			}
 			break;
 
-		case GL_READ_FRAMEBUFFER_EXT:
+		case GL_READ_FRAMEBUFFER:
 			if (framebuffer != glDsaState.readFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.readFramebuffer = framebuffer;
 			}
 			break;
@@ -247,7 +247,7 @@ void GL_BindRenderbuffer(GLuint renderbuffer)
 {
 	if (renderbuffer != glDsaState.renderbuffer)
 	{
-		qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
+		qglBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
 		glDsaState.renderbuffer = renderbuffer;
 	}
 }
@@ -256,32 +256,32 @@ GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
 	GLenum internalformat, GLsizei width, GLsizei height)
 {
 	GL_BindRenderbuffer(renderbuffer);
-	qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height);
+	qglRenderbufferStorage(GL_RENDERBUFFER, internalformat, width, height);
 }
 
 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
 	GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
 {
 	GL_BindRenderbuffer(renderbuffer);
-	qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height);
+	qglRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height);
 }
 
 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
 {
 	GL_BindFramebuffer(target, framebuffer);
-	return qglCheckFramebufferStatusEXT(target);
+	return qglCheckFramebufferStatus(target);
 }
 
 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
 	GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
-	qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+	qglFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textarget, texture, level);
 }
 
 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
 	GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 {
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
-	qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+	qglFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, renderbuffertarget, renderbuffer);
 }
diff --git a/MP/code/rend2/tr_extensions.c b/MP/code/rend2/tr_extensions.c
index 37bbe84..7df5295 100644
--- a/MP/code/rend2/tr_extensions.c
+++ b/MP/code/rend2/tr_extensions.c
@@ -34,10 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
@@ -75,6 +72,33 @@ void GLimp_InitExtraExtensions()
 	// OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
 	QGL_2_0_PROCS;
 
+	// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+	// QGL_*_PROCS becomes several functions, do not remove {}
+	if (glRefConfig.openglMajorVersion >= 3)
+	{
+		QGL_3_0_PROCS;
+
+		glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
+		glRefConfig.framebufferBlit = qtrue;
+		glRefConfig.framebufferMultisample = qtrue;
+
+		qglGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
+		qglGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
+
+		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], "OpenGL 3.0+ framebuffer procs");
+
+		// Don't let this be disabled, core context requires it
+		glRefConfig.vertexArrayObject = qtrue;
+
+		ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], "OpenGL 3.0+ vertex array object procs");
+	}
+	else
+	{
+		ri.Printf(PRINT_ALL, result[2], "OpenGL 3.0+ framebuffer procs");
+		ri.Printf(PRINT_ALL, result[2], "OpenGL 3.0+ vertex array object procs");
+
+	}
+
 	// Determine GLSL version
 	if (1)
 	{
@@ -136,57 +160,6 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
-	// GL_EXT_framebuffer_object
-	extension = "GL_EXT_framebuffer_object";
-	glRefConfig.framebufferObject = qfalse;
-	if( SDL_GL_ExtensionSupported( extension ) )
-	{
-		glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
-
-		qglGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
-		qglGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
-
-		QGL_EXT_framebuffer_object_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
-	// GL_EXT_framebuffer_blit
-	extension = "GL_EXT_framebuffer_blit";
-	glRefConfig.framebufferBlit = qfalse;
-	if (SDL_GL_ExtensionSupported(extension))
-	{
-		glRefConfig.framebufferBlit = qtrue;
-
-		QGL_EXT_framebuffer_blit_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferBlit], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
-	// GL_EXT_framebuffer_multisample
-	extension = "GL_EXT_framebuffer_multisample";
-	glRefConfig.framebufferMultisample = qfalse;
-	if (SDL_GL_ExtensionSupported(extension))
-	{
-		glRefConfig.framebufferMultisample = qtrue;
-
-		QGL_EXT_framebuffer_multisample_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferMultisample], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
 	glRefConfig.textureCompression = TCR_NONE;
 
 	// GL_ARB_texture_compression_rgtc
@@ -251,22 +224,6 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
-	// GL_ARB_vertex_array_object
-	extension = "GL_ARB_vertex_array_object";
-	glRefConfig.vertexArrayObject = qfalse;
-	if( SDL_GL_ExtensionSupported( extension ) )
-	{
-		glRefConfig.vertexArrayObject = !!r_arb_vertex_array_object->integer;
-
-		QGL_ARB_vertex_array_object_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
 	// GL_EXT_direct_state_access
 	extension = "GL_EXT_direct_state_access";
 	glRefConfig.directStateAccess = qfalse;
diff --git a/MP/code/rend2/tr_fbo.c b/MP/code/rend2/tr_fbo.c
index 6b7ab01..54dc8fe 100644
--- a/MP/code/rend2/tr_fbo.c
+++ b/MP/code/rend2/tr_fbo.c
@@ -32,48 +32,38 @@ R_CheckFBO
 */
 qboolean R_CheckFBO(const FBO_t * fbo)
 {
-	GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER_EXT);
+	GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER);
 
-	if(code == GL_FRAMEBUFFER_COMPLETE_EXT)
+	if(code == GL_FRAMEBUFFER_COMPLETE)
 		return qtrue;
 
 	// an error occured
 	switch (code)
 	{
-		case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+		case GL_FRAMEBUFFER_UNSUPPORTED:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Unsupported framebuffer format\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete attachment\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing attachment\n", fbo->name);
 			break;
 
-			//case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
-			//  ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, duplicate attachment\n", fbo->name);
-			//  break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
-			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, attached images must have same dimensions\n",
-					  fbo->name);
-			break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
-			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, attached images must have same format\n",
-					  fbo->name);
-			break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing draw buffer\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing read buffer\n", fbo->name);
 			break;
 
+		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete multisample\n", fbo->name);
+			break;
+
 		default:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code);
 			break;
@@ -117,7 +107,7 @@ FBO_t          *FBO_Create(const char *name, int width, int height)
 	fbo->width = width;
 	fbo->height = height;
 
-	qglGenFramebuffersEXT(1, &fbo->frameBuffer);
+	qglGenFramebuffers(1, &fbo->frameBuffer);
 
 	return fbo;
 }
@@ -145,7 +135,7 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 		case GL_RGBA32F_ARB:
 			fbo->colorFormat = format;
 			pRenderBuffer = &fbo->colorBuffers[index];
-			attachment = GL_COLOR_ATTACHMENT0_EXT + index;
+			attachment = GL_COLOR_ATTACHMENT0 + index;
 			break;
 
 		case GL_DEPTH_COMPONENT:
@@ -154,21 +144,21 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 		case GL_DEPTH_COMPONENT32_ARB:
 			fbo->depthFormat = format;
 			pRenderBuffer = &fbo->depthBuffer;
-			attachment = GL_DEPTH_ATTACHMENT_EXT;
+			attachment = GL_DEPTH_ATTACHMENT;
 			break;
 
 		case GL_STENCIL_INDEX:
-		case GL_STENCIL_INDEX1_EXT:
-		case GL_STENCIL_INDEX4_EXT:
-		case GL_STENCIL_INDEX8_EXT:
-		case GL_STENCIL_INDEX16_EXT:
+		case GL_STENCIL_INDEX1:
+		case GL_STENCIL_INDEX4:
+		case GL_STENCIL_INDEX8:
+		case GL_STENCIL_INDEX16:
 			fbo->stencilFormat = format;
 			pRenderBuffer = &fbo->stencilBuffer;
-			attachment = GL_STENCIL_ATTACHMENT_EXT;
+			attachment = GL_STENCIL_ATTACHMENT;
 			break;
 
-		case GL_DEPTH_STENCIL_EXT:
-		case GL_DEPTH24_STENCIL8_EXT:
+		case GL_DEPTH_STENCIL:
+		case GL_DEPTH24_STENCIL8:
 			fbo->packedDepthStencilFormat = format;
 			pRenderBuffer = &fbo->packedDepthStencilBuffer;
 			attachment = 0; // special for stencil and depth
@@ -181,7 +171,7 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 
 	absent = *pRenderBuffer == 0;
 	if (absent)
-		qglGenRenderbuffersEXT(1, pRenderBuffer);
+		qglGenRenderbuffers(1, pRenderBuffer);
 
 	if (multisample && glRefConfig.framebufferMultisample)
 		qglNamedRenderbufferStorageMultisampleEXT(*pRenderBuffer, multisample, format, fbo->width, fbo->height);
@@ -192,12 +182,12 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 	{
 		if (attachment == 0)
 		{
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT,   GL_RENDERBUFFER_EXT, *pRenderBuffer);
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT,   GL_RENDERBUFFER, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *pRenderBuffer);
 		}
 		else
 		{
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER, *pRenderBuffer);
 		}
 	}
 }
@@ -217,7 +207,7 @@ void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubem
 		target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside;
 
 	qglNamedFramebufferTexture2DEXT(fbo->frameBuffer, attachment, target, image->texnum, 0);
-	index = attachment - GL_COLOR_ATTACHMENT0_EXT;
+	index = attachment - GL_COLOR_ATTACHMENT0;
 	if (index >= 0 && index <= 15)
 		fbo->colorImage[index] = image;
 }
@@ -245,7 +235,7 @@ void FBO_Bind(FBO_t * fbo)
 		GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL"));
 	}
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, fbo ? fbo->frameBuffer : 0);
 	glState.currentFBO = fbo;
 }
 
@@ -275,7 +265,7 @@ void FBO_Init(void)
 		hdrFormat = GL_RGBA16F_ARB;
 
 	if (glRefConfig.framebufferMultisample)
-		qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
+		qglGetIntegerv(GL_MAX_SAMPLES, &multisample);
 
 	if (r_ext_framebuffer_multisample->integer < multisample)
 		multisample = r_ext_framebuffer_multisample->integer;
@@ -292,19 +282,19 @@ void FBO_Init(void)
 	{
 		tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
 		FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample);
-		FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
+		FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24, 0, multisample);
 		R_CheckFBO(tr.renderFbo);
 
 		tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.msaaResolveFbo);
 	}
 	else if (r_hdr->integer)
 	{
 		tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.renderFbo);
 	}
 
@@ -312,23 +302,23 @@ void FBO_Init(void)
 	// this fixes the corrupt screen bug with r_hdr 1 on older hardware
 	if (tr.renderFbo)
 	{
-		GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer);
+		GL_BindFramebuffer(GL_FRAMEBUFFER, tr.renderFbo->frameBuffer);
 		qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 	}
 
 	if (tr.screenScratchImage)
 	{
 		tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
-		FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.screenScratchFbo);
 	}
 
 	if (tr.sunRaysImage)
 	{
 		tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.sunRaysFbo);
 	}
 
@@ -338,7 +328,7 @@ void FBO_Init(void)
 		for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
 		{
 			tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
-			FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0, 0);
 			FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
 			R_CheckFBO(tr.pshadowFbos[i]);
 		}
@@ -352,7 +342,7 @@ void FBO_Init(void)
 			// FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
 			// This at least gets sun shadows working on older GPUs (Intel)
 			FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
-			FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
+			FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT, 0);
 			R_CheckFBO(tr.sunShadowFbo[i]);
 		}
 	}
@@ -360,7 +350,7 @@ void FBO_Init(void)
 	if (tr.screenShadowImage)
 	{
 		tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
-		FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.screenShadowFbo);
 	}
 
@@ -369,7 +359,7 @@ void FBO_Init(void)
 		for (i = 0; i < 2; i++)
 		{
 			tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
-			FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0, 0);
 			R_CheckFBO(tr.textureScratchFbo[i]);
 		}
 	}
@@ -377,14 +367,14 @@ void FBO_Init(void)
 	if (tr.calcLevelsImage)
 	{
 		tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
-		FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.calcLevelsFbo);
 	}
 
 	if (tr.targetLevelsImage)
 	{
 		tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
-		FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.targetLevelsFbo);
 	}
 
@@ -393,7 +383,7 @@ void FBO_Init(void)
 		for (i = 0; i < 2; i++)
 		{
 			tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
-			FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0, 0);
 			R_CheckFBO(tr.quarterFbo[i]);
 		}
 	}
@@ -401,28 +391,28 @@ void FBO_Init(void)
 	if (tr.hdrDepthImage)
 	{
 		tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
-		FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.hdrDepthFbo);
 	}
 
 	if (tr.screenSsaoImage)
 	{
 		tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
-		FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.screenSsaoFbo);
 	}
 
 	if (tr.renderCubeImage)
 	{
 		tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height);
-		FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0, 0);
 		FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
 		R_CheckFBO(tr.renderCubeFbo);
 	}
 
 	GL_CheckErrors();
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, 0);
 	glState.currentFBO = NULL;
 }
 
@@ -450,17 +440,17 @@ void FBO_Shutdown(void)
 		for(j = 0; j < glRefConfig.maxColorAttachments; j++)
 		{
 			if(fbo->colorBuffers[j])
-				qglDeleteRenderbuffersEXT(1, &fbo->colorBuffers[j]);
+				qglDeleteRenderbuffers(1, &fbo->colorBuffers[j]);
 		}
 
 		if(fbo->depthBuffer)
-			qglDeleteRenderbuffersEXT(1, &fbo->depthBuffer);
+			qglDeleteRenderbuffers(1, &fbo->depthBuffer);
 
 		if(fbo->stencilBuffer)
-			qglDeleteRenderbuffersEXT(1, &fbo->stencilBuffer);
+			qglDeleteRenderbuffers(1, &fbo->stencilBuffer);
 
 		if(fbo->frameBuffer)
-			qglDeleteFramebuffersEXT(1, &fbo->frameBuffer);
+			qglDeleteFramebuffers(1, &fbo->frameBuffer);
 	}
 }
 
@@ -661,12 +651,12 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu
 		VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]);
 	}
 
-	GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb);
-	GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
-	qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
+	GL_BindFramebuffer(GL_READ_FRAMEBUFFER, srcFb);
+	GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFb);
+	qglBlitFramebuffer(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
 	                      dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3],
 						  buffers, filter);
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, 0);
 	glState.currentFBO = NULL;
 }
diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c
index da8d347..6455f77 100644
--- a/MP/code/rend2/tr_glsl.c
+++ b/MP/code/rend2/tr_glsl.c
@@ -147,6 +147,8 @@ static uniformInfo_t uniformsInfo[] =
 
 	{ "u_CubeMapInfo", GLSL_VEC4 },
 
+	{ "u_AlphaTest", GLSL_INT },
+
 	{ "u_FireRiseDir", GLSL_VEC3 },
 	{ "u_ZFadeLowest", GLSL_FLOAT },
 	{ "u_ZFadeHighest", GLSL_FLOAT },
@@ -243,7 +245,10 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *
 	// HACK: abuse the GLSL preprocessor to turn GLSL 1.20 shaders into 1.30 ones
 	if(glRefConfig.glslMajorVersion > 1 || (glRefConfig.glslMajorVersion == 1 && glRefConfig.glslMinorVersion >= 30))
 	{
-		Q_strcat(dest, size, "#version 130\n");
+		if (glRefConfig.glslMajorVersion > 1 || (glRefConfig.glslMajorVersion == 1 && glRefConfig.glslMinorVersion >= 50))
+			Q_strcat(dest, size, "#version 150\n");
+		else
+			Q_strcat(dest, size, "#version 130\n");
 
 		if(shaderType == GL_VERTEX_SHADER)
 		{
@@ -256,11 +261,15 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *
 
 			Q_strcat(dest, size, "out vec4 out_Color;\n");
 			Q_strcat(dest, size, "#define gl_FragColor out_Color\n");
+			Q_strcat(dest, size, "#define texture2D texture\n");
+			Q_strcat(dest, size, "#define textureCubeLod textureLod\n");
+			Q_strcat(dest, size, "#define shadow2D texture\n");
 		}
 	}
 	else
 	{
 		Q_strcat(dest, size, "#version 120\n");
+		Q_strcat(dest, size, "#define shadow2D(a,b) shadow2D(a,b).r \n");
 	}
 
 	// HACK: add some macros to avoid extra uniforms and save speed and code maintenance
@@ -957,7 +966,7 @@ void GLSL_InitGPUShaders(void)
 
 	attribs = ATTR_POSITION | ATTR_TEXCOORD;
 
-	if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp))
+	if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, extradefines, qtrue, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp))
 	{
 		ri.Error(ERR_FATAL, "Could not load texturecolor shader!");
 	}
diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c
index 272b014..314ac89 100644
--- a/MP/code/rend2/tr_image.c
+++ b/MP/code/rend2/tr_image.c
@@ -2202,7 +2202,7 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe
 	}
 
 	image = tr.images[tr.numImages] = ri.Hunk_Alloc( sizeof( image_t ), h_low );
-	image->texnum = 1024 + tr.numImages;
+	qglGenTextures(1, &image->texnum);
 	tr.numImages++;
 
 	image->type = type;
@@ -2851,13 +2851,13 @@ void R_CreateBuiltinImages( void ) {
 			tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
 
 		if (r_shadowBlur->integer || r_ssao->integer)
-			tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
+			tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_R32F);
 
 		if (r_drawSunRays->integer)
 			tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
 
-		tr.renderDepthImage  = R_CreateImage("*renderdepth",  NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
-		tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
+		tr.renderDepthImage  = R_CreateImage("*renderdepth",  NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
+		tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
 
 		{
 			void *p;
@@ -2899,7 +2899,7 @@ void R_CreateBuiltinImages( void ) {
 		{
 			for ( x = 0; x < 4; x++)
 			{
-				tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
+				tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
 				qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
 				qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
 			}
diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c
index 0d7da2d..b152bab 100644
--- a/MP/code/rend2/tr_init.c
+++ b/MP/code/rend2/tr_init.c
@@ -335,7 +335,7 @@ static void InitOpenGL( void ) {
 	if ( glConfig.vidWidth == 0 ) {
 		GLint temp;
 
-		GLimp_Init();
+		GLimp_Init( qtrue );
 		GLimp_InitExtraExtensions();
 
 		strcpy( renderer_buffer, glConfig.renderer_string );
@@ -1032,14 +1032,11 @@ void GL_SetDefaultState( void ) {
 
 	qglCullFace( GL_FRONT );
 
-	qglColor4f( 1,1,1,1 );
-
 	GL_BindNullTextures();
 
 	if (glRefConfig.framebufferObject)
 		GL_BindNullFramebuffers();
 
-	qglEnable( GL_TEXTURE_2D );
 	GL_TextureMode( r_textureMode->string );
 
 	//qglShadeModel( GL_SMOOTH );
@@ -1168,7 +1165,21 @@ void GfxInfo_f( void ) {
 	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
 	ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
 	ri.Printf( PRINT_ALL, "GL_EXTENSIONS: " );
-	R_PrintLongString( glConfig.extensions_string );
+	if (glRefConfig.openglMajorVersion >= 3)
+	{
+		GLint numExtensions;
+		int i;
+
+		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+		for (i = 0; i < numExtensions; i++)
+		{
+			ri.Printf(PRINT_ALL, "%s ", qglGetStringi(GL_EXTENSIONS, i));
+		}
+	}
+	else
+	{
+		R_PrintLongString( glConfig.extensions_string );
+	}
 	ri.Printf( PRINT_ALL, "\n" );
 	ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
 	ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits );
@@ -1191,7 +1202,6 @@ void GfxInfo_f( void ) {
 	ri.Printf( PRINT_ALL, "texturemode: %s\n", r_textureMode->string );
 	ri.Printf( PRINT_ALL, "picmip: %d\n", r_picmip->integer );
 	ri.Printf( PRINT_ALL, "texture bits: %d\n", r_texturebits->integer );
-	ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] );
 	ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] );
 	ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] );
 	ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression != TC_NONE] );
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index cc146d1..cebc52c 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -780,6 +780,8 @@ typedef enum
 
 	UNIFORM_CUBEMAPINFO,
 
+	UNIFORM_ALPHATEST,
+
 	UNIFORM_FIRERISEDIR,
 	UNIFORM_ZFADELOWEST,
 	UNIFORM_ZFADEHIGHEST,
@@ -2164,7 +2166,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
 ====================================================================
 */
 
-void	GLimp_Init( void );
+void	GLimp_Init( qboolean );
 void	GLimp_Shutdown( void );
 void	GLimp_EndFrame( void );
 
diff --git a/MP/code/rend2/tr_shade.c b/MP/code/rend2/tr_shade.c
index 6ce9c6c..0c66ed3 100644
--- a/MP/code/rend2/tr_shade.c
+++ b/MP/code/rend2/tr_shade.c
@@ -129,6 +129,7 @@ static void DrawTris (shaderCommands_t *input) {
 		GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
 		VectorSet4(color, 1, 1, 1, 1);
 		GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color);
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		R_DrawElements(input->numIndexes, input->firstIndex);
 	}
@@ -418,6 +419,8 @@ static void ProjectDlightTexture( void ) {
 			GL_State( GLS_ATEST_GT_0 | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
 		}
 
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 1);
+
 		R_DrawElements(tess.numIndexes, tess.firstIndex);
 
 		backEnd.pc.c_totalIndexes += tess.numIndexes;
@@ -844,6 +847,7 @@ static void ForwardDlight( void ) {
 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
 		// where they aren't rendered
 		GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
 
@@ -956,6 +960,7 @@ static void ProjectPshadowVBOGLSL( void ) {
 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
 		// where they aren't rendered
 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		GL_BindToTMU( tr.pshadowMaps[l], TB_DIFFUSEMAP );
 
@@ -1103,6 +1108,7 @@ static void RB_FogPass( int wolfFog ) {
 	} else {
 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
 	}
+	GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 	R_DrawElements(tess.numIndexes, tess.firstIndex);
 }
@@ -1287,6 +1293,25 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
 			GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT);
 		}
 
+		GL_State( pStage->stateBits );
+		if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_GT_0)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 1);
+		}
+		else if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_LT_80)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 2);
+		}
+		else if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_GE_80)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 3);
+		}
+		else
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
+		}
+
+
 		{
 			vec4_t baseColor;
 			vec4_t vertColor;
@@ -1663,6 +1688,7 @@ static void RB_RenderShadowmap( shaderCommands_t *input )
 		GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, backEnd.viewParms.zFar);
 
 		GL_State( 0 );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		//
 		// do multitexture
diff --git a/MP/code/rend2/tr_shader.c b/MP/code/rend2/tr_shader.c
index dcd3f02..cfa8c14 100644
--- a/MP/code/rend2/tr_shader.c
+++ b/MP/code/rend2/tr_shader.c
@@ -3140,9 +3140,7 @@ static shader_t *FinishShader( void ) {
 	//
 	// look for multitexture potential
 	//
-	if ( qglActiveTextureARB ) {
-		stage = CollapseStagesToGLSL();
-	}
+	stage = CollapseStagesToGLSL();
 
 	if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
 		if ( vertexLightmap ) {
diff --git a/MP/code/rend2/tr_sky.c b/MP/code/rend2/tr_sky.c
index c4972d0..9dc76e3 100644
--- a/MP/code/rend2/tr_sky.c
+++ b/MP/code/rend2/tr_sky.c
@@ -471,8 +471,12 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
 
 		VectorSet4(vector, 0.0, 0.0, 0.0, 0.0);
 		GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
+
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 	}
 
+	R_DrawElements(tess.numIndexes - tess.firstIndex, tess.firstIndex);
+
 	//qglDrawElements(GL_TRIANGLES, tess.numIndexes - tess.firstIndex, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex * sizeof(glIndex_t)));
 	
 	//R_BindNullVBO();
@@ -579,6 +583,8 @@ static void DrawSkySideInner( struct image_s *image, const int mins[2], const in
 
 		VectorSet4(vector, 0.0, 0.0, 0.0, 0.0);
 		GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
+
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 	}
 
 	R_DrawElements(tess.numIndexes - tess.firstIndex, tess.firstIndex);
diff --git a/MP/code/rend2/tr_surface.c b/MP/code/rend2/tr_surface.c
index 02b455e..8719cdb 100644
--- a/MP/code/rend2/tr_surface.c
+++ b/MP/code/rend2/tr_surface.c
@@ -574,6 +574,8 @@ static void RB_SurfaceBeam( void ) {
 
 	GLSL_SetUniformVec4(sp, UNIFORM_COLOR, colorRed);
 
+	GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
+
 	R_DrawElements(tess.numIndexes, tess.firstIndex);
 
 	tess.numIndexes = 0;
diff --git a/MP/code/renderer/qgl.h b/MP/code/renderer/qgl.h
index 1e8fa1c..fd929a2 100644
--- a/MP/code/renderer/qgl.h
+++ b/MP/code/renderer/qgl.h
@@ -523,6 +523,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 
 // OpenGL 1.3, was GL_ARB_texture_compression
 #define QGL_1_3_PROCS \
+	GLE(void, ActiveTexture, GLenum texture) \
 	GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
 	GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
 
@@ -620,97 +621,25 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_HALF_FLOAT_ARB                   0x140B
 #endif
 
-// GL_EXT_framebuffer_object
-#define QGL_EXT_framebuffer_object_PROCS \
-	GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
-	GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
-	GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
-	GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
-	GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
-	GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
-	GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
-	GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
-	GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
-	GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
-	GLE(void, GenerateMipmapEXT, GLenum target) \
-
-#ifndef GL_EXT_framebuffer_object
-#define GL_EXT_framebuffer_object
-#define GL_FRAMEBUFFER_EXT                     0x8D40
-#define GL_RENDERBUFFER_EXT                    0x8D41
-#define GL_STENCIL_INDEX1_EXT                  0x8D46
-#define GL_STENCIL_INDEX4_EXT                  0x8D47
-#define GL_STENCIL_INDEX8_EXT                  0x8D48
-#define GL_STENCIL_INDEX16_EXT                 0x8D49
-#define GL_RENDERBUFFER_WIDTH_EXT              0x8D42
-#define GL_RENDERBUFFER_HEIGHT_EXT             0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT    0x8D44
-#define GL_RENDERBUFFER_RED_SIZE_EXT           0x8D50
-#define GL_RENDERBUFFER_GREEN_SIZE_EXT         0x8D51
-#define GL_RENDERBUFFER_BLUE_SIZE_EXT          0x8D52
-#define GL_RENDERBUFFER_ALPHA_SIZE_EXT         0x8D53
-#define GL_RENDERBUFFER_DEPTH_SIZE_EXT         0x8D54
-#define GL_RENDERBUFFER_STENCIL_SIZE_EXT       0x8D55
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT            0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT  0x8CD3
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     0x8CD4
-#define GL_COLOR_ATTACHMENT0_EXT                0x8CE0
-#define GL_COLOR_ATTACHMENT1_EXT                0x8CE1
-#define GL_COLOR_ATTACHMENT2_EXT                0x8CE2
-#define GL_COLOR_ATTACHMENT3_EXT                0x8CE3
-#define GL_COLOR_ATTACHMENT4_EXT                0x8CE4
-#define GL_COLOR_ATTACHMENT5_EXT                0x8CE5
-#define GL_COLOR_ATTACHMENT6_EXT                0x8CE6
-#define GL_COLOR_ATTACHMENT7_EXT                0x8CE7
-#define GL_COLOR_ATTACHMENT8_EXT                0x8CE8
-#define GL_COLOR_ATTACHMENT9_EXT                0x8CE9
-#define GL_COLOR_ATTACHMENT10_EXT               0x8CEA
-#define GL_COLOR_ATTACHMENT11_EXT               0x8CEB
-#define GL_COLOR_ATTACHMENT12_EXT               0x8CEC
-#define GL_COLOR_ATTACHMENT13_EXT               0x8CED
-#define GL_COLOR_ATTACHMENT14_EXT               0x8CEE
-#define GL_COLOR_ATTACHMENT15_EXT               0x8CEF
-#define GL_DEPTH_ATTACHMENT_EXT                 0x8D00
-#define GL_STENCIL_ATTACHMENT_EXT               0x8D20
-#define GL_FRAMEBUFFER_COMPLETE_EXT                          0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT             0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT     0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT             0x8CD9
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT                0x8CDA
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT            0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT            0x8CDC
-#define GL_FRAMEBUFFER_UNSUPPORTED_EXT                       0x8CDD
-#define GL_FRAMEBUFFER_BINDING_EXT             0x8CA6
-#define GL_RENDERBUFFER_BINDING_EXT            0x8CA7
-#define GL_MAX_COLOR_ATTACHMENTS_EXT           0x8CDF
-#define GL_MAX_RENDERBUFFER_SIZE_EXT           0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT   0x0506
-#endif
-
-// GL_EXT_framebuffer_blit
-#define QGL_EXT_framebuffer_blit_PROCS \
-	GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
-
-#ifndef GL_EXT_framebuffer_blit
-#define GL_EXT_framebuffer_blit
-#define GL_READ_FRAMEBUFFER_EXT                0x8CA8
-#define GL_DRAW_FRAMEBUFFER_EXT                0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_EXT        0x8CA6
-#define GL_READ_FRAMEBUFFER_BINDING_EXT        0x8CAA
-#endif
-
-// GL_EXT_framebuffer_multisample
-#define QGL_EXT_framebuffer_multisample_PROCS \
-	GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
-
-#ifndef GL_EXT_framebuffer_multisample
-#define GL_EXT_framebuffer_multisample
-#define GL_RENDERBUFFER_SAMPLES_EXT                0x8CAB
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT  0x8D56
-#define GL_MAX_SAMPLES_EXT                         0x8D57
-#endif
+// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+#define QGL_3_0_PROCS \
+	GLE(const GLubyte *, GetStringi, GLenum name, GLuint index) \
+	GLE(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) \
+	GLE(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) \
+	GLE(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) \
+	GLE(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindFramebuffer, GLenum target, GLuint framebuffer) \
+	GLE(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) \
+	GLE(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) \
+	GLE(GLenum, CheckFramebufferStatus, GLenum target) \
+	GLE(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
+	GLE(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
+	GLE(void, GenerateMipmap, GLenum target) \
+	GLE(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
+	GLE(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindVertexArray, GLuint array) \
+	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
+	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
 
 #ifndef GL_ARB_texture_compression_rgtc
 #define GL_ARB_texture_compression_rgtc
@@ -738,17 +667,6 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_TEXTURE_CUBE_MAP_SEAMLESS               0x884F
 #endif
 
-// GL_ARB_vertex_array_object
-#define QGL_ARB_vertex_array_object_PROCS \
-	GLE(void, BindVertexArray, GLuint array) \
-	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
-	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
-
-#ifndef GL_ARB_vertex_array_object
-#define GL_ARB_vertex_array_object
-#define GL_VERTEX_ARRAY_BINDING_ARB                0x85B5
-#endif
-
 // GL_EXT_direct_state_access
 #define QGL_EXT_direct_state_access_PROCS \
 	GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
@@ -777,10 +695,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
diff --git a/MP/code/renderer/tr_init.c b/MP/code/renderer/tr_init.c
index 63b7886..ce3da3c 100644
--- a/MP/code/renderer/tr_init.c
+++ b/MP/code/renderer/tr_init.c
@@ -275,7 +275,7 @@ static void InitOpenGL( void ) {
 	if ( glConfig.vidWidth == 0 ) {
 		GLint temp;
 
-		GLimp_Init();
+		GLimp_Init( qfalse );
 
 		strcpy( renderer_buffer, glConfig.renderer_string );
 		Q_strlwr( renderer_buffer );
diff --git a/MP/code/renderer/tr_local.h b/MP/code/renderer/tr_local.h
index e0722f6..1508fdd 100644
--- a/MP/code/renderer/tr_local.h
+++ b/MP/code/renderer/tr_local.h
@@ -1423,7 +1423,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
 ====================================================================
 */
 
-void	GLimp_Init( void );
+void	GLimp_Init( qboolean );
 void	GLimp_Shutdown( void );
 void	GLimp_EndFrame( void );
 
diff --git a/MP/code/sdl/sdl_glimp.c b/MP/code/sdl/sdl_glimp.c
index 9bae76b..c3d91ef 100644
--- a/MP/code/sdl/sdl_glimp.c
+++ b/MP/code/sdl/sdl_glimp.c
@@ -242,7 +242,7 @@ static void GLimp_DetectAvailableModes(void)
 GLimp_SetMode
 ===============
 */
-static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
+static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qboolean coreContext)
 {
 	const char *glstring;
 	int perChannelColorBits;
@@ -528,7 +528,37 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 
 		SDL_SetWindowIcon( SDL_window, icon );
 
-		if( ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
+		if (coreContext)
+		{
+			int profileMask, majorVersion, minorVersion;
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profileMask);
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &majorVersion);
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minorVersion);
+
+			ri.Printf(PRINT_ALL, "Trying to get an OpenGL 3.2 core context\n");
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+			if ((SDL_glContext = SDL_GL_CreateContext(SDL_window)) == NULL)
+			{
+				ri.Printf(PRINT_ALL, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
+				ri.Printf(PRINT_ALL, "Reverting to default context\n");
+
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profileMask);
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion);
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorVersion);
+			}
+			else
+			{
+				ri.Printf(PRINT_ALL, "SDL_GL_CreateContext succeeded, but: %s\n", SDL_GetError());
+			}
+		}
+		else
+		{
+			SDL_glContext = NULL;
+		}
+
+		if( !SDL_glContext && ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
 		{
 			ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
 			continue;
@@ -573,7 +603,7 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 GLimp_StartDriverAndSetMode
 ===============
 */
-static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder)
+static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder, qboolean gl3Core)
 {
 	rserr_t err;
 
@@ -600,7 +630,7 @@ static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qbool
 		fullscreen = qfalse;
 	}
 	
-	err = GLimp_SetMode(mode, fullscreen, noborder);
+	err = GLimp_SetMode(mode, fullscreen, noborder, gl3Core);
 
 	switch ( err )
 	{
@@ -820,7 +850,7 @@ This routine is responsible for initializing the OS specific portions
 of OpenGL
 ===============
 */
-void GLimp_Init( void )
+void GLimp_Init( qboolean coreContext)
 {
 	ri.Printf( PRINT_DEVELOPER, "Glimp_Init( )\n" );
 
@@ -842,13 +872,13 @@ void GLimp_Init( void )
 	ri.Sys_GLimpInit( );
 
 	// Create the window and set up the context
-	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, r_noborder->integer))
+	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, r_noborder->integer, coreContext))
 		goto success;
 
 	// Try again, this time in a platform specific "safe mode"
 	ri.Sys_GLimpSafeInit( );
 
-	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, qfalse))
+	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, qfalse, coreContext))
 		goto success;
 
 	// Finally, try the default screen resolution
@@ -857,7 +887,7 @@ void GLimp_Init( void )
 		ri.Printf( PRINT_ALL, "Setting r_mode %d failed, falling back on r_mode %d\n",
 				r_mode->integer, R_MODE_FALLBACK );
 
-		if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse))
+		if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse, coreContext))
 			goto success;
 	}
 
@@ -879,7 +909,10 @@ success:
 	if (*glConfig.renderer_string && glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n')
 		glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0;
 	Q_strncpyz( glConfig.version_string, (char *) qglGetString (GL_VERSION), sizeof( glConfig.version_string ) );
-	Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+	if (qglGetString(GL_EXTENSIONS))
+		Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+	else
+		Q_strncpyz( glConfig.extensions_string, "Not available (core context, fixme)", sizeof( glConfig.extensions_string ) );
 
 	// initialize extensions
 	GLimp_InitExtensions( );
diff --git a/SP/code/rend2/glsl/dlight_fp.glsl b/SP/code/rend2/glsl/dlight_fp.glsl
index 8ffca5b..41be049 100644
--- a/SP/code/rend2/glsl/dlight_fp.glsl
+++ b/SP/code/rend2/glsl/dlight_fp.glsl
@@ -1,5 +1,7 @@
 uniform sampler2D u_DiffuseMap;
 
+uniform int       u_AlphaTest;
+
 varying vec2      var_Tex1;
 varying vec4      var_Color;
 
@@ -8,5 +10,23 @@ void main()
 {
 	vec4 color = texture2D(u_DiffuseMap, var_Tex1);
 
-	gl_FragColor = color * var_Color;
+	float alpha = color.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
+	
+	gl_FragColor.rgb = color.rgb * var_Color.rgb;
+	gl_FragColor.a = alpha;
 }
diff --git a/SP/code/rend2/glsl/generic_fp.glsl b/SP/code/rend2/glsl/generic_fp.glsl
index 50db078..c0a4940 100644
--- a/SP/code/rend2/glsl/generic_fp.glsl
+++ b/SP/code/rend2/glsl/generic_fp.glsl
@@ -1,5 +1,7 @@
 uniform sampler2D u_DiffuseMap;
 
+uniform int       u_AlphaTest;
+
 varying vec2      var_DiffuseTex;
 
 varying vec4      var_Color;
@@ -8,5 +10,24 @@ varying vec4      var_Color;
 void main()
 {
 	vec4 color  = texture2D(u_DiffuseMap, var_DiffuseTex);
-	gl_FragColor = color * var_Color;
+
+	float alpha = color.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
+	
+	gl_FragColor.rgb = color.rgb * var_Color.rgb;
+	gl_FragColor.a = alpha;
 }
diff --git a/SP/code/rend2/glsl/lightall_fp.glsl b/SP/code/rend2/glsl/lightall_fp.glsl
index 5cb8233..8e7c9b4 100644
--- a/SP/code/rend2/glsl/lightall_fp.glsl
+++ b/SP/code/rend2/glsl/lightall_fp.glsl
@@ -45,6 +45,8 @@ uniform vec4      u_CubeMapInfo;
 #endif
 #endif
 
+uniform int       u_AlphaTest;
+
 varying vec4      var_TexCoords;
 
 varying vec4      var_Color;
@@ -228,6 +230,23 @@ void main()
 #endif
 
 	vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
+	
+	float alpha = diffuse.a * var_Color.a;
+	if (u_AlphaTest == 1)
+	{
+		if (alpha == 0.0)
+			discard;
+	}
+	else if (u_AlphaTest == 2)
+	{
+		if (alpha >= 0.5)
+			discard;
+	}
+	else if (u_AlphaTest == 3)
+	{
+		if (alpha < 0.5)
+			discard;
+	}
 
 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
 	L = var_LightDir.xyz;
@@ -406,5 +425,5 @@ void main()
 
 #endif
 
-	gl_FragColor.a = diffuse.a * var_Color.a;
+	gl_FragColor.a = alpha;
 }
diff --git a/SP/code/rend2/glsl/shadowmask_fp.glsl b/SP/code/rend2/glsl/shadowmask_fp.glsl
index 053907c..2b57e3b 100644
--- a/SP/code/rend2/glsl/shadowmask_fp.glsl
+++ b/SP/code/rend2/glsl/shadowmask_fp.glsl
@@ -52,10 +52,10 @@ float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
 	offset.y += offset.x;
 	if (offset.y > 1.1) offset.y = 0.0;
 	
-	mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5,  0.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5,  0.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist)).r
-	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist)).r;
+	mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5,  0.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5,  0.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist))
+	     + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist));
 	 
 	mult *= 0.25;
 #endif
@@ -66,23 +66,23 @@ float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
 	float cosr = cos(r) * scale;
 	mat2 rmat = mat2(cosr, sinr, -sinr, cosr);
 
-	mult =  shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist)).r;
+	mult =  shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist));
   #if defined(USE_SHADOW_FILTER2)
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist)).r;
-	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist)).r;
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist));
+	mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist));
 
 	mult *= 0.11111;
   #else
     mult *= 0.33333;
   #endif
 #else
-	mult = shadow2D(shadowmap, vec3(st, dist)).r;
+	mult = shadow2D(shadowmap, vec3(st, dist));
 #endif
 
 	return mult;
diff --git a/SP/code/rend2/qgl.h b/SP/code/rend2/qgl.h
index bafa29b..b1f3a18 100644
--- a/SP/code/rend2/qgl.h
+++ b/SP/code/rend2/qgl.h
@@ -464,6 +464,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 
 // OpenGL 1.3, was GL_ARB_texture_compression
 #define QGL_1_3_PROCS \
+	GLE(void, ActiveTexture, GLenum texture) \
 	GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
 	GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
 
@@ -561,97 +562,25 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_HALF_FLOAT_ARB                   0x140B
 #endif
 
-// GL_EXT_framebuffer_object
-#define QGL_EXT_framebuffer_object_PROCS \
-	GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
-	GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
-	GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
-	GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
-	GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
-	GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
-	GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
-	GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
-	GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
-	GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
-	GLE(void, GenerateMipmapEXT, GLenum target) \
-
-#ifndef GL_EXT_framebuffer_object
-#define GL_EXT_framebuffer_object
-#define GL_FRAMEBUFFER_EXT                     0x8D40
-#define GL_RENDERBUFFER_EXT                    0x8D41
-#define GL_STENCIL_INDEX1_EXT                  0x8D46
-#define GL_STENCIL_INDEX4_EXT                  0x8D47
-#define GL_STENCIL_INDEX8_EXT                  0x8D48
-#define GL_STENCIL_INDEX16_EXT                 0x8D49
-#define GL_RENDERBUFFER_WIDTH_EXT              0x8D42
-#define GL_RENDERBUFFER_HEIGHT_EXT             0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT    0x8D44
-#define GL_RENDERBUFFER_RED_SIZE_EXT           0x8D50
-#define GL_RENDERBUFFER_GREEN_SIZE_EXT         0x8D51
-#define GL_RENDERBUFFER_BLUE_SIZE_EXT          0x8D52
-#define GL_RENDERBUFFER_ALPHA_SIZE_EXT         0x8D53
-#define GL_RENDERBUFFER_DEPTH_SIZE_EXT         0x8D54
-#define GL_RENDERBUFFER_STENCIL_SIZE_EXT       0x8D55
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT            0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT  0x8CD3
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     0x8CD4
-#define GL_COLOR_ATTACHMENT0_EXT                0x8CE0
-#define GL_COLOR_ATTACHMENT1_EXT                0x8CE1
-#define GL_COLOR_ATTACHMENT2_EXT                0x8CE2
-#define GL_COLOR_ATTACHMENT3_EXT                0x8CE3
-#define GL_COLOR_ATTACHMENT4_EXT                0x8CE4
-#define GL_COLOR_ATTACHMENT5_EXT                0x8CE5
-#define GL_COLOR_ATTACHMENT6_EXT                0x8CE6
-#define GL_COLOR_ATTACHMENT7_EXT                0x8CE7
-#define GL_COLOR_ATTACHMENT8_EXT                0x8CE8
-#define GL_COLOR_ATTACHMENT9_EXT                0x8CE9
-#define GL_COLOR_ATTACHMENT10_EXT               0x8CEA
-#define GL_COLOR_ATTACHMENT11_EXT               0x8CEB
-#define GL_COLOR_ATTACHMENT12_EXT               0x8CEC
-#define GL_COLOR_ATTACHMENT13_EXT               0x8CED
-#define GL_COLOR_ATTACHMENT14_EXT               0x8CEE
-#define GL_COLOR_ATTACHMENT15_EXT               0x8CEF
-#define GL_DEPTH_ATTACHMENT_EXT                 0x8D00
-#define GL_STENCIL_ATTACHMENT_EXT               0x8D20
-#define GL_FRAMEBUFFER_COMPLETE_EXT                          0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT             0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT     0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT             0x8CD9
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT                0x8CDA
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT            0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT            0x8CDC
-#define GL_FRAMEBUFFER_UNSUPPORTED_EXT                       0x8CDD
-#define GL_FRAMEBUFFER_BINDING_EXT             0x8CA6
-#define GL_RENDERBUFFER_BINDING_EXT            0x8CA7
-#define GL_MAX_COLOR_ATTACHMENTS_EXT           0x8CDF
-#define GL_MAX_RENDERBUFFER_SIZE_EXT           0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT   0x0506
-#endif
-
-// GL_EXT_framebuffer_blit
-#define QGL_EXT_framebuffer_blit_PROCS \
-	GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
-
-#ifndef GL_EXT_framebuffer_blit
-#define GL_EXT_framebuffer_blit
-#define GL_READ_FRAMEBUFFER_EXT                0x8CA8
-#define GL_DRAW_FRAMEBUFFER_EXT                0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_EXT        0x8CA6
-#define GL_READ_FRAMEBUFFER_BINDING_EXT        0x8CAA
-#endif
-
-// GL_EXT_framebuffer_multisample
-#define QGL_EXT_framebuffer_multisample_PROCS \
-	GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
-
-#ifndef GL_EXT_framebuffer_multisample
-#define GL_EXT_framebuffer_multisample
-#define GL_RENDERBUFFER_SAMPLES_EXT                0x8CAB
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT  0x8D56
-#define GL_MAX_SAMPLES_EXT                         0x8D57
-#endif
+// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+#define QGL_3_0_PROCS \
+	GLE(const GLubyte *, GetStringi, GLenum name, GLuint index) \
+	GLE(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) \
+	GLE(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) \
+	GLE(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) \
+	GLE(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindFramebuffer, GLenum target, GLuint framebuffer) \
+	GLE(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) \
+	GLE(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) \
+	GLE(GLenum, CheckFramebufferStatus, GLenum target) \
+	GLE(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
+	GLE(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
+	GLE(void, GenerateMipmap, GLenum target) \
+	GLE(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
+	GLE(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindVertexArray, GLuint array) \
+	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
+	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
 
 #ifndef GL_ARB_texture_compression_rgtc
 #define GL_ARB_texture_compression_rgtc
@@ -679,17 +608,6 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_TEXTURE_CUBE_MAP_SEAMLESS               0x884F
 #endif
 
-// GL_ARB_vertex_array_object
-#define QGL_ARB_vertex_array_object_PROCS \
-	GLE(void, BindVertexArray, GLuint array) \
-	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
-	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
-
-#ifndef GL_ARB_vertex_array_object
-#define GL_ARB_vertex_array_object
-#define GL_VERTEX_ARRAY_BINDING_ARB                0x85B5
-#endif
-
 // GL_EXT_direct_state_access
 #define QGL_EXT_direct_state_access_PROCS \
 	GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
@@ -718,10 +636,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
diff --git a/SP/code/rend2/tr_backend.c b/SP/code/rend2/tr_backend.c
index 3ece870..2790086 100644
--- a/SP/code/rend2/tr_backend.c
+++ b/SP/code/rend2/tr_backend.c
@@ -256,43 +256,6 @@ void GL_State( unsigned long stateBits ) {
 		}
 	}
 
-	//
-	// alpha test
-	//
-	if ( diff & GLS_ATEST_BITS ) {
-		uint32_t oldState = glState.glStateBits & GLS_ATEST_BITS;
-		uint32_t newState = stateBits & GLS_ATEST_BITS;
-		uint32_t storedState = glState.storedGlState & GLS_ATEST_BITS;
-
-		if (oldState == 0)
-		{
-			qglEnable(GL_ALPHA_TEST);
-		}
-		else if (newState == 0)
-		{
-			qglDisable(GL_ALPHA_TEST);
-		}
-
-		if (newState != 0 && storedState != newState)
-		{
-			glState.storedGlState &= ~GLS_ATEST_BITS;
-			glState.storedGlState |= newState;
-
-			switch ( newState )
-			{
-			case GLS_ATEST_GT_0:
-				qglAlphaFunc( GL_GREATER, 0.0f );
-				break;
-			case GLS_ATEST_LT_80:
-				qglAlphaFunc( GL_LESS, 0.5f );
-				break;
-			case GLS_ATEST_GE_80:
-				qglAlphaFunc( GL_GEQUAL, 0.5f );
-				break;
-			}
-		}
-	}
-
 	glState.glStateBits = stateBits;
 }
 
diff --git a/SP/code/rend2/tr_dsa.c b/SP/code/rend2/tr_dsa.c
index 8fde841..a9d0756 100644
--- a/SP/code/rend2/tr_dsa.c
+++ b/SP/code/rend2/tr_dsa.c
@@ -43,7 +43,7 @@ void GL_BindNullTextures()
 	{
 		for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
 		{
-			qglBindMultiTextureEXT(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0);
+			qglBindMultiTextureEXT(GL_TEXTURE0 + i, GL_TEXTURE_2D, 0);
 			glDsaState.textures[i] = 0;
 		}
 	}
@@ -51,19 +51,19 @@ void GL_BindNullTextures()
 	{
 		for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
 		{
-			qglActiveTextureARB(GL_TEXTURE0_ARB + i);
+			qglActiveTexture(GL_TEXTURE0 + i);
 			qglBindTexture(GL_TEXTURE_2D, 0);
 			glDsaState.textures[i] = 0;
 		}
 
-		qglActiveTextureARB(GL_TEXTURE0_ARB);
-		glDsaState.texunit = GL_TEXTURE0_ARB;
+		qglActiveTexture(GL_TEXTURE0);
+		glDsaState.texunit = GL_TEXTURE0;
 	}
 }
 
 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture)
 {
-	GLuint tmu = texunit - GL_TEXTURE0_ARB;
+	GLuint tmu = texunit - GL_TEXTURE0;
 
 	if (glDsaState.textures[tmu] == texture)
 		return 0;
@@ -80,7 +80,7 @@ GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint
 {
 	if (glDsaState.texunit != texunit)
 	{
-		qglActiveTextureARB(texunit);
+		qglActiveTexture(texunit);
 		glDsaState.texunit = texunit;
 	}
 
@@ -138,7 +138,7 @@ GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum targ
 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target)
 {
 	GL_BindMultiTexture(glDsaState.texunit, target, texture);
-	qglGenerateMipmapEXT(target);
+	qglGenerateMipmap(target);
 }
 
 void GL_BindNullProgram()
@@ -207,9 +207,9 @@ GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
 
 void GL_BindNullFramebuffers()
 {
-	qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+	qglBindFramebuffer(GL_FRAMEBUFFER, 0);
 	glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0;
-	qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+	qglBindRenderbuffer(GL_RENDERBUFFER, 0);
 	glDsaState.renderbuffer = 0;
 }
 
@@ -217,26 +217,26 @@ void GL_BindFramebuffer(GLenum target, GLuint framebuffer)
 {
 	switch (target)
 	{
-		case GL_FRAMEBUFFER_EXT:
+		case GL_FRAMEBUFFER:
 			if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer;
 			}
 			break;
 
-		case GL_DRAW_FRAMEBUFFER_EXT:
+		case GL_DRAW_FRAMEBUFFER:
 			if (framebuffer != glDsaState.drawFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.drawFramebuffer = framebuffer;
 			}
 			break;
 
-		case GL_READ_FRAMEBUFFER_EXT:
+		case GL_READ_FRAMEBUFFER:
 			if (framebuffer != glDsaState.readFramebuffer)
 			{
-				qglBindFramebufferEXT(target, framebuffer);
+				qglBindFramebuffer(target, framebuffer);
 				glDsaState.readFramebuffer = framebuffer;
 			}
 			break;
@@ -247,7 +247,7 @@ void GL_BindRenderbuffer(GLuint renderbuffer)
 {
 	if (renderbuffer != glDsaState.renderbuffer)
 	{
-		qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
+		qglBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
 		glDsaState.renderbuffer = renderbuffer;
 	}
 }
@@ -256,32 +256,32 @@ GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
 	GLenum internalformat, GLsizei width, GLsizei height)
 {
 	GL_BindRenderbuffer(renderbuffer);
-	qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height);
+	qglRenderbufferStorage(GL_RENDERBUFFER, internalformat, width, height);
 }
 
 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
 	GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
 {
 	GL_BindRenderbuffer(renderbuffer);
-	qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height);
+	qglRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height);
 }
 
 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
 {
 	GL_BindFramebuffer(target, framebuffer);
-	return qglCheckFramebufferStatusEXT(target);
+	return qglCheckFramebufferStatus(target);
 }
 
 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
 	GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
-	qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+	qglFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textarget, texture, level);
 }
 
 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
 	GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 {
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
-	qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+	qglFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, renderbuffertarget, renderbuffer);
 }
diff --git a/SP/code/rend2/tr_extensions.c b/SP/code/rend2/tr_extensions.c
index 37bbe84..7df5295 100644
--- a/SP/code/rend2/tr_extensions.c
+++ b/SP/code/rend2/tr_extensions.c
@@ -34,10 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
@@ -75,6 +72,33 @@ void GLimp_InitExtraExtensions()
 	// OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
 	QGL_2_0_PROCS;
 
+	// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+	// QGL_*_PROCS becomes several functions, do not remove {}
+	if (glRefConfig.openglMajorVersion >= 3)
+	{
+		QGL_3_0_PROCS;
+
+		glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
+		glRefConfig.framebufferBlit = qtrue;
+		glRefConfig.framebufferMultisample = qtrue;
+
+		qglGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
+		qglGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
+
+		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], "OpenGL 3.0+ framebuffer procs");
+
+		// Don't let this be disabled, core context requires it
+		glRefConfig.vertexArrayObject = qtrue;
+
+		ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], "OpenGL 3.0+ vertex array object procs");
+	}
+	else
+	{
+		ri.Printf(PRINT_ALL, result[2], "OpenGL 3.0+ framebuffer procs");
+		ri.Printf(PRINT_ALL, result[2], "OpenGL 3.0+ vertex array object procs");
+
+	}
+
 	// Determine GLSL version
 	if (1)
 	{
@@ -136,57 +160,6 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
-	// GL_EXT_framebuffer_object
-	extension = "GL_EXT_framebuffer_object";
-	glRefConfig.framebufferObject = qfalse;
-	if( SDL_GL_ExtensionSupported( extension ) )
-	{
-		glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
-
-		qglGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
-		qglGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
-
-		QGL_EXT_framebuffer_object_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
-	// GL_EXT_framebuffer_blit
-	extension = "GL_EXT_framebuffer_blit";
-	glRefConfig.framebufferBlit = qfalse;
-	if (SDL_GL_ExtensionSupported(extension))
-	{
-		glRefConfig.framebufferBlit = qtrue;
-
-		QGL_EXT_framebuffer_blit_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferBlit], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
-	// GL_EXT_framebuffer_multisample
-	extension = "GL_EXT_framebuffer_multisample";
-	glRefConfig.framebufferMultisample = qfalse;
-	if (SDL_GL_ExtensionSupported(extension))
-	{
-		glRefConfig.framebufferMultisample = qtrue;
-
-		QGL_EXT_framebuffer_multisample_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.framebufferMultisample], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
 	glRefConfig.textureCompression = TCR_NONE;
 
 	// GL_ARB_texture_compression_rgtc
@@ -251,22 +224,6 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
-	// GL_ARB_vertex_array_object
-	extension = "GL_ARB_vertex_array_object";
-	glRefConfig.vertexArrayObject = qfalse;
-	if( SDL_GL_ExtensionSupported( extension ) )
-	{
-		glRefConfig.vertexArrayObject = !!r_arb_vertex_array_object->integer;
-
-		QGL_ARB_vertex_array_object_PROCS;
-
-		ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], extension);
-	}
-	else
-	{
-		ri.Printf(PRINT_ALL, result[2], extension);
-	}
-
 	// GL_EXT_direct_state_access
 	extension = "GL_EXT_direct_state_access";
 	glRefConfig.directStateAccess = qfalse;
diff --git a/SP/code/rend2/tr_fbo.c b/SP/code/rend2/tr_fbo.c
index 6b7ab01..54dc8fe 100644
--- a/SP/code/rend2/tr_fbo.c
+++ b/SP/code/rend2/tr_fbo.c
@@ -32,48 +32,38 @@ R_CheckFBO
 */
 qboolean R_CheckFBO(const FBO_t * fbo)
 {
-	GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER_EXT);
+	GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER);
 
-	if(code == GL_FRAMEBUFFER_COMPLETE_EXT)
+	if(code == GL_FRAMEBUFFER_COMPLETE)
 		return qtrue;
 
 	// an error occured
 	switch (code)
 	{
-		case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+		case GL_FRAMEBUFFER_UNSUPPORTED:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Unsupported framebuffer format\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete attachment\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing attachment\n", fbo->name);
 			break;
 
-			//case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
-			//  ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, duplicate attachment\n", fbo->name);
-			//  break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
-			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, attached images must have same dimensions\n",
-					  fbo->name);
-			break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
-			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, attached images must have same format\n",
-					  fbo->name);
-			break;
-
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing draw buffer\n", fbo->name);
 			break;
 
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete, missing read buffer\n", fbo->name);
 			break;
 
+		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Framebuffer incomplete multisample\n", fbo->name);
+			break;
+
 		default:
 			ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code);
 			break;
@@ -117,7 +107,7 @@ FBO_t          *FBO_Create(const char *name, int width, int height)
 	fbo->width = width;
 	fbo->height = height;
 
-	qglGenFramebuffersEXT(1, &fbo->frameBuffer);
+	qglGenFramebuffers(1, &fbo->frameBuffer);
 
 	return fbo;
 }
@@ -145,7 +135,7 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 		case GL_RGBA32F_ARB:
 			fbo->colorFormat = format;
 			pRenderBuffer = &fbo->colorBuffers[index];
-			attachment = GL_COLOR_ATTACHMENT0_EXT + index;
+			attachment = GL_COLOR_ATTACHMENT0 + index;
 			break;
 
 		case GL_DEPTH_COMPONENT:
@@ -154,21 +144,21 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 		case GL_DEPTH_COMPONENT32_ARB:
 			fbo->depthFormat = format;
 			pRenderBuffer = &fbo->depthBuffer;
-			attachment = GL_DEPTH_ATTACHMENT_EXT;
+			attachment = GL_DEPTH_ATTACHMENT;
 			break;
 
 		case GL_STENCIL_INDEX:
-		case GL_STENCIL_INDEX1_EXT:
-		case GL_STENCIL_INDEX4_EXT:
-		case GL_STENCIL_INDEX8_EXT:
-		case GL_STENCIL_INDEX16_EXT:
+		case GL_STENCIL_INDEX1:
+		case GL_STENCIL_INDEX4:
+		case GL_STENCIL_INDEX8:
+		case GL_STENCIL_INDEX16:
 			fbo->stencilFormat = format;
 			pRenderBuffer = &fbo->stencilBuffer;
-			attachment = GL_STENCIL_ATTACHMENT_EXT;
+			attachment = GL_STENCIL_ATTACHMENT;
 			break;
 
-		case GL_DEPTH_STENCIL_EXT:
-		case GL_DEPTH24_STENCIL8_EXT:
+		case GL_DEPTH_STENCIL:
+		case GL_DEPTH24_STENCIL8:
 			fbo->packedDepthStencilFormat = format;
 			pRenderBuffer = &fbo->packedDepthStencilBuffer;
 			attachment = 0; // special for stencil and depth
@@ -181,7 +171,7 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 
 	absent = *pRenderBuffer == 0;
 	if (absent)
-		qglGenRenderbuffersEXT(1, pRenderBuffer);
+		qglGenRenderbuffers(1, pRenderBuffer);
 
 	if (multisample && glRefConfig.framebufferMultisample)
 		qglNamedRenderbufferStorageMultisampleEXT(*pRenderBuffer, multisample, format, fbo->width, fbo->height);
@@ -192,12 +182,12 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
 	{
 		if (attachment == 0)
 		{
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT,   GL_RENDERBUFFER_EXT, *pRenderBuffer);
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT,   GL_RENDERBUFFER, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *pRenderBuffer);
 		}
 		else
 		{
-			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
+			qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER, *pRenderBuffer);
 		}
 	}
 }
@@ -217,7 +207,7 @@ void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubem
 		target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside;
 
 	qglNamedFramebufferTexture2DEXT(fbo->frameBuffer, attachment, target, image->texnum, 0);
-	index = attachment - GL_COLOR_ATTACHMENT0_EXT;
+	index = attachment - GL_COLOR_ATTACHMENT0;
 	if (index >= 0 && index <= 15)
 		fbo->colorImage[index] = image;
 }
@@ -245,7 +235,7 @@ void FBO_Bind(FBO_t * fbo)
 		GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL"));
 	}
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, fbo ? fbo->frameBuffer : 0);
 	glState.currentFBO = fbo;
 }
 
@@ -275,7 +265,7 @@ void FBO_Init(void)
 		hdrFormat = GL_RGBA16F_ARB;
 
 	if (glRefConfig.framebufferMultisample)
-		qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
+		qglGetIntegerv(GL_MAX_SAMPLES, &multisample);
 
 	if (r_ext_framebuffer_multisample->integer < multisample)
 		multisample = r_ext_framebuffer_multisample->integer;
@@ -292,19 +282,19 @@ void FBO_Init(void)
 	{
 		tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
 		FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample);
-		FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
+		FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24, 0, multisample);
 		R_CheckFBO(tr.renderFbo);
 
 		tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.msaaResolveFbo);
 	}
 	else if (r_hdr->integer)
 	{
 		tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.renderFbo);
 	}
 
@@ -312,23 +302,23 @@ void FBO_Init(void)
 	// this fixes the corrupt screen bug with r_hdr 1 on older hardware
 	if (tr.renderFbo)
 	{
-		GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer);
+		GL_BindFramebuffer(GL_FRAMEBUFFER, tr.renderFbo->frameBuffer);
 		qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 	}
 
 	if (tr.screenScratchImage)
 	{
 		tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
-		FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.screenScratchFbo);
 	}
 
 	if (tr.sunRaysImage)
 	{
 		tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
-		FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
-		FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
+		FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0, 0);
+		FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT, 0);
 		R_CheckFBO(tr.sunRaysFbo);
 	}
 
@@ -338,7 +328,7 @@ void FBO_Init(void)
 		for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
 		{
 			tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
-			FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0, 0);
 			FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
 			R_CheckFBO(tr.pshadowFbos[i]);
 		}
@@ -352,7 +342,7 @@ void FBO_Init(void)
 			// FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
 			// This at least gets sun shadows working on older GPUs (Intel)
 			FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
-			FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
+			FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT, 0);
 			R_CheckFBO(tr.sunShadowFbo[i]);
 		}
 	}
@@ -360,7 +350,7 @@ void FBO_Init(void)
 	if (tr.screenShadowImage)
 	{
 		tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
-		FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.screenShadowFbo);
 	}
 
@@ -369,7 +359,7 @@ void FBO_Init(void)
 		for (i = 0; i < 2; i++)
 		{
 			tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
-			FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0, 0);
 			R_CheckFBO(tr.textureScratchFbo[i]);
 		}
 	}
@@ -377,14 +367,14 @@ void FBO_Init(void)
 	if (tr.calcLevelsImage)
 	{
 		tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
-		FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.calcLevelsFbo);
 	}
 
 	if (tr.targetLevelsImage)
 	{
 		tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
-		FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.targetLevelsFbo);
 	}
 
@@ -393,7 +383,7 @@ void FBO_Init(void)
 		for (i = 0; i < 2; i++)
 		{
 			tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
-			FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+			FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0, 0);
 			R_CheckFBO(tr.quarterFbo[i]);
 		}
 	}
@@ -401,28 +391,28 @@ void FBO_Init(void)
 	if (tr.hdrDepthImage)
 	{
 		tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
-		FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.hdrDepthFbo);
 	}
 
 	if (tr.screenSsaoImage)
 	{
 		tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
-		FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0, 0);
 		R_CheckFBO(tr.screenSsaoFbo);
 	}
 
 	if (tr.renderCubeImage)
 	{
 		tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height);
-		FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0);
+		FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0, 0);
 		FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
 		R_CheckFBO(tr.renderCubeFbo);
 	}
 
 	GL_CheckErrors();
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, 0);
 	glState.currentFBO = NULL;
 }
 
@@ -450,17 +440,17 @@ void FBO_Shutdown(void)
 		for(j = 0; j < glRefConfig.maxColorAttachments; j++)
 		{
 			if(fbo->colorBuffers[j])
-				qglDeleteRenderbuffersEXT(1, &fbo->colorBuffers[j]);
+				qglDeleteRenderbuffers(1, &fbo->colorBuffers[j]);
 		}
 
 		if(fbo->depthBuffer)
-			qglDeleteRenderbuffersEXT(1, &fbo->depthBuffer);
+			qglDeleteRenderbuffers(1, &fbo->depthBuffer);
 
 		if(fbo->stencilBuffer)
-			qglDeleteRenderbuffersEXT(1, &fbo->stencilBuffer);
+			qglDeleteRenderbuffers(1, &fbo->stencilBuffer);
 
 		if(fbo->frameBuffer)
-			qglDeleteFramebuffersEXT(1, &fbo->frameBuffer);
+			qglDeleteFramebuffers(1, &fbo->frameBuffer);
 	}
 }
 
@@ -661,12 +651,12 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu
 		VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]);
 	}
 
-	GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb);
-	GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
-	qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
+	GL_BindFramebuffer(GL_READ_FRAMEBUFFER, srcFb);
+	GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFb);
+	qglBlitFramebuffer(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
 	                      dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3],
 						  buffers, filter);
 
-	GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+	GL_BindFramebuffer(GL_FRAMEBUFFER, 0);
 	glState.currentFBO = NULL;
 }
diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c
index da8d347..6455f77 100644
--- a/SP/code/rend2/tr_glsl.c
+++ b/SP/code/rend2/tr_glsl.c
@@ -147,6 +147,8 @@ static uniformInfo_t uniformsInfo[] =
 
 	{ "u_CubeMapInfo", GLSL_VEC4 },
 
+	{ "u_AlphaTest", GLSL_INT },
+
 	{ "u_FireRiseDir", GLSL_VEC3 },
 	{ "u_ZFadeLowest", GLSL_FLOAT },
 	{ "u_ZFadeHighest", GLSL_FLOAT },
@@ -243,7 +245,10 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *
 	// HACK: abuse the GLSL preprocessor to turn GLSL 1.20 shaders into 1.30 ones
 	if(glRefConfig.glslMajorVersion > 1 || (glRefConfig.glslMajorVersion == 1 && glRefConfig.glslMinorVersion >= 30))
 	{
-		Q_strcat(dest, size, "#version 130\n");
+		if (glRefConfig.glslMajorVersion > 1 || (glRefConfig.glslMajorVersion == 1 && glRefConfig.glslMinorVersion >= 50))
+			Q_strcat(dest, size, "#version 150\n");
+		else
+			Q_strcat(dest, size, "#version 130\n");
 
 		if(shaderType == GL_VERTEX_SHADER)
 		{
@@ -256,11 +261,15 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *
 
 			Q_strcat(dest, size, "out vec4 out_Color;\n");
 			Q_strcat(dest, size, "#define gl_FragColor out_Color\n");
+			Q_strcat(dest, size, "#define texture2D texture\n");
+			Q_strcat(dest, size, "#define textureCubeLod textureLod\n");
+			Q_strcat(dest, size, "#define shadow2D texture\n");
 		}
 	}
 	else
 	{
 		Q_strcat(dest, size, "#version 120\n");
+		Q_strcat(dest, size, "#define shadow2D(a,b) shadow2D(a,b).r \n");
 	}
 
 	// HACK: add some macros to avoid extra uniforms and save speed and code maintenance
@@ -957,7 +966,7 @@ void GLSL_InitGPUShaders(void)
 
 	attribs = ATTR_POSITION | ATTR_TEXCOORD;
 
-	if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp))
+	if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, extradefines, qtrue, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp))
 	{
 		ri.Error(ERR_FATAL, "Could not load texturecolor shader!");
 	}
diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c
index 5a02fe9..82abd2b 100644
--- a/SP/code/rend2/tr_image.c
+++ b/SP/code/rend2/tr_image.c
@@ -2198,7 +2198,7 @@ image_t *R_CreateImageExt2( const char *name, byte *pic, int width, int height,
 	}
 
 	image = tr.images[tr.numImages] = ri.Hunk_Alloc( sizeof( image_t ), h_low );
-	image->texnum = 1024 + tr.numImages;
+	qglGenTextures(1, &image->texnum);
 	tr.numImages++;
 
 	image->type = type;
@@ -2855,13 +2855,13 @@ void R_CreateBuiltinImages( void ) {
 			tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
 
 		if (r_shadowBlur->integer || r_ssao->integer)
-			tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
+			tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_R32F);
 
 		if (r_drawSunRays->integer)
 			tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
 
-		tr.renderDepthImage  = R_CreateImage("*renderdepth",  NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
-		tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
+		tr.renderDepthImage  = R_CreateImage("*renderdepth",  NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
+		tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
 
 		{
 			void *p;
@@ -2903,7 +2903,7 @@ void R_CreateBuiltinImages( void ) {
 		{
 			for ( x = 0; x < 4; x++)
 			{
-				tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
+				tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24);
 
 				qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
 				qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c
index 6d212d1..d8f07ec 100644
--- a/SP/code/rend2/tr_init.c
+++ b/SP/code/rend2/tr_init.c
@@ -341,7 +341,7 @@ static void InitOpenGL( void ) {
 	if ( glConfig.vidWidth == 0 ) {
 		GLint temp;
 
-		GLimp_Init();
+		GLimp_Init( qtrue );
 		GLimp_InitExtraExtensions();
 
 		strcpy( renderer_buffer, glConfig.renderer_string );
@@ -1035,14 +1035,11 @@ void GL_SetDefaultState( void ) {
 
 	qglCullFace( GL_FRONT );
 
-	qglColor4f( 1,1,1,1 );
-
 	GL_BindNullTextures();
 
 	if (glRefConfig.framebufferObject)
 		GL_BindNullFramebuffers();
 
-	qglEnable( GL_TEXTURE_2D );
 	GL_TextureMode( r_textureMode->string );
 
 	//qglShadeModel( GL_SMOOTH );
@@ -1172,7 +1169,21 @@ void GfxInfo_f( void ) {
 	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
 	ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
 	ri.Printf( PRINT_ALL, "GL_EXTENSIONS: " );
-	R_PrintLongString( glConfig.extensions_string );
+	if (glRefConfig.openglMajorVersion >= 3)
+	{
+		GLint numExtensions;
+		int i;
+
+		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+		for (i = 0; i < numExtensions; i++)
+		{
+			ri.Printf(PRINT_ALL, "%s ", qglGetStringi(GL_EXTENSIONS, i));
+		}
+	}
+	else
+	{
+		R_PrintLongString( glConfig.extensions_string );
+	}
 	ri.Printf( PRINT_ALL, "\n" );
 	ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
 	ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits );
@@ -1195,7 +1206,6 @@ void GfxInfo_f( void ) {
 	ri.Printf( PRINT_ALL, "picmip: %d\n", r_picmip->integer );
 	ri.Printf( PRINT_ALL, "picmip2: %d\n", r_picmip2->integer );
 	ri.Printf( PRINT_ALL, "texture bits: %d\n", r_texturebits->integer );
-	ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] );
 	ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] );
 	ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] );
 	ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression != TC_NONE] );
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index cf78ef2..739cb60 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -785,6 +785,8 @@ typedef enum
 
 	UNIFORM_CUBEMAPINFO,
 
+	UNIFORM_ALPHATEST,
+
 	UNIFORM_FIRERISEDIR,
 	UNIFORM_ZFADELOWEST,
 	UNIFORM_ZFADEHIGHEST,
@@ -2192,7 +2194,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
 ====================================================================
 */
 
-void	GLimp_Init( void );
+void	GLimp_Init( qboolean );
 void	GLimp_Shutdown( void );
 void	GLimp_EndFrame( void );
 
diff --git a/SP/code/rend2/tr_shade.c b/SP/code/rend2/tr_shade.c
index 9c0675d..12167d6 100644
--- a/SP/code/rend2/tr_shade.c
+++ b/SP/code/rend2/tr_shade.c
@@ -122,6 +122,7 @@ static void DrawTris (shaderCommands_t *input) {
 		GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
 		VectorSet4(color, 1, 1, 1, 1);
 		GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color);
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		R_DrawElements(input->numIndexes, input->firstIndex);
 	}
@@ -412,6 +413,8 @@ static void ProjectDlightTexture( void ) {
 			GL_State( GLS_ATEST_GT_0 | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
 		}
 
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 1);
+
 		R_DrawElements(tess.numIndexes, tess.firstIndex);
 
 		backEnd.pc.c_totalIndexes += tess.numIndexes;
@@ -838,6 +841,7 @@ static void ForwardDlight( void ) {
 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
 		// where they aren't rendered
 		GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
 
@@ -950,6 +954,7 @@ static void ProjectPshadowVBOGLSL( void ) {
 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
 		// where they aren't rendered
 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		GL_BindToTMU( tr.pshadowMaps[l], TB_DIFFUSEMAP );
 
@@ -1097,6 +1102,7 @@ static void RB_FogPass( int wolfFog ) {
 	} else {
 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
 	}
+	GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 	R_DrawElements(tess.numIndexes, tess.firstIndex);
 }
@@ -1281,6 +1287,25 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
 			GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT);
 		}
 
+		GL_State( pStage->stateBits );
+		if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_GT_0)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 1);
+		}
+		else if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_LT_80)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 2);
+		}
+		else if ((pStage->stateBits & GLS_ATEST_BITS) == GLS_ATEST_GE_80)
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 3);
+		}
+		else
+		{
+			GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
+		}
+
+
 		{
 			vec4_t baseColor;
 			vec4_t vertColor;
@@ -1658,6 +1683,7 @@ static void RB_RenderShadowmap( shaderCommands_t *input )
 		GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, backEnd.viewParms.zFar);
 
 		GL_State( 0 );
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 
 		//
 		// do multitexture
diff --git a/SP/code/rend2/tr_shader.c b/SP/code/rend2/tr_shader.c
index 7338fe0..8029ccc 100644
--- a/SP/code/rend2/tr_shader.c
+++ b/SP/code/rend2/tr_shader.c
@@ -3167,9 +3167,7 @@ static shader_t *FinishShader( void ) {
 	//
 	// look for multitexture potential
 	//
-	if ( qglActiveTextureARB ) {
-		stage = CollapseStagesToGLSL();
-	}
+	stage = CollapseStagesToGLSL();
 
 	if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
 		if ( vertexLightmap ) {
diff --git a/SP/code/rend2/tr_sky.c b/SP/code/rend2/tr_sky.c
index 648d9aa..835c36d 100644
--- a/SP/code/rend2/tr_sky.c
+++ b/SP/code/rend2/tr_sky.c
@@ -468,6 +468,8 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
 
 		VectorSet4(vector, 0.0, 0.0, 0.0, 0.0);
 		GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
+
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 	}
 
 	R_DrawElements(tess.numIndexes - tess.firstIndex, tess.firstIndex);
@@ -578,6 +580,8 @@ static void DrawSkySideInner( struct image_s *image, const int mins[2], const in
 
 		VectorSet4(vector, 0.0, 0.0, 0.0, 0.0);
 		GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
+
+		GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
 	}
 
 	R_DrawElements(tess.numIndexes - tess.firstIndex, tess.firstIndex);
diff --git a/SP/code/rend2/tr_surface.c b/SP/code/rend2/tr_surface.c
index 771bb76..eec96a0 100644
--- a/SP/code/rend2/tr_surface.c
+++ b/SP/code/rend2/tr_surface.c
@@ -572,6 +572,8 @@ static void RB_SurfaceBeam( void ) {
 
 	GLSL_SetUniformVec4(sp, UNIFORM_COLOR, colorRed);
 
+	GLSL_SetUniformInt(sp, UNIFORM_ALPHATEST, 0);
+
 	R_DrawElements(tess.numIndexes, tess.firstIndex);
 
 	tess.numIndexes = 0;
diff --git a/SP/code/renderer/qgl.h b/SP/code/renderer/qgl.h
index d6fe1d7..9d92b9f 100644
--- a/SP/code/renderer/qgl.h
+++ b/SP/code/renderer/qgl.h
@@ -523,6 +523,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 
 // OpenGL 1.3, was GL_ARB_texture_compression
 #define QGL_1_3_PROCS \
+	GLE(void, ActiveTexture, GLenum texture) \
 	GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
 	GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
 
@@ -620,97 +621,25 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_HALF_FLOAT_ARB                   0x140B
 #endif
 
-// GL_EXT_framebuffer_object
-#define QGL_EXT_framebuffer_object_PROCS \
-	GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
-	GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
-	GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
-	GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
-	GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
-	GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
-	GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
-	GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
-	GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
-	GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
-	GLE(void, GenerateMipmapEXT, GLenum target) \
-
-#ifndef GL_EXT_framebuffer_object
-#define GL_EXT_framebuffer_object
-#define GL_FRAMEBUFFER_EXT                     0x8D40
-#define GL_RENDERBUFFER_EXT                    0x8D41
-#define GL_STENCIL_INDEX1_EXT                  0x8D46
-#define GL_STENCIL_INDEX4_EXT                  0x8D47
-#define GL_STENCIL_INDEX8_EXT                  0x8D48
-#define GL_STENCIL_INDEX16_EXT                 0x8D49
-#define GL_RENDERBUFFER_WIDTH_EXT              0x8D42
-#define GL_RENDERBUFFER_HEIGHT_EXT             0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT    0x8D44
-#define GL_RENDERBUFFER_RED_SIZE_EXT           0x8D50
-#define GL_RENDERBUFFER_GREEN_SIZE_EXT         0x8D51
-#define GL_RENDERBUFFER_BLUE_SIZE_EXT          0x8D52
-#define GL_RENDERBUFFER_ALPHA_SIZE_EXT         0x8D53
-#define GL_RENDERBUFFER_DEPTH_SIZE_EXT         0x8D54
-#define GL_RENDERBUFFER_STENCIL_SIZE_EXT       0x8D55
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT            0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT            0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT          0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT  0x8CD3
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT     0x8CD4
-#define GL_COLOR_ATTACHMENT0_EXT                0x8CE0
-#define GL_COLOR_ATTACHMENT1_EXT                0x8CE1
-#define GL_COLOR_ATTACHMENT2_EXT                0x8CE2
-#define GL_COLOR_ATTACHMENT3_EXT                0x8CE3
-#define GL_COLOR_ATTACHMENT4_EXT                0x8CE4
-#define GL_COLOR_ATTACHMENT5_EXT                0x8CE5
-#define GL_COLOR_ATTACHMENT6_EXT                0x8CE6
-#define GL_COLOR_ATTACHMENT7_EXT                0x8CE7
-#define GL_COLOR_ATTACHMENT8_EXT                0x8CE8
-#define GL_COLOR_ATTACHMENT9_EXT                0x8CE9
-#define GL_COLOR_ATTACHMENT10_EXT               0x8CEA
-#define GL_COLOR_ATTACHMENT11_EXT               0x8CEB
-#define GL_COLOR_ATTACHMENT12_EXT               0x8CEC
-#define GL_COLOR_ATTACHMENT13_EXT               0x8CED
-#define GL_COLOR_ATTACHMENT14_EXT               0x8CEE
-#define GL_COLOR_ATTACHMENT15_EXT               0x8CEF
-#define GL_DEPTH_ATTACHMENT_EXT                 0x8D00
-#define GL_STENCIL_ATTACHMENT_EXT               0x8D20
-#define GL_FRAMEBUFFER_COMPLETE_EXT                          0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT             0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT     0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT             0x8CD9
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT                0x8CDA
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT            0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT            0x8CDC
-#define GL_FRAMEBUFFER_UNSUPPORTED_EXT                       0x8CDD
-#define GL_FRAMEBUFFER_BINDING_EXT             0x8CA6
-#define GL_RENDERBUFFER_BINDING_EXT            0x8CA7
-#define GL_MAX_COLOR_ATTACHMENTS_EXT           0x8CDF
-#define GL_MAX_RENDERBUFFER_SIZE_EXT           0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT   0x0506
-#endif
-
-// GL_EXT_framebuffer_blit
-#define QGL_EXT_framebuffer_blit_PROCS \
-	GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
-
-#ifndef GL_EXT_framebuffer_blit
-#define GL_EXT_framebuffer_blit
-#define GL_READ_FRAMEBUFFER_EXT                0x8CA8
-#define GL_DRAW_FRAMEBUFFER_EXT                0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_EXT        0x8CA6
-#define GL_READ_FRAMEBUFFER_BINDING_EXT        0x8CAA
-#endif
-
-// GL_EXT_framebuffer_multisample
-#define QGL_EXT_framebuffer_multisample_PROCS \
-	GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
-
-#ifndef GL_EXT_framebuffer_multisample
-#define GL_EXT_framebuffer_multisample
-#define GL_RENDERBUFFER_SAMPLES_EXT                0x8CAB
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT  0x8D56
-#define GL_MAX_SAMPLES_EXT                         0x8D57
-#endif
+// OpenGL 3.0, was GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, and GL_ARB_vertex_array_object
+#define QGL_3_0_PROCS \
+	GLE(const GLubyte *, GetStringi, GLenum name, GLuint index) \
+	GLE(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) \
+	GLE(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) \
+	GLE(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) \
+	GLE(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindFramebuffer, GLenum target, GLuint framebuffer) \
+	GLE(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) \
+	GLE(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) \
+	GLE(GLenum, CheckFramebufferStatus, GLenum target) \
+	GLE(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
+	GLE(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
+	GLE(void, GenerateMipmap, GLenum target) \
+	GLE(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
+	GLE(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
+	GLE(void, BindVertexArray, GLuint array) \
+	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
+	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
 
 #ifndef GL_ARB_texture_compression_rgtc
 #define GL_ARB_texture_compression_rgtc
@@ -738,17 +667,6 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 #define GL_TEXTURE_CUBE_MAP_SEAMLESS               0x884F
 #endif
 
-// GL_ARB_vertex_array_object
-#define QGL_ARB_vertex_array_object_PROCS \
-	GLE(void, BindVertexArray, GLuint array) \
-	GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
-	GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
-
-#ifndef GL_ARB_vertex_array_object
-#define GL_ARB_vertex_array_object
-#define GL_VERTEX_ARRAY_BINDING_ARB                0x85B5
-#endif
-
 // GL_EXT_direct_state_access
 #define QGL_EXT_direct_state_access_PROCS \
 	GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
@@ -777,10 +695,7 @@ extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
 QGL_1_3_PROCS;
 QGL_1_5_PROCS;
 QGL_2_0_PROCS;
-QGL_EXT_framebuffer_object_PROCS;
-QGL_EXT_framebuffer_blit_PROCS;
-QGL_EXT_framebuffer_multisample_PROCS;
-QGL_ARB_vertex_array_object_PROCS;
+QGL_3_0_PROCS;
 QGL_EXT_direct_state_access_PROCS;
 #undef GLE
 
diff --git a/SP/code/renderer/tr_init.c b/SP/code/renderer/tr_init.c
index 6b1df45..3e01811 100644
--- a/SP/code/renderer/tr_init.c
+++ b/SP/code/renderer/tr_init.c
@@ -281,7 +281,7 @@ static void InitOpenGL( void ) {
 	if ( glConfig.vidWidth == 0 ) {
 		GLint temp;
 
-		GLimp_Init();
+		GLimp_Init( qfalse );
 
 		strcpy( renderer_buffer, glConfig.renderer_string );
 		Q_strlwr( renderer_buffer );
diff --git a/SP/code/renderer/tr_local.h b/SP/code/renderer/tr_local.h
index a53ee2f..b978e3a 100644
--- a/SP/code/renderer/tr_local.h
+++ b/SP/code/renderer/tr_local.h
@@ -1449,7 +1449,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
 ====================================================================
 */
 
-void	GLimp_Init( void );
+void	GLimp_Init( qboolean );
 void	GLimp_Shutdown( void );
 void	GLimp_EndFrame( void );
 
diff --git a/SP/code/sdl/sdl_glimp.c b/SP/code/sdl/sdl_glimp.c
index 9bae76b..c3d91ef 100644
--- a/SP/code/sdl/sdl_glimp.c
+++ b/SP/code/sdl/sdl_glimp.c
@@ -242,7 +242,7 @@ static void GLimp_DetectAvailableModes(void)
 GLimp_SetMode
 ===============
 */
-static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
+static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qboolean coreContext)
 {
 	const char *glstring;
 	int perChannelColorBits;
@@ -528,7 +528,37 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 
 		SDL_SetWindowIcon( SDL_window, icon );
 
-		if( ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
+		if (coreContext)
+		{
+			int profileMask, majorVersion, minorVersion;
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profileMask);
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &majorVersion);
+			SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minorVersion);
+
+			ri.Printf(PRINT_ALL, "Trying to get an OpenGL 3.2 core context\n");
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+			SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+			if ((SDL_glContext = SDL_GL_CreateContext(SDL_window)) == NULL)
+			{
+				ri.Printf(PRINT_ALL, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
+				ri.Printf(PRINT_ALL, "Reverting to default context\n");
+
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profileMask);
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion);
+				SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorVersion);
+			}
+			else
+			{
+				ri.Printf(PRINT_ALL, "SDL_GL_CreateContext succeeded, but: %s\n", SDL_GetError());
+			}
+		}
+		else
+		{
+			SDL_glContext = NULL;
+		}
+
+		if( !SDL_glContext && ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
 		{
 			ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
 			continue;
@@ -573,7 +603,7 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 GLimp_StartDriverAndSetMode
 ===============
 */
-static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder)
+static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder, qboolean gl3Core)
 {
 	rserr_t err;
 
@@ -600,7 +630,7 @@ static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qbool
 		fullscreen = qfalse;
 	}
 	
-	err = GLimp_SetMode(mode, fullscreen, noborder);
+	err = GLimp_SetMode(mode, fullscreen, noborder, gl3Core);
 
 	switch ( err )
 	{
@@ -820,7 +850,7 @@ This routine is responsible for initializing the OS specific portions
 of OpenGL
 ===============
 */
-void GLimp_Init( void )
+void GLimp_Init( qboolean coreContext)
 {
 	ri.Printf( PRINT_DEVELOPER, "Glimp_Init( )\n" );
 
@@ -842,13 +872,13 @@ void GLimp_Init( void )
 	ri.Sys_GLimpInit( );
 
 	// Create the window and set up the context
-	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, r_noborder->integer))
+	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, r_noborder->integer, coreContext))
 		goto success;
 
 	// Try again, this time in a platform specific "safe mode"
 	ri.Sys_GLimpSafeInit( );
 
-	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, qfalse))
+	if(GLimp_StartDriverAndSetMode(r_mode->integer, r_fullscreen->integer, qfalse, coreContext))
 		goto success;
 
 	// Finally, try the default screen resolution
@@ -857,7 +887,7 @@ void GLimp_Init( void )
 		ri.Printf( PRINT_ALL, "Setting r_mode %d failed, falling back on r_mode %d\n",
 				r_mode->integer, R_MODE_FALLBACK );
 
-		if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse))
+		if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse, coreContext))
 			goto success;
 	}
 
@@ -879,7 +909,10 @@ success:
 	if (*glConfig.renderer_string && glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n')
 		glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0;
 	Q_strncpyz( glConfig.version_string, (char *) qglGetString (GL_VERSION), sizeof( glConfig.version_string ) );
-	Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+	if (qglGetString(GL_EXTENSIONS))
+		Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+	else
+		Q_strncpyz( glConfig.extensions_string, "Not available (core context, fixme)", sizeof( glConfig.extensions_string ) );
 
 	// initialize extensions
 	GLimp_InitExtensions( );

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git



More information about the Pkg-games-commits mailing list