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

smcv pushed a commit to annotated tag 1.42d
in repository iortcw.

commit b38bf35b7cbb1f23ef57f62ac7cd0a8469d3a08b
Author: m4n4t4...@gmail.com 
<m4n4t4...@gmail.com@e65d2741-a53d-b2dc-ae96-bb75fa5e4c4a>
Date:   Sun Nov 2 13:59:19 2014 +0000

    All: Rend2: Fix corrupt models
---
 MP/code/rend2/tr_glsl.c    |  56 -------------
 MP/code/rend2/tr_init.c    |  14 ++--
 MP/code/rend2/tr_local.h   |   3 +-
 MP/code/rend2/tr_model.c   | 200 ++++++++++++++++++++-------------------------
 MP/code/rend2/tr_shade.c   |   6 --
 MP/code/rend2/tr_surface.c |  61 +++++++++++---
 MP/code/rend2/tr_vbo.c     |  68 ++++++++++-----
 SP/code/rend2/tr_glsl.c    |  56 -------------
 SP/code/rend2/tr_init.c    |  16 ++--
 SP/code/rend2/tr_local.h   |   3 +-
 SP/code/rend2/tr_model.c   | 200 ++++++++++++++++++++-------------------------
 SP/code/rend2/tr_shade.c   |   6 --
 SP/code/rend2/tr_surface.c |  61 +++++++++++---
 SP/code/rend2/tr_vbo.c     |  68 ++++++++++-----
 14 files changed, 387 insertions(+), 431 deletions(-)

diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c
index 5a8cccd..ef2820a 100644
--- a/MP/code/rend2/tr_glsl.c
+++ b/MP/code/rend2/tr_glsl.c
@@ -1497,62 +1497,6 @@ void GLSL_BindNullProgram(void)
 }
 
 
-void GLSL_VertexAttribPointers(uint32_t attribBits)
-{
-       int newFrame, oldFrame;
-       vao_t *vao = glState.currentVao;
-       int attribIndex;
-       uint32_t extraOffsets[ATTR_INDEX_COUNT];
-
-       if(!vao)
-       {
-               ri.Error(ERR_FATAL, "GL_VertexAttribPointers: no VAO bound");
-               return;
-       }
-
-       // don't just call LogComment, or we will get a call to va() every 
frame!
-       if(r_logFile->integer)
-       {
-               GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", 
vao->name));
-       }
-
-       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
-               extraOffsets[attribIndex] = 0;
-
-       // position/normal/tangent are always set in case of animation
-       oldFrame = glState.vertexAttribsOldFrame;
-       newFrame = glState.vertexAttribsNewFrame;
-       if (glState.vertexAnimation)
-       {
-               extraOffsets[ATTR_INDEX_POSITION]  = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_POSITION2] = oldFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_NORMAL]    = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_NORMAL2]   = oldFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_TANGENT]   = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_TANGENT2]  = oldFrame * vao->frameSize;
-       }
-
-       // this may not be bound if we're using VAOs
-       if (glRefConfig.vertexArrayObject)
-       {
-               qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
-       }
-
-       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
-       {
-               uint32_t attribBit = 1 << attribIndex;
-               vaoAttrib_t *vAtb;
-
-               if (!(attribBits & attribBit))
-                       continue;
-
-               vAtb = &vao->attribs[attribIndex];
-
-               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + 
extraOffsets[attribIndex]));
-       }
-}
-
-
 shaderProgram_t *GLSL_GetGenericShaderProgram(int stage, glfog_t *glFog)
 {
        shaderStage_t *pStage = tess.xstages[stage];
diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c
index 8da6300..b85963f 100644
--- a/MP/code/rend2/tr_init.c
+++ b/MP/code/rend2/tr_init.c
@@ -1023,9 +1023,13 @@ void GL_SetDefaultState( void ) {
        glState.currentProgram = 0;
        qglUseProgramObjectARB(0);
 
+       if (glRefConfig.vertexArrayObject)
+               qglBindVertexArrayARB(0);
+
        qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
        glState.currentVao = NULL;
+       glState.vertexAttribsEnabled = 0;
 
        qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
        qglDepthMask( GL_TRUE );
@@ -1037,6 +1041,11 @@ void GL_SetDefaultState( void ) {
        if (glRefConfig.seamlessCubeMap)
                qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 
+       // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
+       qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
+
+       qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );        // FIXME: get color of 
sky
+
 //----(SA)     added.
        // ATI pn_triangles
        if ( qglPNTrianglesiATI ) {
@@ -1064,11 +1073,6 @@ void GL_SetDefaultState( void ) {
        }
 
 //----(SA)     end
-
-       // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
-       qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
-
-       qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );        // FIXME: get color of 
sky
 }
 
 /*
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index f5cf755..bf97a1d 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -1493,10 +1493,9 @@ typedef struct {
        int         faceCullFront;
        uint32_t    glStateBits;
        uint32_t    storedGlState;
-       uint32_t        vertexAttribsNewFrame;
-       uint32_t        vertexAttribsOldFrame;
        float           vertexAttribsInterpolation;
        qboolean        vertexAnimation;
+       uint32_t        vertexAttribsEnabled;  // global if no VAOs, tess only 
otherwise
        shaderProgram_t *currentProgram;
        FBO_t          *currentFBO;
        vao_t          *currentVao;
diff --git a/MP/code/rend2/tr_model.c b/MP/code/rend2/tr_model.c
index 0c925d5..dda845d 100644
--- a/MP/code/rend2/tr_model.c
+++ b/MP/code/rend2/tr_model.c
@@ -978,8 +978,8 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        {
                                st = surf->st;
                                for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
-                                       dataOfs += sizeof(st->st);
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
+                                       dataOfs += sizeof(vec2_t);
                                }
 
                                v = surf->verts;
@@ -992,8 +992,8 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
-                                       dataOfs += sizeof(v->xyz);
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
+                                       dataOfs += sizeof(vec3_t);
 
                                        // normal
                                        p = (uint32_t *)(data + dataOfs);
@@ -1025,11 +1025,11 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
                                        dataOfs += sizeof(st->st);
 
                                        // normal
@@ -1057,61 +1057,49 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        vaoSurf->numVerts = surf->numVerts;
                        
                        vaoSurf->minIndex = 0;
-                       vaoSurf->maxIndex = surf->numVerts;
+                       vaoSurf->maxIndex = surf->numVerts - 1;
 
                        vaoSurf->vao = R_CreateVao(va("staticMD3Mesh_VAO '%s'", 
surf->name), data, dataSize, (byte *)surf->indexes, surf->numIndexes * 
sizeof(*surf->indexes), VAO_USAGE_STATIC);
 
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].enabled = 1;
 #ifdef USE_VERT_TANGENT_SPACE
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
 #endif
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].enabled = 
1;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].count = 2;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].type = 
GL_FLOAT;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].normalized 
= GL_FALSE;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].offset = 
offset_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].offset = 
offset_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].offset = 
offset_tangent;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].stride = 
stride_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].stride = 
stride_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].stride = 
stride_tangent;
-
-                       vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].count = 4;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].normalized = 
GL_TRUE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].normalized = 
GL_TRUE;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].offset = 
offset_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].offset = 
offset_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].offset = 
offset_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].offset = 
offset_tangent;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].stride = 
stride_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].stride = 
stride_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].stride = 
stride_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].stride = 
stride_tangent;
+
+                       if (mdvModel->numFrames > 1)
+                       {
+                               vaoSurf->vao->attribs[ATTR_INDEX_POSITION2] = 
vaoSurf->vao->attribs[ATTR_INDEX_POSITION];
+                               vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2  ] = 
vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ];
+                               vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2 ] = 
vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ];
+
+                               vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       }
 
                        Vao_SetVertexPointers(vaoSurf->vao);
 
@@ -1498,8 +1486,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        {
                                st = surf->st;
                                for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
-                                       dataOfs += sizeof(st->st);
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
+                                       dataOfs += sizeof(vec2_t);
                                }
 
                                v = surf->verts;
@@ -1512,8 +1500,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
-                                       dataOfs += sizeof(v->xyz);
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
+                                       dataOfs += sizeof(vec3_t);
 
                                        // normal
                                        p = (uint32_t *)(data + dataOfs);
@@ -1545,11 +1533,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
                                        dataOfs += sizeof(st->st);
 
                                        // normal
@@ -1577,61 +1565,49 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        vaoSurf->numVerts = surf->numVerts;
                        
                        vaoSurf->minIndex = 0;
-                       vaoSurf->maxIndex = surf->numVerts;
+                       vaoSurf->maxIndex = surf->numVerts - 1;
 
                        vaoSurf->vao = R_CreateVao(va("staticMD3Mesh_VAO '%s'", 
surf->name), data, dataSize, (byte *)surf->indexes, surf->numIndexes * 
sizeof(*surf->indexes), VAO_USAGE_STATIC);
 
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].enabled = 1;
 #ifdef USE_VERT_TANGENT_SPACE
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
 #endif
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].enabled = 
1;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].count = 2;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].type = 
GL_FLOAT;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].normalized 
= GL_FALSE;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].offset = 
offset_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].offset = 
offset_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].offset = 
offset_tangent;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].stride = 
stride_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].stride = 
stride_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].stride = 
stride_tangent;
-
-                       vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].count = 4;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].normalized = 
GL_TRUE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].normalized = 
GL_TRUE;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].offset = 
offset_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].offset = 
offset_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].offset = 
offset_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].offset = 
offset_tangent;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].stride = 
stride_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].stride = 
stride_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].stride = 
stride_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].stride = 
stride_tangent;
+
+                       if (mdvModel->numFrames > 1)
+                       {
+                               vaoSurf->vao->attribs[ATTR_INDEX_POSITION2] = 
vaoSurf->vao->attribs[ATTR_INDEX_POSITION];
+                               vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2  ] = 
vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ];
+                               vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2 ] = 
vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ];
+
+                               vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       }
 
                        Vao_SetVertexPointers(vaoSurf->vao);
 
diff --git a/MP/code/rend2/tr_shade.c b/MP/code/rend2/tr_shade.c
index 20f8cac..07d2884 100644
--- a/MP/code/rend2/tr_shade.c
+++ b/MP/code/rend2/tr_shade.c
@@ -1667,12 +1667,6 @@ void RB_StageIteratorGeneric( void )
        }
 
        //
-       // Set vertex attribs and pointers
-       //
-       if (glState.vertexAnimation)
-               GLSL_VertexAttribPointers(vertexAttribs & (ATTR_POSITION | 
ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TANGENT | ATTR_TANGENT2));
-
-       //
        // render depth if in depthfill mode
        //
        if (backEnd.depthFill)
diff --git a/MP/code/rend2/tr_surface.c b/MP/code/rend2/tr_surface.c
index fab37a4..df5ae0c 100644
--- a/MP/code/rend2/tr_surface.c
+++ b/MP/code/rend2/tr_surface.c
@@ -1843,8 +1843,8 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
 
        tess.useInternalVao = qfalse;
 
-       tess.numIndexes += surface->numIndexes;
-       tess.numVertexes += surface->numVerts;
+       tess.numIndexes = surface->numIndexes;
+       tess.numVertexes = surface->numVerts;
        tess.minIndex = surface->minIndex;
        tess.maxIndex = surface->maxIndex;
 
@@ -1853,20 +1853,57 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
 
        refEnt = &backEnd.currentEntity->e;
 
-       if(refEnt->oldframe == refEnt->frame)
-       {
-               glState.vertexAttribsInterpolation = 0;
-       }
-       else
-       {
-               glState.vertexAttribsInterpolation = refEnt->backlerp;
-       }
+       glState.vertexAttribsInterpolation = (refEnt->oldframe == 
refEnt->frame) ? 0.0f : refEnt->backlerp;
 
-       glState.vertexAttribsOldFrame = refEnt->oldframe;
-       glState.vertexAttribsNewFrame = refEnt->frame;
        if (surface->mdvModel->numFrames > 1)
+       {
+               int frameOffset, attribIndex;
+               vaoAttrib_t *vAtb;
+
                glState.vertexAnimation = qtrue;
 
+               if (glRefConfig.vertexArrayObject)
+               {
+                       qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
surface->vao->vertexesVBO);
+               }
+
+               frameOffset    = refEnt->frame * surface->vao->frameSize;
+
+               attribIndex = ATTR_INDEX_POSITION;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_NORMAL;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_TANGENT;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               frameOffset = refEnt->oldframe * surface->vao->frameSize;
+
+               attribIndex = ATTR_INDEX_POSITION2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_NORMAL2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_TANGENT2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+
+               if (!glRefConfig.vertexArrayObject)
+               {
+                       attribIndex = ATTR_INDEX_TEXCOORD;
+                       vAtb = &surface->vao->attribs[attribIndex];
+                       qglVertexAttribPointerARB(attribIndex, vAtb->count, 
vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
+               }
+       }
+
        RB_EndSurface();
 
        // So we don't lerp surfaces that shouldn't be lerped
diff --git a/MP/code/rend2/tr_vbo.c b/MP/code/rend2/tr_vbo.c
index 5c44b0e..9734c5a 100644
--- a/MP/code/rend2/tr_vbo.c
+++ b/MP/code/rend2/tr_vbo.c
@@ -94,24 +94,32 @@ void R_VaoUnpackNormal(vec3_t v, uint32_t b)
 
 void Vao_SetVertexPointers(vao_t *vao)
 {
-       int i;
+       int attribIndex;
 
        // set vertex pointers
-       for (i = 0; i < ATTR_INDEX_COUNT; i++)
+       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
        {
-               if (vao->attribs[i].enabled)
+               uint32_t attribBit = 1 << attribIndex;
+               vaoAttrib_t *vAtb = &vao->attribs[attribIndex];
+
+               if (vAtb->enabled)
                {
-                       qglVertexAttribPointerARB((GLuint)i,
-                                                                 
(GLint)vao->attribs[i].count,
-                                                                 
(GLenum)vao->attribs[i].type, 
-                                                                 
(GLboolean)vao->attribs[i].normalized, 
-                                                                 
(GLsizei)vao->attribs[i].stride,
-                                                                 
BUFFER_OFFSET(vao->attribs[i].offset));
-                       qglEnableVertexAttribArrayARB(i);
+                       qglVertexAttribPointerARB(attribIndex, vAtb->count, 
vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
+                       if (glRefConfig.vertexArrayObject || 
!(glState.vertexAttribsEnabled & attribBit))
+                               qglEnableVertexAttribArrayARB(attribIndex);
+
+                       if (!glRefConfig.vertexArrayObject || vao == tess.vao)
+                               glState.vertexAttribsEnabled |= attribBit;
                }
                else
                {
-                       qglDisableVertexAttribArrayARB(i);
+                       // don't disable vertex attribs when using vertex array 
objects
+                       // Vao_SetVertexPointers is only called during init 
when using VAOs, and vertex attribs start disabled anyway
+                       if (!glRefConfig.vertexArrayObject && 
(glState.vertexAttribsEnabled & attribBit))
+                               qglDisableVertexAttribArrayARB(attribIndex);
+
+                       if (!glRefConfig.vertexArrayObject || vao == tess.vao)
+                               glState.vertexAttribsEnabled &= ~attribBit;
                }
        }
 }
@@ -386,8 +394,6 @@ void R_BindVao(vao_t * vao)
                glState.currentVao = vao;
 
                glState.vertexAttribsInterpolation = 0;
-               glState.vertexAttribsOldFrame = 0;
-               glState.vertexAttribsNewFrame = 0;
                glState.vertexAnimation = qfalse;
                backEnd.pc.c_vaoBinds++;
 
@@ -398,13 +404,19 @@ void R_BindVao(vao_t * vao)
                        // why you no save GL_ELEMENT_ARRAY_BUFFER binding, 
Intel?
                        if (1)
                                qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 
vao->indexesIBO);
+
+                       // tess VAO always has buffers bound
+                       if (vao == tess.vao)
+                               qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
vao->vertexesVBO);
                }
                else
                {
                        qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
                        qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
vao->indexesIBO);
 
-                       Vao_SetVertexPointers(vao);
+                       // tess VAO doesn't have vertex pointers set until data 
is uploaded
+                       if (vao != tess.vao)
+                               Vao_SetVertexPointers(vao);
                }
        }
 }
@@ -642,13 +654,6 @@ void RB_UpdateTessVao(unsigned int attribBits)
 
                R_BindVao(tess.vao);
 
-               // these may not be bound if we're using VAOs
-               if (glRefConfig.vertexArrayObject)
-               {
-                       qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
tess.vao->vertexesVBO);
-                       qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
tess.vao->indexesIBO);
-               }
-
                // orphan old vertex buffer so we don't stall on it
                qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vao->vertexesSize, 
NULL, GL_DYNAMIC_DRAW_ARB);
 
@@ -666,12 +671,31 @@ void RB_UpdateTessVao(unsigned int attribBits)
 
                for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; 
attribIndex++)
                {
-                       if (attribBits & (1 << attribIndex))
+                       uint32_t attribBit = 1 << attribIndex;
+
+                       if (attribBits & attribBit)
                        {
                                vaoAttrib_t *vAtb = 
&tess.vao->attribs[attribIndex];
 
                                // note: tess has a VBO where stride == size
                                qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 
vAtb->offset, tess.numVertexes * vAtb->stride, 
tess.attribPointers[attribIndex]);
+
+                               if (!glRefConfig.vertexArrayObject)
+                                       qglVertexAttribPointerARB(attribIndex, 
vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, 
BUFFER_OFFSET(vAtb->offset));
+
+                               if (!(glState.vertexAttribsEnabled & attribBit))
+                               {
+                                       
qglEnableVertexAttribArrayARB(attribIndex);
+                                       glState.vertexAttribsEnabled |= 
attribBit;
+                               }
+                       }
+                       else
+                       {
+                               if ((glState.vertexAttribsEnabled & attribBit))
+                               {
+                                       
qglDisableVertexAttribArrayARB(attribIndex);
+                                       glState.vertexAttribsEnabled &= 
~attribBit;
+                               }
                        }
                }
 
diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c
index 5a8cccd..ef2820a 100644
--- a/SP/code/rend2/tr_glsl.c
+++ b/SP/code/rend2/tr_glsl.c
@@ -1497,62 +1497,6 @@ void GLSL_BindNullProgram(void)
 }
 
 
-void GLSL_VertexAttribPointers(uint32_t attribBits)
-{
-       int newFrame, oldFrame;
-       vao_t *vao = glState.currentVao;
-       int attribIndex;
-       uint32_t extraOffsets[ATTR_INDEX_COUNT];
-
-       if(!vao)
-       {
-               ri.Error(ERR_FATAL, "GL_VertexAttribPointers: no VAO bound");
-               return;
-       }
-
-       // don't just call LogComment, or we will get a call to va() every 
frame!
-       if(r_logFile->integer)
-       {
-               GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", 
vao->name));
-       }
-
-       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
-               extraOffsets[attribIndex] = 0;
-
-       // position/normal/tangent are always set in case of animation
-       oldFrame = glState.vertexAttribsOldFrame;
-       newFrame = glState.vertexAttribsNewFrame;
-       if (glState.vertexAnimation)
-       {
-               extraOffsets[ATTR_INDEX_POSITION]  = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_POSITION2] = oldFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_NORMAL]    = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_NORMAL2]   = oldFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_TANGENT]   = newFrame * vao->frameSize;
-               extraOffsets[ATTR_INDEX_TANGENT2]  = oldFrame * vao->frameSize;
-       }
-
-       // this may not be bound if we're using VAOs
-       if (glRefConfig.vertexArrayObject)
-       {
-               qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
-       }
-
-       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
-       {
-               uint32_t attribBit = 1 << attribIndex;
-               vaoAttrib_t *vAtb;
-
-               if (!(attribBits & attribBit))
-                       continue;
-
-               vAtb = &vao->attribs[attribIndex];
-
-               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + 
extraOffsets[attribIndex]));
-       }
-}
-
-
 shaderProgram_t *GLSL_GetGenericShaderProgram(int stage, glfog_t *glFog)
 {
        shaderStage_t *pStage = tess.xstages[stage];
diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c
index 0f1aa2d..df826b2 100644
--- a/SP/code/rend2/tr_init.c
+++ b/SP/code/rend2/tr_init.c
@@ -1028,9 +1028,13 @@ void GL_SetDefaultState( void ) {
        glState.currentProgram = 0;
        qglUseProgramObjectARB(0);
 
+       if (glRefConfig.vertexArrayObject)
+               qglBindVertexArrayARB(0);
+
        qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
        glState.currentVao = NULL;
+       glState.vertexAttribsEnabled = 0;
 
        qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
        qglDepthMask( GL_TRUE );
@@ -1042,6 +1046,12 @@ void GL_SetDefaultState( void ) {
        if (glRefConfig.seamlessCubeMap)
                qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 
+       
+       // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
+       qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
+
+       qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );        // FIXME: get color of 
sky
+
 //----(SA)     added.
        // ATI pn_triangles
        if ( qglPNTrianglesiATI ) {
@@ -1067,13 +1077,7 @@ void GL_SetDefaultState( void ) {
                // set when rendering
 //        qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 
glConfig.maxAnisotropy);
        }
-
 //----(SA)     end
-
-       // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
-       qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
-
-       qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );        // FIXME: get color of 
sky
 }
 
 /*
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index bb7e721..35169aa 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -1506,10 +1506,9 @@ typedef struct {
        int         faceCullFront;
        uint32_t    glStateBits;
        uint32_t    storedGlState;
-       uint32_t        vertexAttribsNewFrame;
-       uint32_t        vertexAttribsOldFrame;
        float           vertexAttribsInterpolation;
        qboolean        vertexAnimation;
+       uint32_t        vertexAttribsEnabled;  // global if no VAOs, tess only 
otherwise
        shaderProgram_t *currentProgram;
        FBO_t          *currentFBO;
        vao_t          *currentVao;
diff --git a/SP/code/rend2/tr_model.c b/SP/code/rend2/tr_model.c
index ea8bebb..435915b 100644
--- a/SP/code/rend2/tr_model.c
+++ b/SP/code/rend2/tr_model.c
@@ -980,8 +980,8 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        {
                                st = surf->st;
                                for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
-                                       dataOfs += sizeof(st->st);
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
+                                       dataOfs += sizeof(vec2_t);
                                }
 
                                v = surf->verts;
@@ -994,8 +994,8 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
-                                       dataOfs += sizeof(v->xyz);
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
+                                       dataOfs += sizeof(vec3_t);
 
                                        // normal
                                        p = (uint32_t *)(data + dataOfs);
@@ -1027,11 +1027,11 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
                                        dataOfs += sizeof(st->st);
 
                                        // normal
@@ -1059,61 +1059,49 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        vaoSurf->numVerts = surf->numVerts;
                        
                        vaoSurf->minIndex = 0;
-                       vaoSurf->maxIndex = surf->numVerts;
+                       vaoSurf->maxIndex = surf->numVerts - 1;
 
                        vaoSurf->vao = R_CreateVao(va("staticMD3Mesh_VAO '%s'", 
surf->name), data, dataSize, (byte *)surf->indexes, surf->numIndexes * 
sizeof(*surf->indexes), VAO_USAGE_STATIC);
 
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].enabled = 1;
 #ifdef USE_VERT_TANGENT_SPACE
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
 #endif
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].enabled = 
1;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].count = 2;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].type = 
GL_FLOAT;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].normalized 
= GL_FALSE;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].offset = 
offset_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].offset = 
offset_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].offset = 
offset_tangent;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].stride = 
stride_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].stride = 
stride_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].stride = 
stride_tangent;
-
-                       vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].count = 4;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].normalized = 
GL_TRUE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].normalized = 
GL_TRUE;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].offset = 
offset_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].offset = 
offset_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].offset = 
offset_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].offset = 
offset_tangent;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].stride = 
stride_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].stride = 
stride_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].stride = 
stride_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].stride = 
stride_tangent;
+
+                       if (mdvModel->numFrames > 1)
+                       {
+                               vaoSurf->vao->attribs[ATTR_INDEX_POSITION2] = 
vaoSurf->vao->attribs[ATTR_INDEX_POSITION];
+                               vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2  ] = 
vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ];
+                               vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2 ] = 
vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ];
+
+                               vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       }
 
                        Vao_SetVertexPointers(vaoSurf->vao);
 
@@ -1500,8 +1488,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        {
                                st = surf->st;
                                for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
-                                       dataOfs += sizeof(st->st);
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
+                                       dataOfs += sizeof(vec2_t);
                                }
 
                                v = surf->verts;
@@ -1514,8 +1502,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
-                                       dataOfs += sizeof(v->xyz);
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
+                                       dataOfs += sizeof(vec3_t);
 
                                        // normal
                                        p = (uint32_t *)(data + dataOfs);
@@ -1547,11 +1535,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        uint32_t *p;
 
                                        // xyz
-                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(v->xyz));
+                                       memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(st->st));
+                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
                                        dataOfs += sizeof(st->st);
 
                                        // normal
@@ -1579,61 +1567,49 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        vaoSurf->numVerts = surf->numVerts;
                        
                        vaoSurf->minIndex = 0;
-                       vaoSurf->maxIndex = surf->numVerts;
+                       vaoSurf->maxIndex = surf->numVerts - 1;
 
                        vaoSurf->vao = R_CreateVao(va("staticMD3Mesh_VAO '%s'", 
surf->name), data, dataSize, (byte *)surf->indexes, surf->numIndexes * 
sizeof(*surf->indexes), VAO_USAGE_STATIC);
 
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].enabled = 1;
 #ifdef USE_VERT_TANGENT_SPACE
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].enabled = 
1;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].enabled = 
1;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
 #endif
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].enabled = 
1;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].count = 3;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].count = 4;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].count = 2;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].type = 
GL_FLOAT;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].type = 
glRefConfig.packedNormalDataType;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].type = 
GL_FLOAT;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].normalized 
= GL_FALSE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].normalized 
= GL_TRUE;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].normalized 
= GL_FALSE;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].offset = 
offset_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].offset = 
offset_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].offset = 
offset_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].offset = 
offset_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].offset = 
offset_tangent;
-
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION  ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION2 ].stride = 
stride_xyz;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD  ].stride = 
stride_st;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL    ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2   ].stride = 
stride_normal;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT   ].stride = 
stride_tangent;
-                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2  ].stride = 
stride_tangent;
-
-                       vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].count = 4;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = 
GL_FLOAT;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = 
GL_FALSE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].normalized = 
GL_TRUE;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].normalized = 
GL_TRUE;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].offset = 
offset_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].offset = 
offset_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].offset = 
offset_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].offset = 
offset_tangent;
+
+                       vaoSurf->vao->attribs[ATTR_INDEX_POSITION].stride = 
stride_xyz;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].stride = 
stride_st;
+                       vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].stride = 
stride_normal;
+                       vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].stride = 
stride_tangent;
+
+                       if (mdvModel->numFrames > 1)
+                       {
+                               vaoSurf->vao->attribs[ATTR_INDEX_POSITION2] = 
vaoSurf->vao->attribs[ATTR_INDEX_POSITION];
+                               vaoSurf->vao->attribs[ATTR_INDEX_NORMAL2  ] = 
vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ];
+                               vaoSurf->vao->attribs[ATTR_INDEX_TANGENT2 ] = 
vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ];
+
+                               vaoSurf->vao->frameSize = stride_xyz    * 
surf->numVerts;
+                       }
 
                        Vao_SetVertexPointers(vaoSurf->vao);
 
diff --git a/SP/code/rend2/tr_shade.c b/SP/code/rend2/tr_shade.c
index 3dcad5b..bb0f78b 100644
--- a/SP/code/rend2/tr_shade.c
+++ b/SP/code/rend2/tr_shade.c
@@ -1668,12 +1668,6 @@ void RB_StageIteratorGeneric( void )
        }
 
        //
-       // Set vertex attribs and pointers
-       //
-       if (glState.vertexAnimation)
-               GLSL_VertexAttribPointers(vertexAttribs & (ATTR_POSITION | 
ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TANGENT | ATTR_TANGENT2));
-
-       //
        // render depth if in depthfill mode
        //
        if (backEnd.depthFill)
diff --git a/SP/code/rend2/tr_surface.c b/SP/code/rend2/tr_surface.c
index 429fb89..f3afa01 100644
--- a/SP/code/rend2/tr_surface.c
+++ b/SP/code/rend2/tr_surface.c
@@ -1840,8 +1840,8 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
 
        tess.useInternalVao = qfalse;
 
-       tess.numIndexes += surface->numIndexes;
-       tess.numVertexes += surface->numVerts;
+       tess.numIndexes = surface->numIndexes;
+       tess.numVertexes = surface->numVerts;
        tess.minIndex = surface->minIndex;
        tess.maxIndex = surface->maxIndex;
 
@@ -1850,20 +1850,57 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
 
        refEnt = &backEnd.currentEntity->e;
 
-       if(refEnt->oldframe == refEnt->frame)
-       {
-               glState.vertexAttribsInterpolation = 0;
-       }
-       else
-       {
-               glState.vertexAttribsInterpolation = refEnt->backlerp;
-       }
+       glState.vertexAttribsInterpolation = (refEnt->oldframe == 
refEnt->frame) ? 0.0f : refEnt->backlerp;
 
-       glState.vertexAttribsOldFrame = refEnt->oldframe;
-       glState.vertexAttribsNewFrame = refEnt->frame;
        if (surface->mdvModel->numFrames > 1)
+       {
+               int frameOffset, attribIndex;
+               vaoAttrib_t *vAtb;
+
                glState.vertexAnimation = qtrue;
 
+               if (glRefConfig.vertexArrayObject)
+               {
+                       qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
surface->vao->vertexesVBO);
+               }
+
+               frameOffset    = refEnt->frame * surface->vao->frameSize;
+
+               attribIndex = ATTR_INDEX_POSITION;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_NORMAL;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_TANGENT;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               frameOffset = refEnt->oldframe * surface->vao->frameSize;
+
+               attribIndex = ATTR_INDEX_POSITION2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_NORMAL2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+               attribIndex = ATTR_INDEX_TANGENT2;
+               vAtb = &surface->vao->attribs[attribIndex];
+               qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, 
vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
+
+
+               if (!glRefConfig.vertexArrayObject)
+               {
+                       attribIndex = ATTR_INDEX_TEXCOORD;
+                       vAtb = &surface->vao->attribs[attribIndex];
+                       qglVertexAttribPointerARB(attribIndex, vAtb->count, 
vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
+               }
+       }
+
        RB_EndSurface();
 
        // So we don't lerp surfaces that shouldn't be lerped
diff --git a/SP/code/rend2/tr_vbo.c b/SP/code/rend2/tr_vbo.c
index 5c44b0e..9734c5a 100644
--- a/SP/code/rend2/tr_vbo.c
+++ b/SP/code/rend2/tr_vbo.c
@@ -94,24 +94,32 @@ void R_VaoUnpackNormal(vec3_t v, uint32_t b)
 
 void Vao_SetVertexPointers(vao_t *vao)
 {
-       int i;
+       int attribIndex;
 
        // set vertex pointers
-       for (i = 0; i < ATTR_INDEX_COUNT; i++)
+       for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++)
        {
-               if (vao->attribs[i].enabled)
+               uint32_t attribBit = 1 << attribIndex;
+               vaoAttrib_t *vAtb = &vao->attribs[attribIndex];
+
+               if (vAtb->enabled)
                {
-                       qglVertexAttribPointerARB((GLuint)i,
-                                                                 
(GLint)vao->attribs[i].count,
-                                                                 
(GLenum)vao->attribs[i].type, 
-                                                                 
(GLboolean)vao->attribs[i].normalized, 
-                                                                 
(GLsizei)vao->attribs[i].stride,
-                                                                 
BUFFER_OFFSET(vao->attribs[i].offset));
-                       qglEnableVertexAttribArrayARB(i);
+                       qglVertexAttribPointerARB(attribIndex, vAtb->count, 
vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
+                       if (glRefConfig.vertexArrayObject || 
!(glState.vertexAttribsEnabled & attribBit))
+                               qglEnableVertexAttribArrayARB(attribIndex);
+
+                       if (!glRefConfig.vertexArrayObject || vao == tess.vao)
+                               glState.vertexAttribsEnabled |= attribBit;
                }
                else
                {
-                       qglDisableVertexAttribArrayARB(i);
+                       // don't disable vertex attribs when using vertex array 
objects
+                       // Vao_SetVertexPointers is only called during init 
when using VAOs, and vertex attribs start disabled anyway
+                       if (!glRefConfig.vertexArrayObject && 
(glState.vertexAttribsEnabled & attribBit))
+                               qglDisableVertexAttribArrayARB(attribIndex);
+
+                       if (!glRefConfig.vertexArrayObject || vao == tess.vao)
+                               glState.vertexAttribsEnabled &= ~attribBit;
                }
        }
 }
@@ -386,8 +394,6 @@ void R_BindVao(vao_t * vao)
                glState.currentVao = vao;
 
                glState.vertexAttribsInterpolation = 0;
-               glState.vertexAttribsOldFrame = 0;
-               glState.vertexAttribsNewFrame = 0;
                glState.vertexAnimation = qfalse;
                backEnd.pc.c_vaoBinds++;
 
@@ -398,13 +404,19 @@ void R_BindVao(vao_t * vao)
                        // why you no save GL_ELEMENT_ARRAY_BUFFER binding, 
Intel?
                        if (1)
                                qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 
vao->indexesIBO);
+
+                       // tess VAO always has buffers bound
+                       if (vao == tess.vao)
+                               qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
vao->vertexesVBO);
                }
                else
                {
                        qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
                        qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
vao->indexesIBO);
 
-                       Vao_SetVertexPointers(vao);
+                       // tess VAO doesn't have vertex pointers set until data 
is uploaded
+                       if (vao != tess.vao)
+                               Vao_SetVertexPointers(vao);
                }
        }
 }
@@ -642,13 +654,6 @@ void RB_UpdateTessVao(unsigned int attribBits)
 
                R_BindVao(tess.vao);
 
-               // these may not be bound if we're using VAOs
-               if (glRefConfig.vertexArrayObject)
-               {
-                       qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 
tess.vao->vertexesVBO);
-                       qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
tess.vao->indexesIBO);
-               }
-
                // orphan old vertex buffer so we don't stall on it
                qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vao->vertexesSize, 
NULL, GL_DYNAMIC_DRAW_ARB);
 
@@ -666,12 +671,31 @@ void RB_UpdateTessVao(unsigned int attribBits)
 
                for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; 
attribIndex++)
                {
-                       if (attribBits & (1 << attribIndex))
+                       uint32_t attribBit = 1 << attribIndex;
+
+                       if (attribBits & attribBit)
                        {
                                vaoAttrib_t *vAtb = 
&tess.vao->attribs[attribIndex];
 
                                // note: tess has a VBO where stride == size
                                qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 
vAtb->offset, tess.numVertexes * vAtb->stride, 
tess.attribPointers[attribIndex]);
+
+                               if (!glRefConfig.vertexArrayObject)
+                                       qglVertexAttribPointerARB(attribIndex, 
vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, 
BUFFER_OFFSET(vAtb->offset));
+
+                               if (!(glState.vertexAttribsEnabled & attribBit))
+                               {
+                                       
qglEnableVertexAttribArrayARB(attribIndex);
+                                       glState.vertexAttribsEnabled |= 
attribBit;
+                               }
+                       }
+                       else
+                       {
+                               if ((glState.vertexAttribsEnabled & attribBit))
+                               {
+                                       
qglDisableVertexAttribArrayARB(attribIndex);
+                                       glState.vertexAttribsEnabled &= 
~attribBit;
+                               }
                        }
                }
 

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

_______________________________________________
Pkg-games-commits mailing list
Pkg-games-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

Reply via email to