From b0f0376a4fd5609f55f91dbf4838188515a7a58a Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Mon, 6 May 2013 18:01:44 -0700 Subject: [PATCH 01/21] Misc fixes to IBO code to correctly use sizeof(glIndex_t) --- code/renderergl2/tr_shade.c | 4 ++-- code/renderergl2/tr_sky.c | 2 +- code/renderergl2/tr_surface.c | 4 ++-- code/renderergl2/tr_vbo.c | 13 +++++-------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 633b3f43..adb164e5 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -44,9 +44,9 @@ R_DrawElements void R_DrawElementsVBO( int numIndexes, glIndex_t firstIndex, glIndex_t minIndex, glIndex_t maxIndex ) { if (glRefConfig.drawRangeElements) - qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); + qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t))); else - qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); + qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t))); } diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index f1e5249d..75970740 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -468,7 +468,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max R_DrawElementsVBO(tess.numIndexes - tess.firstIndex, tess.firstIndex, tess.minIndex, tess.maxIndex); - //qglDrawElements(GL_TRIANGLES, tess.numIndexes - tess.firstIndex, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex * sizeof(GL_INDEX_TYPE))); + //qglDrawElements(GL_TRIANGLES, tess.numIndexes - tess.firstIndex, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex * sizeof(glIndex_t))); //R_BindNullVBO(); //R_BindNullIBO(); diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 427d153d..ba1825f4 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -437,8 +437,8 @@ static qboolean RB_SurfaceVbo(VBO_t *vbo, IBO_t *ibo, int numVerts, int numIndex // merge this into any existing multidraw primitives mergeForward = -1; mergeBack = -1; - firstIndexOffset = BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE)); - lastIndexOffset = BUFFER_OFFSET((firstIndex + numIndexes) * sizeof(GL_INDEX_TYPE)); + firstIndexOffset = BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)); + lastIndexOffset = BUFFER_OFFSET((firstIndex + numIndexes) * sizeof(glIndex_t)); if (r_mergeMultidraws->integer) { diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index e9f2598b..09f6104a 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -506,12 +506,11 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * IBO_t *ibo; int i, j; - byte *indexes; + glIndex_t *indexes; int indexesSize; - int indexesOfs; + int indexesCount; srfTriangle_t *tri; - glIndex_t index; int glUsage; switch (usage) @@ -548,17 +547,15 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * Q_strncpyz(ibo->name, name, sizeof(ibo->name)); - indexesSize = numTriangles * 3 * sizeof(int); + indexesSize = numTriangles * 3 * sizeof(glIndex_t); indexes = ri.Hunk_AllocateTempMemory(indexesSize); - indexesOfs = 0; + indexesCount = 0; for(i = 0, tri = triangles; i < numTriangles; i++, tri++) { for(j = 0; j < 3; j++) { - index = tri->indexes[j]; - memcpy(indexes + indexesOfs, &index, sizeof(glIndex_t)); - indexesOfs += sizeof(glIndex_t); + indexes[indexesCount++] = tri->indexes[j]; } } From 3846c115e637b594d33f5becb71562a62ae83b81 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Sun, 3 Nov 2013 19:34:22 -0800 Subject: [PATCH 02/21] OpenGL2: Reduce glsl shader count by using a uniform to disable textures. --- code/renderergl2/glsl/lightall_fp.glsl | 13 ++- code/renderergl2/glsl/lightall_vp.glsl | 31 ++++--- code/renderergl2/tr_glsl.c | 121 ++++++++++++------------- code/renderergl2/tr_image.c | 3 - code/renderergl2/tr_local.h | 13 ++- code/renderergl2/tr_shade.c | 109 +++++++++++----------- code/renderergl2/tr_shader.c | 11 +-- 7 files changed, 147 insertions(+), 154 deletions(-) diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index f223bb0c..53fd1b43 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -24,6 +24,10 @@ uniform sampler2D u_ShadowMap; uniform samplerCube u_CubeMap; #endif +#if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP) +uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube +#endif + #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) uniform vec3 u_DirectedLight; uniform vec3 u_AmbientLight; @@ -52,7 +56,7 @@ varying vec4 var_Bitangent; varying vec3 var_LightColor; #endif -#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -304,6 +308,7 @@ void main() #if defined(USE_TANGENT_SPACE_LIGHT) L = L * tangentToWorld; #endif + L = L * u_EnableTextures.y + var_LightDir.xyz; #elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) L = var_LightDir.xyz; #endif @@ -352,6 +357,7 @@ void main() #else N.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - vec2(1.0); #endif + N.xy *= u_EnableTextures.x; N.z = sqrt(1.0 - clamp(dot(N.xy, N.xy), 0.0, 1.0)); #if !defined(USE_TANGENT_SPACE_LIGHT) N = normalize(tangentToWorld * N); @@ -412,6 +418,7 @@ void main() #if defined(USE_SPECULARMAP) vec4 specular = texture2D(u_SpecularMap, texCoords); + specular = mix(vec4(1.0), specular, u_EnableTextures.z); #if defined(USE_GAMMA2_TEXTURES) specular.rgb *= specular.rgb; #endif @@ -470,7 +477,7 @@ void main() R = tangentToWorld * R; #endif - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb; + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; #if defined(USE_LIGHTMAP) cubeLightColor *= lightSample.rgb; @@ -480,7 +487,7 @@ void main() cubeLightColor *= lightColor * NL + ambientColor; #endif - //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb; + //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb * u_EnableTextures.w; gl_FragColor.rgb += cubeLightColor * reflectance; #endif diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index ce83d10a..284b3973 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/renderergl2/glsl/lightall_vp.glsl @@ -20,15 +20,19 @@ attribute vec3 attr_Bitangent2; attribute vec3 attr_LightDirection; #endif -#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) +#if defined(USE_DELUXEMAP) +uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube +#endif + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) uniform vec3 u_ViewOrigin; -uniform vec3 u_LocalViewOrigin; #endif #if defined(USE_TCGEN) uniform int u_TCGen0; uniform vec3 u_TCGen0Vector0; uniform vec3 u_TCGen0Vector1; +uniform vec3 u_LocalViewOrigin; #endif #if defined(USE_TCMOD) @@ -51,8 +55,8 @@ uniform float u_VertexLerp; #if defined(USE_LIGHT_VECTOR) uniform vec4 u_LightOrigin; uniform float u_LightRadius; -uniform vec3 u_DirectedLight; #if defined(USE_FAST_LIGHT) +uniform vec3 u_DirectedLight; uniform vec3 u_AmbientLight; #endif #endif @@ -66,7 +70,7 @@ varying vec4 var_TexCoords; varying vec4 var_Color; -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_Normal; varying vec4 var_Tangent; varying vec4 var_Bitangent; @@ -76,7 +80,7 @@ varying vec4 var_Bitangent; varying vec3 var_LightColor; #endif -#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif @@ -150,7 +154,7 @@ float CalcLightAttenuation(vec3 dir, float sqrRadius) void main() { #if defined(USE_VERTEX_ANIMATION) - vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); + vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp)); vec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp)); vec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp)); @@ -184,7 +188,7 @@ void main() #if defined(USE_LIGHT_VECTOR) vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w); -#elif defined(USE_LIGHT) && !defined(USE_DELUXEMAP) +#elif defined(USE_LIGHT) vec3 L = attr_LightDirection; #if defined(USE_MODELMATRIX) L = (u_ModelMatrix * vec4(L, 0.0)).xyz; @@ -213,15 +217,18 @@ void main() var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius; #endif -#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_LIGHT_VECTOR) var_LightDir = vec4(L, u_LightRadius * u_LightRadius); #else var_LightDir = vec4(L, 0.0); #endif + #if defined(USE_DELUXEMAP) + var_LightDir *= 1.0 - u_EnableTextures.y; + #endif #endif -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) vec3 viewDir = u_ViewOrigin - position; #endif @@ -232,16 +239,16 @@ void main() var_PrimaryLightDir.xyz = var_PrimaryLightDir.xyz * tangentToWorld; #endif - #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) + #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) var_LightDir.xyz = var_LightDir.xyz * tangentToWorld; #endif - #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) viewDir = viewDir * tangentToWorld; #endif #endif -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) // store view direction in tangent space to save on varyings var_Normal = vec4(normal, viewDir.x); var_Tangent = vec4(tangent, viewDir.y); diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index 8203e68b..d67744f8 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -84,6 +84,8 @@ static uniformInfo_t uniformsInfo[] = { "u_ShadowMvp2", GLSL_MAT16 }, { "u_ShadowMvp3", GLSL_MAT16 }, + { "u_EnableTextures", GLSL_VEC4 }, + { "u_DiffuseTexMatrix", GLSL_VEC4 }, { "u_DiffuseTexOffTurb", GLSL_VEC4 }, { "u_Texture1Env", GLSL_INT }, @@ -997,27 +999,19 @@ void GLSL_InitGPUShaders(void) for (i = 0; i < LIGHTDEF_COUNT; i++) { + int lightType = i & LIGHTDEF_LIGHTTYPE_MASK; + qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer); + // skip impossible combos if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer) continue; - if ((i & LIGHTDEF_USE_DELUXEMAP) && !r_deluxeMapping->integer) + if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP)) continue; - if ((i & LIGHTDEF_USE_CUBEMAP) && !r_cubeMapping->integer) + if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP)) continue; - if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP) && (i & LIGHTDEF_USE_DELUXEMAP)) - continue; - - if (!(i & LIGHTDEF_LIGHTTYPE_MASK)) - { - if (i & LIGHTDEF_USE_SHADOWMAP) - continue; - if (i & LIGHTDEF_USE_CUBEMAP) - continue; - } - attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL; extradefines[0] = '\0'; @@ -1026,30 +1020,30 @@ void GLSL_InitGPUShaders(void) Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value)); if (r_specularIsMetallic->value) - Q_strcat(extradefines, 1024, va("#define SPECULAR_IS_METALLIC\n")); + Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); if (1) - { Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n"); - } if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer)) Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); - if (i & LIGHTDEF_LIGHTTYPE_MASK) + if (lightType) { Q_strcat(extradefines, 1024, "#define USE_LIGHT\n"); - if (r_normalMapping->integer == 0 && r_specularMapping->integer == 0) + if (fastLight) Q_strcat(extradefines, 1024, "#define USE_FAST_LIGHT\n"); - switch (i & LIGHTDEF_LIGHTTYPE_MASK) + switch (lightType) { case LIGHTDEF_USE_LIGHTMAP: Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n"); + if (r_deluxeMapping->integer && !fastLight) + Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n"); attribs |= ATTR_LIGHTCOORD | ATTR_LIGHTDIRECTION; break; case LIGHTDEF_USE_LIGHT_VECTOR: @@ -1062,62 +1056,59 @@ void GLSL_InitGPUShaders(void) default: break; } - } - if (r_normalMapping->integer) - { - Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n"); + if (r_normalMapping->integer) + { + Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n"); - if (r_normalMapping->integer == 2) - Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n"); + if (r_normalMapping->integer == 2) + Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n"); - if (r_normalMapping->integer == 3) - Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n"); + if (r_normalMapping->integer == 3) + Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n"); #ifdef USE_VERT_TANGENT_SPACE - Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n"); - attribs |= ATTR_TANGENT | ATTR_BITANGENT; + Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n"); + attribs |= ATTR_TANGENT | ATTR_BITANGENT; #endif - } - if (r_specularMapping->integer) - { - Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n"); - - switch (r_specularMapping->integer) - { - case 1: - default: - Q_strcat(extradefines, 1024, "#define USE_BLINN\n"); - break; - - case 2: - Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n"); - break; - - case 3: - Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n"); - break; - - case 4: - Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n"); - break; - - case 5: - Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n"); - break; + if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) + Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); } + + if (r_specularMapping->integer) + { + Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n"); + + switch (r_specularMapping->integer) + { + case 1: + default: + Q_strcat(extradefines, 1024, "#define USE_BLINN\n"); + break; + + case 2: + Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n"); + break; + + case 3: + Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n"); + break; + + case 4: + Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n"); + break; + + case 5: + Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n"); + break; + } + } + + if (r_cubeMapping->integer) + Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); } - if ((i & LIGHTDEF_USE_DELUXEMAP) && r_deluxeMapping->integer) - Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n"); - - if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) - Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); - - if ((i & LIGHTDEF_USE_CUBEMAP)) - Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); - if (i & LIGHTDEF_USE_SHADOWMAP) { Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index 09031dc0..777dcff5 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2875,9 +2875,6 @@ void R_CreateBuiltinImages( void ) { Com_Memset( data, 255, sizeof( data ) ); tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, 0); - Com_Memset( data, 128, sizeof( data ) ); - tr.greyImage = R_CreateImage("*grey", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, GL_RGBA8); - if (r_dlightMode->integer >= 2) { for( x = 0; x < MAX_DLIGHTS; x++) diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 0cc1f491..2f910e26 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -680,12 +680,10 @@ enum LIGHTDEF_LIGHTTYPE_MASK = 0x0003, LIGHTDEF_ENTITY = 0x0004, LIGHTDEF_USE_TCGEN_AND_TCMOD = 0x0008, - LIGHTDEF_USE_DELUXEMAP = 0x0010, - LIGHTDEF_USE_PARALLAXMAP = 0x0020, - LIGHTDEF_USE_SHADOWMAP = 0x0040, - LIGHTDEF_USE_CUBEMAP = 0x0080, - LIGHTDEF_ALL = 0x00FF, - LIGHTDEF_COUNT = 0x0100 + LIGHTDEF_USE_PARALLAXMAP = 0x0010, + LIGHTDEF_USE_SHADOWMAP = 0x0020, + LIGHTDEF_ALL = 0x003F, + LIGHTDEF_COUNT = 0x0040 }; enum @@ -722,6 +720,8 @@ typedef enum UNIFORM_SHADOWMVP2, UNIFORM_SHADOWMVP3, + UNIFORM_ENABLETEXTURES, + UNIFORM_DIFFUSETEXMATRIX, UNIFORM_DIFFUSETEXOFFTURB, UNIFORM_TEXTURE1ENV, @@ -1609,7 +1609,6 @@ typedef struct { image_t *fogImage; image_t *dlightImage; // inverse-quare highlight for projective adding image_t *flareImage; - image_t *greyImage; // full of 0x80 image_t *whiteImage; // full of 0xff image_t *identityLightImage; // full of tr.identityLightByte diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 74b8fe1f..7c07c95b 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -730,7 +730,7 @@ static void ForwardDlight( void ) { { int index = pStage->glslShaderIndex; - index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP); + index &= ~LIGHTDEF_LIGHTTYPE_MASK; index |= LIGHTDEF_USE_LIGHT_VECTOR; sp = &tr.lightallShader[index]; @@ -1098,11 +1098,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) index |= LIGHTDEF_USE_SHADOWMAP; } - if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && (index & LIGHTDEF_LIGHTTYPE_MASK) && input->cubemapIndex) - { - index |= LIGHTDEF_USE_CUBEMAP; - } - if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP) { index = LIGHTDEF_USE_LIGHTMAP; @@ -1228,6 +1223,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) else if ( pStage->glslShaderGroup == tr.lightallShader ) { int i; + vec4_t enableTextures; if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)) { @@ -1237,73 +1233,78 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir); } + VectorSet4(enableTextures, 0, 0, 0, 0); if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (pStage->bundle[i].image[0]) - { - switch(i) - { - case TB_LIGHTMAP: - R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i); - break; - - case TB_DIFFUSEMAP: - case TB_SPECULARMAP: - case TB_SHADOWMAP: - case TB_CUBEMAP: - default: - GL_BindToTMU( tr.whiteImage, i); - break; - - case TB_NORMALMAP: - case TB_DELUXEMAP: - GL_BindToTMU( tr.greyImage, i); - break; - } - } + if (i == TB_LIGHTMAP) + R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i); + else + GL_BindToTMU( tr.whiteImage, i ); } } else if (r_lightmap->integer == 3 && pStage->bundle[TB_DELUXEMAP].image[0]) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (pStage->bundle[i].image[0]) - { - switch(i) - { - case TB_LIGHTMAP: - R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); - break; - - case TB_DIFFUSEMAP: - case TB_SPECULARMAP: - case TB_SHADOWMAP: - case TB_CUBEMAP: - default: - GL_BindToTMU( tr.whiteImage, i); - break; - - case TB_NORMALMAP: - case TB_DELUXEMAP: - GL_BindToTMU( tr.greyImage, i); - break; - } - } + if (i == TB_LIGHTMAP) + R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); + else + GL_BindToTMU( tr.whiteImage, i ); } - } else { - for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + qboolean light = (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) != 0; + qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer); + + if (pStage->bundle[TB_DIFFUSEMAP].image[0]) + R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); + + if (pStage->bundle[TB_LIGHTMAP].image[0]) + R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], TB_LIGHTMAP); + + // bind textures that are sampled and used in the glsl shader, and + // bind whiteImage to textures that are sampled but zeroed in the glsl shader + // + // alternatives: + // - use the last bound texture + // -> costs more to sample a higher res texture then throw out the result + // - disable texture sampling in glsl shader with #ifdefs, as before + // -> increases the number of shaders that must be compiled + // + if (light && !fastLight) { - if (pStage->bundle[i].image[0]) + if (pStage->bundle[TB_NORMALMAP].image[0]) { - R_BindAnimatedImageToTMU( &pStage->bundle[i], i); + R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP); + enableTextures[0] = 1.0f; } + else if (r_normalMapping->integer) + GL_BindToTMU( tr.whiteImage, TB_NORMALMAP ); + + if (pStage->bundle[TB_DELUXEMAP].image[0]) + { + R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], TB_DELUXEMAP); + enableTextures[1] = 1.0f; + } + else if (r_deluxeMapping->integer) + GL_BindToTMU( tr.whiteImage, TB_DELUXEMAP ); + + if (pStage->bundle[TB_SPECULARMAP].image[0]) + { + R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); + enableTextures[2] = 1.0f; + } + else if (r_specularMapping->integer) + GL_BindToTMU( tr.whiteImage, TB_SPECULARMAP ); } + + enableTextures[3] = (r_cubeMapping->integer && !(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex) ? 1.0f : 0.0f; } + + GLSL_SetUniformVec4(sp, UNIFORM_ENABLETEXTURES, enableTextures); } else if ( pStage->bundle[1].image[0] != 0 ) { diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index 7ff74feb..65f0c5dc 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -2208,7 +2208,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, //ri.Printf(PRINT_ALL, ", deluxemap"); diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0]; diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex]; - defs |= LIGHTDEF_USE_DELUXEMAP; } if (r_normalMapping->integer) @@ -2525,8 +2524,6 @@ static qboolean CollapseStagesToGLSL(void) { pStage->glslShaderGroup = tr.lightallShader; pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP; - if (r_deluxeMapping->integer && tr.worldDeluxeMapping) - pStage->glslShaderIndex |= LIGHTDEF_USE_DELUXEMAP; pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP]; pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage; pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse; @@ -2559,7 +2556,7 @@ static qboolean CollapseStagesToGLSL(void) } } - // insert default normal and specular textures if necessary + // insert default material info if needed for (i = 0; i < MAX_SHADER_STAGES; i++) { shaderStage_t *pStage = &stages[i]; @@ -2573,14 +2570,8 @@ static qboolean CollapseStagesToGLSL(void) if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) == 0) continue; - if (!pStage->bundle[TB_NORMALMAP].image[0] && r_normalMapping->integer) - { - pStage->bundle[TB_NORMALMAP].image[0] = tr.greyImage; - } - if (!pStage->bundle[TB_SPECULARMAP].image[0] && r_specularMapping->integer) { - pStage->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage; if (!pStage->materialInfo[0]) pStage->materialInfo[0] = r_baseSpecular->value; if (!pStage->materialInfo[1]) From 0e25d0357b3e2f6d425a3aa92098509d3c3c396e Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 4 Nov 2013 21:53:05 -0800 Subject: [PATCH 03/21] OpenGL2: Revisit fragment tangent space calculation, and remove tangent space lighting. --- code/renderergl2/glsl/lightall_fp.glsl | 67 +++++++++++++++----------- code/renderergl2/glsl/lightall_vp.glsl | 36 ++++++++------ 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index 53fd1b43..51e4634f 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -46,10 +46,15 @@ varying vec4 var_TexCoords; varying vec4 var_Color; -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) -varying vec4 var_Normal; -varying vec4 var_Tangent; -varying vec4 var_Bitangent; +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) + #if defined(USE_VERT_TANGENT_SPACE) +varying vec4 var_Normal; +varying vec4 var_Tangent; +varying vec4 var_Bitangent; + #else +varying vec3 var_Normal; +varying vec3 var_ViewDir; + #endif #endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) @@ -293,6 +298,25 @@ float CalcLightAttenuation(vec3 dir, float sqrRadius) return attenuation; } +// from http://www.thetenthplanet.de/archives/1180 +mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv ) +{ + // get edge vectors of the pixel triangle + vec3 dp1 = dFdx( p ); + vec3 dp2 = dFdy( p ); + vec2 duv1 = dFdx( uv ); + vec2 duv2 = dFdy( uv ); + + // solve the linear system + vec3 dp2perp = cross( dp2, N ); + vec3 dp1perp = cross( N, dp1 ); + vec3 T = dp2perp * duv1.x + dp1perp * duv2.x; + vec3 B = dp2perp * duv1.y + dp1perp * duv2.y; + + // construct a scale-invariant frame + float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) ); + return mat3( T * invmax, B * invmax, N ); +} void main() { @@ -300,21 +324,26 @@ void main() float NL, NH, NE, EH; #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + #if defined(USE_VERT_TANGENT_SPACE) mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz); + #else + mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy); + #endif #endif #if defined(USE_DELUXEMAP) L = (2.0 * texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(1.0)); - #if defined(USE_TANGENT_SPACE_LIGHT) - L = L * tangentToWorld; - #endif L = L * u_EnableTextures.y + var_LightDir.xyz; #elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) L = var_LightDir.xyz; #endif #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + #if defined(USE_VERT_TANGENT_SPACE) E = normalize(vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w)); + #else + E = normalize(var_ViewDir); + #endif #endif #if defined(USE_LIGHTMAP) @@ -333,11 +362,7 @@ void main() vec2 texCoords = var_TexCoords.xy; #if defined(USE_PARALLAXMAP) - #if defined(USE_TANGENT_SPACE_LIGHT) - vec3 offsetDir = E; - #else - vec3 offsetDir = E * tangentToWorld; - #endif + vec3 offsetDir = normalize(E * tangentToWorld); offsetDir.xy *= -0.05 / offsetDir.z; @@ -359,11 +384,7 @@ void main() #endif N.xy *= u_EnableTextures.x; N.z = sqrt(1.0 - clamp(dot(N.xy, N.xy), 0.0, 1.0)); - #if !defined(USE_TANGENT_SPACE_LIGHT) N = normalize(tangentToWorld * N); - #endif - #elif defined(USE_TANGENT_SPACE_LIGHT) - N = vec3(0.0, 0.0, 1.0); #else N = normalize(var_Normal.xyz); #endif @@ -375,11 +396,7 @@ void main() float shadowValue = texture2D(u_ShadowMap, shadowTex).r; // surfaces not facing the light are always shadowed - #if defined(USE_TANGENT_SPACE_LIGHT) - shadowValue *= step(0.0, var_PrimaryLightDir.z); - #else shadowValue *= step(0.0, dot(var_Normal.xyz, var_PrimaryLightDir.xyz)); - #endif #if defined(SHADOWMAP_MODULATE) //vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor); @@ -395,12 +412,7 @@ void main() #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) vec3 ambientColor = lightColor; - - #if defined(USE_TANGENT_SPACE_LIGHT) - float surfNL = L.z; - #else float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); - #endif // Scale the incoming light to compensate for the baked-in light angle // attenuation. @@ -418,7 +430,7 @@ void main() #if defined(USE_SPECULARMAP) vec4 specular = texture2D(u_SpecularMap, texCoords); - specular = mix(vec4(1.0), specular, u_EnableTextures.z); + specular = (specular - vec4(1.0)) * u_EnableTextures.z + vec4(1.0); #if defined(USE_GAMMA2_TEXTURES) specular.rgb *= specular.rgb; #endif @@ -473,9 +485,6 @@ void main() reflectance = EnvironmentBRDF(gloss, NE, specular.rgb); vec3 R = reflect(E, N); - #if defined(USE_TANGENT_SPACE_LIGHT) - R = tangentToWorld * R; - #endif vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index 284b3973..aa0fe25b 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/renderergl2/glsl/lightall_vp.glsl @@ -6,14 +6,18 @@ attribute vec4 attr_Color; attribute vec3 attr_Position; attribute vec3 attr_Normal; +#if defined(USE_VERT_TANGENT_SPACE) attribute vec3 attr_Tangent; attribute vec3 attr_Bitangent; +#endif #if defined(USE_VERTEX_ANIMATION) attribute vec3 attr_Position2; attribute vec3 attr_Normal2; + #if defined(USE_VERT_TANGENT_SPACE) attribute vec3 attr_Tangent2; attribute vec3 attr_Bitangent2; + #endif #endif #if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR) @@ -71,9 +75,14 @@ varying vec4 var_TexCoords; varying vec4 var_Color; #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + #if defined(USE_VERT_TANGENT_SPACE) varying vec4 var_Normal; varying vec4 var_Tangent; varying vec4 var_Bitangent; + #else +varying vec3 var_Normal; +varying vec3 var_ViewDir; + #endif #endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) @@ -156,13 +165,17 @@ void main() #if defined(USE_VERTEX_ANIMATION) vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp)); + #if defined(USE_VERT_TANGENT_SPACE) vec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp)); vec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp)); + #endif #else vec3 position = attr_Position; vec3 normal = attr_Normal; + #if defined(USE_VERT_TANGENT_SPACE) vec3 tangent = attr_Tangent; vec3 bitangent = attr_Bitangent; + #endif #endif #if defined(USE_TCGEN) @@ -182,8 +195,10 @@ void main() #if defined(USE_MODELMATRIX) position = (u_ModelMatrix * vec4(position, 1.0)).xyz; normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz; + #if defined(USE_VERT_TANGENT_SPACE) tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; bitangent = (u_ModelMatrix * vec4(bitangent, 0.0)).xyz; + #endif #endif #if defined(USE_LIGHT_VECTOR) @@ -232,26 +247,15 @@ void main() vec3 viewDir = u_ViewOrigin - position; #endif -#if defined(USE_TANGENT_SPACE_LIGHT) - mat3 tangentToWorld = mat3(tangent, bitangent, normal); - - #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) - var_PrimaryLightDir.xyz = var_PrimaryLightDir.xyz * tangentToWorld; - #endif - - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - var_LightDir.xyz = var_LightDir.xyz * tangentToWorld; - #endif - - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - viewDir = viewDir * tangentToWorld; - #endif -#endif - #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + #if defined(USE_VERT_TANGENT_SPACE) // store view direction in tangent space to save on varyings var_Normal = vec4(normal, viewDir.x); var_Tangent = vec4(tangent, viewDir.y); var_Bitangent = vec4(bitangent, viewDir.z); + #else + var_Normal = normal; + var_ViewDir = viewDir; + #endif #endif } From a7c5fc0ee7b5bb97e9dea4db56f9b91e5dbe6afb Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 4 Nov 2013 22:50:53 -0800 Subject: [PATCH 04/21] OpenGL2: Some small shader optimizations. --- code/renderergl2/glsl/lightall_fp.glsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index 51e4634f..b937483e 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -332,8 +332,8 @@ void main() #endif #if defined(USE_DELUXEMAP) - L = (2.0 * texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(1.0)); - L = L * u_EnableTextures.y + var_LightDir.xyz; + L = texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5); + L = L * u_EnableTextures.y + var_LightDir.xyz; #elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) L = var_LightDir.xyz; #endif @@ -378,12 +378,12 @@ void main() #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) - N.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - vec2(1.0); + N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); #else - N.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - vec2(1.0); + N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5); #endif N.xy *= u_EnableTextures.x; - N.z = sqrt(1.0 - clamp(dot(N.xy, N.xy), 0.0, 1.0)); + N.z = sqrt(0.25 - dot(N.xy, N.xy)); N = normalize(tangentToWorld * N); #else N = normalize(var_Normal.xyz); From 8c3ae8d7d283c90c3a3d9037f36a874e7575a9d4 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 5 Nov 2013 00:08:59 -0800 Subject: [PATCH 05/21] OpenGL2: Reimplement soft overbright to avoid a framebuffer blit. --- code/renderergl2/tr_backend.c | 57 +++++++++++-------------------- code/renderergl2/tr_cmds.c | 6 ---- code/renderergl2/tr_fbo.c | 16 --------- code/renderergl2/tr_image.c | 3 -- code/renderergl2/tr_local.h | 2 -- code/renderergl2/tr_postprocess.c | 40 ++++++++++++++++------ code/renderergl2/tr_shade.c | 23 +++++++++++-- code/renderergl2/tr_sky.c | 2 +- 8 files changed, 70 insertions(+), 79 deletions(-) diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 08dc167e..10d05353 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -449,7 +449,7 @@ void RB_BeginDrawingView (void) { { if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL))) { - FBO_Bind(tr.screenScratchFbo); + FBO_Bind(NULL); } else { @@ -859,7 +859,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * { if (!tr.renderFbo || backEnd.framePostProcessed) { - FBO_Bind(tr.screenScratchFbo); + FBO_Bind(NULL); } else { @@ -946,7 +946,7 @@ const void *RB_StretchPic ( const void *data ) { { if (!tr.renderFbo || backEnd.framePostProcessed) { - FBO_Bind(tr.screenScratchFbo); + FBO_Bind(NULL); } else { @@ -1443,7 +1443,7 @@ const void *RB_ClearDepth(const void *data) { if (!tr.renderFbo || backEnd.framePostProcessed) { - FBO_Bind(tr.screenScratchFbo); + FBO_Bind(NULL); } else { @@ -1512,32 +1512,13 @@ const void *RB_SwapBuffers( const void *data ) { { // Resolving an RGB16F MSAA FBO to the screen messes with the brightness, so resolve to an RGB16F FBO first FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); - FBO_FastBlit(tr.msaaResolveFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(tr.msaaResolveFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else if (tr.renderFbo) { - FBO_FastBlit(tr.renderFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(tr.renderFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } } - - if (tr.screenScratchFbo) - { - vec4_t color; - - color[0] = - color[1] = - color[2] = pow(2, tr.overbrightBits); //exp2(tr.overbrightBits); - color[3] = 1.0f; - - // turn off colormask when copying final image - if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3]) - qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - FBO_Blit(tr.screenScratchFbo, NULL, NULL, NULL, NULL, NULL, color, 0); - - if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3]) - qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]); - } } if ( !glState.finishCalled ) { @@ -1654,11 +1635,11 @@ const void *RB_PostProcess(const void *data) if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; - RB_ToneMap(srcFbo, srcBox, tr.screenScratchFbo, dstBox, autoExposure); + RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); } else if (r_cameraExposure->value == 0.0f) { - FBO_FastBlit(srcFbo, srcBox, tr.screenScratchFbo, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(srcFbo, srcBox, NULL, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { @@ -1669,15 +1650,15 @@ const void *RB_PostProcess(const void *data) color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[3] = 1.0f; - FBO_Blit(srcFbo, srcBox, NULL, tr.screenScratchFbo, dstBox, NULL, color, 0); + FBO_Blit(srcFbo, srcBox, NULL, NULL, dstBox, NULL, color, 0); } } if (r_drawSunRays->integer) - RB_SunRays(tr.screenScratchFbo, srcBox, tr.screenScratchFbo, dstBox); + RB_SunRays(NULL, srcBox, NULL, dstBox); if (1) - RB_BokehBlur(tr.screenScratchFbo, srcBox, tr.screenScratchFbo, dstBox, backEnd.refdef.blurFactor); + RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor); else RB_GaussianBlur(backEnd.refdef.blurFactor); @@ -1685,27 +1666,27 @@ const void *RB_PostProcess(const void *data) { vec4i_t dstBox; VectorSet4(dstBox, 0, 0, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 128, 0, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); } if (0) { vec4i_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); } if (0) { vec4i_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); } #if 0 @@ -1717,8 +1698,8 @@ const void *RB_PostProcess(const void *data) if (cubemapIndex) { VectorSet4(dstBox, 0, glConfig.vidHeight - 256, 256, 256); - //FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0); - FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1], NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0); + //FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0); + FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1], NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0); } } #endif diff --git a/code/renderergl2/tr_cmds.c b/code/renderergl2/tr_cmds.c index 1426b581..139a3430 100644 --- a/code/renderergl2/tr_cmds.c +++ b/code/renderergl2/tr_cmds.c @@ -442,12 +442,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) { qglClear(GL_COLOR_BUFFER_BIT); } - if (tr.screenScratchFbo) - { - FBO_Bind(tr.screenScratchFbo); - qglClear(GL_COLOR_BUFFER_BIT); - } - FBO_Bind(NULL); } diff --git a/code/renderergl2/tr_fbo.c b/code/renderergl2/tr_fbo.c index a1d1339b..d9fd917f 100644 --- a/code/renderergl2/tr_fbo.c +++ b/code/renderergl2/tr_fbo.c @@ -526,22 +526,6 @@ void FBO_Init(void) R_CheckFBO(tr.targetLevelsFbo); } - if (r_softOverbright->integer) - { - //tr.screenScratchFbo = FBO_Create("_screenscratch", width, height); - tr.screenScratchFbo = FBO_Create("_screenscratch", tr.screenScratchImage->width, tr.screenScratchImage->height); - FBO_Bind(tr.screenScratchFbo); - - //FBO_CreateBuffer(tr.screenScratchFbo, format, 0, 0); - FBO_AttachTextureImage(tr.screenScratchImage, 0); - - // FIXME: hack: share zbuffer between render fbo and pre-screen fbo - //FBO_CreateBuffer(tr.screenScratchFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - - R_CheckFBO(tr.screenScratchFbo); - } - for (i = 0; i < 2; i++) { tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index 777dcff5..56b4b882 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2931,9 +2931,6 @@ void R_CreateBuiltinImages( void ) { if (r_drawSunRays->integer) tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); - if (r_softOverbright->integer) - tr.screenScratchImage = R_CreateImage("*screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); - if (glRefConfig.framebufferObject) { tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 2f910e26..b534d46b 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1620,7 +1620,6 @@ typedef struct { image_t *renderDepthImage; image_t *pshadowMaps[MAX_DRAWN_PSHADOWS]; image_t *textureScratchImage[2]; - image_t *screenScratchImage; image_t *quarterImage[2]; image_t *calcLevelsImage; image_t *targetLevelsImage; @@ -1639,7 +1638,6 @@ typedef struct { FBO_t *depthFbo; FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS]; FBO_t *textureScratchFbo[2]; - FBO_t *screenScratchFbo; FBO_t *quarterFbo[2]; FBO_t *calcLevelsFbo; FBO_t *targetLevelsFbo; diff --git a/code/renderergl2/tr_postprocess.c b/code/renderergl2/tr_postprocess.c index cab9d42b..dba19d4a 100644 --- a/code/renderergl2/tr_postprocess.c +++ b/code/renderergl2/tr_postprocess.c @@ -255,10 +255,20 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc float s1 = iscale + s0; float t1 = iscale + t0; - srcBox[0] = s0 * srcFbo->width; - srcBox[1] = t0 * srcFbo->height; - srcBox[2] = (s1 - s0) * srcFbo->width; - srcBox[3] = (t1 - t0) * srcFbo->height; + if (srcFbo) + { + srcBox[0] = s0 * srcFbo->width; + srcBox[1] = t0 * srcFbo->height; + srcBox[2] = (s1 - s0) * srcFbo->width; + srcBox[3] = (t1 - t0) * srcFbo->height; + } + else + { + srcBox[0] = s0 * glConfig.vidWidth; + srcBox[1] = t0 * glConfig.vidHeight; + srcBox[2] = (s1 - s0) * glConfig.vidWidth; + srcBox[3] = (t1 - t0) * glConfig.vidHeight; + } FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); @@ -351,10 +361,20 @@ void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox) VectorSet4(color, mul, mul, mul, 1); - rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width; - rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height; - rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width; - rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height; + if (srcFbo) + { + rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width; + rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height; + rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width; + rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height; + } + else + { + rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / glConfig.vidWidth; + rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / glConfig.vidHeight; + rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / glConfig.vidWidth; + rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / glConfig.vidHeight; + } quarterBox[0] = 0; quarterBox[1] = tr.quarterFbo[0]->height; @@ -480,7 +500,7 @@ void RB_GaussianBlur(float blur) VectorSet4(color, 1, 1, 1, 1); // first, downsample the framebuffer - FBO_FastBlit(tr.screenScratchFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); + FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); // set the alpha channel @@ -498,6 +518,6 @@ void RB_GaussianBlur(float blur) VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); color[3] = factor; - FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } } diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 7c07c95b..03916819 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -443,7 +443,7 @@ static void ProjectDlightTexture( void ) { } -static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor ) +static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor, int blend ) { baseColor[0] = baseColor[1] = @@ -601,6 +601,23 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t break; } + // multiply color by overbrightbits if this isn't a blend + if (r_softOverbright->integer && tr.overbrightBits + && !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_DST_COLOR) + && !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR) + && !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) + && !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR)) + { + float scale = 1 << tr.overbrightBits; + + baseColor[0] *= scale; + baseColor[1] *= scale; + baseColor[2] *= scale; + vertColor[0] *= scale; + vertColor[1] *= scale; + vertColor[2] *= scale; + } + // FIXME: find some way to implement this. #if 0 // if in greyscale rendering mode turn all color values into greyscale. @@ -769,7 +786,7 @@ static void ForwardDlight( void ) { vec4_t baseColor; vec4_t vertColor; - ComputeShaderColors(pStage, baseColor, vertColor); + ComputeShaderColors(pStage, baseColor, vertColor, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); @@ -1141,7 +1158,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) vec4_t baseColor; vec4_t vertColor; - ComputeShaderColors(pStage, baseColor, vertColor); + ComputeShaderColors(pStage, baseColor, vertColor, pStage->stateBits); if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL)) { diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index 7fd4b3aa..162b9e5e 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -449,7 +449,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max color[0] = color[1] = - color[2] = tr.identityLight * backEnd.refdef.colorScale; + color[2] = (r_softOverbright->integer ? 1.0 : tr.identityLight) * backEnd.refdef.colorScale; color[3] = 1.0f; GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color); From 7672533e8f97fa0d49b3a180f13379908e7ea87e Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 5 Nov 2013 20:07:10 -0800 Subject: [PATCH 06/21] OpenGL2: Prefer VBO/IBO sizes of around 4MB. --- code/renderergl2/tr_bsp.c | 91 +++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 275fdf83..d5588cce 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -1851,6 +1851,9 @@ static void R_CreateWorldVBOs(void) VBO_t *vbo; IBO_t *ibo; + int maxVboSize = 4 * 1024 * 1024; + int maxIboSize = 4 * 1024 * 1024; + int startTime, endTime; startTime = ri.Milliseconds(); @@ -1859,10 +1862,21 @@ static void R_CreateWorldVBOs(void) numSortedSurfaces = 0; for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { - if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES) - { - numSortedSurfaces++; - } + shader_t *shader = surface->shader; + + if (shader->isPortal) + continue; + + if (shader->isSky) + continue; + + if (ShaderRequiresCPUDeforms(shader)) + continue; + + if (!(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)) + continue; + + numSortedSurfaces++; } // presort surfaces @@ -1871,19 +1885,66 @@ static void R_CreateWorldVBOs(void) j = 0; for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { - if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES) - { - surfacesSorted[j++] = surface; - } + shader_t *shader = surface->shader; + + if (shader->isPortal) + continue; + + if (shader->isSky) + continue; + + if (ShaderRequiresCPUDeforms(shader)) + continue; + + if (!(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)) + continue; + + surfacesSorted[j++] = surface; } qsort(surfacesSorted, numSortedSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare); k = 0; - for(firstSurf = lastSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = lastSurf) + for(firstSurf = lastSurf = currSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = currSurf = lastSurf) { - while(lastSurf < &surfacesSorted[numSortedSurfaces] && (*lastSurf)->shader->sortedIndex == (*firstSurf)->shader->sortedIndex) - lastSurf++; + int currVboSize, currIboSize; + + currVboSize = currIboSize = 0; + while (currVboSize < maxVboSize && currIboSize < maxIboSize && lastSurf < &surfacesSorted[numSortedSurfaces]) + { + int addVboSize, addIboSize, currShaderIndex; + + addVboSize = addIboSize = 0; + currShaderIndex = (*currSurf)->shader->sortedIndex; + while(currSurf < &surfacesSorted[numSortedSurfaces] && (*currSurf)->shader->sortedIndex == currShaderIndex) + { + srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; + + switch (bspSurf->surfaceType) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + addVboSize += bspSurf->numVerts * sizeof(srfVert_t); + addIboSize += bspSurf->numTriangles * 3 *sizeof(glIndex_t); + break; + + default: + break; + } + + currSurf++; + } + + if ((currVboSize != 0 && addVboSize + currVboSize > maxVboSize) + || (currIboSize != 0 && addIboSize + currIboSize > maxIboSize)) + break; + + lastSurf = currSurf; + + currVboSize += addVboSize; + currIboSize += addIboSize; + } numVerts = 0; numTriangles = 0; @@ -1897,12 +1958,8 @@ static void R_CreateWorldVBOs(void) case SF_FACE: case SF_GRID: case SF_TRIANGLES: - if(bspSurf->numVerts) - numVerts += bspSurf->numVerts; - - if(bspSurf->numTriangles) - numTriangles += bspSurf->numTriangles; - + numVerts += bspSurf->numVerts; + numTriangles += bspSurf->numTriangles; numSurfaces++; break; From fd4cd6612d2c3be0ff604d64cc96d72eba2c4427 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Wed, 6 Nov 2013 22:23:33 -0600 Subject: [PATCH 07/21] Fix running if built on OS X 10.9 strncpy with in == out causes signal 6 if built on OS X 10.9. (If built on older OS X versions, the game works on 10.9 though.) It was happening in COM_StripExtension during map load. --- code/qcommon/q_shared.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/qcommon/q_shared.c b/code/qcommon/q_shared.c index 357451c5..690838cc 100644 --- a/code/qcommon/q_shared.c +++ b/code/qcommon/q_shared.c @@ -76,8 +76,12 @@ COM_StripExtension void COM_StripExtension( const char *in, char *out, int destsize ) { const char *dot = strrchr(in, '.'), *slash; + if (dot && (!(slash = strrchr(in, '/')) || slash < dot)) - Q_strncpyz(out, in, (destsize < dot-in+1 ? destsize : dot-in+1)); + destsize = (destsize < dot-in+1 ? destsize : dot-in+1); + + if ( in == out && destsize > 1 ) + out[destsize-1] = '\0'; else Q_strncpyz(out, in, destsize); } From d295db747c0f4d10a2eaa75ac40c480f918cc197 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 7 Nov 2013 04:03:52 -0800 Subject: [PATCH 08/21] OpenGL2: Small optimizations and comments in world VBO creation and surface merging. --- code/renderergl2/tr_bsp.c | 214 +++++++++++--------------------------- 1 file changed, 60 insertions(+), 154 deletions(-) diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index d5588cce..9914ee1d 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -1862,6 +1862,7 @@ static void R_CreateWorldVBOs(void) numSortedSurfaces = 0; for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { + srfBspSurface_t *bspSurf; shader_t *shader = surface->shader; if (shader->isPortal) @@ -1873,9 +1874,15 @@ static void R_CreateWorldVBOs(void) if (ShaderRequiresCPUDeforms(shader)) continue; + // check for this now so we can use srfBspSurface_t* universally in the rest of the function if (!(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)) continue; + bspSurf = (srfBspSurface_t *) surface->data; + + if (!bspSurf->numTriangles || !bspSurf->numVerts) + continue; + numSortedSurfaces++; } @@ -1885,6 +1892,7 @@ static void R_CreateWorldVBOs(void) j = 0; for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { + srfBspSurface_t *bspSurf; shader_t *shader = surface->shader; if (shader->isPortal) @@ -1896,44 +1904,42 @@ static void R_CreateWorldVBOs(void) if (ShaderRequiresCPUDeforms(shader)) continue; + // check for this now so we can use srfBspSurface_t* universally in the rest of the function if (!(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)) continue; + bspSurf = (srfBspSurface_t *) surface->data; + + if (!bspSurf->numTriangles || !bspSurf->numVerts) + continue; + surfacesSorted[j++] = surface; } qsort(surfacesSorted, numSortedSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare); k = 0; - for(firstSurf = lastSurf = currSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = currSurf = lastSurf) + for(firstSurf = lastSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = lastSurf) { int currVboSize, currIboSize; + // Find range of surfaces to merge by: + // - Collecting a number of surfaces which fit under maxVboSize/maxIboSize, or + // - All the surfaces with a single shader which go over maxVboSize/maxIboSize currVboSize = currIboSize = 0; while (currVboSize < maxVboSize && currIboSize < maxIboSize && lastSurf < &surfacesSorted[numSortedSurfaces]) { int addVboSize, addIboSize, currShaderIndex; addVboSize = addIboSize = 0; - currShaderIndex = (*currSurf)->shader->sortedIndex; - while(currSurf < &surfacesSorted[numSortedSurfaces] && (*currSurf)->shader->sortedIndex == currShaderIndex) + currShaderIndex = (*lastSurf)->shader->sortedIndex; + + for(currSurf = lastSurf; currSurf < &surfacesSorted[numSortedSurfaces] && (*currSurf)->shader->sortedIndex == currShaderIndex; currSurf++) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - switch (bspSurf->surfaceType) - { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - addVboSize += bspSurf->numVerts * sizeof(srfVert_t); - addIboSize += bspSurf->numTriangles * 3 *sizeof(glIndex_t); - break; - - default: - break; - } - - currSurf++; + addVboSize += bspSurf->numVerts * sizeof(srfVert_t); + addIboSize += bspSurf->numTriangles * 3 * sizeof(glIndex_t); } if ((currVboSize != 0 && addVboSize + currVboSize > maxVboSize) @@ -1946,6 +1952,7 @@ static void R_CreateWorldVBOs(void) currIboSize += addIboSize; } + // count verts/triangles/surfaces numVerts = 0; numTriangles = 0; numSurfaces = 0; @@ -1953,102 +1960,48 @@ static void R_CreateWorldVBOs(void) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - switch (bspSurf->surfaceType) - { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - numVerts += bspSurf->numVerts; - numTriangles += bspSurf->numTriangles; - numSurfaces++; - break; - - default: - break; - } + numVerts += bspSurf->numVerts; + numTriangles += bspSurf->numTriangles; + numSurfaces++; } - if(!numVerts || !numTriangles) - continue; - ri.Printf(PRINT_ALL, "...calculating world VBO %d ( %i verts %i tris )\n", k, numVerts, numTriangles); // create arrays verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t)); triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t)); - // set up triangle indices + // set up triangle indices and copy vertices numVerts = 0; numTriangles = 0; for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; + srfTriangle_t *tri; - switch (bspSurf->surfaceType) + bspSurf->firstIndex = numTriangles * 3; + bspSurf->minIndex = numVerts + bspSurf->triangles->indexes[0]; + bspSurf->maxIndex = numVerts + bspSurf->triangles->indexes[0]; + + for(i = 0, tri = bspSurf->triangles; i < bspSurf->numTriangles; i++, tri++) { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - bspSurf->firstIndex = numTriangles * 3; - - if(bspSurf->numTriangles) - { - srfTriangle_t *tri; - - bspSurf->minIndex = numVerts + bspSurf->triangles->indexes[0]; - bspSurf->maxIndex = numVerts + bspSurf->triangles->indexes[0]; - - for(i = 0, tri = bspSurf->triangles; i < bspSurf->numTriangles; i++, tri++) - { - for(j = 0; j < 3; j++) - { - triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; - bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + tri->indexes[j]); - bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + tri->indexes[j]); - } - } - - numTriangles += bspSurf->numTriangles; - } - - if(bspSurf->numVerts) - numVerts += bspSurf->numVerts; - - break; - - default: - break; + for(j = 0; j < 3; j++) + { + triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; + bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + tri->indexes[j]); + bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + tri->indexes[j]); + } } - } - // build vertices - numVerts = 0; - for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) - { - srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; + bspSurf->firstVert = numVerts; - switch (bspSurf->surfaceType) + for(i = 0; i < bspSurf->numVerts; i++) { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - bspSurf->firstVert = numVerts; - - if(bspSurf->numVerts) - { - for(i = 0; i < bspSurf->numVerts; i++) - { - CopyVert(&bspSurf->verts[i], &verts[numVerts + i]); - } - - numVerts += bspSurf->numVerts; - } - - break; - - default: - break; + CopyVert(&bspSurf->verts[i], &verts[numVerts + i]); } + + numTriangles += bspSurf->numTriangles; + numVerts += bspSurf->numVerts; } #ifdef USE_VERT_TANGENT_SPACE @@ -2068,29 +2021,14 @@ static void R_CreateWorldVBOs(void) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - switch (bspSurf->surfaceType) - { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - if( bspSurf->numVerts && bspSurf->numTriangles) - { - bspSurf->vbo = vbo; - bspSurf->ibo = ibo; - } - - break; - - default: - break; - } + bspSurf->vbo = vbo; + bspSurf->ibo = ibo; } ri.Hunk_FreeTempMemory(triangles); ri.Hunk_FreeTempMemory(verts); k++; - } ri.Free(surfacesSorted); @@ -3159,24 +3097,13 @@ void R_MergeLeafSurfaces(void) surf1 = s_worldData.surfaces + i; // retrieve vbo - switch(*surf1->data) - { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - vbo = ((srfBspSurface_t *)(surf1->data))->vbo; - break; - - default: - vbo = NULL; - break; - } + vbo = ((srfBspSurface_t *)(surf1->data))->vbo; // count verts, indexes, and surfaces numSurfsToMerge = 0; numTriangles = 0; numVerts = 0; - for (j = 0; j < numWorldSurfaces; j++) + for (j = i; j < numWorldSurfaces; j++) { msurface_t *surf2; srfBspSurface_t *bspSurf; @@ -3187,19 +3114,8 @@ void R_MergeLeafSurfaces(void) surf2 = s_worldData.surfaces + j; bspSurf = (srfBspSurface_t *) surf2->data; - switch(bspSurf->surfaceType) - { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - numTriangles += bspSurf->numTriangles; - numVerts += bspSurf->numVerts; - break; - - default: - break; - } - + numTriangles += bspSurf->numTriangles; + numVerts += bspSurf->numVerts; numSurfsToMerge++; } @@ -3220,7 +3136,7 @@ void R_MergeLeafSurfaces(void) // Merge surfaces (indexes) and calculate bounds ClearBounds(bounds[0], bounds[1]); firstIndex = numIboIndexes; - for (j = 0; j < numWorldSurfaces; j++) + for (j = i; j < numWorldSurfaces; j++) { msurface_t *surf2; srfBspSurface_t *bspSurf; @@ -3234,24 +3150,14 @@ void R_MergeLeafSurfaces(void) AddPointToBounds(surf2->cullinfo.bounds[1], bounds[0], bounds[1]); bspSurf = (srfBspSurface_t *) surf2->data; - switch(bspSurf->surfaceType) + for (k = 0; k < bspSurf->numTriangles; k++) { - case SF_FACE: - case SF_GRID: - case SF_TRIANGLES: - for (k = 0; k < bspSurf->numTriangles; k++) - { - *outIboIndexes++ = bspSurf->triangles[k].indexes[0] + bspSurf->firstVert; - *outIboIndexes++ = bspSurf->triangles[k].indexes[1] + bspSurf->firstVert; - *outIboIndexes++ = bspSurf->triangles[k].indexes[2] + bspSurf->firstVert; - numIboIndexes += 3; - } - break; - - // never happens, but silences a compile warning - default: - break; + *outIboIndexes++ = bspSurf->triangles[k].indexes[0] + bspSurf->firstVert; + *outIboIndexes++ = bspSurf->triangles[k].indexes[1] + bspSurf->firstVert; + *outIboIndexes++ = bspSurf->triangles[k].indexes[2] + bspSurf->firstVert; + numIboIndexes += 3; } + break; } vboSurf = ri.Hunk_Alloc(sizeof(*vboSurf), h_low); @@ -3268,7 +3174,7 @@ void R_MergeLeafSurfaces(void) vboSurf->minIndex = *(iboIndexes + firstIndex); vboSurf->maxIndex = *(iboIndexes + firstIndex); - for (j = 1; j < numTriangles * 3; j++) + for (j = 0; j < numTriangles * 3; j++) { vboSurf->minIndex = MIN(vboSurf->minIndex, *(iboIndexes + firstIndex + j)); vboSurf->maxIndex = MAX(vboSurf->maxIndex, *(iboIndexes + firstIndex + j)); From ef9fe17dd5a7b15f0b3c2b31fa45d783d9856bc0 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 8 Nov 2013 01:46:17 -0800 Subject: [PATCH 09/21] OpenGL2: Remove srfTriangle_t, and use glIndex_t instead. --- code/renderergl2/tr_bsp.c | 148 ++++++++++++++++------------------ code/renderergl2/tr_curve.c | 124 ++++++++++------------------ code/renderergl2/tr_local.h | 18 ++--- code/renderergl2/tr_main.c | 6 +- code/renderergl2/tr_marks.c | 12 +-- code/renderergl2/tr_model.c | 38 ++++----- code/renderergl2/tr_surface.c | 50 +++++------- code/renderergl2/tr_vbo.c | 12 +-- 8 files changed, 173 insertions(+), 235 deletions(-) diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 9914ee1d..419ba055 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -653,8 +653,8 @@ ParseFace static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) { int i, j; srfBspSurface_t *cv; - srfTriangle_t *tri; - int numVerts, numTriangles, badTriangles; + glIndex_t *tri; + int numVerts, numIndexes, badTriangles; int realLightmapNum; realLightmapNum = LittleLong( ds->lightmapNum ); @@ -675,14 +675,14 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, surf->shader = tr.defaultShader; } - numTriangles = LittleLong(ds->numIndexes) / 3; + numIndexes = LittleLong(ds->numIndexes); //cv = ri.Hunk_Alloc(sizeof(*cv), h_low); cv = (void *)surf->data; cv->surfaceType = SF_FACE; - cv->numTriangles = numTriangles; - cv->triangles = ri.Hunk_Alloc(numTriangles * sizeof(cv->triangles[0]), h_low); + cv->numIndexes = numIndexes; + cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]), h_low); cv->numVerts = numVerts; cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low); @@ -740,29 +740,29 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, // copy triangles badTriangles = 0; indexes += LittleLong(ds->firstIndex); - for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = cv->indexes; i < numIndexes; i += 3, tri += 3) { for(j = 0; j < 3; j++) { - tri->indexes[j] = LittleLong(indexes[i * 3 + j]); + tri[j] = LittleLong(indexes[i + j]); - if(tri->indexes[j] < 0 || tri->indexes[j] >= numVerts) + if(tri[j] < 0 || tri[j] >= numVerts) { ri.Error(ERR_DROP, "Bad index in face surface"); } } - if ((tri->indexes[0] == tri->indexes[1]) || (tri->indexes[1] == tri->indexes[2]) || (tri->indexes[0] == tri->indexes[2])) + if ((tri[0] == tri[1]) || (tri[1] == tri[2]) || (tri[0] == tri[2])) { - tri--; + tri -= 3; badTriangles++; } } if (badTriangles) { - ri.Printf(PRINT_WARNING, "Face has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles); - cv->numTriangles -= badTriangles; + ri.Printf(PRINT_WARNING, "Face has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numIndexes / 3, numVerts, numIndexes / 3 - badTriangles); + cv->numIndexes -= badTriangles * 3; } // take the plane information from the lightmap vector @@ -781,11 +781,11 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, { srfVert_t *dv[3]; - for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = cv->indexes; i < numIndexes; i += 3, tri += 3) { - dv[0] = &cv->verts[tri->indexes[0]]; - dv[1] = &cv->verts[tri->indexes[1]]; - dv[2] = &cv->verts[tri->indexes[2]]; + dv[0] = &cv->verts[tri[0]]; + dv[1] = &cv->verts[tri[1]]; + dv[2] = &cv->verts[tri[2]]; R_CalcTangentVectors(dv); } @@ -904,9 +904,9 @@ ParseTriSurf */ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) { srfBspSurface_t *cv; - srfTriangle_t *tri; + glIndex_t *tri; int i, j; - int numVerts, numTriangles, badTriangles; + int numVerts, numIndexes, badTriangles; // get fog volume surf->fogIndex = LittleLong( ds->fogNum ) + 1; @@ -918,14 +918,14 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor } numVerts = LittleLong(ds->numVerts); - numTriangles = LittleLong(ds->numIndexes) / 3; + numIndexes = LittleLong(ds->numIndexes); //cv = ri.Hunk_Alloc(sizeof(*cv), h_low); cv = (void *)surf->data; cv->surfaceType = SF_TRIANGLES; - cv->numTriangles = numTriangles; - cv->triangles = ri.Hunk_Alloc(numTriangles * sizeof(cv->triangles[0]), h_low); + cv->numIndexes = numIndexes; + cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]), h_low); cv->numVerts = numVerts; cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low); @@ -984,29 +984,29 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor // copy triangles badTriangles = 0; indexes += LittleLong(ds->firstIndex); - for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = cv->indexes; i < numIndexes; i += 3, tri += 3) { for(j = 0; j < 3; j++) { - tri->indexes[j] = LittleLong(indexes[i * 3 + j]); + tri[j] = LittleLong(indexes[i + j]); - if(tri->indexes[j] < 0 || tri->indexes[j] >= numVerts) + if(tri[j] < 0 || tri[j] >= numVerts) { ri.Error(ERR_DROP, "Bad index in face surface"); } } - if ((tri->indexes[0] == tri->indexes[1]) || (tri->indexes[1] == tri->indexes[2]) || (tri->indexes[0] == tri->indexes[2])) + if ((tri[0] == tri[1]) || (tri[1] == tri[2]) || (tri[0] == tri[2])) { - tri--; + tri -= 3; badTriangles++; } } if (badTriangles) { - ri.Printf(PRINT_WARNING, "Trisurf has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles); - cv->numTriangles -= badTriangles; + ri.Printf(PRINT_WARNING, "Trisurf has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numIndexes / 3, numVerts, numIndexes / 3 - badTriangles); + cv->numIndexes -= badTriangles * 3; } #ifdef USE_VERT_TANGENT_SPACE @@ -1014,11 +1014,11 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor { srfVert_t *dv[3]; - for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = cv->indexes; i < numIndexes; i += 3, tri += 3) { - dv[0] = &cv->verts[tri->indexes[0]]; - dv[1] = &cv->verts[tri->indexes[1]]; - dv[2] = &cv->verts[tri->indexes[2]]; + dv[0] = &cv->verts[tri[0]]; + dv[1] = &cv->verts[tri[1]]; + dv[2] = &cv->verts[tri[2]]; R_CalcTangentVectors(dv); } @@ -1747,9 +1747,9 @@ void R_MovePatchSurfacesToHunk(void) { hunkgrid->heightLodError = ri.Hunk_Alloc( grid->height * 4, h_low ); Com_Memcpy( hunkgrid->heightLodError, grid->heightLodError, grid->height * 4 ); - hunkgrid->numTriangles = grid->numTriangles; - hunkgrid->triangles = ri.Hunk_Alloc(grid->numTriangles * sizeof(srfTriangle_t), h_low); - Com_Memcpy(hunkgrid->triangles, grid->triangles, grid->numTriangles * sizeof(srfTriangle_t)); + hunkgrid->numIndexes = grid->numIndexes; + hunkgrid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low); + Com_Memcpy(hunkgrid->indexes, grid->indexes, grid->numIndexes * sizeof(glIndex_t)); hunkgrid->numVerts = grid->numVerts; hunkgrid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low); @@ -1841,8 +1841,8 @@ static void R_CreateWorldVBOs(void) int numVerts; srfVert_t *verts; - int numTriangles; - srfTriangle_t *triangles; + int numIndexes; + glIndex_t *indexes; int numSortedSurfaces, numSurfaces; msurface_t *surface, **firstSurf, **lastSurf, **currSurf; @@ -1880,7 +1880,7 @@ static void R_CreateWorldVBOs(void) bspSurf = (srfBspSurface_t *) surface->data; - if (!bspSurf->numTriangles || !bspSurf->numVerts) + if (!bspSurf->numIndexes || !bspSurf->numVerts) continue; numSortedSurfaces++; @@ -1910,7 +1910,7 @@ static void R_CreateWorldVBOs(void) bspSurf = (srfBspSurface_t *) surface->data; - if (!bspSurf->numTriangles || !bspSurf->numVerts) + if (!bspSurf->numIndexes || !bspSurf->numVerts) continue; surfacesSorted[j++] = surface; @@ -1939,7 +1939,7 @@ static void R_CreateWorldVBOs(void) srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; addVboSize += bspSurf->numVerts * sizeof(srfVert_t); - addIboSize += bspSurf->numTriangles * 3 * sizeof(glIndex_t); + addIboSize += bspSurf->numIndexes * sizeof(glIndex_t); } if ((currVboSize != 0 && addVboSize + currVboSize > maxVboSize) @@ -1952,56 +1952,50 @@ static void R_CreateWorldVBOs(void) currIboSize += addIboSize; } - // count verts/triangles/surfaces + // count verts/indexes/surfaces numVerts = 0; - numTriangles = 0; + numIndexes = 0; numSurfaces = 0; for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; numVerts += bspSurf->numVerts; - numTriangles += bspSurf->numTriangles; + numIndexes += bspSurf->numIndexes; numSurfaces++; } - ri.Printf(PRINT_ALL, "...calculating world VBO %d ( %i verts %i tris )\n", k, numVerts, numTriangles); + ri.Printf(PRINT_ALL, "...calculating world VBO %d ( %i verts %i tris )\n", k, numVerts, numIndexes / 3); // create arrays verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t)); - triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t)); + indexes = ri.Hunk_AllocateTempMemory(numIndexes * sizeof(glIndex_t)); - // set up triangle indices and copy vertices + // set up indices and copy vertices numVerts = 0; - numTriangles = 0; + numIndexes = 0; for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - srfTriangle_t *tri; + glIndex_t *surfIndex; - bspSurf->firstIndex = numTriangles * 3; - bspSurf->minIndex = numVerts + bspSurf->triangles->indexes[0]; - bspSurf->maxIndex = numVerts + bspSurf->triangles->indexes[0]; + bspSurf->firstIndex = numIndexes; + bspSurf->minIndex = numVerts + bspSurf->indexes[0]; + bspSurf->maxIndex = numVerts + bspSurf->indexes[0]; - for(i = 0, tri = bspSurf->triangles; i < bspSurf->numTriangles; i++, tri++) + for(i = 0, surfIndex = bspSurf->indexes; i < bspSurf->numIndexes; i++, surfIndex++) { - for(j = 0; j < 3; j++) - { - triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; - bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + tri->indexes[j]); - bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + tri->indexes[j]); - } + indexes[numIndexes++] = numVerts + *surfIndex; + bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + *surfIndex); + bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + *surfIndex); } bspSurf->firstVert = numVerts; for(i = 0; i < bspSurf->numVerts; i++) { - CopyVert(&bspSurf->verts[i], &verts[numVerts + i]); + CopyVert(&bspSurf->verts[i], &verts[numVerts++]); } - - numTriangles += bspSurf->numTriangles; - numVerts += bspSurf->numVerts; } #ifdef USE_VERT_TANGENT_SPACE @@ -2014,9 +2008,9 @@ static void R_CreateWorldVBOs(void) ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); #endif - ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", k), numTriangles, triangles, VBO_USAGE_STATIC); + ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", k), numIndexes, indexes, VBO_USAGE_STATIC); - // point triangle surfaces to VBO + // point bsp surfaces to VBO for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; @@ -2025,7 +2019,7 @@ static void R_CreateWorldVBOs(void) bspSurf->ibo = ibo; } - ri.Hunk_FreeTempMemory(triangles); + ri.Hunk_FreeTempMemory(indexes); ri.Hunk_FreeTempMemory(verts); k++; @@ -2099,7 +2093,7 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) { // Two passes, allocate surfaces first, then load them full of data // This ensures surfaces are close together to reduce L2 cache misses when using VBOs, - // which don't actually use the verts and tris + // which don't actually use the verts and indexes in = (void *)(fileBase + surfs->fileofs); out = s_worldData.surfaces; for ( i = 0 ; i < count ; i++, in++, out++ ) { @@ -3085,7 +3079,7 @@ void R_MergeLeafSurfaces(void) vec3_t bounds[2]; int numSurfsToMerge; - int numTriangles; + int numIndexes; int numVerts; int firstIndex; @@ -3101,7 +3095,7 @@ void R_MergeLeafSurfaces(void) // count verts, indexes, and surfaces numSurfsToMerge = 0; - numTriangles = 0; + numIndexes = 0; numVerts = 0; for (j = i; j < numWorldSurfaces; j++) { @@ -3114,12 +3108,12 @@ void R_MergeLeafSurfaces(void) surf2 = s_worldData.surfaces + j; bspSurf = (srfBspSurface_t *) surf2->data; - numTriangles += bspSurf->numTriangles; + numIndexes += bspSurf->numIndexes; numVerts += bspSurf->numVerts; numSurfsToMerge++; } - if (numVerts == 0 || numTriangles == 0 || numSurfsToMerge < 2) + if (numVerts == 0 || numIndexes == 0 || numSurfsToMerge < 2) { continue; } @@ -3131,7 +3125,7 @@ void R_MergeLeafSurfaces(void) numIboIndexes = 0; // allocate indexes - iboIndexes = outIboIndexes = ri.Malloc(numTriangles * 3 * sizeof(*outIboIndexes)); + iboIndexes = outIboIndexes = ri.Malloc(numIndexes * sizeof(*outIboIndexes)); // Merge surfaces (indexes) and calculate bounds ClearBounds(bounds[0], bounds[1]); @@ -3150,12 +3144,10 @@ void R_MergeLeafSurfaces(void) AddPointToBounds(surf2->cullinfo.bounds[1], bounds[0], bounds[1]); bspSurf = (srfBspSurface_t *) surf2->data; - for (k = 0; k < bspSurf->numTriangles; k++) + for (k = 0; k < bspSurf->numIndexes; k++) { - *outIboIndexes++ = bspSurf->triangles[k].indexes[0] + bspSurf->firstVert; - *outIboIndexes++ = bspSurf->triangles[k].indexes[1] + bspSurf->firstVert; - *outIboIndexes++ = bspSurf->triangles[k].indexes[2] + bspSurf->firstVert; - numIboIndexes += 3; + *outIboIndexes++ = bspSurf->indexes[k] + bspSurf->firstVert; + numIboIndexes++; } break; } @@ -3167,14 +3159,14 @@ void R_MergeLeafSurfaces(void) vboSurf->vbo = vbo; vboSurf->ibo = ibo; - vboSurf->numTriangles = numTriangles; + vboSurf->numIndexes = numIndexes; vboSurf->numVerts = numVerts; vboSurf->firstIndex = firstIndex; vboSurf->minIndex = *(iboIndexes + firstIndex); vboSurf->maxIndex = *(iboIndexes + firstIndex); - for (j = 0; j < numTriangles * 3; j++) + for (j = 0; j < numIndexes; j++) { vboSurf->minIndex = MIN(vboSurf->minIndex, *(iboIndexes + firstIndex + j)); vboSurf->maxIndex = MAX(vboSurf->maxIndex, *(iboIndexes + firstIndex + j)); diff --git a/code/renderergl2/tr_curve.c b/code/renderergl2/tr_curve.c index e9414159..4f36243b 100644 --- a/code/renderergl2/tr_curve.c +++ b/code/renderergl2/tr_curve.c @@ -213,13 +213,13 @@ 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, - srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) +static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numIndexes, + glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) { int i, j; srfVert_t *dv[3]; static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE]; - srfTriangle_t *tri; + glIndex_t *tri; // FIXME: use more elegant way for(i = 0; i < width; i++) @@ -231,53 +231,15 @@ static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRI } } - for(i = 0, tri = triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = indexes; i < numIndexes; i += 3, tri += 3) { - dv[0] = &ctrl2[tri->indexes[0]]; - dv[1] = &ctrl2[tri->indexes[1]]; - dv[2] = &ctrl2[tri->indexes[2]]; + dv[0] = &ctrl2[tri[0]]; + dv[1] = &ctrl2[tri[1]]; + dv[2] = &ctrl2[tri[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++) @@ -293,18 +255,18 @@ 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], - srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) +static int MakeMeshIndexes(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], + glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) { int i, j; - int numTriangles; + int numIndexes; int w, h; srfVert_t *dv; static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE]; h = height - 1; w = width - 1; - numTriangles = 0; + numIndexes = 0; for(i = 0; i < h; i++) { for(j = 0; j < w; j++) @@ -317,15 +279,13 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE v3 = v2 + width; v4 = v3 + 1; - triangles[numTriangles].indexes[0] = v2; - triangles[numTriangles].indexes[1] = v3; - triangles[numTriangles].indexes[2] = v1; - numTriangles++; + indexes[numIndexes++] = v2; + indexes[numIndexes++] = v3; + indexes[numIndexes++] = v1; - triangles[numTriangles].indexes[0] = v1; - triangles[numTriangles].indexes[1] = v3; - triangles[numTriangles].indexes[2] = v4; - numTriangles++; + indexes[numIndexes++] = v1; + indexes[numIndexes++] = v3; + indexes[numIndexes++] = v4; } } @@ -339,7 +299,7 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE } } - return numTriangles; + return numIndexes; } @@ -418,7 +378,7 @@ R_CreateSurfaceGridMesh */ srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE], - int numTriangles, srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) { + int numIndexes, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) { int i, j, size; srfVert_t *vert; vec3_t tmpVec; @@ -437,9 +397,9 @@ srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height, grid->heightLodError = /*ri.Hunk_Alloc*/ ri.Malloc( height * 4 ); Com_Memcpy( grid->heightLodError, errorTable[1], height * 4 ); - grid->numTriangles = numTriangles; - grid->triangles = ri.Malloc(grid->numTriangles * sizeof(srfTriangle_t)); - Com_Memcpy(grid->triangles, triangles, numTriangles * sizeof(srfTriangle_t)); + grid->numIndexes = numIndexes; + grid->indexes = ri.Malloc(grid->numIndexes * sizeof(glIndex_t)); + Com_Memcpy(grid->indexes, indexes, numIndexes * sizeof(glIndex_t)); grid->numVerts = (width * height); grid->verts = ri.Malloc(grid->numVerts * sizeof(srfVert_t)); @@ -453,9 +413,9 @@ srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height, grid->heightLodError = ri.Hunk_Alloc( height * 4 ); Com_Memcpy( grid->heightLodError, errorTable[1], height * 4 ); - grid->numTriangles = numTriangles; - grid->triangles = ri.Hunk_Alloc(grid->numTriangles * sizeof(srfTriangle_t), h_low); - Com_Memcpy(grid->triangles, triangles, numTriangles * sizeof(srfTriangle_t)); + grid->numIndexes = numIndexes; + grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low); + Com_Memcpy(grid->indexes, indexes, numIndexes * sizeof(glIndex_t)); grid->numVerts = (width * height); grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low); @@ -493,7 +453,7 @@ R_FreeSurfaceGridMesh void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) { ri.Free(grid->widthLodError); ri.Free(grid->heightLodError); - ri.Free(grid->triangles); + ri.Free(grid->indexes); ri.Free(grid->verts); ri.Free(grid); } @@ -514,8 +474,8 @@ srfBspSurface_t *R_SubdividePatchToGrid( int width, int height, int t; srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; float errorTable[2][MAX_GRID_SIZE]; - int numTriangles; - static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]; + int numIndexes; + static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]; int consecutiveComplete; for ( i = 0 ; i < width ; i++ ) { @@ -669,16 +629,16 @@ srfBspSurface_t *R_SubdividePatchToGrid( int width, int height, } #endif - // calculate triangles - numTriangles = MakeMeshTriangles(width, height, ctrl, triangles); + // calculate indexes + numIndexes = MakeMeshIndexes(width, height, ctrl, indexes); // calculate normals MakeMeshNormals( width, height, ctrl ); #ifdef USE_VERT_TANGENT_SPACE - MakeMeshTangentVectors(width, height, ctrl, numTriangles, triangles); + MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes); #endif - return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles); + return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes); } /* @@ -693,8 +653,8 @@ srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, float errorTable[2][MAX_GRID_SIZE]; float lodRadius; vec3_t lodOrigin; - int numTriangles; - static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]; + int numIndexes; + static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]; oldwidth = 0; width = grid->width + 1; @@ -724,8 +684,8 @@ srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, // put all the aproximating points on the curve //PutPointsOnCurve( ctrl, width, height ); - // calculate triangles - numTriangles = MakeMeshTriangles(width, height, ctrl, triangles); + // calculate indexes + numIndexes = MakeMeshIndexes(width, height, ctrl, indexes); // calculate normals MakeMeshNormals( width, height, ctrl ); @@ -735,7 +695,7 @@ srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, // free the old grid R_FreeSurfaceGridMesh(grid); // create a new grid - grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles); + grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes); grid->lodRadius = lodRadius; VectorCopy(lodOrigin, grid->lodOrigin); return grid; @@ -753,8 +713,8 @@ srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, ve float errorTable[2][MAX_GRID_SIZE]; float lodRadius; vec3_t lodOrigin; - int numTriangles; - static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]; + int numIndexes; + static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]; oldheight = 0; width = grid->width; @@ -784,8 +744,8 @@ srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, ve // put all the aproximating points on the curve //PutPointsOnCurve( ctrl, width, height ); - // calculate triangles - numTriangles = MakeMeshTriangles(width, height, ctrl, triangles); + // calculate indexes + numIndexes = MakeMeshIndexes(width, height, ctrl, indexes); // calculate normals MakeMeshNormals( width, height, ctrl ); @@ -795,7 +755,7 @@ srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, ve // free the old grid R_FreeSurfaceGridMesh(grid); // create a new grid - grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles); + grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes); grid->lodRadius = lodRadius; VectorCopy(lodOrigin, grid->lodOrigin); return grid; diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index b534d46b..368dd39e 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1003,12 +1003,6 @@ typedef struct #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 -{ - int indexes[3]; - int neighbors[3]; -} srfTriangle_t; - // srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VBO_MESH typedef struct srfBspSurface_s { @@ -1024,9 +1018,9 @@ typedef struct srfBspSurface_s float cullRadius; cplane_t cullPlane; - // triangle definitions - int numTriangles; - srfTriangle_t *triangles; + // indexes + int numIndexes; + glIndex_t *indexes; // vertexes int numVerts; @@ -1326,8 +1320,8 @@ typedef struct mdvSurface_s mdvVertex_t *verts; mdvSt_t *st; - int numTriangles; - srfTriangle_t *triangles; + int numIndexes; + glIndex_t *indexes; struct mdvModel_s *model; } mdvSurface_t; @@ -2275,7 +2269,7 @@ VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vertexes, uint32_t stateBits, vboUsage_t usage); IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, vboUsage_t usage); -IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * triangles, vboUsage_t usage); +IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage); void R_BindVBO(VBO_t * vbo); void R_BindNullVBO(void); diff --git a/code/renderergl2/tr_main.c b/code/renderergl2/tr_main.c index 37993d4d..a198583c 100644 --- a/code/renderergl2/tr_main.c +++ b/code/renderergl2/tr_main.c @@ -1288,9 +1288,9 @@ void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) { return; case SF_TRIANGLES: tri = (srfBspSurface_t *)surfType; - v1 = tri->verts + tri->triangles[0].indexes[0]; - v2 = tri->verts + tri->triangles[0].indexes[1]; - v3 = tri->verts + tri->triangles[0].indexes[2]; + v1 = tri->verts + tri->indexes[0]; + v2 = tri->verts + tri->indexes[1]; + v3 = tri->verts + tri->indexes[2]; PlaneFromPoints( plane4, v1->xyz, v2->xyz, v3->xyz ); VectorCopy( plane4, plane->normal ); plane->dist = plane4[3]; diff --git a/code/renderergl2/tr_marks.c b/code/renderergl2/tr_marks.c index dc625102..830d4d29 100644 --- a/code/renderergl2/tr_marks.c +++ b/code/renderergl2/tr_marks.c @@ -269,7 +269,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio int numClipPoints; float *v; srfBspSurface_t *cv; - srfTriangle_t *tri; + glIndex_t *tri; srfVert_t *dv; vec3_t normal; vec3_t projectionDir; @@ -414,11 +414,11 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio continue; } - for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++) + for(k = 0, tri = surf->indexes; k < surf->numIndexes; k += 3, tri += 3) { for(j = 0; j < 3; j++) { - v = surf->verts[tri->indexes[j]].xyz; + v = surf->verts[tri[j]].xyz; VectorMA(v, MARKER_OFFSET, surf->cullPlane.normal, clipPoints[0][j]); } @@ -437,12 +437,12 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio srfBspSurface_t *surf = (srfBspSurface_t *) surfaces[i]; - for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++) + for(k = 0, tri = surf->indexes; k < surf->numIndexes; k += 3, tri += 3) { for(j = 0; j < 3; j++) { - v = surf->verts[tri->indexes[j]].xyz; - VectorMA(v, MARKER_OFFSET, surf->verts[tri->indexes[j]].normal, clipPoints[0][j]); + v = surf->verts[tri[j]].xyz; + VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]); } // add the fragments of this face diff --git a/code/renderergl2/tr_model.c b/code/renderergl2/tr_model.c index 6d9cd9e4..a97dd6be 100644 --- a/code/renderergl2/tr_model.c +++ b/code/renderergl2/tr_model.c @@ -394,7 +394,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, mdvFrame_t *frame; mdvSurface_t *surf;//, *surface; int *shaderIndex; - srfTriangle_t *tri; + glIndex_t *tri; mdvVertex_t *v; mdvSt_t *st; mdvTag_t *tag; @@ -551,15 +551,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, } // swap all the triangles - surf->numTriangles = md3Surf->numTriangles; - surf->triangles = tri = ri.Hunk_Alloc(sizeof(*tri) * md3Surf->numTriangles, h_low); + surf->numIndexes = md3Surf->numTriangles * 3; + surf->indexes = tri = ri.Hunk_Alloc(sizeof(*tri) * 3 * md3Surf->numTriangles, h_low); md3Tri = (md3Triangle_t *) ((byte *) md3Surf + md3Surf->ofsTriangles); - for(j = 0; j < md3Surf->numTriangles; j++, tri++, md3Tri++) + for(j = 0; j < md3Surf->numTriangles; j++, tri += 3, md3Tri++) { - tri->indexes[0] = LittleLong(md3Tri->indexes[0]); - tri->indexes[1] = LittleLong(md3Tri->indexes[1]); - tri->indexes[2] = LittleLong(md3Tri->indexes[2]); + tri[0] = LittleLong(md3Tri->indexes[0]); + tri[1] = LittleLong(md3Tri->indexes[1]); + tri[2] = LittleLong(md3Tri->indexes[2]); } // swap all the XyzNormals @@ -623,15 +623,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, for(f = 0; f < mdvModel->numFrames; f++) { - for(j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++) + for(j = 0, tri = surf->indexes; j < surf->numIndexes; j += 3, tri += 3) { - v0 = surf->verts[surf->numVerts * f + tri->indexes[0]].xyz; - v1 = surf->verts[surf->numVerts * f + tri->indexes[1]].xyz; - v2 = surf->verts[surf->numVerts * f + tri->indexes[2]].xyz; + v0 = surf->verts[surf->numVerts * f + tri[0]].xyz; + v1 = surf->verts[surf->numVerts * f + tri[1]].xyz; + v2 = surf->verts[surf->numVerts * f + tri[2]].xyz; - t0 = surf->st[tri->indexes[0]].st; - t1 = surf->st[tri->indexes[1]].st; - t2 = surf->st[tri->indexes[2]].st; + t0 = surf->st[tri[0]].st; + t1 = surf->st[tri[1]].st; + t2 = surf->st[tri[2]].st; if (!r_recalcMD3Normals->integer) VectorCopy(v->normal, normal); @@ -649,15 +649,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, { float *v; - v = surf->verts[surf->numVerts * f + tri->indexes[k]].tangent; + v = surf->verts[surf->numVerts * f + tri[k]].tangent; VectorAdd(v, tangent, v); - v = surf->verts[surf->numVerts * f + tri->indexes[k]].bitangent; + v = surf->verts[surf->numVerts * f + tri[k]].bitangent; VectorAdd(v, bitangent, v); if (r_recalcMD3Normals->integer) { - v = surf->verts[surf->numVerts * f + tri->indexes[k]].normal; + v = surf->verts[surf->numVerts * f + tri[k]].normal; VectorAdd(v, normal, v); } } @@ -753,7 +753,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vboSurf->surfaceType = SF_VBO_MDVMESH; vboSurf->mdvModel = mdvModel; vboSurf->mdvSurface = surf; - vboSurf->numIndexes = surf->numTriangles * 3; + vboSurf->numIndexes = surf->numIndexes; vboSurf->numVerts = surf->numVerts; vboSurf->minIndex = 0; @@ -782,7 +782,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, ri.Free(data); - vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numTriangles, surf->triangles, VBO_USAGE_STATIC); + vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numIndexes, surf->indexes, VBO_USAGE_STATIC); } } diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 5102e1d1..fd9fb661 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -311,30 +311,28 @@ static void RB_SurfacePolychain( srfPoly_t *p ) { tess.numVertexes = numv; } -static void RB_SurfaceVertsAndTris( int numVerts, srfVert_t *verts, int numTriangles, srfTriangle_t *triangles, int dlightBits, int pshadowBits) +static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIndexes, glIndex_t *indexes, int dlightBits, int pshadowBits) { int i; - srfTriangle_t *tri; + glIndex_t *inIndex; srfVert_t *dv; float *xyz, *normal, *texCoords, *lightCoords, *lightdir; #ifdef USE_VERT_TANGENT_SPACE float *tangent, *bitangent; #endif - glIndex_t *index; + glIndex_t *outIndex; float *color; RB_CheckVBOandIBO(tess.vbo, tess.ibo); - RB_CHECKOVERFLOW( numVerts, numTriangles * 3 ); + RB_CHECKOVERFLOW( numVerts, numIndexes ); - tri = triangles; - index = &tess.indexes[ tess.numIndexes ]; - for ( i = 0 ; i < numTriangles ; i++, tri++ ) { - *index++ = tess.numVertexes + tri->indexes[0]; - *index++ = tess.numVertexes + tri->indexes[1]; - *index++ = tess.numVertexes + tri->indexes[2]; + inIndex = indexes; + outIndex = &tess.indexes[ tess.numIndexes ]; + for ( i = 0 ; i < numIndexes ; i++ ) { + *outIndex++ = tess.numVertexes + *inIndex++; } - tess.numIndexes += numTriangles * 3; + tess.numIndexes += numIndexes; if ( tess.shader->vertexAttribs & ATTR_POSITION ) { @@ -523,14 +521,14 @@ RB_SurfaceTriangles ============= */ static void RB_SurfaceTriangles( srfBspSurface_t *srf ) { - if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, + if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) ) { return; } - RB_SurfaceVertsAndTris(srf->numVerts, srf->verts, srf->numTriangles, - srf->triangles, srf->dlightBits, srf->pshadowBits); + RB_SurfaceVertsAndIndexes(srf->numVerts, srf->verts, srf->numIndexes, + srf->indexes, srf->dlightBits, srf->pshadowBits); } @@ -1201,9 +1199,7 @@ RB_SurfaceMesh static void RB_SurfaceMesh(mdvSurface_t *surface) { int j; float backlerp; - srfTriangle_t *triangles; mdvSt_t *texCoords; - int indexes; int Bob, Doug; int numVerts; @@ -1213,20 +1209,16 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) { backlerp = backEnd.currentEntity->e.backlerp; } - RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles*3 ); + RB_CHECKOVERFLOW( surface->numVerts, surface->numIndexes ); LerpMeshVertexes (surface, backlerp); - triangles = surface->triangles; - indexes = surface->numTriangles * 3; Bob = tess.numIndexes; Doug = tess.numVertexes; - for (j = 0 ; j < surface->numTriangles ; j++) { - tess.indexes[Bob + j*3 + 0] = Doug + triangles[j].indexes[0]; - tess.indexes[Bob + j*3 + 1] = Doug + triangles[j].indexes[1]; - tess.indexes[Bob + j*3 + 2] = Doug + triangles[j].indexes[2]; + for (j = 0 ; j < surface->numIndexes ; j++) { + tess.indexes[Bob + j] = Doug + surface->indexes[j]; } - tess.numIndexes += indexes; + tess.numIndexes += surface->numIndexes; texCoords = surface->st; @@ -1248,14 +1240,14 @@ RB_SurfaceFace ============== */ static void RB_SurfaceFace( srfBspSurface_t *srf ) { - if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, + if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) ) { return; } - RB_SurfaceVertsAndTris(srf->numVerts, srf->verts, srf->numTriangles, - srf->triangles, srf->dlightBits, srf->pshadowBits); + RB_SurfaceVertsAndIndexes(srf->numVerts, srf->verts, srf->numIndexes, + srf->indexes, srf->dlightBits, srf->pshadowBits); } @@ -1317,7 +1309,7 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { int pshadowBits; //int *vDlightBits; - if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, + if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) ) { return; @@ -1576,7 +1568,7 @@ static void RB_SurfaceFlare(srfFlare_t *surf) static void RB_SurfaceVBOMesh(srfBspSurface_t * srf) { - RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, srf->firstIndex, + RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qfalse ); } diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index 11eb3ceb..44a461a6 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -501,7 +501,7 @@ IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, v R_CreateIBO2 ============ */ -IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * triangles, vboUsage_t usage) +IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage) { IBO_t *ibo; int i, j; @@ -510,7 +510,7 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * int indexesSize; int indexesOfs; - srfTriangle_t *tri; + glIndex_t *tri; glIndex_t index; int glUsage; @@ -529,7 +529,7 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * return NULL; } - if(!numTriangles) + if(!numIndexes) return NULL; if(strlen(name) >= MAX_QPATH) @@ -548,15 +548,15 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * Q_strncpyz(ibo->name, name, sizeof(ibo->name)); - indexesSize = numTriangles * 3 * sizeof(int); + indexesSize = numIndexes * sizeof(glIndex_t); indexes = ri.Hunk_AllocateTempMemory(indexesSize); indexesOfs = 0; - for(i = 0, tri = triangles; i < numTriangles; i++, tri++) + for(i = 0, tri = inIndexes; i < numIndexes; i += 3, tri += 3) { for(j = 0; j < 3; j++) { - index = tri->indexes[j]; + index = tri[j]; memcpy(indexes + indexesOfs, &index, sizeof(glIndex_t)); indexesOfs += sizeof(glIndex_t); } From 90c98c90a3768411cf27f0b92734d0e016f9053d Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 26 Oct 2013 22:31:44 -0500 Subject: [PATCH 10/21] Fix VM FOpenFile( FS_READ ) files seeking twice in FS_Seek --- code/qcommon/files.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 20808f0b..0b13ecdb 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -1628,9 +1628,11 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { } if (fsh[f].streamed) { + int r; fsh[f].streamed = qfalse; - FS_Seek( f, offset, origin ); + r = FS_Seek( f, offset, origin ); fsh[f].streamed = qtrue; + return r; } if (fsh[f].zipFile == qtrue) { From c69db4a4002bd640c638f7314381c5d3b3a6864a Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 26 Oct 2013 22:36:09 -0500 Subject: [PATCH 11/21] Remove unused variable baseOffset from fsh[] --- code/qcommon/files.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 0b13ecdb..b6af640a 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -275,7 +275,6 @@ typedef struct qfile_us { typedef struct { qfile_ut handleFiles; qboolean handleSync; - int baseOffset; int fileSize; int zipFilePos; qboolean zipFile; @@ -4014,11 +4013,6 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) { } if ( *f ) { - if (fsh[*f].zipFile == qtrue) { - fsh[*f].baseOffset = unztell(fsh[*f].handleFiles.file.z); - } else { - fsh[*f].baseOffset = ftell(fsh[*f].handleFiles.file.o); - } fsh[*f].fileSize = r; fsh[*f].streamed = qfalse; From 2d45e57068866cf0bc778e5c747bae74de163fa0 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 26 Oct 2013 22:43:53 -0500 Subject: [PATCH 12/21] Support FS_SEEK_END and negative offset for zipped files in FS_Seek Use FS_SEEK_END in sound code instead of working around it. If FS_SEEK_SET and going to current position, just return. --- code/client/snd_codec_ogg.c | 5 +--- code/client/snd_codec_opus.c | 5 +--- code/qcommon/files.c | 47 +++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/code/client/snd_codec_ogg.c b/code/client/snd_codec_ogg.c index c424649f..2fa6abf0 100644 --- a/code/client/snd_codec_ogg.c +++ b/code/client/snd_codec_ogg.c @@ -157,11 +157,8 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence) case SEEK_END : { - // Quake 3 seems to have trouble with FS_SEEK_END - // so we use the file length and FS_SEEK_SET - // set the file position in the actual file with the Q3 function - retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET); + retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END); // something has gone wrong, so we return here if(retVal < 0) diff --git a/code/client/snd_codec_opus.c b/code/client/snd_codec_opus.c index 190aee9a..b43dea44 100644 --- a/code/client/snd_codec_opus.c +++ b/code/client/snd_codec_opus.c @@ -146,11 +146,8 @@ int S_OggOpus_Callback_seek(void *datasource, opus_int64 offset, int whence) case SEEK_END : { - // Quake 3 seems to have trouble with FS_SEEK_END - // so we use the file length and FS_SEEK_SET - // set the file position in the actual file with the Q3 function - retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET); + retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END); // something has gone wrong, so we return here if(retVal < 0) diff --git a/code/qcommon/files.c b/code/qcommon/files.c index b6af640a..1e66cff2 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -277,6 +277,7 @@ typedef struct { qboolean handleSync; int fileSize; int zipFilePos; + int zipFileLen; qboolean zipFile; qboolean streamed; char name[MAX_ZPATH]; @@ -1261,6 +1262,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_ // open the file in the zip unzOpenCurrentFile(fsh[*file].handleFiles.file.z); fsh[*file].zipFilePos = pakFile->pos; + fsh[*file].zipFileLen = pakFile->len; if(fs_debug->integer) { @@ -1635,23 +1637,52 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { } if (fsh[f].zipFile == qtrue) { - //FIXME: this is incomplete and really, really - //crappy (but better than what was here before) + //FIXME: this is really, really crappy + //(but better than what was here before) byte buffer[PK3_SEEK_BUFFER_SIZE]; - int remainder = offset; + int remainder; + int currentPosition = FS_FTell( f ); - if( offset < 0 || origin == FS_SEEK_END ) { - Com_Error( ERR_FATAL, "Negative offsets and FS_SEEK_END not implemented " - "for FS_Seek on pk3 file contents" ); - return -1; + // change negative offsets into FS_SEEK_SET + if ( offset < 0 ) { + switch( origin ) { + case FS_SEEK_END: + remainder = fsh[f].zipFileLen + offset; + break; + + case FS_SEEK_CUR: + remainder = currentPosition + offset; + break; + + case FS_SEEK_SET: + default: + remainder = 0; + break; + } + + if ( remainder < 0 ) { + remainder = 0; + } + + origin = FS_SEEK_SET; + } else { + if ( origin == FS_SEEK_END ) { + remainder = fsh[f].zipFileLen - currentPosition + offset; + } else { + remainder = offset; + } } switch( origin ) { case FS_SEEK_SET: + if ( remainder == currentPosition ) { + return offset; + } unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos); unzOpenCurrentFile(fsh[f].handleFiles.file.z); //fallthrough + case FS_SEEK_END: case FS_SEEK_CUR: while( remainder > PK3_SEEK_BUFFER_SIZE ) { FS_Read( buffer, PK3_SEEK_BUFFER_SIZE, f ); @@ -1659,12 +1690,10 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { } FS_Read( buffer, remainder, f ); return offset; - break; default: Com_Error( ERR_FATAL, "Bad origin in FS_Seek" ); return -1; - break; } } else { FILE *file; From 028f0f1ac4cb41a68caef4c230fdabab577aa8a7 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 26 Oct 2013 23:53:44 -0500 Subject: [PATCH 13/21] Remove old comment that FS_Seek doesn't work on zipped files --- code/qcommon/qcommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 65271464..9583cd9b 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -694,7 +694,7 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ); // opens a file for reading, writing, or appending depending on the value of mode int FS_Seek( fileHandle_t f, long offset, int origin ); -// seek on a file (doesn't work for zip files!!!!!!!!) +// seek on a file qboolean FS_FilenameCompare( const char *s1, const char *s2 ); From baf5737779467b2f3e55a751b5bd44bff663fd0a Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 27 Oct 2013 00:51:53 -0500 Subject: [PATCH 14/21] Remove function prototypes for non-existant Sys_* DLL functions --- code/qcommon/qcommon.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 9583cd9b..414b341b 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -1063,19 +1063,6 @@ void * QDECL Sys_LoadGameDll( const char *name, intptr_t (QDECL **entryPoint)(in intptr_t (QDECL *systemcalls)(intptr_t, ...) ); void Sys_UnloadDll( void *dllHandle ); -void Sys_UnloadGame( void ); -void *Sys_GetGameAPI( void *parms ); - -void Sys_UnloadCGame( void ); -void *Sys_GetCGameAPI( void ); - -void Sys_UnloadUI( void ); -void *Sys_GetUIAPI( void ); - -//bot libraries -void Sys_UnloadBotLib( void ); -void *Sys_GetBotLibAPI( void *parms ); - char *Sys_GetCurrentUser( void ); void QDECL Sys_Error( const char *error, ...) __attribute__ ((noreturn, format (printf, 1, 2))); From d526eacd10240335cc8534544f1e501a89e9630f Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 9 Nov 2013 16:57:43 -0600 Subject: [PATCH 15/21] Fix flares being invisible after vid_restart flareCoeff was only set if r_flareCoeff cvar was set as modified. Cvars are set as modified when created or changed. --- code/renderergl1/tr_flares.c | 21 ++++++++++++++++----- code/renderergl2/tr_flares.c | 21 ++++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/code/renderergl1/tr_flares.c b/code/renderergl1/tr_flares.c index 1d0a9175..7bd95194 100644 --- a/code/renderergl1/tr_flares.c +++ b/code/renderergl1/tr_flares.c @@ -86,6 +86,19 @@ flare_t *r_activeFlares, *r_inactiveFlares; int flareCoeff; +/* +================== +R_SetFlareCoeff +================== +*/ +static void R_SetFlareCoeff( void ) { + + if(r_flareCoeff->value == 0.0f) + flareCoeff = atof(FLARE_STDCOEFF); + else + flareCoeff = r_flareCoeff->value; +} + /* ================== R_ClearFlares @@ -102,6 +115,8 @@ void R_ClearFlares( void ) { r_flareStructs[i].next = r_inactiveFlares; r_inactiveFlares = &r_flareStructs[i]; } + + R_SetFlareCoeff(); } @@ -450,11 +465,7 @@ void RB_RenderFlares (void) { if(r_flareCoeff->modified) { - if(r_flareCoeff->value == 0.0f) - flareCoeff = atof(FLARE_STDCOEFF); - else - flareCoeff = r_flareCoeff->value; - + R_SetFlareCoeff(); r_flareCoeff->modified = qfalse; } diff --git a/code/renderergl2/tr_flares.c b/code/renderergl2/tr_flares.c index bc016c1c..4447aa23 100644 --- a/code/renderergl2/tr_flares.c +++ b/code/renderergl2/tr_flares.c @@ -86,6 +86,19 @@ flare_t *r_activeFlares, *r_inactiveFlares; int flareCoeff; +/* +================== +R_SetFlareCoeff +================== +*/ +static void R_SetFlareCoeff( void ) { + + if(r_flareCoeff->value == 0.0f) + flareCoeff = atof(FLARE_STDCOEFF); + else + flareCoeff = r_flareCoeff->value; +} + /* ================== R_ClearFlares @@ -102,6 +115,8 @@ void R_ClearFlares( void ) { r_flareStructs[i].next = r_inactiveFlares; r_inactiveFlares = &r_flareStructs[i]; } + + R_SetFlareCoeff(); } @@ -451,11 +466,7 @@ void RB_RenderFlares (void) { if(r_flareCoeff->modified) { - if(r_flareCoeff->value == 0.0f) - flareCoeff = atof(FLARE_STDCOEFF); - else - flareCoeff = r_flareCoeff->value; - + R_SetFlareCoeff(); r_flareCoeff->modified = qfalse; } From 5795be68f6aabba02c9707eef4e193cf334cd946 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 10 Nov 2013 22:42:48 -0600 Subject: [PATCH 16/21] Make OpenAL buffer management work on OS X Don't assume we have unlimited OpenAL buffers. Detach buffers from sources by setting AL_BUFFER to 0. Cannot delete buffers on OS X immediately after alSourceUnqueueBuffers. Free unprocessed stream and music buffers. Free unused sfx buffers when sound file exists and fails loading into OpenAL (though I haven't seen it fail). --- code/client/snd_openal.c | 137 ++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 32 deletions(-) diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index 649c748e..54749e24 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -312,6 +312,44 @@ static qboolean S_AL_BufferEvict( void ) return qfalse; } +/* +================= +S_AL_GenBuffers +================= +*/ +static qboolean S_AL_GenBuffers(ALsizei numBuffers, ALuint *buffers, const char *name) +{ + ALenum error; + + S_AL_ClearError( qfalse ); + qalGenBuffers( numBuffers, buffers ); + error = qalGetError(); + + // If we ran out of buffers, start evicting the least recently used sounds + while( error == AL_INVALID_VALUE ) + { + if( !S_AL_BufferEvict( ) ) + { + Com_Printf( S_COLOR_RED "ERROR: Out of audio buffers\n"); + return qfalse; + } + + // Try again + S_AL_ClearError( qfalse ); + qalGenBuffers( numBuffers, buffers ); + error = qalGetError(); + } + + if( error != AL_NO_ERROR ) + { + Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n", + name, S_AL_ErrorMsg(error)); + return qfalse; + } + + return qtrue; +} + /* ================= S_AL_BufferLoad @@ -354,14 +392,10 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) format = S_AL_Format(info.width, info.channels); // Create a buffer - S_AL_ClearError( qfalse ); - qalGenBuffers(1, &curSfx->buffer); - if((error = qalGetError()) != AL_NO_ERROR) + if (!S_AL_GenBuffers(1, &curSfx->buffer, curSfx->filename)) { S_AL_BufferUseDefault(sfx); Hunk_FreeTempMemory(data); - Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n", - curSfx->filename, S_AL_ErrorMsg(error)); return; } @@ -383,6 +417,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) { if( !S_AL_BufferEvict( ) ) { + qalDeleteBuffers(1, &curSfx->buffer); S_AL_BufferUseDefault(sfx); Hunk_FreeTempMemory(data); Com_Printf( S_COLOR_RED "ERROR: Out of memory loading %s\n", curSfx->filename); @@ -397,6 +432,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) // Some other error condition if(error != AL_NO_ERROR) { + qalDeleteBuffers(1, &curSfx->buffer); S_AL_BufferUseDefault(sfx); Hunk_FreeTempMemory(data); Com_Printf( S_COLOR_RED "ERROR: Can't fill sound buffer for %s - %s\n", @@ -964,7 +1000,7 @@ static void S_AL_SrcKill(srcHandle_t src) curSource->isPlaying = qfalse; } - // Remove the buffer + // Detach any buffers qalSourcei(curSource->alSource, AL_BUFFER, 0); curSource->sfx = 0; @@ -1623,9 +1659,15 @@ ALuint S_AL_SrcGet(srcHandle_t src) //=========================================================================== +// Q3A cinematics use up to 12 buffers at once +#define MAX_STREAM_BUFFERS 20 + static srcHandle_t streamSourceHandles[MAX_RAW_STREAMS]; static qboolean streamPlaying[MAX_RAW_STREAMS]; static ALuint streamSources[MAX_RAW_STREAMS]; +static ALuint streamBuffers[MAX_RAW_STREAMS][MAX_STREAM_BUFFERS]; +static int streamNumBuffers[MAX_RAW_STREAMS]; +static int streamBufIndex[MAX_RAW_STREAMS]; /* ================= @@ -1683,6 +1725,9 @@ static void S_AL_AllocateStreamChannel(int stream, int entityNum) streamSourceHandles[stream] = cursrc; streamSources[stream] = alsrc; + + streamNumBuffers[stream] = 0; + streamBufIndex[stream] = 0; } /* @@ -1695,6 +1740,15 @@ static void S_AL_FreeStreamChannel( int stream ) if ((stream < 0) || (stream >= MAX_RAW_STREAMS)) return; + // Detach any buffers + qalSourcei(streamSources[stream], AL_BUFFER, 0); + + // Delete the buffers + if (streamNumBuffers[stream] > 0) { + qalDeleteBuffers(streamNumBuffers[stream], streamBuffers[stream]); + streamNumBuffers[stream] = 0; + } + // Release the output streamSource S_AL_SrcUnlock(streamSourceHandles[stream]); S_AL_SrcKill(streamSourceHandles[stream]); @@ -1710,6 +1764,7 @@ S_AL_RawSamples static void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels, const byte *data, float volume, int entityNum) { + int numBuffers; ALuint buffer; ALuint format; @@ -1731,8 +1786,40 @@ void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels, } } - // Create a buffer, and stuff the data into it - qalGenBuffers(1, &buffer); + qalGetSourcei(streamSources[stream], AL_BUFFERS_QUEUED, &numBuffers); + + if (numBuffers == MAX_STREAM_BUFFERS) + { + Com_DPrintf(S_COLOR_RED"WARNING: Steam dropping raw samples, reached MAX_STREAM_BUFFERS\n"); + return; + } + + // Allocate a new AL buffer if needed + if (numBuffers == streamNumBuffers[stream]) + { + ALuint oldBuffers[MAX_STREAM_BUFFERS]; + int i; + + if (!S_AL_GenBuffers(1, &buffer, "stream")) + return; + + Com_Memcpy(oldBuffers, &streamBuffers[stream], sizeof (oldBuffers)); + + // Reorder buffer array in order of oldest to newest + for ( i = 0; i < streamNumBuffers[stream]; ++i ) + streamBuffers[stream][i] = oldBuffers[(streamBufIndex[stream] + i) % streamNumBuffers[stream]]; + + // Add the new buffer to end + streamBuffers[stream][streamNumBuffers[stream]] = buffer; + streamBufIndex[stream] = streamNumBuffers[stream]; + streamNumBuffers[stream]++; + } + + // Select next buffer in loop + buffer = streamBuffers[stream][ streamBufIndex[stream] ]; + streamBufIndex[stream] = (streamBufIndex[stream] + 1) % streamNumBuffers[stream]; + + // Fill buffer qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate); // Shove the data onto the streamSource @@ -1762,13 +1849,12 @@ void S_AL_StreamUpdate( int stream ) if(streamSourceHandles[stream] == -1) return; - // Un-queue any buffers, and delete them + // Un-queue any buffers qalGetSourcei( streamSources[stream], AL_BUFFERS_PROCESSED, &numBuffers ); while( numBuffers-- ) { ALuint buffer; qalSourceUnqueueBuffers(streamSources[stream], 1, &buffer); - qalDeleteBuffers(1, &buffer); } // Start the streamSource playing if necessary @@ -1799,8 +1885,6 @@ S_AL_StreamDie static void S_AL_StreamDie( int stream ) { - int numBuffers; - if ((stream < 0) || (stream >= MAX_RAW_STREAMS)) return; @@ -1810,15 +1894,6 @@ void S_AL_StreamDie( int stream ) streamPlaying[stream] = qfalse; qalSourceStop(streamSources[stream]); - // Un-queue any buffers, and delete them - qalGetSourcei( streamSources[stream], AL_BUFFERS_PROCESSED, &numBuffers ); - while( numBuffers-- ) - { - ALuint buffer; - qalSourceUnqueueBuffers(streamSources[stream], 1, &buffer); - qalDeleteBuffers(1, &buffer); - } - S_AL_FreeStreamChannel(stream); } @@ -1910,22 +1985,17 @@ S_AL_StopBackgroundTrack static void S_AL_StopBackgroundTrack( void ) { - int numBuffers; - if(!musicPlaying) return; // Stop playing qalSourceStop(musicSource); - // Un-queue any buffers, and delete them - qalGetSourcei( musicSource, AL_BUFFERS_PROCESSED, &numBuffers ); - while( numBuffers-- ) - { - ALuint buffer; - qalSourceUnqueueBuffers(musicSource, 1, &buffer); - qalDeleteBuffers(1, &buffer); - } + // Detach any buffers + qalSourcei(musicSource, AL_BUFFER, 0); + + // Delete the buffers + qalDeleteBuffers(NUM_MUSIC_BUFFERS, musicBuffers); // Free the musicSource S_AL_MusicSourceFree(); @@ -2058,7 +2128,8 @@ void S_AL_StartBackgroundTrack( const char *intro, const char *loop ) } // Generate the musicBuffers - qalGenBuffers(NUM_MUSIC_BUFFERS, musicBuffers); + if (!S_AL_GenBuffers(NUM_MUSIC_BUFFERS, musicBuffers, "music")) + return; // Queue the musicBuffers up for(i = 0; i < NUM_MUSIC_BUFFERS; i++) @@ -2419,6 +2490,8 @@ qboolean S_AL_Init( soundInterface_t *si ) streamSourceHandles[i] = -1; streamPlaying[i] = qfalse; streamSources[i] = 0; + streamNumBuffers[i] = 0; + streamBufIndex[i] = 0; } // New console variables From b3bd74fce7d91b68498eff94797657a96755fb67 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 10 Nov 2013 23:28:54 -0600 Subject: [PATCH 17/21] Fix restoring loop sound position on OS X The default OpenAL library on OS X errors AL_INVALID_VALUE for AL_SEC_OFFSET if source isn't playing. --- code/client/snd_openal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index 54749e24..b42eae59 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -1517,6 +1517,10 @@ void S_AL_SrcUpdate( void ) if(!curSource->isPlaying) { + qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE); + curSource->isPlaying = qtrue; + qalSourcePlay(curSource->alSource); + if(curSource->priority == SRCPRI_AMBIENT) { // If there are other ambient looping sources with the same sound, @@ -1574,10 +1578,6 @@ void S_AL_SrcUpdate( void ) } curSfx->loopActiveCnt++; - - qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE); - curSource->isPlaying = qtrue; - qalSourcePlay(curSource->alSource); } // Update locality From 203ab7b9af3f76e866ee6ba2a19427278cbbc001 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 10 Nov 2013 23:39:50 -0600 Subject: [PATCH 18/21] Fix cinematics often being silent on OS X If OpenAL source isn't playing, often what happens is: queued buffers is 0 and processed buffers is non-0. S_AL_StreamUpdate won't play the steam if queued buffers 0. So start the stream in S_AL_RawSamples. --- code/client/snd_openal.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index b42eae59..e2d19990 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -1830,6 +1830,13 @@ void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels, // Volume S_AL_Gain (streamSources[stream], volume * s_volume->value * s_alGain->value); } + + // Start stream + if(!streamPlaying[stream]) + { + qalSourcePlay( streamSources[stream] ); + streamPlaying[stream] = qtrue; + } } /* From 93be2655f8a6305271930e308351e8722c1acf57 Mon Sep 17 00:00:00 2001 From: Ensiform Date: Mon, 11 Nov 2013 01:09:10 -0600 Subject: [PATCH 19/21] Remove unused cvar_t variable cl_trn --- code/client/cl_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 143e1201..daf2ed58 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -112,7 +112,6 @@ cvar_t *cl_conXOffset; cvar_t *cl_inGameVideo; cvar_t *cl_serverStatusResendTime; -cvar_t *cl_trn; cvar_t *cl_lanForcePackets; From a53e7c3074543fcbccb0e2be4d0121e3b7f9d1e1 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Mon, 11 Nov 2013 01:12:42 -0600 Subject: [PATCH 20/21] Fix comparing unsigned values to < 0 in gl2 --- code/renderergl2/tr_bsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 419ba055..28b99dd3 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -746,7 +746,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, { tri[j] = LittleLong(indexes[i + j]); - if(tri[j] < 0 || tri[j] >= numVerts) + if(tri[j] >= numVerts) { ri.Error(ERR_DROP, "Bad index in face surface"); } @@ -990,7 +990,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor { tri[j] = LittleLong(indexes[i + j]); - if(tri[j] < 0 || tri[j] >= numVerts) + if(tri[j] >= numVerts) { ri.Error(ERR_DROP, "Bad index in face surface"); } From 6e5f8cc918e89b279070b0335648149af43ac1bd Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 12 Nov 2013 19:21:51 -0800 Subject: [PATCH 21/21] OpenGL2: Calculate bitangent in shader, and store normal/tangent as normalized byte arrays. --- code/renderergl2/glsl/generic_vp.glsl | 30 ++++---- code/renderergl2/glsl/lightall_vp.glsl | 24 ++++--- code/renderergl2/tr_animation.c | 12 ++-- code/renderergl2/tr_bsp.c | 6 +- code/renderergl2/tr_curve.c | 3 +- code/renderergl2/tr_glsl.c | 83 +++++----------------- code/renderergl2/tr_local.h | 54 ++++++-------- code/renderergl2/tr_main.c | 25 +++++-- code/renderergl2/tr_model.c | 37 +++++----- code/renderergl2/tr_model_iqm.c | 23 +++--- code/renderergl2/tr_shade.c | 1 - code/renderergl2/tr_shade_calc.c | 46 ++++++++---- code/renderergl2/tr_shader.c | 2 +- code/renderergl2/tr_surface.c | 97 +++++++++++++++++--------- code/renderergl2/tr_vbo.c | 96 +++++++++++-------------- 15 files changed, 268 insertions(+), 271 deletions(-) diff --git a/code/renderergl2/glsl/generic_vp.glsl b/code/renderergl2/glsl/generic_vp.glsl index 94e3c83e..baae6046 100644 --- a/code/renderergl2/glsl/generic_vp.glsl +++ b/code/renderergl2/glsl/generic_vp.glsl @@ -1,8 +1,8 @@ -attribute vec4 attr_Position; +attribute vec3 attr_Position; attribute vec3 attr_Normal; #if defined(USE_VERTEX_ANIMATION) -attribute vec4 attr_Position2; +attribute vec3 attr_Position2; attribute vec3 attr_Normal2; #endif @@ -167,7 +167,7 @@ vec4 CalcColor(vec3 position, vec3 normal) if (u_AlphaGen == AGEN_LIGHTING_SPECULAR) { - vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position.xyz); + vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position); vec3 reflected = -reflect(lightDir, normal); color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0); @@ -184,10 +184,10 @@ vec4 CalcColor(vec3 position, vec3 normal) #endif #if defined(USE_FOG) -float CalcFog(vec4 position) +float CalcFog(vec3 position) { - float s = dot(position, u_FogDistance) * 8.0; - float t = dot(position, u_FogDepth); + float s = (dot(position, u_FogDistance.xyz) + u_FogDistance.w) * 8.0; + float t = dot(position, u_FogDepth.xyz) + u_FogDepth.w; float eyeOutside = step(0.0, -u_FogEyeT); float fogged = step(eyeOutside, t); @@ -202,27 +202,27 @@ float CalcFog(vec4 position) void main() { #if defined(USE_VERTEX_ANIMATION) - vec4 position = mix(attr_Position, attr_Position2, u_VertexLerp); - vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp)); + vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); + vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp) * 2.0 - vec3(1.0)); #else - vec4 position = attr_Position; - vec3 normal = attr_Normal; + vec3 position = attr_Position; + vec3 normal = attr_Normal * 2.0 - vec3(1.0); #endif #if defined(USE_DEFORM_VERTEXES) - position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st); + position = DeformPosition(position, normal, attr_TexCoord0.st); #endif - gl_Position = u_ModelViewProjectionMatrix * position; + gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0); #if defined(USE_TCGEN) - vec2 tex = GenTexCoords(u_TCGen0, position.xyz, normal, u_TCGen0Vector0, u_TCGen0Vector1); + vec2 tex = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1); #else vec2 tex = attr_TexCoord0.st; #endif #if defined(USE_TCMOD) - var_DiffuseTex = ModTexCoords(tex, position.xyz, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); + var_DiffuseTex = ModTexCoords(tex, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); #else var_DiffuseTex = tex; #endif @@ -232,7 +232,7 @@ void main() #endif #if defined(USE_RGBAGEN) - var_Color = CalcColor(position.xyz, normal); + var_Color = CalcColor(position, normal); #else var_Color = u_VertColor * attr_Color + u_BaseColor; #endif diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index aa0fe25b..f6164957 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/renderergl2/glsl/lightall_vp.glsl @@ -7,8 +7,7 @@ attribute vec4 attr_Color; attribute vec3 attr_Position; attribute vec3 attr_Normal; #if defined(USE_VERT_TANGENT_SPACE) -attribute vec3 attr_Tangent; -attribute vec3 attr_Bitangent; +attribute vec4 attr_Tangent; #endif #if defined(USE_VERTEX_ANIMATION) @@ -163,21 +162,24 @@ float CalcLightAttenuation(vec3 dir, float sqrRadius) void main() { #if defined(USE_VERTEX_ANIMATION) - vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); - vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp)); - #if defined(USE_VERT_TANGENT_SPACE) - vec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp)); - vec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp)); + vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); + vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp) * 2.0 - vec3(1.0)); + #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + vec3 tangent = normalize(mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp) * 2.0 - vec3(1.0)); #endif #else vec3 position = attr_Position; - vec3 normal = attr_Normal; - #if defined(USE_VERT_TANGENT_SPACE) - vec3 tangent = attr_Tangent; - vec3 bitangent = attr_Bitangent; + vec3 normal = attr_Normal * 2.0 - vec3(1.0); + #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + vec3 tangent = attr_Tangent.xyz * 2.0 - vec3(1.0); #endif #endif +#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + vec3 bitangent = cross(normal, tangent); + bitangent *= attr_Tangent.w * 2.0 - 1.0; +#endif + #if defined(USE_TCGEN) vec2 texCoords = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1); #else diff --git a/code/renderergl2/tr_animation.c b/code/renderergl2/tr_animation.c index 985fe9bb..f3329ee4 100644 --- a/code/renderergl2/tr_animation.c +++ b/code/renderergl2/tr_animation.c @@ -152,9 +152,9 @@ void RB_SurfaceAnim( md4Surface_t *surface ) { tess.xyz[baseVertex + j][1] = tempVert[1]; tess.xyz[baseVertex + j][2] = tempVert[2]; - tess.normal[baseVertex + j][0] = tempNormal[0]; - tess.normal[baseVertex + j][1] = tempNormal[1]; - tess.normal[baseVertex + j][2] = tempNormal[2]; + tess.normal[baseVertex + j][0] = (uint8_t)(tempNormal[0] * 127.5f + 128.0f); + tess.normal[baseVertex + j][1] = (uint8_t)(tempNormal[1] * 127.5f + 128.0f); + tess.normal[baseVertex + j][2] = (uint8_t)(tempNormal[2] * 127.5f + 128.0f); tess.texCoords[baseVertex + j][0][0] = v->texCoords[0]; tess.texCoords[baseVertex + j][0][1] = v->texCoords[1]; @@ -548,9 +548,9 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface ) tess.xyz[baseVertex + j][1] = tempVert[1]; tess.xyz[baseVertex + j][2] = tempVert[2]; - tess.normal[baseVertex + j][0] = tempNormal[0]; - tess.normal[baseVertex + j][1] = tempNormal[1]; - tess.normal[baseVertex + j][2] = tempNormal[2]; + tess.normal[baseVertex + j][0] = (uint8_t)(tempNormal[0] * 127.5f + 128.0f); + tess.normal[baseVertex + j][1] = (uint8_t)(tempNormal[1] * 127.5f + 128.0f); + tess.normal[baseVertex + j][2] = (uint8_t)(tempNormal[2] * 127.5f + 128.0f); tess.texCoords[baseVertex + j][0][0] = v->texCoords[0]; tess.texCoords[baseVertex + j][0][1] = v->texCoords[1]; diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 28b99dd3..2947e8ff 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -1810,12 +1810,14 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out) out->xyz[j] = in->xyz[j]; #ifdef USE_VERT_TANGENT_SPACE 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->lightdir[j] = in->lightdir[j]; } + out->tangent[3] = in->tangent[3]; + for(j = 0; j < 2; j++) { out->st[j] = in->st[j]; @@ -2000,7 +2002,7 @@ static void R_CreateWorldVBOs(void) #ifdef USE_VERT_TANGENT_SPACE vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT | + ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); #else vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, diff --git a/code/renderergl2/tr_curve.c b/code/renderergl2/tr_curve.c index 4f36243b..91c80a4d 100644 --- a/code/renderergl2/tr_curve.c +++ b/code/renderergl2/tr_curve.c @@ -247,8 +247,7 @@ static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRI 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); + VectorCopy4(dv[0]->tangent, dv[1]->tangent); } } } diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index d67744f8..d0573b97 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -528,9 +528,6 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int #ifdef USE_VERT_TANGENT_SPACE if(attribs & ATTR_TANGENT) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); - - if(attribs & ATTR_BITANGENT) - qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT, "attr_Bitangent"); #endif if(attribs & ATTR_NORMAL) @@ -554,9 +551,6 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int #ifdef USE_VERT_TANGENT_SPACE if(attribs & ATTR_TANGENT2) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2"); - - if(attribs & ATTR_BITANGENT2) - qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT2, "attr_Bitangent2"); #endif GLSL_LinkProgram(program->program); @@ -1069,7 +1063,7 @@ void GLSL_InitGPUShaders(void) #ifdef USE_VERT_TANGENT_SPACE Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n"); - attribs |= ATTR_TANGENT | ATTR_BITANGENT; + attribs |= ATTR_TANGENT; #endif if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) @@ -1133,7 +1127,7 @@ void GLSL_InitGPUShaders(void) #ifdef USE_VERT_TANGENT_SPACE if (r_normalMapping->integer) { - attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2; + attribs |= ATTR_TANGENT2; } #endif } @@ -1400,12 +1394,10 @@ void GLSL_ShutdownGPUShaders(void) qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); #ifdef USE_VERT_TANGENT_SPACE qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); - qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT); #endif qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); #ifdef USE_VERT_TANGENT_SPACE qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); - qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2); #endif qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION); @@ -1565,20 +1557,6 @@ void GLSL_VertexAttribsState(uint32_t stateBits) 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); - } - } #endif if(diff & ATTR_COLOR) @@ -1651,20 +1629,6 @@ void GLSL_VertexAttribsState(uint32_t stateBits) qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2); } } - - if(diff & ATTR_BITANGENT2) - { - if(stateBits & ATTR_BITANGENT2) - { - GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n"); - qglEnableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2); - } - else - { - GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n"); - qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2); - } - } #endif glState.vertexAttribsState = stateBits; @@ -1674,17 +1638,18 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { qboolean animated; int newFrame, oldFrame; + VBO_t *vbo = glState.currentVBO; - if(!glState.currentVBO) + if(!vbo) { ri.Error(ERR_FATAL, "GL_VertexAttribPointers: no VBO bound"); return; } // don't just call LogComment, or we will get a call to va() every frame! - GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", glState.currentVBO->name)); + GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", vbo->name)); - // position/normal/tangent/bitangent are always set in case of animation + // position/normal/tangent are always set in case of animation oldFrame = glState.vertexAttribsOldFrame; newFrame = glState.vertexAttribsNewFrame; animated = glState.vertexAnimation; @@ -1693,7 +1658,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, glState.currentVBO->stride_xyz, BUFFER_OFFSET(glState.currentVBO->ofs_xyz + newFrame * glState.currentVBO->size_xyz)); + qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + newFrame * vbo->size_xyz)); glState.vertexAttribPointersSet |= ATTR_POSITION; } @@ -1701,7 +1666,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TEXCOORD )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD0, 2, GL_FLOAT, 0, glState.currentVBO->stride_st, BUFFER_OFFSET(glState.currentVBO->ofs_st)); + qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD0, 2, GL_FLOAT, 0, vbo->stride_st, BUFFER_OFFSET(vbo->ofs_st)); glState.vertexAttribPointersSet |= ATTR_TEXCOORD; } @@ -1709,7 +1674,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTCOORD )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD1, 2, GL_FLOAT, 0, glState.currentVBO->stride_lightmap, BUFFER_OFFSET(glState.currentVBO->ofs_lightmap)); + qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD1, 2, GL_FLOAT, 0, vbo->stride_lightmap, BUFFER_OFFSET(vbo->ofs_lightmap)); glState.vertexAttribPointersSet |= ATTR_LIGHTCOORD; } @@ -1717,7 +1682,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 3, GL_FLOAT, 0, glState.currentVBO->stride_normal, BUFFER_OFFSET(glState.currentVBO->ofs_normal + newFrame * glState.currentVBO->size_normal)); + qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 3, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + newFrame * vbo->size_normal)); glState.vertexAttribPointersSet |= ATTR_NORMAL; } @@ -1726,24 +1691,16 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { 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 + newFrame * glState.currentVBO->size_normal)); // FIXME + qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + newFrame * vbo->size_normal)); // FIXME glState.vertexAttribPointersSet |= ATTR_TANGENT; } - - if((attribBits & ATTR_BITANGENT) && (!(glState.vertexAttribPointersSet & ATTR_BITANGENT) || animated)) - { - 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 + newFrame * glState.currentVBO->size_normal)); // FIXME - glState.vertexAttribPointersSet |= ATTR_BITANGENT; - } #endif if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR)) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_COLOR )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_COLOR, 4, GL_FLOAT, 0, glState.currentVBO->stride_vertexcolor, BUFFER_OFFSET(glState.currentVBO->ofs_vertexcolor)); + qglVertexAttribPointerARB(ATTR_INDEX_COLOR, 4, GL_FLOAT, 0, vbo->stride_vertexcolor, BUFFER_OFFSET(vbo->ofs_vertexcolor)); glState.vertexAttribPointersSet |= ATTR_COLOR; } @@ -1751,7 +1708,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTDIRECTION )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 3, GL_FLOAT, 0, glState.currentVBO->stride_lightdir, BUFFER_OFFSET(glState.currentVBO->ofs_lightdir)); + qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 3, GL_FLOAT, 0, vbo->stride_lightdir, BUFFER_OFFSET(vbo->ofs_lightdir)); glState.vertexAttribPointersSet |= ATTR_LIGHTDIRECTION; } @@ -1759,7 +1716,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION2 )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_POSITION2, 3, GL_FLOAT, 0, glState.currentVBO->stride_xyz, BUFFER_OFFSET(glState.currentVBO->ofs_xyz + oldFrame * glState.currentVBO->size_xyz)); + qglVertexAttribPointerARB(ATTR_INDEX_POSITION2, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + oldFrame * vbo->size_xyz)); glState.vertexAttribPointersSet |= ATTR_POSITION2; } @@ -1767,7 +1724,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL2 )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 3, GL_FLOAT, 0, glState.currentVBO->stride_normal, BUFFER_OFFSET(glState.currentVBO->ofs_normal + oldFrame * glState.currentVBO->size_normal)); + qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 3, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + oldFrame * vbo->size_normal)); glState.vertexAttribPointersSet |= ATTR_NORMAL2; } @@ -1776,17 +1733,9 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) { GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n"); - qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_tangent, BUFFER_OFFSET(glState.currentVBO->ofs_tangent + oldFrame * glState.currentVBO->size_normal)); // FIXME + qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 4, GL_UNSIGNED_BYTE, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + oldFrame * vbo->size_normal)); // FIXME glState.vertexAttribPointersSet |= ATTR_TANGENT2; } - - if((attribBits & ATTR_BITANGENT2) && (!(glState.vertexAttribPointersSet & ATTR_BITANGENT2) || animated)) - { - GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_BITANGENT2 )\n"); - - qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + oldFrame * glState.currentVBO->size_normal)); // FIXME - glState.vertexAttribPointersSet |= ATTR_BITANGENT2; - } #endif } diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 368dd39e..1adfc361 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -116,7 +116,6 @@ typedef struct VBO_s uint32_t ofs_lightdir; #ifdef USE_VERT_TANGENT_SPACE uint32_t ofs_tangent; - uint32_t ofs_bitangent; #endif uint32_t stride_xyz; uint32_t stride_normal; @@ -126,7 +125,6 @@ typedef struct VBO_s uint32_t stride_lightdir; #ifdef USE_VERT_TANGENT_SPACE uint32_t stride_tangent; - uint32_t stride_bitangent; #endif uint32_t size_xyz; uint32_t size_normal; @@ -515,19 +513,17 @@ enum ATTR_INDEX_TEXCOORD0 = 1, ATTR_INDEX_TEXCOORD1 = 2, ATTR_INDEX_TANGENT = 3, - ATTR_INDEX_BITANGENT = 4, - ATTR_INDEX_NORMAL = 5, - ATTR_INDEX_COLOR = 6, - ATTR_INDEX_PAINTCOLOR = 7, - ATTR_INDEX_LIGHTDIRECTION = 8, - ATTR_INDEX_BONE_INDEXES = 9, - ATTR_INDEX_BONE_WEIGHTS = 10, + ATTR_INDEX_NORMAL = 4, + ATTR_INDEX_COLOR = 5, + ATTR_INDEX_PAINTCOLOR = 6, + ATTR_INDEX_LIGHTDIRECTION = 7, + ATTR_INDEX_BONE_INDEXES = 8, + ATTR_INDEX_BONE_WEIGHTS = 9, // GPU vertex animations - ATTR_INDEX_POSITION2 = 11, - ATTR_INDEX_TANGENT2 = 12, - ATTR_INDEX_BITANGENT2 = 13, - ATTR_INDEX_NORMAL2 = 14 + ATTR_INDEX_POSITION2 = 10, + ATTR_INDEX_TANGENT2 = 11, + ATTR_INDEX_NORMAL2 = 12 }; enum @@ -613,26 +609,23 @@ enum ATTR_TEXCOORD = 0x0002, ATTR_LIGHTCOORD = 0x0004, ATTR_TANGENT = 0x0008, - ATTR_BITANGENT = 0x0010, - ATTR_NORMAL = 0x0020, - ATTR_COLOR = 0x0040, - ATTR_PAINTCOLOR = 0x0080, - ATTR_LIGHTDIRECTION = 0x0100, - ATTR_BONE_INDEXES = 0x0200, - ATTR_BONE_WEIGHTS = 0x0400, + ATTR_NORMAL = 0x0010, + ATTR_COLOR = 0x0020, + ATTR_PAINTCOLOR = 0x0040, + ATTR_LIGHTDIRECTION = 0x0080, + ATTR_BONE_INDEXES = 0x0100, + ATTR_BONE_WEIGHTS = 0x0200, // for .md3 interpolation - ATTR_POSITION2 = 0x0800, - ATTR_TANGENT2 = 0x1000, - ATTR_BITANGENT2 = 0x2000, - ATTR_NORMAL2 = 0x4000, + ATTR_POSITION2 = 0x0400, + ATTR_TANGENT2 = 0x0800, + ATTR_NORMAL2 = 0x1000, ATTR_DEFAULT = ATTR_POSITION, ATTR_BITS = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | - ATTR_BITANGENT | ATTR_NORMAL | ATTR_COLOR | ATTR_PAINTCOLOR | @@ -641,7 +634,6 @@ enum ATTR_BONE_WEIGHTS | ATTR_POSITION2 | ATTR_TANGENT2 | - ATTR_BITANGENT2 | ATTR_NORMAL2 }; @@ -986,8 +978,7 @@ typedef struct vec2_t lightmap; vec3_t normal; #ifdef USE_VERT_TANGENT_SPACE - vec3_t tangent; - vec3_t bitangent; + vec4_t tangent; #endif vec3_t lightdir; vec4_t vertexColors; @@ -998,7 +989,7 @@ typedef struct } 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}} #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 @@ -2094,10 +2085,9 @@ 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); + uint8_t normal[SHADER_MAX_VERTEXES][4] QALIGN(16); #ifdef USE_VERT_TANGENT_SPACE - vec4_t tangent[SHADER_MAX_VERTEXES] QALIGN(16); - vec4_t bitangent[SHADER_MAX_VERTEXES] QALIGN(16); + uint8_t tangent[SHADER_MAX_VERTEXES][4] QALIGN(16); #endif vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16); vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16); diff --git a/code/renderergl2/tr_main.c b/code/renderergl2/tr_main.c index a198583c..e87bb8ee 100644 --- a/code/renderergl2/tr_main.c +++ b/code/renderergl2/tr_main.c @@ -454,6 +454,8 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3]) /* do each vertex */ for(i = 0; i < 3; i++) { + vec3_t bitangent, nxt; + // calculate s tangent vector s = dv[i]->st[0] + 10.0f; t = dv[i]->st[1]; @@ -475,12 +477,16 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3]) 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]; + bitangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0]; + bitangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1]; + 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); + VectorSubtract(bitangent, dv[i]->xyz, bitangent); + VectorNormalize(bitangent); + + // store bitangent handedness + CrossProduct(dv[i]->normal, dv[i]->tangent, nxt); + dv[i]->tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f; // debug code //% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i, @@ -1556,7 +1562,8 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128 for ( i = 0; i < tess.numIndexes; i += 3 ) { - vec3_t normal; + vec3_t normal, tNormal; + float len; VectorSubtract( tess.xyz[tess.indexes[i]], tr.viewParms.or.origin, normal ); @@ -1567,7 +1574,11 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128 shortest = len; } - if ( DotProduct( normal, tess.normal[tess.indexes[i]] ) >= 0 ) + tNormal[0] = tess.normal[tess.indexes[i]][0] / 127.5f - 1.0f; + tNormal[1] = tess.normal[tess.indexes[i]][1] / 127.5f - 1.0f; + tNormal[2] = tess.normal[tess.indexes[i]][2] / 127.5f - 1.0f; + + if ( DotProduct( normal, tNormal ) >= 0 ) { numTriangles--; } diff --git a/code/renderergl2/tr_model.c b/code/renderergl2/tr_model.c index a97dd6be..0b1500d6 100644 --- a/code/renderergl2/tr_model.c +++ b/code/renderergl2/tr_model.c @@ -689,11 +689,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, for (i = 0; i < mdvModel->numSurfaces; i++, vboSurf++, surf++) { vec3_t *verts; - vec3_t *normals; vec2_t *texcoords; + uint8_t *normals; #ifdef USE_VERT_TANGENT_SPACE - vec3_t *tangents; - vec3_t *bitangents; + uint8_t *tangents; #endif byte *data; @@ -701,7 +700,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, int ofs_xyz, ofs_normal, ofs_st; #ifdef USE_VERT_TANGENT_SPACE - int ofs_tangent, ofs_bitangent; + int ofs_tangent; #endif dataSize = 0; @@ -710,14 +709,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*verts); ofs_normal = dataSize; - dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals); + dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals) * 4; #ifdef USE_VERT_TANGENT_SPACE ofs_tangent = dataSize; - dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents); - - ofs_bitangent = dataSize; - dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*bitangents); + dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents) * 4; #endif ofs_st = dataSize; @@ -729,18 +725,25 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, normals = (void *)(data + ofs_normal); #ifdef USE_VERT_TANGENT_SPACE tangents = (void *)(data + ofs_tangent); - bitangents = (void *)(data + ofs_bitangent); #endif texcoords = (void *)(data + ofs_st); v = surf->verts; for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ ) { + vec3_t nxt; + + CrossProduct(v->normal, v->tangent, nxt); VectorCopy(v->xyz, verts[j]); - VectorCopy(v->normal, normals[j]); + normals[j*4+0] = (uint8_t)(v->normal[0] * 127.5f + 128.0f); + normals[j*4+1] = (uint8_t)(v->normal[1] * 127.5f + 128.0f); + normals[j*4+2] = (uint8_t)(v->normal[2] * 127.5f + 128.0f); + normals[j*4+3] = 0; #ifdef USE_VERT_TANGENT_SPACE - VectorCopy(v->tangent, tangents[j]); - VectorCopy(v->bitangent, bitangents[j]); + tangents[j*4+0] = (uint8_t)(v->tangent[0] * 127.5f + 128.0f); + tangents[j*4+1] = (uint8_t)(v->tangent[1] * 127.5f + 128.0f); + tangents[j*4+2] = (uint8_t)(v->tangent[2] * 127.5f + 128.0f); + tangents[j*4+3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? 0 : 255; #endif } @@ -765,20 +768,18 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vboSurf->vbo->ofs_normal = ofs_normal; #ifdef USE_VERT_TANGENT_SPACE vboSurf->vbo->ofs_tangent = ofs_tangent; - vboSurf->vbo->ofs_bitangent = ofs_bitangent; #endif vboSurf->vbo->ofs_st = ofs_st; vboSurf->vbo->stride_xyz = sizeof(*verts); - vboSurf->vbo->stride_normal = sizeof(*normals); + vboSurf->vbo->stride_normal = sizeof(*normals) * 4; #ifdef USE_VERT_TANGENT_SPACE - vboSurf->vbo->stride_tangent = sizeof(*tangents); - vboSurf->vbo->stride_bitangent = sizeof(*bitangents); + vboSurf->vbo->stride_tangent = sizeof(*tangents) * 4; #endif vboSurf->vbo->stride_st = sizeof(*st); vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts; - vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts; + vboSurf->vbo->size_normal = sizeof(*normals) * surf->numVerts * 4; ri.Free(data); diff --git a/code/renderergl2/tr_model_iqm.c b/code/renderergl2/tr_model_iqm.c index 44c4a956..d41a8f52 100644 --- a/code/renderergl2/tr_model_iqm.c +++ b/code/renderergl2/tr_model_iqm.c @@ -1024,7 +1024,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { int i; vec4_t *outXYZ; - vec4_t *outNormal; + uint8_t *outNormal; vec2_t (*outTexCoord)[2]; vec4_t *outColor; @@ -1039,7 +1039,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 ); outXYZ = &tess.xyz[tess.numVertexes]; - outNormal = &tess.normal[tess.numVertexes]; + outNormal = &tess.normal[tess.numVertexes][0]; outTexCoord = &tess.texCoords[tess.numVertexes]; outColor = &tess.vertexColors[tess.numVertexes]; @@ -1050,7 +1050,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { // transform vertexes and fill other data for( i = 0; i < surf->num_vertexes; - i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) { + i++, outXYZ++, outNormal+=4, outTexCoord++, outColor++ ) { int j, k; float vtxMat[12]; float nrmMat[9]; @@ -1116,19 +1116,22 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { vtxMat[11]; (*outXYZ)[3] = 1.0f; - (*outNormal)[0] = + (outNormal)[0] = (uint8_t)(( nrmMat[ 0] * data->normals[3*vtx+0] + nrmMat[ 1] * data->normals[3*vtx+1] + - nrmMat[ 2] * data->normals[3*vtx+2]; - (*outNormal)[1] = + nrmMat[ 2] * data->normals[3*vtx+2] + )* 127.5f + 128.0f); + (outNormal)[1] = (uint8_t)(( nrmMat[ 3] * data->normals[3*vtx+0] + nrmMat[ 4] * data->normals[3*vtx+1] + - nrmMat[ 5] * data->normals[3*vtx+2]; - (*outNormal)[2] = + nrmMat[ 5] * data->normals[3*vtx+2] + )* 127.5f + 128.0f); + (outNormal)[2] = (uint8_t)(( nrmMat[ 6] * data->normals[3*vtx+0] + nrmMat[ 7] * data->normals[3*vtx+1] + - nrmMat[ 8] * data->normals[3*vtx+2]; - (*outNormal)[3] = 0.0f; + nrmMat[ 8] * data->normals[3*vtx+2] + )* 127.5f + 128.0f); + (outNormal)[3] = 0; (*outColor)[0] = data->colors[4*vtx+0] / 255.0f; (*outColor)[1] = data->colors[4*vtx+1] / 255.0f; diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 608de9d8..695b42fc 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -1027,7 +1027,6 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input ) vertexAttribs |= ATTR_NORMAL2; #ifdef USE_VERT_TANGENT_SPACE vertexAttribs |= ATTR_TANGENT2; - vertexAttribs |= ATTR_BITANGENT2; #endif } } diff --git a/code/renderergl2/tr_shade_calc.c b/code/renderergl2/tr_shade_calc.c index faab03e5..d77136e7 100644 --- a/code/renderergl2/tr_shade_calc.c +++ b/code/renderergl2/tr_shade_calc.c @@ -116,7 +116,7 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) vec3_t offset; float scale; float *xyz = ( float * ) tess.xyz; - float *normal = ( float * ) tess.normal; + uint8_t *normal = ( uint8_t * ) tess.normal; float *table; if ( ds->deformationWave.frequency == 0 ) @@ -125,7 +125,9 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { - VectorScale( normal, scale, offset ); + offset[0] = (normal[0] / 127.5f - 1.0f) * scale; + offset[1] = (normal[1] / 127.5f - 1.0f) * scale; + offset[2] = (normal[2] / 127.5f - 1.0f) * scale; xyz[0] += offset[0]; xyz[1] += offset[1]; @@ -145,7 +147,9 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) ds->deformationWave.phase + off, ds->deformationWave.frequency ); - VectorScale( normal, scale, offset ); + offset[0] = (normal[0] / 127.5f - 1.0f) * scale; + offset[1] = (normal[1] / 127.5f - 1.0f) * scale; + offset[2] = (normal[2] / 127.5f - 1.0f) * scale; xyz[0] += offset[0]; xyz[1] += offset[1]; @@ -165,25 +169,35 @@ void RB_CalcDeformNormals( deformStage_t *ds ) { int i; float scale; float *xyz = ( float * ) tess.xyz; - float *normal = ( float * ) tess.normal; + uint8_t *normal = ( uint8_t * ) tess.normal; for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { + vec3_t fNormal; + + fNormal[0] = normal[0] / 127.5f - 1.0f; + fNormal[1] = normal[1] / 127.5f - 1.0f; + fNormal[2] = normal[2] / 127.5f - 1.0f; + scale = 0.98f; scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale, tess.shaderTime * ds->deformationWave.frequency ); - normal[ 0 ] += ds->deformationWave.amplitude * scale; + fNormal[ 0 ] += ds->deformationWave.amplitude * scale; scale = 0.98f; scale = R_NoiseGet4f( 100 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale, tess.shaderTime * ds->deformationWave.frequency ); - normal[ 1 ] += ds->deformationWave.amplitude * scale; + fNormal[ 1 ] += ds->deformationWave.amplitude * scale; scale = 0.98f; scale = R_NoiseGet4f( 200 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale, tess.shaderTime * ds->deformationWave.frequency ); - normal[ 2 ] += ds->deformationWave.amplitude * scale; + fNormal[ 2 ] += ds->deformationWave.amplitude * scale; - VectorNormalizeFast( normal ); + VectorNormalizeFast( fNormal ); + + normal[0] = (uint8_t)(fNormal[0] * 127.5f + 128.0f); + normal[1] = (uint8_t)(fNormal[0] * 127.5f + 128.0f); + normal[2] = (uint8_t)(fNormal[0] * 127.5f + 128.0f); } } @@ -197,7 +211,7 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) { int i; const float *st = ( const float * ) tess.texCoords[0]; float *xyz = ( float * ) tess.xyz; - float *normal = ( float * ) tess.normal; + uint8_t *normal = ( uint8_t * ) tess.normal; float now; now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f; @@ -210,9 +224,9 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) { scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight; - xyz[0] += normal[0] * scale; - xyz[1] += normal[1] * scale; - xyz[2] += normal[2] * scale; + xyz[0] += (normal[0] / 127.5f - 1.0f) * scale; + xyz[1] += (normal[1] / 127.5f - 1.0f) * scale; + xyz[2] += (normal[2] / 127.5f - 1.0f) * scale; } } @@ -262,11 +276,17 @@ void DeformText( const char *text ) { float color[4]; float bottom, top; vec3_t mid; + vec3_t fNormal; height[0] = 0; height[1] = 0; height[2] = -1; - CrossProduct( tess.normal[0], height, width ); + + fNormal[0] = tess.normal[0][0] / 127.5f - 1.0f; + fNormal[1] = tess.normal[0][1] / 127.5f - 1.0f; + fNormal[2] = tess.normal[0][2] / 127.5f - 1.0f; + + CrossProduct( fNormal, height, width ); // find the midpoint of the box VectorClear( mid ); diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index 65f0c5dc..308b0f14 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -1947,7 +1947,7 @@ static void ComputeVertexAttribs(void) #ifdef USE_VERT_TANGENT_SPACE if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0)) { - shader.vertexAttribs |= ATTR_BITANGENT | ATTR_TANGENT; + shader.vertexAttribs |= ATTR_TANGENT; } #endif diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 46f1c2fe..8978519c 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -124,10 +124,25 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], // constant normal all the way around VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal ); - VectorCopy(normal, tess.normal[ndx]); - VectorCopy(normal, tess.normal[ndx+1]); - VectorCopy(normal, tess.normal[ndx+2]); - VectorCopy(normal, tess.normal[ndx+3]); + tess.normal[ndx][0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + tess.normal[ndx][1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + tess.normal[ndx][2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + tess.normal[ndx][3] = 0; + + tess.normal[ndx+1][0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + tess.normal[ndx+1][1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + tess.normal[ndx+1][2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + tess.normal[ndx+1][3] = 0; + + tess.normal[ndx+2][0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + tess.normal[ndx+2][1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + tess.normal[ndx+2][2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + tess.normal[ndx+2][3] = 0; + + tess.normal[ndx+3][0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + tess.normal[ndx+3][1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + tess.normal[ndx+3][2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + tess.normal[ndx+3][3] = 0; // standard square texture coordinates VectorSet2(tess.texCoords[ndx ][0], s1, t1); @@ -316,9 +331,10 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn int i; glIndex_t *inIndex; srfVert_t *dv; - float *xyz, *normal, *texCoords, *lightCoords, *lightdir; + float *xyz, *texCoords, *lightCoords, *lightdir; + uint8_t *normal; #ifdef USE_VERT_TANGENT_SPACE - float *tangent, *bitangent; + uint8_t *tangent; #endif glIndex_t *outIndex; float *color; @@ -347,7 +363,12 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn dv = verts; normal = tess.normal[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 ) - VectorCopy(dv->normal, normal); + { + normal[0] = (uint8_t)(dv->normal[0] * 127.5f + 128.0f); + normal[1] = (uint8_t)(dv->normal[1] * 127.5f + 128.0f); + normal[2] = (uint8_t)(dv->normal[2] * 127.5f + 128.0f); + normal[3] = 0; + } } #ifdef USE_VERT_TANGENT_SPACE @@ -356,15 +377,12 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn dv = verts; tangent = tess.tangent[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 ) - VectorCopy(dv->tangent, tangent); - } - - if ( tess.shader->vertexAttribs & ATTR_BITANGENT ) - { - dv = verts; - bitangent = tess.bitangent[ tess.numVertexes ]; - for ( i = 0 ; i < numVerts ; i++, dv++, bitangent+=4 ) - VectorCopy(dv->bitangent, bitangent); + { + tangent[0] = (uint8_t)(dv->tangent[0] * 127.5f + 128.0f); + tangent[1] = (uint8_t)(dv->tangent[1] * 127.5f + 128.0f); + tangent[2] = (uint8_t)(dv->tangent[2] * 127.5f + 128.0f); + tangent[3] = (uint8_t)(dv->tangent[3] * 127.5f + 128.0f); + } } #endif @@ -1127,7 +1145,8 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts); } #endif - float *outXyz, *outNormal; + float *outXyz; + uint8_t *outNormal; mdvVertex_t *newVerts; int vertNum; @@ -1144,8 +1163,16 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { + vec3_t normal; + VectorCopy(newVerts->xyz, outXyz); - VectorCopy(newVerts->normal, outNormal); + VectorCopy(newVerts->normal, normal); + + outNormal[0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + outNormal[1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + outNormal[2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + outNormal[3] = 0; + newVerts++; outXyz += 4; outNormal += 4; @@ -1163,15 +1190,22 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { + vec3_t normal; + VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz); - VectorLerp(newVerts->normal, oldVerts->normal, backlerp, outNormal); - //VectorNormalize(outNormal); + VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal); + VectorNormalize(normal); + + outNormal[0] = (uint8_t)(normal[0] * 127.5f + 128.0f); + outNormal[1] = (uint8_t)(normal[1] * 127.5f + 128.0f); + outNormal[2] = (uint8_t)(normal[2] * 127.5f + 128.0f); + outNormal[3] = 0; + newVerts++; oldVerts++; outXyz += 4; outNormal += 4; } - VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], surf->numVerts); } } @@ -1292,9 +1326,9 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { int i, j; float *xyz; float *texCoords, *lightCoords; - float *normal; + uint8_t *normal; #ifdef USE_VERT_TANGENT_SPACE - float *tangent, *bitangent; + uint8_t *tangent; #endif float *color, *lightdir; srfVert_t *dv; @@ -1382,7 +1416,6 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { normal = tess.normal[numVertexes]; #ifdef USE_VERT_TANGENT_SPACE tangent = tess.tangent[numVertexes]; - bitangent = tess.bitangent[numVertexes]; #endif texCoords = tess.texCoords[numVertexes][0]; lightCoords = tess.texCoords[numVertexes][1]; @@ -1403,22 +1436,22 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { - VectorCopy(dv->normal, normal); + normal[0] = (uint8_t)(dv->normal[0] * 127.5f + 128.0f); + normal[1] = (uint8_t)(dv->normal[1] * 127.5f + 128.0f); + normal[2] = (uint8_t)(dv->normal[2] * 127.5f + 128.0f); + normal[3] = 0; normal += 4; } #ifdef USE_VERT_TANGENT_SPACE if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { - VectorCopy(dv->tangent, tangent); + tangent[0] = (uint8_t)(dv->tangent[0] * 127.5f + 128.0f); + tangent[1] = (uint8_t)(dv->tangent[1] * 127.5f + 128.0f); + tangent[2] = (uint8_t)(dv->tangent[2] * 127.5f + 128.0f); + tangent[3] = (uint8_t)(dv->tangent[3] * 127.5f + 128.0f); tangent += 4; } - - if ( tess.shader->vertexAttribs & ATTR_BITANGENT ) - { - VectorCopy(dv->bitangent, bitangent); - bitangent += 4; - } #endif if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) { diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index a75432f4..8c1a6779 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -142,20 +142,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert if(stateBits & ATTR_NORMAL) { vbo->ofs_normal = dataSize; - dataSize += sizeof(verts[0].normal); + dataSize += sizeof(uint8_t) * 4; } #ifdef USE_VERT_TANGENT_SPACE 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); + dataSize += sizeof(uint8_t) * 4; } #endif @@ -187,7 +181,6 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert vbo->stride_normal = dataSize; #ifdef USE_VERT_TANGENT_SPACE vbo->stride_tangent = dataSize; - vbo->stride_bitangent = dataSize; #endif vbo->stride_st = dataSize; vbo->stride_lightmap = dataSize; @@ -211,23 +204,31 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert // normal if(stateBits & ATTR_NORMAL) { - memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal)); - dataOfs += sizeof(verts[i].normal); + uint8_t *p = data + dataOfs; + + p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f); + p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f); + p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f); + p[3] = 0; + + dataOfs += sizeof(uint8_t) * 4; } #ifdef USE_VERT_TANGENT_SPACE // tangent if(stateBits & ATTR_TANGENT) { - memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent)); - dataOfs += sizeof(verts[i].tangent); - } + vec3_t nxt; + uint8_t *p = data + dataOfs; - // bitangent - if(stateBits & ATTR_BITANGENT) - { - memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent)); - dataOfs += sizeof(verts[i].bitangent); + CrossProduct(verts[i].normal, verts[i].tangent, nxt); + + p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f); + p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f); + p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f); + p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f); + + dataOfs += sizeof(uint8_t) * 4; } #endif @@ -267,18 +268,13 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert if(stateBits & ATTR_NORMAL) { - dataSize += sizeof(verts[0].normal); + dataSize += sizeof(uint8_t) * 4; } #ifdef USE_VERT_TANGENT_SPACE if(stateBits & ATTR_TANGENT) { - dataSize += sizeof(verts[0].tangent); - } - - if(stateBits & ATTR_BITANGENT) - { - dataSize += sizeof(verts[0].bitangent); + dataSize += sizeof(uint8_t) * 4; } #endif @@ -311,7 +307,6 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert vbo->ofs_normal = 0; #ifdef USE_VERT_TANGENT_SPACE vbo->ofs_tangent = 0; - vbo->ofs_bitangent = 0; #endif vbo->ofs_st = 0; vbo->ofs_lightmap = 0; @@ -319,10 +314,9 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert vbo->ofs_lightdir = 0; vbo->stride_xyz = sizeof(verts[0].xyz); - vbo->stride_normal = sizeof(verts[0].normal); + vbo->stride_normal = sizeof(uint8_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - vbo->stride_tangent = sizeof(verts[0].tangent); - vbo->stride_bitangent = sizeof(verts[0].bitangent); + vbo->stride_tangent = sizeof(uint8_t) * 4; #endif vbo->stride_vertexcolor = sizeof(verts[0].vertexColors); vbo->stride_st = sizeof(verts[0].st); @@ -345,8 +339,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert vbo->ofs_normal = dataOfs; for (i = 0; i < numVertexes; i++) { - memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal)); - dataOfs += sizeof(verts[i].normal); + uint8_t *p = data + dataOfs; + + p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f); + p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f); + p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f); + p[3] = 0; + + dataOfs += sizeof(uint8_t) * 4; } } @@ -357,19 +357,17 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert 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); - } - } + vec3_t nxt; + uint8_t *p = data + dataOfs; - // 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); + CrossProduct(verts[i].normal, verts[i].tangent, nxt); + + p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f); + p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f); + p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f); + p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f); + + dataOfs += sizeof(uint8_t) * 4; } } #endif @@ -691,7 +689,6 @@ void R_InitVBOs(void) dataSize += sizeof(tess.normal[0]); #ifdef USE_VERT_TANGENT_SPACE dataSize += sizeof(tess.tangent[0]); - dataSize += sizeof(tess.bitangent[0]); #endif dataSize += sizeof(tess.vertexColors[0]); dataSize += sizeof(tess.texCoords[0][0]) * 2; @@ -706,7 +703,6 @@ void R_InitVBOs(void) 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; @@ -720,7 +716,6 @@ void R_InitVBOs(void) tess.vbo->stride_normal = sizeof(tess.normal[0]); #ifdef USE_VERT_TANGENT_SPACE tess.vbo->stride_tangent = sizeof(tess.tangent[0]); - tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]); #endif tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]); tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2; @@ -878,12 +873,6 @@ void RB_UpdateVBOs(unsigned int attribBits) //ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0])); qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent); } - - if(attribBits & ATTR_BITANGENT) - { - //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); - } #endif if(attribBits & ATTR_COLOR) @@ -905,7 +894,6 @@ void RB_UpdateVBOs(unsigned int attribBits) 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_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_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir);