]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
physics: fix and refactor unsticking
[xonotic/darkplaces.git] / gl_backend.c
index 60487161c7ec195b77051e1d8c8b8879056d8382..b5336a226223f62d852b5760a5b8e534117c8546 100644 (file)
@@ -2,91 +2,19 @@
 #include "quakedef.h"
 #include "cl_collision.h"
 
-// on GLES we have to use some proper #define's
-#ifndef GL_FRAMEBUFFER
-#define GL_FRAMEBUFFER                                   0x8D40
-#define GL_DEPTH_ATTACHMENT                              0x8D00
-#define GL_COLOR_ATTACHMENT0                             0x8CE0
-#define GL_INVALID_FRAMEBUFFER_OPERATION                 0x0506
-#endif
-#ifndef GL_COLOR_ATTACHMENT1
-#define GL_COLOR_ATTACHMENT1                             0x8CE1
-#define GL_COLOR_ATTACHMENT2                             0x8CE2
-#define GL_COLOR_ATTACHMENT3                             0x8CE3
-#define GL_COLOR_ATTACHMENT4                             0x8CE4
-#define GL_COLOR_ATTACHMENT5                             0x8CE5
-#define GL_COLOR_ATTACHMENT6                             0x8CE6
-#define GL_COLOR_ATTACHMENT7                             0x8CE7
-#define GL_COLOR_ATTACHMENT8                             0x8CE8
-#define GL_COLOR_ATTACHMENT9                             0x8CE9
-#define GL_COLOR_ATTACHMENT10                            0x8CEA
-#define GL_COLOR_ATTACHMENT11                            0x8CEB
-#define GL_COLOR_ATTACHMENT12                            0x8CEC
-#define GL_COLOR_ATTACHMENT13                            0x8CED
-#define GL_COLOR_ATTACHMENT14                            0x8CEE
-#define GL_COLOR_ATTACHMENT15                            0x8CEF
-#endif
-#ifndef GL_ARRAY_BUFFER
-#define GL_ARRAY_BUFFER               0x8892
-#define GL_ELEMENT_ARRAY_BUFFER       0x8893
-#endif
-#ifndef GL_TEXTURE0
-#define GL_TEXTURE0                                    0x84C0
-#define GL_TEXTURE1                                    0x84C1
-#define GL_TEXTURE2                                    0x84C2
-#define GL_TEXTURE3                                    0x84C3
-#define GL_TEXTURE4                                    0x84C4
-#define GL_TEXTURE5                                    0x84C5
-#define GL_TEXTURE6                                    0x84C6
-#define GL_TEXTURE7                                    0x84C7
-#define GL_TEXTURE8                                    0x84C8
-#define GL_TEXTURE9                                    0x84C9
-#define GL_TEXTURE10                           0x84CA
-#define GL_TEXTURE11                           0x84CB
-#define GL_TEXTURE12                           0x84CC
-#define GL_TEXTURE13                           0x84CD
-#define GL_TEXTURE14                           0x84CE
-#define GL_TEXTURE15                           0x84CF
-#define GL_TEXTURE16                           0x84D0
-#define GL_TEXTURE17                           0x84D1
-#define GL_TEXTURE18                           0x84D2
-#define GL_TEXTURE19                           0x84D3
-#define GL_TEXTURE20                           0x84D4
-#define GL_TEXTURE21                           0x84D5
-#define GL_TEXTURE22                           0x84D6
-#define GL_TEXTURE23                           0x84D7
-#define GL_TEXTURE24                           0x84D8
-#define GL_TEXTURE25                           0x84D9
-#define GL_TEXTURE26                           0x84DA
-#define GL_TEXTURE27                           0x84DB
-#define GL_TEXTURE28                           0x84DC
-#define GL_TEXTURE29                           0x84DD
-#define GL_TEXTURE30                           0x84DE
-#define GL_TEXTURE31                           0x84DF
-#endif
-
-#ifndef GL_TEXTURE_3D
-#define GL_TEXTURE_3D                          0x806F
-#endif
-#ifndef GL_TEXTURE_CUBE_MAP
-#define GL_TEXTURE_CUBE_MAP                0x8513
-#endif
-
-
 #define MAX_RENDERTARGETS 4
 
-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"};
+cvar_t gl_debug = {CF_CLIENT, "gl_debug", "0", "enables OpenGL debug output, 0 = off, 1 = HIGH severity only, 2 = also MEDIUM severity, 3 = also LOW severity messages.  (note: enabling may not take effect until vid_restart on some drivers)"};
+cvar_t gl_paranoid = {CF_CLIENT, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
+cvar_t gl_printcheckerror = {CF_CLIENT, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
 
-cvar_t r_render = {0, "r_render", "1", "enables rendering 3D views (you want this on!)"};
-cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
-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_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 r_render = {CF_CLIENT, "r_render", "1", "enables rendering 3D views (you want this on!)"};
+cvar_t r_renderview = {CF_CLIENT, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
+cvar_t r_waterwarp = {CF_CLIENT | CF_ARCHIVE, "r_waterwarp", "1", "warp view while underwater"};
+cvar_t gl_polyblend = {CF_CLIENT | CF_ARCHIVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
 
-cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
-qboolean v_flipped_state = false;
+cvar_t v_flipped = {CF_CLIENT, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
+qbool v_flipped_state = false;
 
 r_viewport_t gl_viewport;
 matrix4x4_t gl_modelmatrix;
@@ -96,15 +24,10 @@ matrix4x4_t gl_projectionmatrix;
 matrix4x4_t gl_modelviewprojectionmatrix;
 float gl_modelview16f[16];
 float gl_modelviewprojection16f[16];
-qboolean gl_modelmatrixchanged;
-
-int gl_maxdrawrangeelementsvertices;
-int gl_maxdrawrangeelementsindices;
+qbool gl_modelmatrixchanged;
 
 #ifdef DEBUGGL
-int gl_errornumber = 0;
-
-void GL_PrintError(int errornumber, const char *filename, int linenumber)
+void GL_PrintError(GLenum errornumber, const char *filename, unsigned int linenumber)
 {
        switch(errornumber)
        {
@@ -153,11 +76,41 @@ void GL_PrintError(int errornumber, const char *filename, int linenumber)
                break;
        }
 }
+
+static void GLAPIENTRY GL_DebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const GLvoid* userParam)
+{
+       const char *sev = "ENUM?", *typ = "ENUM?", *src = "ENUM?";
+       switch (severity)
+       {
+       case GL_DEBUG_SEVERITY_LOW_ARB: sev = "LOW"; break;
+       case GL_DEBUG_SEVERITY_MEDIUM_ARB: sev = "MED"; break;
+       case GL_DEBUG_SEVERITY_HIGH_ARB: sev = "HIGH"; break;
+       }
+       switch (type)
+       {
+       case GL_DEBUG_TYPE_ERROR_ARB: typ = "ERROR"; break;
+       case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typ = "DEPRECATED"; break;
+       case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typ = "UNDEFINED"; break;
+       case GL_DEBUG_TYPE_PORTABILITY_ARB: typ = "PORTABILITY"; break;
+       case GL_DEBUG_TYPE_PERFORMANCE_ARB: typ = "PERFORMANCE"; break;
+       case GL_DEBUG_TYPE_OTHER_ARB: typ = "OTHER"; break;
+       }
+       switch (source)
+       {
+       case GL_DEBUG_SOURCE_API_ARB: src = "API"; break;
+       case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: src = "SHADER"; break;
+       case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: src = "WIN"; break;
+       case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: src = "THIRDPARTY"; break;
+       case GL_DEBUG_SOURCE_APPLICATION_ARB: src = "APP"; break;
+       case GL_DEBUG_SOURCE_OTHER_ARB: src = "OTHER"; break;
+       }
+       Con_Printf("GLDEBUG: %s %s %s: %u: %s\n", sev, typ, src, (unsigned int)id, message);
+}
 #endif
 
 #define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
 
-void SCR_ScreenShot_f (void);
+void SCR_ScreenShot_f(cmd_state_t *cmd);
 
 typedef struct gltextureunit_s
 {
@@ -171,12 +124,6 @@ typedef struct gltextureunit_s
        rtexture_t *texture;
        int t2d, t3d, tcubemap;
        int arrayenabled;
-       int rgbscale, alphascale;
-       int combine;
-       int combinergb, combinealpha;
-       // texmatrixenabled exists only to avoid unnecessary texmatrix compares
-       int texmatrixenabled;
-       matrix4x4_t matrix;
 }
 gltextureunit_t;
 
@@ -186,20 +133,16 @@ typedef struct gl_state_s
        int cullfaceenable;
        int blendfunc1;
        int blendfunc2;
-       qboolean blend;
+       qbool blend;
        GLboolean depthmask;
        int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order)
        int depthtest;
        int depthfunc;
        float depthrange[2];
        float polygonoffset[2];
-       int alphatest;
-       int alphafunc;
-       float alphafuncvalue;
-       qboolean alphatocoverage;
+       qbool alphatocoverage;
        int scissortest;
        unsigned int unit;
-       unsigned int clientunit;
        gltextureunit_t units[MAX_TEXTUREUNITS];
        float color4f[4];
        int lockrange_first;
@@ -209,7 +152,10 @@ typedef struct gl_state_s
        int uniformbufferobject;
        int framebufferobject;
        int defaultframebufferobject; // deal with platforms that use a non-zero default fbo
-       qboolean pointer_color_enabled;
+       qbool pointer_color_enabled;
+
+       // GL3.2 Core requires that we have a GL_VERTEX_ARRAY_OBJECT, but... just one.
+       unsigned int defaultvao;
 
        int pointer_vertex_components;
        int pointer_vertex_gltype;
@@ -231,7 +177,7 @@ typedef struct gl_state_s
 
        memexpandablearray_t meshbufferarray;
 
-       qboolean active;
+       qbool active;
 }
 gl_state_t;
 
@@ -297,7 +243,7 @@ unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
 
-static void GL_VBOStats_f(void)
+static void GL_VBOStats_f(cmd_state_t *cmd)
 {
        GL_Mesh_ListVBOs(true);
 }
@@ -310,26 +256,32 @@ static void gl_backend_start(void)
 
        Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
 
-       Con_DPrintf("OpenGL backend started.\n");
+       Con_Printf("OpenGL backend started\n");
 
        CHECKGLERROR
 
-       GL_Backend_ResetState();
-
        switch(vid.renderpath)
        {
+#ifndef USE_GLES2
        case RENDERPATH_GL32:
+               // GL3.2 Core requires that we have a VAO bound - but using more than one has no performance benefit so this is just placeholder
+               qglGenVertexArrays(1, &gl_state.defaultvao);
+               qglBindVertexArray(gl_state.defaultvao);
+               // fall through
+#endif //USE_GLES2
        case RENDERPATH_GLES2:
                // fetch current fbo here (default fbo is not 0 on some GLES devices)
                CHECKGLERROR
                qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);CHECKGLERROR
                break;
        }
+
+       GL_Backend_ResetState();
 }
 
 static void gl_backend_shutdown(void)
 {
-       Con_DPrint("OpenGL Backend shutting down\n");
+       Con_Print("OpenGL backend shutting down\n");
 
        switch(vid.renderpath)
        {
@@ -416,16 +368,16 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&r_waterwarp);
        Cvar_RegisterVariable(&gl_polyblend);
        Cvar_RegisterVariable(&v_flipped);
-       Cvar_RegisterVariable(&gl_dither);
+       Cvar_RegisterVariable(&gl_debug);
        Cvar_RegisterVariable(&gl_paranoid);
        Cvar_RegisterVariable(&gl_printcheckerror);
 
-       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");
+       Cmd_AddCommand(CF_CLIENT, "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);
 }
 
-void GL_SetMirrorState(qboolean state);
+void GL_SetMirrorState(qbool state);
 
 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
 {
@@ -474,7 +426,7 @@ static int bboxedges[12][2] =
        {3, 7}, // XY, +Z
 };
 
-qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
+qbool R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
 {
        int i, ix1, iy1, ix2, iy2;
        float x1, y1, x2, y2;
@@ -609,7 +561,7 @@ static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m
        Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
        VectorScale(normal, -dist, v3);
        Matrix4x4_Transform(&v->viewmatrix, v3, v4);
-       // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
+       // FIXME: LadyHavoc: I think this can be done more efficiently somehow but I can't remember the technique
        clipPlane[3] = -DotProduct(v4, clipPlane);
 
        // Calculate the clip-space corner point opposite the clipping plane
@@ -1018,51 +970,51 @@ int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colorte
                // 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
+               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->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->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)
+               if (colortexture4)
                {
-                       qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
+                       qglDrawBuffers(4, drawbuffers);CHECKGLERROR
                        qglReadBuffer(GL_NONE);CHECKGLERROR
                }
-               else if (colortexture3 && qglDrawBuffersARB)
+               else if (colortexture3)
                {
-                       qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
+                       qglDrawBuffers(3, drawbuffers);CHECKGLERROR
                        qglReadBuffer(GL_NONE);CHECKGLERROR
                }
-               else if (colortexture2 && qglDrawBuffersARB)
+               else if (colortexture2)
                {
-                       qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
+                       qglDrawBuffers(2, drawbuffers);CHECKGLERROR
                        qglReadBuffer(GL_NONE);CHECKGLERROR
                }
-               else if (colortexture && qglDrawBuffer)
+               else if (colortexture)
                {
                        qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
                        qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
                }
-               else if (qglDrawBuffer)
+               else
                {
                        qglDrawBuffer(GL_NONE);CHECKGLERROR
                        qglReadBuffer(GL_NONE);CHECKGLERROR
@@ -1129,9 +1081,6 @@ static void GL_Backend_ResetState(void)
 {
        gl_state.active = true;
        gl_state.depthtest = true;
-       gl_state.alphatest = false;
-       gl_state.alphafunc = GL_GEQUAL;
-       gl_state.alphafuncvalue = 0.5f;
        gl_state.alphatocoverage = false;
        gl_state.blendfunc1 = GL_ONE;
        gl_state.blendfunc2 = GL_ZERO;
@@ -1152,6 +1101,27 @@ static void GL_Backend_ResetState(void)
        {
        case RENDERPATH_GL32:
        case RENDERPATH_GLES2:
+               // set up debug output early
+#ifdef DEBUGGL
+               if (vid.support.arb_debug_output)
+               {
+                       GLuint unused = 0;
+                       CHECKGLERROR
+                       if (gl_debug.integer >= 1)
+                               qglEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+                       if (gl_debug.integer >= 3)
+                               qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unused, gl_debug.integer >= 3 ? GL_TRUE : GL_FALSE);
+                       else if (gl_debug.integer >= 1)
+                       {
+                               qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, &unused, gl_debug.integer >= 3 ? GL_TRUE : GL_FALSE);
+                               qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM_ARB, 0, &unused, gl_debug.integer >= 2 ? GL_TRUE : GL_FALSE);
+                               qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH_ARB, 0, &unused, gl_debug.integer >= 1 ? GL_TRUE : GL_FALSE);
+                       }
+                       else
+                               qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unused, GL_FALSE);
+                       qglDebugMessageCallbackARB(GL_DebugOutputCallback, NULL);
+               }
+#endif //DEBUGGL
                CHECKGLERROR
                qglColorMask(1, 1, 1, 1);CHECKGLERROR
                qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
@@ -1169,7 +1139,6 @@ static void GL_Backend_ResetState(void)
                qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
                qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
                gl_state.unit = MAX_TEXTUREUNITS;
-               gl_state.clientunit = MAX_TEXTUREUNITS;
                CHECKGLERROR
                break;
        }
@@ -1195,7 +1164,7 @@ void GL_BlendFunc(int blendfunc1, int blendfunc2)
 {
        if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
        {
-               qboolean blendenable;
+               qbool blendenable;
                gl_state.blendfunc1 = blendfunc1;
                gl_state.blendfunc2 = blendfunc2;
                blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
@@ -1305,7 +1274,7 @@ void GL_DepthRange(float nearfrac, float farfrac)
        }
 }
 
-void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
+void R_SetStencil(qbool enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
 {
        switch (vid.renderpath)
        {
@@ -1345,7 +1314,7 @@ void GL_PolygonOffset(float planeoffset, float depthoffset)
        }
 }
 
-void GL_SetMirrorState(qboolean state)
+void GL_SetMirrorState(qbool state)
 {
        if (v_flipped_state != state)
        {
@@ -1408,7 +1377,7 @@ void GL_CullFace(int state)
        }
 }
 
-void GL_AlphaToCoverage(qboolean state)
+void GL_AlphaToCoverage(qbool state)
 {
        if (gl_state.alphatocoverage != state)
        {
@@ -1418,18 +1387,18 @@ void GL_AlphaToCoverage(qboolean state)
                case RENDERPATH_GLES2:
                        break;
                case RENDERPATH_GL32:
-#ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
+#ifndef USE_GLES2
                        // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
                        CHECKGLERROR
                        if (gl_state.alphatocoverage)
                        {
-                               qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
-//                             qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
+                               qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);CHECKGLERROR
+//                             qglEnable(GL_MULTISAMPLE);CHECKGLERROR
                        }
                        else
                        {
-                               qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
-//                             qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
+                               qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);CHECKGLERROR
+//                             qglDisable(GL_MULTISAMPLE);CHECKGLERROR
                        }
 #endif
                        break;
@@ -1529,7 +1498,7 @@ void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilva
                if (mask & GL_DEPTH_BUFFER_BIT)
                {
 #ifdef USE_GLES2
-                       qglClearDepthf(depthvalue);CHECKGLERROR
+                       //qglClearDepthf(depthvalue);CHECKGLERROR
 #else
                        qglClearDepth(depthvalue);CHECKGLERROR
 #endif
@@ -1584,12 +1553,12 @@ void R_Mesh_Start(void)
        R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
        if (gl_printcheckerror.integer && !gl_paranoid.integer)
        {
-               Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
+               Con_Printf(CON_WARN "WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
                Cvar_SetValueQuick(&gl_paranoid, 1);
        }
 }
 
-static qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
+static qbool GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
 {
        int shaderobject;
        int shadercompiled;
@@ -1792,7 +1761,7 @@ void R_Mesh_Finish(void)
        R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
 }
 
-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 *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qbool isindexbuffer, qbool isuniformbuffer, qbool isdynamic, qbool isindex16)
 {
        r_meshbuffer_t *buffer;
        buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
@@ -1804,12 +1773,12 @@ r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const cha
        buffer->isuniformbuffer = isuniformbuffer;
        buffer->isdynamic = isdynamic;
        buffer->isindex16 = isindex16;
-       strlcpy(buffer->name, name, sizeof(buffer->name));
+       dp_strlcpy(buffer->name, name, sizeof(buffer->name));
        R_Mesh_UpdateMeshBuffer(buffer, data, size, false, 0);
        return buffer;
 }
 
-void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size, qboolean subdata, size_t offset)
+void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size, qbool subdata, size_t offset)
 {
        if (!buffer)
                return;
@@ -1882,7 +1851,7 @@ void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
 }
 
 static const char *buffertypename[R_BUFFERDATA_COUNT] = {"vertex", "index16", "index32", "uniform"};
-void GL_Mesh_ListVBOs(qboolean printeach)
+void GL_Mesh_ListVBOs(qbool printeach)
 {
        int i, endindex;
        int type;
@@ -1940,7 +1909,7 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void
                {
                        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);
+                               Con_DPrintf("Warning: no bufferobject in R_Mesh_VertexPointer(%i, %i, %i, %p, %p, %08x)", components, gltype, (int)stride, pointer, (void *)vertexbuffer, (unsigned int)bufferoffset);
                        gl_state.pointer_vertex_components = components;
                        gl_state.pointer_vertex_gltype = gltype;
                        gl_state.pointer_vertex_stride = stride;
@@ -1949,7 +1918,7 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void
                        gl_state.pointer_vertex_offset = bufferoffset;
                        CHECKGLERROR
                        GL_BindVBO(bufferobject);
-                       // LordHavoc: special flag added to gltype for unnormalized types
+                       // LadyHavoc: special flag added to gltype for unnormalized types
                        qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                }
                break;
@@ -1985,7 +1954,7 @@ void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *
                                gl_state.pointer_color_offset = bufferoffset;
                                CHECKGLERROR
                                GL_BindVBO(bufferobject);
-                               // LordHavoc: special flag added to gltype for unnormalized types
+                               // LadyHavoc: special flag added to gltype for unnormalized types
                                qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                        }
                }
@@ -2037,7 +2006,7 @@ void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, si
                                unit->pointer_texcoord_vertexbuffer = vertexbuffer;
                                unit->pointer_texcoord_offset = bufferoffset;
                                GL_BindVBO(bufferobject);
-                               // LordHavoc: special flag added to gltype for unnormalized types
+                               // LadyHavoc: special flag added to gltype for unnormalized types
                                qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                        }
                }
@@ -2100,41 +2069,52 @@ void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
        int texnum;
        if (unitnum >= MAX_TEXTUREUNITS)
                Sys_Error("R_Mesh_TexBind: unitnum %i > max units %i\n", unitnum, MAX_TEXTUREUNITS);
-       if (unit->texture == tex)
-               return;
        switch(vid.renderpath)
        {
        case RENDERPATH_GL32:
        case RENDERPATH_GLES2:
-               if (!tex)
+               if (tex)
                {
-                       tex = r_texture_white;
-                       // not initialized enough yet...
-                       if (!tex)
-                               return;
+                       texnum = R_GetTexture(tex);
+                       switch (tex->gltexturetypeenum)
+                       {
+                       case GL_TEXTURE_2D:
+                               if (unit->t2d != texnum) { GL_ActiveTexture(unitnum);qglBindTexture(GL_TEXTURE_2D, texnum); CHECKGLERROR unit->t2d = texnum; }
+                               if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+                               if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
+                               break;
+                       case GL_TEXTURE_3D:
+                               if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+                               if (unit->t3d != texnum) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, texnum); CHECKGLERROR unit->t3d = texnum; }
+                               if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
+                               break;
+                       case GL_TEXTURE_CUBE_MAP:
+                               if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+                               if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+                               if (unit->tcubemap != texnum) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, texnum); CHECKGLERROR unit->tcubemap = texnum; }
+                               break;
+                       }
                }
-               unit->texture = tex;
-               texnum = R_GetTexture(tex);
-               switch(tex->gltexturetypeenum)
+               else
                {
-               case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
-               case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
-               case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
+                       if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+                       if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+                       if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
                }
-               break;
        }
+       unit->texture = tex;
 }
 
 void R_Mesh_ResetTextureState(void)
 {
+#if 0
        unsigned int unitnum;
-
+       
        BACKENDACTIVECHECK
 
        for (unitnum = 0;unitnum < MAX_TEXTUREUNITS;unitnum++)
                R_Mesh_TexBind(unitnum, NULL);
-       for (unitnum = 0;unitnum < MAX_TEXTUREUNITS;unitnum++)
-               R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+#endif
 }
 
 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer, int bufferoffset)
@@ -2142,32 +2122,16 @@ void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, con
        // upload temporary vertexbuffer for this rendering
        if (!vertexbuffer)
                vertexbuffer = R_BufferData_Store(numvertices * sizeof(float[3]), (void *)vertex3f, R_BUFFERDATA_VERTEX, &bufferoffset);
-       if (vertexbuffer)
-       {
-               R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, bufferoffset);
-               R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
-               R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 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);
-       }
-       else
-       {
-               R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
-               R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
-               R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 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_Mesh_VertexPointer(     3, GL_FLOAT        , sizeof(float[3])        , vertex3f  , vertexbuffer     , bufferoffset           );
+       R_Mesh_ColorPointer(      4, GL_FLOAT        , sizeof(float[4])        , NULL      , NULL             , 0                      );
+       R_Mesh_TexCoordPointer(0, 2, GL_FLOAT        , sizeof(float[2])        , NULL      , NULL             , 0                      );
+       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_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
@@ -2178,9 +2142,12 @@ void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3
        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);
+       if (color4f)
+               buffer_color4f    = R_BufferData_Store(numvertices * sizeof(float[4]), color4f   , R_BUFFERDATA_VERTEX, &bufferoffset_color4f   );
+       if (vertex3f)
+               buffer_vertex3f   = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f  , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f  );
+       if (texcoord2f)
+               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        );
@@ -2209,13 +2176,20 @@ void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f,
        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);
+       if (color4f)
+               buffer_color4f            = R_BufferData_Store(numvertices * sizeof(float[4]), color4f           , R_BUFFERDATA_VERTEX, &bufferoffset_color4f           );
+       if (vertex3f)
+               buffer_vertex3f           = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f          , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f          );
+       if (svector3f)
+               buffer_svector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), svector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_svector3f         );
+       if (tvector3f)
+               buffer_tvector3f          = R_BufferData_Store(numvertices * sizeof(float[3]), tvector3f         , R_BUFFERDATA_VERTEX, &bufferoffset_tvector3f         );
+       if (normal3f)
+               buffer_normal3f           = R_BufferData_Store(numvertices * sizeof(float[3]), normal3f          , R_BUFFERDATA_VERTEX, &bufferoffset_normal3f          );
+       if (texcoordtexture2f)
+               buffer_texcoordtexture2f  = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordtexture2f , R_BUFFERDATA_VERTEX, &bufferoffset_texcoordtexture2f );
+       if (texcoordlightmap2f)
+               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 );
@@ -2228,7 +2202,7 @@ void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f,
        R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL              , NULL                     , 0                              );
 }
 
-void GL_BlendEquationSubtract(qboolean negated)
+void GL_BlendEquationSubtract(qbool negated)
 {
        CHECKGLERROR
        if(negated)
@@ -2237,7 +2211,7 @@ void GL_BlendEquationSubtract(qboolean negated)
                {
                case RENDERPATH_GL32:
                case RENDERPATH_GLES2:
-                       qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);CHECKGLERROR
+                       qglBlendEquation(GL_FUNC_REVERSE_SUBTRACT);CHECKGLERROR
                        break;
                }
        }
@@ -2247,7 +2221,7 @@ void GL_BlendEquationSubtract(qboolean negated)
                {
                case RENDERPATH_GL32:
                case RENDERPATH_GLES2:
-                       qglBlendEquationEXT(GL_FUNC_ADD);CHECKGLERROR
+                       qglBlendEquation(GL_FUNC_ADD);CHECKGLERROR
                        break;
                }
        }