diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index 178c9679..e9c7d4da 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 986a40d2..dc3ed42a 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/renderercommon/tr_font.c b/code/renderercommon/tr_font.c index 4b641bac..0f89d5ad 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)); diff --git a/code/renderergl1/tr_backend.c b/code/renderergl1/tr_backend.c index 8f4939bb..22392396 100644 --- a/code/renderergl1/tr_backend.c +++ b/code/renderergl1/tr_backend.c @@ -481,7 +481,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_image.c b/code/renderergl1/tr_image.c index f8a88991..39f3e57f 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/renderergl1/tr_local.h b/code/renderergl1/tr_local.h index 5d0fba27..b1028527 100644 --- a/code/renderergl1/tr_local.h +++ b/code/renderergl1/tr_local.h @@ -478,7 +478,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 ) @@ -504,11 +503,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_shade.c b/code/renderergl1/tr_shade.c index 84645ea9..96a4cfdb 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_shadows.c b/code/renderergl1/tr_shadows.c index 3582ae44..13fbfdf7 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/renderergl1/tr_surface.c b/code/renderergl1/tr_surface.c index 6cd3320d..1948063c 100644 --- a/code/renderergl1/tr_surface.c +++ b/code/renderergl1/tr_surface.c @@ -1485,7 +1485,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; @@ -1821,12 +1822,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 ) { } @@ -1842,6 +1837,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/glsl/generic_fp.glsl b/code/renderergl2/glsl/generic_fp.glsl index aefa33c3..50db0785 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 859b4363..bbe08e84 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/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index f2da7821..d1182781 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -100,6 +100,12 @@ 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; + + 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) { @@ -109,11 +115,20 @@ 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; + prevTexDepth = prevT; + } + prevT = t; } depth = bestDepth; - + +#if !defined (USE_RELIEFMAP) + 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) { @@ -129,6 +144,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) depth += size; } +#endif return bestDepth; } @@ -357,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; diff --git a/code/renderergl2/tr_animation.c b/code/renderergl2/tr_animation.c index 7153556d..74226752 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_backend.c b/code/renderergl2/tr_backend.c index a06d5e5d..5229c3ac 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -544,9 +544,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; @@ -554,7 +551,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]; diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index 61f01551..9fd7745f 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -711,4 +711,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 b844678f..da9a94d2 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; +union f32_u { + float f; + uint32_t i; + struct { + unsigned int fraction:23; + unsigned int exponent:8; + unsigned int sign:1; + } pack; +}; - int sign, inExponent, inFraction; - int outExponent, outFraction; +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; + f16.pack.exponent = CLAMP(f32.pack.exponent - 112, 0, 31); + f16.pack.fraction = f32.pack.fraction >> 13; + f16.pack.sign = f32.pack.sign; - 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; - - return out; + return f16.i; } diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index 757bab38..f526b8c6 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!"); @@ -1086,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) @@ -1495,11 +1492,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_image.c b/code/renderergl2/tr_image.c index cb42ee05..e95b559f 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 ); } /* diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index 13915fea..133e13c5 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -104,6 +104,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; @@ -952,6 +953,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); @@ -1152,6 +1155,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 2c3b13de..40e3df63 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -452,8 +452,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. @@ -564,9 +562,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 @@ -638,7 +635,6 @@ typedef enum UNIFORM_DIFFUSETEXMATRIX, UNIFORM_DIFFUSETEXOFFTURB, - UNIFORM_TEXTURE1ENV, UNIFORM_TCGEN0, UNIFORM_TCGEN0VECTOR0, @@ -853,7 +849,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, @@ -882,11 +877,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; @@ -1412,6 +1402,10 @@ typedef struct { qboolean seamlessCubeMap; GLenum packedNormalDataType; + GLenum packedTexcoordDataType; + GLenum packedColorDataType; + int packedTexcoordDataSize; + int packedColorDataSize; qboolean floatLightmap; qboolean vertexArrayObject; @@ -1713,6 +1707,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 +2175,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 fc201769..897e202e 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 f0b2b388..3cabca00 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.c b/code/renderergl2/tr_shade.c index 06136fd7..c931ccf4 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -1377,16 +1377,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 @@ -1395,8 +1385,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_shade_calc.c b/code/renderergl2/tr_shade_calc.c index d2c27dd8..d0419954 100644 --- a/code/renderergl2/tr_shade_calc.c +++ b/code/renderergl2/tr_shade_calc.c @@ -191,7 +191,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) { VectorNormalizeFast( fNormal ); - *normal = R_VaoPackNormal(fNormal); + R_VaoPackNormal((byte *)normal, fNormal); } } diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index 9d178b35..dee778fd 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -2132,161 +2132,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, @@ -2617,9 +2462,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) @@ -3688,15 +3530,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 { diff --git a/code/renderergl2/tr_shadows.c b/code/renderergl2/tr_shadows.c index 3582ae44..13fbfdf7 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 diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 0ac8ea3c..6473e6da 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -88,8 +88,11 @@ 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_CheckVao(tess.vao); + RB_CHECKOVERFLOW( 4, 6 ); ndx = tess.numVertexes; @@ -123,10 +126,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); @@ -289,6 +293,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 @@ -354,7 +360,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 @@ -363,7 +369,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 @@ -396,7 +402,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 @@ -1206,6 +1212,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; @@ -1287,6 +1295,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; @@ -1729,7 +1739,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; @@ -1754,7 +1764,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++; @@ -1798,6 +1808,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); @@ -1905,6 +1917,8 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { return; } + RB_CheckVao(tess.vao); + dlightBits = srf->dlightBits; tess.dlightBits |= dlightBits; @@ -1992,13 +2006,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 ) @@ -2021,7 +2035,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; @@ -2264,12 +2278,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 ) { } @@ -2286,7 +2294,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 }; diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index 981741fb..8f9ba66f 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]; - - return num.i; + 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 *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 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 = v[3] * 127.0f; } + + return 4; } -uint32_t R_VaoPackNormal(vec3_t v) +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 *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; - - return num.i; + 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 *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 = 0; + 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 num.i; + 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 + { + float *num = (float *)out; + + *num++ = st[0]; + *num++ = st[1]; + + return sizeof(*num) * 2; } } +int R_VaoPackColors(byte *out, vec4_t color) +{ + if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT) + { + uint16_t *num = (uint16_t *)out; + + *num++ = FloatToHalf(color[0]); + *num++ = FloatToHalf(color[1]); + *num++ = FloatToHalf(color[2]); + *num++ = FloatToHalf(color[3]); + + return sizeof(*num) * 4; + } + else + { + float *num = (float *)out; + + *num++ = color[0]; + *num++ = color[1]; + *num++ = color[2]; + *num++ = color[3]; + + 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; + union pack8_u *num = (union pack8_u *)&b; - num.i = 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; + union pack8_u *num = (union pack8_u *)&b; - num.i = 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; diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c index 2f7ff2e5..7bf6bf0d 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; diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index 6cdaa12c..7d06e180 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]; diff --git a/opengl2-readme.txt b/opengl2-readme.txt index 167d26f1..5c4cb60b 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