]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
remove unused variable
[xonotic/darkplaces.git] / gl_backend.c
index 02ddae2cfd5bbea97444b4516b8bf160f2f88120..f68d27b8f8bdf47aad9ccd778528caf93dcadd70 100644 (file)
@@ -706,8 +706,6 @@ qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
        if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
                return false;
 
-       x1 = y1 = x2 = y2 = 0;
-
        // transform all corners that are infront of the nearclip plane
        VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
        plane4f[3] = r_refdef.view.frustum[4].dist;
@@ -1249,9 +1247,9 @@ static void GL_BindEBO(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;
        switch(vid.renderpath)
        {
        case RENDERPATH_GL11:
@@ -1259,17 +1257,120 @@ int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colorte
        case RENDERPATH_GL20:
        case RENDERPATH_GLES1:
        case RENDERPATH_GLES2:
-               if (!vid.support.ext_framebuffer_object)
-                       return 0;
-               qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
-               R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
-               if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
-               if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
-               if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
-               if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
-               if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
-               if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
-               return temp;
+               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
+#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
+#else
+                       if (depthtexture  && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, depthtexture->glisdepthstencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT  , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+#endif
+                       if (depthtexture  && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, depthtexture->glisdepthstencil ? GL_DEPTH_STENCIL_ATTACHMENT : 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
+                       }
+#endif
+                       status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
+                       if (status != GL_FRAMEBUFFER_COMPLETE)
+                       {
+                               Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+                               qglDeleteFramebuffers(1, (GLuint*)&temp);
+                               temp = 0;
+                       }
+                       return temp;
+               }
+               else if (vid.support.ext_framebuffer_object)
+               {
+                       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
+                       }
+#endif
+                       status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
+                       if (status != GL_FRAMEBUFFER_COMPLETE)
+                       {
+                               Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+                               qglDeleteFramebuffers(1, (GLuint*)&temp);
+                               temp = 0;
+                       }
+                       return temp;
+               }
+               return 0;
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
@@ -1290,7 +1391,7 @@ void R_Mesh_DestroyFramebufferObject(int fbo)
        case RENDERPATH_GLES1:
        case RENDERPATH_GLES2:
                if (fbo)
-                       qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
+                       qglDeleteFramebuffers(1, (GLuint*)&fbo);
                break;
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
@@ -1304,10 +1405,6 @@ void R_Mesh_DestroyFramebufferObject(int fbo)
 #ifdef SUPPORTD3D
 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
 {
-// LordHavoc: for some weird reason the redundant SetDepthStencilSurface calls are necessary (otherwise the lights fail depth test, as if they were using the shadowmap depth surface and render target still)
-       if (gl_state.d3drt_depthsurface == depthsurface && gl_state.d3drt_colorsurfaces[0] == colorsurface0 && gl_state.d3drt_colorsurfaces[1] == colorsurface1 && gl_state.d3drt_colorsurfaces[2] == colorsurface2 && gl_state.d3drt_colorsurfaces[3] == colorsurface3)
-               return;
-
        gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
        if (gl_state.d3drt_depthsurface != depthsurface)
        {
@@ -1361,7 +1458,7 @@ void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colo
                if (gl_state.framebufferobject != fbo)
                {
                        gl_state.framebufferobject = fbo;
-                       qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
+                       qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
                }
                break;
        case RENDERPATH_D3D9:
@@ -1370,19 +1467,24 @@ void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colo
                // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
                if (fbo)
                {
-                       IDirect3DSurface9 *colorsurfaces[4];
-                       for (i = 0;i < 4;i++)
+                       IDirect3DSurface9 *surfaces[5];
+                       for (i = 0;i < 5;i++)
                        {
-                               colorsurfaces[i] = NULL;
+                               surfaces[i] = NULL;
                                if (textures[i])
-                                       IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
+                               {
+                                       if (textures[i]->d3dsurface)
+                                               surfaces[i] = (IDirect3DSurface9 *)textures[i]->d3dsurface;
+                                       else
+                                               IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &surfaces[i]);
+                               }
                        }
                        // set the render targets for real
-                       R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
+                       R_Mesh_SetRenderTargetsD3D9(surfaces[4], surfaces[0], surfaces[1], surfaces[2], surfaces[3]);
                        // release the texture surface levels (they won't be lost while bound...)
-                       for (i = 0;i < 4;i++)
-                               if (textures[i])
-                                       IDirect3DSurface9_Release(colorsurfaces[i]);
+                       for (i = 0;i < 5;i++)
+                               if (textures[i] && !textures[i]->d3dsurface)
+                                       IDirect3DSurface9_Release(surfaces[i]);
                }
                else
                        R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
@@ -1441,8 +1543,6 @@ static int d3dstencilopforglfunc(int f)
 }
 #endif
 
-extern cvar_t r_transparent_alphatocoverage;
-
 static void GL_Backend_ResetState(void)
 {
        unsigned int i;
@@ -1514,8 +1614,8 @@ static void GL_Backend_ResetState(void)
 
                if (vid.support.ext_framebuffer_object)
                {
-                       //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
-                       qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+                       //qglBindRenderbuffer(GL_RENDERBUFFER, 0);
+                       qglBindFramebuffer(GL_FRAMEBUFFER, 0);
                }
 
                qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
@@ -1526,7 +1626,7 @@ static void GL_Backend_ResetState(void)
                qglColor4f(1, 1, 1, 1);CHECKGLERROR
 
                if (vid.support.ext_framebuffer_object)
-                       qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
+                       qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.framebufferobject);
 
                gl_state.unit = MAX_TEXTUREUNITS;
                gl_state.clientunit = MAX_TEXTUREUNITS;
@@ -1585,7 +1685,7 @@ static void GL_Backend_ResetState(void)
                        qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
                }
                if (vid.support.ext_framebuffer_object)
-                       qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
+                       qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
                qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
                qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
                qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
@@ -1928,7 +2028,8 @@ void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int fro
                        qglStencilMask(writemask);CHECKGLERROR
                        qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
                        qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
-                       qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
+                       qglStencilFuncSeparate(GL_FRONT, frontcompare, comparereference, comparereference);CHECKGLERROR
+                       qglStencilFuncSeparate(GL_BACK, backcompare, comparereference, comparereference);CHECKGLERROR
                }
                else if (vid.support.ext_stencil_two_side)
                {
@@ -2536,7 +2637,7 @@ static qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenu
        qglCompileShader(shaderobject);CHECKGLERROR
        qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
        qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
-       if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
+       if (compilelog[0] && ((strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error")) || ((strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")) && developer.integer) || developer_extra.integer))
        {
                int i, j, pretextlines = 0;
                for (i = 0;i < numstrings - 1;i++)
@@ -2574,8 +2675,8 @@ unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **ver
        qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
        qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
        qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
-       qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
-       qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
+       qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_SkeletalIndex");
+       qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_SkeletalWeight");
 #ifndef USE_GLES2
        if(vid.support.gl20shaders130)
                qglBindFragDataLocation(programobject, 0, "dp_FragColor");
@@ -2704,9 +2805,9 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
        bufferoffset3i = element3i_bufferoffset;
        bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
        bufferoffset3s = element3s_bufferoffset;
-       r_refdef.stats.draws++;
-       r_refdef.stats.draws_vertices += numvertices;
-       r_refdef.stats.draws_elements += numelements;
+       r_refdef.stats[r_stat_draws]++;
+       r_refdef.stats[r_stat_draws_vertices] += numvertices;
+       r_refdef.stats[r_stat_draws_elements] += numelements;
        if (gl_paranoid.integer)
        {
                unsigned int i;
@@ -2811,7 +2912,7 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
                                                                        else
                                                                                qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
                                                                }
-                                                               else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
+                                                               else if (gl_state.units[j].pointer_texcoord_gltype == (int)(GL_SHORT | 0x80000000))
                                                                {
                                                                        const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
                                                                        if (gl_state.units[j].pointer_texcoord_components == 4)
@@ -2826,6 +2927,30 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
                                                                else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
                                                                {
                                                                        const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
+                                                                       if (gl_state.units[j].pointer_texcoord_components == 4)
+                                                                               qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 127.0f), sb[1] * (1.0f / 127.0f), sb[2] * (1.0f / 127.0f), sb[3] * (1.0f / 127.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 3)
+                                                                               qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 127.0f), sb[1] * (1.0f / 127.0f), sb[2] * (1.0f / 127.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 2)
+                                                                               qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 127.0f), sb[1] * (1.0f / 127.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 1)
+                                                                               qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 127.0f));
+                                                               }
+                                                               else if (gl_state.units[j].pointer_texcoord_gltype == GL_UNSIGNED_BYTE)
+                                                               {
+                                                                       const GLubyte *sb = (const GLubyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
+                                                                       if (gl_state.units[j].pointer_texcoord_components == 4)
+                                                                               qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 255.0f), sb[1] * (1.0f / 255.0f), sb[2] * (1.0f / 255.0f), sb[3] * (1.0f / 255.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 3)
+                                                                               qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 255.0f), sb[1] * (1.0f / 255.0f), sb[2] * (1.0f / 255.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 2)
+                                                                               qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 255.0f), sb[1] * (1.0f / 255.0f));
+                                                                       else if (gl_state.units[j].pointer_texcoord_components == 1)
+                                                                               qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0] * (1.0f / 255.0f));
+                                                               }
+                                                               else if (gl_state.units[j].pointer_texcoord_gltype == (int)(GL_UNSIGNED_BYTE | 0x80000000))
+                                                               {
+                                                                       const GLubyte *sb = (const GLubyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
                                                                        if (gl_state.units[j].pointer_texcoord_components == 4)
                                                                                qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
                                                                        else if (gl_state.units[j].pointer_texcoord_components == 3)
@@ -3175,13 +3300,13 @@ void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t si
                return;
        if (buffer->isindexbuffer)
        {
-               r_refdef.stats.indexbufferuploadcount++;
-               r_refdef.stats.indexbufferuploadsize += size;
+               r_refdef.stats[r_stat_indexbufferuploadcount]++;
+               r_refdef.stats[r_stat_indexbufferuploadsize] += size;
        }
        else
        {
-               r_refdef.stats.vertexbufferuploadcount++;
-               r_refdef.stats.vertexbufferuploadsize += size;
+               r_refdef.stats[r_stat_vertexbufferuploadcount]++;
+               r_refdef.stats[r_stat_vertexbufferuploadsize] += size;
        }
        switch(vid.renderpath)
        {
@@ -3354,7 +3479,8 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void
                        gl_state.pointer_vertex_offset = bufferoffset;
                        CHECKGLERROR
                        GL_BindVBO(bufferobject);
-                       qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
+                       // LordHavoc: special flag added to gltype for unnormalized types
+                       qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                }
                break;
        case RENDERPATH_D3D9:
@@ -3436,7 +3562,8 @@ void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *
                                gl_state.pointer_color_offset = bufferoffset;
                                CHECKGLERROR
                                GL_BindVBO(bufferobject);
-                               qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
+                               // LordHavoc: special flag added to gltype for unnormalized types
+                               qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                        }
                }
                else
@@ -3531,7 +3658,8 @@ 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);
-                               qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
+                               // LordHavoc: special flag added to gltype for unnormalized types
+                               qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
                        }
                }
                else
@@ -4012,6 +4140,8 @@ D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
        {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f         ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
        {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f          ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
        {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
+       {0, (int)((size_t)&((r_vertexmesh_t *)0)->skeletalindex4ub  ), D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6},
+       {0, (int)((size_t)&((r_vertexmesh_t *)0)->skeletalweight4ub ), D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7},
        D3DDECL_END()
 };
 
@@ -4092,6 +4222,9 @@ void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, con
                        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
                {
@@ -4102,6 +4235,9 @@ void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, con
                        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);
                }
                break;
        case RENDERPATH_GL13:
@@ -4206,6 +4342,9 @@ void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3
                        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);
                        return;
                }
                break;
@@ -4286,6 +4425,9 @@ void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *ve
                        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
                {
@@ -4296,6 +4438,9 @@ void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *ve
                        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);
                }
                break;
        case RENDERPATH_GL13:
@@ -4400,6 +4545,9 @@ void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f,
                        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);
                        return;
                }
                break;
@@ -4491,6 +4639,9 @@ void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex,
                        R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(*vertex), vertex->tvector3f         , vertexbuffer, (int)((unsigned char *)vertex->tvector3f          - (unsigned char *)vertex));
                        R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(*vertex), vertex->normal3f          , vertexbuffer, (int)((unsigned char *)vertex->normal3f           - (unsigned char *)vertex));
                        R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
+                       R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(*vertex), NULL, NULL, 0);
+                       R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(*vertex), vertex->skeletalindex4ub  , vertexbuffer, (int)((unsigned char *)vertex->skeletalindex4ub   - (unsigned char *)vertex));
+                       R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->skeletalweight4ub , vertexbuffer, (int)((unsigned char *)vertex->skeletalweight4ub  - (unsigned char *)vertex));
                }
                else
                {
@@ -4501,6 +4652,9 @@ void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex,
                        R_Mesh_TexCoordPointer(2, 3, GL_FLOAT        , sizeof(*vertex), vertex->tvector3f         , NULL, 0);
                        R_Mesh_TexCoordPointer(3, 3, GL_FLOAT        , sizeof(*vertex), vertex->normal3f          , NULL, 0);
                        R_Mesh_TexCoordPointer(4, 2, GL_FLOAT        , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
+                       R_Mesh_TexCoordPointer(5, 2, GL_FLOAT        , sizeof(*vertex), NULL, NULL, 0);
+                       R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(*vertex), vertex->skeletalindex4ub  , NULL, 0);
+                       R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->skeletalweight4ub , NULL, 0);
                }
                break;
        case RENDERPATH_GL13: