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 62de750f94ea2593040299e2fb9fac9398339bbb
Author: m4n4t4...@gmail.com 
<m4n4t4...@gmail.com@e65d2741-a53d-b2dc-ae96-bb75fa5e4c4a>
Date:   Wed Nov 5 23:19:33 2014 +0000

    All: Rend2: Support half floats for texcoords and vertex colors
---
 MP/code/rend2/tr_animation.c  |   4 +-
 MP/code/rend2/tr_extensions.c |  27 +++++-
 MP/code/rend2/tr_extramath.c  |  61 ++++++--------
 MP/code/rend2/tr_init.c       |   2 +
 MP/code/rend2/tr_local.h      |  11 ++-
 MP/code/rend2/tr_model.c      |  68 +++++----------
 MP/code/rend2/tr_model_iqm.c  |   4 +-
 MP/code/rend2/tr_shade_calc.c |   2 +-
 MP/code/rend2/tr_surface.c    |  24 +++---
 MP/code/rend2/tr_vbo.c        | 186 ++++++++++++++++++++++++------------------
 SP/code/rend2/tr_animation.c  |   4 +-
 SP/code/rend2/tr_extensions.c |  27 +++++-
 SP/code/rend2/tr_extramath.c  |  61 ++++++--------
 SP/code/rend2/tr_init.c       |   2 +
 SP/code/rend2/tr_local.h      |  11 ++-
 SP/code/rend2/tr_model.c      |  68 +++++----------
 SP/code/rend2/tr_model_iqm.c  |   4 +-
 SP/code/rend2/tr_shade_calc.c |   2 +-
 SP/code/rend2/tr_surface.c    |  24 +++---
 SP/code/rend2/tr_vbo.c        | 186 ++++++++++++++++++++++++------------------
 20 files changed, 414 insertions(+), 364 deletions(-)

diff --git a/MP/code/rend2/tr_animation.c b/MP/code/rend2/tr_animation.c
index f912366..4a26f4e 100644
--- a/MP/code/rend2/tr_animation.c
+++ b/MP/code/rend2/tr_animation.c
@@ -1187,7 +1187,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) {
 
                LocalMatrixTransformVector( v->normal, 
bones[v->weights[0].boneIndex].matrix, newNormal );
                
-               *tempNormal = R_VaoPackNormal(newNormal);
+               R_VaoPackNormal((byte *)tempNormal, newNormal);
 
                tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
                tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
@@ -1756,7 +1756,7 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface )
                tess.xyz[baseVertex + j][1] = tempVert[1];
                tess.xyz[baseVertex + j][2] = tempVert[2];
 
-               tess.normal[baseVertex + j] = R_VaoPackNormal(tempNormal);
+               R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], 
tempNormal);
 
                tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
                tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
diff --git a/MP/code/rend2/tr_extensions.c b/MP/code/rend2/tr_extensions.c
index b770e6c..c0f4d04 100644
--- a/MP/code/rend2/tr_extensions.c
+++ b/MP/code/rend2/tr_extensions.c
@@ -33,8 +33,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
02110-1301  USA
 void            (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint 
start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
 
 // GL_EXT_multi_draw_arrays
-void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, 
const GLsizei *count, GLsizei primcount);
-void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, 
GLenum type, const GLvoid* *indices, GLsizei primcount);
+void            (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint 
*first, const GLsizei *count, GLsizei primcount);
+void            (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const 
GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
 
 // GL_ARB_vertex_shader
 void            (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, 
GLuint index, const GLcharARB * name);
@@ -709,4 +709,27 @@ void GLimp_InitExtraExtensions()
                ri.Printf(PRINT_ALL, result[2], extension);
        }
 
+       // GL_ARB_half_float_vertex
+       extension = "GL_ARB_half_float_vertex";
+       glRefConfig.packedTexcoordDataType = GL_FLOAT;
+       glRefConfig.packedTexcoordDataSize = sizeof(float) * 2;
+       glRefConfig.packedColorDataType    = GL_FLOAT;
+       glRefConfig.packedColorDataSize    = sizeof(float) * 4;
+       if( GLimp_HaveExtension( extension ) )
+       {
+               if (r_arb_half_float_vertex->integer)
+               {
+                       glRefConfig.packedTexcoordDataType = GL_HALF_FLOAT;
+                       glRefConfig.packedTexcoordDataSize = sizeof(uint16_t) * 
2;
+                       glRefConfig.packedColorDataType    = GL_HALF_FLOAT;
+                       glRefConfig.packedColorDataSize    = sizeof(uint16_t) * 
4;
+               }
+
+               ri.Printf(PRINT_ALL, result[r_arb_half_float_vertex->integer ? 
1 : 0], extension);
+       }
+       else
+       {
+               ri.Printf(PRINT_ALL, result[2], extension);
+       }
+
 }
diff --git a/MP/code/rend2/tr_extramath.c b/MP/code/rend2/tr_extramath.c
index b844678..da9a94d 100644
--- a/MP/code/rend2/tr_extramath.c
+++ b/MP/code/rend2/tr_extramath.c
@@ -199,42 +199,35 @@ int NextPowerOfTwo(int in)
        return out;
 }
 
-unsigned short FloatToHalf(float in)
-{
-       unsigned short out;
-       
-       union
-       {
-               float f;
-               unsigned int i;
-       } f32;
-
-       int sign, inExponent, inFraction;
-       int outExponent, outFraction;
+union f32_u {
+       float f;
+       uint32_t i;
+       struct {
+               unsigned int fraction:23;
+               unsigned int exponent:8;
+               unsigned int sign:1;
+       } pack;
+};
+
+union f16_u {
+       uint16_t i;
+       struct {
+               unsigned int fraction:10;
+               unsigned int exponent:5;
+               unsigned int sign:1;
+       } pack;
+};
+
+uint16_t FloatToHalf(float in)
+{
+       union f32_u f32;
+       union f16_u f16;
 
        f32.f = in;
 
-       sign       = (f32.i & 0x80000000) >> 31;
-       inExponent = (f32.i & 0x7F800000) >> 23;
-       inFraction =  f32.i & 0x007FFFFF;
-
-       outExponent = CLAMP(inExponent - 127, -15, 16) + 15;
-
-       outFraction = 0;
-       if (outExponent == 0x1F)
-       {
-               if (inExponent == 0xFF && inFraction != 0)
-                       outFraction = 0x3FF;
-       }
-       else if (outExponent == 0x00)
-       {
-               if (inExponent == 0x00 && inFraction != 0)
-                       outFraction = 0x3FF;
-       }
-       else
-               outFraction = inFraction >> 13;
-
-       out = (sign << 15) | (outExponent << 10) | outFraction;
+       f16.pack.exponent = CLAMP(f32.pack.exponent - 112, 0, 31);
+       f16.pack.fraction = f32.pack.fraction >> 13;
+       f16.pack.sign     = f32.pack.sign;
 
-       return out;
+       return f16.i;
 }
diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c
index b85963f..a3bf09e 100644
--- a/MP/code/rend2/tr_init.c
+++ b/MP/code/rend2/tr_init.c
@@ -121,6 +121,7 @@ cvar_t  *r_ext_multi_draw_arrays;
 cvar_t  *r_ext_framebuffer_object;
 cvar_t  *r_ext_texture_float;
 cvar_t  *r_arb_half_float_pixel;
+cvar_t  *r_arb_half_float_vertex;
 cvar_t  *r_ext_framebuffer_multisample;
 cvar_t  *r_arb_seamless_cube_map;
 cvar_t  *r_arb_vertex_type_2_10_10_10_rev;
@@ -1255,6 +1256,7 @@ void R_Register( void ) {
        r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", 
"1", CVAR_ARCHIVE | CVAR_LATCH);
        r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
+       r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_ext_framebuffer_multisample = ri.Cvar_Get( 
"r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( 
"r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH);
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index bf97a1d..96c70a1 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -1545,6 +1545,10 @@ typedef struct {
        qboolean seamlessCubeMap;
 
        GLenum packedNormalDataType;
+       GLenum packedTexcoordDataType;
+       GLenum packedColorDataType;
+       int packedTexcoordDataSize;
+       int packedColorDataSize;
 
        qboolean floatLightmap;
        qboolean vertexArrayObject;
@@ -1890,6 +1894,7 @@ extern  cvar_t  *r_ext_multi_draw_arrays;
 extern  cvar_t  *r_ext_framebuffer_object;
 extern  cvar_t  *r_ext_texture_float;
 extern  cvar_t  *r_arb_half_float_pixel;
+extern  cvar_t  *r_arb_half_float_vertex;
 extern  cvar_t  *r_ext_framebuffer_multisample;
 extern  cvar_t  *r_arb_seamless_cube_map;
 extern  cvar_t  *r_arb_vertex_type_2_10_10_10_rev;
@@ -2415,8 +2420,10 @@ VERTEX BUFFER OBJECTS
 ============================================================
 */
 
-uint32_t R_VaoPackTangent(vec4_t v);
-uint32_t R_VaoPackNormal(vec3_t v);
+int R_VaoPackTangent(byte *out, vec4_t v);
+int R_VaoPackNormal(byte *out, vec3_t v);
+int R_VaoPackTexCoord(byte *out, vec2_t st);
+int R_VaoPackColors(byte *out, vec4_t color);
 void R_VaoUnpackTangent(vec4_t v, uint32_t b);
 void R_VaoUnpackNormal(vec3_t v, uint32_t b);
 
diff --git a/MP/code/rend2/tr_model.c b/MP/code/rend2/tr_model.c
index dda845d..876a487 100644
--- a/MP/code/rend2/tr_model.c
+++ b/MP/code/rend2/tr_model.c
@@ -941,10 +941,10 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        {
                                // vertex animation, store texcoords first, 
then position/normal/tangents
                                offset_st      = 0;
-                               offset_xyz     = surf->numVerts * 
sizeof(vec2_t);
+                               offset_xyz     = surf->numVerts * 
glRefConfig.packedTexcoordDataSize;
                                offset_normal  = offset_xyz + sizeof(vec3_t);
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
-                               stride_st  = sizeof(vec2_t);
+                               stride_st  = glRefConfig.packedTexcoordDataSize;
                                stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz += sizeof(uint32_t);
@@ -958,7 +958,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                // no animation, interleave everything
                                offset_xyz     = 0;
                                offset_st      = offset_xyz + sizeof(vec3_t);
-                               offset_normal  = offset_st + sizeof(vec2_t);
+                               offset_normal  = offset_st + 
glRefConfig.packedTexcoordDataSize;
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz = offset_tangent + sizeof(uint32_t);
@@ -978,8 +978,7 @@ 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(vec2_t));
-                                       dataOfs += sizeof(vec2_t);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
                                }
 
                                v = surf->verts;
@@ -989,16 +988,12 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(vec3_t);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1006,9 +1001,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1022,20 +1015,15 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
-                                       dataOfs += sizeof(st->st);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1043,9 +1031,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1073,7 +1059,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        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_TEXCOORD].type = 
glRefConfig.packedTexcoordDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
 
@@ -1449,10 +1435,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        {
                                // vertex animation, store texcoords first, 
then position/normal/tangents
                                offset_st      = 0;
-                               offset_xyz     = surf->numVerts * 
sizeof(vec2_t);
+                               offset_xyz     = surf->numVerts * 
glRefConfig.packedTexcoordDataSize;
                                offset_normal  = offset_xyz + sizeof(vec3_t);
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
-                               stride_st  = sizeof(vec2_t);
+                               stride_st  = glRefConfig.packedTexcoordDataSize;
                                stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz += sizeof(uint32_t);
@@ -1466,7 +1452,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                // no animation, interleave everything
                                offset_xyz     = 0;
                                offset_st      = offset_xyz + sizeof(vec3_t);
-                               offset_normal  = offset_st + sizeof(vec2_t);
+                               offset_normal  = offset_st + 
glRefConfig.packedTexcoordDataSize;
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz = offset_tangent + sizeof(uint32_t);
@@ -1486,8 +1472,7 @@ 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(vec2_t));
-                                       dataOfs += sizeof(vec2_t);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
                                }
 
                                v = surf->verts;
@@ -1497,16 +1482,12 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(vec3_t);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1514,9 +1495,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1530,20 +1509,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
-                                       dataOfs += sizeof(st->st);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1551,9 +1525,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1581,7 +1553,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        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_TEXCOORD].type = 
glRefConfig.packedTexcoordDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
 
diff --git a/MP/code/rend2/tr_model_iqm.c b/MP/code/rend2/tr_model_iqm.c
index 79ac510..6095a39 100644
--- a/MP/code/rend2/tr_model_iqm.c
+++ b/MP/code/rend2/tr_model_iqm.c
@@ -1130,7 +1130,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
                        normal[1] = DotProduct(&nrmMat[3], 
&data->normals[3*vtx]);
                        normal[2] = DotProduct(&nrmMat[6], 
&data->normals[3*vtx]);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                        tangent[0] = DotProduct(&nrmMat[0], 
&data->tangents[4*vtx]);
@@ -1138,7 +1138,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
                        tangent[2] = DotProduct(&nrmMat[6], 
&data->tangents[4*vtx]);
                        tangent[3] = data->tangents[4*vtx+3];
 
-                       *outTangent++ = R_VaoPackTangent(tangent);
+                       R_VaoPackTangent((byte *)outTangent++, tangent);
 #endif
                }
 
diff --git a/MP/code/rend2/tr_shade_calc.c b/MP/code/rend2/tr_shade_calc.c
index cb96aa0..7d6ab09 100644
--- a/MP/code/rend2/tr_shade_calc.c
+++ b/MP/code/rend2/tr_shade_calc.c
@@ -244,7 +244,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
 
                VectorNormalizeFast( fNormal );
 
-               *normal = R_VaoPackNormal(fNormal);
+               R_VaoPackNormal((byte *)normal, fNormal);
        }
 }
 
diff --git a/MP/code/rend2/tr_surface.c b/MP/code/rend2/tr_surface.c
index df5ae0c..d22cc2c 100644
--- a/MP/code/rend2/tr_surface.c
+++ b/MP/code/rend2/tr_surface.c
@@ -94,6 +94,7 @@ RB_AddQuadStampExt
 */
 void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float 
color[4], float s1, float t1, float s2, float t2 ) {
        vec3_t normal;
+       uint32_t    pNormal;
        int ndx;
 
        RB_CHECKOVERFLOW( 4, 6 );
@@ -129,10 +130,11 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, 
vec3_t up, float color[4],
        // constant normal all the way around
        VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
 
+       R_VaoPackNormal((byte *)&pNormal, normal);
        tess.normal[ndx] =
        tess.normal[ndx+1] =
        tess.normal[ndx+2] =
-       tess.normal[ndx+3] = R_VaoPackNormal(normal);
+       tess.normal[ndx+3] = pNormal;
 
        // standard square texture coordinates
        VectorSet2(tess.texCoords[ndx  ][0], s1, t1);
@@ -374,7 +376,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                normal = &tess.normal[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
-                       *normal = R_VaoPackNormal(dv->normal);
+                       R_VaoPackNormal((byte *)normal, dv->normal);
        }
 
 #ifdef USE_VERT_TANGENT_SPACE
@@ -383,7 +385,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                tangent = &tess.tangent[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
-                       *tangent = R_VaoPackTangent(dv->tangent);
+                       R_VaoPackTangent((byte *)tangent, dv->tangent);
        }
 #endif
 
@@ -416,7 +418,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                lightdir = &tess.lightdir[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
-                       *lightdir = R_VaoPackNormal(dv->lightdir);
+                       R_VaoPackNormal((byte *)lightdir, dv->lightdir);
        }
 
 #if 0  // nothing even uses vertex dlightbits
@@ -1172,7 +1174,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, 
float backlerp)
                        VectorCopy(newVerts->xyz,    outXyz);
                        VectorCopy(newVerts->normal, normal);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
                        newVerts++;
                        outXyz += 4;
@@ -1197,7 +1199,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, 
float backlerp)
                        VectorLerp(newVerts->normal, oldVerts->normal, 
backlerp, normal);
                        VectorNormalize(normal);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
                        newVerts++;
                        oldVerts++;
@@ -1364,7 +1366,7 @@ static void LerpCMeshVertexes( mdcSurface_t *surf, float 
backlerp ) {
                                fNormal[2] = tr.sinTable[( lng + ( 
FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
                        }
 
-                       *outNormal = R_VaoPackNormal(fNormal);
+                       R_VaoPackNormal((byte *)outNormal, fNormal);
                }
        } else {
                //
@@ -1434,7 +1436,7 @@ static void LerpCMeshVertexes( mdcSurface_t *surf, float 
backlerp ) {
 
                        VectorNormalize( fNormal );
                        
-                       *outNormal = R_VaoPackNormal(fNormal);
+                       R_VaoPackNormal((byte *)outNormal, fNormal);
                }
        }
 }
@@ -1662,13 +1664,13 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
 
                                if ( tess.shader->vertexAttribs & ATTR_NORMAL )
                                {
-                                       *normal++ = R_VaoPackNormal(dv->normal);
+                                       R_VaoPackNormal((byte *)normal++, 
dv->normal);
                                }
 
 #ifdef USE_VERT_TANGENT_SPACE
                                if ( tess.shader->vertexAttribs & ATTR_TANGENT )
                                {
-                                       *tangent++ = 
R_VaoPackTangent(dv->tangent);
+                                       R_VaoPackTangent((byte *)tangent++, 
dv->tangent);
                                }
 #endif
 
@@ -1692,7 +1694,7 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
 
                                if ( tess.shader->vertexAttribs & 
ATTR_LIGHTDIRECTION )
                                {
-                                       *lightdir++ = 
R_VaoPackNormal(dv->lightdir);
+                                       R_VaoPackNormal((byte *)lightdir++, 
dv->lightdir);
                                }
 
                                //*vDlightBits++ = dlightBits;
diff --git a/MP/code/rend2/tr_vbo.c b/MP/code/rend2/tr_vbo.c
index 981741f..8f9ba66 100644
--- a/MP/code/rend2/tr_vbo.c
+++ b/MP/code/rend2/tr_vbo.c
@@ -44,81 +44,122 @@ union pack8_u {
 };
 
 
-uint32_t R_VaoPackTangent(vec4_t v)
+int R_VaoPackTangent(byte *out, vec4_t v)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)out;
 
-               num.pack.x = v[0] * 511.0f;
-               num.pack.y = v[1] * 511.0f;
-               num.pack.z = v[2] * 511.0f;
-               num.pack.w = v[3];
+               num->pack.x = v[0] * 511.0f;
+               num->pack.y = v[1] * 511.0f;
+               num->pack.z = v[2] * 511.0f;
+               num->pack.w = v[3];
+       }
+       else
+       {
+               union pack8_u *num = (union pack8_u *)out;
+
+               num->pack.x = v[0] * 127.0f;
+               num->pack.y = v[1] * 127.0f;
+               num->pack.z = v[2] * 127.0f;
+               num->pack.w = v[3] * 127.0f;
+       }
+
+       return 4;
+}
+
+int R_VaoPackNormal(byte *out, vec3_t v)
+{
+       if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
+       {
+               union pack10_u *num = (union pack10_u *)out;
+
+               num->pack.x = v[0] * 511.0f;
+               num->pack.y = v[1] * 511.0f;
+               num->pack.z = v[2] * 511.0f;
+               num->pack.w = 0;
+       }
+       else
+       {
+               union pack8_u *num = (union pack8_u *)out;
 
-               return num.i;
+               num->pack.x = v[0] * 127.0f;
+               num->pack.y = v[1] * 127.0f;
+               num->pack.z = v[2] * 127.0f;
+               num->pack.w = 0;
+       }
+
+       return 4;
+}
+
+int R_VaoPackTexCoord(byte *out, vec2_t st)
+{
+       if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
+       {
+               uint16_t *num = (uint16_t *)out;
+
+               *num++ = FloatToHalf(st[0]);
+               *num++ = FloatToHalf(st[1]);
+
+               return sizeof(*num) * 2;
        }
        else
        {
-               union pack8_u num;
+               float *num = (float *)out;
 
-               num.pack.x = v[0] * 127.0f;
-               num.pack.y = v[1] * 127.0f;
-               num.pack.z = v[2] * 127.0f;
-               num.pack.w = v[3] * 127.0f;
+               *num++ = st[0];
+               *num++ = st[1];
 
-               return num.i;
+               return sizeof(*num) * 2;
        }
 }
 
-uint32_t R_VaoPackNormal(vec3_t v)
+int R_VaoPackColors(byte *out, vec4_t color)
 {
-       if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
+       if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
        {
-               union pack10_u num;
+               uint16_t *num = (uint16_t *)out;
 
-               num.pack.x = v[0] * 511.0f;
-               num.pack.y = v[1] * 511.0f;
-               num.pack.z = v[2] * 511.0f;
-               num.pack.w = 0;
+               *num++ = FloatToHalf(color[0]);
+               *num++ = FloatToHalf(color[1]);
+               *num++ = FloatToHalf(color[2]);
+               *num++ = FloatToHalf(color[3]);
 
-               return num.i;
+               return sizeof(*num) * 4;
        }
        else
        {
-               union pack8_u num;
+               float *num = (float *)out;
 
-               num.pack.x = v[0] * 127.0f;
-               num.pack.y = v[1] * 127.0f;
-               num.pack.z = v[2] * 127.0f;
-               num.pack.w = 0;
+               *num++ = color[0];
+               *num++ = color[1];
+               *num++ = color[2];
+               *num++ = color[3];
 
-               return num.i;
+               return sizeof(*num) * 4;
        }
 }
 
+
 void R_VaoUnpackTangent(vec4_t v, uint32_t b)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)&b;
 
-               num.i = b;
-
-               v[0] = num.pack.x / 511.0f;
-               v[1] = num.pack.y / 511.0f;
-               v[2] = num.pack.z / 511.0f;
-               v[3] = num.pack.w; 
+               v[0] = num->pack.x / 511.0f;
+               v[1] = num->pack.y / 511.0f;
+               v[2] = num->pack.z / 511.0f;
+               v[3] = num->pack.w; 
        }
        else
        {
-               union pack8_u num;
-
-               num.i = b;
+               union pack8_u *num = (union pack8_u *)&b;
 
-               v[0] = num.pack.x / 127.0f;
-               v[1] = num.pack.y / 127.0f;
-               v[2] = num.pack.z / 127.0f;
-               v[3] = num.pack.w / 127.0f; 
+               v[0] = num->pack.x / 127.0f;
+               v[1] = num->pack.y / 127.0f;
+               v[2] = num->pack.z / 127.0f;
+               v[3] = num->pack.w / 127.0f; 
        }
 }
 
@@ -126,23 +167,19 @@ void R_VaoUnpackNormal(vec3_t v, uint32_t b)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)&b;
 
-               num.i = b;
-
-               v[0] = num.pack.x / 511.0f;
-               v[1] = num.pack.y / 511.0f;
-               v[2] = num.pack.z / 511.0f;
+               v[0] = num->pack.x / 511.0f;
+               v[1] = num->pack.y / 511.0f;
+               v[2] = num->pack.z / 511.0f;
        }
        else
        {
-               union pack8_u num;
-
-               num.i = b;
+               union pack8_u *num = (union pack8_u *)&b;
 
-               v[0] = num.pack.x / 127.0f;
-               v[1] = num.pack.y / 127.0f;
-               v[2] = num.pack.z / 127.0f;
+               v[0] = num->pack.x / 127.0f;
+               v[1] = num->pack.y / 127.0f;
+               v[2] = num->pack.z / 127.0f;
        }
 }
 
@@ -312,9 +349,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
        vao->attribs[ATTR_INDEX_POSITION      ].type = GL_FLOAT;
        vao->attribs[ATTR_INDEX_NORMAL        ].type = 
glRefConfig.packedNormalDataType;
        vao->attribs[ATTR_INDEX_TANGENT       ].type = 
glRefConfig.packedNormalDataType;
-       vao->attribs[ATTR_INDEX_TEXCOORD      ].type = GL_FLOAT;
-       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].type = GL_FLOAT;
-       vao->attribs[ATTR_INDEX_COLOR         ].type = GL_FLOAT;
+       vao->attribs[ATTR_INDEX_TEXCOORD      ].type = 
glRefConfig.packedTexcoordDataType;
+       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].type = 
glRefConfig.packedTexcoordDataType;
+       vao->attribs[ATTR_INDEX_COLOR         ].type = 
glRefConfig.packedColorDataType;
        vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = 
glRefConfig.packedNormalDataType;
 
        vao->attribs[ATTR_INDEX_POSITION      ].normalized = GL_FALSE;
@@ -330,9 +367,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
 #ifdef USE_VERT_TANGENT_SPACE
        vao->attribs[ATTR_INDEX_TANGENT       ].offset = dataSize; dataSize += 
sizeof(uint32_t);
 #endif
-       vao->attribs[ATTR_INDEX_TEXCOORD      ].offset = dataSize; dataSize += 
sizeof(verts[0].st);
-       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].offset = dataSize; dataSize += 
sizeof(verts[0].lightmap);
-       vao->attribs[ATTR_INDEX_COLOR         ].offset = dataSize; dataSize += 
sizeof(verts[0].vertexColors);
+       vao->attribs[ATTR_INDEX_TEXCOORD      ].offset = dataSize; dataSize += 
glRefConfig.packedTexcoordDataSize;
+       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].offset = dataSize; dataSize += 
glRefConfig.packedTexcoordDataSize;
+       vao->attribs[ATTR_INDEX_COLOR         ].offset = dataSize; dataSize += 
glRefConfig.packedColorDataSize;
        vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += 
sizeof(uint32_t);
 
        vao->attribs[ATTR_INDEX_POSITION      ].stride = dataSize;
@@ -358,40 +395,29 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
 
        for (i = 0; i < numVertexes; i++)
        {
-               uint32_t *p;
-
                // xyz
                memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz));
                dataOfs += sizeof(verts[i].xyz);
 
                // normal
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackNormal(verts[i].normal);
-               dataOfs += sizeof(uint32_t);
+               dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                // tangent
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackTangent(verts[i].tangent);
-               dataOfs += sizeof(uint32_t);
+               dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent);
 #endif
 
-               // vertex texcoords
-               memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
-               dataOfs += sizeof(verts[i].st);
+               // texcoords
+               dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st);
 
-               // feed vertex lightmap texcoords
-               memcpy(data + dataOfs, &verts[i].lightmap, 
sizeof(verts[i].lightmap));
-               dataOfs += sizeof(verts[i].lightmap);
+               // lightmap texcoords
+               dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap);
 
-               // feed vertex colors
-               memcpy(data + dataOfs, &verts[i].vertexColors, 
sizeof(verts[i].vertexColors));
-               dataOfs += sizeof(verts[i].vertexColors);
+               // colors
+               dataOfs += R_VaoPackColors(data + dataOfs, 
verts[i].vertexColors);
 
-               // feed vertex light directions
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackNormal(verts[i].lightdir);
-               dataOfs += sizeof(uint32_t);
+               // light directions
+               dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir);
        }
 
        vao->vertexesSize = dataSize;
diff --git a/SP/code/rend2/tr_animation.c b/SP/code/rend2/tr_animation.c
index e4f27ca..f2f777c 100644
--- a/SP/code/rend2/tr_animation.c
+++ b/SP/code/rend2/tr_animation.c
@@ -1198,7 +1198,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) {
                }
                LocalMatrixTransformVector( v->normal, 
bones[v->weights[0].boneIndex].matrix, newNormal );
                
-               *tempNormal = R_VaoPackNormal(newNormal);
+               R_VaoPackNormal((byte *)tempNormal, newNormal);
 
                tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
                tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
@@ -1748,7 +1748,7 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface )
                tess.xyz[baseVertex + j][1] = tempVert[1];
                tess.xyz[baseVertex + j][2] = tempVert[2];
 
-               tess.normal[baseVertex + j] = R_VaoPackNormal(tempNormal);
+               R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], 
tempNormal);
 
                tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
                tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
diff --git a/SP/code/rend2/tr_extensions.c b/SP/code/rend2/tr_extensions.c
index b770e6c..c0f4d04 100644
--- a/SP/code/rend2/tr_extensions.c
+++ b/SP/code/rend2/tr_extensions.c
@@ -33,8 +33,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
02110-1301  USA
 void            (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint 
start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
 
 // GL_EXT_multi_draw_arrays
-void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, 
const GLsizei *count, GLsizei primcount);
-void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, 
GLenum type, const GLvoid* *indices, GLsizei primcount);
+void            (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint 
*first, const GLsizei *count, GLsizei primcount);
+void            (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const 
GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
 
 // GL_ARB_vertex_shader
 void            (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, 
GLuint index, const GLcharARB * name);
@@ -709,4 +709,27 @@ void GLimp_InitExtraExtensions()
                ri.Printf(PRINT_ALL, result[2], extension);
        }
 
+       // GL_ARB_half_float_vertex
+       extension = "GL_ARB_half_float_vertex";
+       glRefConfig.packedTexcoordDataType = GL_FLOAT;
+       glRefConfig.packedTexcoordDataSize = sizeof(float) * 2;
+       glRefConfig.packedColorDataType    = GL_FLOAT;
+       glRefConfig.packedColorDataSize    = sizeof(float) * 4;
+       if( GLimp_HaveExtension( extension ) )
+       {
+               if (r_arb_half_float_vertex->integer)
+               {
+                       glRefConfig.packedTexcoordDataType = GL_HALF_FLOAT;
+                       glRefConfig.packedTexcoordDataSize = sizeof(uint16_t) * 
2;
+                       glRefConfig.packedColorDataType    = GL_HALF_FLOAT;
+                       glRefConfig.packedColorDataSize    = sizeof(uint16_t) * 
4;
+               }
+
+               ri.Printf(PRINT_ALL, result[r_arb_half_float_vertex->integer ? 
1 : 0], extension);
+       }
+       else
+       {
+               ri.Printf(PRINT_ALL, result[2], extension);
+       }
+
 }
diff --git a/SP/code/rend2/tr_extramath.c b/SP/code/rend2/tr_extramath.c
index b844678..da9a94d 100644
--- a/SP/code/rend2/tr_extramath.c
+++ b/SP/code/rend2/tr_extramath.c
@@ -199,42 +199,35 @@ int NextPowerOfTwo(int in)
        return out;
 }
 
-unsigned short FloatToHalf(float in)
-{
-       unsigned short out;
-       
-       union
-       {
-               float f;
-               unsigned int i;
-       } f32;
-
-       int sign, inExponent, inFraction;
-       int outExponent, outFraction;
+union f32_u {
+       float f;
+       uint32_t i;
+       struct {
+               unsigned int fraction:23;
+               unsigned int exponent:8;
+               unsigned int sign:1;
+       } pack;
+};
+
+union f16_u {
+       uint16_t i;
+       struct {
+               unsigned int fraction:10;
+               unsigned int exponent:5;
+               unsigned int sign:1;
+       } pack;
+};
+
+uint16_t FloatToHalf(float in)
+{
+       union f32_u f32;
+       union f16_u f16;
 
        f32.f = in;
 
-       sign       = (f32.i & 0x80000000) >> 31;
-       inExponent = (f32.i & 0x7F800000) >> 23;
-       inFraction =  f32.i & 0x007FFFFF;
-
-       outExponent = CLAMP(inExponent - 127, -15, 16) + 15;
-
-       outFraction = 0;
-       if (outExponent == 0x1F)
-       {
-               if (inExponent == 0xFF && inFraction != 0)
-                       outFraction = 0x3FF;
-       }
-       else if (outExponent == 0x00)
-       {
-               if (inExponent == 0x00 && inFraction != 0)
-                       outFraction = 0x3FF;
-       }
-       else
-               outFraction = inFraction >> 13;
-
-       out = (sign << 15) | (outExponent << 10) | outFraction;
+       f16.pack.exponent = CLAMP(f32.pack.exponent - 112, 0, 31);
+       f16.pack.fraction = f32.pack.fraction >> 13;
+       f16.pack.sign     = f32.pack.sign;
 
-       return out;
+       return f16.i;
 }
diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c
index df826b2..0e99183 100644
--- a/SP/code/rend2/tr_init.c
+++ b/SP/code/rend2/tr_init.c
@@ -127,6 +127,7 @@ cvar_t  *r_ext_multi_draw_arrays;
 cvar_t  *r_ext_framebuffer_object;
 cvar_t  *r_ext_texture_float;
 cvar_t  *r_arb_half_float_pixel;
+cvar_t  *r_arb_half_float_vertex;
 cvar_t  *r_ext_framebuffer_multisample;
 cvar_t  *r_arb_seamless_cube_map;
 cvar_t  *r_arb_vertex_type_2_10_10_10_rev;
@@ -1272,6 +1273,7 @@ void R_Register( void ) {
        r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", 
"1", CVAR_ARCHIVE | CVAR_LATCH);
        r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
+       r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_ext_framebuffer_multisample = ri.Cvar_Get( 
"r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", 
CVAR_ARCHIVE | CVAR_LATCH);
        r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( 
"r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH);
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index 35169aa..567e40a 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -1558,6 +1558,10 @@ typedef struct {
        qboolean seamlessCubeMap;
 
        GLenum packedNormalDataType;
+       GLenum packedTexcoordDataType;
+       GLenum packedColorDataType;
+       int packedTexcoordDataSize;
+       int packedColorDataSize;
 
        qboolean floatLightmap;
        qboolean vertexArrayObject;
@@ -1914,6 +1918,7 @@ extern  cvar_t  *r_ext_multi_draw_arrays;
 extern  cvar_t  *r_ext_framebuffer_object;
 extern  cvar_t  *r_ext_texture_float;
 extern  cvar_t  *r_arb_half_float_pixel;
+extern  cvar_t  *r_arb_half_float_vertex;
 extern  cvar_t  *r_ext_framebuffer_multisample;
 extern  cvar_t  *r_arb_seamless_cube_map;
 extern  cvar_t  *r_arb_vertex_type_2_10_10_10_rev;
@@ -2443,8 +2448,10 @@ VERTEX BUFFER OBJECTS
 ============================================================
 */
 
-uint32_t R_VaoPackTangent(vec4_t v);
-uint32_t R_VaoPackNormal(vec3_t v);
+int R_VaoPackTangent(byte *out, vec4_t v);
+int R_VaoPackNormal(byte *out, vec3_t v);
+int R_VaoPackTexCoord(byte *out, vec2_t st);
+int R_VaoPackColors(byte *out, vec4_t color);
 void R_VaoUnpackTangent(vec4_t v, uint32_t b);
 void R_VaoUnpackNormal(vec3_t v, uint32_t b);
 
diff --git a/SP/code/rend2/tr_model.c b/SP/code/rend2/tr_model.c
index 435915b..2504d06 100644
--- a/SP/code/rend2/tr_model.c
+++ b/SP/code/rend2/tr_model.c
@@ -943,10 +943,10 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        {
                                // vertex animation, store texcoords first, 
then position/normal/tangents
                                offset_st      = 0;
-                               offset_xyz     = surf->numVerts * 
sizeof(vec2_t);
+                               offset_xyz     = surf->numVerts * 
glRefConfig.packedTexcoordDataSize;
                                offset_normal  = offset_xyz + sizeof(vec3_t);
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
-                               stride_st  = sizeof(vec2_t);
+                               stride_st  = glRefConfig.packedTexcoordDataSize;
                                stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz += sizeof(uint32_t);
@@ -960,7 +960,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                // no animation, interleave everything
                                offset_xyz     = 0;
                                offset_st      = offset_xyz + sizeof(vec3_t);
-                               offset_normal  = offset_st + sizeof(vec2_t);
+                               offset_normal  = offset_st + 
glRefConfig.packedTexcoordDataSize;
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz = offset_tangent + sizeof(uint32_t);
@@ -980,8 +980,7 @@ 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(vec2_t));
-                                       dataOfs += sizeof(vec2_t);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
                                }
 
                                v = surf->verts;
@@ -991,16 +990,12 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(vec3_t);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1008,9 +1003,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1024,20 +1017,15 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
-                                       dataOfs += sizeof(st->st);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1045,9 +1033,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1075,7 +1061,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void 
*buffer, const char *modN
                        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_TEXCOORD].type = 
glRefConfig.packedTexcoordDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
 
@@ -1451,10 +1437,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        {
                                // vertex animation, store texcoords first, 
then position/normal/tangents
                                offset_st      = 0;
-                               offset_xyz     = surf->numVerts * 
sizeof(vec2_t);
+                               offset_xyz     = surf->numVerts * 
glRefConfig.packedTexcoordDataSize;
                                offset_normal  = offset_xyz + sizeof(vec3_t);
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
-                               stride_st  = sizeof(vec2_t);
+                               stride_st  = glRefConfig.packedTexcoordDataSize;
                                stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz += sizeof(uint32_t);
@@ -1468,7 +1454,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                // no animation, interleave everything
                                offset_xyz     = 0;
                                offset_st      = offset_xyz + sizeof(vec3_t);
-                               offset_normal  = offset_st + sizeof(vec2_t);
+                               offset_normal  = offset_st + 
glRefConfig.packedTexcoordDataSize;
                                offset_tangent = offset_normal + 
sizeof(uint32_t);
 #ifdef USE_VERT_TANGENT_SPACE
                                stride_xyz = offset_tangent + sizeof(uint32_t);
@@ -1488,8 +1474,7 @@ 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(vec2_t));
-                                       dataOfs += sizeof(vec2_t);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
                                }
 
                                v = surf->verts;
@@ -1499,16 +1484,12 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(vec3_t);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1516,9 +1497,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1532,20 +1511,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        vec3_t nxt;
                                        vec4_t tangent;
 #endif
-                                       uint32_t *p;
-
                                        // xyz
                                        memcpy(data + dataOfs, &v->xyz, 
sizeof(vec3_t));
                                        dataOfs += sizeof(v->xyz);
 
                                        // st
-                                       memcpy(data + dataOfs, &st->st, 
sizeof(vec2_t));
-                                       dataOfs += sizeof(st->st);
+                                       dataOfs += R_VaoPackTexCoord(data + 
dataOfs, st->st);
 
                                        // normal
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackNormal(v->normal);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackNormal(data + 
dataOfs, v->normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                                        CrossProduct(v->normal, v->tangent, 
nxt);
@@ -1553,9 +1527,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                                        tangent[3] = (DotProduct(nxt, 
v->bitangent) < 0.0f) ? -1.0f : 1.0f;
 
                                        // tangent
-                                       p = (uint32_t *)(data + dataOfs);
-                                       *p = R_VaoPackTangent(tangent);
-                                       dataOfs += sizeof(uint32_t);
+                                       dataOfs += R_VaoPackTangent(data + 
dataOfs, tangent);
 #endif
                                }
                        }
@@ -1583,7 +1555,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void 
*buffer, const char *modN
                        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_TEXCOORD].type = 
glRefConfig.packedTexcoordDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_NORMAL  ].type = 
glRefConfig.packedNormalDataType;
                        vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = 
glRefConfig.packedNormalDataType;
 
diff --git a/SP/code/rend2/tr_model_iqm.c b/SP/code/rend2/tr_model_iqm.c
index 0079506..4e51c18 100644
--- a/SP/code/rend2/tr_model_iqm.c
+++ b/SP/code/rend2/tr_model_iqm.c
@@ -1130,7 +1130,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
                        normal[1] = DotProduct(&nrmMat[3], 
&data->normals[3*vtx]);
                        normal[2] = DotProduct(&nrmMat[6], 
&data->normals[3*vtx]);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                        tangent[0] = DotProduct(&nrmMat[0], 
&data->tangents[4*vtx]);
@@ -1138,7 +1138,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
                        tangent[2] = DotProduct(&nrmMat[6], 
&data->tangents[4*vtx]);
                        tangent[3] = data->tangents[4*vtx+3];
 
-                       *outTangent++ = R_VaoPackTangent(tangent);
+                       R_VaoPackTangent((byte *)outTangent++, tangent);
 #endif
                }
 
diff --git a/SP/code/rend2/tr_shade_calc.c b/SP/code/rend2/tr_shade_calc.c
index 4bfad4c..d1e6b44 100644
--- a/SP/code/rend2/tr_shade_calc.c
+++ b/SP/code/rend2/tr_shade_calc.c
@@ -244,7 +244,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
 
                VectorNormalizeFast( fNormal );
 
-               *normal = R_VaoPackNormal(fNormal);
+               R_VaoPackNormal((byte *)normal, fNormal);
        }
 }
 
diff --git a/SP/code/rend2/tr_surface.c b/SP/code/rend2/tr_surface.c
index f3afa01..7c9bc05 100644
--- a/SP/code/rend2/tr_surface.c
+++ b/SP/code/rend2/tr_surface.c
@@ -94,6 +94,7 @@ RB_AddQuadStampExt
 */
 void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float 
color[4], float s1, float t1, float s2, float t2 ) {
        vec3_t normal;
+       uint32_t    pNormal;
        int ndx;
 
        RB_CHECKOVERFLOW( 4, 6 );
@@ -129,10 +130,11 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, 
vec3_t up, float color[4],
        // constant normal all the way around
        VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
 
+       R_VaoPackNormal((byte *)&pNormal, normal);
        tess.normal[ndx] =
        tess.normal[ndx+1] =
        tess.normal[ndx+2] =
-       tess.normal[ndx+3] = R_VaoPackNormal(normal);
+       tess.normal[ndx+3] = pNormal;
 
        // standard square texture coordinates
        VectorSet2(tess.texCoords[ndx  ][0], s1, t1);
@@ -374,7 +376,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                normal = &tess.normal[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
-                       *normal = R_VaoPackNormal(dv->normal);
+                       R_VaoPackNormal((byte *)normal, dv->normal);
        }
 
 #ifdef USE_VERT_TANGENT_SPACE
@@ -383,7 +385,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                tangent = &tess.tangent[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
-                       *tangent = R_VaoPackTangent(dv->tangent);
+                       R_VaoPackTangent((byte *)tangent, dv->tangent);
        }
 #endif
 
@@ -416,7 +418,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, 
srfVert_t *verts, int numIn
                dv = verts;
                lightdir = &tess.lightdir[ tess.numVertexes ];
                for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
-                       *lightdir = R_VaoPackNormal(dv->lightdir);
+                       R_VaoPackNormal((byte *)lightdir, dv->lightdir);
        }
 
 #if 0  // nothing even uses vertex dlightbits
@@ -1170,7 +1172,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, 
float backlerp)
                        VectorCopy(newVerts->xyz,    outXyz);
                        VectorCopy(newVerts->normal, normal);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
                        newVerts++;
                        outXyz += 4;
@@ -1195,7 +1197,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, 
float backlerp)
                        VectorLerp(newVerts->normal, oldVerts->normal, 
backlerp, normal);
                        VectorNormalize(normal);
 
-                       *outNormal = R_VaoPackNormal(normal);
+                       R_VaoPackNormal((byte *)outNormal, normal);
 
                        newVerts++;
                        oldVerts++;
@@ -1362,7 +1364,7 @@ static void LerpCMeshVertexes( mdcSurface_t *surf, float 
backlerp ) {
                                fNormal[2] = tr.sinTable[( lng + ( 
FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
                        }
 
-                       *outNormal = R_VaoPackNormal(fNormal);
+                       R_VaoPackNormal((byte *)outNormal, fNormal);
                }
        } else {
                //
@@ -1432,7 +1434,7 @@ static void LerpCMeshVertexes( mdcSurface_t *surf, float 
backlerp ) {
 
                        VectorNormalize( fNormal );
                        
-                       *outNormal = R_VaoPackNormal(fNormal);
+                       R_VaoPackNormal((byte *)outNormal, fNormal);
                }
        }
 }
@@ -1659,13 +1661,13 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
 
                                if ( tess.shader->vertexAttribs & ATTR_NORMAL )
                                {
-                                       *normal++ = R_VaoPackNormal(dv->normal);
+                                       R_VaoPackNormal((byte *)normal++, 
dv->normal);
                                }
 
 #ifdef USE_VERT_TANGENT_SPACE
                                if ( tess.shader->vertexAttribs & ATTR_TANGENT )
                                {
-                                       *tangent++ = 
R_VaoPackTangent(dv->tangent);
+                                       R_VaoPackTangent((byte *)tangent++, 
dv->tangent);
                                }
 #endif
 
@@ -1689,7 +1691,7 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
 
                                if ( tess.shader->vertexAttribs & 
ATTR_LIGHTDIRECTION )
                                {
-                                       *lightdir++ = 
R_VaoPackNormal(dv->lightdir);
+                                       R_VaoPackNormal((byte *)lightdir++, 
dv->lightdir);
                                }
 
                                //*vDlightBits++ = dlightBits;
diff --git a/SP/code/rend2/tr_vbo.c b/SP/code/rend2/tr_vbo.c
index 981741f..8f9ba66 100644
--- a/SP/code/rend2/tr_vbo.c
+++ b/SP/code/rend2/tr_vbo.c
@@ -44,81 +44,122 @@ union pack8_u {
 };
 
 
-uint32_t R_VaoPackTangent(vec4_t v)
+int R_VaoPackTangent(byte *out, vec4_t v)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)out;
 
-               num.pack.x = v[0] * 511.0f;
-               num.pack.y = v[1] * 511.0f;
-               num.pack.z = v[2] * 511.0f;
-               num.pack.w = v[3];
+               num->pack.x = v[0] * 511.0f;
+               num->pack.y = v[1] * 511.0f;
+               num->pack.z = v[2] * 511.0f;
+               num->pack.w = v[3];
+       }
+       else
+       {
+               union pack8_u *num = (union pack8_u *)out;
+
+               num->pack.x = v[0] * 127.0f;
+               num->pack.y = v[1] * 127.0f;
+               num->pack.z = v[2] * 127.0f;
+               num->pack.w = v[3] * 127.0f;
+       }
+
+       return 4;
+}
+
+int R_VaoPackNormal(byte *out, vec3_t v)
+{
+       if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
+       {
+               union pack10_u *num = (union pack10_u *)out;
+
+               num->pack.x = v[0] * 511.0f;
+               num->pack.y = v[1] * 511.0f;
+               num->pack.z = v[2] * 511.0f;
+               num->pack.w = 0;
+       }
+       else
+       {
+               union pack8_u *num = (union pack8_u *)out;
 
-               return num.i;
+               num->pack.x = v[0] * 127.0f;
+               num->pack.y = v[1] * 127.0f;
+               num->pack.z = v[2] * 127.0f;
+               num->pack.w = 0;
+       }
+
+       return 4;
+}
+
+int R_VaoPackTexCoord(byte *out, vec2_t st)
+{
+       if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
+       {
+               uint16_t *num = (uint16_t *)out;
+
+               *num++ = FloatToHalf(st[0]);
+               *num++ = FloatToHalf(st[1]);
+
+               return sizeof(*num) * 2;
        }
        else
        {
-               union pack8_u num;
+               float *num = (float *)out;
 
-               num.pack.x = v[0] * 127.0f;
-               num.pack.y = v[1] * 127.0f;
-               num.pack.z = v[2] * 127.0f;
-               num.pack.w = v[3] * 127.0f;
+               *num++ = st[0];
+               *num++ = st[1];
 
-               return num.i;
+               return sizeof(*num) * 2;
        }
 }
 
-uint32_t R_VaoPackNormal(vec3_t v)
+int R_VaoPackColors(byte *out, vec4_t color)
 {
-       if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
+       if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
        {
-               union pack10_u num;
+               uint16_t *num = (uint16_t *)out;
 
-               num.pack.x = v[0] * 511.0f;
-               num.pack.y = v[1] * 511.0f;
-               num.pack.z = v[2] * 511.0f;
-               num.pack.w = 0;
+               *num++ = FloatToHalf(color[0]);
+               *num++ = FloatToHalf(color[1]);
+               *num++ = FloatToHalf(color[2]);
+               *num++ = FloatToHalf(color[3]);
 
-               return num.i;
+               return sizeof(*num) * 4;
        }
        else
        {
-               union pack8_u num;
+               float *num = (float *)out;
 
-               num.pack.x = v[0] * 127.0f;
-               num.pack.y = v[1] * 127.0f;
-               num.pack.z = v[2] * 127.0f;
-               num.pack.w = 0;
+               *num++ = color[0];
+               *num++ = color[1];
+               *num++ = color[2];
+               *num++ = color[3];
 
-               return num.i;
+               return sizeof(*num) * 4;
        }
 }
 
+
 void R_VaoUnpackTangent(vec4_t v, uint32_t b)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)&b;
 
-               num.i = b;
-
-               v[0] = num.pack.x / 511.0f;
-               v[1] = num.pack.y / 511.0f;
-               v[2] = num.pack.z / 511.0f;
-               v[3] = num.pack.w; 
+               v[0] = num->pack.x / 511.0f;
+               v[1] = num->pack.y / 511.0f;
+               v[2] = num->pack.z / 511.0f;
+               v[3] = num->pack.w; 
        }
        else
        {
-               union pack8_u num;
-
-               num.i = b;
+               union pack8_u *num = (union pack8_u *)&b;
 
-               v[0] = num.pack.x / 127.0f;
-               v[1] = num.pack.y / 127.0f;
-               v[2] = num.pack.z / 127.0f;
-               v[3] = num.pack.w / 127.0f; 
+               v[0] = num->pack.x / 127.0f;
+               v[1] = num->pack.y / 127.0f;
+               v[2] = num->pack.z / 127.0f;
+               v[3] = num->pack.w / 127.0f; 
        }
 }
 
@@ -126,23 +167,19 @@ void R_VaoUnpackNormal(vec3_t v, uint32_t b)
 {
        if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
        {
-               union pack10_u num;
+               union pack10_u *num = (union pack10_u *)&b;
 
-               num.i = b;
-
-               v[0] = num.pack.x / 511.0f;
-               v[1] = num.pack.y / 511.0f;
-               v[2] = num.pack.z / 511.0f;
+               v[0] = num->pack.x / 511.0f;
+               v[1] = num->pack.y / 511.0f;
+               v[2] = num->pack.z / 511.0f;
        }
        else
        {
-               union pack8_u num;
-
-               num.i = b;
+               union pack8_u *num = (union pack8_u *)&b;
 
-               v[0] = num.pack.x / 127.0f;
-               v[1] = num.pack.y / 127.0f;
-               v[2] = num.pack.z / 127.0f;
+               v[0] = num->pack.x / 127.0f;
+               v[1] = num->pack.y / 127.0f;
+               v[2] = num->pack.z / 127.0f;
        }
 }
 
@@ -312,9 +349,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
        vao->attribs[ATTR_INDEX_POSITION      ].type = GL_FLOAT;
        vao->attribs[ATTR_INDEX_NORMAL        ].type = 
glRefConfig.packedNormalDataType;
        vao->attribs[ATTR_INDEX_TANGENT       ].type = 
glRefConfig.packedNormalDataType;
-       vao->attribs[ATTR_INDEX_TEXCOORD      ].type = GL_FLOAT;
-       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].type = GL_FLOAT;
-       vao->attribs[ATTR_INDEX_COLOR         ].type = GL_FLOAT;
+       vao->attribs[ATTR_INDEX_TEXCOORD      ].type = 
glRefConfig.packedTexcoordDataType;
+       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].type = 
glRefConfig.packedTexcoordDataType;
+       vao->attribs[ATTR_INDEX_COLOR         ].type = 
glRefConfig.packedColorDataType;
        vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = 
glRefConfig.packedNormalDataType;
 
        vao->attribs[ATTR_INDEX_POSITION      ].normalized = GL_FALSE;
@@ -330,9 +367,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
 #ifdef USE_VERT_TANGENT_SPACE
        vao->attribs[ATTR_INDEX_TANGENT       ].offset = dataSize; dataSize += 
sizeof(uint32_t);
 #endif
-       vao->attribs[ATTR_INDEX_TEXCOORD      ].offset = dataSize; dataSize += 
sizeof(verts[0].st);
-       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].offset = dataSize; dataSize += 
sizeof(verts[0].lightmap);
-       vao->attribs[ATTR_INDEX_COLOR         ].offset = dataSize; dataSize += 
sizeof(verts[0].vertexColors);
+       vao->attribs[ATTR_INDEX_TEXCOORD      ].offset = dataSize; dataSize += 
glRefConfig.packedTexcoordDataSize;
+       vao->attribs[ATTR_INDEX_LIGHTCOORD    ].offset = dataSize; dataSize += 
glRefConfig.packedTexcoordDataSize;
+       vao->attribs[ATTR_INDEX_COLOR         ].offset = dataSize; dataSize += 
glRefConfig.packedColorDataSize;
        vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += 
sizeof(uint32_t);
 
        vao->attribs[ATTR_INDEX_POSITION      ].stride = dataSize;
@@ -358,40 +395,29 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, 
srfVert_t *verts, int num
 
        for (i = 0; i < numVertexes; i++)
        {
-               uint32_t *p;
-
                // xyz
                memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz));
                dataOfs += sizeof(verts[i].xyz);
 
                // normal
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackNormal(verts[i].normal);
-               dataOfs += sizeof(uint32_t);
+               dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal);
 
 #ifdef USE_VERT_TANGENT_SPACE
                // tangent
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackTangent(verts[i].tangent);
-               dataOfs += sizeof(uint32_t);
+               dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent);
 #endif
 
-               // vertex texcoords
-               memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
-               dataOfs += sizeof(verts[i].st);
+               // texcoords
+               dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st);
 
-               // feed vertex lightmap texcoords
-               memcpy(data + dataOfs, &verts[i].lightmap, 
sizeof(verts[i].lightmap));
-               dataOfs += sizeof(verts[i].lightmap);
+               // lightmap texcoords
+               dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap);
 
-               // feed vertex colors
-               memcpy(data + dataOfs, &verts[i].vertexColors, 
sizeof(verts[i].vertexColors));
-               dataOfs += sizeof(verts[i].vertexColors);
+               // colors
+               dataOfs += R_VaoPackColors(data + dataOfs, 
verts[i].vertexColors);
 
-               // feed vertex light directions
-               p = (uint32_t *)(data + dataOfs);
-               *p = R_VaoPackNormal(verts[i].lightdir);
-               dataOfs += sizeof(uint32_t);
+               // light directions
+               dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir);
        }
 
        vao->vertexesSize = dataSize;

-- 
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