From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Sun, 20 May 2018 23:59:04 +0000 (+0000)
Subject: Just assume GL_ARB_texture_non_power_of_two and a number of other extensions are... 
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ea165f1fabf5482f920308899a606eef655dfa89;p=xonotic%2Fdarkplaces.git

Just assume GL_ARB_texture_non_power_of_two and a number of other extensions are supported, this simplifies a lot of conditions.

Always use GL_ARB_vertex_buffer_object.

Remove use of glDrawRangeElements as it doesn't exist in GL3.2 Core Profile, and is less necessary with GL_ARB_vertex_buffer_object.

Merge a number of extensions into the core opengl functions.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12428 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/cl_screen.c b/cl_screen.c
index b3b8c4b8..d86c9686 100644
--- a/cl_screen.c
+++ b/cl_screen.c
@@ -2273,17 +2273,8 @@ static void SCR_SetLoadingScreenTexture(void)
 
 	SCR_ClearLoadingScreenTexture();
 
-	if (vid.support.arb_texture_non_power_of_two)
-	{
-		w = vid.width; h = vid.height;
-		loadingscreentexture_w = loadingscreentexture_h = 1;
-	}
-	else
-	{
-		w = CeilPowerOf2(vid.width); h = CeilPowerOf2(vid.height);
-		loadingscreentexture_w = vid.width / (float) w;
-		loadingscreentexture_h = vid.height / (float) h;
-	}
+	w = vid.width; h = vid.height;
+	loadingscreentexture_w = loadingscreentexture_h = 1;
 
 	loadingscreentexture = R_LoadTexture2D(r_main_texturepool, "loadingscreentexture", w, h, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP, -1, NULL);
 	R_Mesh_CopyToTexture(loadingscreentexture, 0, 0, 0, 0, vid.width, vid.height);
diff --git a/ft2.c b/ft2.c
index 3671c8b1..c7bb6633 100644
--- a/ft2.c
+++ b/ft2.c
@@ -928,7 +928,7 @@ static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean check_only)
 	memset(&temp, 0, sizeof(temp));
 	temp.size = size;
 	temp.glyphSize = size*2 + max(gpad_l + gpad_r, gpad_t + gpad_b);
-	if (!(r_font_nonpoweroftwo.integer && vid.support.arb_texture_non_power_of_two))
+	if (!r_font_nonpoweroftwo.integer)
 		temp.glyphSize = CeilPowerOf2(temp.glyphSize);
 	temp.sfx = (1.0/64.0)/(double)size;
 	temp.sfy = (1.0/64.0)/(double)size;
diff --git a/gl_backend.c b/gl_backend.c
index 4bde4354..84d0ab0d 100644
--- a/gl_backend.c
+++ b/gl_backend.c
@@ -75,7 +75,6 @@
 
 #define MAX_RENDERTARGETS 4
 
-cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
 
@@ -84,9 +83,6 @@ cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you
 cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
 cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
-cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
-cvar_t gl_vbo_dynamicvertex = {CVAR_SAVE, "gl_vbo_dynamicvertex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
-cvar_t gl_vbo_dynamicindex = {CVAR_SAVE, "gl_vbo_dynamicindex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
 cvar_t gl_fbo = {CVAR_SAVE, "gl_fbo", "1", "make use of GL_ARB_framebuffer_object extension to enable shadowmaps and other features using pixel formats different from the framebuffer"};
 
 cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
@@ -233,11 +229,6 @@ typedef struct gl_state_s
 	size_t preparevertices_tempdatamaxsize;
 	int preparevertices_numvertices;
 
-	qboolean usevbo_staticvertex;
-	qboolean usevbo_staticindex;
-	qboolean usevbo_dynamicvertex;
-	qboolean usevbo_dynamicindex;
-
 	memexpandablearray_t meshbufferarray;
 
 	qboolean active;
@@ -313,25 +304,10 @@ static void GL_VBOStats_f(void)
 
 static void GL_Backend_ResetState(void);
 
-static void R_Mesh_SetUseVBO(void)
-{
-	switch(vid.renderpath)
-	{
-	case RENDERPATH_GL20:
-	case RENDERPATH_GLES2:
-		gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
-		gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
-		gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo.integer) || vid.forcevbo;
-		gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer && gl_vbo.integer) || vid.forcevbo;
-		break;
-	}
-}
-
 static void gl_backend_start(void)
 {
 	memset(&gl_state, 0, sizeof(gl_state));
 
-	R_Mesh_SetUseVBO();
 	Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
 
 	Con_DPrintf("OpenGL backend started.\n");
@@ -345,8 +321,7 @@ static void gl_backend_start(void)
 	case RENDERPATH_GL20:
 	case RENDERPATH_GLES2:
 		// fetch current fbo here (default fbo is not 0 on some GLES devices)
-		if (vid.support.ext_framebuffer_object)
-			qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);
+		qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);
 		break;
 	}
 }
@@ -441,14 +416,9 @@ void gl_backend_init(void)
 	Cvar_RegisterVariable(&gl_polyblend);
 	Cvar_RegisterVariable(&v_flipped);
 	Cvar_RegisterVariable(&gl_dither);
-	Cvar_RegisterVariable(&gl_vbo);
-	Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
-	Cvar_RegisterVariable(&gl_vbo_dynamicindex);
 	Cvar_RegisterVariable(&gl_paranoid);
 	Cvar_RegisterVariable(&gl_printcheckerror);
 
-	Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
-
 	Cmd_AddCommand("gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
 
 	R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
@@ -1018,7 +988,7 @@ static void GL_BindVBO(int bufferobject)
 	{
 		gl_state.vertexbufferobject = bufferobject;
 		CHECKGLERROR
-		qglBindBufferARB(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+		qglBindBuffer(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
 	}
 }
 
@@ -1028,7 +998,7 @@ static void GL_BindEBO(int bufferobject)
 	{
 		gl_state.elementbufferobject = bufferobject;
 		CHECKGLERROR
-		qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+		qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
 	}
 }
 
@@ -1039,7 +1009,7 @@ static void GL_BindUBO(int bufferobject)
 		gl_state.uniformbufferobject = bufferobject;
 #ifdef GL_UNIFORM_BUFFER
 		CHECKGLERROR
-		qglBindBufferARB(GL_UNIFORM_BUFFER, bufferobject);CHECKGLERROR
+		qglBindBuffer(GL_UNIFORM_BUFFER, bufferobject);CHECKGLERROR
 #endif
 	}
 }
@@ -1047,135 +1017,76 @@ static void GL_BindUBO(int bufferobject)
 static const GLuint drawbuffers[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
 {
+	int temp;
+	GLuint status;
 	switch(vid.renderpath)
 	{
 	case RENDERPATH_GL20:
 	case RENDERPATH_GLES2:
-		if (vid.support.arb_framebuffer_object)
-		{
-			int temp;
-			GLuint status;
-			qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
-			R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
-			// GL_ARB_framebuffer_object (GL3-class hardware) - depth stencil attachment
+		qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
+		R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
+		// GL_ARB_framebuffer_object (GL3-class hardware) - depth stencil attachment
 #ifdef USE_GLES2
-			// FIXME: separate stencil attachment on GLES
-			if (depthtexture  && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
-			if (depthtexture  && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+		// FIXME: separate stencil attachment on GLES
+		if (depthtexture  && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+		if (depthtexture  && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
 #else
-			if (depthtexture  && depthtexture->texnum )
-			{
-				qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
-				if (depthtexture->glisdepthstencil) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
-			}
-			if (depthtexture  && depthtexture->renderbuffernum )
-			{
-				qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
-				if (depthtexture->glisdepthstencil) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
-			}
+		if (depthtexture  && depthtexture->texnum )
+		{
+			qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+			if (depthtexture->glisdepthstencil) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+		}
+		if (depthtexture  && depthtexture->renderbuffernum )
+		{
+			qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+			if (depthtexture->glisdepthstencil) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+		}
 #endif
-			if (colortexture  && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
-			if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
-			if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
-			if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
-			if (colortexture  && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
-			if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
-			if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
-			if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
+		if (colortexture  && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
+		if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
+		if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
+		if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
+		if (colortexture  && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
+		if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
+		if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
+		if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
 
 #ifndef USE_GLES2
-			if (colortexture4 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture3 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture2 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture && qglDrawBuffer)
-			{
-				qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-				qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-			}
-			else if (qglDrawBuffer)
-			{
-				qglDrawBuffer(GL_NONE);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-#endif
-			status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
-			if (status != GL_FRAMEBUFFER_COMPLETE)
-			{
-				Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
-				gl_state.framebufferobject = 0; // GL unbinds it for us
-				qglDeleteFramebuffers(1, (GLuint*)&temp);
-				temp = 0;
-			}
-			return temp;
+		if (colortexture4 && qglDrawBuffersARB)
+		{
+			qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
+			qglReadBuffer(GL_NONE);CHECKGLERROR
 		}
-		else if (vid.support.ext_framebuffer_object)
+		else if (colortexture3 && qglDrawBuffersARB)
 		{
-			int temp;
-			GLuint status;
-			qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
-			R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
-			// GL_EXT_framebuffer_object (GL2-class hardware) - no depth stencil attachment, let it break stencil
-			if (depthtexture  && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
-			if (depthtexture  && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT  , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
-			if (colortexture  && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
-			if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
-			if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
-			if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
-			if (colortexture  && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
-			if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
-			if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
-			if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
-
-#ifndef USE_GLES2
-			if (colortexture4 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture3 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture2 && qglDrawBuffersARB)
-			{
-				qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
-			else if (colortexture && qglDrawBuffer)
-			{
-				qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-				qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-			}
-			else if (qglDrawBuffer)
-			{
-				qglDrawBuffer(GL_NONE);CHECKGLERROR
-				qglReadBuffer(GL_NONE);CHECKGLERROR
-			}
+			qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
+			qglReadBuffer(GL_NONE);CHECKGLERROR
+		}
+		else if (colortexture2 && qglDrawBuffersARB)
+		{
+			qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
+			qglReadBuffer(GL_NONE);CHECKGLERROR
+		}
+		else if (colortexture && qglDrawBuffer)
+		{
+			qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+			qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+		}
+		else if (qglDrawBuffer)
+		{
+			qglDrawBuffer(GL_NONE);CHECKGLERROR
+			qglReadBuffer(GL_NONE);CHECKGLERROR
+		}
 #endif
-			status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
-			if (status != GL_FRAMEBUFFER_COMPLETE)
-			{
-				Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
-				gl_state.framebufferobject = 0; // GL unbinds it for us
-				qglDeleteFramebuffers(1, (GLuint*)&temp);
-				temp = 0;
-			}
-			return temp;
+		status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
+		if (status != GL_FRAMEBUFFER_COMPLETE)
+		{
+			Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+			gl_state.framebufferobject = 0; // GL unbinds it for us
+			qglDeleteFramebuffers(1, (GLuint*)&temp);
+			temp = 0;
 		}
-		return 0;
+		return temp;
 	}
 	return 0;
 }
@@ -1262,17 +1173,11 @@ static void GL_Backend_ResetState(void)
 		qglEnable(GL_DEPTH_TEST);CHECKGLERROR
 		qglDepthMask(gl_state.depthmask);CHECKGLERROR
 		qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
-		if (vid.support.arb_vertex_buffer_object)
-		{
-			qglBindBufferARB(GL_ARRAY_BUFFER, 0);
-			qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
-		}
-		if (vid.support.ext_framebuffer_object)
-			qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
+		qglBindBuffer(GL_ARRAY_BUFFER, 0);
+		qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+		qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
 		qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
-		qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
 		qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
-		qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
 		qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
 		gl_state.unit = MAX_TEXTUREUNITS;
 		gl_state.clientunit = MAX_TEXTUREUNITS;
@@ -1280,19 +1185,12 @@ static void GL_Backend_ResetState(void)
 		{
 			GL_ActiveTexture(i);
 			qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
-			if (vid.support.ext_texture_3d)
-			{
-				qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
-			}
-			if (vid.support.arb_texture_cube_map)
-			{
-				qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
-			}
+			qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
+			qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
 		}
 		for (i = 0;i < vid.texarrayunits;i++)
 		{
 			GL_BindVBO(0);
-			qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
 			qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
 		}
 		CHECKGLERROR
@@ -1706,7 +1604,6 @@ void R_Mesh_Start(void)
 {
 	BACKENDACTIVECHECK
 	R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
-	R_Mesh_SetUseVBO();
 	if (gl_printcheckerror.integer && !gl_paranoid.integer)
 	{
 		Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
@@ -1819,7 +1716,6 @@ void GL_Backend_FreeProgram(unsigned int prog)
 }
 
 // renders triangles using vertices from the active arrays
-int paranoidblah = 0;
 void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, int element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, int element3s_bufferoffset)
 {
 	unsigned int numelements = numtriangles * 3;
@@ -1842,27 +1738,15 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
 		element3s += firsttriangle * 3;
 	if (element3s_indexbuffer)
 		element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
-	switch(vid.renderpath)
-	{
-	case RENDERPATH_GL20:
-	case RENDERPATH_GLES2:
-		// check if the user specified to ignore static index buffers
-		if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
-		{
-			element3i_indexbuffer = NULL;
-			element3s_indexbuffer = NULL;
-		}
-		break;
-	}
 	// upload a dynamic index buffer if needed
 	if (element3s)
 	{
-		if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
+		if (!element3s_indexbuffer)
 			element3s_indexbuffer = R_BufferData_Store(numelements * sizeof(*element3s), (void *)element3s, R_BUFFERDATA_INDEX16, &element3s_bufferoffset);
 	}
 	else if (element3i)
 	{
-		if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
+		if (!element3i_indexbuffer)
 			element3i_indexbuffer = R_BufferData_Store(numelements * sizeof(*element3i), (void *)element3i, R_BUFFERDATA_INDEX32, &element3i_bufferoffset);
 	}
 	bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
@@ -1875,44 +1759,6 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
 	if (gl_paranoid.integer)
 	{
 		unsigned int i;
-		// LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
-#if 0
-		unsigned int j, size;
-		const int *p;
-		// note: there's no validation done here on buffer objects because it
-		// is somewhat difficult to get at the data, and gl_paranoid can be
-		// used without buffer objects if the need arises
-		// (the data could be gotten using glMapBuffer but it would be very
-		//  slow due to uncachable video memory reads)
-		if (!qglIsEnabled(GL_VERTEX_ARRAY))
-			Con_Print("R_Mesh_Draw: vertex array not enabled\n");
-		CHECKGLERROR
-		if (gl_state.pointer_vertex_pointer)
-			for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
-				paranoidblah += *p;
-		if (gl_state.pointer_color_enabled)
-		{
-			if (!qglIsEnabled(GL_COLOR_ARRAY))
-				Con_Print("R_Mesh_Draw: color array set but not enabled\n");
-			CHECKGLERROR
-			if (gl_state.pointer_color && gl_state.pointer_color_enabled)
-				for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
-					paranoidblah += *p;
-		}
-		for (i = 0;i < vid.texarrayunits;i++)
-		{
-			if (gl_state.units[i].arrayenabled)
-			{
-				GL_ClientActiveTexture(i);
-				if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
-					Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
-				CHECKGLERROR
-				if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
-					for (j = 0, size = numvertices * gl_state.units[i].arraycomponents, p = (int *)((float *)gl_state.units[i].pointer_texcoord + firstvertex * gl_state.units[i].arraycomponents);j < size;j++, p++)
-						paranoidblah += *p;
-			}
-		}
-#endif
 		if (element3i)
 		{
 			for (i = 0;i < (unsigned int) numtriangles * 3;i++)
@@ -1941,107 +1787,21 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
 		switch(vid.renderpath)
 		{
 		case RENDERPATH_GL20:
-			CHECKGLERROR
-			if (bufferobject3s)
-			{
-				GL_BindEBO(bufferobject3s);
-#ifndef USE_GLES2
-				if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
-				{
-					qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
-					CHECKGLERROR
-				}
-				else
-#endif
-				{
-					qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
-					CHECKGLERROR
-				}
-			}
-			else if (bufferobject3i)
-			{
-				GL_BindEBO(bufferobject3i);
-#ifndef USE_GLES2
-				if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
-				{
-					qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
-					CHECKGLERROR
-				}
-				else
-#endif
-				{
-					qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
-					CHECKGLERROR
-				}
-			}
-			else if (element3s)
-			{
-				GL_BindEBO(0);
-#ifndef USE_GLES2
-				if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
-				{
-					qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
-					CHECKGLERROR
-				}
-				else
-#endif
-				{
-					qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
-					CHECKGLERROR
-				}
-			}
-			else if (element3i)
-			{
-				GL_BindEBO(0);
-#ifndef USE_GLES2
-				if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
-				{
-					qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
-					CHECKGLERROR
-				}
-				else
-#endif
-				{
-					qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
-					CHECKGLERROR
-				}
-			}
-			else
-			{
-				qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
-				CHECKGLERROR
-			}
-			break;
 		case RENDERPATH_GLES2:
-			// GLES does not have glDrawRangeElements so this is a bit shorter than the GL20 path
+			CHECKGLERROR
 			if (bufferobject3s)
 			{
 				GL_BindEBO(bufferobject3s);
-				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
-				CHECKGLERROR
+				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);CHECKGLERROR
 			}
 			else if (bufferobject3i)
 			{
 				GL_BindEBO(bufferobject3i);
-				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
-				CHECKGLERROR
-			}
-			else if (element3s)
-			{
-				GL_BindEBO(0);
-				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
-				CHECKGLERROR
-			}
-			else if (element3i)
-			{
-				GL_BindEBO(0);
-				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
-				CHECKGLERROR
+				qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);CHECKGLERROR
 			}
 			else
 			{
-				qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
-				CHECKGLERROR
+				qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);CHECKGLERROR
 			}
 			break;
 		}
@@ -2057,18 +1817,6 @@ void R_Mesh_Finish(void)
 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isuniformbuffer, qboolean isdynamic, qboolean isindex16)
 {
 	r_meshbuffer_t *buffer;
-	if (isuniformbuffer)
-	{
-		if (!vid.support.arb_uniform_buffer_object)
-			return NULL;
-	}
-	else
-	{
-		if (!vid.support.arb_vertex_buffer_object)
-			return NULL;
-		if (!isdynamic && !(isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex))
-			return NULL;
-	}
 	buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
 	memset(buffer, 0, sizeof(*buffer));
 	buffer->bufferobject = 0;
@@ -2104,7 +1852,7 @@ void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t si
 	case RENDERPATH_GL20:
 	case RENDERPATH_GLES2:
 		if (!buffer->bufferobject)
-			qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
+			qglGenBuffers(1, (GLuint *)&buffer->bufferobject);
 		if (buffer->isuniformbuffer)
 			GL_BindUBO(buffer->bufferobject);
 		else if (buffer->isindexbuffer)
@@ -2120,9 +1868,9 @@ void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t si
 				buffertype = GL_UNIFORM_BUFFER;
 #endif
 			if (subdata)
-				qglBufferSubDataARB(buffertype, offset, size, data);
+				qglBufferSubData(buffertype, offset, size, data);
 			else
-				qglBufferDataARB(buffertype, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
+				qglBufferData(buffertype, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
 		}
 		if (buffer->isuniformbuffer)
 			GL_BindUBO(0);
@@ -2145,7 +1893,7 @@ void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
 			gl_state.vertexbufferobject = 0;
 		if (gl_state.elementbufferobject == buffer->bufferobject)
 			gl_state.elementbufferobject = 0;
-		qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
+		qglDeleteBuffers(1, (GLuint *)&buffer->bufferobject);
 		break;
 	}
 	Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
@@ -2209,6 +1957,8 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void
 		if (gl_state.pointer_vertex_components != components || gl_state.pointer_vertex_gltype != gltype || gl_state.pointer_vertex_stride != stride || gl_state.pointer_vertex_pointer != pointer || gl_state.pointer_vertex_vertexbuffer != vertexbuffer || gl_state.pointer_vertex_offset != bufferoffset)
 		{
 			int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
+			if (!bufferobject && gl_paranoid.integer)
+				Con_DPrintf("Warning: no bufferobject in R_Mesh_VertexPointer(%i, %i, %i, %p, %p, %08x)", components, gltype, (int)stride, pointer, vertexbuffer, (unsigned int)bufferoffset);
 			gl_state.pointer_vertex_components = components;
 			gl_state.pointer_vertex_gltype = gltype;
 			gl_state.pointer_vertex_stride = stride;
@@ -2410,9 +2160,7 @@ void R_Mesh_ResetTextureState(void)
 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer, int bufferoffset)
 {
 	// upload temporary vertexbuffer for this rendering
-	if (!gl_state.usevbo_staticvertex)
-		vertexbuffer = NULL;
-	if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
+	if (!vertexbuffer)
 		vertexbuffer = R_BufferData_Store(numvertices * sizeof(float[3]), (void *)vertex3f, R_BUFFERDATA_VERTEX, &bufferoffset);
 	if (vertexbuffer)
 	{
@@ -2444,92 +2192,60 @@ void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, con
 
 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
 {
-	if (gl_state.usevbo_dynamicvertex)
-	{
-		r_meshbuffer_t *buffer_vertex3f = NULL;
-		r_meshbuffer_t *buffer_color4f = NULL;
-		r_meshbuffer_t *buffer_texcoord2f = NULL;
-		int bufferoffset_vertex3f = 0;
-		int bufferoffset_color4f = 0;
-		int bufferoffset_texcoord2f = 0;
-		buffer_color4f    = R_BufferData_Store(numvertices * sizeof(float[4]), color4f   , R_BUFFERDATA_VERTEX, &bufferoffset_color4f   );
-		buffer_vertex3f   = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f  , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f  );
-		buffer_texcoord2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoord2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoord2f);
-		R_Mesh_VertexPointer(     3, GL_FLOAT        , sizeof(float[3])        , vertex3f          , buffer_vertex3f          , bufferoffset_vertex3f          );
-		R_Mesh_ColorPointer(      4, GL_FLOAT        , sizeof(float[4])        , color4f           , buffer_color4f           , bufferoffset_color4f           );
-		R_Mesh_TexCoordPointer(0, 2, GL_FLOAT        , sizeof(float[2])        , texcoord2f        , buffer_texcoord2f        , bufferoffset_texcoord2f        );
-		R_Mesh_TexCoordPointer(1, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
-	}
-	else
-	{
-		R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
-		R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
-		R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
-		R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
-	}
+	r_meshbuffer_t *buffer_vertex3f = NULL;
+	r_meshbuffer_t *buffer_color4f = NULL;
+	r_meshbuffer_t *buffer_texcoord2f = NULL;
+	int bufferoffset_vertex3f = 0;
+	int bufferoffset_color4f = 0;
+	int bufferoffset_texcoord2f = 0;
+	buffer_color4f    = R_BufferData_Store(numvertices * sizeof(float[4]), color4f   , R_BUFFERDATA_VERTEX, &bufferoffset_color4f   );
+	buffer_vertex3f   = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f  , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f  );
+	buffer_texcoord2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoord2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoord2f);
+	R_Mesh_VertexPointer(     3, GL_FLOAT        , sizeof(float[3])        , vertex3f          , buffer_vertex3f          , bufferoffset_vertex3f          );
+	R_Mesh_ColorPointer(      4, GL_FLOAT        , sizeof(float[4])        , color4f           , buffer_color4f           , bufferoffset_color4f           );
+	R_Mesh_TexCoordPointer(0, 2, GL_FLOAT        , sizeof(float[2])        , texcoord2f        , buffer_texcoord2f        , bufferoffset_texcoord2f        );
+	R_Mesh_TexCoordPointer(1, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(float[3])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
 }
 
 void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *color4f, const float *texcoordtexture2f, const float *texcoordlightmap2f)
 {
-	if (gl_state.usevbo_dynamicvertex)
-	{
-		r_meshbuffer_t *buffer_vertex3f = NULL;
-		r_meshbuffer_t *buffer_color4f = NULL;
-		r_meshbuffer_t *buffer_texcoordtexture2f = NULL;
-		r_meshbuffer_t *buffer_svector3f = NULL;
-		r_meshbuffer_t *buffer_tvector3f = NULL;
-		r_meshbuffer_t *buffer_normal3f = NULL;
-		r_meshbuffer_t *buffer_texcoordlightmap2f = NULL;
-		int bufferoffset_vertex3f = 0;
-		int bufferoffset_color4f = 0;
-		int bufferoffset_texcoordtexture2f = 0;
-		int bufferoffset_svector3f = 0;
-		int bufferoffset_tvector3f = 0;
-		int bufferoffset_normal3f = 0;
-		int bufferoffset_texcoordlightmap2f = 0;
-		buffer_color4f            = R_BufferData_Store(numvertices * sizeof(float[4]), color4f           , R_BUFFERDATA_VERTEX, &bufferoffset_color4f           );
-		buffer_vertex3f           = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f          , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f          );
-		buffer_svector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), svector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_svector3f         );
-		buffer_tvector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), tvector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_tvector3f         );
-		buffer_normal3f           = R_BufferData_Store(numvertices * sizeof(float[3]), normal3f          , R_BUFFERDATA_VERTEX, &bufferoffset_normal3f          );
-		buffer_texcoordtexture2f  = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordtexture2f , R_BUFFERDATA_VERTEX, &bufferoffset_texcoordtexture2f );
-		buffer_texcoordlightmap2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordlightmap2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoordlightmap2f);
-		R_Mesh_VertexPointer(     3, GL_FLOAT        , sizeof(float[3])        , vertex3f          , buffer_vertex3f          , bufferoffset_vertex3f          );
-		R_Mesh_ColorPointer(      4, GL_FLOAT        , sizeof(float[4])        , color4f           , buffer_color4f           , bufferoffset_color4f           );
-		R_Mesh_TexCoordPointer(0, 2, GL_FLOAT        , sizeof(float[2])        , texcoordtexture2f , buffer_texcoordtexture2f , bufferoffset_texcoordtexture2f );
-		R_Mesh_TexCoordPointer(1, 3, GL_FLOAT        , sizeof(float[3])        , svector3f         , buffer_svector3f         , bufferoffset_svector3f         );
-		R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(float[3])        , tvector3f         , buffer_tvector3f         , bufferoffset_tvector3f         );
-		R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(float[3])        , normal3f          , buffer_normal3f          , bufferoffset_normal3f          );
-		R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(float[2])        , texcoordlightmap2f, buffer_texcoordlightmap2f, bufferoffset_texcoordlightmap2f);
-		R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
-		R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
-	}
-	else
-	{
-		R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
-		R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
-		R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
-		R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
-		R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
-		R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
-		R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
-		R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
-		R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
-	}
+	r_meshbuffer_t *buffer_vertex3f = NULL;
+	r_meshbuffer_t *buffer_color4f = NULL;
+	r_meshbuffer_t *buffer_texcoordtexture2f = NULL;
+	r_meshbuffer_t *buffer_svector3f = NULL;
+	r_meshbuffer_t *buffer_tvector3f = NULL;
+	r_meshbuffer_t *buffer_normal3f = NULL;
+	r_meshbuffer_t *buffer_texcoordlightmap2f = NULL;
+	int bufferoffset_vertex3f = 0;
+	int bufferoffset_color4f = 0;
+	int bufferoffset_texcoordtexture2f = 0;
+	int bufferoffset_svector3f = 0;
+	int bufferoffset_tvector3f = 0;
+	int bufferoffset_normal3f = 0;
+	int bufferoffset_texcoordlightmap2f = 0;
+	buffer_color4f            = R_BufferData_Store(numvertices * sizeof(float[4]), color4f           , R_BUFFERDATA_VERTEX, &bufferoffset_color4f           );
+	buffer_vertex3f           = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f          , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f          );
+	buffer_svector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), svector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_svector3f         );
+	buffer_tvector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), tvector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_tvector3f         );
+	buffer_normal3f           = R_BufferData_Store(numvertices * sizeof(float[3]), normal3f          , R_BUFFERDATA_VERTEX, &bufferoffset_normal3f          );
+	buffer_texcoordtexture2f  = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordtexture2f , R_BUFFERDATA_VERTEX, &bufferoffset_texcoordtexture2f );
+	buffer_texcoordlightmap2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordlightmap2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoordlightmap2f);
+	R_Mesh_VertexPointer(     3, GL_FLOAT        , sizeof(float[3])        , vertex3f          , buffer_vertex3f          , bufferoffset_vertex3f          );
+	R_Mesh_ColorPointer(      4, GL_FLOAT        , sizeof(float[4])        , color4f           , buffer_color4f           , bufferoffset_color4f           );
+	R_Mesh_TexCoordPointer(0, 2, GL_FLOAT        , sizeof(float[2])        , texcoordtexture2f , buffer_texcoordtexture2f , bufferoffset_texcoordtexture2f );
+	R_Mesh_TexCoordPointer(1, 3, GL_FLOAT        , sizeof(float[3])        , svector3f         , buffer_svector3f         , bufferoffset_svector3f         );
+	R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(float[3])        , tvector3f         , buffer_tvector3f         , bufferoffset_tvector3f         );
+	R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(float[3])        , normal3f          , buffer_normal3f          , bufferoffset_normal3f          );
+	R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(float[2])        , texcoordlightmap2f, buffer_texcoordlightmap2f, bufferoffset_texcoordlightmap2f);
+	R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(float[2])        , NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
+	R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
 }
 
 void GL_BlendEquationSubtract(qboolean negated)
diff --git a/gl_backend.h b/gl_backend.h
index 62b5bf97..2e505cd1 100644
--- a/gl_backend.h
+++ b/gl_backend.h
@@ -12,9 +12,6 @@ extern float gl_modelview16f[16];
 extern float gl_modelviewprojection16f[16];
 extern qboolean gl_modelmatrixchanged;
 
-extern cvar_t gl_vbo_dynamicvertex;
-extern cvar_t gl_vbo_dynamicindex;
-
 #define POLYGONELEMENTS_MAXPOINTS 258
 extern int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
 extern unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
diff --git a/gl_rmain.c b/gl_rmain.c
index 9799396a..ba6c4432 100644
--- a/gl_rmain.c
+++ b/gl_rmain.c
@@ -1331,12 +1331,10 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
 		if (p->loc_Texture_ReflectCube     >= 0) {p->tex_Texture_ReflectCube      = sampler;qglUniform1i(p->loc_Texture_ReflectCube     , sampler);sampler++;}
 		if (p->loc_Texture_BounceGrid      >= 0) {p->tex_Texture_BounceGrid       = sampler;qglUniform1i(p->loc_Texture_BounceGrid      , sampler);sampler++;}
 		// get the uniform block indices so we can bind them
+		p->ubiloc_Skeletal_Transform12_UniformBlock = -1;
 #ifndef USE_GLES2 /* FIXME: GLES3 only */
-		if (vid.support.arb_uniform_buffer_object)
-			p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
-		else
+		p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
 #endif
-			p->ubiloc_Skeletal_Transform12_UniformBlock = -1;
 		// clear the uniform block bindings
 		p->ubibind_Skeletal_Transform12_UniformBlock = -1;
 		// bind the uniform blocks in use
@@ -3043,10 +3041,9 @@ static void gl_main_start(void)
 		r_loadgloss = true;
 		r_loadfog = false;
 #ifdef GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
-		if (vid.support.arb_uniform_buffer_object)
-			qglGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &r_uniformbufferalignment);
+		qglGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &r_uniformbufferalignment);
 #endif
-			break;
+		break;
 	}
 
 	R_AnimCache_Free();
@@ -3071,11 +3068,8 @@ static void gl_main_start(void)
 	r_main_texturepool = R_AllocTexturePool();
 	R_BuildBlankTextures();
 	R_BuildNoTexture();
-	if (vid.support.arb_texture_cube_map)
-	{
-		R_BuildWhiteCube();
-		R_BuildNormalizationCube();
-	}
+	R_BuildWhiteCube();
+	R_BuildNormalizationCube();
 	r_texture_fogattenuation = NULL;
 	r_texture_fogheighttexture = NULL;
 	r_texture_gammaramps = NULL;
@@ -5124,9 +5118,6 @@ static void R_Bloom_StartFrame(void)
 		r_fb.usedepthtextures = r_usedepthtextures.integer != 0;
 		if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
 		if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F;
-		// for simplicity, bloom requires FBO render to texture, which basically all video drivers support now
-		if (!vid.support.ext_framebuffer_object)
-			return;
 		break;
 	case RENDERPATH_GLES2:
 		r_fb.usedepthtextures = false;
@@ -5577,7 +5568,7 @@ void R_UpdateVariables(void)
 	switch(vid.renderpath)
 	{
 	case RENDERPATH_GL20:
-		r_gpuskeletal = vid.support.arb_uniform_buffer_object && r_glsl_skeletal.integer && !r_showsurfaces.integer; // FIXME add r_showsurfaces support to GLSL skeletal!
+		r_gpuskeletal = r_glsl_skeletal.integer && !r_showsurfaces.integer;
 	case RENDERPATH_GLES2:
 		if(!vid_gammatables_trivial)
 		{
@@ -7470,7 +7461,6 @@ static void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, in
 }
 
 static const int quadedges[6][2] = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
-extern cvar_t gl_vbo;
 void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const msurface_t **texturesurfacelist)
 {
 	int deformindex;
@@ -7827,13 +7817,10 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
 					rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
 			}
 			// upload buffer data for the copytriangles batch
-			if (((r_batch_dynamicbuffer.integer || gl_vbo_dynamicindex.integer) && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
-			{
-				if (rsurface.batchelement3s)
-					rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
-				else if (rsurface.batchelement3i)
-					rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
-			}
+			if (rsurface.batchelement3s)
+				rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
+			else if (rsurface.batchelement3i)
+				rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
 		}
 		else
 		{
@@ -8560,31 +8547,28 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
 	}
 
 	// upload buffer data for the dynamic batch
-	if (((r_batch_dynamicbuffer.integer || gl_vbo_dynamicvertex.integer || gl_vbo_dynamicindex.integer) && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
-	{
-		if (rsurface.batchvertex3f)
-			rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset);
-		if (rsurface.batchsvector3f)
-			rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset);
-		if (rsurface.batchtvector3f)
-			rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
-		if (rsurface.batchnormal3f)
-			rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
-		if (rsurface.batchlightmapcolor4f)
-			rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
-		if (rsurface.batchtexcoordtexture2f)
-			rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
-		if (rsurface.batchtexcoordlightmap2f)
-			rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
-		if (rsurface.batchskeletalindex4ub)
-			rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);
-		if (rsurface.batchskeletalweight4ub)
-			rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset);
-		if (rsurface.batchelement3s)
-			rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
-		else if (rsurface.batchelement3i)
-			rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
-	}
+	if (rsurface.batchvertex3f)
+		rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset);
+	if (rsurface.batchsvector3f)
+		rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset);
+	if (rsurface.batchtvector3f)
+		rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
+	if (rsurface.batchnormal3f)
+		rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
+	if (rsurface.batchlightmapcolor4f)
+		rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
+	if (rsurface.batchtexcoordtexture2f)
+		rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
+	if (rsurface.batchtexcoordlightmap2f)
+		rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
+	if (rsurface.batchskeletalindex4ub)
+		rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);
+	if (rsurface.batchskeletalweight4ub)
+		rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset);
+	if (rsurface.batchelement3s)
+		rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
+	else if (rsurface.batchelement3i)
+		rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
 }
 
 void RSurf_DrawBatch(void)
diff --git a/gl_textures.c b/gl_textures.c
index 9c1f5f17..80fd30ae 100644
--- a/gl_textures.c
+++ b/gl_textures.c
@@ -205,7 +205,6 @@ typedef struct gltexture_s
 	// palette if the texture is TEXTYPE_PALETTE
 	const unsigned int *palette;
 	// actual stored texture size after gl_picmip and gl_max_size are applied
-	// (power of 2 if vid.support.arb_texture_non_power_of_two is not supported)
 	int tilewidth, tileheight, tiledepth;
 	// 1 or 6 depending on texturetype
 	int sides;
@@ -517,21 +516,9 @@ static void GL_Texture_CalcImageSize(int texturetype, int flags, int miplevel, i
 		break;
 	}
 
-	if (vid.support.arb_texture_non_power_of_two)
-	{
-		width2 = min(inwidth >> picmip, maxsize);
-		height2 = min(inheight >> picmip, maxsize);
-		depth2 = min(indepth >> picmip, maxsize);
-	}
-	else
-	{
-		for (width2 = 1;width2 < inwidth;width2 <<= 1);
-		for (width2 >>= picmip;width2 > maxsize;width2 >>= 1);
-		for (height2 = 1;height2 < inheight;height2 <<= 1);
-		for (height2 >>= picmip;height2 > maxsize;height2 >>= 1);
-		for (depth2 = 1;depth2 < indepth;depth2 <<= 1);
-		for (depth2 >>= picmip;depth2 > maxsize;depth2 >>= 1);
-	}
+	width2 = min(inwidth >> picmip, maxsize);
+	height2 = min(inheight >> picmip, maxsize);
+	depth2 = min(indepth >> picmip, maxsize);
 
 	miplevels = 1;
 	if (flags & TEXF_MIPMAP)
@@ -1212,17 +1199,6 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
 		}
 	}
 
-	if (texturetype == GLTEXTURETYPE_CUBEMAP && !vid.support.arb_texture_cube_map)
-	{
-		Con_Printf ("R_LoadTexture: cubemap texture not supported by driver\n");
-		return NULL;
-	}
-	if (texturetype == GLTEXTURETYPE_3D && !vid.support.ext_texture_3d)
-	{
-		Con_Printf ("R_LoadTexture: 3d texture not supported by driver\n");
-		return NULL;
-	}
-
 	texinfo = R_GetTexTypeInfo(textype, flags);
 	size = width * height * depth * sides * texinfo->inputbytesperpixel;
 	if (size < 1)
@@ -1598,7 +1574,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 	unsigned char *dds;
 	fs_offset_t ddsfilesize;
 	unsigned int ddssize;
-	qboolean force_swdecode, npothack;
+	qboolean force_swdecode;
 #ifdef __ANDROID__
 	// ELUAN: FIXME: separate this code
 	char vabuf[1024];
@@ -1919,17 +1895,9 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 	}
 
 	force_swdecode = false;
-	npothack = 
-		(!vid.support.arb_texture_non_power_of_two &&
-			(
-				(dds_width & (dds_width - 1))
-				||
-				(dds_height & (dds_height - 1))
-			)
-		);
 	if(bytesperblock)
 	{
-		if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && !npothack)
+		if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc)
 		{
 			if(r_texture_dds_swdecode.integer > 1)
 				force_swdecode = true;
@@ -2207,12 +2175,6 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 	glt->tiledepth = 1;
 	glt->miplevels = dds_miplevels;
 
-	if(npothack)
-	{
-		for (glt->tilewidth = 1;glt->tilewidth < mipwidth;glt->tilewidth <<= 1);
-		for (glt->tileheight = 1;glt->tileheight < mipheight;glt->tileheight <<= 1);
-	}
-
 	// texture uploading can take a while, so make sure we're sending keepalives
 	CL_KeepaliveMessage(false);
 
@@ -2241,19 +2203,6 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 		mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
 		if (mippixels + mipsize > mippixels_start + mipsize_total)
 			break;
-		if(npothack)
-		{
-			upload_mipwidth = (glt->tilewidth >> mip);
-			upload_mipheight = (glt->tileheight >> mip);
-			if(upload_mipwidth != mipwidth || upload_mipheight != mipheight)
-			// I _think_ they always mismatch, but I was too lazy
-			// to properly check, and this test here is really
-			// harmless
-			{
-				upload_mippixels = (unsigned char *) Mem_Alloc(tempmempool, 4 * upload_mipwidth * upload_mipheight);
-				Image_Resample32(mippixels, mipwidth, mipheight, 1, upload_mippixels, upload_mipwidth, upload_mipheight, 1, r_lerpimages.integer);
-			}
-		}
 		switch(vid.renderpath)
 		{
 		case RENDERPATH_GL20:
diff --git a/glquake.h b/glquake.h
index 646c3d36..c3cd3d5a 100644
--- a/glquake.h
+++ b/glquake.h
@@ -491,14 +491,14 @@ extern void (GLAPIENTRY *qglBlendEquationEXT)(GLenum); // also supplied by GL_bl
 #define GL_BUFFER_MAPPED              0x88BC
 #define GL_BUFFER_MAP_POINTER         0x88BD
 #endif
-extern void (GLAPIENTRY *qglBindBufferARB) (GLenum target, GLuint buffer);
-extern void (GLAPIENTRY *qglDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
-extern void (GLAPIENTRY *qglGenBuffersARB) (GLsizei n, GLuint *buffers);
-extern GLboolean (GLAPIENTRY *qglIsBufferARB) (GLuint buffer);
-extern GLvoid* (GLAPIENTRY *qglMapBufferARB) (GLenum target, GLenum access);
-extern GLboolean (GLAPIENTRY *qglUnmapBufferARB) (GLenum target);
-extern void (GLAPIENTRY *qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
-extern void (GLAPIENTRY *qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+extern void (GLAPIENTRY *qglBindBuffer) (GLenum target, GLuint buffer);
+extern void (GLAPIENTRY *qglDeleteBuffers) (GLsizei n, const GLuint *buffers);
+extern void (GLAPIENTRY *qglGenBuffers) (GLsizei n, GLuint *buffers);
+extern GLboolean (GLAPIENTRY *qglIsBuffer) (GLuint buffer);
+extern GLvoid* (GLAPIENTRY *qglMapBuffer) (GLenum target, GLenum access);
+extern GLboolean (GLAPIENTRY *qglUnmapBuffer) (GLenum target);
+extern void (GLAPIENTRY *qglBufferData) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+extern void (GLAPIENTRY *qglBufferSubData) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
 
 //GL_ARB_framebuffer_object
 // (slight differences from GL_EXT_framebuffer_object as this integrates GL_EXT_packed_depth_stencil)
@@ -742,7 +742,6 @@ extern void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
 extern void (GLAPIENTRY *qglDepthRangef)(GLclampf near_val, GLclampf far_val);
 extern void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
 
-extern void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
 extern void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
 extern void (GLAPIENTRY *qglDrawArrays)(GLenum mode, GLint first, GLsizei count);
 
@@ -1099,7 +1098,7 @@ void GL_PrintError(int errornumber, const char *filename, int linenumber);
 //#define qglBeginQueryARB glBeginQuery
 #define qglBindAttribLocation glBindAttribLocation
 //#define qglBindFragDataLocation glBindFragDataLocation
-#define qglBindBufferARB glBindBuffer
+#define qglBindBuffer glBindBuffer
 #define qglBindFramebuffer glBindFramebuffer
 #define qglBindRenderbuffer glBindRenderbuffer
 #define qglBindTexture glBindTexture
@@ -1122,7 +1121,7 @@ void GL_PrintError(int errornumber, const char *filename, int linenumber);
 #define qglCopyTexSubImage2D glCopyTexSubImage2D
 #define qglCopyTexSubImage3D glCopyTexSubImage3D
 #define qglCullFace glCullFace
-#define qglDeleteBuffersARB glDeleteBuffers
+#define qglDeleteBuffers glDeleteBuffers
 #define qglDeleteFramebuffers glDeleteFramebuffers
 #define qglDeleteProgram glDeleteProgram
 #define qglDeleteShader glDeleteShader
@@ -1139,7 +1138,6 @@ void GL_PrintError(int errornumber, const char *filename, int linenumber);
 //#define qglDrawBuffer glDrawBuffer
 //#define qglDrawBuffersARB glDrawBuffers
 #define qglDrawElements glDrawElements
-//#define qglDrawRangeElements glDrawRangeElements
 #define qglEnable glEnable
 #define qglEnableVertexAttribArray glEnableVertexAttribArray
 //#define qglEndQueryARB glEndQuery
@@ -1148,7 +1146,7 @@ void GL_PrintError(int errornumber, const char *filename, int linenumber);
 #define qglFramebufferRenderbuffer glFramebufferRenderbuffer
 #define qglFramebufferTexture2D glFramebufferTexture2D
 #define qglFramebufferTexture3DEXT glFramebufferTexture3D
-#define qglGenBuffersARB glGenBuffers
+#define qglGenBuffers glGenBuffers
 #define qglGenFramebuffers glGenFramebuffers
 //#define qglGenQueriesARB glGenQueries
 #define qglGenRenderbuffers glGenRenderbuffers
diff --git a/r_shadow.c b/r_shadow.c
index 87f3a48e..71bb892b 100644
--- a/r_shadow.c
+++ b/r_shadow.c
@@ -24,7 +24,6 @@ r_shadow_rendermode_t;
 
 typedef enum r_shadow_shadowmode_e
 {
-	R_SHADOW_SHADOWMODE_STENCIL,
 	R_SHADOW_SHADOWMODE_SHADOWMAP2D
 }
 r_shadow_shadowmode_t;
@@ -311,7 +310,7 @@ static void R_Shadow_SetShadowMode(void)
 	r_shadow_shadowmapdepthtexture = r_fb.usedepthtextures;
 	r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
 	Mod_AllocLightmap_Init(&r_shadow_shadowmapatlas_state, r_main_mempool, r_shadow_shadowmaptexturesize, r_shadow_shadowmaptexturesize);
-	if ((r_shadow_shadowmapping.integer || r_shadow_deferred.integer) && vid.support.ext_framebuffer_object)
+	if (r_shadow_shadowmapping.integer || r_shadow_deferred.integer)
 	{
 		switch(vid.renderpath)
 		{
@@ -320,7 +319,7 @@ static void R_Shadow_SetShadowMode(void)
 			{
 				if (!r_fb.usedepthtextures)
 					r_shadow_shadowmappcf = 1;
-				else if((strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) && vid.support.arb_shadow && r_shadow_shadowmapshadowsampler)
+				else if((strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) && r_shadow_shadowmapshadowsampler)
 				{
 					r_shadow_shadowmapsampler = true;
 					r_shadow_shadowmappcf = 1;
@@ -330,11 +329,11 @@ static void R_Shadow_SetShadowMode(void)
 				else if((strstr(gl_vendor, "ATI") || strstr(gl_vendor, "Advanced Micro Devices")) && !strstr(gl_renderer, "Mesa") && !strstr(gl_version, "Mesa"))
 					r_shadow_shadowmappcf = 1;
 				else
-					r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
+					r_shadow_shadowmapsampler = r_shadow_shadowmapshadowsampler;
 			}
 			else
 			{
-                r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
+                r_shadow_shadowmapsampler = r_shadow_shadowmapshadowsampler;
 				switch (r_shadow_shadowmapfilterquality)
 				{
 				case 1:
@@ -462,11 +461,11 @@ static void r_shadow_start(void)
 	{
 	case RENDERPATH_GL20:
 		r_shadow_bouncegrid_state.allowdirectionalshading = true;
-		r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
+		r_shadow_bouncegrid_state.capable = true;
 		break;
 	case RENDERPATH_GLES2:
 		// for performance reasons, do not use directional shading on GLES devices
-		r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
+		r_shadow_bouncegrid_state.capable = true;
 		break;
 	}
 }
@@ -1926,21 +1925,9 @@ static void R_Shadow_BounceGrid_UpdateSpacing(void)
 	c[1] = (int)floor(size[1] / spacing[1] + 0.5f);
 	c[2] = (int)floor(size[2] / spacing[2] + 0.5f);
 	// figure out the exact texture size (honoring power of 2 if required)
-	c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
-	c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
-	c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
-	if (vid.support.arb_texture_non_power_of_two)
-	{
-		resolution[0] = c[0];
-		resolution[1] = c[1];
-		resolution[2] = c[2];
-	}
-	else
-	{
-		for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
-		for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
-		for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
-	}
+	resolution[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
+	resolution[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
+	resolution[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
 	size[0] = spacing[0] * resolution[0];
 	size[1] = spacing[1] * resolution[1];
 	size[2] = spacing[2] * resolution[2];
@@ -1953,22 +1940,10 @@ static void R_Shadow_BounceGrid_UpdateSpacing(void)
 		c[0] = r_shadow_bouncegrid_dynamic_x.integer;
 		c[1] = r_shadow_bouncegrid_dynamic_y.integer;
 		c[2] = r_shadow_bouncegrid_dynamic_z.integer;
-		// now we can calculate the texture size (power of 2 if required)
-		c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
-		c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
-		c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
-		if (vid.support.arb_texture_non_power_of_two)
-		{
-			resolution[0] = c[0];
-			resolution[1] = c[1];
-			resolution[2] = c[2];
-		}
-		else
-		{
-			for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
-			for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
-			for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
-		}
+		// now we can calculate the texture size
+		resolution[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
+		resolution[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
+		resolution[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
 		size[0] = spacing[0] * resolution[0];
 		size[1] = spacing[1] * resolution[1];
 		size[2] = spacing[2] * resolution[2];
@@ -4071,10 +4046,10 @@ void R_Shadow_PrepareLights(void)
 	int shadowmapmaxsize = bound(shadowmapborder+2, r_shadow_shadowmapping_maxsize.integer, shadowmaptexturesize / 8);
 
 	if (r_shadow_shadowmaptexturesize != shadowmaptexturesize ||
-		(r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL) != (r_shadow_shadowmapping.integer || r_shadow_deferred.integer) ||
+		!(r_shadow_shadowmapping.integer || r_shadow_deferred.integer) ||
 		r_shadow_shadowmapvsdct != (r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20) ||
 		r_shadow_shadowmapfilterquality != r_shadow_shadowmapping_filterquality.integer ||
-		r_shadow_shadowmapshadowsampler != (vid.support.arb_shadow && r_shadow_shadowmapping_useshadowsampler.integer) ||
+		r_shadow_shadowmapshadowsampler != r_shadow_shadowmapping_useshadowsampler.integer ||
 		r_shadow_shadowmapdepthbits != r_shadow_shadowmapping_depthbits.integer ||
 		r_shadow_shadowmapborder != shadowmapborder ||
 		r_shadow_shadowmapmaxsize != shadowmapmaxsize ||
@@ -4087,7 +4062,7 @@ void R_Shadow_PrepareLights(void)
 	{
 	case RENDERPATH_GL20:
 #ifndef USE_GLES2
-		if (!r_shadow_deferred.integer || r_shadow_shadowmode == R_SHADOW_SHADOWMODE_STENCIL || !vid.support.ext_framebuffer_object || vid.maxdrawbuffers < 2)
+		if (!r_shadow_deferred.integer || vid.maxdrawbuffers < 2)
 		{
 			r_shadow_usingdeferredprepass = false;
 			if (r_shadow_prepass_width)
@@ -4517,11 +4492,11 @@ static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
 			if (vid.support.arb_query_buffer_object) {
 #define BUFFER_OFFSET(i)    ((GLint *)((unsigned char*)NULL + (i)))
 				if (!r_shadow_occlusion_buf) {
-					qglGenBuffersARB(1, &r_shadow_occlusion_buf);
-					qglBindBufferARB(GL_QUERY_BUFFER_ARB, r_shadow_occlusion_buf);
-					qglBufferDataARB(GL_QUERY_BUFFER_ARB, 8, NULL, GL_DYNAMIC_COPY);
+					qglGenBuffers(1, &r_shadow_occlusion_buf);
+					qglBindBuffer(GL_QUERY_BUFFER_ARB, r_shadow_occlusion_buf);
+					qglBufferData(GL_QUERY_BUFFER_ARB, 8, NULL, GL_DYNAMIC_COPY);
 				} else {
-					qglBindBufferARB(GL_QUERY_BUFFER_ARB, r_shadow_occlusion_buf);
+					qglBindBuffer(GL_QUERY_BUFFER_ARB, r_shadow_occlusion_buf);
 				}
 				qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, BUFFER_OFFSET(0));
 				qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, BUFFER_OFFSET(4));
diff --git a/vid.h b/vid.h
index 5e4ac2f7..fa036e6e 100644
--- a/vid.h
+++ b/vid.h
@@ -37,33 +37,19 @@ renderpath_t;
 
 typedef struct viddef_support_s
 {
-	qboolean gl20shaders;
 	qboolean gl20shaders130; // indicates glBindFragDataLocation is available
 	int glshaderversion; // typical values: 100 110 120 130 140 ...
 	qboolean amd_texture_texture4;
-	qboolean arb_depth_texture;
 	qboolean arb_draw_buffers;
-	qboolean arb_framebuffer_object;
-	qboolean arb_multitexture;
 	qboolean arb_occlusion_query;
 	qboolean arb_query_buffer_object;
-	qboolean arb_shadow;
 	qboolean arb_texture_compression;
-	qboolean arb_texture_cube_map;
-	qboolean arb_texture_env_combine;
 	qboolean arb_texture_gather;
-	qboolean arb_texture_non_power_of_two;
-	qboolean arb_vertex_buffer_object;
-	qboolean arb_uniform_buffer_object;
 	qboolean ext_blend_minmax;
 	qboolean ext_blend_subtract;
 	qboolean ext_blend_func_separate;
-	qboolean ext_draw_range_elements;
-	qboolean ext_framebuffer_object;
 	qboolean ext_packed_depth_stencil;
-	qboolean ext_texture_3d;
 	qboolean ext_texture_compression_s3tc;
-	qboolean ext_texture_edge_clamp;
 	qboolean ext_texture_filter_anisotropic;
 	qboolean ext_texture_srgb;
 	qboolean arb_texture_float;
@@ -106,7 +92,6 @@ typedef struct viddef_s
 	qboolean sRGBcapable3D; // whether 3D rendering can be sRGB corrected (renderpath)
 
 	renderpath_t renderpath;
-	qboolean forcevbo; // some renderpaths can not operate without it
 	qboolean allowalphatocoverage; // indicates the GL_AlphaToCoverage function works on this renderpath and framebuffer
 
 	unsigned int texunits;
diff --git a/vid_sdl.c b/vid_sdl.c
index 6fe76123..0e4e7b86 100644
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -1358,8 +1358,6 @@ void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {PRECALL;glDrawAr
 void wrapglDrawBuffer(GLenum mode) {PRECALL;Con_Printf("glDrawBuffer(mode)\n");POSTCALL;}
 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {PRECALL;Con_Printf("glDrawBuffers(n, bufs)\n");POSTCALL;}
 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawElements(mode, count, type, indices);POSTCALL;}
-//void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
-//void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
 void wrapglEnable(GLenum cap) {PRECALL;glEnable(cap);POSTCALL;}
 void wrapglEnableVertexAttribArray(GLuint index) {PRECALL;glEnableVertexAttribArray(index);POSTCALL;}
 //void wrapglEndQuery(GLenum target) {PRECALL;glEndQuery(target);POSTCALL;}
@@ -1508,7 +1506,7 @@ void GLES_Init(void)
 //	qglGetHandleARB = wrapglGetHandle;
 	qglGetAttribLocation = wrapglGetAttribLocation;
 	qglGetUniformLocation = wrapglGetUniformLocation;
-//	qglMapBufferARB = wrapglMapBuffer;
+//	qglMapBuffer = wrapglMapBuffer;
 	qglGetString = wrapglGetString;
 //	qglActiveStencilFaceEXT = wrapglActiveStencilFace;
 	qglActiveTexture = wrapglActiveTexture;
@@ -1517,7 +1515,7 @@ void GLES_Init(void)
 //	qglBeginQueryARB = wrapglBeginQuery;
 	qglBindAttribLocation = wrapglBindAttribLocation;
 //	qglBindFragDataLocation = wrapglBindFragDataLocation;
-	qglBindBufferARB = wrapglBindBuffer;
+	qglBindBuffer = wrapglBindBuffer;
 	qglBindFramebuffer = wrapglBindFramebuffer;
 	qglBindRenderbuffer = wrapglBindRenderbuffer;
 	qglBindTexture = wrapglBindTexture;
@@ -1539,7 +1537,7 @@ void GLES_Init(void)
 	qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
 	qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
 	qglCullFace = wrapglCullFace;
-	qglDeleteBuffersARB = wrapglDeleteBuffers;
+	qglDeleteBuffers = wrapglDeleteBuffers;
 	qglDeleteFramebuffers = wrapglDeleteFramebuffers;
 	qglDeleteProgram = wrapglDeleteProgram;
 	qglDeleteShader = wrapglDeleteShader;
@@ -1556,7 +1554,6 @@ void GLES_Init(void)
 //	qglDrawBuffer = wrapglDrawBuffer;
 //	qglDrawBuffersARB = wrapglDrawBuffers;
 	qglDrawElements = wrapglDrawElements;
-//	qglDrawRangeElements = wrapglDrawRangeElements;
 	qglEnable = wrapglEnable;
 	qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
 //	qglEndQueryARB = wrapglEndQuery;
@@ -1565,7 +1562,7 @@ void GLES_Init(void)
 	qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
 	qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
 	qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
-	qglGenBuffersARB = wrapglGenBuffers;
+	qglGenBuffers = wrapglGenBuffers;
 	qglGenFramebuffers = wrapglGenFramebuffers;
 //	qglGenQueriesARB = wrapglGenQueries;
 	qglGenRenderbuffers = wrapglGenRenderbuffers;
@@ -1711,37 +1708,18 @@ void GLES_Init(void)
 	// GLES devices in general do not like GL_BGRA, so use GL_RGBA
 	vid.forcetextype = TEXTYPE_RGBA;
 	
-	vid.support.gl20shaders = true;
 	vid.support.amd_texture_texture4 = false;
-	vid.support.arb_depth_texture = SDL_GL_ExtensionSupported("GL_OES_depth_texture") != 0; // renderbuffer used anyway on gles2?
 	vid.support.arb_draw_buffers = false;
-	vid.support.arb_multitexture = false;
 	vid.support.arb_occlusion_query = false;
 	vid.support.arb_query_buffer_object = false;
-	vid.support.arb_shadow = false;
 	vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
-	vid.support.arb_texture_cube_map = SDL_GL_ExtensionSupported("GL_OES_texture_cube_map") != 0;
-	vid.support.arb_texture_env_combine = false;
 	vid.support.arb_texture_gather = false;
-	vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
-	vid.support.arb_vertex_buffer_object = true; // GLES2 core
 	vid.support.ext_blend_minmax = false;
 	vid.support.ext_blend_subtract = true; // GLES2 core
 	vid.support.ext_blend_func_separate = true; // GLES2 core
-	vid.support.ext_draw_range_elements = false;
-
-	/*	ELUAN:
-		Note: "In OS 2.1, the functions in GL_OES_framebuffer_object were not usable from the Java API.
-		Calling them just threw an exception. Android developer relations confirmed that they forgot to implement these. (yeah...)
-		It's apparently been fixed in 2.2, though I haven't tested."
-	*/
-	// LadyHavoc: Android 2.1 is way old now, enabling this again, it's going to be required soon.
-	vid.support.ext_framebuffer_object = true;
 
 	vid.support.ext_packed_depth_stencil = false;
-	vid.support.ext_texture_3d = SDL_GL_ExtensionSupported("GL_OES_texture_3D") != 0;
 	vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0;
-	vid.support.ext_texture_edge_clamp = true; // GLES2 core
 	vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
 	vid.support.ext_texture_srgb = false;
 	vid.support.arb_texture_float = SDL_GL_ExtensionSupported("GL_OES_texture_float") != 0;
@@ -1794,13 +1772,11 @@ void GLES_Init(void)
 	vid.texunits = 4;
 	vid.teximageunits = 8;
 	vid.texarrayunits = 5;
-	//qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
 	qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&vid.teximageunits);CHECKGLERROR
-	//qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (GLint*)&vid.texarrayunits);CHECKGLERROR
 	vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
 	vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
 	vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
-	Con_DPrintf("Using GLES2.0 rendering path - %i texture matrix, %i texture images, %i texcoords%s\n", vid.texunits, vid.teximageunits, vid.texarrayunits, vid.support.ext_framebuffer_object ? ", shadowmapping supported" : "");
+	Con_DPrint("Using GLES2 rendering path\n");
 	vid.renderpath = RENDERPATH_GLES2;
 	vid.sRGBcapable2D = false;
 	vid.sRGBcapable3D = false;
diff --git a/vid_shared.c b/vid_shared.c
index 4d177b07..6041fec2 100644
--- a/vid_shared.c
+++ b/vid_shared.c
@@ -234,7 +234,6 @@ void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
 void (GLAPIENTRY *qglDepthRangef)(GLclampf near_val, GLclampf far_val);
 void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
 
-void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
 void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
 void (GLAPIENTRY *qglDrawArrays)(GLenum mode, GLint first, GLsizei count);
 
@@ -260,26 +259,14 @@ void (GLAPIENTRY *qglHint)(GLenum target, GLenum mode);
 void (GLAPIENTRY *qglGenTextures)(GLsizei n, GLuint *textures);
 void (GLAPIENTRY *qglDeleteTextures)(GLsizei n, const GLuint *textures);
 void (GLAPIENTRY *qglBindTexture)(GLenum target, GLuint texture);
-//void (GLAPIENTRY *qglPrioritizeTextures)(GLsizei n, const GLuint *textures, const GLclampf *priorities);
-//GLboolean (GLAPIENTRY *qglAreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences);
-//GLboolean (GLAPIENTRY *qglIsTexture)(GLuint texture);
-//void (GLAPIENTRY *qglPixelStoref)(GLenum pname, GLfloat param);
+
 void (GLAPIENTRY *qglPixelStorei)(GLenum pname, GLint param);
 
-//void (GLAPIENTRY *qglTexImage1D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
 void (GLAPIENTRY *qglTexImage2D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-//void (GLAPIENTRY *qglTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
 void (GLAPIENTRY *qglTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
-//void (GLAPIENTRY *qglCopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
 void (GLAPIENTRY *qglCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-//void (GLAPIENTRY *qglCopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
 void (GLAPIENTRY *qglCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
 
-
-void (GLAPIENTRY *qglDrawRangeElementsEXT)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
-
-//void (GLAPIENTRY *qglColorTableEXT)(int, int, int, int, int, const void *);
-
 void (GLAPIENTRY *qglTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
 void (GLAPIENTRY *qglTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
 void (GLAPIENTRY *qglCopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
@@ -290,10 +277,6 @@ void (GLAPIENTRY *qglPolygonOffset)(GLfloat factor, GLfloat units);
 void (GLAPIENTRY *qglPolygonMode)(GLenum face, GLenum mode);
 void (GLAPIENTRY *qglPolygonStipple)(const GLubyte *mask);
 
-//void (GLAPIENTRY *qglClipPlane)(GLenum plane, const GLdouble *equation);
-//void (GLAPIENTRY *qglGetClipPlane)(GLenum plane, GLdouble *equation);
-
-//[515]: added on 29.07.2005
 void (GLAPIENTRY *qglPointSize)(GLfloat size);
 
 void (GLAPIENTRY *qglBlendEquationEXT)(GLenum);
@@ -304,7 +287,6 @@ void (GLAPIENTRY *qglActiveStencilFaceEXT)(GLenum);
 
 void (GLAPIENTRY *qglDeleteShader)(GLuint obj);
 void (GLAPIENTRY *qglDeleteProgram)(GLuint obj);
-//GLuint (GLAPIENTRY *qglGetHandle)(GLenum pname);
 void (GLAPIENTRY *qglDetachShader)(GLuint containerObj, GLuint attachedObj);
 GLuint (GLAPIENTRY *qglCreateShader)(GLenum shaderType);
 void (GLAPIENTRY *qglShaderSource)(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length);
@@ -393,14 +375,14 @@ void (GLAPIENTRY *qglGetVertexAttribiv)(GLuint index, GLenum pname, GLint *param
 void (GLAPIENTRY *qglGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid **pointer);
 
 //GL_ARB_vertex_buffer_object
-void (GLAPIENTRY *qglBindBufferARB) (GLenum target, GLuint buffer);
-void (GLAPIENTRY *qglDeleteBuffersARB) (GLsizei n, const GLuint *buffers);
-void (GLAPIENTRY *qglGenBuffersARB) (GLsizei n, GLuint *buffers);
-GLboolean (GLAPIENTRY *qglIsBufferARB) (GLuint buffer);
-GLvoid* (GLAPIENTRY *qglMapBufferARB) (GLenum target, GLenum access);
-GLboolean (GLAPIENTRY *qglUnmapBufferARB) (GLenum target);
-void (GLAPIENTRY *qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
-void (GLAPIENTRY *qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+void (GLAPIENTRY *qglBindBuffer) (GLenum target, GLuint buffer);
+void (GLAPIENTRY *qglDeleteBuffers) (GLsizei n, const GLuint *buffers);
+void (GLAPIENTRY *qglGenBuffers) (GLsizei n, GLuint *buffers);
+GLboolean (GLAPIENTRY *qglIsBuffer) (GLuint buffer);
+GLvoid* (GLAPIENTRY *qglMapBuffer) (GLenum target, GLenum access);
+GLboolean (GLAPIENTRY *qglUnmapBuffer) (GLenum target);
+void (GLAPIENTRY *qglBufferData) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+void (GLAPIENTRY *qglBufferSubData) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
 
 //GL_ARB_framebuffer_object
 GLboolean (GLAPIENTRY *qglIsRenderbuffer)(GLuint renderbuffer);
@@ -539,7 +521,8 @@ qboolean GL_CheckExtension(const char *minglver_or_ext, const dllfunction_t *fun
 }
 
 #ifndef USE_GLES2
-static dllfunction_t opengl110funcs[] =
+// functions we require from the driver - some of these are OpenGL 2.0, some are a bit newer
+static dllfunction_t openglfuncs[] =
 {
 	{"glClearColor", (void **) &qglClearColor},
 	{"glClear", (void **) &qglClear},
@@ -565,7 +548,6 @@ static dllfunction_t opengl110funcs[] =
 	{"glDrawElements", (void **) &qglDrawElements},
 	{"glDrawArrays", (void **) &qglDrawArrays},
 	{"glColorMask", (void **) &qglColorMask},
-//[515]: added on 29.07.2005
 	{"glPointSize", (void**) &qglPointSize},
 	{"glViewport", (void **) &qglViewport},
 	{"glReadPixels", (void **) &qglReadPixels},
@@ -582,68 +564,24 @@ static dllfunction_t opengl110funcs[] =
 	{"glGetTexLevelParameterfv", (void **) &qglGetTexLevelParameterfv},
 	{"glGetTexLevelParameteriv", (void **) &qglGetTexLevelParameteriv},
 	{"glHint", (void **) &qglHint},
-//	{"glPixelStoref", (void **) &qglPixelStoref},
 	{"glPixelStorei", (void **) &qglPixelStorei},
 	{"glGenTextures", (void **) &qglGenTextures},
 	{"glDeleteTextures", (void **) &qglDeleteTextures},
 	{"glBindTexture", (void **) &qglBindTexture},
-//	{"glPrioritizeTextures", (void **) &qglPrioritizeTextures},
-//	{"glAreTexturesResident", (void **) &qglAreTexturesResident},
-//	{"glIsTexture", (void **) &qglIsTexture},
-//	{"glTexImage1D", (void **) &qglTexImage1D},
 	{"glTexImage2D", (void **) &qglTexImage2D},
-//	{"glTexSubImage1D", (void **) &qglTexSubImage1D},
 	{"glTexSubImage2D", (void **) &qglTexSubImage2D},
-//	{"glCopyTexImage1D", (void **) &qglCopyTexImage1D},
 	{"glCopyTexImage2D", (void **) &qglCopyTexImage2D},
-//	{"glCopyTexSubImage1D", (void **) &qglCopyTexSubImage1D},
 	{"glCopyTexSubImage2D", (void **) &qglCopyTexSubImage2D},
 	{"glScissor", (void **) &qglScissor},
 	{"glPolygonOffset", (void **) &qglPolygonOffset},
 	{"glPolygonMode", (void **) &qglPolygonMode},
 	{"glPolygonStipple", (void **) &qglPolygonStipple},
-//	{"glClipPlane", (void **) &qglClipPlane},
-//	{"glGetClipPlane", (void **) &qglGetClipPlane},
-	{NULL, NULL}
-};
-
-static dllfunction_t drawrangeelementsfuncs[] =
-{
-	{"glDrawRangeElements", (void **) &qglDrawRangeElements},
-	{NULL, NULL}
-};
-
-static dllfunction_t drawrangeelementsextfuncs[] =
-{
-	{"glDrawRangeElementsEXT", (void **) &qglDrawRangeElementsEXT},
-	{NULL, NULL}
-};
-
-static dllfunction_t multitexturefuncs[] =
-{
-	{"glActiveTextureARB", (void **) &qglActiveTexture},
-	{NULL, NULL}
-};
-
-static dllfunction_t texture3dextfuncs[] =
-{
-	{"glTexImage3DEXT", (void **) &qglTexImage3D},
-	{"glTexSubImage3DEXT", (void **) &qglTexSubImage3D},
-	{"glCopyTexSubImage3DEXT", (void **) &qglCopyTexSubImage3D},
-	{NULL, NULL}
-};
-
-static dllfunction_t blendequationfuncs[] =
-{
-	{"glBlendEquationEXT", (void **) &qglBlendEquationEXT},
-	{NULL, NULL}
-};
-
-static dllfunction_t gl20shaderfuncs[] =
-{
+	{"glActiveTexture", (void **) &qglActiveTexture},
+	{"glTexImage3D", (void **) &qglTexImage3D},
+	{"glTexSubImage3D", (void **) &qglTexSubImage3D},
+	{"glCopyTexSubImage3D", (void **) &qglCopyTexSubImage3D},
 	{"glDeleteShader", (void **) &qglDeleteShader},
 	{"glDeleteProgram", (void **) &qglDeleteProgram},
-//	{"glGetHandle", (void **) &qglGetHandle},
 	{"glDetachShader", (void **) &qglDetachShader},
 	{"glCreateShader", (void **) &qglCreateShader},
 	{"glShaderSource", (void **) &qglShaderSource},
@@ -728,51 +666,20 @@ static dllfunction_t gl20shaderfuncs[] =
 	{"glGetVertexAttribfv", (void **) &qglGetVertexAttribfv},
 	{"glGetVertexAttribiv", (void **) &qglGetVertexAttribiv},
 	{"glGetVertexAttribPointerv", (void **) &qglGetVertexAttribPointerv},
-	{NULL, NULL}
-};
-
-static dllfunction_t glsl130funcs[] =
-{
-	{"glBindFragDataLocation", (void **) &qglBindFragDataLocation},
-	{NULL, NULL}
-};
-
-static dllfunction_t vbofuncs[] =
-{
-	{"glBindBufferARB"    , (void **) &qglBindBufferARB},
-	{"glDeleteBuffersARB" , (void **) &qglDeleteBuffersARB},
-	{"glGenBuffersARB"    , (void **) &qglGenBuffersARB},
-	{"glIsBufferARB"      , (void **) &qglIsBufferARB},
-	{"glMapBufferARB"     , (void **) &qglMapBufferARB},
-	{"glUnmapBufferARB"   , (void **) &qglUnmapBufferARB},
-	{"glBufferDataARB"    , (void **) &qglBufferDataARB},
-	{"glBufferSubDataARB" , (void **) &qglBufferSubDataARB},
-	{NULL, NULL}
-};
-
-static dllfunction_t ubofuncs[] =
-{
-	{"glGetUniformIndices"        , (void **) &qglGetUniformIndices},
-	{"glGetActiveUniformsiv"      , (void **) &qglGetActiveUniformsiv},
-	{"glGetActiveUniformName"     , (void **) &qglGetActiveUniformName},
-	{"glGetUniformBlockIndex"     , (void **) &qglGetUniformBlockIndex},
-	{"glGetActiveUniformBlockiv"  , (void **) &qglGetActiveUniformBlockiv},
-	{"glGetActiveUniformBlockName", (void **) &qglGetActiveUniformBlockName},
-	{"glBindBufferRange"          , (void **) &qglBindBufferRange},
-	{"glBindBufferBase"           , (void **) &qglBindBufferBase},
-	{"glGetIntegeri_v"            , (void **) &qglGetIntegeri_v},
-	{"glUniformBlockBinding"      , (void **) &qglUniformBlockBinding},
-	{NULL, NULL}
-};
-
-static dllfunction_t arbfbofuncs[] =
-{
+	{"glBindBuffer"    , (void **) &qglBindBuffer},
+	{"glDeleteBuffers" , (void **) &qglDeleteBuffers},
+	{"glGenBuffers"    , (void **) &qglGenBuffers},
+	{"glIsBuffer"      , (void **) &qglIsBuffer},
+	{"glMapBuffer"     , (void **) &qglMapBuffer},
+	{"glUnmapBuffer"   , (void **) &qglUnmapBuffer},
+	{"glBufferData"    , (void **) &qglBufferData},
+	{"glBufferSubData" , (void **) &qglBufferSubData},
 	{"glIsRenderbuffer"                      , (void **) &qglIsRenderbuffer},
 	{"glBindRenderbuffer"                    , (void **) &qglBindRenderbuffer},
 	{"glDeleteRenderbuffers"                 , (void **) &qglDeleteRenderbuffers},
 	{"glGenRenderbuffers"                    , (void **) &qglGenRenderbuffers},
 	{"glRenderbufferStorage"                 , (void **) &qglRenderbufferStorage},
-	{"glRenderbufferStorageMultisample"      , (void **) &qglRenderbufferStorageMultisample}, // not in GL_EXT_framebuffer_object
+	{"glRenderbufferStorageMultisample"      , (void **) &qglRenderbufferStorageMultisample},
 	{"glGetRenderbufferParameteriv"          , (void **) &qglGetRenderbufferParameteriv},
 	{"glIsFramebuffer"                       , (void **) &qglIsFramebuffer},
 	{"glBindFramebuffer"                     , (void **) &qglBindFramebuffer},
@@ -782,33 +689,33 @@ static dllfunction_t arbfbofuncs[] =
 	{"glFramebufferTexture1D"                , (void **) &qglFramebufferTexture1D},
 	{"glFramebufferTexture2D"                , (void **) &qglFramebufferTexture2D},
 	{"glFramebufferTexture3D"                , (void **) &qglFramebufferTexture3D},
-	{"glFramebufferTextureLayer"             , (void **) &qglFramebufferTextureLayer}, // not in GL_EXT_framebuffer_object
+	{"glFramebufferTextureLayer"             , (void **) &qglFramebufferTextureLayer},
 	{"glFramebufferRenderbuffer"             , (void **) &qglFramebufferRenderbuffer},
 	{"glGetFramebufferAttachmentParameteriv" , (void **) &qglGetFramebufferAttachmentParameteriv},
-	{"glBlitFramebuffer"                     , (void **) &qglBlitFramebuffer}, // not in GL_EXT_framebuffer_object
+	{"glBlitFramebuffer"                     , (void **) &qglBlitFramebuffer},
 	{"glGenerateMipmap"                      , (void **) &qglGenerateMipmap},
+	{"glGetUniformIndices"        , (void **) &qglGetUniformIndices},
+	{"glGetActiveUniformsiv"      , (void **) &qglGetActiveUniformsiv},
+	{"glGetActiveUniformName"     , (void **) &qglGetActiveUniformName},
+	{"glGetUniformBlockIndex"     , (void **) &qglGetUniformBlockIndex},
+	{"glGetActiveUniformBlockiv"  , (void **) &qglGetActiveUniformBlockiv},
+	{"glGetActiveUniformBlockName", (void **) &qglGetActiveUniformBlockName},
+	{"glBindBufferRange"          , (void **) &qglBindBufferRange},
+	{"glBindBufferBase"           , (void **) &qglBindBufferBase},
+	{"glGetIntegeri_v"            , (void **) &qglGetIntegeri_v},
+	{"glUniformBlockBinding"      , (void **) &qglUniformBlockBinding},
 	{NULL, NULL}
 };
 
-static dllfunction_t extfbofuncs[] =
+static dllfunction_t blendequationfuncs[] =
 {
-	{"glIsRenderbufferEXT"                      , (void **) &qglIsRenderbuffer},
-	{"glBindRenderbufferEXT"                    , (void **) &qglBindRenderbuffer},
-	{"glDeleteRenderbuffersEXT"                 , (void **) &qglDeleteRenderbuffers},
-	{"glGenRenderbuffersEXT"                    , (void **) &qglGenRenderbuffers},
-	{"glRenderbufferStorageEXT"                 , (void **) &qglRenderbufferStorage},
-	{"glGetRenderbufferParameterivEXT"          , (void **) &qglGetRenderbufferParameteriv},
-	{"glIsFramebufferEXT"                       , (void **) &qglIsFramebuffer},
-	{"glBindFramebufferEXT"                     , (void **) &qglBindFramebuffer},
-	{"glDeleteFramebuffersEXT"                  , (void **) &qglDeleteFramebuffers},
-	{"glGenFramebuffersEXT"                     , (void **) &qglGenFramebuffers},
-	{"glCheckFramebufferStatusEXT"              , (void **) &qglCheckFramebufferStatus},
-	{"glFramebufferTexture1DEXT"                , (void **) &qglFramebufferTexture1D},
-	{"glFramebufferTexture2DEXT"                , (void **) &qglFramebufferTexture2D},
-	{"glFramebufferTexture3DEXT"                , (void **) &qglFramebufferTexture3D},
-	{"glFramebufferRenderbufferEXT"             , (void **) &qglFramebufferRenderbuffer},
-	{"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameteriv},
-	{"glGenerateMipmapEXT"                      , (void **) &qglGenerateMipmap},
+	{"glBlendEquationEXT", (void **) &qglBlendEquationEXT},
+	{NULL, NULL}
+};
+
+static dllfunction_t glsl130funcs[] =
+{
+	{"glBindFragDataLocation", (void **) &qglBindFragDataLocation},
 	{NULL, NULL}
 };
 
@@ -816,10 +723,8 @@ static dllfunction_t texturecompressionfuncs[] =
 {
 	{"glCompressedTexImage3DARB",    (void **) &qglCompressedTexImage3DARB},
 	{"glCompressedTexImage2DARB",    (void **) &qglCompressedTexImage2DARB},
-//	{"glCompressedTexImage1DARB",    (void **) &qglCompressedTexImage1DARB},
 	{"glCompressedTexSubImage3DARB", (void **) &qglCompressedTexSubImage3DARB},
 	{"glCompressedTexSubImage2DARB", (void **) &qglCompressedTexSubImage2DARB},
-//	{"glCompressedTexSubImage1DARB", (void **) &qglCompressedTexSubImage1DARB},
 	{"glGetCompressedTexImageARB",   (void **) &qglGetCompressedTexImageARB},
 	{NULL, NULL}
 };
@@ -867,7 +772,6 @@ void VID_ClearExtensions(void)
 	vid.renderpath = RENDERPATH_GL20;
 	vid.sRGBcapable2D = false;
 	vid.sRGBcapable3D = false;
-	vid.forcevbo = false;
 	vid.maxtexturesize_2d = 0;
 	vid.maxtexturesize_3d = 0;
 	vid.maxtexturesize_cubemap = 0;
@@ -879,7 +783,6 @@ void VID_ClearExtensions(void)
 
 #ifndef USE_GLES2
 	// this is a complete list of all functions that are directly checked in the renderer
-	qglDrawRangeElements = NULL;
 	qglDrawBuffer = NULL;
 	qglPolygonStipple = NULL;
 	qglFlush = NULL;
@@ -893,61 +796,40 @@ void VID_ClearExtensions(void)
 #ifndef USE_GLES2
 void VID_CheckExtensions(void)
 {
-	if (!GL_CheckExtension("glbase", opengl110funcs, NULL, false))
-		Sys_Error("OpenGL 1.1.0 functions not found");
-	vid.support.gl20shaders = GL_CheckExtension("2.0", gl20shaderfuncs, "-noshaders", true);
+	char *s;
+	if (!GL_CheckExtension("glbase", openglfuncs, NULL, false))
+		Sys_Error("OpenGL driver/hardware lacks required features");
 
 	CHECKGLERROR
 
 	Con_DPrint("Checking OpenGL extensions...\n");
 
-	if (vid.support.gl20shaders)
-	{
-		char *s;
-		// detect what GLSL version is available, to enable features like r_glsl_skeletal and higher quality reliefmapping
+	// detect what GLSL version is available, to enable features like r_glsl_skeletal and higher quality reliefmapping
+	vid.support.glshaderversion = 100;
+	s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
+	if (s)
+		vid.support.glshaderversion = (int)(atof(s) * 100.0f + 0.5f);
+	if (vid.support.glshaderversion < 100)
 		vid.support.glshaderversion = 100;
-		s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
-		if (s)
-			vid.support.glshaderversion = (int)(atof(s) * 100.0f + 0.5f);
-		if (vid.support.glshaderversion < 100)
-			vid.support.glshaderversion = 100;
-		Con_DPrintf("Detected GLSL #version %i\n", vid.support.glshaderversion);
-		// get the glBindFragDataLocation function
-		if (vid.support.glshaderversion >= 130)
-			vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
-	}
+	Con_DPrintf("Detected GLSL #version %i\n", vid.support.glshaderversion);
+	// get the glBindFragDataLocation function
+	if (vid.support.glshaderversion >= 130)
+		vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
 
 	// GL drivers generally prefer GL_BGRA
 	vid.forcetextype = GL_BGRA;
 
 	vid.support.amd_texture_texture4 = GL_CheckExtension("GL_AMD_texture_texture4", NULL, "-notexture4", false);
-	vid.support.arb_depth_texture = GL_CheckExtension("GL_ARB_depth_texture", NULL, "-nodepthtexture", false);
 	vid.support.arb_draw_buffers = GL_CheckExtension("GL_ARB_draw_buffers", drawbuffersfuncs, "-nodrawbuffers", false);
-	vid.support.arb_multitexture = GL_CheckExtension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false);
 	vid.support.arb_occlusion_query = GL_CheckExtension("GL_ARB_occlusion_query", occlusionqueryfuncs, "-noocclusionquery", false);
 	vid.support.arb_query_buffer_object = GL_CheckExtension("GL_ARB_query_buffer_object", NULL, "-noquerybuffer", true);
-	vid.support.arb_shadow = GL_CheckExtension("GL_ARB_shadow", NULL, "-noshadow", false);
 	vid.support.arb_texture_compression = GL_CheckExtension("GL_ARB_texture_compression", texturecompressionfuncs, "-notexturecompression", false);
-	vid.support.arb_texture_cube_map = GL_CheckExtension("GL_ARB_texture_cube_map", NULL, "-nocubemap", false);
-	vid.support.arb_texture_env_combine = GL_CheckExtension("GL_ARB_texture_env_combine", NULL, "-nocombine", false) || GL_CheckExtension("GL_EXT_texture_env_combine", NULL, "-nocombine", false);
 	vid.support.arb_texture_gather = GL_CheckExtension("GL_ARB_texture_gather", NULL, "-notexturegather", false);
-	vid.support.arb_texture_non_power_of_two = GL_CheckExtension("GL_ARB_texture_non_power_of_two", NULL, "-notexturenonpoweroftwo", false);
-	vid.support.arb_vertex_buffer_object = GL_CheckExtension("GL_ARB_vertex_buffer_object", vbofuncs, "-novbo", false);
-	vid.support.arb_uniform_buffer_object = GL_CheckExtension("GL_ARB_uniform_buffer_object", ubofuncs, "-noubo", false);
 	vid.support.ext_blend_minmax = GL_CheckExtension("GL_EXT_blend_minmax", blendequationfuncs, "-noblendminmax", false);
 	vid.support.ext_blend_subtract = GL_CheckExtension("GL_EXT_blend_subtract", blendequationfuncs, "-noblendsubtract", false);
 	vid.support.ext_blend_func_separate = GL_CheckExtension("GL_EXT_blend_func_separate", blendfuncseparatefuncs, "-noblendfuncseparate", false);
-	vid.support.ext_draw_range_elements = GL_CheckExtension("drawrangeelements", drawrangeelementsfuncs, "-nodrawrangeelements", true) || GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
-	vid.support.arb_framebuffer_object = GL_CheckExtension("GL_ARB_framebuffer_object", arbfbofuncs, "-nofbo", false);
-	if (vid.support.arb_framebuffer_object)
-		vid.support.ext_framebuffer_object = true;
-	else
-		vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", extfbofuncs, "-nofbo", false);
-
 	vid.support.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil", NULL, "-nopackeddepthstencil", false);
-	vid.support.ext_texture_3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false);
 	vid.support.ext_texture_compression_s3tc = GL_CheckExtension("GL_EXT_texture_compression_s3tc", NULL, "-nos3tc", false);
-	vid.support.ext_texture_edge_clamp = GL_CheckExtension("GL_EXT_texture_edge_clamp", NULL, "-noedgeclamp", false) || GL_CheckExtension("GL_SGIS_texture_edge_clamp", NULL, "-noedgeclamp", false);
 	vid.support.ext_texture_filter_anisotropic = GL_CheckExtension("GL_EXT_texture_filter_anisotropic", NULL, "-noanisotropy", false);
 	vid.support.ext_texture_srgb = GL_CheckExtension("GL_EXT_texture_sRGB", NULL, "-nosrgb", false);
 	vid.support.arb_texture_float = GL_CheckExtension("GL_ARB_texture_float", NULL, "-notexturefloat", false);
@@ -984,52 +866,25 @@ void VID_CheckExtensions(void)
 	if (vid.support.arb_draw_buffers)
 		qglGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, (GLint*)&vid.maxdrawbuffers);
 
-	// disable non-power-of-two textures on Radeon X1600 and other cards that do not accelerate it with some filtering modes / repeat modes that we use
-	// we detect these cards by checking if the hardware supports vertex texture fetch (Geforce6 does, Radeon X1600 does not, all GL3-class hardware does)
-	if(vid.support.arb_texture_non_power_of_two && vid.support.gl20shaders)
-	{
-		int val = 0;
-		qglGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &val);CHECKGLERROR
-		if (val < 1)
-			vid.support.arb_texture_non_power_of_two = false;
-	}
-
-	// we don't care if it's an extension or not, they are identical functions, so keep it simple in the rendering code
-	if (qglDrawRangeElements == NULL)
-		qglDrawRangeElements = qglDrawRangeElementsEXT;
-
 	qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
 	qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
 	qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap);
 	qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
 
-	// verify that 3d textures are really supported
-	if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
-	{
-		vid.support.ext_texture_3d = false;
-		Con_Printf("GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
-	}
-
 	vid.texunits = vid.teximageunits = vid.texarrayunits = 1;
 	qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
-	if (vid.support.gl20shaders && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two)
-	{
-		qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
-		qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int *)&vid.teximageunits);CHECKGLERROR
-		qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (int *)&vid.texarrayunits);CHECKGLERROR
-		vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS);
-		vid.teximageunits = bound(16, vid.teximageunits, MAX_TEXTUREUNITS);
-		vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS);
-		Con_DPrintf("Using GL2.0+fbo rendering path - %i texture matrix, %i texture images, %i texcoords%s\n", vid.texunits, vid.teximageunits, vid.texarrayunits, vid.support.ext_framebuffer_object ? ", shadowmapping supported" : "");
-		vid.renderpath = RENDERPATH_GL20;
-		vid.sRGBcapable2D = false;
-		vid.sRGBcapable3D = true;
-		Con_Printf("vid.support.arb_multisample %i\n", vid.support.arb_multisample);
-		Con_Printf("vid.support.gl20shaders %i\n", vid.support.gl20shaders);
-		vid.allowalphatocoverage = true; // but see below, it may get turned to false again if GL_SAMPLES_ARB is <= 1
-	}
-	else
-		Sys_Error("OpenGL 2.0 and GL_EXT_framebuffer_object required");
+	qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
+	qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int *)&vid.teximageunits);CHECKGLERROR
+	qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (int *)&vid.texarrayunits);CHECKGLERROR
+	vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS);
+	vid.teximageunits = bound(16, vid.teximageunits, MAX_TEXTUREUNITS);
+	vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS);
+	Con_DPrint("Using GL2+extensions rendering path\n");
+	vid.renderpath = RENDERPATH_GL20;
+	vid.sRGBcapable2D = false;
+	vid.sRGBcapable3D = true;
+	Con_DPrintf("vid.support.arb_multisample %i\n", vid.support.arb_multisample);
+	vid.allowalphatocoverage = true; // but see below, it may get turned to false again if GL_SAMPLES_ARB is <= 1
 
 	// enable multisample antialiasing if possible
 	if(vid.support.arb_multisample)