Calculate tangent space in fragment shader instead of storing per vertex

This commit is contained in:
James Canete 2012-04-25 08:26:39 +00:00
parent 0e6eed98c0
commit 24b39fe00f
11 changed files with 341 additions and 220 deletions

View File

@ -1,3 +1,4 @@
- Calculate tangent space in fragment shader instead of storing per vertex
- Fix sun flare with sky portals. Sun flare must be inside sky portal. - Fix sun flare with sky portals. Sun flare must be inside sky portal.
- Speed up tone mapping - Speed up tone mapping
- Add fast light shader path when r_normalMapping and r_specularMapping are 0 - Add fast light shader path when r_normalMapping and r_specularMapping are 0

View File

@ -768,6 +768,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
surf->data = (surfaceType_t *)cv; surf->data = (surfaceType_t *)cv;
#ifdef USE_VERT_TANGENT_SPACE
// Tr3B - calc tangent spaces // Tr3B - calc tangent spaces
{ {
srfVert_t *dv[3]; srfVert_t *dv[3];
@ -781,6 +782,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
R_CalcTangentVectors(dv); R_CalcTangentVectors(dv);
} }
} }
#endif
} }
@ -999,6 +1001,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
cv->numTriangles -= badTriangles; cv->numTriangles -= badTriangles;
} }
#ifdef USE_VERT_TANGENT_SPACE
// Tr3B - calc tangent spaces // Tr3B - calc tangent spaces
{ {
srfVert_t *dv[3]; srfVert_t *dv[3];
@ -1012,6 +1015,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
R_CalcTangentVectors(dv); R_CalcTangentVectors(dv);
} }
} }
#endif
} }
/* /*
@ -1788,8 +1792,10 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out)
for(j = 0; j < 3; j++) for(j = 0; j < 3; j++)
{ {
out->xyz[j] = in->xyz[j]; out->xyz[j] = in->xyz[j];
#ifdef USE_VERT_TANGENT_SPACE
out->tangent[j] = in->tangent[j]; out->tangent[j] = in->tangent[j];
out->bitangent[j] = in->bitangent[j]; out->bitangent[j] = in->bitangent[j];
#endif
out->normal[j] = in->normal[j]; out->normal[j] = in->normal[j];
out->lightdir[j] = in->lightdir[j]; out->lightdir[j] = in->lightdir[j];
} }
@ -2031,9 +2037,15 @@ static void R_CreateWorldVBO(void)
} }
} }
#ifdef USE_VERT_TANGENT_SPACE
s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts, s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts,
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT | ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT |
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
#else
s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts,
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD |
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
#endif
s_worldData.ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", 0), numTriangles, triangles, VBO_USAGE_STATIC); s_worldData.ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", 0), numTriangles, triangles, VBO_USAGE_STATIC);

View File

@ -212,7 +212,7 @@ static int neighbors[8][2] = {
} }
} }
#ifdef USE_VERT_TANGENT_SPACE
static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numTriangles, static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numTriangles,
srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2])
{ {
@ -290,6 +290,7 @@ static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRI
} }
} }
} }
#endif
static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
@ -667,7 +668,9 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
// calculate normals // calculate normals
MakeMeshNormals( width, height, ctrl ); MakeMeshNormals( width, height, ctrl );
#ifdef USE_VERT_TANGENT_SPACE
MakeMeshTangentVectors(width, height, ctrl, numTriangles, triangles); MakeMeshTangentVectors(width, height, ctrl, numTriangles, triangles);
#endif
return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles); return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles);
} }

View File

@ -226,74 +226,75 @@ static const char *fallbackLightallShader_vp =
"attribute vec4 attr_TexCoord0;\r\n#if defined(USE_LIGHTMAP)\r\nattribute ve" "attribute vec4 attr_TexCoord0;\r\n#if defined(USE_LIGHTMAP)\r\nattribute ve"
"c4 attr_TexCoord1;\r\n#endif\r\nattribute vec4 attr_Color;\r\n\r\nattribute" "c4 attr_TexCoord1;\r\n#endif\r\nattribute vec4 attr_Color;\r\n\r\nattribute"
" vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\n\r\n#if defined(USE_" " vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\n\r\n#if defined(USE_"
"NORMALMAP)\r\nattribute vec3 attr_Tangent;\r\nattribute vec3 attr_Bitangent" "VERT_TANGENT_SPACE)\r\nattribute vec3 attr_Tangent;\r\nattribute vec3 attr_"
";\r\n#endif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute vec4 attr" "Bitangent;\r\n#endif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute "
"_Position2;\r\nattribute vec3 attr_Normal2;\r\n #if defined(USE_NORMALMAP)" "vec4 attr_Position2;\r\nattribute vec3 attr_Normal2;\r\n #if defined(USE_V"
"\r\nattribute vec3 attr_Tangent2;\r\nattribute vec3 attr_Bitangent2;\r\n #" "ERT_TANGENT_SPACE)\r\nattribute vec3 attr_Tangent2;\r\nattribute vec3 attr_"
"endif\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)" "Bitangent2;\r\n #endif\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined"
"\r\nattribute vec3 attr_LightDirection;\r\n#endif\r\n\r\n#if defined(TCGEN_" "(USE_LIGHT_VECTOR)\r\nattribute vec3 attr_LightDirection;\r\n#endif\r\n\r\n"
"ENVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(US" "#if defined(TCGEN_ENVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIG"
"E_FAST_LIGHT)\r\nuniform vec3 u_ViewOrigin;\r\n#endif\r\n\r\nuniform mat4" "HT) && !defined(USE_FAST_LIGHT)\r\nuniform vec3 u_ViewOrigin;\r\n#endif\r"
" u_DiffuseTexMatrix;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\nun" "\n\r\nuniform mat4 u_DiffuseTexMatrix;\r\nuniform mat4 u_ModelViewProje"
"iform vec4 u_BaseColor;\r\nuniform vec4 u_VertColor;\r\n\r\n#if defined" "ctionMatrix;\r\nuniform vec4 u_BaseColor;\r\nuniform vec4 u_VertColor;"
"(USE_MODELMATRIX)\r\nuniform mat4 u_ModelMatrix;\r\n#endif\r\n\r\n#if def" "\r\n\r\n#if defined(USE_MODELMATRIX)\r\nuniform mat4 u_ModelMatrix;\r\n#e"
"ined(USE_VERTEX_ANIMATION)\r\nuniform float u_VertexLerp;\r\n#endif\r\n\r" "ndif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nuniform float u_VertexLer"
"\n#if defined(USE_LIGHT_VECTOR)\r\nuniform vec4 u_LightOrigin;\r\n #if d" "p;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR)\r\nuniform vec4 u_Light"
"efined(USE_FAST_LIGHT)\r\nuniform vec3 u_DirectedLight;\r\nuniform vec3 " "Origin;\r\n #if defined(USE_FAST_LIGHT)\r\nuniform vec3 u_DirectedLight;"
" u_AmbientLight;\r\nuniform float u_LightRadius;\r\n #endif\r\n#endif\r\n" "\r\nuniform vec3 u_AmbientLight;\r\nuniform float u_LightRadius;\r\n #e"
"\r\nvarying vec2 var_DiffuseTex;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nvary" "ndif\r\n#endif\r\n\r\nvarying vec2 var_DiffuseTex;\r\n\r\n#if defined(USE"
"ing vec2 var_LightTex;\r\n#endif\r\n\r\n#if defined(USE_NORMALMAP) || def" "_LIGHTMAP)\r\nvarying vec2 var_LightTex;\r\n#endif\r\n\r\n#if defined(USE"
"ined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\nvarying vec3 var_SampleToV" "_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\nvarying ve"
"iew;\r\n#endif\r\n\r\nvarying vec4 var_Color;\r\n//varying vec3 var_Pos" "c3 var_SampleToView;\r\n#endif\r\n\r\nvarying vec4 var_Color;\r\nvaryin"
"ition;\r\nvarying vec3 var_Normal;\r\n#if defined(USE_NORMALMAP)\r\nvaryi" "g vec3 var_Position;\r\nvarying vec3 var_Normal;\r\n\r\n#if defined(USE"
"ng vec3 var_Tangent;\r\nvarying vec3 var_Bitangent;\r\n#endif\r\n\r\n#i" "_VERT_TANGENT_SPACE)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_B"
"f defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)\r\nvarying vec3 va" "itangent;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR) && defined(USE_FAS"
"r_VectLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXE" "T_LIGHT)\r\nvarying vec3 var_VectLight;\r\n#endif\r\n\r\n#if defined(USE_"
"MAP)\r\nvarying vec3 var_WorldLight;\r\n#endif\r\n\r\n\r\nvec2 DoTexMatri" "LIGHT) && !defined(USE_DELUXEMAP)\r\nvarying vec3 var_WorldLight;\r\n#end"
"x(vec2 st, vec3 position, mat4 texMatrix)\r\n{\r\n\tvec2 st2 = (texMatrix *" "if\r\n\r\n\r\nvec2 DoTexMatrix(vec2 st, vec3 position, mat4 texMatrix)\r\n{"
" vec4(st, 1, 0)).st;\r\n\r\n\tvec3 offsetPos = position.xyz / 1024.0;\r\n\t" "\r\n\tvec2 st2 = (texMatrix * vec4(st, 1, 0)).st;\r\n\r\n\tvec3 offsetPos ="
"offsetPos.x += offsetPos.z;\r\n\r\n\tvec2 texOffset = sin((offsetPos.xy + v" " position.xyz / 1024.0;\r\n\toffsetPos.x += offsetPos.z;\r\n\r\n\tvec2 texO"
"ec2(texMatrix[3][1])) * 2.0 * M_PI);\r\n\t\r\n\treturn st2 + texOffset * te" "ffset = sin((offsetPos.xy + vec2(texMatrix[3][1])) * 2.0 * M_PI);\r\n\t\r\n"
"xMatrix[3][0];\r\n}\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_VERTEX_ANIMA" "\treturn st2 + texOffset * texMatrix[3][0];\r\n}\r\n\r\nvoid main()\r\n{\r"
"TION)\r\n\tvec4 position = mix(attr_Position, attr_Position2, u_VertexLerp" "\n#if defined(USE_VERTEX_ANIMATION)\r\n\tvec4 position = mix(attr_Position"
");\r\n\tvec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_V" ", attr_Position2, u_VertexLerp);\r\n\tvec3 normal = normalize(mix(attr_N"
"ertexLerp));\r\n #if defined(USE_NORMALMAP)\r\n\tvec3 tangent = normaliz" "ormal, attr_Normal2, u_VertexLerp));\r\n #if defined(USE_VERT_TANGEN"
"e(mix(attr_Tangent, attr_Tangent2, u_VertexLerp));\r\n\tvec3 bitangent " "T_SPACE)\r\n\tvec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2,"
"= normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp));\r\n #endi" " u_VertexLerp));\r\n\tvec3 bitangent = normalize(mix(attr_Bitangent, attr"
"f\r\n#else\r\n\tvec4 position = attr_Position;\r\n\tvec3 normal = attr_" "_Bitangent2, u_VertexLerp));\r\n #endif\r\n#else\r\n\tvec4 position = att"
"Normal;\r\n #if defined(USE_NORMALMAP)\r\n\tvec3 tangent = attr_Tangent;" "r_Position;\r\n\tvec3 normal = attr_Normal;\r\n #if defined(USE_VERT_TA"
"\r\n\tvec3 bitangent = attr_Bitangent;\r\n #endif\r\n#endif\r\n\r\n\tgl_Po" "NGENT_SPACE)\r\n\tvec3 tangent = attr_Tangent;\r\n\tvec3 bitangent = attr"
"sition = u_ModelViewProjectionMatrix * position;\r\n\r\n#if (defined(USE_LI" "_Bitangent;\r\n #endif\r\n#endif\r\n\r\n\tgl_Position = u_ModelViewProject"
"GHTMAP) || defined(USE_LIGHT_VERTEX)) && !defined(USE_DELUXEMAP)\r\n\tvec3 " "ionMatrix * position;\r\n\r\n#if (defined(USE_LIGHTMAP) || defined(USE_LIGH"
"worldLight = attr_LightDirection;\r\n#endif\r\n\t\r\n#if defined(USE_MODELM" "T_VERTEX)) && !defined(USE_DELUXEMAP)\r\n\tvec3 worldLight = attr_LightDire"
"ATRIX)\r\n\tposition = u_ModelMatrix * position;\r\n\tnormal = (u_Model" "ction;\r\n#endif\r\n\t\r\n#if defined(USE_MODELMATRIX)\r\n\tposition = u_M"
"Matrix * vec4(normal, 0.0)).xyz;\r\n\r\n #if defined (USE_NORMALMAP)\r\n\t" "odelMatrix * position;\r\n\tnormal = (u_ModelMatrix * vec4(normal, 0.0))"
"tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;\r\n\tbitangent = (u_M" ".xyz;\r\n #if defined(USE_VERT_TANGENT_SPACE)\r\n\ttangent = (u_ModelMat"
"odelMatrix * vec4(bitangent, 0.0)).xyz;\r\n #endif\r\n\r\n #if defined(US" "rix * vec4(tangent, 0.0)).xyz;\r\n\tbitangent = (u_ModelMatrix * vec4(bitan"
"E_LIGHTMAP) && !defined(USE_DELUXEMAP)\r\n\tworldLight = (u_ModelMatrix * v" "gent, 0.0)).xyz;\r\n #endif\r\n\r\n #if defined(USE_LIGHTMAP) && !defined"
"ec4(worldLight, 0.0)).xyz;\r\n #endif\r\n#endif\r\n\r\n#if defined(TCGEN_E" "(USE_DELUXEMAP)\r\n\tworldLight = (u_ModelMatrix * vec4(worldLight, 0.0)).x"
"NVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE" "yz;\r\n #endif\r\n#endif\r\n\r\n\tvar_Position = position.xyz;\r\n\r\n#if "
"_FAST_LIGHT)\r\n\tvec3 SampleToView = u_ViewOrigin - position.xyz;\r\n#endi" "defined(TCGEN_ENVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIGHT) "
"f\r\n\r\n#if defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_F" "&& !defined(USE_FAST_LIGHT)\r\n\tvec3 SampleToView = u_ViewOrigin - positio"
"AST_LIGHT)\r\n\tvar_SampleToView = SampleToView;\r\n#endif\r\n\r\n#if defin" "n.xyz;\r\n#endif\r\n\r\n#if defined(USE_NORMALMAP) || defined(USE_LIGHT) &&"
"ed(TCGEN_ENVIRONMENT)\r\n\tvec3 viewer = normalize(SampleToView);\r\n\tvec3" " !defined(USE_FAST_LIGHT)\r\n\tvar_SampleToView = SampleToView;\r\n#endif\r"
" reflected = normal * 2.0 * dot(normal, viewer) - viewer;\r\n\r\n\tvec2 tex" "\n\r\n#if defined(TCGEN_ENVIRONMENT)\r\n\tvec3 viewer = normalize(SampleToV"
" = reflected.yz * vec2(0.5, -0.5) + 0.5;\r\n#else\r\n\tvec2 tex = attr_TexC" "iew);\r\n\tvec3 reflected = normal * 2.0 * dot(normal, viewer) - viewer;\r"
"oord0.st;\r\n#endif\r\n\r\n\tvar_DiffuseTex = DoTexMatrix(tex, position.xyz" "\n\r\n\tvec2 tex = reflected.yz * vec2(0.5, -0.5) + 0.5;\r\n#else\r\n\tvec2"
", u_DiffuseTexMatrix);\r\n\r\n#if defined(USE_LIGHTMAP)\r\n\tvar_LightTex =" " tex = attr_TexCoord0.st;\r\n#endif\r\n\r\n\tvar_DiffuseTex = DoTexMatrix(t"
" attr_TexCoord1.st;\r\n#endif\r\n\r\n\tvar_Color = u_VertColor * attr_Color" "ex, position.xyz, u_DiffuseTexMatrix);\r\n\r\n#if defined(USE_LIGHTMAP)\r\n"
" + u_BaseColor;\r\n \r\n\tvar_Normal = normal;\r\n\r\n#if defined (USE_NOR" "\tvar_LightTex = attr_TexCoord1.st;\r\n#endif\r\n\r\n\tvar_Color = u_VertCo"
"MALMAP)\r\n\tvar_Tangent = tangent;\r\n\tvar_Bitangent = bitangent;\r\n#end" "lor * attr_Color + u_BaseColor;\r\n \r\n\tvar_Normal = normal;\r\n#if defi"
"if\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)\r\n #if define" "ned(USE_VERT_TANGENT_SPACE)\r\n\tvar_Tangent = tangent;\r\n\tvar_Bitangent "
"d(USE_LIGHT_VECTOR)\r\n\tvec3 worldLight = u_LightOrigin.xyz - (position.xy" "= bitangent;\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXE"
"z * u_LightOrigin.w);\r\n #endif\r\n\r\n\tworldLight += normal * 0.0001;\r" "MAP)\r\n #if defined(USE_LIGHT_VECTOR)\r\n\tvec3 worldLight = u_LightOrigi"
"\n\tvar_WorldLight = worldLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VEC" "n.xyz - (position.xyz * u_LightOrigin.w);\r\n #endif\r\n\r\n\tworldLight +"
"TOR) && defined(USE_FAST_LIGHT)\r\n #if defined(USE_INVSQRLIGHT)\r\n\tfloa" "= normal * 0.0001;\r\n\tvar_WorldLight = worldLight;\r\n#endif\r\n\r\n#if d"
"t intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\tfloat inte" "efined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)\r\n #if defined(USE_IN"
"nsity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_Light" "VSQRLIGHT)\r\n\tfloat intensity = 1.0 / dot(worldLight, worldLight);\r\n #"
"Radius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\tfloat NL = clamp(dot(normal, n" "else\r\n\tfloat intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_L"
"ormalize(worldLight)), 0.0, 1.0);\r\n\r\n\tvar_VectLight = u_DirectedLight " "ightRadius * u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\tfloat NL ="
"* intensity * NL + u_AmbientLight;\r\n#endif\r\n}\r\n"; " clamp(dot(normal, normalize(worldLight)), 0.0, 1.0);\r\n\r\n\tvar_VectLigh"
"t = u_DirectedLight * intensity * NL + u_AmbientLight;\r\n#endif\r\n}\r\n";
static const char *fallbackLightallShader_fp = static const char *fallbackLightallShader_fp =
"uniform sampler2D u_DiffuseMap;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nuniform" "uniform sampler2D u_DiffuseMap;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nuniform"
@ -308,123 +309,129 @@ static const char *fallbackLightallShader_fp =
"t u_SpecularReflectance;\r\n#endif\r\n\r\n#if !defined(USE_FAST_LIGHT)" "t u_SpecularReflectance;\r\n#endif\r\n\r\n#if !defined(USE_FAST_LIGHT)"
"\r\nuniform float u_DiffuseRoughness;\r\n#endif\r\n\r\nvarying vec2 " "\r\nuniform float u_DiffuseRoughness;\r\n#endif\r\n\r\nvarying vec2 "
" var_DiffuseTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_Lig" " var_DiffuseTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_Lig"
"htTex;\r\n#endif\r\nvarying vec4 var_Color;\r\n\r\nvarying vec3 v" "htTex;\r\n#endif\r\nvarying vec4 var_Color;\r\nvarying vec3 var_P"
"ar_SampleToView;\r\n\r\nvarying vec3 var_Normal;\r\n#if defined(USE_NO" "osition;\r\n\r\nvarying vec3 var_SampleToView;\r\n\r\nvarying vec3 "
"RMALMAP)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bitange" " var_Normal;\r\n#if defined(USE_VERT_TANGENT_SPACE)\r\nvarying vec3 v"
"nt;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGH" "ar_Tangent;\r\nvarying vec3 var_Bitangent;\r\n#endif\r\n\r\n#if define"
"T)\r\nvarying vec3 var_VectLight;\r\n#endif\r\n\r\n#if defined(USE_LIG" "d(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)\r\nvarying vec3 var_Vec"
"HT) && !defined(USE_DELUXEMAP)\r\nvarying vec3 var_WorldLight;\r\n#end" "tLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)"
"if\r\n\r\n#define EPSILON 0.00000001\r\n\r\n#if defined(USE_PARALLAXMAP)\r" "\r\nvarying vec3 var_WorldLight;\r\n#endif\r\n\r\n#define EPSILON 0.00"
"\nfloat SampleHeight(sampler2D normalMap, vec2 t)\r\n{\r\n #if defined(SWI" "000001\r\n\r\n#if defined(USE_PARALLAXMAP)\r\nfloat SampleHeight(sampler2D "
"ZZLE_NORMALMAP)\r\n\treturn texture2D(normalMap, t).r;\r\n #else\r\n\tretu" "normalMap, vec2 t)\r\n{\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\treturn tex"
"rn texture2D(normalMap, t).a;\r\n #endif\r\n}\r\n\r\nfloat RayIntersectDis" "ture2D(normalMap, t).r;\r\n #else\r\n\treturn texture2D(normalMap, t).a;\r"
"placeMap(vec2 dp, vec2 ds, sampler2D normalMap)\r\n{\r\n\tconst int linearS" "\n #endif\r\n}\r\n\r\nfloat RayIntersectDisplaceMap(vec2 dp, vec2 ds, samp"
"earchSteps = 16;\r\n\tconst int binarySearchSteps = 6;\r\n\r\n\tfloat depth" "ler2D normalMap)\r\n{\r\n\tconst int linearSearchSteps = 16;\r\n\tconst int"
"Step = 1.0 / float(linearSearchSteps);\r\n\r\n\t// current size of search w" " binarySearchSteps = 6;\r\n\r\n\tfloat depthStep = 1.0 / float(linearSearch"
"indow\r\n\tfloat size = depthStep;\r\n\r\n\t// current depth position\r\n\t" "Steps);\r\n\r\n\t// current size of search window\r\n\tfloat size = depthSt"
"float depth = 0.0;\r\n\r\n\t// best match found (starts with last position " "ep;\r\n\r\n\t// current depth position\r\n\tfloat depth = 0.0;\r\n\r\n\t// "
"1.0)\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t// search front to back for first" "best match found (starts with last position 1.0)\r\n\tfloat bestDepth = 1.0"
" point inside object\r\n\tfor(int i = 0; i < linearSearchSteps - 1; ++i)\r" ";\r\n\r\n\t// search front to back for first point inside object\r\n\tfor(i"
"\n\t{\r\n\t\tdepth += size;\r\n\t\t\r\n\t\tfloat t = SampleHeight(normalMap" "nt i = 0; i < linearSearchSteps - 1; ++i)\r\n\t{\r\n\t\tdepth += size;\r\n"
", dp + ds * depth);\r\n\t\t\r\n\t\tif(bestDepth > 0.996)\t\t// if no depth " "\t\t\r\n\t\tfloat t = SampleHeight(normalMap, dp + ds * depth);\r\n\t\t\r\n"
"found yet\r\n\t\t\tif(depth >= t)\r\n\t\t\t\tbestDepth = depth;\t// store b" "\t\tif(bestDepth > 0.996)\t\t// if no depth found yet\r\n\t\t\tif(depth >= "
"est depth\r\n\t}\r\n\r\n\tdepth = bestDepth;\r\n\t\r\n\t// recurse around f" "t)\r\n\t\t\t\tbestDepth = depth;\t// store best depth\r\n\t}\r\n\r\n\tdepth"
"irst point (depth) for closest match\r\n\tfor(int i = 0; i < binarySearchSt" " = bestDepth;\r\n\t\r\n\t// recurse around first point (depth) for closest "
"eps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;\r\n\r\n\t\tfloat t = SampleHeight(norm" "match\r\n\tfor(int i = 0; i < binarySearchSteps; ++i)\r\n\t{\r\n\t\tsize *="
"alMap, dp + ds * depth);\r\n\t\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n\t\t\tbe" " 0.5;\r\n\r\n\t\tfloat t = SampleHeight(normalMap, dp + ds * depth);\r\n\t"
"stDepth = depth;\r\n\t\t\tdepth -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\tdepth +=" "\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n\t\t\tbestDepth = depth;\r\n\t\t\tdept"
" size;\r\n\t}\r\n\r\n\treturn bestDepth;\r\n}\r\n#endif\r\n\r\nfloat CalcDi" "h -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\tdepth += size;\r\n\t}\r\n\r\n\treturn "
"ffuse(vec3 N, vec3 L, vec3 E, float NE, float NL, float fzero, float roughn" "bestDepth;\r\n}\r\n#endif\r\n\r\nfloat CalcDiffuse(vec3 N, vec3 L, vec3 E, "
"ess)\r\n{\r\n #if defined(USE_OREN_NAYAR)\r\n\tfloat gamma = dot(E - N * N" "float NE, float NL, float fzero, float roughness)\r\n{\r\n #if defined(USE"
"E, L - N * NL);\r\n\tfloat r_sq = roughness * roughness;\r\n\r\n\tfloat A =" "_OREN_NAYAR)\r\n\tfloat gamma = dot(E - N * NE, L - N * NL);\r\n\tfloat r_s"
" 1.0 - 0.5 * (r_sq / (r_sq + 0.57));\r\n\tfloat B = 0.45 * (r_sq / (r_sq + " "q = roughness * roughness;\r\n\r\n\tfloat A = 1.0 - 0.5 * (r_sq / (r_sq + 0"
"0.09));\r\n\r\n\tfloat alpha = max(acos(NE), acos(NL));\r\n\tfloat beta = " ".57));\r\n\tfloat B = 0.45 * (r_sq / (r_sq + 0.09));\r\n\r\n\tfloat alpha ="
"min(acos(NE), acos(NL));\r\n\r\n\tfloat C = sin(alpha) * tan(beta);\r\n\r\n" " max(acos(NE), acos(NL));\r\n\tfloat beta = min(acos(NE), acos(NL));\r\n\r"
"\treturn A + B * clamp(gamma, 0.0, 1.0) * C;\r\n #else\r\n\treturn 1.0 - f" "\n\tfloat C = sin(alpha) * tan(beta);\r\n\r\n\treturn A + B * clamp(gamma, "
"zero;\r\n #endif\r\n}\r\n\r\n#if defined(USE_SPECULARMAP)\r\nfloat CalcSpe" "0.0, 1.0) * C;\r\n #else\r\n\treturn 1.0 - fzero;\r\n #endif\r\n}\r\n\r\n"
"cular(float NH, float NL, float NE, float EH, float fzero, float shininess)" "#if defined(USE_SPECULARMAP)\r\nfloat CalcSpecular(float NH, float NL, floa"
"\r\n{\r\n #if defined(USE_BLINN) || defined(USE_TRIACE) || defined(USE_TOR" "t NE, float EH, float fzero, float shininess)\r\n{\r\n #if defined(USE_BLI"
"RANCE_SPARROW)\r\n\tfloat blinn = pow(NH, shininess);\r\n #endif\r\n\r\n " "NN) || defined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW)\r\n\tfloat blin"
"#if defined(USE_BLINN)\r\n\treturn blinn;\r\n #endif\r\n\r\n #if defined(" "n = pow(NH, shininess);\r\n #endif\r\n\r\n #if defined(USE_BLINN)\r\n\tre"
"USE_COOK_TORRANCE) || defined (USE_TRIACE) || defined (USE_TORRANCE_SPARROW" "turn blinn;\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined "
")\r\n\tfloat fresnel = fzero + (1.0 - fzero) * pow(1.0 - EH, 5);\r\n #endi" "(USE_TRIACE) || defined (USE_TORRANCE_SPARROW)\r\n\tfloat fresnel = fzero +"
"f\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined(USE_TORRANCE_SPARROW)" " (1.0 - fzero) * pow(1.0 - EH, 5);\r\n #endif\r\n\r\n #if defined(USE_COO"
"\r\n\tfloat geo = 2.0 * NH * min(NE, NL);\r\n\tgeo /= max(EH, geo);\r\n #e" "K_TORRANCE) || defined(USE_TORRANCE_SPARROW)\r\n\tfloat geo = 2.0 * NH * mi"
"ndif \r\n\r\n #if defined(USE_COOK_TORRANCE)\r\n\tfloat m = sqrt(2.0 / sh" "n(NE, NL);\r\n\tgeo /= max(EH, geo);\r\n #endif \r\n\r\n #if defined(USE"
"ininess);\r\n\r\n\tfloat m_sq = m * m;\r\n\tfloat NH_sq = NH * NH;\r\n\tflo" "_COOK_TORRANCE)\r\n\tfloat m = sqrt(2.0 / shininess);\r\n\r\n\tfloat m_sq ="
"at beckmann = exp((NH_sq - 1.0) / max(m_sq * NH_sq, EPSILON)) / max(4.0 * m" " m * m;\r\n\tfloat NH_sq = NH * NH;\r\n\tfloat beckmann = exp((NH_sq - 1.0)"
"_sq * NH_sq * NH_sq, EPSILON);\r\n\r\n\treturn fresnel * geo * beckmann / m" " / max(m_sq * NH_sq, EPSILON)) / max(4.0 * m_sq * NH_sq * NH_sq, EPSILON);"
"ax(NE, EPSILON);\r\n #endif\r\n\r\n #if defined(USE_TRIACE)\r\n\tfloat sc" "\r\n\r\n\treturn fresnel * geo * beckmann / max(NE, EPSILON);\r\n #endif\r"
"ale = 0.1248582 * shininess + 0.2691817;\r\n\r\n\treturn fresnel * scale * " "\n\r\n #if defined(USE_TRIACE)\r\n\tfloat scale = 0.1248582 * shininess + "
"blinn / max(max(NL, NE), EPSILON);\r\n #endif\r\n \r\n #if defined(USE_T" "0.2691817;\r\n\r\n\treturn fresnel * scale * blinn / max(max(NL, NE), EPSIL"
"ORRANCE_SPARROW)\r\n\tfloat scale = 0.125 * shininess + 1.0;\r\n\r\n\tretur" "ON);\r\n #endif\r\n \r\n #if defined(USE_TORRANCE_SPARROW)\r\n\tfloat sc"
"n fresnel * geo * scale * blinn / max(NE, EPSILON);\r\n #endif\r\n}\r\n#en" "ale = 0.125 * shininess + 1.0;\r\n\r\n\treturn fresnel * geo * scale * blin"
"dif\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_DELUXEMAP)\r\n\tvec3 worldLi" "n / max(NE, EPSILON);\r\n #endif\r\n}\r\n#endif\r\n\r\nvoid main()\r\n{\r"
"ght = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0);\r\n\t//wo" "\n#if defined(USE_DELUXEMAP)\r\n\tvec3 worldLight = 2.0 * texture2D(u_Delux"
"rldLight += var_WorldLight * 0.0001;\r\n#elif defined(USE_LIGHT)\r\n\tvec3 " "eMap, var_LightTex).xyz - vec3(1.0);\r\n\t//worldLight += var_WorldLight * "
"worldLight = var_WorldLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHTMAP)\r\n" "0.0001;\r\n#elif defined(USE_LIGHT)\r\n\tvec3 worldLight = var_WorldLight;"
"\tvec4 lightSample = texture2D(u_LightMap, var_LightTex).rgba;\r\n #if def" "\r\n#endif\r\n\r\n#if defined(USE_LIGHTMAP)\r\n\tvec4 lightSample = texture"
"ined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *= exp2(lightSample.a * 255.0 - 12" "2D(u_LightMap, var_LightTex).rgba;\r\n #if defined(RGBE_LIGHTMAP)\r\n\tlig"
"8.0);\r\n #endif\r\n\tvec3 directedLight = lightSample.rgb;\r\n#elif defin" "htSample.rgb *= exp2(lightSample.a * 255.0 - 128.0);\r\n #endif\r\n\tvec3 "
"ed(USE_LIGHT_VECTOR)\r\n #if defined(USE_FAST_LIGHT)\r\n\tvec3 directedLig" "directedLight = lightSample.rgb;\r\n#elif defined(USE_LIGHT_VECTOR)\r\n #i"
"ht = var_VectLight;\r\n #else\r\n #if defined(USE_INVSQRLIGHT)\r\n\tflo" "f defined(USE_FAST_LIGHT)\r\n\tvec3 directedLight = var_VectLight;\r\n #el"
"at intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\tfloat i" "se\r\n #if defined(USE_INVSQRLIGHT)\r\n\tfloat intensity = 1.0 / dot(wor"
"ntensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_Li" "ldLight, worldLight);\r\n #else\r\n\tfloat intensity = clamp((1.0 - dot("
"ghtRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n #if defined(USE_SHADOWM" "worldLight, worldLight) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0"
"AP)\r\n \tvec3 dist3 = textureCube(u_ShadowMap, worldLight).rgb;\r\n\tfloa" ");\r\n #endif\r\n #if defined(USE_SHADOWMAP)\r\n \tvec3 dist3 = text"
"t dist = dot(dist3, vec3(1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0)) * u_Ligh" "ureCube(u_ShadowMap, worldLight).rgb;\r\n\tfloat dist = dot(dist3, vec3(1.0"
"tRadius;\r\n\r\n\tintensity *= clamp(sign(dist - length(worldLight)), 0.0, " " / (256.0 * 256.0), 1.0 / 256.0, 1.0)) * u_LightRadius;\r\n\r\n\tintensity "
"1.0);\r\n #endif\r\n\tvec3 directedLight = u_DirectedLight * intensity;" "*= clamp(sign(dist - length(worldLight)), 0.0, 1.0);\r\n #endif\r\n\tvec"
"\r\n\tvec3 ambientLight = u_AmbientLight;\r\n #endif\r\n#elif defined(USE" "3 directedLight = u_DirectedLight * intensity;\r\n\tvec3 ambientLight = u_"
"_LIGHT_VERTEX)\r\n\tvec3 directedLight = var_Color.rgb;\r\n#endif\r\n\t\r\n" "AmbientLight;\r\n #endif\r\n#elif defined(USE_LIGHT_VERTEX)\r\n\tvec3 dire"
"#if defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT" "ctedLight = var_Color.rgb;\r\n#endif\r\n\t\r\n#if defined(USE_NORMALMAP) ||"
")\r\n\tvec3 SampleToView = normalize(var_SampleToView);\r\n#endif\r\n\tvec2" " defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tvec3 SampleToView = no"
" tex = var_DiffuseTex;\r\n\r\n\tfloat ambientDiff = 1.0;\r\n\r\n#if defined" "rmalize(var_SampleToView);\r\n#endif\r\n\tvec2 tex = var_DiffuseTex;\r\n\r"
"(USE_NORMALMAP)\r\n\tmat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitang" "\n\tfloat ambientDiff = 1.0;\r\n\r\n#if defined(USE_NORMALMAP)\r\n #if def"
"ent.xyz, var_Normal.xyz);\r\n\r\n #if defined(USE_PARALLAXMAP)\r\n\tvec3 o" "ined(USE_VERT_TANGENT_SPACE)\r\n vec3 tangent = normalize(var_Tangent)"
"ffsetDir = normalize(SampleToView * tangentToWorld);\r\n #if 0\r\n fl" ";\r\n\tvec3 bitangent = normalize(var_Bitangent);\r\n #else\r\n\tvec3 q0 "
"oat height = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist = 0.05 * heig" "= dFdx(var_Position.xyz);\r\n\tvec3 q1 = dFdy(var_Position.xyz);\r\n\tvec2"
"ht - (0.05 / 2.0);\r\n #else\r\n\toffsetDir.xy *= 0.02 / offsetDir.z;\r" " st0 = dFdx(tex);\r\n\tvec2 st1 = dFdy(tex);\r\n\r\n\tvec3 tangent = -nor"
"\n\tfloat pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u_NormalMap);" "malize( q0 * st1.t - q1 * st0.t);\r\n\tvec3 bitangent = -normalize(-q0 * st"
"\r\n #endif\t\r\n\ttex += offsetDir.xy * pdist;\r\n #endif\r\n #if def" "1.s + q1 * st0.s);\r\n #endif\r\n\r\n\tmat3 tangentToWorld = mat3(tangent,"
"ined(SWIZZLE_NORMALMAP)\r\n\tvec3 normal = 2.0 * texture2D(u_NormalMap, tex" " bitangent, normalize(var_Normal.xyz));\r\n\r\n #if defined(USE_PARALLAXMA"
").agb - 1.0;\r\n #else\r\n\tvec3 normal = 2.0 * texture2D(u_NormalMap, tex" "P)\r\n\tvec3 offsetDir = normalize(SampleToView * tangentToWorld);\r\n #"
").rgb - 1.0;\r\n #endif\r\n\tnormal.z = sqrt(clamp(1.0 - dot(normal.xy, no" "if 0\r\n float height = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist"
"rmal.xy), 0.0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld * normal;\r\n " " = 0.05 * height - (0.05 / 2.0);\r\n #else\r\n\toffsetDir.xy *= 0.02 / o"
" #if defined(r_normalAmbient)\r\n\tambientDiff = 0.781341 * normal.z + 0.21" "ffsetDir.z;\r\n\tfloat pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u"
"8659;\r\n #endif\r\n#else\r\n\tvec3 worldNormal = var_Normal;\r\n#endif\r" "_NormalMap);\r\n #endif\t\r\n\ttex += offsetDir.xy * pdist;\r\n #endif"
"\n\r\n\tvec4 diffuse = texture2D(u_DiffuseMap, tex);\r\n\r\n#if defined(USE" "\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"_LIGHT) && defined(USE_FAST_LIGHT)\r\n\tdiffuse.rgb *= directedLight;\r\n#e" "ormalMap, tex).agb - 1.0;\r\n #else\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"lif defined(USE_LIGHT)\r\n\tworldNormal = normalize(worldNormal);\r\n\tworl" "ormalMap, tex).rgb - 1.0;\r\n #endif\r\n\tnormal.z = sqrt(clamp(1.0 - dot("
"dLight = normalize(worldLight);\r\n\r\n #if defined(USE_LIGHTMAP) || defin" "normal.xy, normal.xy), 0.0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld *"
"ed(USE_LIGHT_VERTEX)\r\n\tdirectedLight /= max(dot(normalize(var_Normal), w" " normal;\r\n #if defined(r_normalAmbient)\r\n\tambientDiff = 0.781341 * no"
"orldLight), 0.004);\r\n\r\n #if defined(r_normalAmbient)\r\n\tvec3 ambie" "rmal.z + 0.218659;\r\n #endif\r\n#else\r\n\tvec3 worldNormal = var_Normal;"
"ntLight = directedLight * r_normalAmbient;\r\n\tdirectedLight -= ambientLig" "\r\n#endif\r\n\r\n\tvec4 diffuse = texture2D(u_DiffuseMap, tex);\r\n\r\n#if"
"ht;\r\n #else\r\n\tvec3 ambientLight = vec3(0);\r\n #endif\r\n #endi" " defined(USE_LIGHT) && defined(USE_FAST_LIGHT)\r\n\tdiffuse.rgb *= directed"
"f\r\n\r\n\tfloat NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0);\r\n" "Light;\r\n#elif defined(USE_LIGHT)\r\n\tworldNormal = normalize(worldNormal"
"\tfloat NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0);\r\n #if def" ");\r\n\tworldLight = normalize(worldLight);\r\n\r\n #if defined(USE_LIGHTM"
"ined(USE_SPECULARMAP)\r\n\tfloat fzero = u_SpecularReflectance;\r\n #else" "AP) || defined(USE_LIGHT_VERTEX)\r\n\tdirectedLight /= max(dot(normalize(va"
"\r\n\tfloat fzero = 0.0;\r\n #endif\r\n\tfloat directedDiff = NL * CalcDif" "r_Normal), worldLight), 0.004);\r\n\r\n #if defined(r_normalAmbient)\r\n"
"fuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, u_DiffuseRoughne" "\tvec3 ambientLight = directedLight * r_normalAmbient;\r\n\tdirectedLight -"
"ss);\r\n\tdiffuse.rgb *= directedLight * directedDiff + ambientDiff * ambie" "= ambientLight;\r\n #else\r\n\tvec3 ambientLight = vec3(0);\r\n #endi"
"ntLight;\r\n \r\n #if defined(USE_SPECULARMAP)\r\n\tvec4 specular = textu" "f\r\n #endif\r\n\r\n\tfloat NL = clamp(dot(worldNormal, worldLight), 0."
"re2D(u_SpecularMap, tex);\r\n\t//specular.rgb = clamp(specular.rgb - diffus" "0, 1.0);\r\n\tfloat NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0);"
"e.rgb, 0.0, 1.0);\r\n\tfloat shininess = specular.a * 255 + 1.0;\r\n\r\n\tv" "\r\n #if defined(USE_SPECULARMAP)\r\n\tfloat fzero = u_SpecularReflectance"
"ec3 halfAngle = normalize(worldLight + SampleToView);\r\n\r\n\tfloat EH = c" ";\r\n #else\r\n\tfloat fzero = 0.0;\r\n #endif\r\n\tfloat directedDiff = "
"lamp(dot(SampleToView, halfAngle), 0.0, 1.0);\r\n\tfloat NH = clamp(dot(wor" "NL * CalcDiffuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, u_Di"
"ldNormal, halfAngle), 0.0, 1.0);\r\n\r\n\tfloat directedSpec = NL * CalcSp" "ffuseRoughness);\r\n\tdiffuse.rgb *= directedLight * directedDiff + ambient"
"ecular(NH, NL, NE, EH, fzero, shininess);\r\n \r\n #if defined(r_normal" "Diff * ambientLight;\r\n \r\n #if defined(USE_SPECULARMAP)\r\n\tvec4 spec"
"Ambient)\r\n\tvec3 ambientHalf = normalize(var_Normal + SampleToView);\r\n" "ular = texture2D(u_SpecularMap, tex);\r\n\t//specular.rgb = clamp(specular."
"\tfloat ambientSpec = max(dot(ambientHalf, worldNormal) + 0.5, 0.0);\r\n\ta" "rgb - diffuse.rgb, 0.0, 1.0);\r\n\tfloat shininess = specular.a * 255 + 1.0"
"mbientSpec *= ambientSpec * 0.44;\r\n\tambientSpec = pow(ambientSpec, shini" ";\r\n\r\n\tvec3 halfAngle = normalize(worldLight + SampleToView);\r\n\r\n\t"
"ness) * fzero;\r\n #if defined(USE_TRIACE)\r\n\tambientSpec *= 0.12485" "float EH = clamp(dot(SampleToView, halfAngle), 0.0, 1.0);\r\n\tfloat NH = c"
"82 * shininess + 0.2691817;\r\n #endif \r\n\tspecular.rgb *= direct" "lamp(dot(worldNormal, halfAngle), 0.0, 1.0);\r\n\r\n\tfloat directedSpec ="
"edSpec * directedLight + ambientSpec * ambientLight;\r\n #else\r\n\tspec" " NL * CalcSpecular(NH, NL, NE, EH, fzero, shininess);\r\n \r\n #if defi"
"ular.rgb *= directedSpec * directedLight;\r\n #endif\r\n #endif\r\n#end" "ned(r_normalAmbient)\r\n\tvec3 ambientHalf = normalize(var_Normal + SampleT"
"if\r\n\r\n\tgl_FragColor = diffuse;\r\n\r\n#if defined(USE_SPECULARMAP) && " "oView);\r\n\tfloat ambientSpec = max(dot(ambientHalf, worldNormal) + 0.5, 0"
"defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tgl_FragColor.rgb += spe" ".0);\r\n\tambientSpec *= ambientSpec * 0.44;\r\n\tambientSpec = pow(ambient"
"cular.rgb;\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VERTEX)\r\n\tgl_FragColo" "Spec, shininess) * fzero;\r\n #if defined(USE_TRIACE)\r\n\tambientSpec"
"r *= var_Color;\r\n#endif\r\n}\r\n"; " *= 0.1248582 * shininess + 0.2691817;\r\n #endif \r\n\tspecular.rg"
"b *= directedSpec * directedLight + ambientSpec * ambientLight;\r\n #els"
"e\r\n\tspecular.rgb *= directedSpec * directedLight;\r\n #endif\r\n #en"
"dif\r\n#endif\r\n\r\n\tgl_FragColor = diffuse;\r\n\r\n#if defined(USE_SPECU"
"LARMAP) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tgl_FragColor"
".rgb += specular.rgb;\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VERTEX)\r\n\t"
"gl_FragColor *= var_Color;\r\n#endif\r\n}\r\n";
static const char *fallbackShadowfillShader_vp = static const char *fallbackShadowfillShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute" "attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute"
@ -633,26 +640,26 @@ static const char *fallbackToneMapShader_vp =
static const char *fallbackToneMapShader_fp = static const char *fallbackToneMapShader_fp =
"uniform sampler2D u_TextureMap;\r\nuniform sampler2D u_LevelsMap;\r\n\r\nun" "uniform sampler2D u_TextureMap;\r\nuniform sampler2D u_LevelsMap;\r\n\r\nun"
"iform vec4 u_Color;\r\n\r\nuniform vec2 u_InvTexRes;\r\nuniform v" "iform vec4 u_Color;\r\n\r\nuniform vec2 u_AutoExposureMinMax;\r\n"
"ec2 u_AutoExposureMinMax;\r\n\r\nvarying vec2 var_TexCoords;\r\n" "\r\nvarying vec2 var_TexCoords;\r\n\r\nconst vec3 LUMINANCE_VECTOR = "
"\r\nconst vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0" " vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.587, 0.114);\r\n\r\nvec3 Fi"
".299, 0.587, 0.114);\r\n\r\nvec3 FilmicTonemap(vec3 x)\r\n{\r\n\tconst floa" "lmicTonemap(vec3 x)\r\n{\r\n\tconst float SS = 0.22; // Shoulder Strength"
"t SS = 0.22; // Shoulder Strength\r\n\tconst float LS = 0.30; // Linear S" "\r\n\tconst float LS = 0.30; // Linear Strength\r\n\tconst float LA = 0.1"
"trength\r\n\tconst float LA = 0.10; // Linear Angle\r\n\tconst float TS =" "0; // Linear Angle\r\n\tconst float TS = 0.20; // Toe Strength\r\n\tconst "
" 0.20; // Toe Strength\r\n\tconst float TAN = 0.01; // Toe Angle Numerator" "float TAN = 0.01; // Toe Angle Numerator\r\n\tconst float TAD = 0.30; // To"
"\r\n\tconst float TAD = 0.30; // Toe Angle Denominator\r\n\t\r\n\tvec3 SSxx" "e Angle Denominator\r\n\t\r\n\tvec3 SSxx = SS * x * x;\r\n\tvec3 LSx = LS *"
" = SS * x * x;\r\n\tvec3 LSx = LS * x;\r\n\tvec3 LALSx = LSx * LA;\r\n\t\r" " x;\r\n\tvec3 LALSx = LSx * LA;\r\n\t\r\n\treturn ((SSxx + LALSx + TS * TAN"
"\n\treturn ((SSxx + LALSx + TS * TAN) / (SSxx + LSx + TS * TAD)) - TAN / TA" ") / (SSxx + LSx + TS * TAD)) - TAN / TAD;\r\n\r\n\t//return ((x*(SS*x+LA*LS"
"D;\r\n\r\n\t//return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/T" ")+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/TAD;\r\n\r\n}\r\n\r\nvoid main()\r\n{"
"AD;\r\n\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = texture2D(u_TextureM" "\r\n\tvec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;\r\n\tv"
"ap, var_TexCoords) * u_Color;\r\n\tvec3 minAvgMax = texture2D(u_LevelsMap, " "ec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;\r\n\tvec3 logMin"
"var_TexCoords).rgb;\r\n\tvec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10" "AvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u_AutoExposureMinMax.y, -u_Auto"
".0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x);\r\n\t\t\r\n\tfloat a" "ExposureMinMax.x);\r\n\t\t\r\n\tfloat avgLum = exp2(logMinAvgMaxLum.y);\r\n"
"vgLum = exp2(logMinAvgMaxLum.y);\r\n\t//float maxLum = exp2(logMinAvgMaxLum" "\t//float maxLum = exp2(logMinAvgMaxLum.z);\r\n\t\r\n\tcolor.rgb /= avgLum;"
".z);\r\n\t\r\n\tcolor.rgb /= avgLum;\r\n\r\n\tvec3 fWhite = 1.0 / FilmicTon" "\r\n\r\n\tvec3 fWhite = 1.0 / FilmicTonemap(vec3(2.0));\r\n\tcolor.rgb = Fi"
"emap(vec3(2.0));\r\n\tcolor.rgb = FilmicTonemap(color.rgb) * fWhite;\r\n\t" "lmicTonemap(color.rgb) * fWhite;\r\n\t\r\n#if defined(r_obbcorrect)\r\n\tco"
"\r\n#if defined(r_obbcorrect)\r\n\tcolor.rgb /= r_obbcorrect;\r\n#endif\r\n" "lor.rgb /= r_obbcorrect;\r\n#endif\r\n\t\r\n\tgl_FragColor = color;\r\n}\r"
"\t\r\n\tgl_FragColor = color;\r\n}\r\n"; "\n";
static const char *fallbackCalcLevels4xShader_vp = static const char *fallbackCalcLevels4xShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\n\r\nunif" "attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\n\r\nunif"
@ -1147,11 +1154,13 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
// if(attribs & ATTR_TEXCOORD3) // if(attribs & ATTR_TEXCOORD3)
// qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3"); // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
#ifdef USE_VERT_TANGENT_SPACE
if(attribs & ATTR_TANGENT) if(attribs & ATTR_TANGENT)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
if(attribs & ATTR_BITANGENT) if(attribs & ATTR_BITANGENT)
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT, "attr_Bitangent"); qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT, "attr_Bitangent");
#endif
if(attribs & ATTR_NORMAL) if(attribs & ATTR_NORMAL)
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal"); qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
@ -1171,11 +1180,13 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
if(attribs & ATTR_NORMAL2) if(attribs & ATTR_NORMAL2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
#ifdef USE_VERT_TANGENT_SPACE
if(attribs & ATTR_TANGENT2) if(attribs & ATTR_TANGENT2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
if(attribs & ATTR_BITANGENT2) if(attribs & ATTR_BITANGENT2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT2, "attr_Bitangent2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT2, "attr_Bitangent2");
#endif
GLSL_LinkProgram(program->program); GLSL_LinkProgram(program->program);
@ -1788,7 +1799,10 @@ void GLSL_InitGPUShaders(void)
if (r_normalMapping->integer == 2) if (r_normalMapping->integer == 2)
Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n"); Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n");
#ifdef USE_VERT_TANGENT_SPACE
Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE");
attribs |= ATTR_TANGENT | ATTR_BITANGENT; attribs |= ATTR_TANGENT | ATTR_BITANGENT;
#endif
} }
if ((i & LIGHTDEF_USE_SPECULARMAP) && r_specularMapping->integer) if ((i & LIGHTDEF_USE_SPECULARMAP) && r_specularMapping->integer)
@ -1830,10 +1844,12 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n"); Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2; attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
#ifdef USE_VERT_TANGENT_SPACE
if (i & LIGHTDEF_USE_NORMALMAP && r_normalMapping->integer) if (i & LIGHTDEF_USE_NORMALMAP && r_normalMapping->integer)
{ {
attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2; attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2;
} }
#endif
} }
if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackLightallShader_vp, fallbackLightallShader_fp, GENERIC_UNIFORM_COUNT)) if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackLightallShader_vp, fallbackLightallShader_fp, GENERIC_UNIFORM_COUNT))
@ -2097,11 +2113,15 @@ void GLSL_ShutdownGPUShaders(void)
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION);
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL);
#ifdef USE_VERT_TANGENT_SPACE
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT); qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
#endif
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2);
#ifdef USE_VERT_TANGENT_SPACE
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2); qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
#endif
qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR);
qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION);
GLSL_BindNullProgram(); GLSL_BindNullProgram();
@ -2234,6 +2254,7 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
} }
} }
#ifdef USE_VERT_TANGENT_SPACE
if(diff & ATTR_TANGENT) if(diff & ATTR_TANGENT)
{ {
if(stateBits & ATTR_TANGENT) if(stateBits & ATTR_TANGENT)
@ -2261,6 +2282,7 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT); qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
} }
} }
#endif
if(diff & ATTR_COLOR) if(diff & ATTR_COLOR)
{ {
@ -2318,6 +2340,7 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
} }
} }
#ifdef USE_VERT_TANGENT_SPACE
if(diff & ATTR_TANGENT2) if(diff & ATTR_TANGENT2)
{ {
if(stateBits & ATTR_TANGENT2) if(stateBits & ATTR_TANGENT2)
@ -2345,6 +2368,7 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2); qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
} }
} }
#endif
glState.vertexAttribsState = stateBits; glState.vertexAttribsState = stateBits;
} }
@ -2392,6 +2416,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
glState.vertexAttribPointersSet |= ATTR_NORMAL; glState.vertexAttribPointersSet |= ATTR_NORMAL;
} }
#ifdef USE_VERT_TANGENT_SPACE
if((attribBits & ATTR_TANGENT) && !(glState.vertexAttribPointersSet & ATTR_TANGENT)) if((attribBits & ATTR_TANGENT) && !(glState.vertexAttribPointersSet & ATTR_TANGENT))
{ {
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n"); GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n");
@ -2407,6 +2432,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
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 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; glState.vertexAttribPointersSet |= ATTR_BITANGENT;
} }
#endif
if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR)) if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR))
{ {
@ -2440,6 +2466,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
glState.vertexAttribPointersSet |= ATTR_NORMAL2; glState.vertexAttribPointersSet |= ATTR_NORMAL2;
} }
#ifdef USE_VERT_TANGENT_SPACE
if((attribBits & ATTR_TANGENT2) && !(glState.vertexAttribPointersSet & ATTR_TANGENT2)) if((attribBits & ATTR_TANGENT2) && !(glState.vertexAttribPointersSet & ATTR_TANGENT2))
{ {
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n"); GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n");
@ -2455,6 +2482,8 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + glState.vertexAttribsOldFrame * glState.currentVBO->size_normal)); // FIXME qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + glState.vertexAttribsOldFrame * glState.currentVBO->size_normal)); // FIXME
glState.vertexAttribPointersSet |= ATTR_BITANGENT2; glState.vertexAttribPointersSet |= ATTR_BITANGENT2;
} }
#endif
} }
shaderProgram_t *GLSL_GetGenericShaderProgram(int stage) shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)

View File

@ -162,16 +162,20 @@ typedef struct VBO_s
uint32_t ofs_lightmap; uint32_t ofs_lightmap;
uint32_t ofs_vertexcolor; uint32_t ofs_vertexcolor;
uint32_t ofs_lightdir; uint32_t ofs_lightdir;
#ifdef USE_VERT_TANGENT_SPACE
uint32_t ofs_tangent; uint32_t ofs_tangent;
uint32_t ofs_bitangent; uint32_t ofs_bitangent;
#endif
uint32_t stride_xyz; uint32_t stride_xyz;
uint32_t stride_normal; uint32_t stride_normal;
uint32_t stride_st; uint32_t stride_st;
uint32_t stride_lightmap; uint32_t stride_lightmap;
uint32_t stride_vertexcolor; uint32_t stride_vertexcolor;
uint32_t stride_lightdir; uint32_t stride_lightdir;
#ifdef USE_VERT_TANGENT_SPACE
uint32_t stride_tangent; uint32_t stride_tangent;
uint32_t stride_bitangent; uint32_t stride_bitangent;
#endif
uint32_t size_xyz; uint32_t size_xyz;
uint32_t size_normal; uint32_t size_normal;
@ -1036,8 +1040,10 @@ typedef struct
vec2_t st; vec2_t st;
vec2_t lightmap; vec2_t lightmap;
vec3_t normal; vec3_t normal;
#ifdef USE_VERT_TANGENT_SPACE
vec3_t tangent; vec3_t tangent;
vec3_t bitangent; vec3_t bitangent;
#endif
vec3_t lightdir; vec3_t lightdir;
vec4_t vertexColors; vec4_t vertexColors;
@ -1046,7 +1052,11 @@ typedef struct
#endif #endif
} srfVert_t; } srfVert_t;
#ifdef USE_VERT_TANGENT_SPACE
#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, 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, 0, 0, 0}}
#else
#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}}
#endif
typedef struct typedef struct
{ {
@ -1415,8 +1425,10 @@ typedef struct
{ {
vec3_t xyz; vec3_t xyz;
vec3_t normal; vec3_t normal;
#ifdef USE_VERT_TANGENT_SPACE
vec3_t tangent; vec3_t tangent;
vec3_t bitangent; vec3_t bitangent;
#endif
} mdvVertex_t; } mdvVertex_t;
typedef struct typedef struct
@ -2234,8 +2246,10 @@ typedef struct shaderCommands_s
glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16); glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
vec4_t normal[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
#ifdef USE_VERT_TANGENT_SPACE
vec4_t tangent[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
vec4_t bitangent[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t bitangent[SHADER_MAX_VERTEXES] QALIGN(16);
#endif
vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16); vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
vec4_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16); vec4_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);

View File

@ -438,6 +438,7 @@ void R_CalcTBN2(vec3_t tangent, vec3_t bitangent, vec3_t normal,
} }
#ifdef USE_VERT_TANGENT_SPACE
qboolean R_CalcTangentVectors(srfVert_t * dv[3]) qboolean R_CalcTangentVectors(srfVert_t * dv[3])
{ {
int i; int i;
@ -488,6 +489,7 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3])
return qtrue; return qtrue;
} }
#endif
/* /*

View File

@ -609,6 +609,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
st->st[1] = LittleFloat(md3st->st[1]); st->st[1] = LittleFloat(md3st->st[1]);
} }
#ifdef USE_VERT_TANGENT_SPACE
// calc tangent spaces // calc tangent spaces
{ {
// Valgrind complaints: Conditional jump or move depends on uninitialised value(s) // Valgrind complaints: Conditional jump or move depends on uninitialised value(s)
@ -677,6 +678,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
VectorNormalize(v->normal); VectorNormalize(v->normal);
} }
} }
#endif
// find the next surface // find the next surface
md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd); md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd);
@ -695,14 +697,19 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
{ {
vec3_t *verts; vec3_t *verts;
vec3_t *normals; vec3_t *normals;
vec2_t *texcoords;
#ifdef USE_VERT_TANGENT_SPACE
vec3_t *tangents; vec3_t *tangents;
vec3_t *bitangents; vec3_t *bitangents;
vec2_t *texcoords; #endif
byte *data; byte *data;
int dataSize; int dataSize;
int ofs_xyz, ofs_normal, ofs_st, ofs_tangent, ofs_bitangent; int ofs_xyz, ofs_normal, ofs_st;
#ifdef USE_VERT_TANGENT_SPACE
int ofs_tangent, ofs_bitangent;
#endif
dataSize = 0; dataSize = 0;
@ -712,11 +719,13 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
ofs_normal = dataSize; ofs_normal = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals); dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals);
#ifdef USE_VERT_TANGENT_SPACE
ofs_tangent = dataSize; ofs_tangent = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents); dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents);
ofs_bitangent = dataSize; ofs_bitangent = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*bitangents); dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*bitangents);
#endif
ofs_st = dataSize; ofs_st = dataSize;
dataSize += surf->numVerts * sizeof(*texcoords); dataSize += surf->numVerts * sizeof(*texcoords);
@ -725,8 +734,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
verts = (void *)(data + ofs_xyz); verts = (void *)(data + ofs_xyz);
normals = (void *)(data + ofs_normal); normals = (void *)(data + ofs_normal);
#ifdef USE_VERT_TANGENT_SPACE
tangents = (void *)(data + ofs_tangent); tangents = (void *)(data + ofs_tangent);
bitangents = (void *)(data + ofs_bitangent); bitangents = (void *)(data + ofs_bitangent);
#endif
texcoords = (void *)(data + ofs_st); texcoords = (void *)(data + ofs_st);
v = surf->verts; v = surf->verts;
@ -734,8 +745,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
{ {
VectorCopy(v->xyz, verts[j]); VectorCopy(v->xyz, verts[j]);
VectorCopy(v->normal, normals[j]); VectorCopy(v->normal, normals[j]);
#ifdef USE_VERT_TANGENT_SPACE
VectorCopy(v->tangent, tangents[j]); VectorCopy(v->tangent, tangents[j]);
VectorCopy(v->bitangent, bitangents[j]); VectorCopy(v->bitangent, bitangents[j]);
#endif
} }
st = surf->st; st = surf->st;
@ -753,14 +766,18 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
vboSurf->vbo->ofs_xyz = ofs_xyz; vboSurf->vbo->ofs_xyz = ofs_xyz;
vboSurf->vbo->ofs_normal = ofs_normal; vboSurf->vbo->ofs_normal = ofs_normal;
#ifdef USE_VERT_TANGENT_SPACE
vboSurf->vbo->ofs_tangent = ofs_tangent; vboSurf->vbo->ofs_tangent = ofs_tangent;
vboSurf->vbo->ofs_bitangent = ofs_bitangent; vboSurf->vbo->ofs_bitangent = ofs_bitangent;
#endif
vboSurf->vbo->ofs_st = ofs_st; vboSurf->vbo->ofs_st = ofs_st;
vboSurf->vbo->stride_xyz = sizeof(*verts); vboSurf->vbo->stride_xyz = sizeof(*verts);
vboSurf->vbo->stride_normal = sizeof(*normals); vboSurf->vbo->stride_normal = sizeof(*normals);
#ifdef USE_VERT_TANGENT_SPACE
vboSurf->vbo->stride_tangent = sizeof(*tangents); vboSurf->vbo->stride_tangent = sizeof(*tangents);
vboSurf->vbo->stride_bitangent = sizeof(*bitangents); vboSurf->vbo->stride_bitangent = sizeof(*bitangents);
#endif
vboSurf->vbo->stride_st = sizeof(*st); vboSurf->vbo->stride_st = sizeof(*st);
vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts; vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts;

View File

@ -1002,8 +1002,10 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
if (vertexAttribs & ATTR_NORMAL) if (vertexAttribs & ATTR_NORMAL)
{ {
vertexAttribs |= ATTR_NORMAL2; vertexAttribs |= ATTR_NORMAL2;
#ifdef USE_VERT_TANGENT_SPACE
vertexAttribs |= ATTR_TANGENT2; vertexAttribs |= ATTR_TANGENT2;
vertexAttribs |= ATTR_BITANGENT2; vertexAttribs |= ATTR_BITANGENT2;
#endif
} }
} }

View File

@ -1881,10 +1881,12 @@ static void ComputeVertexAttribs(void)
{ {
shader.vertexAttribs |= ATTR_NORMAL; shader.vertexAttribs |= ATTR_NORMAL;
#ifdef USE_VERT_TANGENT_SPACE
if (pStage->glslShaderIndex & LIGHTDEF_USE_NORMALMAP) if (pStage->glslShaderIndex & LIGHTDEF_USE_NORMALMAP)
{ {
shader.vertexAttribs |= ATTR_BITANGENT | ATTR_TANGENT; shader.vertexAttribs |= ATTR_BITANGENT | ATTR_TANGENT;
} }
#endif
switch (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) switch (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)
{ {

View File

@ -361,7 +361,10 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
int i; int i;
srfTriangle_t *tri; srfTriangle_t *tri;
srfVert_t *dv; srfVert_t *dv;
float *xyz, *normal, *tangent, *bitangent, *texCoords, *lightCoords, *lightdir; float *xyz, *normal, *texCoords, *lightCoords, *lightdir;
#ifdef USE_VERT_TANGENT_SPACE
float *tangent, *bitangent;
#endif
glIndex_t *index; glIndex_t *index;
float *color; float *color;
@ -394,6 +397,7 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
VectorCopy(dv->normal, normal); VectorCopy(dv->normal, normal);
} }
#ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT ) if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{ {
dv = verts; dv = verts;
@ -409,6 +413,7 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
for ( i = 0 ; i < numVerts ; i++, dv++, bitangent+=4 ) for ( i = 0 ; i < numVerts ; i++, dv++, bitangent+=4 )
VectorCopy(dv->bitangent, bitangent); VectorCopy(dv->bitangent, bitangent);
} }
#endif
if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
{ {
@ -1329,7 +1334,10 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
int i, j; int i, j;
float *xyz; float *xyz;
float *texCoords, *lightCoords; float *texCoords, *lightCoords;
float *normal, *tangent, *bitangent; float *normal;
#ifdef USE_VERT_TANGENT_SPACE
float *tangent, *bitangent;
#endif
float *color, *lightdir; float *color, *lightdir;
srfVert_t *dv; srfVert_t *dv;
int rows, irows, vrows; int rows, irows, vrows;
@ -1413,8 +1421,10 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
xyz = tess.xyz[numVertexes]; xyz = tess.xyz[numVertexes];
normal = tess.normal[numVertexes]; normal = tess.normal[numVertexes];
#ifdef USE_VERT_TANGENT_SPACE
tangent = tess.tangent[numVertexes]; tangent = tess.tangent[numVertexes];
bitangent = tess.bitangent[numVertexes]; bitangent = tess.bitangent[numVertexes];
#endif
texCoords = tess.texCoords[numVertexes][0]; texCoords = tess.texCoords[numVertexes][0];
lightCoords = tess.texCoords[numVertexes][1]; lightCoords = tess.texCoords[numVertexes][1];
color = tess.vertexColors[numVertexes]; color = tess.vertexColors[numVertexes];
@ -1438,6 +1448,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
normal += 4; normal += 4;
} }
#ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT ) if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{ {
VectorCopy(dv->tangent, tangent); VectorCopy(dv->tangent, tangent);
@ -1449,7 +1460,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
VectorCopy(dv->bitangent, bitangent); VectorCopy(dv->bitangent, bitangent);
bitangent += 4; bitangent += 4;
} }
#endif
if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
{ {
VectorCopy2(dv->st, texCoords); VectorCopy2(dv->st, texCoords);

View File

@ -147,6 +147,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
dataSize += sizeof(verts[0].normal); dataSize += sizeof(verts[0].normal);
} }
#ifdef USE_VERT_TANGENT_SPACE
if(stateBits & ATTR_TANGENT) if(stateBits & ATTR_TANGENT)
{ {
vbo->ofs_tangent = dataSize; vbo->ofs_tangent = dataSize;
@ -158,6 +159,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_bitangent = dataSize; vbo->ofs_bitangent = dataSize;
dataSize += sizeof(verts[0].bitangent); dataSize += sizeof(verts[0].bitangent);
} }
#endif
if(stateBits & ATTR_TEXCOORD) if(stateBits & ATTR_TEXCOORD)
{ {
@ -185,8 +187,10 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->stride_xyz = dataSize; vbo->stride_xyz = dataSize;
vbo->stride_normal = dataSize; vbo->stride_normal = dataSize;
#ifdef USE_VERT_TANGENT_SPACE
vbo->stride_tangent = dataSize; vbo->stride_tangent = dataSize;
vbo->stride_bitangent = dataSize; vbo->stride_bitangent = dataSize;
#endif
vbo->stride_st = dataSize; vbo->stride_st = dataSize;
vbo->stride_lightmap = dataSize; vbo->stride_lightmap = dataSize;
vbo->stride_vertexcolor = dataSize; vbo->stride_vertexcolor = dataSize;
@ -213,6 +217,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
dataOfs += sizeof(verts[i].normal); dataOfs += sizeof(verts[i].normal);
} }
#ifdef USE_VERT_TANGENT_SPACE
// tangent // tangent
if(stateBits & ATTR_TANGENT) if(stateBits & ATTR_TANGENT)
{ {
@ -226,6 +231,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent)); memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent));
dataOfs += sizeof(verts[i].bitangent); dataOfs += sizeof(verts[i].bitangent);
} }
#endif
// vertex texcoords // vertex texcoords
if(stateBits & ATTR_TEXCOORD) if(stateBits & ATTR_TEXCOORD)
@ -266,6 +272,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
dataSize += sizeof(verts[0].normal); dataSize += sizeof(verts[0].normal);
} }
#ifdef USE_VERT_TANGENT_SPACE
if(stateBits & ATTR_TANGENT) if(stateBits & ATTR_TANGENT)
{ {
dataSize += sizeof(verts[0].tangent); dataSize += sizeof(verts[0].tangent);
@ -275,6 +282,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
{ {
dataSize += sizeof(verts[0].bitangent); dataSize += sizeof(verts[0].bitangent);
} }
#endif
if(stateBits & ATTR_TEXCOORD) if(stateBits & ATTR_TEXCOORD)
{ {
@ -303,8 +311,10 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->ofs_xyz = 0; vbo->ofs_xyz = 0;
vbo->ofs_normal = 0; vbo->ofs_normal = 0;
#ifdef USE_VERT_TANGENT_SPACE
vbo->ofs_tangent = 0; vbo->ofs_tangent = 0;
vbo->ofs_bitangent = 0; vbo->ofs_bitangent = 0;
#endif
vbo->ofs_st = 0; vbo->ofs_st = 0;
vbo->ofs_lightmap = 0; vbo->ofs_lightmap = 0;
vbo->ofs_vertexcolor = 0; vbo->ofs_vertexcolor = 0;
@ -312,8 +322,10 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
vbo->stride_xyz = sizeof(verts[0].xyz); vbo->stride_xyz = sizeof(verts[0].xyz);
vbo->stride_normal = sizeof(verts[0].normal); vbo->stride_normal = sizeof(verts[0].normal);
#ifdef USE_VERT_TANGENT_SPACE
vbo->stride_tangent = sizeof(verts[0].tangent); vbo->stride_tangent = sizeof(verts[0].tangent);
vbo->stride_bitangent = sizeof(verts[0].bitangent); vbo->stride_bitangent = sizeof(verts[0].bitangent);
#endif
vbo->stride_vertexcolor = sizeof(verts[0].vertexColors); vbo->stride_vertexcolor = sizeof(verts[0].vertexColors);
vbo->stride_st = sizeof(verts[0].st); vbo->stride_st = sizeof(verts[0].st);
vbo->stride_lightmap = sizeof(verts[0].lightmap); vbo->stride_lightmap = sizeof(verts[0].lightmap);
@ -340,6 +352,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
} }
} }
#ifdef USE_VERT_TANGENT_SPACE
// tangent // tangent
if(stateBits & ATTR_TANGENT) if(stateBits & ATTR_TANGENT)
{ {
@ -361,6 +374,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
dataOfs += sizeof(verts[i].bitangent); dataOfs += sizeof(verts[i].bitangent);
} }
} }
#endif
// vertex texcoords // vertex texcoords
if(stateBits & ATTR_TEXCOORD) if(stateBits & ATTR_TEXCOORD)
@ -678,6 +692,7 @@ R_InitVBOs
void R_InitVBOs(void) void R_InitVBOs(void)
{ {
int dataSize; int dataSize;
int offset;
ri.Printf(PRINT_ALL, "------- R_InitVBOs -------\n"); ri.Printf(PRINT_ALL, "------- R_InitVBOs -------\n");
@ -686,8 +701,10 @@ void R_InitVBOs(void)
dataSize = sizeof(tess.xyz[0]); dataSize = sizeof(tess.xyz[0]);
dataSize += sizeof(tess.normal[0]); dataSize += sizeof(tess.normal[0]);
#ifdef USE_VERT_TANGENT_SPACE
dataSize += sizeof(tess.tangent[0]); dataSize += sizeof(tess.tangent[0]);
dataSize += sizeof(tess.bitangent[0]); dataSize += sizeof(tess.bitangent[0]);
#endif
dataSize += sizeof(tess.vertexColors[0]); dataSize += sizeof(tess.vertexColors[0]);
dataSize += sizeof(tess.texCoords[0][0]) * 2; dataSize += sizeof(tess.texCoords[0][0]) * 2;
dataSize += sizeof(tess.lightdir[0]); dataSize += sizeof(tess.lightdir[0]);
@ -695,21 +712,28 @@ void R_InitVBOs(void)
tess.vbo = R_CreateVBO("tessVertexArray_VBO", NULL, dataSize, VBO_USAGE_DYNAMIC); tess.vbo = R_CreateVBO("tessVertexArray_VBO", NULL, dataSize, VBO_USAGE_DYNAMIC);
tess.vbo->ofs_xyz = 0; offset = 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_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->ofs_xyz = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES;
tess.vbo->ofs_lightdir = tess.vbo->ofs_vertexcolor + sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES; tess.vbo->ofs_normal = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
#ifdef USE_VERT_TANGENT_SPACE
tess.vbo->ofs_tangent = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES;
tess.vbo->ofs_bitangent = offset; offset += sizeof(tess.bitangent[0]) * SHADER_MAX_VERTEXES;
#endif
// these next two are actually interleaved
tess.vbo->ofs_st = offset;
tess.vbo->ofs_lightmap = offset + sizeof(tess.texCoords[0][0]);
offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES;
tess.vbo->ofs_vertexcolor = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES;
tess.vbo->ofs_lightdir = offset;
tess.vbo->stride_xyz = sizeof(tess.xyz[0]); tess.vbo->stride_xyz = sizeof(tess.xyz[0]);
tess.vbo->stride_normal = sizeof(tess.normal[0]); tess.vbo->stride_normal = sizeof(tess.normal[0]);
#ifdef USE_VERT_TANGENT_SPACE
tess.vbo->stride_tangent = sizeof(tess.tangent[0]); tess.vbo->stride_tangent = sizeof(tess.tangent[0]);
tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]); tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]);
#endif
tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]); tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]);
tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2;
tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2;
@ -857,6 +881,7 @@ void RB_UpdateVBOs(unsigned int attribBits)
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_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal);
} }
#ifdef USE_VERT_TANGENT_SPACE
if(attribBits & ATTR_TANGENT) if(attribBits & ATTR_TANGENT)
{ {
//ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0])); //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]));
@ -868,6 +893,7 @@ void RB_UpdateVBOs(unsigned int attribBits)
//ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0])); //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]));
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_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
} }
#endif
if(attribBits & ATTR_COLOR) if(attribBits & ATTR_COLOR)
{ {
@ -886,8 +912,10 @@ 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_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_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_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal);
#ifdef USE_VERT_TANGENT_SPACE
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_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_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
#endif
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors); qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors);
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir); qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir);
} }