OpenGL2: Support GL_ARB_vertex_type_2_10_10_10_rev for normals/tangents/lightdirs

This commit is contained in:
SmileTheory 2013-12-09 17:33:54 -08:00
parent 4c9d39ae6e
commit f6f3a19f73
13 changed files with 239 additions and 198 deletions

View file

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

View file

@ -411,9 +411,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];

View file

@ -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);
}
}

View file

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

View file

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

View file

@ -101,6 +101,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;
@ -1126,6 +1127,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 );

View file

@ -1423,6 +1423,8 @@ typedef struct {
qboolean depthClamp;
qboolean seamlessCubeMap;
GLenum packedNormalDataType;
} glRefConfig_t;
@ -1720,6 +1722,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
@ -2006,13 +2009,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;
@ -2176,6 +2179,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);

View file

@ -1574,9 +1574,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 )
{

View file

@ -683,9 +683,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;
@ -702,11 +702,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;
@ -725,18 +725,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
}
@ -765,14 +764,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);

View file

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

View file

@ -116,29 +116,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;
@ -147,13 +145,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;
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;
}
}
}
@ -169,14 +165,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,
@ -195,9 +189,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);
}
}
@ -211,22 +203,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,10 +277,7 @@ void DeformText( const char *text ) {
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

View file

@ -124,25 +124,10 @@ 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);
@ -331,10 +316,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;
@ -361,28 +347,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
@ -413,9 +389,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
@ -1150,14 +1126,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)
{
@ -1172,14 +1148,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
@ -1200,15 +1173,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++;
}
}
@ -1330,11 +1300,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;
@ -1417,14 +1388,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++ ) {
@ -1440,21 +1411,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 )
@ -1477,8 +1440,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;

View file

@ -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;
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
@ -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);
}
}
}