From 943259f6b4af7bc77429fe44f75e263086dae68a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 3 Nov 2014 19:10:35 -0800 Subject: [PATCH 01/14] OpenGL2: Support half floats for texcoords and vertex colors. --- code/renderergl2/tr_animation.c | 2 +- code/renderergl2/tr_extensions.c | 23 ++++ code/renderergl2/tr_extramath.c | 61 +++++----- code/renderergl2/tr_init.c | 2 + code/renderergl2/tr_local.h | 11 +- code/renderergl2/tr_model.c | 34 ++---- code/renderergl2/tr_model_iqm.c | 4 +- code/renderergl2/tr_shade_calc.c | 2 +- code/renderergl2/tr_surface.c | 20 ++-- code/renderergl2/tr_vbo.c | 186 ++++++++++++++++++------------- 10 files changed, 192 insertions(+), 153 deletions(-) diff --git a/code/renderergl2/tr_animation.c b/code/renderergl2/tr_animation.c index 7153556d88..74226752e3 100644 --- a/code/renderergl2/tr_animation.c +++ b/code/renderergl2/tr_animation.c @@ -412,7 +412,7 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface ) tess.xyz[baseVertex + j][1] = tempVert[1]; tess.xyz[baseVertex + j][2] = tempVert[2]; - tess.normal[baseVertex + j] = R_VaoPackNormal(tempNormal); + R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], tempNormal); tess.texCoords[baseVertex + j][0][0] = v->texCoords[0]; tess.texCoords[baseVertex + j][0][1] = v->texCoords[1]; diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index b4a8db5437..357d4795fb 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -709,4 +709,27 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + // GL_ARB_half_float_vertex + extension = "GL_ARB_half_float_vertex"; + glRefConfig.packedTexcoordDataType = GL_FLOAT; + glRefConfig.packedTexcoordDataSize = sizeof(float) * 2; + glRefConfig.packedColorDataType = GL_FLOAT; + glRefConfig.packedColorDataSize = sizeof(float) * 4; + if( GLimp_HaveExtension( extension ) ) + { + if (r_arb_half_float_vertex->integer) + { + glRefConfig.packedTexcoordDataType = GL_HALF_FLOAT; + glRefConfig.packedTexcoordDataSize = sizeof(uint16_t) * 2; + glRefConfig.packedColorDataType = GL_HALF_FLOAT; + glRefConfig.packedColorDataSize = sizeof(uint16_t) * 4; + } + + ri.Printf(PRINT_ALL, result[r_arb_half_float_vertex->integer ? 1 : 0], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } + } diff --git a/code/renderergl2/tr_extramath.c b/code/renderergl2/tr_extramath.c index b844678f2e..da9a94d25d 100644 --- a/code/renderergl2/tr_extramath.c +++ b/code/renderergl2/tr_extramath.c @@ -199,42 +199,35 @@ int NextPowerOfTwo(int in) return out; } -unsigned short FloatToHalf(float in) -{ - unsigned short out; - - union - { - float f; - unsigned int i; - } f32; - - int sign, inExponent, inFraction; - int outExponent, outFraction; +union f32_u { + float f; + uint32_t i; + struct { + unsigned int fraction:23; + unsigned int exponent:8; + unsigned int sign:1; + } pack; +}; + +union f16_u { + uint16_t i; + struct { + unsigned int fraction:10; + unsigned int exponent:5; + unsigned int sign:1; + } pack; +}; + +uint16_t FloatToHalf(float in) +{ + union f32_u f32; + union f16_u f16; f32.f = in; - sign = (f32.i & 0x80000000) >> 31; - inExponent = (f32.i & 0x7F800000) >> 23; - inFraction = f32.i & 0x007FFFFF; - - outExponent = CLAMP(inExponent - 127, -15, 16) + 15; - - outFraction = 0; - if (outExponent == 0x1F) - { - if (inExponent == 0xFF && inFraction != 0) - outFraction = 0x3FF; - } - else if (outExponent == 0x00) - { - if (inExponent == 0x00 && inFraction != 0) - outFraction = 0x3FF; - } - else - outFraction = inFraction >> 13; - - out = (sign << 15) | (outExponent << 10) | outFraction; + f16.pack.exponent = CLAMP(f32.pack.exponent - 112, 0, 31); + f16.pack.fraction = f32.pack.fraction >> 13; + f16.pack.sign = f32.pack.sign; - return out; + return f16.i; } diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index eb185305ad..e79d735d1a 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -101,6 +101,7 @@ cvar_t *r_ext_multi_draw_arrays; cvar_t *r_ext_framebuffer_object; cvar_t *r_ext_texture_float; cvar_t *r_arb_half_float_pixel; +cvar_t *r_arb_half_float_vertex; cvar_t *r_ext_framebuffer_multisample; cvar_t *r_arb_seamless_cube_map; cvar_t *r_arb_vertex_type_2_10_10_10_rev; @@ -1141,6 +1142,7 @@ void R_Register( void ) r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH); + r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH); r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH); diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 25517272ff..e4a5284ec3 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1416,6 +1416,10 @@ typedef struct { qboolean seamlessCubeMap; GLenum packedNormalDataType; + GLenum packedTexcoordDataType; + GLenum packedColorDataType; + int packedTexcoordDataSize; + int packedColorDataSize; qboolean floatLightmap; qboolean vertexArrayObject; @@ -1713,6 +1717,7 @@ extern cvar_t *r_ext_multi_draw_arrays; extern cvar_t *r_ext_framebuffer_object; extern cvar_t *r_ext_texture_float; extern cvar_t *r_arb_half_float_pixel; +extern cvar_t *r_arb_half_float_vertex; extern cvar_t *r_ext_framebuffer_multisample; extern cvar_t *r_arb_seamless_cube_map; extern cvar_t *r_arb_vertex_type_2_10_10_10_rev; @@ -2180,8 +2185,10 @@ VERTEX BUFFER OBJECTS ============================================================ */ -uint32_t R_VaoPackTangent(vec4_t v); -uint32_t R_VaoPackNormal(vec3_t v); +int R_VaoPackTangent(byte *out, vec4_t v); +int R_VaoPackNormal(byte *out, vec3_t v); +int R_VaoPackTexCoord(byte *out, vec2_t st); +int R_VaoPackColors(byte *out, vec4_t color); void R_VaoUnpackTangent(vec4_t v, uint32_t b); void R_VaoUnpackNormal(vec3_t v, uint32_t b); diff --git a/code/renderergl2/tr_model.c b/code/renderergl2/tr_model.c index fc2017692f..897e202e96 100644 --- a/code/renderergl2/tr_model.c +++ b/code/renderergl2/tr_model.c @@ -674,10 +674,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, { // vertex animation, store texcoords first, then position/normal/tangents offset_st = 0; - offset_xyz = surf->numVerts * sizeof(vec2_t); + offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize; offset_normal = offset_xyz + sizeof(vec3_t); offset_tangent = offset_normal + sizeof(uint32_t); - stride_st = sizeof(vec2_t); + stride_st = glRefConfig.packedTexcoordDataSize; stride_xyz = sizeof(vec3_t) + sizeof(uint32_t); #ifdef USE_VERT_TANGENT_SPACE stride_xyz += sizeof(uint32_t); @@ -691,7 +691,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, // no animation, interleave everything offset_xyz = 0; offset_st = offset_xyz + sizeof(vec3_t); - offset_normal = offset_st + sizeof(vec2_t); + offset_normal = offset_st + glRefConfig.packedTexcoordDataSize; offset_tangent = offset_normal + sizeof(uint32_t); #ifdef USE_VERT_TANGENT_SPACE stride_xyz = offset_tangent + sizeof(uint32_t); @@ -711,8 +711,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, { st = surf->st; for ( j = 0 ; j < surf->numVerts ; j++, st++ ) { - memcpy(data + dataOfs, &st->st, sizeof(vec2_t)); - dataOfs += sizeof(vec2_t); + dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st); } v = surf->verts; @@ -722,16 +721,12 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vec3_t nxt; vec4_t tangent; #endif - uint32_t *p; - // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(vec3_t); // normal - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackNormal(v->normal); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); #ifdef USE_VERT_TANGENT_SPACE CrossProduct(v->normal, v->tangent, nxt); @@ -739,9 +734,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackTangent(tangent); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackTangent(data + dataOfs, tangent); #endif } } @@ -755,20 +748,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vec3_t nxt; vec4_t tangent; #endif - uint32_t *p; - // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(v->xyz); // st - memcpy(data + dataOfs, &st->st, sizeof(vec2_t)); - dataOfs += sizeof(st->st); + dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st); // normal - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackNormal(v->normal); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); #ifdef USE_VERT_TANGENT_SPACE CrossProduct(v->normal, v->tangent, nxt); @@ -776,9 +764,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackTangent(tangent); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackTangent(data + dataOfs, tangent); #endif } } @@ -807,7 +793,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4; vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT; - vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = GL_FLOAT; + vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType; vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; diff --git a/code/renderergl2/tr_model_iqm.c b/code/renderergl2/tr_model_iqm.c index f0b2b38848..376e703092 100644 --- a/code/renderergl2/tr_model_iqm.c +++ b/code/renderergl2/tr_model_iqm.c @@ -1130,7 +1130,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]); normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]); - *outNormal = R_VaoPackNormal(normal); + R_VaoPackNormal((byte *)outNormal++, normal); #ifdef USE_VERT_TANGENT_SPACE tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]); @@ -1138,7 +1138,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]); tangent[3] = data->tangents[4*vtx+3]; - *outTangent++ = R_VaoPackTangent(tangent); + R_VaoPackTangent((byte *)outTangent++, tangent); #endif } diff --git a/code/renderergl2/tr_shade_calc.c b/code/renderergl2/tr_shade_calc.c index c5cc651ea3..bb16bb0d00 100644 --- a/code/renderergl2/tr_shade_calc.c +++ b/code/renderergl2/tr_shade_calc.c @@ -189,7 +189,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) { VectorNormalizeFast( fNormal ); - *normal = R_VaoPackNormal(fNormal); + R_VaoPackNormal((byte *)normal, fNormal); } } diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index d4617ec482..2b0ae0f144 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -88,6 +88,7 @@ RB_AddQuadStampExt */ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) { vec3_t normal; + uint32_t pNormal; int ndx; RB_CHECKOVERFLOW( 4, 6 ); @@ -123,10 +124,11 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], // constant normal all the way around VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal ); + R_VaoPackNormal((byte *)&pNormal, normal); tess.normal[ndx] = tess.normal[ndx+1] = tess.normal[ndx+2] = - tess.normal[ndx+3] = R_VaoPackNormal(normal); + tess.normal[ndx+3] = pNormal; // standard square texture coordinates VectorSet2(tess.texCoords[ndx ][0], s1, t1); @@ -346,7 +348,7 @@ 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++ ) - *normal = R_VaoPackNormal(dv->normal); + R_VaoPackNormal((byte *)normal, dv->normal); } #ifdef USE_VERT_TANGENT_SPACE @@ -355,7 +357,7 @@ 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++ ) - *tangent = R_VaoPackTangent(dv->tangent); + R_VaoPackTangent((byte *)tangent, dv->tangent); } #endif @@ -388,7 +390,7 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn dv = verts; lightdir = &tess.lightdir[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ ) - *lightdir = R_VaoPackNormal(dv->lightdir); + R_VaoPackNormal((byte *)lightdir, dv->lightdir); } #if 0 // nothing even uses vertex dlightbits @@ -1147,7 +1149,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) VectorCopy(newVerts->xyz, outXyz); VectorCopy(newVerts->normal, normal); - *outNormal = R_VaoPackNormal(normal); + R_VaoPackNormal((byte *)outNormal, normal); newVerts++; outXyz += 4; @@ -1172,7 +1174,7 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal); VectorNormalize(normal); - *outNormal = R_VaoPackNormal(normal); + R_VaoPackNormal((byte *)outNormal, normal); newVerts++; oldVerts++; @@ -1410,13 +1412,13 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { - *normal++ = R_VaoPackNormal(dv->normal); + R_VaoPackNormal((byte *)normal++, dv->normal); } #ifdef USE_VERT_TANGENT_SPACE if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { - *tangent++ = R_VaoPackTangent(dv->tangent); + R_VaoPackTangent((byte *)tangent++, dv->tangent); } #endif if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) @@ -1439,7 +1441,7 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION ) { - *lightdir++ = R_VaoPackNormal(dv->lightdir); + R_VaoPackNormal((byte *)lightdir++, dv->lightdir); } //*vDlightBits++ = dlightBits; diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index 981741fba7..8f9ba66fe7 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -44,81 +44,122 @@ union pack8_u { }; -uint32_t R_VaoPackTangent(vec4_t v) +int R_VaoPackTangent(byte *out, vec4_t v) { if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) { - union pack10_u num; + union pack10_u *num = (union pack10_u *)out; - num.pack.x = v[0] * 511.0f; - num.pack.y = v[1] * 511.0f; - num.pack.z = v[2] * 511.0f; - num.pack.w = v[3]; + num->pack.x = v[0] * 511.0f; + num->pack.y = v[1] * 511.0f; + num->pack.z = v[2] * 511.0f; + num->pack.w = v[3]; + } + else + { + union pack8_u *num = (union pack8_u *)out; + + num->pack.x = v[0] * 127.0f; + num->pack.y = v[1] * 127.0f; + num->pack.z = v[2] * 127.0f; + num->pack.w = v[3] * 127.0f; + } + + return 4; +} + +int R_VaoPackNormal(byte *out, vec3_t v) +{ + if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) + { + union pack10_u *num = (union pack10_u *)out; + + num->pack.x = v[0] * 511.0f; + num->pack.y = v[1] * 511.0f; + num->pack.z = v[2] * 511.0f; + num->pack.w = 0; + } + else + { + union pack8_u *num = (union pack8_u *)out; - return num.i; + num->pack.x = v[0] * 127.0f; + num->pack.y = v[1] * 127.0f; + num->pack.z = v[2] * 127.0f; + num->pack.w = 0; + } + + return 4; +} + +int R_VaoPackTexCoord(byte *out, vec2_t st) +{ + if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT) + { + uint16_t *num = (uint16_t *)out; + + *num++ = FloatToHalf(st[0]); + *num++ = FloatToHalf(st[1]); + + return sizeof(*num) * 2; } else { - union pack8_u num; + float *num = (float *)out; - num.pack.x = v[0] * 127.0f; - num.pack.y = v[1] * 127.0f; - num.pack.z = v[2] * 127.0f; - num.pack.w = v[3] * 127.0f; + *num++ = st[0]; + *num++ = st[1]; - return num.i; + return sizeof(*num) * 2; } } -uint32_t R_VaoPackNormal(vec3_t v) +int R_VaoPackColors(byte *out, vec4_t color) { - if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) + if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT) { - union pack10_u num; + uint16_t *num = (uint16_t *)out; - num.pack.x = v[0] * 511.0f; - num.pack.y = v[1] * 511.0f; - num.pack.z = v[2] * 511.0f; - num.pack.w = 0; + *num++ = FloatToHalf(color[0]); + *num++ = FloatToHalf(color[1]); + *num++ = FloatToHalf(color[2]); + *num++ = FloatToHalf(color[3]); - return num.i; + return sizeof(*num) * 4; } else { - union pack8_u num; + float *num = (float *)out; - num.pack.x = v[0] * 127.0f; - num.pack.y = v[1] * 127.0f; - num.pack.z = v[2] * 127.0f; - num.pack.w = 0; + *num++ = color[0]; + *num++ = color[1]; + *num++ = color[2]; + *num++ = color[3]; - return num.i; + return sizeof(*num) * 4; } } + void R_VaoUnpackTangent(vec4_t v, uint32_t b) { if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) { - union pack10_u num; + union pack10_u *num = (union pack10_u *)&b; - num.i = b; - - v[0] = num.pack.x / 511.0f; - v[1] = num.pack.y / 511.0f; - v[2] = num.pack.z / 511.0f; - v[3] = num.pack.w; + v[0] = num->pack.x / 511.0f; + v[1] = num->pack.y / 511.0f; + v[2] = num->pack.z / 511.0f; + v[3] = num->pack.w; } else { - union pack8_u num; - - num.i = b; + union pack8_u *num = (union pack8_u *)&b; - v[0] = num.pack.x / 127.0f; - v[1] = num.pack.y / 127.0f; - v[2] = num.pack.z / 127.0f; - v[3] = num.pack.w / 127.0f; + v[0] = num->pack.x / 127.0f; + v[1] = num->pack.y / 127.0f; + v[2] = num->pack.z / 127.0f; + v[3] = num->pack.w / 127.0f; } } @@ -126,23 +167,19 @@ void R_VaoUnpackNormal(vec3_t v, uint32_t b) { if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) { - union pack10_u num; + union pack10_u *num = (union pack10_u *)&b; - num.i = b; - - v[0] = num.pack.x / 511.0f; - v[1] = num.pack.y / 511.0f; - v[2] = num.pack.z / 511.0f; + v[0] = num->pack.x / 511.0f; + v[1] = num->pack.y / 511.0f; + v[2] = num->pack.z / 511.0f; } else { - union pack8_u num; - - num.i = b; + union pack8_u *num = (union pack8_u *)&b; - v[0] = num.pack.x / 127.0f; - v[1] = num.pack.y / 127.0f; - v[2] = num.pack.z / 127.0f; + v[0] = num->pack.x / 127.0f; + v[1] = num->pack.y / 127.0f; + v[2] = num->pack.z / 127.0f; } } @@ -312,9 +349,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; - vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT; - vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT; - vao->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT; + vao->attribs[ATTR_INDEX_TEXCOORD ].type = glRefConfig.packedTexcoordDataType; + vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = glRefConfig.packedTexcoordDataType; + vao->attribs[ATTR_INDEX_COLOR ].type = glRefConfig.packedColorDataType; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; @@ -330,9 +367,9 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num #ifdef USE_VERT_TANGENT_SPACE vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t); #endif - vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += sizeof(verts[0].st); - vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += sizeof(verts[0].lightmap); - vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += sizeof(verts[0].vertexColors); + vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; + vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; + vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += glRefConfig.packedColorDataSize; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t); vao->attribs[ATTR_INDEX_POSITION ].stride = dataSize; @@ -358,40 +395,29 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num for (i = 0; i < numVertexes; i++) { - uint32_t *p; - // xyz memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz)); dataOfs += sizeof(verts[i].xyz); // normal - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackNormal(verts[i].normal); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal); #ifdef USE_VERT_TANGENT_SPACE // tangent - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackTangent(verts[i].tangent); - dataOfs += sizeof(uint32_t); + dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent); #endif - // vertex texcoords - memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st)); - dataOfs += sizeof(verts[i].st); + // texcoords + dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st); - // feed vertex lightmap texcoords - memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap)); - dataOfs += sizeof(verts[i].lightmap); + // lightmap texcoords + dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap); - // feed vertex colors - memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors)); - dataOfs += sizeof(verts[i].vertexColors); + // colors + dataOfs += R_VaoPackColors(data + dataOfs, verts[i].vertexColors); - // feed vertex light directions - p = (uint32_t *)(data + dataOfs); - *p = R_VaoPackNormal(verts[i].lightdir); - dataOfs += sizeof(uint32_t); + // light directions + dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir); } vao->vertexesSize = dataSize; From 1ad2b413efd36752a3b22ed44cbd442e58a123a9 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 3 Nov 2014 22:18:17 -0800 Subject: [PATCH 02/14] Remove accidentally added increment. --- code/renderergl2/tr_model_iqm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/renderergl2/tr_model_iqm.c b/code/renderergl2/tr_model_iqm.c index 376e703092..3cabca0088 100644 --- a/code/renderergl2/tr_model_iqm.c +++ b/code/renderergl2/tr_model_iqm.c @@ -1130,7 +1130,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]); normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]); - R_VaoPackNormal((byte *)outNormal++, normal); + R_VaoPackNormal((byte *)outNormal, normal); #ifdef USE_VERT_TANGENT_SPACE tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]); From 1d016e6ff5123c06a40c93adb1a5c4df3f697948 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Fri, 7 Nov 2014 21:34:22 -0600 Subject: [PATCH 03/14] Clear window buffer when it's created When starting the game in windowed mode, the window buffer used whatever was on the screen before running the game. Kind of like you could see through the window, but it doesn't update what happens behind it. It makes it look like something is broken or non-responsive. So clear the window opengl buffer to black. Credit to theinvsblman for the code. --- code/sdl/sdl_glimp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c index 1f12fb72bc..df201686b1 100644 --- a/code/sdl/sdl_glimp.c +++ b/code/sdl/sdl_glimp.c @@ -462,6 +462,10 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder) continue; } + qglClearColor( 0, 0, 0, 1 ); + qglClear( GL_COLOR_BUFFER_BIT ); + SDL_GL_SwapWindow( SDL_window ); + SDL_GL_SetSwapInterval( r_swapInterval->integer ); glConfig.colorBits = testColorBits; From b1821e303daa2575cd232cc9923b6eaa1fa485a6 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 10 Nov 2014 21:59:37 -0800 Subject: [PATCH 04/14] OpenGL2: remove lightmap support from generic glsl shader. This path was barely used and doing this compiles fewer shaders. --- code/renderergl2/glsl/generic_fp.glsl | 33 ----- code/renderergl2/glsl/generic_vp.glsl | 9 +- code/renderergl2/tr_glsl.c | 12 -- code/renderergl2/tr_local.h | 8 +- code/renderergl2/tr_shade.c | 12 -- code/renderergl2/tr_shader.c | 167 -------------------------- 6 files changed, 3 insertions(+), 238 deletions(-) diff --git a/code/renderergl2/glsl/generic_fp.glsl b/code/renderergl2/glsl/generic_fp.glsl index aefa33c3fa..50db078547 100644 --- a/code/renderergl2/glsl/generic_fp.glsl +++ b/code/renderergl2/glsl/generic_fp.glsl @@ -1,45 +1,12 @@ uniform sampler2D u_DiffuseMap; -#if defined(USE_LIGHTMAP) -uniform sampler2D u_LightMap; - -uniform int u_Texture1Env; -#endif - varying vec2 var_DiffuseTex; -#if defined(USE_LIGHTMAP) -varying vec2 var_LightTex; -#endif - varying vec4 var_Color; void main() { vec4 color = texture2D(u_DiffuseMap, var_DiffuseTex); -#if defined(USE_LIGHTMAP) - vec4 color2 = texture2D(u_LightMap, var_LightTex); - #if defined(RGBM_LIGHTMAP) - color2.rgb *= color2.a; - color2.a = 1.0; - #endif - - if (u_Texture1Env == TEXENV_MODULATE) - { - color *= color2; - } - else if (u_Texture1Env == TEXENV_ADD) - { - color += color2; - } - else if (u_Texture1Env == TEXENV_REPLACE) - { - color = color2; - } - - //color = color * (u_Texture1Env.xxxx + color2 * u_Texture1Env.z) + color2 * u_Texture1Env.y; -#endif - gl_FragColor = color * var_Color; } diff --git a/code/renderergl2/glsl/generic_vp.glsl b/code/renderergl2/glsl/generic_vp.glsl index 859b436383..bbe08e842c 100644 --- a/code/renderergl2/glsl/generic_vp.glsl +++ b/code/renderergl2/glsl/generic_vp.glsl @@ -9,7 +9,7 @@ attribute vec3 attr_Normal2; attribute vec4 attr_Color; attribute vec4 attr_TexCoord0; -#if defined(USE_LIGHTMAP) || defined(USE_TCGEN) +#if defined(USE_TCGEN) attribute vec4 attr_TexCoord1; #endif @@ -57,9 +57,6 @@ uniform float u_VertexLerp; #endif varying vec2 var_DiffuseTex; -#if defined(USE_LIGHTMAP) -varying vec2 var_LightTex; -#endif varying vec4 var_Color; #if defined(USE_DEFORM_VERTEXES) @@ -230,10 +227,6 @@ void main() var_DiffuseTex = tex; #endif -#if defined(USE_LIGHTMAP) - var_LightTex = attr_TexCoord1.st; -#endif - #if defined(USE_RGBAGEN) var_Color = CalcColor(position, normal); #else diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index 757bab3886..7dfea6a675 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -90,7 +90,6 @@ static uniformInfo_t uniformsInfo[] = { "u_DiffuseTexMatrix", GLSL_VEC4 }, { "u_DiffuseTexOffTurb", GLSL_VEC4 }, - { "u_Texture1Env", GLSL_INT }, { "u_TCGen0", GLSL_INT }, { "u_TCGen0Vector0", GLSL_VEC3 }, @@ -919,12 +918,6 @@ void GLSL_InitGPUShaders(void) if (i & GENERICDEF_USE_RGBAGEN) Q_strcat(extradefines, 1024, "#define USE_RGBAGEN\n"); - if (i & GENERICDEF_USE_LIGHTMAP) - Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n"); - - if (r_hdr->integer && !glRefConfig.floatLightmap) - Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); - if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp)) { ri.Error(ERR_FATAL, "Could not load generic shader!"); @@ -1495,11 +1488,6 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage) shaderAttribs |= GENERICDEF_USE_FOG; } - if (pStage->bundle[1].image[0] && tess.shader->multitextureEnv) - { - shaderAttribs |= GENERICDEF_USE_LIGHTMAP; - } - switch (pStage->rgbGen) { case CGEN_LIGHTING_DIFFUSE: diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index e4a5284ec3..c21b7b4835 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -451,8 +451,6 @@ typedef struct shader_s { float portalRange; // distance to fog out at qboolean isPortal; - int multitextureEnv; // 0, GL_MODULATE, GL_ADD (FIXME: put in stage) - cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED qboolean polygonOffset; // set for decals and other items that must be offset qboolean noMipMaps; // for console fonts, 2D elements, etc. @@ -563,9 +561,8 @@ enum GENERICDEF_USE_VERTEX_ANIMATION = 0x0004, GENERICDEF_USE_FOG = 0x0008, GENERICDEF_USE_RGBAGEN = 0x0010, - GENERICDEF_USE_LIGHTMAP = 0x0020, - GENERICDEF_ALL = 0x003F, - GENERICDEF_COUNT = 0x0040, + GENERICDEF_ALL = 0x001F, + GENERICDEF_COUNT = 0x0020, }; enum @@ -637,7 +634,6 @@ typedef enum UNIFORM_DIFFUSETEXMATRIX, UNIFORM_DIFFUSETEXOFFTURB, - UNIFORM_TEXTURE1ENV, UNIFORM_TCGEN0, UNIFORM_TCGEN0VECTOR0, diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index f70017e402..70b4353ed2 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -1351,16 +1351,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) else if ( pStage->bundle[1].image[0] != 0 ) { R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); - - // - // lightmap/secondary pass - // - if ( r_lightmap->integer ) { - GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, GL_REPLACE); - } else { - GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, tess.shader->multitextureEnv); - } - R_BindAnimatedImageToTMU( &pStage->bundle[1], 1 ); } else @@ -1369,8 +1359,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) // set state // R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); - - GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0); } // diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index a8b13787d4..7ead2e57a7 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -2122,161 +2122,6 @@ static void ComputeVertexAttribs(void) } } -typedef struct { - int blendA; - int blendB; - - int multitextureEnv; - int multitextureBlend; -} collapse_t; - -static collapse_t collapse[] = { - { 0, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, - GL_MODULATE, 0 }, - - { 0, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, - GL_MODULATE, 0 }, - - { GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, - GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR }, - - { GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, - GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR }, - - { GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, - GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR }, - - { GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, - GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR }, - - { 0, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE, - GL_ADD, 0 }, - - { GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE, - GL_ADD, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE }, -#if 0 - { 0, GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_SRCBLEND_SRC_ALPHA, - GL_DECAL, 0 }, -#endif - { -1 } -}; - -/* -================ -CollapseMultitexture - -Attempt to combine two stages into a single multitexture stage -FIXME: I think modulated add + modulated add collapses incorrectly -================= -*/ -static qboolean CollapseMultitexture( void ) { - int abits, bbits; - int i; - textureBundle_t tmpBundle; - - if ( !qglActiveTextureARB ) { - return qfalse; - } - - // make sure both stages are active - if ( !stages[0].active || !stages[1].active ) { - return qfalse; - } - - // on voodoo2, don't combine different tmus - if ( glConfig.driverType == GLDRV_VOODOO ) { - if ( stages[0].bundle[0].image[0]->TMU == - stages[1].bundle[0].image[0]->TMU ) { - return qfalse; - } - } - - abits = stages[0].stateBits; - bbits = stages[1].stateBits; - - // make sure that both stages have identical state other than blend modes - if ( ( abits & ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS | GLS_DEPTHMASK_TRUE ) ) != - ( bbits & ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS | GLS_DEPTHMASK_TRUE ) ) ) { - return qfalse; - } - - abits &= ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); - bbits &= ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); - - // search for a valid multitexture blend function - for ( i = 0; collapse[i].blendA != -1 ; i++ ) { - if ( abits == collapse[i].blendA - && bbits == collapse[i].blendB ) { - break; - } - } - - // nothing found - if ( collapse[i].blendA == -1 ) { - return qfalse; - } - - // GL_ADD is a separate extension - if ( collapse[i].multitextureEnv == GL_ADD && !glConfig.textureEnvAddAvailable ) { - return qfalse; - } - - // make sure waveforms have identical parameters - if ( ( stages[0].rgbGen != stages[1].rgbGen ) || - ( stages[0].alphaGen != stages[1].alphaGen ) ) { - return qfalse; - } - - // an add collapse can only have identity colors - if ( collapse[i].multitextureEnv == GL_ADD && stages[0].rgbGen != CGEN_IDENTITY ) { - return qfalse; - } - - if ( stages[0].rgbGen == CGEN_WAVEFORM ) - { - if ( memcmp( &stages[0].rgbWave, - &stages[1].rgbWave, - sizeof( stages[0].rgbWave ) ) ) - { - return qfalse; - } - } - if ( stages[0].alphaGen == AGEN_WAVEFORM ) - { - if ( memcmp( &stages[0].alphaWave, - &stages[1].alphaWave, - sizeof( stages[0].alphaWave ) ) ) - { - return qfalse; - } - } - - - // make sure that lightmaps are in bundle 1 for 3dfx - if ( stages[0].bundle[0].isLightmap ) - { - tmpBundle = stages[0].bundle[0]; - stages[0].bundle[0] = stages[1].bundle[0]; - stages[0].bundle[1] = tmpBundle; - } - else - { - stages[0].bundle[1] = stages[1].bundle[0]; - } - - // set the new blend state bits - shader.multitextureEnv = collapse[i].multitextureEnv; - stages[0].stateBits &= ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); - stages[0].stateBits |= collapse[i].multitextureBlend; - - // - // move down subsequent shaders - // - memmove( &stages[1], &stages[2], sizeof( stages[0] ) * ( MAX_SHADER_STAGES - 2 ) ); - Com_Memset( &stages[MAX_SHADER_STAGES-1], 0, sizeof( stages[0] ) ); - - return qtrue; -} static void CollapseStagesToLightall(shaderStage_t *diffuse, shaderStage_t *normal, shaderStage_t *specular, shaderStage_t *lightmap, @@ -2607,9 +2452,6 @@ static int CollapseStagesToGLSL(void) numStages++; } - if (numStages == i && i >= 2 && CollapseMultitexture()) - numStages--; - // convert any remaining lightmap stages to a lighting pass with a white texture // only do this with r_sunlightMode non-zero, as it's only for correct shadows. if (r_sunlightMode->integer && shader.numDeforms == 0) @@ -3647,15 +3489,6 @@ void R_ShaderList_f (void) { } else { ri.Printf (PRINT_ALL, " "); } - if ( shader->multitextureEnv == GL_ADD ) { - ri.Printf( PRINT_ALL, "MT(a) " ); - } else if ( shader->multitextureEnv == GL_MODULATE ) { - ri.Printf( PRINT_ALL, "MT(m) " ); - } else if ( shader->multitextureEnv == GL_DECAL ) { - ri.Printf( PRINT_ALL, "MT(d) " ); - } else { - ri.Printf( PRINT_ALL, " " ); - } if ( shader->explicitlyDefined ) { ri.Printf( PRINT_ALL, "E " ); } else { From d9e2184c1a9a1f3115202fb66d3fb29f6753f7ca Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 10 Nov 2014 22:11:36 -0800 Subject: [PATCH 05/14] OpenGL2: Add support for parallax occlusion mapping. --- code/renderergl2/glsl/lightall_fp.glsl | 14 +++++++++++++- code/renderergl2/tr_glsl.c | 4 ++++ opengl2-readme.txt | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index f2da782105..d1155de464 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -100,6 +100,9 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) // best match found (starts with last position 1.0) float bestDepth = 1.0; + // texture depth at best depth + float texDepth = 0.0; + // search front to back for first point inside object for(int i = 0; i < linearSearchSteps - 1; ++i) { @@ -109,11 +112,19 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) if(bestDepth > 0.996) // if no depth found yet if(depth >= t) + { bestDepth = depth; // store best depth + texDepth = t; + } } depth = bestDepth; - + +#if !defined (USE_RELIEFMAP) + float prevDepth = depth - size; + float prevTexDepth = SampleDepth(normalMap, dp + ds * prevDepth); + bestDepth -= size * (prevDepth - prevTexDepth) / (size - texDepth + prevTexDepth); +#else // recurse around first point (depth) for closest match for(int i = 0; i < binarySearchSteps; ++i) { @@ -129,6 +140,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) depth += size; } +#endif return bestDepth; } diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index 7dfea6a675..f526b8c6e2 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -1079,7 +1079,11 @@ void GLSL_InitGPUShaders(void) #endif if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) + { Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); + if (r_parallaxMapping->integer > 1) + Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n"); + } } if (r_specularMapping->integer) diff --git a/opengl2-readme.txt b/opengl2-readme.txt index 167d26f18d..5c4cb60b8a 100644 --- a/opengl2-readme.txt +++ b/opengl2-readme.txt @@ -187,7 +187,8 @@ Cvars for advanced material usage: r_parallaxMapping - Enable parallax mapping for materials that support it. 0 - No. (default) - 1 - Yes. + 1 - Use parallax occlusion mapping. + 2 - Use relief mapping. (slower) r_baseSpecular - Set the specular reflectance of materials which don't include a specular map or From 89b719ec8dc0e02af655c71c03c082a8068febf3 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 14 Nov 2014 01:12:41 -0800 Subject: [PATCH 06/14] OpenGL2: Bit more parallax optimization. --- code/renderergl2/glsl/lightall_fp.glsl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index d1155de464..d118278169 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -103,6 +103,9 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) // texture depth at best depth float texDepth = 0.0; + float prevT = SampleDepth(normalMap, dp); + float prevTexDepth = prevT; + // search front to back for first point inside object for(int i = 0; i < linearSearchSteps - 1; ++i) { @@ -115,15 +118,16 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) { bestDepth = depth; // store best depth texDepth = t; + prevTexDepth = prevT; } + prevT = t; } depth = bestDepth; #if !defined (USE_RELIEFMAP) - float prevDepth = depth - size; - float prevTexDepth = SampleDepth(normalMap, dp + ds * prevDepth); - bestDepth -= size * (prevDepth - prevTexDepth) / (size - texDepth + prevTexDepth); + float div = 1.0 / (1.0 + (prevTexDepth - texDepth) * float(linearSearchSteps)); + bestDepth -= (depth - size - prevTexDepth) * div; #else // recurse around first point (depth) for closest match for(int i = 0; i < binarySearchSteps; ++i) @@ -369,7 +373,7 @@ void main() vec2 texCoords = var_TexCoords.xy; #if defined(USE_PARALLAXMAP) - vec3 offsetDir = normalize(E * tangentToWorld); + vec3 offsetDir = viewDir * tangentToWorld; offsetDir.xy *= -u_NormalScale.a / offsetDir.z; From 22bcda018b253d1d956dcaa9169e6febfbd81861 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 16 Nov 2014 11:53:12 -0600 Subject: [PATCH 07/14] Correct a few OpenGL variable types Affectly no change for desktop OpenGL. Use correct types for OpenGLES support. --- code/renderergl1/tr_backend.c | 2 +- code/renderergl1/tr_shade.c | 4 ++-- code/renderergl1/tr_surface.c | 3 ++- code/renderergl2/tr_backend.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/renderergl1/tr_backend.c b/code/renderergl1/tr_backend.c index 788f780165..a11224561c 100644 --- a/code/renderergl1/tr_backend.c +++ b/code/renderergl1/tr_backend.c @@ -474,7 +474,7 @@ void RB_BeginDrawingView (void) { // clip to the plane of the portal if ( backEnd.viewParms.isPortal ) { float plane[4]; - double plane2[4]; + GLdouble plane2[4]; plane[0] = backEnd.viewParms.portalPlane.normal[0]; plane[1] = backEnd.viewParms.portalPlane.normal[1]; diff --git a/code/renderergl1/tr_shade.c b/code/renderergl1/tr_shade.c index 08648b2e8a..9bdf1e3953 100644 --- a/code/renderergl1/tr_shade.c +++ b/code/renderergl1/tr_shade.c @@ -421,7 +421,7 @@ static void ProjectDlightTexture_altivec( void ) { byte clipBits[SHADER_MAX_VERTEXES]; float texCoordsArray[SHADER_MAX_VERTEXES][2]; byte colorArray[SHADER_MAX_VERTEXES][4]; - unsigned hitIndexes[SHADER_MAX_INDEXES]; + glIndex_t hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; float scale; float radius; @@ -593,7 +593,7 @@ static void ProjectDlightTexture_scalar( void ) { byte clipBits[SHADER_MAX_VERTEXES]; float texCoordsArray[SHADER_MAX_VERTEXES][2]; byte colorArray[SHADER_MAX_VERTEXES][4]; - unsigned hitIndexes[SHADER_MAX_INDEXES]; + glIndex_t hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; float scale; float radius; diff --git a/code/renderergl1/tr_surface.c b/code/renderergl1/tr_surface.c index 1879fe2c02..d318df1db5 100644 --- a/code/renderergl1/tr_surface.c +++ b/code/renderergl1/tr_surface.c @@ -907,7 +907,8 @@ RB_SurfaceFace */ static void RB_SurfaceFace( srfSurfaceFace_t *surf ) { int i; - unsigned *indices, *tessIndexes; + unsigned *indices; + glIndex_t *tessIndexes; float *v; float *normal; int ndx; diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index bb5e57e7be..3b297b8d75 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -548,7 +548,7 @@ void RB_BeginDrawingView (void) { if ( backEnd.viewParms.isPortal ) { #if 0 float plane[4]; - double plane2[4]; + GLdouble plane2[4]; plane[0] = backEnd.viewParms.portalPlane.normal[0]; plane[1] = backEnd.viewParms.portalPlane.normal[1]; From 60d28722effd3447538650f607a937c333c08886 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 16 Nov 2014 11:58:52 -0600 Subject: [PATCH 08/14] Remove unfinished OpenGL display list code It seems unlikely anyone is going to do anything with this aside from stub it out in OpenGLES ports. --- code/renderergl1/tr_local.h | 6 ------ code/renderergl1/tr_surface.c | 9 +-------- code/renderergl2/tr_local.h | 6 ------ code/renderergl2/tr_surface.c | 7 ------- 4 files changed, 1 insertion(+), 27 deletions(-) diff --git a/code/renderergl1/tr_local.h b/code/renderergl1/tr_local.h index c0c62f03f1..47d8ca81ee 100644 --- a/code/renderergl1/tr_local.h +++ b/code/renderergl1/tr_local.h @@ -477,7 +477,6 @@ typedef enum { SF_IQM, SF_FLARE, SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity - SF_DISPLAY_LIST, SF_NUM_SURFACE_TYPES, SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int ) @@ -503,11 +502,6 @@ typedef struct srfPoly_s { polyVert_t *verts; } srfPoly_t; -typedef struct srfDisplayList_s { - surfaceType_t surfaceType; - int listNum; -} srfDisplayList_t; - typedef struct srfFlare_s { surfaceType_t surfaceType; diff --git a/code/renderergl1/tr_surface.c b/code/renderergl1/tr_surface.c index d318df1db5..79852f051d 100644 --- a/code/renderergl1/tr_surface.c +++ b/code/renderergl1/tr_surface.c @@ -1218,12 +1218,6 @@ static void RB_SurfaceFlare(srfFlare_t *surf) RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal); } -static void RB_SurfaceDisplayList( srfDisplayList_t *surf ) { - // all apropriate state must be set in RB_BeginSurface - // this isn't implemented yet... - qglCallList( surf->listNum ); -} - static void RB_SurfaceSkip( void *surf ) { } @@ -1239,6 +1233,5 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = { (void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR, (void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM, (void(*)(void*))RB_SurfaceFlare, // SF_FLARE, - (void(*)(void*))RB_SurfaceEntity, // SF_ENTITY - (void(*)(void*))RB_SurfaceDisplayList // SF_DISPLAY_LIST + (void(*)(void*))RB_SurfaceEntity // SF_ENTITY }; diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index c21b7b4835..a346a8c70c 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -848,7 +848,6 @@ typedef enum { SF_IQM, SF_FLARE, SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity - SF_DISPLAY_LIST, SF_VAO_MESH, SF_VAO_MDVMESH, @@ -877,11 +876,6 @@ typedef struct srfPoly_s { polyVert_t *verts; } srfPoly_t; -typedef struct srfDisplayList_s { - surfaceType_t surfaceType; - int listNum; -} srfDisplayList_t; - typedef struct srfFlare_s { surfaceType_t surfaceType; diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 2b0ae0f144..872208e468 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -1658,12 +1658,6 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface) glState.vertexAnimation = qfalse; } -static void RB_SurfaceDisplayList( srfDisplayList_t *surf ) { - // all apropriate state must be set in RB_BeginSurface - // this isn't implemented yet... - qglCallList( surf->listNum ); -} - static void RB_SurfaceSkip( void *surf ) { } @@ -1680,7 +1674,6 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = { (void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM, (void(*)(void*))RB_SurfaceFlare, // SF_FLARE, (void(*)(void*))RB_SurfaceEntity, // SF_ENTITY - (void(*)(void*))RB_SurfaceDisplayList, // SF_DISPLAY_LIST (void(*)(void*))RB_SurfaceVaoMesh, // SF_VAO_MESH, (void(*)(void*))RB_SurfaceVaoMdvMesh, // SF_VAO_MDVMESH }; From d06deb41c80159b7d16bee77a7cdd1b197d610e2 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 16 Nov 2014 12:47:49 -0600 Subject: [PATCH 09/14] Don't set fog image border color GL1's R_CreateImage sets GL texture to 0 before it ends, so border color is not applied to the fog image. GL_CLAMP is not used for fog image (in either renderer), so it would presumably not be used even if applied to the fog image. --- code/renderergl1/tr_image.c | 12 ------------ code/renderergl2/tr_image.c | 11 ----------- 2 files changed, 23 deletions(-) diff --git a/code/renderergl1/tr_image.c b/code/renderergl1/tr_image.c index f8a8899172..39f3e57f35 100644 --- a/code/renderergl1/tr_image.c +++ b/code/renderergl1/tr_image.c @@ -899,7 +899,6 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); - // FIXME: this stops fog from setting border color? glState.currenttextures[glState.currenttmu] = 0; qglBindTexture( GL_TEXTURE_2D, 0 ); @@ -1168,7 +1167,6 @@ static void R_CreateFogImage( void ) { int x,y; byte *data; float d; - float borderColor[4]; data = ri.Hunk_AllocateTempMemory( FOG_S * FOG_T * 4 ); @@ -1183,18 +1181,8 @@ static void R_CreateFogImage( void ) { data[(y*FOG_S+x)*4+3] = 255*d; } } - // standard openGL clamping doesn't really do what we want -- it includes - // the border color at the edges. OpenGL 1.2 has clamp-to-edge, which does - // what we want. tr.fogImage = R_CreateImage("*fog", (byte *)data, FOG_S, FOG_T, IMGTYPE_COLORALPHA, IMGFLAG_CLAMPTOEDGE, 0 ); ri.Hunk_FreeTempMemory( data ); - - borderColor[0] = 1.0; - borderColor[1] = 1.0; - borderColor[2] = 1.0; - borderColor[3] = 1; - - qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor ); } /* diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index cb42ee052f..e95b559f5c 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2641,7 +2641,6 @@ static void R_CreateFogImage( void ) { int x,y; byte *data; float d; - float borderColor[4]; data = ri.Hunk_AllocateTempMemory( FOG_S * FOG_T * 4 ); @@ -2656,18 +2655,8 @@ static void R_CreateFogImage( void ) { data[(y*FOG_S+x)*4+3] = 255*d; } } - // standard openGL clamping doesn't really do what we want -- it includes - // the border color at the edges. OpenGL 1.2 has clamp-to-edge, which does - // what we want. tr.fogImage = R_CreateImage("*fog", (byte *)data, FOG_S, FOG_T, IMGTYPE_COLORALPHA, IMGFLAG_CLAMPTOEDGE, 0 ); ri.Hunk_FreeTempMemory( data ); - - borderColor[0] = 1.0; - borderColor[1] = 1.0; - borderColor[2] = 1.0; - borderColor[3] = 1; - - qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor ); } /* From c787cf3aef0daa32478f90a5f43fb794ff6b5313 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 16 Nov 2014 21:21:15 -0600 Subject: [PATCH 10/14] Fix stencil shadows not drawing if has 500 or more vertexes Stencil shadow is not drawn if a mesh, or multiple meshes with the same entity and shader, have more than 500 vertexes. The issue is caused by storing the projected positions in the tess vertex buffer. Use a new array instead. --- code/renderergl1/tr_shadows.c | 20 ++++++++------------ code/renderergl2/tr_shadows.c | 20 ++++++++------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/code/renderergl1/tr_shadows.c b/code/renderergl1/tr_shadows.c index 3582ae4479..13fbfdf74e 100644 --- a/code/renderergl1/tr_shadows.c +++ b/code/renderergl1/tr_shadows.c @@ -44,6 +44,7 @@ typedef struct { static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS]; static int numEdgeDefs[SHADER_MAX_VERTEXES]; static int facing[SHADER_MAX_INDEXES/3]; +static vec3_t shadowXyz[SHADER_MAX_VERTEXES]; void R_AddEdgeDef( int i1, int i2, int facing ) { int c; @@ -80,13 +81,13 @@ void R_RenderShadowEdges( void ) { qglBegin( GL_TRIANGLE_STRIP ); qglVertex3fv( tess.xyz[ i1 ] ); - qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i1 ] ); qglVertex3fv( tess.xyz[ i2 ] ); - qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i2 ] ); qglVertex3fv( tess.xyz[ i3 ] ); - qglVertex3fv( tess.xyz[ i3 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i3 ] ); qglVertex3fv( tess.xyz[ i1 ] ); - qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i1 ] ); qglEnd(); } #else @@ -126,9 +127,9 @@ void R_RenderShadowEdges( void ) { if ( hit[ 1 ] == 0 ) { qglBegin( GL_TRIANGLE_STRIP ); qglVertex3fv( tess.xyz[ i ] ); - qglVertex3fv( tess.xyz[ i + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i ] ); qglVertex3fv( tess.xyz[ i2 ] ); - qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i2 ] ); qglEnd(); c_edges++; } else { @@ -157,11 +158,6 @@ void RB_ShadowTessEnd( void ) { vec3_t lightDir; GLboolean rgba[4]; - // we can only do this if we have enough space in the vertex buffers - if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) { - return; - } - if ( glConfig.stencilBits < 4 ) { return; } @@ -170,7 +166,7 @@ void RB_ShadowTessEnd( void ) { // project vertexes away from light direction for ( i = 0 ; i < tess.numVertexes ; i++ ) { - VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] ); + VectorMA( tess.xyz[i], -512, lightDir, shadowXyz[i] ); } // decide which triangles face the light diff --git a/code/renderergl2/tr_shadows.c b/code/renderergl2/tr_shadows.c index 3582ae4479..13fbfdf74e 100644 --- a/code/renderergl2/tr_shadows.c +++ b/code/renderergl2/tr_shadows.c @@ -44,6 +44,7 @@ typedef struct { static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS]; static int numEdgeDefs[SHADER_MAX_VERTEXES]; static int facing[SHADER_MAX_INDEXES/3]; +static vec3_t shadowXyz[SHADER_MAX_VERTEXES]; void R_AddEdgeDef( int i1, int i2, int facing ) { int c; @@ -80,13 +81,13 @@ void R_RenderShadowEdges( void ) { qglBegin( GL_TRIANGLE_STRIP ); qglVertex3fv( tess.xyz[ i1 ] ); - qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i1 ] ); qglVertex3fv( tess.xyz[ i2 ] ); - qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i2 ] ); qglVertex3fv( tess.xyz[ i3 ] ); - qglVertex3fv( tess.xyz[ i3 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i3 ] ); qglVertex3fv( tess.xyz[ i1 ] ); - qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i1 ] ); qglEnd(); } #else @@ -126,9 +127,9 @@ void R_RenderShadowEdges( void ) { if ( hit[ 1 ] == 0 ) { qglBegin( GL_TRIANGLE_STRIP ); qglVertex3fv( tess.xyz[ i ] ); - qglVertex3fv( tess.xyz[ i + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i ] ); qglVertex3fv( tess.xyz[ i2 ] ); - qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] ); + qglVertex3fv( shadowXyz[ i2 ] ); qglEnd(); c_edges++; } else { @@ -157,11 +158,6 @@ void RB_ShadowTessEnd( void ) { vec3_t lightDir; GLboolean rgba[4]; - // we can only do this if we have enough space in the vertex buffers - if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) { - return; - } - if ( glConfig.stencilBits < 4 ) { return; } @@ -170,7 +166,7 @@ void RB_ShadowTessEnd( void ) { // project vertexes away from light direction for ( i = 0 ; i < tess.numVertexes ; i++ ) { - VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] ); + VectorMA( tess.xyz[i], -512, lightDir, shadowXyz[i] ); } // decide which triangles face the light From fd23249357c3efee4d7b1661dab229445191088a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 21 Nov 2014 16:12:53 -0800 Subject: [PATCH 11/14] OpenGL2: Ensure tess VAO is bound before using it. --- code/renderergl2/tr_surface.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 872208e468..c5b1b0f8d3 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -91,6 +91,8 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], uint32_t pNormal; int ndx; + RB_CheckVao(tess.vao); + RB_CHECKOVERFLOW( 4, 6 ); ndx = tess.numVertexes; @@ -283,6 +285,8 @@ static void RB_SurfacePolychain( srfPoly_t *p ) { int i; int numv; + RB_CheckVao(tess.vao); + RB_CHECKOVERFLOW( p->numVerts, 3*(p->numVerts - 2) ); // fan triangles into the tess array @@ -626,6 +630,8 @@ static void DoRailCore( const vec3_t start, const vec3_t end, const vec3_t up, f int vbase; float t = len / 256.0f; + RB_CheckVao(tess.vao); + RB_CHECKOVERFLOW( 4, 6 ); vbase = tess.numVertexes; @@ -707,6 +713,8 @@ static void DoRailDiscs( int numSegs, const vec3_t start, const vec3_t dir, cons } } + RB_CheckVao(tess.vao); + for ( i = 0; i < numSegs; i++ ) { int j; @@ -1218,6 +1226,8 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) { backlerp = backEnd.currentEntity->e.backlerp; } + RB_CheckVao(tess.vao); + RB_CHECKOVERFLOW( surface->numVerts, surface->numIndexes ); LerpMeshVertexes (surface, backlerp); @@ -1325,6 +1335,8 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { return; } + RB_CheckVao(tess.vao); + dlightBits = srf->dlightBits; tess.dlightBits |= dlightBits; From 8c7fedb1feb5f3b046c6e640d8f4da1ad8ec7477 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Sun, 30 Nov 2014 21:50:33 -0800 Subject: [PATCH 12/14] OpenGL2: Fix face culling. --- code/renderergl2/tr_backend.c | 3 --- code/renderergl2/tr_init.c | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 3b297b8d75..e74f8f2480 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -538,9 +538,6 @@ void RB_BeginDrawingView (void) { backEnd.isHyperspace = qfalse; } - glState.faceCulling = -1; // force face culling to set next time - glState.faceCullFront = -1; // same as above - // we will only draw a sun if there was sky rendered in this view backEnd.skyRenderedThisView = qfalse; diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index e79d735d1a..525dfba0cc 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -946,6 +946,8 @@ void GL_SetDefaultState( void ) // glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE; glState.storedGlState = 0; + glState.faceCulling = CT_TWO_SIDED; + glState.faceCullFront = qtrue; glState.currentProgram = 0; qglUseProgramObjectARB(0); From 08ddb99732444a33bc5d5616116f4ee49f57de5f Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Mon, 1 Dec 2014 20:23:22 -0600 Subject: [PATCH 13/14] Fix saving/loading glyph 255 in RegisterFont The glyph for character 255 (lower case y with two dots above it) was rendered, but it's glyph information was not stored in fontInfo_t and not saved into .dat file (including the ones in Team Arena). Attempting to load it from existing .dat font files is fine because shader name is "" and gets 0 handle. The handle was already 0 anyway. --- code/renderercommon/tr_font.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/code/renderercommon/tr_font.c b/code/renderercommon/tr_font.c index 4b641bac4a..0f89d5ad68 100644 --- a/code/renderercommon/tr_font.c +++ b/code/renderercommon/tr_font.c @@ -397,7 +397,7 @@ void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { // Com_Memcpy(font, faceData, sizeof(fontInfo_t)); Q_strncpyz(font->name, name, sizeof(font->name)); - for (i = GLYPH_START; i < GLYPH_END; i++) { + for (i = GLYPH_START; i <= GLYPH_END; i++) { font->glyphs[i].glyph = RE_RegisterShaderNoMip(font->glyphs[i].shaderName); } Com_Memcpy(®isteredFont[registeredFontCount++], font, sizeof(fontInfo_t)); @@ -445,7 +445,7 @@ void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { maxHeight = 0; - for (i = GLYPH_START; i < GLYPH_END; i++) { + for (i = GLYPH_START; i <= GLYPH_END; i++) { RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qtrue); } @@ -455,11 +455,16 @@ void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { lastStart = i; imageNumber = 0; - while ( i <= GLYPH_END ) { + while ( i <= GLYPH_END + 1 ) { - glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qfalse); + if ( i == GLYPH_END + 1 ) { + // upload/save current image buffer + xOut = yOut = -1; + } else { + glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qfalse); + } - if (xOut == -1 || yOut == -1 || i == GLYPH_END) { + if (xOut == -1 || yOut == -1) { // ran out of room // we need to create an image from the bitmap, set all the handles in the glyphs to this point // @@ -504,7 +509,7 @@ void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { xOut = 0; yOut = 0; ri.Free(imageBuff); - if(i == GLYPH_END) + if ( i == GLYPH_END + 1 ) i++; } else { Com_Memcpy(&font->glyphs[i], glyph, sizeof(glyphInfo_t)); From b21a59af8c1cc58947f8b5ee29e55b14b8321238 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Mon, 1 Dec 2014 21:53:06 -0600 Subject: [PATCH 14/14] Fix negative glyph index in Team Arena text functions Team Arena's text functions cast signed char values to int and use as an array index. This works fine for values 0 to 127, but not for -128 to -1 which are a negative array index. Instead use "character & 255" like client and original Q3 ui/cgame string drawing code. --- code/cgame/cg_draw.c | 12 +++--------- code/cgame/cg_newdraw.c | 2 +- code/ui/ui_main.c | 12 ++++++------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index 178c967926..e9c7d4da84 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -49,8 +49,6 @@ int CG_Text_Width(const char *text, float scale, int limit) { float out; glyphInfo_t *glyph; float useScale; -// FIXME: see ui_main.c, same problem -// const unsigned char *s = text; const char *s = text; fontInfo_t *font = &cgDC.Assets.textFont; if (scale <= cg_smallFont.value) { @@ -71,7 +69,7 @@ int CG_Text_Width(const char *text, float scale, int limit) { s += 2; continue; } else { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; out += glyph->xSkip; s++; count++; @@ -86,8 +84,6 @@ int CG_Text_Height(const char *text, float scale, int limit) { float max; glyphInfo_t *glyph; float useScale; -// TTimo: FIXME -// const unsigned char *s = text; const char *s = text; fontInfo_t *font = &cgDC.Assets.textFont; if (scale <= cg_smallFont.value) { @@ -108,7 +104,7 @@ int CG_Text_Height(const char *text, float scale, int limit) { s += 2; continue; } else { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; if (max < glyph->height) { max = glyph->height; } @@ -141,8 +137,6 @@ void CG_Text_Paint(float x, float y, float scale, vec4_t color, const char *text } useScale = scale * font->glyphScale; if (text) { -// TTimo: FIXME -// const unsigned char *s = text; const char *s = text; trap_R_SetColor( color ); memcpy(&newColor[0], &color[0], sizeof(vec4_t)); @@ -152,7 +146,7 @@ void CG_Text_Paint(float x, float y, float scale, vec4_t color, const char *text } count = 0; while (s && *s && count < len) { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height); if ( Q_IsColorString( s ) ) { diff --git a/code/cgame/cg_newdraw.c b/code/cgame/cg_newdraw.c index 986a40d2e4..dc3ed42ad9 100644 --- a/code/cgame/cg_newdraw.c +++ b/code/cgame/cg_newdraw.c @@ -1214,7 +1214,7 @@ static void CG_Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4 } count = 0; while (s && *s && count < len) { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; if ( Q_IsColorString( s ) ) { memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); newColor[3] = color[3]; diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index 6cdaa12c84..7d06e18014 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -284,7 +284,7 @@ int Text_Width(const char *text, float scale, int limit) { s += 2; continue; } else { - glyph = &font->glyphs[(int)*s]; + glyph = &font->glyphs[*s & 255]; out += glyph->xSkip; s++; count++; @@ -319,7 +319,7 @@ int Text_Height(const char *text, float scale, int limit) { s += 2; continue; } else { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; if (max < glyph->height) { max = glyph->height; } @@ -361,7 +361,7 @@ void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, f } count = 0; while (s && *s && count < len) { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height); if ( Q_IsColorString( s ) ) { @@ -429,9 +429,9 @@ void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const cha len = limit; } count = 0; - glyph2 = &font->glyphs[ (int) cursor]; + glyph2 = &font->glyphs[cursor & 255]; while (s && *s && count < len) { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height); if ( Q_IsColorString( s ) ) { @@ -528,7 +528,7 @@ static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t } count = 0; while (s && *s && count < len) { - glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + glyph = &font->glyphs[*s & 255]; if ( Q_IsColorString( s ) ) { memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); newColor[3] = color[3];