summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/renderergl2/glsl/lightall_vp.glsl2
-rw-r--r--src/renderergl2/tr_animation.c4
-rw-r--r--src/renderergl2/tr_extensions.c15
-rw-r--r--src/renderergl2/tr_extramath.h2
-rw-r--r--src/renderergl2/tr_glsl.c10
-rw-r--r--src/renderergl2/tr_init.c2
-rw-r--r--src/renderergl2/tr_local.h15
-rw-r--r--src/renderergl2/tr_main.c4
-rw-r--r--src/renderergl2/tr_model.c31
-rw-r--r--src/renderergl2/tr_model_iqm.c47
-rw-r--r--src/renderergl2/tr_shade_calc.c58
-rw-r--r--src/renderergl2/tr_surface.c106
-rw-r--r--src/renderergl2/tr_vbo.c143
13 files changed, 240 insertions, 199 deletions
diff --git a/src/renderergl2/glsl/lightall_vp.glsl b/src/renderergl2/glsl/lightall_vp.glsl
index f6164957..67628c7f 100644
--- a/src/renderergl2/glsl/lightall_vp.glsl
+++ b/src/renderergl2/glsl/lightall_vp.glsl
@@ -206,7 +206,7 @@ void main()
#if defined(USE_LIGHT_VECTOR)
vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
#elif defined(USE_LIGHT)
- vec3 L = attr_LightDirection;
+ vec3 L = attr_LightDirection * 2.0 - vec3(1.0);
#if defined(USE_MODELMATRIX)
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
#endif
diff --git a/src/renderergl2/tr_animation.c b/src/renderergl2/tr_animation.c
index 96beb309..77bb8611 100644
--- a/src/renderergl2/tr_animation.c
+++ b/src/renderergl2/tr_animation.c
@@ -412,9 +412,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][0] = (uint8_t)(tempNormal[0] * 127.5f + 128.0f);
- tess.normal[baseVertex + j][1] = (uint8_t)(tempNormal[1] * 127.5f + 128.0f);
- tess.normal[baseVertex + j][2] = (uint8_t)(tempNormal[2] * 127.5f + 128.0f);
+ tess.normal[baseVertex + j] = R_VboPackTangent(tempNormal);
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
diff --git a/src/renderergl2/tr_extensions.c b/src/renderergl2/tr_extensions.c
index 4e030965..adca06e9 100644
--- a/src/renderergl2/tr_extensions.c
+++ b/src/renderergl2/tr_extensions.c
@@ -710,4 +710,19 @@ void GLimp_InitExtraExtensions()
{
ri.Printf(PRINT_ALL, result[2], extension);
}
+
+ // GL_ARB_vertex_type_2_10_10_10_rev
+ extension = "GL_ARB_vertex_type_2_10_10_10_rev";
+ glRefConfig.packedNormalDataType = GL_UNSIGNED_BYTE;
+ if( GLimp_HaveExtension( extension ) )
+ {
+ if (r_arb_vertex_type_2_10_10_10_rev->integer)
+ glRefConfig.packedNormalDataType = GL_UNSIGNED_INT_2_10_10_10_REV;
+
+ ri.Printf(PRINT_ALL, result[r_arb_vertex_type_2_10_10_10_rev->integer ? 1 : 0], extension);
+ }
+ else
+ {
+ ri.Printf(PRINT_ALL, result[2], extension);
+ }
}
diff --git a/src/renderergl2/tr_extramath.h b/src/renderergl2/tr_extramath.h
index 0be8f6c0..af7c3804 100644
--- a/src/renderergl2/tr_extramath.h
+++ b/src/renderergl2/tr_extramath.h
@@ -52,7 +52,7 @@ void Mat4SimpleInverse( const mat4_t in, mat4_t out);
#define VectorCopy5(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3],(b)[4]=(a)[4])
#define OffsetByteToFloat(a) ((float)(a) * 1.0f/127.5f - 1.0f)
-#define FloatToOffsetByte(a) (byte)(((a) + 1.0f) * 127.5f)
+#define FloatToOffsetByte(a) (byte)((a) * 127.5f + 128.0f)
#define ByteToFloat(a) ((float)(a) * 1.0f/255.0f)
#define FloatToByte(a) (byte)((a) * 255.0f)
diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c
index 42ce225e..3b6f6306 100644
--- a/src/renderergl2/tr_glsl.c
+++ b/src/renderergl2/tr_glsl.c
@@ -1682,7 +1682,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL )\n");
- qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 3, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + newFrame * vbo->size_normal));
+ qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + newFrame * vbo->size_normal));
glState.vertexAttribPointersSet |= ATTR_NORMAL;
}
@@ -1691,7 +1691,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n");
- qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + newFrame * vbo->size_normal)); // FIXME
+ qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + newFrame * vbo->size_normal)); // FIXME
glState.vertexAttribPointersSet |= ATTR_TANGENT;
}
#endif
@@ -1708,7 +1708,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTDIRECTION )\n");
- qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 3, GL_FLOAT, 0, vbo->stride_lightdir, BUFFER_OFFSET(vbo->ofs_lightdir));
+ qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_lightdir, BUFFER_OFFSET(vbo->ofs_lightdir));
glState.vertexAttribPointersSet |= ATTR_LIGHTDIRECTION;
}
@@ -1724,7 +1724,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL2 )\n");
- qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 3, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + oldFrame * vbo->size_normal));
+ qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + oldFrame * vbo->size_normal));
glState.vertexAttribPointersSet |= ATTR_NORMAL2;
}
@@ -1733,7 +1733,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n");
- qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + oldFrame * vbo->size_normal)); // FIXME
+ qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + oldFrame * vbo->size_normal)); // FIXME
glState.vertexAttribPointersSet |= ATTR_TANGENT2;
}
#endif
diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c
index eb3e0f27..010603a1 100644
--- a/src/renderergl2/tr_init.c
+++ b/src/renderergl2/tr_init.c
@@ -102,6 +102,7 @@ cvar_t *r_ext_texture_float;
cvar_t *r_arb_half_float_pixel;
cvar_t *r_ext_framebuffer_multisample;
cvar_t *r_arb_seamless_cube_map;
+cvar_t *r_arb_vertex_type_2_10_10_10_rev;
cvar_t *r_mergeMultidraws;
cvar_t *r_mergeLeafSurfaces;
@@ -1056,6 +1057,7 @@ void R_Register( void )
r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "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);
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
"0", CVAR_ARCHIVE | CVAR_LATCH );
diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h
index 9c3b8912..3effb9f8 100644
--- a/src/renderergl2/tr_local.h
+++ b/src/renderergl2/tr_local.h
@@ -1424,6 +1424,8 @@ typedef struct {
qboolean depthClamp;
qboolean seamlessCubeMap;
+
+ GLenum packedNormalDataType;
} glRefConfig_t;
@@ -1723,6 +1725,7 @@ extern cvar_t *r_ext_texture_float;
extern cvar_t *r_arb_half_float_pixel;
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;
extern cvar_t *r_nobind; // turns off binding to appropriate textures
extern cvar_t *r_singleShader; // make most world faces use default shader
@@ -2009,13 +2012,13 @@ typedef struct shaderCommands_s
{
glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
- uint8_t normal[SHADER_MAX_VERTEXES][4] QALIGN(16);
+ uint32_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
#ifdef USE_VERT_TANGENT_SPACE
- uint8_t tangent[SHADER_MAX_VERTEXES][4] QALIGN(16);
+ uint32_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
#endif
vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
- vec4_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
+ uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
//int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
VBO_t *vbo;
@@ -2179,6 +2182,12 @@ VERTEX BUFFER OBJECTS
============================================================
*/
+
+uint32_t R_VboPackTangent(vec4_t v);
+uint32_t R_VboPackNormal(vec3_t v);
+void R_VboUnpackTangent(vec4_t v, uint32_t b);
+void R_VboUnpackNormal(vec3_t v, uint32_t b);
+
VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, vboUsage_t usage);
VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vertexes, uint32_t stateBits, vboUsage_t usage);
diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c
index bb2f0587..943a6fa8 100644
--- a/src/renderergl2/tr_main.c
+++ b/src/renderergl2/tr_main.c
@@ -1575,9 +1575,7 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
shortest = len;
}
- tNormal[0] = tess.normal[tess.indexes[i]][0] / 127.5f - 1.0f;
- tNormal[1] = tess.normal[tess.indexes[i]][1] / 127.5f - 1.0f;
- tNormal[2] = tess.normal[tess.indexes[i]][2] / 127.5f - 1.0f;
+ R_VboUnpackNormal(tNormal, tess.normal[tess.indexes[i]]);
if ( DotProduct( normal, tNormal ) >= 0 )
{
diff --git a/src/renderergl2/tr_model.c b/src/renderergl2/tr_model.c
index 2627afc4..7ac9f149 100644
--- a/src/renderergl2/tr_model.c
+++ b/src/renderergl2/tr_model.c
@@ -684,9 +684,9 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
{
vec3_t *verts;
vec2_t *texcoords;
- uint8_t *normals;
+ uint32_t *normals;
#ifdef USE_VERT_TANGENT_SPACE
- uint8_t *tangents;
+ uint32_t *tangents;
#endif
byte *data;
@@ -703,11 +703,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*verts);
ofs_normal = dataSize;
- dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals) * 4;
+ dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals);
#ifdef USE_VERT_TANGENT_SPACE
ofs_tangent = dataSize;
- dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents) * 4;
+ dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents);
#endif
ofs_st = dataSize;
@@ -726,18 +726,17 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
{
vec3_t nxt;
+ vec4_t tangent;
- CrossProduct(v->normal, v->tangent, nxt);
VectorCopy(v->xyz, verts[j]);
- normals[j*4+0] = (uint8_t)(v->normal[0] * 127.5f + 128.0f);
- normals[j*4+1] = (uint8_t)(v->normal[1] * 127.5f + 128.0f);
- normals[j*4+2] = (uint8_t)(v->normal[2] * 127.5f + 128.0f);
- normals[j*4+3] = 0;
+
+ normals[j] = R_VboPackNormal(v->normal);
#ifdef USE_VERT_TANGENT_SPACE
- tangents[j*4+0] = (uint8_t)(v->tangent[0] * 127.5f + 128.0f);
- tangents[j*4+1] = (uint8_t)(v->tangent[1] * 127.5f + 128.0f);
- tangents[j*4+2] = (uint8_t)(v->tangent[2] * 127.5f + 128.0f);
- tangents[j*4+3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? 0 : 255;
+ CrossProduct(v->normal, v->tangent, nxt);
+ VectorCopy(v->tangent, tangent);
+ tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
+
+ tangents[j] = R_VboPackTangent(tangent);
#endif
}
@@ -766,14 +765,14 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
vboSurf->vbo->ofs_st = ofs_st;
vboSurf->vbo->stride_xyz = sizeof(*verts);
- vboSurf->vbo->stride_normal = sizeof(*normals) * 4;
+ vboSurf->vbo->stride_normal = sizeof(*normals);
#ifdef USE_VERT_TANGENT_SPACE
- vboSurf->vbo->stride_tangent = sizeof(*tangents) * 4;
+ vboSurf->vbo->stride_tangent = sizeof(*tangents);
#endif
vboSurf->vbo->stride_st = sizeof(*st);
vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts;
- vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts * 4;
+ vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts;
ri.Free(data);
diff --git a/src/renderergl2/tr_model_iqm.c b/src/renderergl2/tr_model_iqm.c
index 8eab1106..d0ad6074 100644
--- a/src/renderergl2/tr_model_iqm.c
+++ b/src/renderergl2/tr_model_iqm.c
@@ -1024,7 +1024,10 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
int i;
vec4_t *outXYZ;
- uint8_t *outNormal;
+ uint32_t *outNormal;
+#ifdef USE_VERT_TANGENT_SPACE
+ uint32_t *outTangent;
+#endif
vec2_t (*outTexCoord)[2];
vec4_t *outColor;
@@ -1039,7 +1042,10 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
outXYZ = &tess.xyz[tess.numVertexes];
- outNormal = &tess.normal[tess.numVertexes][0];
+ outNormal = &tess.normal[tess.numVertexes];
+#ifdef USE_VERT_TANGENT_SPACE
+ outTangent = &tess.tangent[tess.numVertexes];
+#endif
outTexCoord = &tess.texCoords[tess.numVertexes];
outColor = &tess.vertexColors[tess.numVertexes];
@@ -1050,7 +1056,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
// transform vertexes and fill other data
for( i = 0; i < surf->num_vertexes;
- i++, outXYZ++, outNormal+=4, outTexCoord++, outColor++ ) {
+ i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) {
int j, k;
float vtxMat[12];
float nrmMat[9];
@@ -1116,22 +1122,25 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
vtxMat[11];
(*outXYZ)[3] = 1.0f;
- (outNormal)[0] = (uint8_t)((
- nrmMat[ 0] * data->normals[3*vtx+0] +
- nrmMat[ 1] * data->normals[3*vtx+1] +
- nrmMat[ 2] * data->normals[3*vtx+2]
- )* 127.5f + 128.0f);
- (outNormal)[1] = (uint8_t)((
- nrmMat[ 3] * data->normals[3*vtx+0] +
- nrmMat[ 4] * data->normals[3*vtx+1] +
- nrmMat[ 5] * data->normals[3*vtx+2]
- )* 127.5f + 128.0f);
- (outNormal)[2] = (uint8_t)((
- nrmMat[ 6] * data->normals[3*vtx+0] +
- nrmMat[ 7] * data->normals[3*vtx+1] +
- nrmMat[ 8] * data->normals[3*vtx+2]
- )* 127.5f + 128.0f);
- (outNormal)[3] = 0;
+ {
+ vec3_t normal;
+ vec4_t tangent;
+
+ normal[0] = DotProduct(&nrmMat[0], &data->normals[3*vtx]);
+ normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]);
+ normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]);
+
+ *outNormal = R_VboPackNormal(normal);
+
+#ifdef USE_VERT_TANGENT_SPACE
+ tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]);
+ tangent[1] = DotProduct(&nrmMat[3], &data->tangents[4*vtx]);
+ tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]);
+ tangent[3] = data->tangents[4*vtx+3];
+
+ *outTangent++ = R_VboPackTangent(tangent);
+#endif
+ }
(*outColor)[0] = data->colors[4*vtx+0] / 255.0f;
(*outColor)[1] = data->colors[4*vtx+1] / 255.0f;
diff --git a/src/renderergl2/tr_shade_calc.c b/src/renderergl2/tr_shade_calc.c
index c3172ec2..9b2ac3e8 100644
--- a/src/renderergl2/tr_shade_calc.c
+++ b/src/renderergl2/tr_shade_calc.c
@@ -117,29 +117,27 @@ void RB_CalcDeformVertexes( deformStage_t *ds )
vec3_t offset;
float scale;
float *xyz = ( float * ) tess.xyz;
- uint8_t *normal = ( uint8_t * ) tess.normal;
+ uint32_t *normal = tess.normal;
float *table;
if ( ds->deformationWave.frequency == 0 )
{
scale = EvalWaveForm( &ds->deformationWave );
- for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
+ for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
{
- offset[0] = (normal[0] / 127.5f - 1.0f) * scale;
- offset[1] = (normal[1] / 127.5f - 1.0f) * scale;
- offset[2] = (normal[2] / 127.5f - 1.0f) * scale;
+ R_VboUnpackNormal(offset, *normal);
- xyz[0] += offset[0];
- xyz[1] += offset[1];
- xyz[2] += offset[2];
+ xyz[0] += offset[0] * scale;
+ xyz[1] += offset[1] * scale;
+ xyz[2] += offset[2] * scale;
}
}
else
{
table = TableForFunc( ds->deformationWave.func );
- for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
+ for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
{
float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
@@ -148,13 +146,11 @@ void RB_CalcDeformVertexes( deformStage_t *ds )
ds->deformationWave.phase + off,
ds->deformationWave.frequency );
- offset[0] = (normal[0] / 127.5f - 1.0f) * scale;
- offset[1] = (normal[1] / 127.5f - 1.0f) * scale;
- offset[2] = (normal[2] / 127.5f - 1.0f) * scale;
-
- xyz[0] += offset[0];
- xyz[1] += offset[1];
- xyz[2] += offset[2];
+ R_VboUnpackNormal(offset, *normal);
+
+ xyz[0] += offset[0] * scale;
+ xyz[1] += offset[1] * scale;
+ xyz[2] += offset[2] * scale;
}
}
}
@@ -170,14 +166,12 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
int i;
float scale;
float *xyz = ( float * ) tess.xyz;
- uint8_t *normal = ( uint8_t * ) tess.normal;
+ uint32_t *normal = tess.normal;
- for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
+ for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) {
vec3_t fNormal;
- fNormal[0] = normal[0] / 127.5f - 1.0f;
- fNormal[1] = normal[1] / 127.5f - 1.0f;
- fNormal[2] = normal[2] / 127.5f - 1.0f;
+ R_VboUnpackNormal(fNormal, *normal);
scale = 0.98f;
scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
@@ -196,9 +190,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
VectorNormalizeFast( fNormal );
- normal[0] = (uint8_t)(fNormal[0] * 127.5f + 128.0f);
- normal[1] = (uint8_t)(fNormal[0] * 127.5f + 128.0f);
- normal[2] = (uint8_t)(fNormal[0] * 127.5f + 128.0f);
+ *normal = R_VboPackNormal(fNormal);
}
}
@@ -212,22 +204,25 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
int i;
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
- uint8_t *normal = ( uint8_t * ) tess.normal;
+ uint32_t *normal = tess.normal;
float now;
now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
- for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
+ for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal++ ) {
int off;
float scale;
+ vec3_t fNormal;
+
+ R_VboUnpackNormal(fNormal, *normal);
off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight;
- xyz[0] += (normal[0] / 127.5f - 1.0f) * scale;
- xyz[1] += (normal[1] / 127.5f - 1.0f) * scale;
- xyz[2] += (normal[2] / 127.5f - 1.0f) * scale;
+ xyz[0] += fNormal[0] * scale;
+ xyz[1] += fNormal[1] * scale;
+ xyz[2] += fNormal[2] * scale;
}
}
@@ -282,11 +277,8 @@ void DeformText( const char *text ) {
height[0] = 0;
height[1] = 0;
height[2] = -1;
-
- fNormal[0] = tess.normal[0][0] / 127.5f - 1.0f;
- fNormal[1] = tess.normal[0][1] / 127.5f - 1.0f;
- fNormal[2] = tess.normal[0][2] / 127.5f - 1.0f;
+ R_VboUnpackNormal(fNormal, tess.normal[0]);
CrossProduct( fNormal, height, width );
// find the midpoint of the box
diff --git a/src/renderergl2/tr_surface.c b/src/renderergl2/tr_surface.c
index 10dabbd2..d91085da 100644
--- a/src/renderergl2/tr_surface.c
+++ b/src/renderergl2/tr_surface.c
@@ -125,26 +125,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 );
- tess.normal[ndx][0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- tess.normal[ndx][1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- tess.normal[ndx][2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- tess.normal[ndx][3] = 0;
-
- tess.normal[ndx+1][0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- tess.normal[ndx+1][1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- tess.normal[ndx+1][2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- tess.normal[ndx+1][3] = 0;
-
- tess.normal[ndx+2][0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- tess.normal[ndx+2][1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- tess.normal[ndx+2][2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- tess.normal[ndx+2][3] = 0;
-
- tess.normal[ndx+3][0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- tess.normal[ndx+3][1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- tess.normal[ndx+3][2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- tess.normal[ndx+3][3] = 0;
-
+ tess.normal[ndx] =
+ tess.normal[ndx+1] =
+ tess.normal[ndx+2] =
+ tess.normal[ndx+3] = R_VboPackNormal(normal);
+
// standard square texture coordinates
VectorSet2(tess.texCoords[ndx ][0], s1, t1);
VectorSet2(tess.texCoords[ndx ][1], s1, t1);
@@ -332,10 +317,11 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn
int i;
glIndex_t *inIndex;
srfVert_t *dv;
- float *xyz, *texCoords, *lightCoords, *lightdir;
- uint8_t *normal;
+ float *xyz, *texCoords, *lightCoords;
+ uint32_t *lightdir;
+ uint32_t *normal;
#ifdef USE_VERT_TANGENT_SPACE
- uint8_t *tangent;
+ uint32_t *tangent;
#endif
glIndex_t *outIndex;
float *color;
@@ -362,28 +348,18 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn
if ( tess.shader->vertexAttribs & ATTR_NORMAL )
{
dv = verts;
- normal = tess.normal[ tess.numVertexes ];
- for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 )
- {
- normal[0] = (uint8_t)(dv->normal[0] * 127.5f + 128.0f);
- normal[1] = (uint8_t)(dv->normal[1] * 127.5f + 128.0f);
- normal[2] = (uint8_t)(dv->normal[2] * 127.5f + 128.0f);
- normal[3] = 0;
- }
+ normal = &tess.normal[ tess.numVertexes ];
+ for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
+ *normal = R_VboPackNormal(dv->normal);
}
#ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{
dv = verts;
- tangent = tess.tangent[ tess.numVertexes ];
- for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 )
- {
- tangent[0] = (uint8_t)(dv->tangent[0] * 127.5f + 128.0f);
- tangent[1] = (uint8_t)(dv->tangent[1] * 127.5f + 128.0f);
- tangent[2] = (uint8_t)(dv->tangent[2] * 127.5f + 128.0f);
- tangent[3] = (uint8_t)(dv->tangent[3] * 127.5f + 128.0f);
- }
+ tangent = &tess.tangent[ tess.numVertexes ];
+ for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
+ *tangent = R_VboPackTangent(dv->tangent);
}
#endif
@@ -414,9 +390,9 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn
if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
{
dv = verts;
- lightdir = tess.lightdir[ tess.numVertexes ];
- for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 )
- VectorCopy(dv->lightdir, lightdir);
+ lightdir = &tess.lightdir[ tess.numVertexes ];
+ for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
+ *lightdir = R_VboPackNormal(dv->lightdir);
}
#if 0 // nothing even uses vertex dlightbits
@@ -1151,14 +1127,14 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
}
#endif
float *outXyz;
- uint8_t *outNormal;
+ uint32_t *outNormal;
mdvVertex_t *newVerts;
int vertNum;
newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
outXyz = tess.xyz[tess.numVertexes];
- outNormal = tess.normal[tess.numVertexes];
+ outNormal = &tess.normal[tess.numVertexes];
if (backlerp == 0)
{
@@ -1173,14 +1149,11 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
VectorCopy(newVerts->xyz, outXyz);
VectorCopy(newVerts->normal, normal);
- outNormal[0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- outNormal[1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- outNormal[2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- outNormal[3] = 0;
+ *outNormal = R_VboPackNormal(normal);
newVerts++;
outXyz += 4;
- outNormal += 4;
+ outNormal++;
}
}
else
@@ -1201,15 +1174,12 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal);
VectorNormalize(normal);
- outNormal[0] = (uint8_t)(normal[0] * 127.5f + 128.0f);
- outNormal[1] = (uint8_t)(normal[1] * 127.5f + 128.0f);
- outNormal[2] = (uint8_t)(normal[2] * 127.5f + 128.0f);
- outNormal[3] = 0;
+ *outNormal = R_VboPackNormal(normal);
newVerts++;
oldVerts++;
outXyz += 4;
- outNormal += 4;
+ outNormal++;
}
}
@@ -1331,11 +1301,12 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
int i, j;
float *xyz;
float *texCoords, *lightCoords;
- uint8_t *normal;
+ uint32_t *normal;
#ifdef USE_VERT_TANGENT_SPACE
- uint8_t *tangent;
+ uint32_t *tangent;
#endif
- float *color, *lightdir;
+ float *color;
+ uint32_t *lightdir;
srfVert_t *dv;
int rows, irows, vrows;
int used;
@@ -1418,14 +1389,14 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
numVertexes = tess.numVertexes;
xyz = tess.xyz[numVertexes];
- normal = tess.normal[numVertexes];
+ normal = &tess.normal[numVertexes];
#ifdef USE_VERT_TANGENT_SPACE
- tangent = tess.tangent[numVertexes];
+ tangent = &tess.tangent[numVertexes];
#endif
texCoords = tess.texCoords[numVertexes][0];
lightCoords = tess.texCoords[numVertexes][1];
color = tess.vertexColors[numVertexes];
- lightdir = tess.lightdir[numVertexes];
+ lightdir = &tess.lightdir[numVertexes];
//vDlightBits = &tess.vertexDlightBits[numVertexes];
for ( i = 0 ; i < rows ; i++ ) {
@@ -1441,21 +1412,13 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
if ( tess.shader->vertexAttribs & ATTR_NORMAL )
{
- normal[0] = (uint8_t)(dv->normal[0] * 127.5f + 128.0f);
- normal[1] = (uint8_t)(dv->normal[1] * 127.5f + 128.0f);
- normal[2] = (uint8_t)(dv->normal[2] * 127.5f + 128.0f);
- normal[3] = 0;
- normal += 4;
+ *normal++ = R_VboPackNormal(dv->normal);
}
#ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{
- tangent[0] = (uint8_t)(dv->tangent[0] * 127.5f + 128.0f);
- tangent[1] = (uint8_t)(dv->tangent[1] * 127.5f + 128.0f);
- tangent[2] = (uint8_t)(dv->tangent[2] * 127.5f + 128.0f);
- tangent[3] = (uint8_t)(dv->tangent[3] * 127.5f + 128.0f);
- tangent += 4;
+ *tangent++ = R_VboPackTangent(dv->tangent);
}
#endif
if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
@@ -1478,8 +1441,7 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
{
- VectorCopy(dv->lightdir, lightdir);
- lightdir += 4;
+ *lightdir++ = R_VboPackNormal(dv->lightdir);
}
//*vDlightBits++ = dlightBits;
diff --git a/src/renderergl2/tr_vbo.c b/src/renderergl2/tr_vbo.c
index b18b8f93..8eb85d41 100644
--- a/src/renderergl2/tr_vbo.c
+++ b/src/renderergl2/tr_vbo.c
@@ -22,6 +22,75 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_vbo.c
#include "tr_local.h"
+
+uint32_t R_VboPackTangent(vec4_t v)
+{
+ if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
+ {
+ return (((uint32_t)(v[3] * 1.5f + 2.0f )) << 30)
+ | (((uint32_t)(v[2] * 511.5f + 512.0f)) << 20)
+ | (((uint32_t)(v[1] * 511.5f + 512.0f)) << 10)
+ | (((uint32_t)(v[0] * 511.5f + 512.0f)));
+ }
+ else
+ {
+ return (((uint32_t)(v[3] * 127.5f + 128.0f)) << 24)
+ | (((uint32_t)(v[2] * 127.5f + 128.0f)) << 16)
+ | (((uint32_t)(v[1] * 127.5f + 128.0f)) << 8)
+ | (((uint32_t)(v[0] * 127.5f + 128.0f)));
+ }
+}
+
+uint32_t R_VboPackNormal(vec3_t v)
+{
+ if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
+ {
+ return (((uint32_t)(v[2] * 511.5f + 512.0f)) << 20)
+ | (((uint32_t)(v[1] * 511.5f + 512.0f)) << 10)
+ | (((uint32_t)(v[0] * 511.5f + 512.0f)));
+ }
+ else
+ {
+ return (((uint32_t)(v[2] * 127.5f + 128.0f)) << 16)
+ | (((uint32_t)(v[1] * 127.5f + 128.0f)) << 8)
+ | (((uint32_t)(v[0] * 127.5f + 128.0f)));
+ }
+}
+
+void R_VboUnpackTangent(vec4_t v, uint32_t b)
+{
+ if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
+ {
+ v[0] = ((b) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ v[1] = ((b >> 10) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ v[2] = ((b >> 20) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ v[3] = ((b >> 30) & 0x3) * 1.0f/1.5f - 1.0f;
+ }
+ else
+ {
+ v[0] = ((b) & 0xff) * 1.0f/127.5f - 1.0f;
+ v[1] = ((b >> 8) & 0xff) * 1.0f/127.5f - 1.0f;
+ v[2] = ((b >> 16) & 0xff) * 1.0f/127.5f - 1.0f;
+ v[3] = ((b >> 24) & 0xff) * 1.0f/127.5f - 1.0f;
+ }
+}
+
+void R_VboUnpackNormal(vec3_t v, uint32_t b)
+{
+ if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
+ {
+ v[0] = ((b) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ v[1] = ((b >> 10) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ v[2] = ((b >> 20) & 0x3ff) * 1.0f/511.5f - 1.0f;
+ }
+ else
+ {
+ v[0] = ((b) & 0xff) * 1.0f/127.5f - 1.0f;
+ v[1] = ((b >> 8) & 0xff) * 1.0f/127.5f - 1.0f;
+ v[2] = ((b >> 16) & 0xff) * 1.0f/127.5f - 1.0f;
+ }
+}
+
/*
============
R_CreateVBO
@@ -142,14 +211,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
if(stateBits & ATTR_NORMAL)
{
vbo->ofs_normal = dataSize;
- dataSize += sizeof(uint8_t) * 4;
+ dataSize += sizeof(uint32_t);
}
#ifdef USE_VERT_TANGENT_SPACE
if(stateBits & ATTR_TANGENT)
{
vbo->ofs_tangent = dataSize;
- dataSize += sizeof(uint8_t) * 4;
+ dataSize += sizeof(uint32_t);
}
#endif
@@ -174,7 +243,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
if(stateBits & ATTR_LIGHTDIRECTION)
{
vbo->ofs_lightdir = dataSize;
- dataSize += sizeof(verts[0].lightdir);
+ dataSize += sizeof(uint32_t);
}
vbo->stride_xyz = dataSize;
@@ -204,31 +273,22 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
// normal
if(stateBits & ATTR_NORMAL)
{
- uint8_t *p = data + dataOfs;
+ uint32_t *p = (uint32_t *)(data + dataOfs);
- p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f);
- p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f);
- p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f);
- p[3] = 0;
+ *p = R_VboPackNormal(verts[i].normal);
- dataOfs += sizeof(uint8_t) * 4;
+ dataOfs += sizeof(uint32_t);
}
#ifdef USE_VERT_TANGENT_SPACE
// tangent
if(stateBits & ATTR_TANGENT)
{
- vec3_t nxt;
- uint8_t *p = data + dataOfs;
+ uint32_t *p = (uint32_t *)(data + dataOfs);
- CrossProduct(verts[i].normal, verts[i].tangent, nxt);
+ *p = R_VboPackTangent(verts[i].tangent);
- p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f);
- p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f);
- p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f);
- p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f);
-
- dataOfs += sizeof(uint8_t) * 4;
+ dataOfs += sizeof(uint32_t);
}
#endif
@@ -256,8 +316,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
// feed vertex light directions
if(stateBits & ATTR_LIGHTDIRECTION)
{
- memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
- dataOfs += sizeof(verts[i].lightdir);
+ uint32_t *p = (uint32_t *)(data + dataOfs);
+
+ *p = R_VboPackNormal(verts[i].lightdir);
+
+ dataOfs += sizeof(uint32_t);
}
}
}
@@ -268,13 +331,13 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
if(stateBits & ATTR_NORMAL)
{
- dataSize += sizeof(uint8_t) * 4;
+ dataSize += sizeof(uint32_t);
}
#ifdef USE_VERT_TANGENT_SPACE
if(stateBits & ATTR_TANGENT)
{
- dataSize += sizeof(uint8_t) * 4;
+ dataSize += sizeof(uint32_t);
}
#endif
@@ -295,7 +358,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
if(stateBits & ATTR_LIGHTDIRECTION)
{
- dataSize += sizeof(verts[0].lightdir);
+ dataSize += sizeof(uint32_t);
}
// create VBO
@@ -314,14 +377,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_lightdir = 0;
vbo->stride_xyz = sizeof(verts[0].xyz);
- vbo->stride_normal = sizeof(uint8_t) * 4;
+ vbo->stride_normal = sizeof(uint32_t);
#ifdef USE_VERT_TANGENT_SPACE
- vbo->stride_tangent = sizeof(uint8_t) * 4;
+ vbo->stride_tangent = sizeof(uint32_t);
#endif
vbo->stride_vertexcolor = sizeof(verts[0].vertexColors);
vbo->stride_st = sizeof(verts[0].st);
vbo->stride_lightmap = sizeof(verts[0].lightmap);
- vbo->stride_lightdir = sizeof(verts[0].lightdir);
+ vbo->stride_lightdir = sizeof(uint32_t);
//ri.Printf(PRINT_ALL, "2CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor,
//vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor);
@@ -339,14 +402,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_normal = dataOfs;
for (i = 0; i < numVertexes; i++)
{
- uint8_t *p = data + dataOfs;
+ uint32_t *p = (uint32_t *)(data + dataOfs);
- p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f);
- p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f);
- p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f);
- p[3] = 0;
+ *p = R_VboPackNormal(verts[i].normal);
- dataOfs += sizeof(uint8_t) * 4;
+ dataOfs += sizeof(uint32_t);
}
}
@@ -357,17 +417,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_tangent = dataOfs;
for (i = 0; i < numVertexes; i++)
{
- vec3_t nxt;
- uint8_t *p = data + dataOfs;
-
- CrossProduct(verts[i].normal, verts[i].tangent, nxt);
+ uint32_t *p = (uint32_t *)(data + dataOfs);
- p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f);
- p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f);
- p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f);
- p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f);
+ *p = R_VboPackTangent(verts[i].tangent);
- dataOfs += sizeof(uint8_t) * 4;
+ dataOfs += sizeof(uint32_t);
}
}
#endif
@@ -411,8 +465,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_lightdir = dataOfs;
for (i = 0; i < numVertexes; i++)
{
- memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
- dataOfs += sizeof(verts[i].lightdir);
+ uint32_t *p = (uint32_t *)(data + dataOfs);
+
+ *p = R_VboPackNormal(verts[i].lightdir);
+
+ dataOfs += sizeof(uint32_t);
}
}
}