mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-23 04:32:28 +00:00
Version 13 of the VBO and GLSL patch
This commit is contained in:
parent
8153444877
commit
1d54461fbf
19 changed files with 1487 additions and 242 deletions
|
@ -70,6 +70,7 @@ void GL_SelectTexture( int unit )
|
|||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( unit == 0 )
|
||||
{
|
||||
qglActiveTextureARB( GL_TEXTURE0_ARB );
|
||||
|
@ -92,6 +93,13 @@ void GL_SelectTexture( int unit )
|
|||
} else {
|
||||
ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit );
|
||||
}
|
||||
#else
|
||||
qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
|
||||
if (!(glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer && glRefConfig.glsl && r_arb_shader_objects->integer))
|
||||
{
|
||||
qglClientActiveTextureARB( GL_TEXTURE0_ARB + unit );
|
||||
}
|
||||
#endif
|
||||
|
||||
glState.currenttmu = unit;
|
||||
}
|
||||
|
@ -1021,13 +1029,16 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
|
||||
if (glRefConfig.glsl && r_arb_shader_objects->integer)
|
||||
{
|
||||
shaderProgram_t *sp = &tr.textureOnlyShader;
|
||||
shaderProgram_t *sp = &tr.textureColorShader;
|
||||
vec4_t color;
|
||||
|
||||
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
|
||||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1481,3 +1492,4 @@ void RB_RenderThread( void ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -255,6 +255,7 @@ static void R_LoadLightmaps( lump_t *l ) {
|
|||
//int BIGNUM=16;
|
||||
|
||||
byte *fatbuffer;
|
||||
byte *fatbuffer2;
|
||||
int xoff, yoff, x, y;
|
||||
//float scale = 0.9f;
|
||||
|
||||
|
@ -273,6 +274,9 @@ static void R_LoadLightmaps( lump_t *l ) {
|
|||
|
||||
// create all the lightmaps
|
||||
numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
|
||||
|
||||
numLightmaps >>= (tr.worldDeluxeMapping ? 1 : 0);
|
||||
|
||||
if(numLightmaps == 1)
|
||||
{
|
||||
//FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
|
||||
|
@ -304,18 +308,33 @@ static void R_LoadLightmaps( lump_t *l ) {
|
|||
|
||||
// This is going to be huge (4, 16, or 64MB), so don't use ri.Malloc()
|
||||
fatbuffer = ri.Hunk_AllocateTempMemory(sizeof(byte) * tr.fatLightmapSize * tr.fatLightmapSize * 4);
|
||||
|
||||
Com_Memset(fatbuffer, 128, tr.fatLightmapSize * tr.fatLightmapSize * 4);
|
||||
|
||||
if (tr.worldDeluxeMapping)
|
||||
{
|
||||
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
|
||||
fatbuffer2 = ri.Hunk_AllocateTempMemory(sizeof(byte) * tr.fatLightmapSize * tr.fatLightmapSize * 4);
|
||||
Com_Memset(fatbuffer2, 128, tr.fatLightmapSize * tr.fatLightmapSize * 4);
|
||||
}
|
||||
|
||||
for(i = 0; i < numLightmaps; i++)
|
||||
{
|
||||
// expand the 24 bit on-disk to 32 bit
|
||||
|
||||
if (tr.worldDeluxeMapping)
|
||||
{
|
||||
buf_p = buf + (i * 2) * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_p = buf + i * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
|
||||
}
|
||||
|
||||
|
||||
xoff = i % tr.fatLightmapStep;
|
||||
yoff = i / tr.fatLightmapStep;
|
||||
|
||||
//if (tr.radbumping==qfalse)
|
||||
if(1)
|
||||
// if (tr.worldLightmapping)
|
||||
{
|
||||
for(y = 0; y < LIGHTMAP_SIZE; y++)
|
||||
{
|
||||
|
@ -332,32 +351,39 @@ static void R_LoadLightmaps( lump_t *l ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
/*else
|
||||
|
||||
if (tr.worldDeluxeMapping)
|
||||
{
|
||||
//We need to darken the lightmaps a little bit when mixing radbump and fallback path rendering
|
||||
//because radbump will be darker due to the error introduced by using 3 basis vector probes for lighting instead of surf normal.
|
||||
buf_p = buf + (i * 2 + 1) * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
|
||||
|
||||
for(y = 0; y < LIGHTMAP_SIZE; y++)
|
||||
{
|
||||
for(x = 0; x < LIGHTMAP_SIZE; x++)
|
||||
{
|
||||
int index = (x+(y*tr.fatLightmapSize))+((xoff*LIGHTMAP_SIZE)+(yoff*tr.fatLightmapSize*LIGHTMAP_SIZE));
|
||||
fatbuffer[(index*4)+0 ]=(byte)(((float)buf_p[((x+(y*LIGHTMAP_SIZE))*3)+0])*scale);
|
||||
fatbuffer[(index*4)+1 ]=(byte)(((float)buf_p[((x+(y*LIGHTMAP_SIZE))*3)+1])*scale);
|
||||
fatbuffer[(index*4)+2 ]=(byte)(((float)buf_p[((x+(y*LIGHTMAP_SIZE))*3)+2])*scale);
|
||||
fatbuffer[(index*4)+3 ]=255;
|
||||
int index =
|
||||
(x + (y * tr.fatLightmapSize)) + ((xoff * LIGHTMAP_SIZE) + (yoff * tr.fatLightmapSize * LIGHTMAP_SIZE));
|
||||
fatbuffer2[(index * 4) + 0] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 0];
|
||||
fatbuffer2[(index * 4) + 1] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 1];
|
||||
fatbuffer2[(index * 4) + 2] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 2];
|
||||
fatbuffer2[(index * 4) + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} */
|
||||
|
||||
|
||||
}
|
||||
//memset(fatbuffer,128,tr.fatLightmapSize*tr.fatLightmapSize*4);
|
||||
|
||||
tr.fatLightmap = R_CreateImage(va("_fatlightmap%d", 0), fatbuffer, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
|
||||
tr.lightmaps[0] = tr.fatLightmap;
|
||||
|
||||
ri.Hunk_FreeTempMemory(fatbuffer);
|
||||
|
||||
if (tr.worldDeluxeMapping)
|
||||
{
|
||||
tr.fatDeluxemap = R_CreateImage(va("_fatdeluxemap%d", 0), fatbuffer2, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
|
||||
tr.deluxemaps[0] = tr.fatDeluxemap;
|
||||
|
||||
ri.Hunk_FreeTempMemory(fatbuffer2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -366,7 +392,7 @@ static float FatPackU(float input, int lightmapnum)
|
|||
{
|
||||
if(tr.fatLightmapSize > 0)
|
||||
{
|
||||
int x = lightmapnum % tr.fatLightmapStep;
|
||||
int x = (lightmapnum >> (tr.worldDeluxeMapping ? 1 : 0)) % tr.fatLightmapStep;
|
||||
|
||||
return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)x);
|
||||
}
|
||||
|
@ -378,7 +404,7 @@ static float FatPackV(float input, int lightmapnum)
|
|||
{
|
||||
if(tr.fatLightmapSize > 0)
|
||||
{
|
||||
int y = lightmapnum / ((float)tr.fatLightmapStep);
|
||||
int y = (lightmapnum >> (tr.worldDeluxeMapping ? 1 : 0)) / tr.fatLightmapStep;
|
||||
|
||||
return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)y);
|
||||
}
|
||||
|
@ -575,6 +601,68 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int
|
|||
cv->plane.type = PlaneTypeForNormal( cv->plane.normal );
|
||||
|
||||
surf->data = (surfaceType_t *)cv;
|
||||
|
||||
// Tr3B - calc tangent spaces
|
||||
#if 0
|
||||
{
|
||||
float *v;
|
||||
const float *v0, *v1, *v2;
|
||||
const float *t0, *t1, *t2;
|
||||
vec3_t tangent;
|
||||
vec3_t bitangent;
|
||||
vec3_t normal;
|
||||
|
||||
for(i = 0; i < numVerts; i++)
|
||||
{
|
||||
VectorClear(cv->verts[i].tangent);
|
||||
VectorClear(cv->verts[i].bitangent);
|
||||
VectorClear(cv->verts[i].normal);
|
||||
}
|
||||
|
||||
for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
v0 = cv->verts[tri->indexes[0]].xyz;
|
||||
v1 = cv->verts[tri->indexes[1]].xyz;
|
||||
v2 = cv->verts[tri->indexes[2]].xyz;
|
||||
|
||||
t0 = cv->verts[tri->indexes[0]].st;
|
||||
t1 = cv->verts[tri->indexes[1]].st;
|
||||
t2 = cv->verts[tri->indexes[2]].st;
|
||||
|
||||
R_CalcTangentSpace(tangent, bitangent, normal, v0, v1, v2, t0, t1, t2);
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
v = cv->verts[tri->indexes[j]].tangent;
|
||||
VectorAdd(v, tangent, v);
|
||||
v = cv->verts[tri->indexes[j]].bitangent;
|
||||
VectorAdd(v, bitangent, v);
|
||||
v = cv->verts[tri->indexes[j]].normal;
|
||||
VectorAdd(v, normal, v);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < numVerts; i++)
|
||||
{
|
||||
VectorNormalize(cv->verts[i].tangent);
|
||||
VectorNormalize(cv->verts[i].bitangent);
|
||||
VectorNormalize(cv->verts[i].normal);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
srfVert_t *dv[3];
|
||||
|
||||
for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
dv[0] = &cv->verts[tri->indexes[0]];
|
||||
dv[1] = &cv->verts[tri->indexes[1]];
|
||||
dv[2] = &cv->verts[tri->indexes[2]];
|
||||
|
||||
R_CalcTangentVectors(dv);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -740,6 +828,84 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, i
|
|||
ri.Printf(PRINT_WARNING, "Surface has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles);
|
||||
cv->numTriangles -= badTriangles;
|
||||
}
|
||||
|
||||
// Tr3B - calc tangent spaces
|
||||
#if 0
|
||||
{
|
||||
float *v;
|
||||
const float *v0, *v1, *v2;
|
||||
const float *t0, *t1, *t2;
|
||||
vec3_t tangent;
|
||||
vec3_t bitangent;
|
||||
vec3_t normal;
|
||||
|
||||
for(i = 0; i < numVerts; i++)
|
||||
{
|
||||
VectorClear(cv->verts[i].tangent);
|
||||
VectorClear(cv->verts[i].bitangent);
|
||||
VectorClear(cv->verts[i].normal);
|
||||
}
|
||||
|
||||
for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
v0 = cv->verts[tri->indexes[0]].xyz;
|
||||
v1 = cv->verts[tri->indexes[1]].xyz;
|
||||
v2 = cv->verts[tri->indexes[2]].xyz;
|
||||
|
||||
t0 = cv->verts[tri->indexes[0]].st;
|
||||
t1 = cv->verts[tri->indexes[1]].st;
|
||||
t2 = cv->verts[tri->indexes[2]].st;
|
||||
|
||||
#if 1
|
||||
R_CalcTangentSpace(tangent, bitangent, normal, v0, v1, v2, t0, t1, t2);
|
||||
#else
|
||||
R_CalcNormalForTriangle(normal, v0, v1, v2);
|
||||
R_CalcTangentsForTriangle2(tangent, bitangent, v0, v1, v2, t0, t1, t2);
|
||||
#endif
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
v = cv->verts[tri->indexes[j]].tangent;
|
||||
VectorAdd(v, tangent, v);
|
||||
v = cv->verts[tri->indexes[j]].bitangent;
|
||||
VectorAdd(v, bitangent, v);
|
||||
v = cv->verts[tri->indexes[j]].normal;
|
||||
VectorAdd(v, normal, v);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < numVerts; i++)
|
||||
{
|
||||
float dot;
|
||||
|
||||
//VectorNormalize(cv->verts[i].tangent);
|
||||
VectorNormalize(cv->verts[i].bitangent);
|
||||
VectorNormalize(cv->verts[i].normal);
|
||||
|
||||
// Gram-Schmidt orthogonalize
|
||||
dot = DotProduct(cv->verts[i].normal, cv->verts[i].tangent);
|
||||
VectorMA(cv->verts[i].tangent, -dot, cv->verts[i].normal, cv->verts[i].tangent);
|
||||
VectorNormalize(cv->verts[i].tangent);
|
||||
|
||||
//dot = DotProduct(cv->verts[i].normal, cv->verts[i].tangent);
|
||||
//VectorMA(cv->verts[i].tangent, -dot, cv->verts[i].normal, cv->verts[i].tangent);
|
||||
//VectorNormalize(cv->verts[i].tangent);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
srfVert_t *dv[3];
|
||||
|
||||
for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
dv[0] = &cv->verts[tri->indexes[0]];
|
||||
dv[1] = &cv->verts[tri->indexes[1]];
|
||||
dv[2] = &cv->verts[tri->indexes[2]];
|
||||
|
||||
R_CalcTangentVectors(dv);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1526,8 +1692,8 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out)
|
|||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
out->xyz[j] = in->xyz[j];
|
||||
//out->tangent[j] = in->tangent[j];
|
||||
//out->binormal[j] = in->binormal[j];
|
||||
out->tangent[j] = in->tangent[j];
|
||||
out->bitangent[j] = in->bitangent[j];
|
||||
out->normal[j] = in->normal[j];
|
||||
//out->lightDirection[j] = in->lightDirection[j];
|
||||
}
|
||||
|
@ -1794,12 +1960,12 @@ static void R_CreateWorldVBO(void)
|
|||
}
|
||||
|
||||
s_worldData.vbo = R_CreateVBO2(va("bspModelMesh_vertices %i", 0), numVerts, optimizedVerts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BINORMAL |
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT |
|
||||
ATTR_NORMAL | ATTR_COLOR | GLCS_LIGHTCOLOR | ATTR_LIGHTDIRECTION);
|
||||
#else
|
||||
s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR,
|
||||
VBO_USAGE_STATIC);
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT |
|
||||
ATTR_NORMAL | ATTR_COLOR, VBO_USAGE_STATIC);
|
||||
#endif
|
||||
|
||||
s_worldData.ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", 0), numTriangles, triangles, VBO_USAGE_STATIC);
|
||||
|
@ -2488,6 +2654,20 @@ void R_LoadEntities( lump_t *l ) {
|
|||
sscanf(value, "%f %f %f", &w->lightGridSize[0], &w->lightGridSize[1], &w->lightGridSize[2] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for deluxe mapping provided by NetRadiant's q3map2
|
||||
//FIXME: xmap2?
|
||||
if(!Q_stricmp(keyname, "_q3map2_cmdline"))
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "wtf? %s %s\n", keyname, value);
|
||||
s = strstr(value, "-deluxe");
|
||||
if(s)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "map features directional light mapping\n");
|
||||
tr.worldDeluxeMapping = qtrue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2938,6 +3118,7 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
}
|
||||
|
||||
// load into heap
|
||||
R_LoadEntities( &header->lumps[LUMP_ENTITIES] );
|
||||
R_LoadShaders( &header->lumps[LUMP_SHADERS] );
|
||||
R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS] );
|
||||
R_LoadPlanes (&header->lumps[LUMP_PLANES]);
|
||||
|
@ -2947,7 +3128,6 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
R_LoadNodesAndLeafs (&header->lumps[LUMP_NODES], &header->lumps[LUMP_LEAFS]);
|
||||
R_LoadSubmodels (&header->lumps[LUMP_MODELS]);
|
||||
R_LoadVisibility( &header->lumps[LUMP_VISIBILITY] );
|
||||
R_LoadEntities( &header->lumps[LUMP_ENTITIES] );
|
||||
R_LoadLightGrid( &header->lumps[LUMP_LIGHTGRID] );
|
||||
|
||||
// create static VBOS from the world
|
||||
|
@ -2975,3 +3155,4 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
ri.FS_FreeFile( buffer.v );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -214,6 +214,85 @@ static int neighbors[8][2] = {
|
|||
}
|
||||
|
||||
|
||||
static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numTriangles,
|
||||
srfTriangle_t triangles[SHADER_MAX_TRIANGLES])
|
||||
{
|
||||
int i, j;
|
||||
srfVert_t *dv[3];
|
||||
static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE];
|
||||
srfTriangle_t *tri;
|
||||
|
||||
// FIXME: use more elegant way
|
||||
for(i = 0; i < width; i++)
|
||||
{
|
||||
for(j = 0; j < height; j++)
|
||||
{
|
||||
dv[0] = &ctrl2[j * width + i];
|
||||
*dv[0] = ctrl[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
dv[0] = &ctrl2[tri->indexes[0]];
|
||||
dv[1] = &ctrl2[tri->indexes[1]];
|
||||
dv[2] = &ctrl2[tri->indexes[2]];
|
||||
|
||||
R_CalcTangentVectors(dv);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for(i = 0; i < (width * height); i++)
|
||||
{
|
||||
dv0 = &ctrl2[i];
|
||||
|
||||
VectorNormalize(dv0->normal);
|
||||
#if 0
|
||||
VectorNormalize(dv0->tangent);
|
||||
VectorNormalize(dv0->bitangent);
|
||||
#else
|
||||
d = DotProduct(dv0->tangent, dv0->normal);
|
||||
VectorMA(dv0->tangent, -d, dv0->normal, dv0->tangent);
|
||||
VectorNormalize(dv0->tangent);
|
||||
|
||||
d = DotProduct(dv0->bitangent, dv0->normal);
|
||||
VectorMA(dv0->bitangent, -d, dv0->normal, dv0->bitangent);
|
||||
VectorNormalize(dv0->bitangent);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// do another extra smoothing for normals to avoid flat shading
|
||||
for(i = 0; i < (width * height); i++)
|
||||
{
|
||||
for(j = 0; j < (width * height); j++)
|
||||
{
|
||||
if(R_CompareVert(&ctrl2[i], &ctrl2[j], qfalse))
|
||||
{
|
||||
VectorAdd(ctrl2[i].normal, ctrl2[j].normal, ctrl2[i].normal);
|
||||
}
|
||||
}
|
||||
|
||||
VectorNormalize(ctrl2[i].normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(i = 0; i < width; i++)
|
||||
{
|
||||
for(j = 0; j < height; j++)
|
||||
{
|
||||
dv[0] = &ctrl2[j * width + i];
|
||||
dv[1] = &ctrl[j][i];
|
||||
|
||||
VectorCopy(dv[0]->tangent, dv[1]->tangent);
|
||||
VectorCopy(dv[0]->bitangent, dv[1]->bitangent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
||||
srfTriangle_t triangles[SHADER_MAX_TRIANGLES])
|
||||
{
|
||||
|
@ -589,6 +668,7 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
|||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
MakeMeshTangentVectors(width, height, ctrl, numTriangles, triangles);
|
||||
|
||||
return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles);
|
||||
}
|
||||
|
|
|
@ -527,3 +527,4 @@ void RB_RenderFlares (void) {
|
|||
GL_SetModelviewMatrix(oldmodelview);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -87,60 +87,57 @@ static const char *fallbackGenericShader_vp =
|
|||
"ot(position.xyz, TCGenVector0.xyz);\r\n\t\ttex.t = dot(position.xyz, TCGenV"
|
||||
"ector1.xyz);\r\n\t}\r\n\t\r\n\treturn tex;\r\n}\r\n#endif\r\n\r\nvoid main("
|
||||
")\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\tvec4 tex;\r\n\r\n#if defi"
|
||||
"ned(USE_VERTEX_ANIMATION)\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t\tpositi"
|
||||
"on = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnormal = mix("
|
||||
"attr_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize(normal)"
|
||||
";\r\n\t}\r\n\telse\r\n#endif\r\n\t{\r\n\t\tposition = attr_Position;\r\n\t"
|
||||
"\tnormal = attr_Normal;\r\n\t}\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\n"
|
||||
"\tposition = DeformPosition(position, normal, attr_TexCoord0.st);\r\n#endif"
|
||||
"\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;\r\n\r\n\r\n"
|
||||
"\ttex = vec4(1.0, 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGEN)\r\n\ttex.st"
|
||||
" = GenTexCoords(u_TCGen0, position, normal, u_Texture0Matrix, u_TCGen0Vecto"
|
||||
"r0, u_TCGen0Vector1);\r\n#else\r\n\ttex.st = attr_TexCoord0.st;\r\n#endif\r"
|
||||
"\n \r\n\tvar_Tex1 = (u_Texture0Matrix * tex).st;\r\n\r\n\tif (u_Texture0"
|
||||
"Matrix[3][0] != 0)\r\n\t{\r\n\t\tvar_Tex1.s += sin(((position.x + position."
|
||||
"z) * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Textur"
|
||||
"e0Matrix[3][0];\r\n\t\tvar_Tex1.t += sin((position.y * 1.0 / 128.0 * 0.125 "
|
||||
"+ u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n\t}\r"
|
||||
"\n\r\n\tvar_Tex2 = attr_TexCoord1.st;\r\n\r\n\tif (u_ColorGen == CGEN_IDENT"
|
||||
"ITY)\r\n\t{\r\n\t\tvar_Color.rgb = vec3(1.0);\r\n\t}\r\n\telse if (u_ColorG"
|
||||
"en == CGEN_LIGHTING_DIFFUSE)\r\n\t{\r\n\t\tfloat incoming = dot(attr_Normal"
|
||||
", u_LightDir);\r\n\r\n\t\tif (incoming <= 0)\r\n\t\t{\r\n\t\t\tvar_Color.rg"
|
||||
"b = u_AmbientLight;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tvar_Color.rgb = "
|
||||
"min(u_AmbientLight + u_DirectedLight * incoming, vec3(1));\r\n\t\t}\r\n\t}"
|
||||
"\r\n\telse if (u_ColorGen == CGEN_EXACT_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb"
|
||||
" = attr_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_VERTEX)\r\n\t{\r"
|
||||
"\n\t\tvar_Color.rgb = attr_Color.rgb * u_Color.rgb;\r\n\t}\r\n\telse if (u_"
|
||||
"ColorGen == CGEN_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = (vec3(1.0)"
|
||||
" - attr_Color.rgb) * u_Color.rgb;\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color."
|
||||
"rgb = u_Color.rgb;\r\n\t}\r\n\r\n\tif (u_AlphaGen == AGEN_IDENTITY)\r\n\t{"
|
||||
"\r\n\t\tvar_Color.a = 1.0;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_LIGHTING"
|
||||
"_SPECULAR)\r\n\t{\r\n\t\tvec3 lightDir = vec3(-960.0, -1980.0, 96.0) - posi"
|
||||
"tion.xyz;\r\n\t\tlightDir = normalize(lightDir);\r\n\r\n\t\tfloat d = dot(a"
|
||||
"ttr_Normal, lightDir);\r\n\t\tvec3 reflected = attr_Normal * 2.0 * d - ligh"
|
||||
"tDir;\r\n\r\n\t\tvec3 viewer = u_ViewOrigin - position.xyz;\r\n\t\tfloat il"
|
||||
"ength = 1.0 / length(viewer);\r\n\r\n\t\tfloat l = dot(reflected, viewer);"
|
||||
"\r\n\t\tl *= ilength;\r\n\r\n\t\tif (l < 0.0)\r\n\t\t{\r\n\t\t\tvar_Color.a"
|
||||
" = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tl = l*l;\r\n\t\t\tl = l*l;\r"
|
||||
"\n\t\t\tvar_Color.a = min(l, 1.0);\r\n\t\t}\r\n\t}\r\n\telse if (u_AlphaGen"
|
||||
" == AGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = attr_Color.a;\r\n\t}\r\n\telse"
|
||||
" if (u_AlphaGen == AGEN_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 -"
|
||||
" attr_Color.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t"
|
||||
"\tfloat len;\r\n\t\tvec3 v;\r\n\r\n\t\tv = position.xyz - u_ViewOrigin;\r\n"
|
||||
"\t\tlen = length(v);\r\n\r\n\t\tlen /= u_PortalRange;\r\n\r\n\t\tvar_Color."
|
||||
"a = clamp(len, 0.0, 1.0);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color.a = u_Co"
|
||||
"lor.a;\r\n\t}\r\n\r\n#if defined (USE_FOG)\r\n\tif (u_FogAdjustColors != AC"
|
||||
"FF_NONE) \r\n\t{\r\n\t\tfloat s = dot(position.xyz, u_FogDistance.xyz) + u_"
|
||||
"FogDistance.a;\r\n\t\tfloat t = dot(position.xyz, u_FogDepth.xyz) + u_FogDe"
|
||||
"pth.a;\r\n\t\t\r\n\t\tif (s < 0.0 || t < 0.0 || (u_FogEyeT < 0.0 && t < 1.0"
|
||||
") )\r\n\t\t{\r\n\t\t\ts = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif (u"
|
||||
"_FogEyeT < 0.0)\r\n\t\t\t{\r\n\t\t\t\ts *= t / (t - u_FogEyeT);\r\n\t\t\t}"
|
||||
"\r\n\r\n\t\t\ts *= 8.0;\r\n\t\t\t\t \r\n\t\t\ts = clamp(s, 0.0, 1.0);\r\n"
|
||||
"\r\n\t\t\ts = 1.0 - sqrt(s);\r\n\t\t}\r\n\t\t\r\n\t\tif (u_FogAdjustColors "
|
||||
"== ACFF_MODULATE_RGB)\r\n\t\t{\r\n\t\t\tvar_Color.xyz *= s;\r\n\t\t}\r\n\t"
|
||||
"\telse if (u_FogAdjustColors == ACFF_MODULATE_ALPHA)\r\n\t\t{\r\n\t\t\tvar_"
|
||||
"Color.a *= s;\r\n\t\t}\r\n\t\telse if (u_FogAdjustColors == ACFF_MODULATE_R"
|
||||
"GBA)\r\n\t\t{\r\n\t\t\tvar_Color *= s;\r\n\t\t}\r\n\t}\r\n#endif\r\n}\r\n";
|
||||
"ned(USE_VERTEX_ANIMATION)\r\n\tposition = mix(attr_Position, attr_Position2"
|
||||
", u_VertexLerp);\r\n\tnormal = normalize(mix(attr_Normal, attr_Normal2, u_V"
|
||||
"ertexLerp));\r\n#else\r\n\tposition = attr_Position;\r\n\tnormal = attr_Nor"
|
||||
"mal;\r\n#endif\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\n\tposition = Defo"
|
||||
"rmPosition(position, normal, attr_TexCoord0.st);\r\n#endif\r\n\r\n\tgl_Posi"
|
||||
"tion = u_ModelViewProjectionMatrix * position;\r\n\r\n\r\n\ttex = vec4(1.0,"
|
||||
" 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGEN)\r\n\ttex.st = GenTexCoords(u"
|
||||
"_TCGen0, position, normal, u_Texture0Matrix, u_TCGen0Vector0, u_TCGen0Vecto"
|
||||
"r1);\r\n#else\r\n\ttex.st = attr_TexCoord0.st;\r\n#endif\r\n \r\n\tvar_T"
|
||||
"ex1 = (u_Texture0Matrix * tex).st;\r\n\r\n\tvar_Tex1.s += sin(((position.x "
|
||||
"+ position.z) * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI)"
|
||||
" * u_Texture0Matrix[3][0];\r\n\tvar_Tex1.t += sin((position.y * 1.0 / 128.0"
|
||||
" * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];"
|
||||
"\r\n\r\n\tvar_Tex2 = attr_TexCoord1.st;\r\n\t\r\n\tvar_Color = u_Color;\r\n"
|
||||
"\r\n\tif (u_ColorGen == CGEN_LIGHTING_DIFFUSE)\r\n\t{\r\n\t\tfloat incoming"
|
||||
" = max(dot(normal, u_LightDir), 0.0);\r\n\r\n\t\tvar_Color.rgb = min(u_Dire"
|
||||
"ctedLight * incoming + u_AmbientLight, 1.0);\r\n\t}\r\n\telse if (u_ColorGe"
|
||||
"n == CGEN_EXACT_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = attr_Color.rgb;\r\n\t"
|
||||
"}\r\n\telse if (u_ColorGen == CGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb *= a"
|
||||
"ttr_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_ONE_MINUS_VERTEX)\r"
|
||||
"\n\t{\r\n\t\tvar_Color.rgb *= (vec3(1.0) - attr_Color.rgb);\r\n\t}\r\n\r\n"
|
||||
"\tif (u_AlphaGen == AGEN_LIGHTING_SPECULAR)\r\n\t{\r\n#if 0 // phong specul"
|
||||
"ar\r\n\t\tvec3 lightDir = vec3(-960.0, -1980.0, 96.0) - position.xyz;\r\n\t"
|
||||
"\tlightDir = normalize(lightDir);\r\n\r\n\t\tfloat d = dot(normal, lightDir"
|
||||
");\r\n\t\tvec3 reflected = normal * 2.0 * d - lightDir;\r\n\r\n\t\tvec3 vie"
|
||||
"wer = u_ViewOrigin - position.xyz;\r\n\t\tfloat ilength = 1.0 / length(view"
|
||||
"er);\r\n\r\n\t\tfloat l = dot(reflected, viewer);\r\n\t\tl *= ilength;\r\n"
|
||||
"\r\n\t\tif (l < 0.0)\r\n\t\t{\r\n\t\t\tvar_Color.a = 0.0;\r\n\t\t}\r\n\t\te"
|
||||
"lse\r\n\t\t{\r\n\t\t\tl = l*l;\r\n\t\t\tl = l*l;\r\n\t\t\tvar_Color.a = min"
|
||||
"(l, 1.0);\r\n\t\t}\r\n#else // blinn specular\r\n\t\tvec3 lightDir = normal"
|
||||
"ize(vec3(-960.0, -1980.0, 96.0) - position.xyz);\r\n\t\tvec3 viewer = norma"
|
||||
"lize(u_ViewOrigin - position.xyz);\r\n\t\tvec3 halfangle = normalize(lightD"
|
||||
"ir + viewer);\r\n\t\t\r\n\t\tvar_Color.a = pow(max(dot(normal, halfangle), "
|
||||
"0.0), 4.0);\r\n#endif\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_VERTEX)\r\n\t"
|
||||
"{\r\n\t\tvar_Color.a = attr_Color.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGE"
|
||||
"N_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 - attr_Color.a;\r\n\t}"
|
||||
"\r\n\telse if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t\tfloat alpha = lengt"
|
||||
"h(position.xyz - u_ViewOrigin) / u_PortalRange;\r\n\r\n\t\tvar_Color.a = mi"
|
||||
"n(alpha, 1.0);\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_FRESNEL)\r\n\t{\r\n"
|
||||
"\t\tvec3 viewer = normalize(u_ViewOrigin - position.xyz);\r\n\t\t\r\n\t\tva"
|
||||
"r_Color.a = dot(viewer, normal);\r\n\t}\r\n\r\n#if defined (USE_FOG)\r\n\ti"
|
||||
"f (u_FogAdjustColors != ACFF_NONE) \r\n\t{\r\n\t\tfloat s = max(dot(positio"
|
||||
"n.xyz, u_FogDistance.xyz) + u_FogDistance.a, 0.0);\r\n\t\tfloat t = max(dot"
|
||||
"(position.xyz, u_FogDepth.xyz) + u_FogDepth.a, 0.0);\r\n\t\t\r\n\t\tif (t >"
|
||||
"= 1.0)\r\n\t\t{\r\n\t\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t\t}\r\n\t"
|
||||
"\t\r\n\t\ts = 1.0 - sqrt(min(s * 8.0, 1.0));\r\n\t\r\n\t\tif (u_FogAdjustCo"
|
||||
"lors == ACFF_MODULATE_RGB)\r\n\t\t{\r\n\t\t\tvar_Color.xyz *= s;\r\n\t\t}\r"
|
||||
"\n\t\telse if (u_FogAdjustColors == ACFF_MODULATE_ALPHA)\r\n\t\t{\r\n\t\t\t"
|
||||
"var_Color.a *= s;\r\n\t\t}\r\n\t\telse if (u_FogAdjustColors == ACFF_MODULA"
|
||||
"TE_RGBA)\r\n\t\t{\r\n\t\t\tvar_Color *= s;\r\n\t\t}\r\n\t}\r\n#endif\r\n}\r"
|
||||
"\n";
|
||||
|
||||
static const char *fallbackGenericShader_fp =
|
||||
"uniform sampler2D u_Texture0Map;\r\nuniform sampler2D u_Texture1Map;\r\nuni"
|
||||
|
@ -177,17 +174,17 @@ static const char *fallbackLightmappedShader_fp =
|
|||
"\n\tcolor = texture2D(u_Texture0Map, var_Tex1);\r\n\tlight = texture2D(u_Te"
|
||||
"xture1Map, var_Tex2);\r\n\r\n\tgl_FragColor = color * light;\r\n}\r\n";
|
||||
|
||||
static const char *fallbackTextureOnlyShader_vp =
|
||||
static const char *fallbackTextureColorShader_vp =
|
||||
"#version 120\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_Te"
|
||||
"xCoord0;\r\n\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\n\r\nvarying "
|
||||
"vec2 var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_ModelView"
|
||||
"ProjectionMatrix * attr_Position;\r\n\tvar_Tex1 = attr_TexCoord0.st;\r\n}\r"
|
||||
"\n";
|
||||
|
||||
static const char *fallbackTextureOnlyShader_fp =
|
||||
"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\n\r\nvarying vec2"
|
||||
" var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor = texture2"
|
||||
"D(u_Texture0Map, var_Tex1);\r\n}\r\n";
|
||||
static const char *fallbackTextureColorShader_fp =
|
||||
"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\nuniform vec4 u"
|
||||
"_Color;\r\n\r\nvarying vec2 var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r"
|
||||
"\n\tgl_FragColor = texture2D(u_Texture0Map, var_Tex1) * u_Color;\r\n}\r\n";
|
||||
|
||||
static const char *fallbackFogPassShader_vp =
|
||||
"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute"
|
||||
|
@ -234,19 +231,16 @@ static const char *fallbackFogPassShader_vp =
|
|||
"\n\r\n\r\nvoid\tmain()\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\r\n//"
|
||||
"#if defined(USE_VERTEX_ANIMATION)\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t"
|
||||
"\tposition = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnorma"
|
||||
"l = mix(attr_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize"
|
||||
"(normal);\r\n\t}\r\n\telse\r\n//#endif\r\n\t{\r\n\t\tposition = attr_Positi"
|
||||
"on;\r\n\t\tnormal = attr_Normal;\r\n\t}\r\n\r\n//#if defined(USE_DEFORM_VER"
|
||||
"TEXES)\r\n\tposition = DeformPosition(position, normal, attr_TexCoord0.st);"
|
||||
"\r\n//#endif\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;"
|
||||
"\r\n\r\n\t{\r\n\t\tfloat s = dot(position.xyz, u_FogDistance.xyz) + u_FogDi"
|
||||
"stance.a;\r\n\t\tfloat t = dot(position.xyz, u_FogDepth.xyz) + u_FogDepth.a"
|
||||
";\r\n\r\n\t\tif (s < 0.0 || t < 0.0 || (u_FogEyeT < 0.0 && t < 1.0) )\r\n\t"
|
||||
"\t{\r\n\t\t\ts = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif (u_FogEyeT "
|
||||
"< 0.0)\r\n\t\t\t{\r\n\t\t\t\ts *= t / (t - u_FogEyeT);\r\n\t\t\t}\r\n\r\n\t"
|
||||
"\t\ts *= 8.0;\r\n\t\t \r\n\t\t\ts = clamp(s, 0.0, 1.0);\r\n\r\n\t\t\ts = s"
|
||||
"qrt(s);\r\n\t\t}\r\n\r\n\t\tvar_Color.xyz = u_Color.xyz;\r\n\t\tvar_Color.a"
|
||||
" = u_Color.a * s;\r\n\t}\r\n}\r\n";
|
||||
"l = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));\r\n\t}\r\n\tel"
|
||||
"se\r\n//#endif\r\n\t{\r\n\t\tposition = attr_Position;\r\n\t\tnormal = attr"
|
||||
"_Normal;\r\n\t}\r\n\r\n//#if defined(USE_DEFORM_VERTEXES)\r\n\tposition = D"
|
||||
"eformPosition(position, normal, attr_TexCoord0.st);\r\n//#endif\r\n\r\n\tgl"
|
||||
"_Position = u_ModelViewProjectionMatrix * position;\r\n\r\n\tfloat s = max("
|
||||
"dot(position.xyz, u_FogDistance.xyz) + u_FogDistance.a, 0.0);\r\n\tfloat t "
|
||||
"= max(dot(position.xyz, u_FogDepth.xyz) + u_FogDepth.a, 0.0);\r\n\t\r\n\tif"
|
||||
" (t >= 1.0)\r\n\t{\r\n\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t}\r\n\t"
|
||||
"\r\n\ts = sqrt(min(s * 8.0, 1.0));\r\n\t\r\n\tvar_Color.xyz = u_Color.xyz;"
|
||||
"\r\n\tvar_Color.a = u_Color.a * s;\r\n}\r\n";
|
||||
|
||||
static const char *fallbackFogPassShader_fp =
|
||||
"varying vec4 var_Color;\r\n\r\n\r\nvoid\tmain()\r\n{\r\n\tgl_FragCo"
|
||||
|
@ -291,28 +285,73 @@ static const char *fallbackDlightShader_vp =
|
|||
" = (M_PI * 0.25) * st.x * bulgeWidth + now;\r\n\t\tfloat scale = sin(off) *"
|
||||
" bulgeHeight;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz "
|
||||
"+= offset;\r\n\t}\r\n\r\n\treturn deformed;\r\n}\r\n\r\n\r\nvoid main()\r\n"
|
||||
"{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\tvec3 dist;\r\n\tvec2 tex;\r\n"
|
||||
"\tfloat dlightmod;\r\n\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t\tposition "
|
||||
"= mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnormal = mix(att"
|
||||
"r_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize(normal);\r"
|
||||
"\n\t}\r\n\telse\r\n\t{\r\n\t\tposition = attr_Position;\r\n\t\tnormal = att"
|
||||
"r_Normal;\r\n\t}\r\n\r\n\tposition = DeformPosition(position, normal, attr_"
|
||||
"TexCoord0.st);\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * positio"
|
||||
"n;\r\n\t\r\n\t\r\n\ttex = vec2(0);\r\n\t\r\n\tdist = u_DlightInfo.xyz - pos"
|
||||
"ition.xyz;\t\r\n\tdlightmod = 0;\r\n\r\n\tif (!(dot(dist, normal) < 0))\r\n"
|
||||
"\t{\r\n\t\tfloat diffz = abs(dist.z);\r\n\t\tfloat radius = 1.0 / u_DlightI"
|
||||
"nfo.a;\r\n \r\n\t\tif (diffz <= radius)\r\n\t\t{\r\n\t\t\ttex = vec2(0.5"
|
||||
") + dist.xy * u_DlightInfo.a;\r\n\r\n\t\t\tif (diffz < radius * 0.5)\r\n\t"
|
||||
"\t\t{\r\n\t\t\t\tdlightmod = 1.0;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t"
|
||||
"\t\t\tdlightmod = 2.0 * (radius - diffz) * u_DlightInfo.a;\r\n\t\t\t}\r\n\t"
|
||||
"\t}\r\n\t}\r\n\r\n\tvar_Tex1 = tex;\r\n\tvar_Color.rgb = u_Color.rgb * dlig"
|
||||
"htmod;\r\n\tvar_Color.a = u_Color.a;\r\n}\r\n";
|
||||
"{\r\n\tvec4 position = mix(attr_Position, attr_Position2, u_VertexLerp);\r"
|
||||
"\n\tvec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));"
|
||||
"\r\n\r\n\tposition = DeformPosition(position, normal, attr_TexCoord0.st);\r"
|
||||
"\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;\r\n\t\r\n\tve"
|
||||
"c2 tex = vec2(0);\r\n\t\r\n\tvec3 dist = u_DlightInfo.xyz - position.xyz;\t"
|
||||
"\r\n\tfloat dlightmod = 0;\r\n\r\n\tif (dot(dist, normal) > 0)\r\n\t{\r\n\t"
|
||||
"\tfloat diffz = abs(dist.z);\r\n\t\tfloat radius = 1.0 / u_DlightInfo.a;\r"
|
||||
"\n \r\n\t\tif (diffz <= radius)\r\n\t\t{\r\n\t\t\ttex = vec2(0.5) + dist"
|
||||
".xy * u_DlightInfo.a;\r\n\r\n\t\t\tif (diffz < radius * 0.5)\r\n\t\t\t{\r\n"
|
||||
"\t\t\t\tdlightmod = 1.0;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tdli"
|
||||
"ghtmod = 2.0 * (radius - diffz) * u_DlightInfo.a;\r\n\t\t\t}\r\n\t\t}\r\n\t"
|
||||
"}\r\n\r\n\tvar_Tex1 = tex;\r\n\tvar_Color.rgb = u_Color.rgb * dlightmod;\r"
|
||||
"\n\tvar_Color.a = u_Color.a;\r\n}\r\n";
|
||||
|
||||
static const char *fallbackDlightShader_fp =
|
||||
"uniform sampler2D u_Texture0Map;\r\n\r\nvarying vec2 var_Tex1;\r\nvary"
|
||||
"ing vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 color;\r\n\r"
|
||||
"\n\tcolor = texture2D(u_Texture0Map, var_Tex1);\r\n\r\n\tcolor *= var_Color"
|
||||
";\r\n\r\n\tgl_FragColor = color;\r\n}\r\n";
|
||||
"ing vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = text"
|
||||
"ure2D(u_Texture0Map, var_Tex1);\r\n\r\n\tgl_FragColor = color * var_Color;"
|
||||
"\n}\n";
|
||||
|
||||
static const char *fallbackDeluxemappedShader_vp =
|
||||
"#version 120\r\n\r\n#ifndef M_PI\r\n#define M_PI 3.14159265358979323846f\r"
|
||||
"\n#endif\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoo"
|
||||
"rd0;\r\nattribute vec4 attr_TexCoord1;\r\nattribute vec4 attr_Tangent;\r\na"
|
||||
"ttribute vec4 attr_Bitangent;\r\nattribute vec4 attr_Normal;\r\n\r\nuniform"
|
||||
" mat4 u_Texture0Matrix;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r"
|
||||
"\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2;\r\nvarying vec3 "
|
||||
" var_Position;\r\n\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bi"
|
||||
"tangent;\r\nvarying vec3 var_Normal;\r\n\r\nvoid main()\r\n{\r\n\tvec4 te"
|
||||
"x = vec4(1, 1, 1, 0);\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * "
|
||||
"attr_Position;\r\n\r\n\ttex.st = attr_TexCoord0.st;\r\n\r\n\tvar_Tex1 = (u_"
|
||||
"Texture0Matrix * tex).st;\r\n\r\n\tif (u_Texture0Matrix[3][0] != 0)\r\n\t{"
|
||||
"\r\n\t\tvar_Tex1.s += sin(((attr_Position.x + attr_Position.z) * 1.0 / 128."
|
||||
"0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];"
|
||||
"\r\n\t\tvar_Tex1.t += sin((attr_Position.y * 1.0 / 128.0 * 0.125 + u_Textur"
|
||||
"e0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n\t}\r\n\r\n\tvar"
|
||||
"_Tex2 = attr_TexCoord1.st;\r\n\r\n\tvar_Tangent = attr_Tangent.xyz;\r\n\t"
|
||||
"var_Bitangent = attr_Bitangent.xyz;\r\n\tvar_Normal = attr_Normal.xyz;\r"
|
||||
"\n\t\r\n\tvar_Position = attr_Position.xyz;\r\n}\r\n";
|
||||
|
||||
static const char *fallbackDeluxemappedShader_fp =
|
||||
"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\nuniform sampler2D u"
|
||||
"_Texture1Map;\r\nuniform sampler2D u_Texture2Map;\r\nuniform sampler2D u_Te"
|
||||
"xture3Map;\r\nuniform sampler2D u_Texture4Map;\r\n\r\nuniform vec3 u_V"
|
||||
"iewOrigin;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2"
|
||||
";\r\nvarying vec3 var_Position;\r\n\r\nvarying vec3 var_Tangent;"
|
||||
"\r\nvarying vec3 var_Bitangent;\r\nvarying vec3 var_Normal;\r\n\r"
|
||||
"\nvoid\tmain()\r\n{\r\n\tvec3 SampleToView = normalize(u_ViewOrigin - var_P"
|
||||
"osition);\r\n\r\n\tmat3 tangentToWorld;\r\n\ttangentToWorld = mat3(var_Tang"
|
||||
"ent.xyz, var_Bitangent.xyz, var_Normal.xyz);\r\n\r\n\tmat3 worldToTangent;"
|
||||
"\r\n\tworldToTangent = mat3(tangentToWorld[0][0], tangentToWorld[1][0], tan"
|
||||
"gentToWorld[2][0],\r\n\t\ttangentToWorld[0][1], tangentToWorld[1][1], tange"
|
||||
"ntToWorld[2][1], \r\n\t\ttangentToWorld[0][2], tangentToWorld[1][2], tangen"
|
||||
"tToWorld[2][2]);\r\n\t\t\t\t\t\t\t\t\t\r\n\tfloat height = 0.02 * texture2D"
|
||||
"(u_Texture2Map, var_Tex1).a - (0.02 / 2.0);\r\n\t\r\n\tvec2 offsetDir = nor"
|
||||
"malize(worldToTangent * SampleToView).st;\r\n\tvec2 finalTex = var_Tex1 + o"
|
||||
"ffsetDir * height;\r\n\t\r\n\tvec4 diffuse = texture2D(u_Texture0Map, fina"
|
||||
"lTex);\r\n\tvec4 lightmap = texture2D(u_Texture1Map, var_Tex2);\r\n\tvec4 n"
|
||||
"ormal = texture2D(u_Texture2Map, finalTex);\r\n\tvec4 deluxe = texture2"
|
||||
"D(u_Texture3Map, var_Tex2);\r\n\tvec4 specular = texture2D(u_Texture4Map, f"
|
||||
"inalTex);\r\n\r\n\tvec3 worldNormal = tangentToWorld * normalize(2.0 * nor"
|
||||
"mal.xyz - vec3(1.0));\r\n\tvec3 worldLight = normalize(2.0 * deluxe.xyz -"
|
||||
" vec3(1.0));\r\n\tvec3 HalfAngle = normalize(worldLight + SampleToView);"
|
||||
"\r\n\t\r\n\tdiffuse.rgb *= lightmap.rgb * max(dot(worldNormal, worldLight),"
|
||||
" 0.0);\r\n\tspecular.rgb *= lightmap.rgb * pow(max(dot(worldNormal, HalfAng"
|
||||
"le), 0.0), 16.0);\r\n\t\t\r\n\tgl_FragColor = diffuse;\r\n\tgl_FragColor.rg"
|
||||
"b += specular.rgb;\r\n}\r\n";
|
||||
|
||||
|
||||
static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly)
|
||||
|
@ -488,12 +527,14 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c
|
|||
"#define AGEN_ONE_MINUS_VERTEX %i\n"
|
||||
"#define AGEN_LIGHTING_SPECULAR %i\n"
|
||||
"#define AGEN_PORTAL %i\n"
|
||||
"#define AGEN_FRESNEL %i\n"
|
||||
"#endif\n",
|
||||
AGEN_IDENTITY,
|
||||
AGEN_VERTEX,
|
||||
AGEN_ONE_MINUS_VERTEX,
|
||||
AGEN_LIGHTING_SPECULAR,
|
||||
AGEN_PORTAL));
|
||||
AGEN_PORTAL,
|
||||
AGEN_FRESNEL));
|
||||
|
||||
Q_strcat(bufferExtra, sizeof(bufferExtra),
|
||||
va("#ifndef alphaTest_t\n"
|
||||
|
@ -616,8 +657,6 @@ static int GLSL_LoadGPUShader(GLhandleARB program, GLhandleARB *prevShader, cons
|
|||
size = ri.FS_ReadFile(filename, (void **)&buffer);
|
||||
if(!buffer)
|
||||
{
|
||||
//ri.Error(ERR_DROP, "Couldn't load %s", filename);
|
||||
ri.Printf(PRINT_ALL, "Couldn't load %s, size %d\n", filename, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -771,13 +810,12 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
|
|||
|
||||
if (!(GLSL_LoadGPUShader(program->program, &program->vertexShader, name, GL_VERTEX_SHADER_ARB, extra, addHeader)))
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name);
|
||||
if (fallback_vp)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "compiling fallback...\n");
|
||||
if (!GLSL_CompileGPUShader(program->program, &program->vertexShader, fallback_vp, strlen(fallback_vp), GL_VERTEX_SHADER_ARB, extra, addHeader))
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "Fallback failed!\n");
|
||||
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name);
|
||||
qglDeleteObjectARB(program->program);
|
||||
return 0;
|
||||
}
|
||||
|
@ -793,13 +831,12 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
|
|||
{
|
||||
if(!(GLSL_LoadGPUShader(program->program, &program->fragmentShader, name, GL_FRAGMENT_SHADER_ARB, extra, addHeader)))
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name);
|
||||
if (fallback_fp)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "compiling fallback...\n");
|
||||
if (!GLSL_CompileGPUShader(program->program, &program->fragmentShader, fallback_fp, strlen(fallback_fp), GL_FRAGMENT_SHADER_ARB, extra, addHeader))
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "Fallback failed!\n");
|
||||
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name);
|
||||
qglDeleteObjectARB(program->program);
|
||||
return 0;
|
||||
}
|
||||
|
@ -830,8 +867,8 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
|
|||
if(attribs & ATTR_TANGENT)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
|
||||
|
||||
if(attribs & ATTR_BINORMAL)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_BINORMAL, "attr_Binormal");
|
||||
if(attribs & ATTR_BITANGENT)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT, "attr_Bitangent");
|
||||
|
||||
if(attribs & ATTR_NORMAL)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
|
||||
|
@ -925,8 +962,6 @@ void GLSL_FinishGPUShader(shaderProgram_t *program)
|
|||
}
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_ALL, "size %d\n", size);
|
||||
|
||||
program->uniformBuffer = ri.Malloc(size);
|
||||
|
||||
}
|
||||
|
@ -955,6 +990,8 @@ void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value)
|
|||
return;
|
||||
}
|
||||
|
||||
*compare = value;
|
||||
|
||||
qglUniform1iARB(uniforms[uniformNum], value);
|
||||
}
|
||||
|
||||
|
@ -977,6 +1014,8 @@ void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat valu
|
|||
return;
|
||||
}
|
||||
|
||||
*compare = value;
|
||||
|
||||
qglUniform1fARB(uniforms[uniformNum], value);
|
||||
}
|
||||
|
||||
|
@ -999,6 +1038,9 @@ void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t
|
|||
return;
|
||||
}
|
||||
|
||||
compare[0] = v[0];
|
||||
compare[1] = v[1];
|
||||
|
||||
qglUniform2fARB(uniforms[uniformNum], v[0], v[1]);
|
||||
}
|
||||
|
||||
|
@ -1021,6 +1063,8 @@ void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t
|
|||
return;
|
||||
}
|
||||
|
||||
VectorCopy(v, compare);
|
||||
|
||||
qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1087,8 @@ void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t
|
|||
return;
|
||||
}
|
||||
|
||||
VectorCopy4(v, compare);
|
||||
|
||||
qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
|
||||
|
@ -1065,6 +1111,8 @@ void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const mat
|
|||
return;
|
||||
}
|
||||
|
||||
Matrix16Copy(matrix, compare);
|
||||
|
||||
qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix);
|
||||
}
|
||||
|
||||
|
@ -1233,18 +1281,19 @@ void GLSL_InitGPUShaders(void)
|
|||
|
||||
attribs = ATTR_POSITION | ATTR_TEXCOORD;
|
||||
|
||||
if (!GLSL_InitGPUShader(&tr.textureOnlyShader, "textureonly", attribs, qtrue, NULL, qfalse, fallbackTextureOnlyShader_vp, fallbackTextureOnlyShader_fp, TEXTUREONLY_UNIFORM_COUNT))
|
||||
if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackTextureColorShader_vp, fallbackTextureColorShader_fp, TEXTURECOLOR_UNIFORM_COUNT))
|
||||
{
|
||||
ri.Error(ERR_FATAL, "Could not load textureonly shader!\n");
|
||||
ri.Error(ERR_FATAL, "Could not load texturecolor shader!\n");
|
||||
}
|
||||
|
||||
GLSL_AddUniform(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
|
||||
GLSL_AddUniform(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT);
|
||||
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
|
||||
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_COLOR, "u_Color", GLSL_VEC4);
|
||||
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT);
|
||||
|
||||
GLSL_FinishGPUShader(&tr.textureOnlyShader);
|
||||
GLSL_FinishGPUShader(&tr.textureColorShader);
|
||||
|
||||
qglUseProgramObjectARB(tr.textureOnlyShader.program);
|
||||
GLSL_SetUniformInt(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_TEXTURE0MAP, 0);
|
||||
qglUseProgramObjectARB(tr.textureColorShader.program);
|
||||
GLSL_SetUniformInt(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_TEXTURE0MAP, 0);
|
||||
qglUseProgramObjectARB(0);
|
||||
|
||||
|
||||
|
@ -1290,6 +1339,34 @@ void GLSL_InitGPUShaders(void)
|
|||
GLSL_FinishGPUShader(&tr.dlightShader);
|
||||
|
||||
|
||||
attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR | ATTR_TANGENT | ATTR_BITANGENT;
|
||||
|
||||
if (!GLSL_InitGPUShader(&tr.deluxemappedShader, "deluxemapped", attribs, qtrue, extradefines, qfalse, fallbackDeluxemappedShader_vp, fallbackDeluxemappedShader_fp, GENERIC_UNIFORM_COUNT))
|
||||
{
|
||||
ri.Error(ERR_FATAL, "Could not load generic shader!\n");
|
||||
}
|
||||
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_MODELMATRIX, "u_ModelMatrix", GLSL_MAT16);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MATRIX, "u_Texture0Matrix", GLSL_MAT16);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_VIEWORIGIN, "u_ViewOrigin", GLSL_VEC3);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE1MAP, "u_Texture1Map", GLSL_INT);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE2MAP, "u_Texture2Map", GLSL_INT);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE3MAP, "u_Texture3Map", GLSL_INT);
|
||||
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE4MAP, "u_Texture4Map", GLSL_INT);
|
||||
|
||||
GLSL_FinishGPUShader(&tr.deluxemappedShader);
|
||||
|
||||
qglUseProgramObjectARB(tr.deluxemappedShader.program);
|
||||
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MAP, 0);
|
||||
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE1MAP, 1);
|
||||
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE2MAP, 2);
|
||||
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE3MAP, 3);
|
||||
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE4MAP, 4);
|
||||
qglUseProgramObjectARB(0);
|
||||
|
||||
|
||||
endTime = ri.Milliseconds();
|
||||
|
||||
ri.Printf(PRINT_ALL, "GLSL shaders load time = %5.2f seconds\n", (endTime - startTime) / 1000.0);
|
||||
|
@ -1307,6 +1384,8 @@ void GLSL_ShutdownGPUShaders(void)
|
|||
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR);
|
||||
GLSL_BindNullProgram();
|
||||
|
||||
|
@ -1315,10 +1394,11 @@ void GLSL_ShutdownGPUShaders(void)
|
|||
GLSL_DeleteGPUShader(&tr.genericShader[i]);
|
||||
}
|
||||
|
||||
GLSL_DeleteGPUShader(&tr.textureOnlyShader);
|
||||
GLSL_DeleteGPUShader(&tr.textureColorShader);
|
||||
GLSL_DeleteGPUShader(&tr.lightmappedShader);
|
||||
GLSL_DeleteGPUShader(&tr.fogShader);
|
||||
GLSL_DeleteGPUShader(&tr.dlightShader);
|
||||
GLSL_DeleteGPUShader(&tr.deluxemappedShader);
|
||||
|
||||
glState.currentProgram = 0;
|
||||
qglUseProgramObjectARB(0);
|
||||
|
@ -1431,6 +1511,34 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
|
|||
}
|
||||
}
|
||||
|
||||
if(diff & ATTR_TANGENT)
|
||||
{
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n");
|
||||
qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT )\n");
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
|
||||
}
|
||||
}
|
||||
|
||||
if(diff & ATTR_BITANGENT)
|
||||
{
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_BITANGENT )\n");
|
||||
qglEnableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_BITANGENT )\n");
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
}
|
||||
}
|
||||
|
||||
if(diff & ATTR_COLOR)
|
||||
{
|
||||
if(stateBits & ATTR_COLOR)
|
||||
|
@ -1519,6 +1627,22 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
glState.vertexAttribPointersSet |= ATTR_NORMAL;
|
||||
}
|
||||
|
||||
if((attribBits & ATTR_TANGENT) && !(glState.vertexAttribPointersSet & ATTR_TANGENT))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 3, GL_FLOAT, 0, glState.currentVBO->stride_tangent, BUFFER_OFFSET(glState.currentVBO->ofs_tangent + glState.vertexAttribsNewFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_TANGENT;
|
||||
}
|
||||
|
||||
if((attribBits & ATTR_BITANGENT) && !(glState.vertexAttribPointersSet & ATTR_BITANGENT))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_BITANGENT )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + glState.vertexAttribsNewFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_BITANGENT;
|
||||
}
|
||||
|
||||
if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_COLOR )\n");
|
||||
|
@ -1550,8 +1674,24 @@ shaderProgram_t *GLSL_GetGenericShaderProgram()
|
|||
int shaderAttribs = 0;
|
||||
|
||||
if (tess.fogNum)
|
||||
{
|
||||
int stage;
|
||||
|
||||
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
|
||||
{
|
||||
shaderStage_t *pStage = tess.xstages[stage];
|
||||
|
||||
if ( !pStage )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pStage->adjustColorsForFog)
|
||||
{
|
||||
shaderAttribs |= GLSLDEF_USE_FOG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swapping these two out causes the worse case frame time to increase due to too many context switches
|
||||
|
|
|
@ -1208,6 +1208,18 @@ void R_CreateBuiltinImages( void ) {
|
|||
Com_Memset( data, 255, sizeof( data ) );
|
||||
tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, qfalse, qfalse, GL_REPEAT );
|
||||
|
||||
// black image, for no specular
|
||||
for (x=0 ; x<DEFAULT_SIZE ; x++) {
|
||||
for (y=0 ; y<DEFAULT_SIZE ; y++) {
|
||||
data[y][x][0] =
|
||||
data[y][x][1] =
|
||||
data[y][x][2] = 0;
|
||||
data[y][x][3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
tr.blackImage = R_CreateImage("*black", (byte *)data, 8, 8, qfalse, qfalse, GL_REPEAT );
|
||||
|
||||
// with overbright bits active, we need an image which is some fraction of full color,
|
||||
// for default lightmaps, etc
|
||||
for (x=0 ; x<DEFAULT_SIZE ; x++) {
|
||||
|
@ -1638,3 +1650,4 @@ void R_SkinList_f( void ) {
|
|||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -175,13 +175,19 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
|
|||
byte *data;
|
||||
int lat, lng;
|
||||
vec3_t normal;
|
||||
qboolean ignore;
|
||||
#if idppc
|
||||
float d0, d1, d2, d3, d4, d5;
|
||||
#endif
|
||||
factor = 1.0;
|
||||
data = gridData;
|
||||
ignore = qfalse;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( i & (1<<j) ) {
|
||||
if ((pos[j] + 1) >= tr.world->lightGridBounds[j] - 1)
|
||||
{
|
||||
ignore = qtrue; // ignore values outside lightgrid
|
||||
}
|
||||
factor *= frac[j];
|
||||
data += gridStep[j];
|
||||
} else {
|
||||
|
@ -189,7 +195,7 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( !(data[0]+data[1]+data[2]) ) {
|
||||
if ( ignore || !(data[0]+data[1]+data[2]+data[3]+data[4]+data[5]) ) {
|
||||
continue; // ignore samples in walls
|
||||
}
|
||||
totalFactor += factor;
|
||||
|
|
|
@ -136,11 +136,15 @@ typedef struct VBO_s
|
|||
uint32_t ofs_st;
|
||||
uint32_t ofs_lightmap;
|
||||
uint32_t ofs_vertexcolor;
|
||||
uint32_t ofs_tangent;
|
||||
uint32_t ofs_bitangent;
|
||||
uint32_t stride_xyz;
|
||||
uint32_t stride_normal;
|
||||
uint32_t stride_st;
|
||||
uint32_t stride_lightmap;
|
||||
uint32_t stride_vertexcolor;
|
||||
uint32_t stride_tangent;
|
||||
uint32_t stride_bitangent;
|
||||
uint32_t size_xyz;
|
||||
uint32_t size_normal;
|
||||
|
||||
|
@ -257,7 +261,8 @@ typedef enum {
|
|||
AGEN_LIGHTING_SPECULAR,
|
||||
AGEN_WAVEFORM,
|
||||
AGEN_PORTAL,
|
||||
AGEN_CONST
|
||||
AGEN_CONST,
|
||||
AGEN_FRESNEL
|
||||
} alphaGen_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -382,9 +387,39 @@ typedef struct {
|
|||
qboolean isVideoMap;
|
||||
} textureBundle_t;
|
||||
|
||||
#define NUM_TEXTURE_BUNDLES 2
|
||||
enum
|
||||
{
|
||||
TB_COLORMAP = 0,
|
||||
TB_DIFFUSEMAP = 0,
|
||||
TB_LIGHTMAP,
|
||||
TB_NORMALMAP,
|
||||
TB_DELUXEMAP,
|
||||
TB_SPECULARMAP,
|
||||
NUM_TEXTURE_BUNDLES = 5
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// material shader stage types
|
||||
ST_COLORMAP = 0, // vanilla Q3A style shader treatening
|
||||
ST_DIFFUSEMAP = 0, // treat color and diffusemap the same
|
||||
ST_NORMALMAP,
|
||||
ST_SPECULARMAP,
|
||||
ST_GLSL
|
||||
} stageType_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COLLAPSE_none,
|
||||
COLLAPSE_genericMulti,
|
||||
COLLAPSE_lighting_DB,
|
||||
COLLAPSE_lighting_DBS,
|
||||
COLLAPSE_reflection_CB
|
||||
} collapseType_t;
|
||||
|
||||
typedef struct {
|
||||
stageType_t type;
|
||||
|
||||
qboolean active;
|
||||
|
||||
textureBundle_t bundle[NUM_TEXTURE_BUNDLES];
|
||||
|
@ -402,6 +437,8 @@ typedef struct {
|
|||
acff_t adjustColorsForFog;
|
||||
|
||||
qboolean isDetail;
|
||||
|
||||
struct shaderProgram_s *glslShader;
|
||||
} shaderStage_t;
|
||||
|
||||
struct shaderCommands_s;
|
||||
|
@ -537,7 +574,7 @@ enum
|
|||
ATTR_INDEX_TEXCOORD0 = 1,
|
||||
ATTR_INDEX_TEXCOORD1 = 2,
|
||||
ATTR_INDEX_TANGENT = 3,
|
||||
ATTR_INDEX_BINORMAL = 4,
|
||||
ATTR_INDEX_BITANGENT = 4,
|
||||
ATTR_INDEX_NORMAL = 5,
|
||||
ATTR_INDEX_COLOR = 6,
|
||||
ATTR_INDEX_PAINTCOLOR = 7,
|
||||
|
@ -548,7 +585,7 @@ enum
|
|||
// GPU vertex animations
|
||||
ATTR_INDEX_POSITION2 = 11,
|
||||
ATTR_INDEX_TANGENT2 = 12,
|
||||
ATTR_INDEX_BINORMAL2 = 13,
|
||||
ATTR_INDEX_BITANGENT2 = 13,
|
||||
ATTR_INDEX_NORMAL2 = 14
|
||||
};
|
||||
|
||||
|
@ -635,7 +672,7 @@ enum
|
|||
ATTR_TEXCOORD = 0x0002,
|
||||
ATTR_LIGHTCOORD = 0x0004,
|
||||
ATTR_TANGENT = 0x0008,
|
||||
ATTR_BINORMAL = 0x0010,
|
||||
ATTR_BITANGENT = 0x0010,
|
||||
ATTR_NORMAL = 0x0020,
|
||||
ATTR_COLOR = 0x0040,
|
||||
ATTR_PAINTCOLOR = 0x0080,
|
||||
|
@ -646,7 +683,7 @@ enum
|
|||
// for .md3 interpolation
|
||||
ATTR_POSITION2 = 0x0800,
|
||||
ATTR_TANGENT2 = 0x1000,
|
||||
ATTR_BINORMAL2 = 0x2000,
|
||||
ATTR_BITANGENT2 = 0x2000,
|
||||
ATTR_NORMAL2 = 0x4000,
|
||||
|
||||
ATTR_DEFAULT = ATTR_POSITION,
|
||||
|
@ -654,7 +691,7 @@ enum
|
|||
ATTR_TEXCOORD |
|
||||
ATTR_LIGHTCOORD |
|
||||
ATTR_TANGENT |
|
||||
ATTR_BINORMAL |
|
||||
ATTR_BITANGENT |
|
||||
ATTR_NORMAL |
|
||||
ATTR_COLOR |
|
||||
ATTR_PAINTCOLOR |
|
||||
|
@ -663,7 +700,7 @@ enum
|
|||
ATTR_BONE_WEIGHTS |
|
||||
ATTR_POSITION2 |
|
||||
ATTR_TANGENT2 |
|
||||
ATTR_BINORMAL2 |
|
||||
ATTR_BITANGENT2 |
|
||||
ATTR_NORMAL2
|
||||
};
|
||||
|
||||
|
@ -720,9 +757,10 @@ enum
|
|||
|
||||
enum
|
||||
{
|
||||
TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0,
|
||||
TEXTUREONLY_UNIFORM_TEXTURE0MAP,
|
||||
TEXTUREONLY_UNIFORM_COUNT
|
||||
TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0,
|
||||
TEXTURECOLOR_UNIFORM_TEXTURE0MAP,
|
||||
TEXTURECOLOR_UNIFORM_COLOR,
|
||||
TEXTURECOLOR_UNIFORM_COUNT
|
||||
};
|
||||
|
||||
|
||||
|
@ -762,6 +800,9 @@ enum
|
|||
{
|
||||
GENERIC_UNIFORM_TEXTURE0MAP = 0,
|
||||
GENERIC_UNIFORM_TEXTURE1MAP,
|
||||
GENERIC_UNIFORM_TEXTURE2MAP,
|
||||
GENERIC_UNIFORM_TEXTURE3MAP,
|
||||
GENERIC_UNIFORM_TEXTURE4MAP,
|
||||
GENERIC_UNIFORM_TEXTURE0MATRIX,
|
||||
GENERIC_UNIFORM_TEXTURE1ENV,
|
||||
GENERIC_UNIFORM_VIEWORIGIN,
|
||||
|
@ -783,6 +824,7 @@ enum
|
|||
GENERIC_UNIFORM_FOGDEPTH,
|
||||
GENERIC_UNIFORM_FOGEYET,
|
||||
GENERIC_UNIFORM_FOGADJUSTCOLORS,
|
||||
GENERIC_UNIFORM_MODELMATRIX,
|
||||
GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX,
|
||||
GENERIC_UNIFORM_TIME,
|
||||
GENERIC_UNIFORM_VERTEXLERP,
|
||||
|
@ -953,6 +995,8 @@ typedef struct
|
|||
vec2_t st;
|
||||
vec2_t lightmap;
|
||||
vec3_t normal;
|
||||
vec3_t tangent;
|
||||
vec3_t bitangent;
|
||||
color4ub_t vertexColors;
|
||||
|
||||
#if DEBUG_OPTIMIZEVERTICES
|
||||
|
@ -960,7 +1004,7 @@ typedef struct
|
|||
#endif
|
||||
} srfVert_t;
|
||||
|
||||
#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
|
||||
#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -1552,6 +1596,7 @@ typedef struct {
|
|||
int frameSceneNum; // zeroed at RE_BeginFrame
|
||||
|
||||
qboolean worldMapLoaded;
|
||||
qboolean worldDeluxeMapping;
|
||||
world_t *world;
|
||||
|
||||
const byte *externalVisData; // from RE_SetWorldVisData, shared with CM_Load
|
||||
|
@ -1562,6 +1607,7 @@ typedef struct {
|
|||
image_t *dlightImage; // inverse-quare highlight for projective adding
|
||||
image_t *flareImage;
|
||||
image_t *whiteImage; // full of 0xff
|
||||
image_t *blackImage; // full of 0x000000ff
|
||||
image_t *identityLightImage; // full of tr.identityLightByte
|
||||
|
||||
shader_t *defaultShader;
|
||||
|
@ -1573,8 +1619,10 @@ typedef struct {
|
|||
|
||||
int numLightmaps;
|
||||
image_t **lightmaps;
|
||||
image_t **deluxemaps;
|
||||
|
||||
image_t *fatLightmap;
|
||||
image_t *fatDeluxemap;
|
||||
int fatLightmapSize;
|
||||
int fatLightmapStep;
|
||||
|
||||
|
@ -1590,9 +1638,10 @@ typedef struct {
|
|||
|
||||
shaderProgram_t genericShader[GLSLDEF_COUNT];
|
||||
shaderProgram_t lightmappedShader;
|
||||
shaderProgram_t textureOnlyShader;
|
||||
shaderProgram_t textureColorShader;
|
||||
shaderProgram_t fogShader;
|
||||
shaderProgram_t dlightShader;
|
||||
shaderProgram_t deluxemappedShader;
|
||||
|
||||
|
||||
// -----------------------------------------
|
||||
|
@ -1830,6 +1879,7 @@ void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
|
|||
|
||||
void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap );
|
||||
|
||||
qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
|
||||
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles);
|
||||
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts);
|
||||
|
||||
|
@ -2004,6 +2054,8 @@ typedef struct shaderCommands_s
|
|||
glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
|
||||
vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t bitangent[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
|
||||
color4ub_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
//int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
|
|
|
@ -43,6 +43,446 @@ refimport_t ri;
|
|||
// point at this for their sorting surface
|
||||
surfaceType_t entitySurface = SF_ENTITY;
|
||||
|
||||
/*
|
||||
================
|
||||
R_CompareVert
|
||||
================
|
||||
*/
|
||||
qboolean R_CompareVert(srfVert_t * v1, srfVert_t * v2, qboolean checkST)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
if(floor(v1->xyz[i] + 0.1) != floor(v2->xyz[i] + 0.1))
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if(checkST && ((v1->st[0] != v2->st[0]) || (v1->st[1] != v2->st[1])))
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CalcNormalForTriangle
|
||||
=============
|
||||
*/
|
||||
void R_CalcNormalForTriangle(vec3_t normal, const vec3_t v0, const vec3_t v1, const vec3_t v2)
|
||||
{
|
||||
vec3_t udir, vdir;
|
||||
|
||||
// compute the face normal based on vertex points
|
||||
VectorSubtract(v2, v0, udir);
|
||||
VectorSubtract(v1, v0, vdir);
|
||||
CrossProduct(udir, vdir, normal);
|
||||
|
||||
VectorNormalize(normal);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CalcTangentsForTriangle
|
||||
http://members.rogers.com/deseric/tangentspace.htm
|
||||
=============
|
||||
*/
|
||||
void R_CalcTangentsForTriangle(vec3_t tangent, vec3_t bitangent,
|
||||
const vec3_t v0, const vec3_t v1, const vec3_t v2,
|
||||
const vec2_t t0, const vec2_t t1, const vec2_t t2)
|
||||
{
|
||||
int i;
|
||||
vec3_t planes[3];
|
||||
vec3_t u, v;
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
VectorSet(u, v1[i] - v0[i], t1[0] - t0[0], t1[1] - t0[1]);
|
||||
VectorSet(v, v2[i] - v0[i], t2[0] - t0[0], t2[1] - t0[1]);
|
||||
|
||||
VectorNormalize(u);
|
||||
VectorNormalize(v);
|
||||
|
||||
CrossProduct(u, v, planes[i]);
|
||||
}
|
||||
|
||||
//So your tangent space will be defined by this :
|
||||
//Normal = Normal of the triangle or Tangent X Bitangent (careful with the cross product,
|
||||
// you have to make sure the normal points in the right direction)
|
||||
//Tangent = ( dp(Fx(s,t)) / ds, dp(Fy(s,t)) / ds, dp(Fz(s,t)) / ds ) or ( -Bx/Ax, -By/Ay, - Bz/Az )
|
||||
//Bitangent = ( dp(Fx(s,t)) / dt, dp(Fy(s,t)) / dt, dp(Fz(s,t)) / dt ) or ( -Cx/Ax, -Cy/Ay, -Cz/Az )
|
||||
|
||||
// tangent...
|
||||
tangent[0] = -planes[0][1] / planes[0][0];
|
||||
tangent[1] = -planes[1][1] / planes[1][0];
|
||||
tangent[2] = -planes[2][1] / planes[2][0];
|
||||
VectorNormalize(tangent);
|
||||
|
||||
// bitangent...
|
||||
bitangent[0] = -planes[0][2] / planes[0][0];
|
||||
bitangent[1] = -planes[1][2] / planes[1][0];
|
||||
bitangent[2] = -planes[2][2] / planes[2][0];
|
||||
VectorNormalize(bitangent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CalcTangentSpace
|
||||
=============
|
||||
*/
|
||||
void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
|
||||
{
|
||||
vec3_t cp, u, v;
|
||||
vec3_t faceNormal;
|
||||
|
||||
VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
|
||||
VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[0] = -cp[1] / cp[0];
|
||||
bitangent[0] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
u[0] = v1[1] - v0[1];
|
||||
v[0] = v2[1] - v0[1];
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[1] = -cp[1] / cp[0];
|
||||
bitangent[1] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
u[0] = v1[2] - v0[2];
|
||||
v[0] = v2[2] - v0[2];
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[2] = -cp[1] / cp[0];
|
||||
bitangent[2] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
VectorNormalize(tangent);
|
||||
VectorNormalize(bitangent);
|
||||
|
||||
// compute the face normal based on vertex points
|
||||
VectorSubtract(v2, v0, u);
|
||||
VectorSubtract(v1, v0, v);
|
||||
CrossProduct(u, v, faceNormal);
|
||||
|
||||
VectorNormalize(faceNormal);
|
||||
|
||||
#if 1
|
||||
// Gram-Schmidt orthogonalize
|
||||
//tangent[a] = (t - n * Dot(n, t)).Normalize();
|
||||
VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
|
||||
VectorNormalize(tangent);
|
||||
|
||||
// compute the cross product B=NxT
|
||||
//CrossProduct(normal, tangent, bitangent);
|
||||
#else
|
||||
// normal, compute the cross product N=TxB
|
||||
CrossProduct(tangent, bitangent, normal);
|
||||
VectorNormalize(normal);
|
||||
|
||||
if(DotProduct(normal, faceNormal) < 0)
|
||||
{
|
||||
//VectorInverse(normal);
|
||||
//VectorInverse(tangent);
|
||||
//VectorInverse(bitangent);
|
||||
|
||||
// compute the cross product T=BxN
|
||||
CrossProduct(bitangent, faceNormal, tangent);
|
||||
|
||||
// compute the cross product B=NxT
|
||||
//CrossProduct(normal, tangent, bitangent);
|
||||
}
|
||||
#endif
|
||||
|
||||
VectorCopy(faceNormal, normal);
|
||||
}
|
||||
|
||||
void R_CalcTangentSpaceFast(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
|
||||
{
|
||||
vec3_t cp, u, v;
|
||||
vec3_t faceNormal;
|
||||
|
||||
VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
|
||||
VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[0] = -cp[1] / cp[0];
|
||||
bitangent[0] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
u[0] = v1[1] - v0[1];
|
||||
v[0] = v2[1] - v0[1];
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[1] = -cp[1] / cp[0];
|
||||
bitangent[1] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
u[0] = v1[2] - v0[2];
|
||||
v[0] = v2[2] - v0[2];
|
||||
|
||||
CrossProduct(u, v, cp);
|
||||
if(fabs(cp[0]) > 10e-6)
|
||||
{
|
||||
tangent[2] = -cp[1] / cp[0];
|
||||
bitangent[2] = -cp[2] / cp[0];
|
||||
}
|
||||
|
||||
VectorNormalizeFast(tangent);
|
||||
VectorNormalizeFast(bitangent);
|
||||
|
||||
// compute the face normal based on vertex points
|
||||
VectorSubtract(v2, v0, u);
|
||||
VectorSubtract(v1, v0, v);
|
||||
CrossProduct(u, v, faceNormal);
|
||||
|
||||
VectorNormalizeFast(faceNormal);
|
||||
|
||||
#if 0
|
||||
// normal, compute the cross product N=TxB
|
||||
CrossProduct(tangent, bitangent, normal);
|
||||
VectorNormalizeFast(normal);
|
||||
|
||||
if(DotProduct(normal, faceNormal) < 0)
|
||||
{
|
||||
VectorInverse(normal);
|
||||
//VectorInverse(tangent);
|
||||
//VectorInverse(bitangent);
|
||||
|
||||
CrossProduct(normal, tangent, bitangent);
|
||||
}
|
||||
|
||||
VectorCopy(faceNormal, normal);
|
||||
#else
|
||||
// Gram-Schmidt orthogonalize
|
||||
//tangent[a] = (t - n * Dot(n, t)).Normalize();
|
||||
VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
|
||||
VectorNormalizeFast(tangent);
|
||||
#endif
|
||||
|
||||
VectorCopy(faceNormal, normal);
|
||||
}
|
||||
|
||||
/*
|
||||
http://www.terathon.com/code/tangent.html
|
||||
*/
|
||||
void R_CalcTBN(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3)
|
||||
{
|
||||
vec3_t u, v;
|
||||
float x1, x2, y1, y2, z1, z2;
|
||||
float s1, s2, t1, t2;
|
||||
float r, dot;
|
||||
|
||||
x1 = v2[0] - v1[0];
|
||||
x2 = v3[0] - v1[0];
|
||||
y1 = v2[1] - v1[1];
|
||||
y2 = v3[1] - v1[1];
|
||||
z1 = v2[2] - v1[2];
|
||||
z2 = v3[2] - v1[2];
|
||||
|
||||
s1 = w2[0] - w1[0];
|
||||
s2 = w3[0] - w1[0];
|
||||
t1 = w2[1] - w1[1];
|
||||
t2 = w3[1] - w1[1];
|
||||
|
||||
r = 1.0f / (s1 * t2 - s2 * t1);
|
||||
|
||||
VectorSet(tangent, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
|
||||
VectorSet(bitangent, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
|
||||
|
||||
// compute the face normal based on vertex points
|
||||
VectorSubtract(v3, v1, u);
|
||||
VectorSubtract(v2, v1, v);
|
||||
CrossProduct(u, v, normal);
|
||||
|
||||
VectorNormalize(normal);
|
||||
|
||||
// Gram-Schmidt orthogonalize
|
||||
//tangent[a] = (t - n * Dot(n, t)).Normalize();
|
||||
dot = DotProduct(normal, tangent);
|
||||
VectorMA(tangent, -dot, normal, tangent);
|
||||
VectorNormalize(tangent);
|
||||
|
||||
// B=NxT
|
||||
//CrossProduct(normal, tangent, bitangent);
|
||||
}
|
||||
|
||||
void R_CalcTBN2(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t t1, const vec2_t t2, const vec2_t t3)
|
||||
{
|
||||
vec3_t v2v1;
|
||||
vec3_t v3v1;
|
||||
|
||||
float c2c1_T;
|
||||
float c2c1_B;
|
||||
|
||||
float c3c1_T;
|
||||
float c3c1_B;
|
||||
|
||||
float denominator;
|
||||
float scale1, scale2;
|
||||
|
||||
vec3_t T, B, N, C;
|
||||
|
||||
|
||||
// Calculate the tangent basis for each vertex of the triangle
|
||||
// UPDATE: In the 3rd edition of the accompanying article, the for-loop located here has
|
||||
// been removed as it was redundant (the entire TBN matrix was calculated three times
|
||||
// instead of just one).
|
||||
//
|
||||
// Please note, that this function relies on the fact that the input geometry are triangles
|
||||
// and the tangent basis for each vertex thus is identical!
|
||||
//
|
||||
|
||||
// Calculate the vectors from the current vertex to the two other vertices in the triangle
|
||||
VectorSubtract(v2, v1, v2v1);
|
||||
VectorSubtract(v3, v1, v3v1);
|
||||
|
||||
// The equation presented in the article states that:
|
||||
// c2c1_T = V2.texcoord.x – V1.texcoord.x
|
||||
// c2c1_B = V2.texcoord.y – V1.texcoord.y
|
||||
// c3c1_T = V3.texcoord.x – V1.texcoord.x
|
||||
// c3c1_B = V3.texcoord.y – V1.texcoord.y
|
||||
|
||||
// Calculate c2c1_T and c2c1_B
|
||||
c2c1_T = t2[0] - t1[0];
|
||||
c2c1_B = t2[1] - t2[1];
|
||||
|
||||
// Calculate c3c1_T and c3c1_B
|
||||
c3c1_T = t3[0] - t1[0];
|
||||
c3c1_B = t3[1] - t1[1];
|
||||
|
||||
denominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B;
|
||||
//if(ROUNDOFF(fDenominator) == 0.0f)
|
||||
if(denominator == 0.0f)
|
||||
{
|
||||
// We won't risk a divide by zero, so set the tangent matrix to the identity matrix
|
||||
VectorSet(tangent, 1, 0, 0);
|
||||
VectorSet(bitangent, 0, 1, 0);
|
||||
VectorSet(normal, 0, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the reciprocal value once and for all (to achieve speed)
|
||||
scale1 = 1.0f / denominator;
|
||||
|
||||
// T and B are calculated just as the equation in the article states
|
||||
VectorSet(T, (c3c1_B * v2v1[0] - c2c1_B * v3v1[0]) * scale1,
|
||||
(c3c1_B * v2v1[1] - c2c1_B * v3v1[1]) * scale1,
|
||||
(c3c1_B * v2v1[2] - c2c1_B * v3v1[2]) * scale1);
|
||||
|
||||
VectorSet(B, (-c3c1_T * v2v1[0] + c2c1_T * v3v1[0]) * scale1,
|
||||
(-c3c1_T * v2v1[1] + c2c1_T * v3v1[1]) * scale1,
|
||||
(-c3c1_T * v2v1[2] + c2c1_T * v3v1[2]) * scale1);
|
||||
|
||||
// The normal N is calculated as the cross product between T and B
|
||||
CrossProduct(T, B, N);
|
||||
|
||||
#if 0
|
||||
VectorCopy(T, tangent);
|
||||
VectorCopy(B, bitangent);
|
||||
VectorCopy(N, normal);
|
||||
#else
|
||||
// Calculate the reciprocal value once and for all (to achieve speed)
|
||||
scale2 = 1.0f / ((T[0] * B[1] * N[2] - T[2] * B[1] * N[0]) +
|
||||
(B[0] * N[1] * T[2] - B[2] * N[1] * T[0]) +
|
||||
(N[0] * T[1] * B[2] - N[2] * T[1] * B[0]));
|
||||
|
||||
// Calculate the inverse if the TBN matrix using the formula described in the article.
|
||||
// We store the basis vectors directly in the provided TBN matrix: pvTBNMatrix
|
||||
CrossProduct(B, N, C); tangent[0] = C[0] * scale2;
|
||||
CrossProduct(N, T, C); tangent[1] = -C[0] * scale2;
|
||||
CrossProduct(T, B, C); tangent[2] = C[0] * scale2;
|
||||
VectorNormalize(tangent);
|
||||
|
||||
CrossProduct(B, N, C); bitangent[0] = -C[1] * scale2;
|
||||
CrossProduct(N, T, C); bitangent[1] = C[1] * scale2;
|
||||
CrossProduct(T, B, C); bitangent[2] = -C[1] * scale2;
|
||||
VectorNormalize(bitangent);
|
||||
|
||||
CrossProduct(B, N, C); normal[0] = C[2] * scale2;
|
||||
CrossProduct(N, T, C); normal[1] = -C[2] * scale2;
|
||||
CrossProduct(T, B, C); normal[2] = C[2] * scale2;
|
||||
VectorNormalize(normal);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qboolean R_CalcTangentVectors(srfVert_t * dv[3])
|
||||
{
|
||||
int i;
|
||||
float bb, s, t;
|
||||
vec3_t bary;
|
||||
|
||||
|
||||
/* calculate barycentric basis for the triangle */
|
||||
bb = (dv[1]->st[0] - dv[0]->st[0]) * (dv[2]->st[1] - dv[0]->st[1]) - (dv[2]->st[0] - dv[0]->st[0]) * (dv[1]->st[1] - dv[0]->st[1]);
|
||||
if(fabs(bb) < 0.00000001f)
|
||||
return qfalse;
|
||||
|
||||
/* do each vertex */
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
// calculate s tangent vector
|
||||
s = dv[i]->st[0] + 10.0f;
|
||||
t = dv[i]->st[1];
|
||||
bary[0] = ((dv[1]->st[0] - s) * (dv[2]->st[1] - t) - (dv[2]->st[0] - s) * (dv[1]->st[1] - t)) / bb;
|
||||
bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb;
|
||||
bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb;
|
||||
|
||||
dv[i]->tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
|
||||
dv[i]->tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
|
||||
dv[i]->tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
|
||||
|
||||
VectorSubtract(dv[i]->tangent, dv[i]->xyz, dv[i]->tangent);
|
||||
VectorNormalize(dv[i]->tangent);
|
||||
|
||||
// calculate t tangent vector
|
||||
s = dv[i]->st[0];
|
||||
t = dv[i]->st[1] + 10.0f;
|
||||
bary[0] = ((dv[1]->st[0] - s) * (dv[2]->st[1] - t) - (dv[2]->st[0] - s) * (dv[1]->st[1] - t)) / bb;
|
||||
bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb;
|
||||
bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb;
|
||||
|
||||
dv[i]->bitangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
|
||||
dv[i]->bitangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
|
||||
dv[i]->bitangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
|
||||
|
||||
VectorSubtract(dv[i]->bitangent, dv[i]->xyz, dv[i]->bitangent);
|
||||
VectorNormalize(dv[i]->bitangent);
|
||||
|
||||
// debug code
|
||||
//% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i,
|
||||
//% stv[ i ][ 0 ], stv[ i ][ 1 ], stv[ i ][ 2 ], ttv[ i ][ 0 ], ttv[ i ][ 1 ], ttv[ i ][ 2 ] );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_FindSurfaceTriangleWithEdge
|
||||
|
@ -1607,3 +2047,4 @@ void R_RenderView (viewParms_t *parms) {
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -456,3 +456,4 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
return returnedFragments;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -431,3 +431,4 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1309,3 +1309,4 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
|
|||
VectorCopy( frame->bounds[1], maxs );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -300,12 +300,15 @@ static void DrawTris (shaderCommands_t *input) {
|
|||
{
|
||||
if (glRefConfig.glsl && r_arb_shader_objects->integer)
|
||||
{
|
||||
shaderProgram_t *sp = &tr.textureOnlyShader;
|
||||
shaderProgram_t *sp = &tr.textureColorShader;
|
||||
vec4_t color;
|
||||
|
||||
GLSL_VertexAttribsState(ATTR_POSITION);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
|
||||
|
||||
if (input->multiDrawPrimitives)
|
||||
{
|
||||
|
@ -1541,6 +1544,9 @@ static void ComputeColors( shaderStage_t *pStage )
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AGEN_FRESNEL:
|
||||
// FIXME: implement me!
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1755,6 +1761,9 @@ static void ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
|
|||
case AGEN_PORTAL:
|
||||
// Done entirely in vertex program
|
||||
break;
|
||||
case AGEN_FRESNEL:
|
||||
// Done entirely in vertex program
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2065,6 +2074,9 @@ static void ComputeColorMatrix( shaderStage_t *pStage, float *outmatrix, qboolea
|
|||
}
|
||||
#endif
|
||||
break;
|
||||
case AGEN_FRESNEL:
|
||||
// FIXME: implement me!
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME: find some way to implement this stuff.
|
||||
|
@ -2448,16 +2460,17 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
|
|||
{
|
||||
int stage;
|
||||
matrix_t matrix;
|
||||
shaderProgram_t *sp = GLSL_GetGenericShaderProgram();
|
||||
|
||||
GLSL_BindProgram(sp);
|
||||
int deformGen;
|
||||
vec4_t deformWave;
|
||||
vec3_t deformBulge;
|
||||
float deformSpread;
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
|
||||
float eyeT;
|
||||
|
||||
// u_DeformGen
|
||||
deformGen = DGEN_NONE;
|
||||
if(!ShaderRequiresCPUDeforms(input->shader))
|
||||
{
|
||||
deformStage_t *ds;
|
||||
|
@ -2468,46 +2481,28 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
|
|||
switch (ds->deformation)
|
||||
{
|
||||
case DEFORM_WAVE:
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, ds->deformationWave.func);
|
||||
deformGen = ds->deformationWave.func;
|
||||
{
|
||||
vec4_t v;
|
||||
waveForm_t *wf = &ds->deformationWave;
|
||||
|
||||
VectorSet4(v, wf->base, wf->amplitude, wf->phase, wf->frequency);
|
||||
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DEFORMWAVE, v);
|
||||
VectorSet4(deformWave, wf->base, wf->amplitude, wf->phase, wf->frequency);
|
||||
}
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_DEFORMSPREAD, ds->deformationSpread);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
|
||||
deformSpread = ds->deformationSpread;
|
||||
break;
|
||||
|
||||
case DEFORM_BULGE:
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_BULGE);
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
VectorSet(v, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed);
|
||||
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DEFORMBULGE, v);
|
||||
}
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
|
||||
deformGen = DGEN_BULGE;
|
||||
VectorSet(deformBulge, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed);
|
||||
break;
|
||||
|
||||
default:
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE);
|
||||
}
|
||||
|
||||
if ( input->fogNum ) {
|
||||
fog_t *fog;
|
||||
vec3_t local;
|
||||
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
|
||||
float eyeT;
|
||||
|
||||
fog = tr.world->fogs + tess.fogNum;
|
||||
|
||||
|
@ -2534,27 +2529,65 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
|
|||
} else {
|
||||
eyeT = 1; // non-surface fog always has eye inside
|
||||
}
|
||||
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector);
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT);
|
||||
}
|
||||
|
||||
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
|
||||
{
|
||||
shaderStage_t *pStage = input->xstages[stage];
|
||||
qboolean setcolor = qfalse;
|
||||
shaderProgram_t *sp;
|
||||
|
||||
if ( !pStage )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pStage->glslShader)
|
||||
{
|
||||
sp = pStage->glslShader;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = GLSL_GetGenericShaderProgram();
|
||||
}
|
||||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen);
|
||||
switch(deformGen)
|
||||
{
|
||||
case DGEN_WAVE_SIN:
|
||||
case DGEN_WAVE_SQUARE:
|
||||
case DGEN_WAVE_TRIANGLE:
|
||||
case DGEN_WAVE_SAWTOOTH:
|
||||
case DGEN_WAVE_INVERSE_SAWTOOTH:
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DEFORMWAVE, deformWave);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_DEFORMSPREAD, deformSpread);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
|
||||
break;
|
||||
case DGEN_BULGE:
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DEFORMBULGE, deformBulge);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( input->fogNum ) {
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector);
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector);
|
||||
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT);
|
||||
}
|
||||
|
||||
GL_State( pStage->stateBits );
|
||||
|
||||
switch (pStage->rgbGen)
|
||||
{
|
||||
case CGEN_IDENTITY:
|
||||
case CGEN_EXACT_VERTEX:
|
||||
case CGEN_LIGHTING_DIFFUSE:
|
||||
break;
|
||||
|
@ -2564,11 +2597,11 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
|
|||
|
||||
switch (pStage->alphaGen)
|
||||
{
|
||||
case AGEN_IDENTITY:
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_VERTEX:
|
||||
case AGEN_ONE_MINUS_VERTEX:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
break;
|
||||
default:
|
||||
setcolor = qtrue;
|
||||
|
@ -2617,7 +2650,37 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
|
|||
//
|
||||
// do multitexture
|
||||
//
|
||||
if ( pStage->bundle[1].image[0] != 0 )
|
||||
if ( pStage->glslShader )
|
||||
{
|
||||
int i;
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.modelMatrix);
|
||||
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
if (pStage->bundle[i].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
ComputeTexMatrix( pStage, 0, matrix );
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix);
|
||||
|
||||
//
|
||||
// draw
|
||||
//
|
||||
|
||||
if (input->multiDrawPrimitives)
|
||||
{
|
||||
R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_DrawElementsVBO(input->numIndexes, input->firstIndex);
|
||||
}
|
||||
}
|
||||
else if ( pStage->bundle[1].image[0] != 0 )
|
||||
{
|
||||
DrawMultitexturedVBOGLSL( sp, input, stage );
|
||||
}
|
||||
|
@ -3281,3 +3344,4 @@ void RB_EndSurface( void ) {
|
|||
GLimp_LogComment( "----------\n" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1334,3 +1334,4 @@ void RB_CalcDiffuseColor( unsigned char *colors )
|
|||
RB_CalcDiffuseColor_scalar( colors );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -634,6 +634,22 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
}
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "$deluxemap" ) )
|
||||
{
|
||||
if (!tr.worldDeluxeMapping)
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: shader '%s' wants a deluxe map in a map compiled without them\n", shader.name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
stage->bundle[0].isLightmap = qtrue;
|
||||
if ( shader.lightmapIndex < 0 ) {
|
||||
stage->bundle[0].image[0] = tr.whiteImage;
|
||||
} else {
|
||||
stage->bundle[0].image[0] = tr.deluxemaps[shader.lightmapIndex];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
stage->bundle[0].image[0] = R_FindImageFile( token, !shader.noMipMaps, !shader.noPicMip, GL_REPEAT );
|
||||
|
@ -800,6 +816,36 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
}
|
||||
}
|
||||
//
|
||||
// stage <type>
|
||||
//
|
||||
else if(!Q_stricmp(token, "stage"))
|
||||
{
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if(token[0] == 0)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "WARNING: missing parameters for stage in shader '%s'\n", shader.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!Q_stricmp(token, "diffuseMap"))
|
||||
{
|
||||
stage->type = ST_DIFFUSEMAP;
|
||||
}
|
||||
else if(!Q_stricmp(token, "normalMap") || !Q_stricmp(token, "bumpMap"))
|
||||
{
|
||||
stage->type = ST_NORMALMAP;
|
||||
}
|
||||
else if(!Q_stricmp(token, "specularMap"))
|
||||
{
|
||||
stage->type = ST_SPECULARMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "WARNING: unknown stage parameter '%s' in shader '%s'\n", token, shader.name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//
|
||||
// rgbGen
|
||||
//
|
||||
else if ( !Q_stricmp( token, "rgbGen" ) )
|
||||
|
@ -929,6 +975,10 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
shader.portalRange = atof( token );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( token, "fresnel" ) )
|
||||
{
|
||||
stage->alphaGen = AGEN_FRESNEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: unknown alphaGen parameter '%s' in shader '%s'\n", token, shader.name );
|
||||
|
@ -1807,11 +1857,16 @@ static void ComputeVertexAttribs(void)
|
|||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
if (pStage->glslShader)
|
||||
{
|
||||
if (i == 1 && ( pStage->bundle[1].image[0] == 0 ))
|
||||
shader.vertexAttribs |= ATTR_NORMAL | ATTR_BITANGENT | ATTR_TANGENT;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
break;
|
||||
if ( pStage->bundle[i].image[0] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(pStage->bundle[i].tcGen)
|
||||
|
@ -1850,6 +1905,7 @@ static void ComputeVertexAttribs(void)
|
|||
switch(pStage->alphaGen)
|
||||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_FRESNEL:
|
||||
shader.vertexAttribs |= ATTR_NORMAL;
|
||||
break;
|
||||
|
||||
|
@ -1858,6 +1914,10 @@ static void ComputeVertexAttribs(void)
|
|||
shader.vertexAttribs |= ATTR_COLOR;
|
||||
break;
|
||||
|
||||
case CGEN_LIGHTING_DIFFUSE:
|
||||
shader.vertexAttribs |= ATTR_NORMAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2020,6 +2080,117 @@ static qboolean CollapseMultitexture( void ) {
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
static qboolean CollapseStagesToGLSL(void)
|
||||
{
|
||||
int i, numStages;
|
||||
shaderStage_t *diffuse, *lightmap, *normal, *specular;
|
||||
|
||||
diffuse = NULL;
|
||||
lightmap = NULL;
|
||||
normal = NULL;
|
||||
specular = NULL;
|
||||
|
||||
// find all the stages that are important
|
||||
for (i = 0; i < MAX_SHADER_STAGES; i++)
|
||||
{
|
||||
shaderStage_t *pStage = &stages[i];
|
||||
int blendbits;
|
||||
|
||||
if (!pStage->active)
|
||||
continue;
|
||||
|
||||
blendbits = pStage->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS);
|
||||
|
||||
if (pStage->bundle[0].isLightmap &&
|
||||
(blendbits == (GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO) ||
|
||||
blendbits == (GLS_SRCBLEND_ZERO | GLS_DSTBLEND_SRC_COLOR)))
|
||||
{
|
||||
lightmap = pStage;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pStage->type)
|
||||
{
|
||||
case ST_DIFFUSEMAP:
|
||||
diffuse = pStage;
|
||||
break;
|
||||
case ST_NORMALMAP:
|
||||
normal = pStage;
|
||||
break;
|
||||
case ST_SPECULARMAP:
|
||||
specular = pStage;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we've got these, use deluxemapped shader
|
||||
if (diffuse && lightmap && normal)
|
||||
{
|
||||
if (tr.worldDeluxeMapping)
|
||||
{
|
||||
// reuse diffuse, mark others inactive
|
||||
diffuse->type = ST_GLSL;
|
||||
diffuse->glslShader = &tr.deluxemappedShader;
|
||||
|
||||
diffuse->bundle[TB_LIGHTMAP] = lightmap->bundle[0];
|
||||
diffuse->bundle[TB_NORMALMAP] = normal->bundle[0];
|
||||
|
||||
if (specular)
|
||||
{
|
||||
diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0];
|
||||
diffuse->bundle[TB_SPECULARMAP].image[0] = tr.blackImage;
|
||||
}
|
||||
|
||||
diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0];
|
||||
diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex];
|
||||
|
||||
lightmap->active = qfalse;
|
||||
normal->active = qfalse;
|
||||
|
||||
if (specular)
|
||||
{
|
||||
specular->active = qfalse;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no deluxe mapping, turn off normal and specular
|
||||
normal->active = qfalse;
|
||||
specular->active = qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
// condense stages
|
||||
numStages = 0;
|
||||
for (i = 0; i < MAX_SHADER_STAGES; i++)
|
||||
{
|
||||
if (!stages[i].active)
|
||||
continue;
|
||||
|
||||
if (i == numStages)
|
||||
{
|
||||
numStages++;
|
||||
continue;
|
||||
}
|
||||
|
||||
stages[numStages] = stages[i];
|
||||
stages[i].active = qfalse;
|
||||
numStages++;
|
||||
}
|
||||
|
||||
if (numStages == i && i == 2 && CollapseMultitexture())
|
||||
numStages--;
|
||||
|
||||
return numStages;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
|
||||
|
@ -2435,9 +2606,7 @@ static shader_t *FinishShader( void ) {
|
|||
//
|
||||
// look for multitexture potential
|
||||
//
|
||||
if ( stage > 1 && CollapseMultitexture() ) {
|
||||
stage--;
|
||||
}
|
||||
stage = CollapseStagesToGLSL();
|
||||
|
||||
if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
|
||||
if (vertexLightmap) {
|
||||
|
|
|
@ -389,7 +389,6 @@ static void DrawSkySideVBO( struct image_s *image, const int mins[2], const int
|
|||
int s, t;
|
||||
//int firstVertex = tess.numVertexes;
|
||||
//int firstIndex = tess.numIndexes;
|
||||
matrix_t matrix;
|
||||
vec4_t color;
|
||||
|
||||
tess.numVertexes = 0;
|
||||
|
@ -443,27 +442,18 @@ static void DrawSkySideVBO( struct image_s *image, const int mins[2], const int
|
|||
|
||||
if (glRefConfig.glsl && r_arb_shader_objects->integer)
|
||||
{
|
||||
shaderProgram_t *sp = GLSL_GetGenericShaderProgram();
|
||||
shaderProgram_t *sp = &tr.textureColorShader;
|
||||
|
||||
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, TCGEN_TEXTURE);
|
||||
Matrix16Identity(matrix);
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, 0);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, CGEN_CONST);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, AGEN_CONST);
|
||||
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
color[0] = tr.identityLight;
|
||||
color[1] = tr.identityLight;
|
||||
color[2] = tr.identityLight;
|
||||
color[3] = 1.0f;
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color);
|
||||
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -985,3 +975,4 @@ void RB_StageIteratorSky( void ) {
|
|||
backEnd.skyRenderedThisView = qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -218,12 +218,15 @@ void RB_InstantQuad(vec4_t quadVerts[4])
|
|||
|
||||
if (glRefConfig.glsl && r_arb_shader_objects->integer)
|
||||
{
|
||||
shaderProgram_t *sp = &tr.textureOnlyShader;
|
||||
shaderProgram_t *sp = &tr.textureColorShader;
|
||||
vec4_t color;
|
||||
|
||||
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -335,7 +338,7 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
|
|||
int i;
|
||||
srfTriangle_t *tri;
|
||||
srfVert_t *dv;
|
||||
float *xyz, *normal, *texCoords;
|
||||
float *xyz, *normal, *tangent, *bitangent, *texCoords;
|
||||
glIndex_t *index;
|
||||
byte *color;
|
||||
qboolean needsNormal;
|
||||
|
@ -354,6 +357,8 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
|
|||
dv = verts;
|
||||
xyz = tess.xyz[ tess.numVertexes ];
|
||||
normal = tess.normal[ tess.numVertexes ];
|
||||
tangent = tess.tangent[ tess.numVertexes ];
|
||||
bitangent = tess.bitangent[ tess.numVertexes ];
|
||||
texCoords = tess.texCoords[ tess.numVertexes ][0];
|
||||
color = tess.vertexColors[ tess.numVertexes ];
|
||||
needsNormal = tess.shader->vertexAttribs & ATTR_NORMAL;
|
||||
|
@ -367,6 +372,12 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
|
|||
normal[0] = dv->normal[0];
|
||||
normal[1] = dv->normal[1];
|
||||
normal[2] = dv->normal[2];
|
||||
tangent[0] = dv->tangent[0];
|
||||
tangent[1] = dv->tangent[1];
|
||||
tangent[2] = dv->tangent[2];
|
||||
bitangent[0] = dv->bitangent[0];
|
||||
bitangent[1] = dv->bitangent[1];
|
||||
bitangent[2] = dv->bitangent[2];
|
||||
}
|
||||
|
||||
texCoords[0] = dv->st[0];
|
||||
|
@ -514,7 +525,6 @@ static void RB_SurfaceBeam( void )
|
|||
vec3_t direction, normalized_direction;
|
||||
vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
|
||||
vec3_t oldorigin, origin;
|
||||
matrix_t matrix;
|
||||
vec4_t color;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
@ -576,27 +586,18 @@ static void RB_SurfaceBeam( void )
|
|||
|
||||
if (glRefConfig.glsl && r_arb_shader_objects->integer)
|
||||
{
|
||||
shaderProgram_t *sp = GLSL_GetGenericShaderProgram();
|
||||
shaderProgram_t *sp = &tr.textureColorShader;
|
||||
|
||||
GLSL_VertexAttribsState(ATTR_POSITION);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, TCGEN_IDENTITY);
|
||||
Matrix16Identity(matrix);
|
||||
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, 0);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, CGEN_CONST);
|
||||
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, AGEN_CONST);
|
||||
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
color[0] = 1.0f;
|
||||
color[1] = 0.0f;
|
||||
color[2] = 0.0f;
|
||||
color[3] = 1.0f;
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color);
|
||||
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1295,7 +1296,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
int i, j;
|
||||
float *xyz;
|
||||
float *texCoords;
|
||||
float *normal;
|
||||
float *normal, *tangent, *bitangent;
|
||||
unsigned char *color;
|
||||
srfVert_t *dv;
|
||||
int rows, irows, vrows;
|
||||
|
@ -1377,6 +1378,8 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
|
||||
xyz = tess.xyz[numVertexes];
|
||||
normal = tess.normal[numVertexes];
|
||||
tangent = tess.tangent[numVertexes];
|
||||
bitangent = tess.bitangent[numVertexes];
|
||||
texCoords = tess.texCoords[numVertexes][0];
|
||||
color = ( unsigned char * ) &tess.vertexColors[numVertexes];
|
||||
//vDlightBits = &tess.vertexDlightBits[numVertexes];
|
||||
|
@ -1398,6 +1401,12 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
normal[0] = dv->normal[0];
|
||||
normal[1] = dv->normal[1];
|
||||
normal[2] = dv->normal[2];
|
||||
tangent[0] = dv->tangent[0];
|
||||
tangent[1] = dv->tangent[1];
|
||||
tangent[2] = dv->tangent[2];
|
||||
bitangent[0] = dv->bitangent[0];
|
||||
bitangent[1] = dv->bitangent[1];
|
||||
bitangent[2] = dv->bitangent[2];
|
||||
}
|
||||
* ( unsigned int * ) color = * ( unsigned int * ) dv->vertexColors;
|
||||
//*vDlightBits++ = dlightBits;
|
||||
|
|
|
@ -147,6 +147,18 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
dataSize += sizeof(verts[0].normal);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
vbo->ofs_tangent = dataSize;
|
||||
dataSize += sizeof(verts[0].tangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
vbo->ofs_bitangent = dataSize;
|
||||
dataSize += sizeof(verts[0].bitangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_TEXCOORD)
|
||||
{
|
||||
vbo->ofs_st = dataSize;
|
||||
|
@ -167,6 +179,8 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
|
||||
vbo->stride_xyz = dataSize;
|
||||
vbo->stride_normal = dataSize;
|
||||
vbo->stride_tangent = dataSize;
|
||||
vbo->stride_bitangent = dataSize;
|
||||
vbo->stride_st = dataSize;
|
||||
vbo->stride_lightmap = dataSize;
|
||||
vbo->stride_vertexcolor = dataSize;
|
||||
|
@ -192,6 +206,20 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
dataOfs += sizeof(verts[i].normal);
|
||||
}
|
||||
|
||||
// tangent
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
|
||||
dataOfs += sizeof(verts[i].tangent);
|
||||
}
|
||||
|
||||
// bitangent
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent));
|
||||
dataOfs += sizeof(verts[i].bitangent);
|
||||
}
|
||||
|
||||
// vertex texcoords
|
||||
if(stateBits & ATTR_TEXCOORD)
|
||||
{
|
||||
|
@ -224,6 +252,16 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
dataSize += sizeof(verts[0].normal);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
dataSize += sizeof(verts[0].tangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
dataSize += sizeof(verts[0].bitangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_TEXCOORD)
|
||||
{
|
||||
dataSize += sizeof(verts[0].st);
|
||||
|
@ -246,12 +284,16 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
|
||||
vbo->ofs_xyz = 0;
|
||||
vbo->ofs_normal = 0;
|
||||
vbo->ofs_tangent = 0;
|
||||
vbo->ofs_bitangent = 0;
|
||||
vbo->ofs_st = 0;
|
||||
vbo->ofs_lightmap = 0;
|
||||
vbo->ofs_vertexcolor = 0;
|
||||
|
||||
vbo->stride_xyz = sizeof(verts[0].xyz);
|
||||
vbo->stride_normal = sizeof(verts[0].normal);
|
||||
vbo->stride_tangent = sizeof(verts[0].tangent);
|
||||
vbo->stride_bitangent = sizeof(verts[0].bitangent);
|
||||
vbo->stride_vertexcolor = sizeof(verts[0].vertexColors);
|
||||
vbo->stride_st = sizeof(verts[0].st);
|
||||
vbo->stride_lightmap = sizeof(verts[0].lightmap);
|
||||
|
@ -277,6 +319,28 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
}
|
||||
}
|
||||
|
||||
// tangent
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
vbo->ofs_tangent = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
|
||||
dataOfs += sizeof(verts[i].tangent);
|
||||
}
|
||||
}
|
||||
|
||||
// bitangent
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
vbo->ofs_bitangent = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent));
|
||||
dataOfs += sizeof(verts[i].bitangent);
|
||||
}
|
||||
}
|
||||
|
||||
// vertex texcoords
|
||||
if(stateBits & ATTR_TEXCOORD)
|
||||
{
|
||||
|
@ -591,6 +655,8 @@ void R_InitVBOs(void)
|
|||
|
||||
dataSize = sizeof(tess.xyz[0]);
|
||||
dataSize += sizeof(tess.normal[0]);
|
||||
dataSize += sizeof(tess.tangent[0]);
|
||||
dataSize += sizeof(tess.bitangent[0]);
|
||||
dataSize += sizeof(tess.vertexColors[0]);
|
||||
dataSize += sizeof(tess.texCoords[0][0]) * 2;
|
||||
dataSize *= SHADER_MAX_VERTEXES;
|
||||
|
@ -604,14 +670,18 @@ void R_InitVBOs(void)
|
|||
|
||||
tess.vbo->ofs_xyz = 0;
|
||||
tess.vbo->ofs_normal = tess.vbo->ofs_xyz + sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES;
|
||||
tess.vbo->ofs_tangent = tess.vbo->ofs_normal + sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
|
||||
tess.vbo->ofs_bitangent = tess.vbo->ofs_tangent + sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES;
|
||||
// these next two are actually interleaved
|
||||
tess.vbo->ofs_st = tess.vbo->ofs_normal + sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
|
||||
tess.vbo->ofs_st = tess.vbo->ofs_bitangent + sizeof(tess.bitangent[0]) * SHADER_MAX_VERTEXES;
|
||||
tess.vbo->ofs_lightmap = tess.vbo->ofs_st + sizeof(tess.texCoords[0][0]);
|
||||
|
||||
tess.vbo->ofs_vertexcolor = tess.vbo->ofs_st + sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES;
|
||||
|
||||
tess.vbo->stride_xyz = sizeof(tess.xyz[0]);
|
||||
tess.vbo->stride_normal = sizeof(tess.normal[0]);
|
||||
tess.vbo->stride_tangent = sizeof(tess.tangent[0]);
|
||||
tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]);
|
||||
tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]);
|
||||
tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2;
|
||||
tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2;
|
||||
|
@ -760,6 +830,16 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal);
|
||||
}
|
||||
|
||||
if(attribBits & ATTR_TANGENT)
|
||||
{
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent);
|
||||
}
|
||||
|
||||
if(attribBits & ATTR_BITANGENT)
|
||||
{
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
|
||||
}
|
||||
|
||||
if(attribBits & ATTR_COLOR)
|
||||
{
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors);
|
||||
|
@ -770,6 +850,8 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_xyz, tess.numVertexes * sizeof(tess.xyz[0]), tess.xyz);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_st, tess.numVertexes * sizeof(tess.texCoords[0][0]) * 2, tess.texCoords);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue