This is an automated email from the git hooks/post-receive script. smcv pushed a commit to annotated tag 1.5a in repository iortcw.
commit 626d086a5ae1fea76ead28ae6c4957bc1e71db3b Author: MAN-AT-ARMS <m4n4t4...@gmail.com> Date: Tue Feb 9 19:22:56 2016 -0500 SP: Rend2: Direct State Access / Cubemap loading / Merge cvars into r_pbr Merged cvars: r_glossIsRoughness, r_specularIsMetallic, r_framebufferGamma, r_tonemapGamma, r_materialGamma, r_lightGamma --- SP/Makefile | 1 + SP/code/rend2/glsl/calclevels4x_fp.glsl | 4 +- SP/code/rend2/glsl/lightall_fp.glsl | 48 ++-- SP/code/rend2/glsl/tonemap_fp.glsl | 8 +- SP/code/rend2/qgl.h | 44 ++++ SP/code/rend2/tr_animation.c | 4 +- SP/code/rend2/tr_backend.c | 213 +++++------------- SP/code/rend2/tr_bsp.c | 43 +++- SP/code/rend2/tr_dsa.c | 287 ++++++++++++++++++++++++ SP/code/rend2/tr_dsa.h | 80 +++++++ SP/code/rend2/tr_extensions.c | 109 +++++++++ SP/code/rend2/tr_fbo.c | 290 +++++------------------- SP/code/rend2/tr_fbo.h | 1 + SP/code/rend2/tr_glsl.c | 102 ++------- SP/code/rend2/tr_image.c | 377 +++++++++++++++----------------- SP/code/rend2/tr_init.c | 37 +--- SP/code/rend2/tr_local.h | 27 +-- SP/code/rend2/tr_main.c | 2 +- SP/code/rend2/tr_postprocess.c | 105 ++++----- SP/code/rend2/tr_scene.c | 2 +- SP/code/rend2/tr_shade.c | 16 +- SP/code/rend2/tr_shader.c | 60 +++-- SP/code/rend2/tr_shadows.c | 4 +- SP/code/rend2/tr_sky.c | 4 +- SP/code/rend2/tr_surface.c | 4 +- SP/code/renderer/qgl.h | 56 ++++- SP/code/renderer/tr_image.c | 6 +- SP/code/renderer/tr_local.h | 1 - SP/rend2-readme.txt | 21 +- 29 files changed, 1057 insertions(+), 899 deletions(-) diff --git a/SP/Makefile b/SP/Makefile index 942c06c..c0c5e00 100644 --- a/SP/Makefile +++ b/SP/Makefile @@ -1711,6 +1711,7 @@ Q3R2OBJ = \ $(B)/rend2/tr_bsp.o \ $(B)/rend2/tr_cmds.o \ $(B)/rend2/tr_curve.o \ + $(B)/rend2/tr_dsa.o \ $(B)/rend2/tr_extramath.o \ $(B)/rend2/tr_extensions.o \ $(B)/rend2/tr_fbo.o \ diff --git a/SP/code/rend2/glsl/calclevels4x_fp.glsl b/SP/code/rend2/glsl/calclevels4x_fp.glsl index 1de59e9..0d298b6 100644 --- a/SP/code/rend2/glsl/calclevels4x_fp.glsl +++ b/SP/code/rend2/glsl/calclevels4x_fp.glsl @@ -14,8 +14,8 @@ vec3 GetValues(vec2 offset, vec3 current) #ifdef FIRST_PASS - #if defined(r_framebufferGamma) - minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma)); + #if defined(USE_PBR) + minAvgMax = pow(minAvgMax, vec3(2.2)); #endif float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); diff --git a/SP/code/rend2/glsl/lightall_fp.glsl b/SP/code/rend2/glsl/lightall_fp.glsl index b8f3985..eb8ba90 100644 --- a/SP/code/rend2/glsl/lightall_fp.glsl +++ b/SP/code/rend2/glsl/lightall_fp.glsl @@ -276,9 +276,9 @@ void main() attenuation = 1.0; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - ambientColor = pow(ambientColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); + ambientColor = pow(ambientColor, vec3(2.2)); #endif #if defined(USE_NORMALMAP) @@ -319,7 +319,7 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface - ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); + ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); #endif vec3 reflectance; @@ -335,21 +335,18 @@ void main() specular *= u_SpecularScale; - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #if !defined(SPECULAR_IS_METALLIC) - specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); - #endif + #if defined(USE_PBR) + diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); #endif float gloss = specular.a; - #if defined(GLOSS_IS_ROUGHNESS) - float roughness = gloss; + #if defined(USE_PBR) + float roughness = 1.0 - specular.r; #else float roughness = exp2(-3.0 * gloss); #endif - #if defined(SPECULAR_IS_METALLIC) + #if defined(USE_PBR) // diffuse is actually base color, and green of specular is metallicness float metallic = specular.g; @@ -374,7 +371,7 @@ void main() // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - #if defined(GLOSS_IS_ROUGHNESS) + #if defined(USE_PBR) vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; #else vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; @@ -385,8 +382,8 @@ void main() //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0); //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); - #if defined(r_framebufferGamma) - cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma)); + #if defined(USE_PBR) + cubeLightColor = pow(cubeLightColor, vec3(2.2)); #endif // multiply cubemap values by lighting @@ -421,8 +418,8 @@ void main() lightColor = u_PrimaryLightColor; - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); #endif #if defined(USE_SHADOWMAP) @@ -434,6 +431,11 @@ void main() gl_FragColor.rgb += lightColor * reflectance * NL2; #endif + + #if defined(USE_PBR) + gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); + #endif + #else lightColor = var_Color.rgb; @@ -441,21 +443,9 @@ void main() lightColor *= lightmapColor.rgb; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - #endif - - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #endif - gl_FragColor.rgb = diffuse.rgb * lightColor; #endif -#if defined(r_framebufferGamma) - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma)); -#endif - gl_FragColor.a = diffuse.a * var_Color.a; } diff --git a/SP/code/rend2/glsl/tonemap_fp.glsl b/SP/code/rend2/glsl/tonemap_fp.glsl index 1368c5b..5d8841d 100644 --- a/SP/code/rend2/glsl/tonemap_fp.glsl +++ b/SP/code/rend2/glsl/tonemap_fp.glsl @@ -28,8 +28,8 @@ void main() { vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; -#if defined(r_framebufferGamma) - color.rgb = pow(color.rgb, vec3(r_framebufferGamma)); +#if defined(USE_PBR) + color.rgb = pow(color.rgb, vec3(2.2)); #endif vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; @@ -46,8 +46,8 @@ void main() color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0); -#if defined(r_tonemapGamma) - color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma)); +#if defined(USE_PBR) + color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); #endif gl_FragColor = color; diff --git a/SP/code/rend2/qgl.h b/SP/code/rend2/qgl.h index 1d63a11..bb5f939 100644 --- a/SP/code/rend2/qgl.h +++ b/SP/code/rend2/qgl.h @@ -814,6 +814,50 @@ extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5 #endif +// GL_EXT_direct_state_access +extern GLvoid(APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +extern GLvoid(APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +extern GLvoid(APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +extern GLvoid(APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +extern GLvoid(APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + +extern GLvoid(APIENTRY * qglProgramUniform1i)(GLuint program, GLint location, GLint v0); +extern GLvoid(APIENTRY * qglProgramUniform1f)(GLuint program, GLint location, GLfloat v0); +extern GLvoid(APIENTRY * qglProgramUniform2f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +extern GLvoid(APIENTRY * qglProgramUniform3f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +extern GLvoid(APIENTRY * qglProgramUniform4f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +extern GLvoid(APIENTRY * qglProgramUniform1fv)(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +extern GLvoid(APIENTRY * qglProgramUniformMatrix4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern GLvoid(APIENTRY * qglNamedRenderbufferStorage)(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +extern GLvoid(APIENTRY * qglNamedRenderbufferStorageMultisample)(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +extern GLenum(APIENTRY * qglCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target); +extern GLvoid(APIENTRY * qglNamedFramebufferTexture2D)(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +extern GLvoid(APIENTRY * qglNamedFramebufferRenderbuffer)(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + #if defined(WIN32) // WGL_ARB_create_context #ifndef WGL_ARB_create_context diff --git a/SP/code/rend2/tr_animation.c b/SP/code/rend2/tr_animation.c index 8ca16b7..e5e8453 100644 --- a/SP/code/rend2/tr_animation.c +++ b/SP/code/rend2/tr_animation.c @@ -1209,7 +1209,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) { for ( i = 0; i < surface->numBoneReferences; i++, boneRefs++ ) { bonePtr = &bones[*boneRefs]; - GL_Bind( tr.whiteImage ); + GL_BindToTMU(tr.whiteImage, TB_COLORMAP); qglLineWidth( 1 ); qglBegin( GL_LINES ); for ( j = 0; j < 3; j++ ) { @@ -1243,7 +1243,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) { tempVert = ( float * )( tess.xyz + baseVertex ); tempNormal = ( uint32_t * )( tess.normal + baseVertex ); - GL_Bind( tr.whiteImage ); + GL_BindToTMU(tr.whiteImage, TB_COLORMAP); qglLineWidth( 1 ); qglBegin( GL_LINES ); qglColor3f( .0,.0,.8 ); diff --git a/SP/code/rend2/tr_backend.c b/SP/code/rend2/tr_backend.c index 3f02686..8223e32 100644 --- a/SP/code/rend2/tr_backend.c +++ b/SP/code/rend2/tr_backend.c @@ -27,6 +27,8 @@ If you have questions concerning this license or the applicable additional terms */ #include "tr_local.h" +#include "tr_fbo.h" +#include "tr_dsa.h" backEndData_t *backEndData; backEndState_t backEnd; @@ -41,82 +43,28 @@ static float s_flipMatrix[16] = { 0, 0, 0, 1 }; - -/* -** GL_Bind -*/ -void GL_Bind( image_t *image ) { - int texnum; - - if ( !image ) { - ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" ); - texnum = tr.defaultImage->texnum; - } else { - texnum = image->texnum; - } - - if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option - texnum = tr.dlightImage->texnum; - } - - if ( glState.currenttextures[glState.currenttmu] != texnum ) { - if ( image ) { - image->frameUsed = tr.frameCount; - } - glState.currenttextures[glState.currenttmu] = texnum; - if (image && image->flags & IMGFLAG_CUBEMAP) - qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); - else - qglBindTexture( GL_TEXTURE_2D, texnum ); - } -} - - -/* -** GL_SelectTexture -*/ -void GL_SelectTexture( int unit ) { - if ( glState.currenttmu == unit ) { - return; - } - - if (!(unit >= 0 && unit <= 31)) - ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit ); - - if (!qglActiveTextureARB) - ri.Error( ERR_DROP, "GL_SelectTexture: multitexture disabled" ); - - qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); - - glState.currenttmu = unit; -} - - /* ** GL_BindToTMU */ void GL_BindToTMU( image_t *image, int tmu ) { - int texnum; - int oldtmu = glState.currenttmu; + GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0; + GLenum target = GL_TEXTURE_2D; - if (!image) - texnum = 0; - else - texnum = image->texnum; - - if ( glState.currenttextures[tmu] != texnum ) { - GL_SelectTexture( tmu ); - if (image) - image->frameUsed = tr.frameCount; - glState.currenttextures[tmu] = texnum; + if (image) + { + if (image->flags & IMGFLAG_CUBEMAP) + target = GL_TEXTURE_CUBE_MAP; - if (image && (image->flags & IMGFLAG_CUBEMAP)) - qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); - else - qglBindTexture( GL_TEXTURE_2D, texnum ); - GL_SelectTexture( oldtmu ); + image->frameUsed = tr.frameCount; + texture = image->texnum; + } + else + { + ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n"); } + + GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture); } /* @@ -148,37 +96,6 @@ void GL_Cull( int cullType ) { } /* -** GL_TexEnv -*/ -void GL_TexEnv( int env ) { - if ( env == glState.texEnv[glState.currenttmu] ) { - return; - } - - glState.texEnv[glState.currenttmu] = env; - - - switch ( env ) - { - case GL_MODULATE: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - break; - case GL_REPLACE: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - break; - case GL_DECAL: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); - break; - case GL_ADD: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD ); - break; - default: - ri.Error( ERR_DROP, "GL_TexEnv: invalid env '%d' passed", env ); - break; - } -} - -/* ** GL_State ** ** This routine is responsible for setting the most commonly changed state @@ -457,31 +374,19 @@ void RB_BeginDrawingView( void ) { if (glRefConfig.framebufferObject) { + FBO_t *fbo = backEnd.viewParms.targetFbo; + // FIXME: HUGE HACK: render to the screen fbo if we've already postprocessed the frame and aren't drawing more world // drawing more world check is in case of double renders, such as skyportals - if (backEnd.viewParms.targetFbo == NULL) - { - if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL))) - { - FBO_Bind(NULL); - } - else - { - FBO_Bind(tr.renderFbo); - } - } - else - { - FBO_Bind(backEnd.viewParms.targetFbo); + if (fbo == NULL && !(backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL))) + fbo = tr.renderFbo; - // FIXME: hack for cubemap testing - if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo) - { - cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; - //qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0); - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, cubemap->image->texnum, 0); - } + if (tr.renderCubeFbo && fbo == tr.renderCubeFbo) + { + cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; + FBO_AttachImage(fbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, backEnd.viewParms.targetFboLayer); } + FBO_Bind(fbo); } // @@ -1281,6 +1186,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * } RE_UploadCinematic (w, h, cols, rows, data, client, dirty); + GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP); if ( r_speeds->integer ) { end = ri.Milliseconds(); @@ -1290,14 +1196,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * // FIXME: HUGE hack if (glRefConfig.framebufferObject) { - if (!tr.renderFbo || backEnd.framePostProcessed) - { - FBO_Bind(NULL); - } - else - { - FBO_Bind(tr.renderFbo); - } + FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo); } RB_SetGL2D(); @@ -1322,23 +1221,30 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * void RE_UploadCinematic( int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty ) { + GLuint texture; + + if (!tr.scratchImage[client]) + { + ri.Printf(PRINT_WARNING, "RE_UploadCinematic: scratch images not initialized\n"); + return; + } - GL_Bind( tr.scratchImage[client] ); + texture = tr.scratchImage[client]->texnum; // if the scratchImage isn't in the format we want, specify it as a new texture if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) { tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols; tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows; - qglTexImage2D( GL_TEXTURE_2D, 0, 3, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + qglTextureImage2D(texture, GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { if ( dirty ) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing // it and don't try and do a texture compression - qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data); } } } @@ -1377,16 +1283,7 @@ const void *RB_StretchPic( const void *data ) { // FIXME: HUGE hack if (glRefConfig.framebufferObject) - { - if (!tr.renderFbo || backEnd.framePostProcessed) - { - FBO_Bind(NULL); - } - else - { - FBO_Bind(tr.renderFbo); - } - } + FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo); RB_SetGL2D(); @@ -1590,11 +1487,10 @@ const void *RB_DrawSurfs( const void *data ) { // If we're using multisampling, resolve the depth first FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - else if (tr.renderFbo == NULL) + else if (tr.renderFbo == NULL && tr.renderDepthImage) { // If we're rendering directly to the screen, copy the depth to a texture - GL_BindToTMU(tr.renderDepthImage, 0); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0); + qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0); } if (r_ssao->integer) @@ -1834,10 +1730,8 @@ const void *RB_DrawSurfs( const void *data ) { cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; FBO_Bind(NULL); - GL_SelectTexture(TB_CUBEMAP); - GL_BindToTMU(cubemap->image, TB_CUBEMAP); - qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); - GL_SelectTexture(0); + if (cubemap && cubemap->image) + qglGenerateTextureMipmap(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP); } return (const void *)( cmd + 1 ); @@ -1916,7 +1810,7 @@ void RB_ShowImages( void ) { { vec4_t quadVerts[4]; - GL_Bind(image); + GL_BindToTMU(image, TB_COLORMAP); VectorSet4(quadVerts[0], x, y, 0, 1); VectorSet4(quadVerts[1], x + w, y, 0, 1); @@ -2091,21 +1985,18 @@ const void *RB_CapShadowMap(const void *data) if (cmd->map != -1) { - GL_SelectTexture(0); if (cmd->cubeSide != -1) { if (tr.shadowCubemaps[cmd->map]) { - GL_Bind(tr.shadowCubemaps[cmd->map]); - qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureImage2D(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); } } else { if (tr.pshadowMaps[cmd->map]) { - GL_Bind(tr.pshadowMaps[cmd->map]); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureImage2D(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); } } } @@ -2178,7 +2069,7 @@ const void *RB_PostProcess(const void *data) if (srcFbo) { - if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB) + if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); @@ -2294,11 +2185,11 @@ const void *RB_ExportCubemaps(const void *data) { char filename[MAX_QPATH]; cubemap_t *cubemap = &tr.cubemaps[i]; - unsigned char *p = cubemapPixels; + byte *p = cubemapPixels; for (j = 0; j < 6; j++) { - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); + FBO_AttachImage(tr.renderCubeFbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, j); qglReadPixels(0, 0, r_cubemapSize->integer, r_cubemapSize->integer, GL_RGBA, GL_UNSIGNED_BYTE, p); p += sideSize; } diff --git a/SP/code/rend2/tr_bsp.c b/SP/code/rend2/tr_bsp.c index 8bd2c00..06398e9 100644 --- a/SP/code/rend2/tr_bsp.c +++ b/SP/code/rend2/tr_bsp.c @@ -146,7 +146,7 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale ) float r, g, b; #if defined(USE_OVERBRIGHT) - scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits); + scale *= 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #endif r = in[0] * scale; @@ -3100,7 +3100,7 @@ void R_LoadLightGrid( lump_t *l ) { if (hdrLightGrid) { #if defined(USE_OVERBRIGHT) - float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits); + float lightScale = 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #else float lightScale = 1.0f; #endif @@ -3406,25 +3406,43 @@ void R_AssignCubemapsToWorldSurfaces(void) } -void R_RenderAllCubemaps(void) +void R_LoadCubemaps(void) { - int i, j; + int i; + imgFlags_t flags = IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP; for (i = 0; i < tr.numCubemaps; i++) { - tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); + char filename[MAX_QPATH]; + cubemap_t *cubemap = &tr.cubemaps[i]; + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); + + cubemap->image = R_FindImageFile(filename, IMGTYPE_COLORALPHA, flags); } +} + + +void R_RenderMissingCubemaps(void) +{ + int i, j; + imgFlags_t flags = IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP; ri.Printf(PRINT_ALL, "Total cubemaps: %d\n", tr.numCubemaps ); for (i = 0; i < tr.numCubemaps; i++) { - for (j = 0; j < 6; j++) + if (!tr.cubemaps[i].image) { - RE_ClearScene(); - R_RenderCubemapSide(i, j, qfalse); - R_IssuePendingRenderCommands(); - R_InitNextFrame(); + tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, flags, GL_RGBA8); + + for (j = 0; j < 6; j++) + { + RE_ClearScene(); + R_RenderCubemapSide(i, j, qfalse); + R_IssuePendingRenderCommands(); + R_InitNextFrame(); + } } } } @@ -3801,10 +3819,11 @@ void RE_LoadWorldMap( const char *name ) { // make sure the VAO glState entry is safe R_BindNullVao(); - // Render all cubemaps + // Render or load all cubemaps if (r_cubeMapping->integer && tr.numCubemaps) { - R_RenderAllCubemaps(); + R_LoadCubemaps(); + R_RenderMissingCubemaps(); } ri.FS_FreeFile( buffer.v ); diff --git a/SP/code/rend2/tr_dsa.c b/SP/code/rend2/tr_dsa.c new file mode 100644 index 0000000..a766263 --- /dev/null +++ b/SP/code/rend2/tr_dsa.c @@ -0,0 +1,287 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#include "tr_local.h" + +#include "tr_dsa.h" + +static struct +{ + GLuint textures[NUM_TEXTURE_BUNDLES]; + GLenum texunit; + + GLuint program; + + GLuint drawFramebuffer; + GLuint readFramebuffer; + GLuint renderbuffer; +} +glDsaState; + +void GL_BindNullTextures() +{ + int i; + + if (glRefConfig.directStateAccess) + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglBindMultiTexture(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + } + else + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglActiveTextureARB(GL_TEXTURE0_ARB + i); + qglBindTexture(GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + + qglActiveTextureARB(GL_TEXTURE0_ARB); + glDsaState.texunit = GL_TEXTURE0_ARB; + } +} + +int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + GLuint tmu = texunit - GL_TEXTURE0_ARB; + + if (glDsaState.textures[tmu] == texture) + return 0; + + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) + target = GL_TEXTURE_CUBE_MAP; + + qglBindMultiTexture(texunit, target, texture); + glDsaState.textures[tmu] = texture; + return 1; +} + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + if (glDsaState.texunit != texunit) + { + qglActiveTextureARB(texunit); + glDsaState.texunit = texunit; + } + + qglBindTexture(target, texture); +} + +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameterf(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameteri(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +} + +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data); +} + +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data); +} + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglGenerateMipmapEXT(target); +} + +void GL_BindNullProgram() +{ + qglUseProgramObjectARB(0); + glDsaState.program = 0; +} + +int GL_UseProgramObject(GLuint program) +{ + if (glDsaState.program == program) + return 0; + + qglUseProgramObjectARB(program); + glDsaState.program = program; + return 1; +} + +GLvoid APIENTRY GLDSA_ProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + GL_UseProgramObject(program); + qglUniform1iARB(location, v0); +} + +GLvoid APIENTRY GLDSA_ProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + GL_UseProgramObject(program); + qglUniform1fARB(location, v0); +} + +GLvoid APIENTRY GLDSA_ProgramUniform2f(GLuint program, GLint location, + GLfloat v0, GLfloat v1) +{ + GL_UseProgramObject(program); + qglUniform2fARB(location, v0, v1); +} + +GLvoid APIENTRY GLDSA_ProgramUniform3f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2) +{ + GL_UseProgramObject(program); + qglUniform3fARB(location, v0, v1, v2); +} + +GLvoid APIENTRY GLDSA_ProgramUniform4f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + GL_UseProgramObject(program); + qglUniform4fARB(location, v0, v1, v2, v3); +} + +GLvoid APIENTRY GLDSA_ProgramUniform1fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value) +{ + GL_UseProgramObject(program); + qglUniform1fvARB(location, count, value); +} + +GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GL_UseProgramObject(program); + qglUniformMatrix4fvARB(location, count, transpose, value); +} + +void GL_BindNullFramebuffers() +{ + qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0; + qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glDsaState.readFramebuffer = 0; +} + +void GL_BindFramebuffer(GLenum target, GLuint framebuffer) +{ + switch (target) + { + case GL_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer; + } + break; + + case GL_DRAW_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.drawFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.drawFramebuffer = framebuffer; + } + break; + + case GL_READ_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.readFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.readFramebuffer = framebuffer; + } + break; + } +} + +void GL_BindRenderbuffer(GLuint renderbuffer) +{ + if (renderbuffer != glDsaState.renderbuffer) + { + qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer); + glDsaState.renderbuffer = renderbuffer; + } +} + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorage(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height) +{ + GL_BindRenderbuffer(renderbuffer); + qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height); +} + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisample(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + GL_BindRenderbuffer(renderbuffer); + qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height); +} + +GLenum APIENTRY GLDSA_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target) +{ + GL_BindFramebuffer(target, framebuffer); + return qglCheckFramebufferStatusEXT(target); +} + +GLvoid APIENTRY GLDSA_NamedFramebufferTexture2D(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level); +} + +GLvoid APIENTRY GLDSA_NamedFramebufferRenderbuffer(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); + qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer); +} diff --git a/SP/code/rend2/tr_dsa.h b/SP/code/rend2/tr_dsa.h new file mode 100644 index 0000000..9d610ef --- /dev/null +++ b/SP/code/rend2/tr_dsa.h @@ -0,0 +1,80 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#ifndef __TR_DSA_H__ +#define __TR_DSA_H__ + +#include "qgl.h" + +void GL_BindNullTextures(void); +int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target); + +void GL_BindNullProgram(void); +int GL_UseProgramObject(GLuint program); + +GLvoid APIENTRY GLDSA_ProgramUniform1i(GLuint program, GLint location, GLint v0); +GLvoid APIENTRY GLDSA_ProgramUniform1f(GLuint program, GLint location, GLfloat v0); +GLvoid APIENTRY GLDSA_ProgramUniform2f(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +GLvoid APIENTRY GLDSA_ProgramUniform3f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +GLvoid APIENTRY GLDSA_ProgramUniform4f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLvoid APIENTRY GLDSA_ProgramUniform1fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + +void GL_BindNullFramebuffers(void); +void GL_BindFramebuffer(GLenum target, GLuint framebuffer); +void GL_BindRenderbuffer(GLuint renderbuffer); + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorage(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisample(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +GLenum APIENTRY GLDSA_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target); +GLvoid APIENTRY GLDSA_NamedFramebufferTexture2D(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLvoid APIENTRY GLDSA_NamedFramebufferRenderbuffer(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + +#endif diff --git a/SP/code/rend2/tr_extensions.c b/SP/code/rend2/tr_extensions.c index 8c2d9d0..7a4bacc 100644 --- a/SP/code/rend2/tr_extensions.c +++ b/SP/code/rend2/tr_extensions.c @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "tr_local.h" +#include "tr_dsa.h" // GL_EXT_draw_range_elements void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); @@ -184,6 +185,50 @@ void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays); void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays); GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); +// GL_EXT_direct_state_access +GLvoid (APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +GLvoid (APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid (APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid (APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid (APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + +GLvoid(APIENTRY * qglProgramUniform1i)(GLuint program, GLint location, GLint v0); +GLvoid(APIENTRY * qglProgramUniform1f)(GLuint program, GLint location, GLfloat v0); +GLvoid(APIENTRY * qglProgramUniform2f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +GLvoid(APIENTRY * qglProgramUniform3f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +GLvoid(APIENTRY * qglProgramUniform4f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLvoid(APIENTRY * qglProgramUniform1fv)(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +GLvoid(APIENTRY * qglProgramUniformMatrix4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + +GLvoid(APIENTRY * qglNamedRenderbufferStorage)(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +GLvoid(APIENTRY * qglNamedRenderbufferStorageMultisample)(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +GLenum(APIENTRY * qglCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target); +GLvoid(APIENTRY * qglNamedFramebufferTexture2D)(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLvoid(APIENTRY * qglNamedFramebufferRenderbuffer)(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + static qboolean GLimp_HaveExtension(const char *ext) { const char *ptr = Q_stristr( (char *)qglGetString(GL_EXTENSIONS), ext ); @@ -750,4 +795,68 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + // GL_EXT_direct_state_access + extension = "GL_EXT_direct_state_access"; + + qglBindMultiTexture = GLDSA_BindMultiTexture; + qglTextureParameterf = GLDSA_TextureParameterf; + qglTextureParameteri = GLDSA_TextureParameteri; + qglTextureImage2D = GLDSA_TextureImage2D; + qglTextureSubImage2D = GLDSA_TextureSubImage2D; + qglCopyTextureImage2D = GLDSA_CopyTextureImage2D; + qglCompressedTextureImage2D = GLDSA_CompressedTextureImage2D; + qglCompressedTextureSubImage2D = GLDSA_CompressedTextureSubImage2D; + qglGenerateTextureMipmap = GLDSA_GenerateTextureMipmap; + + qglProgramUniform1i = GLDSA_ProgramUniform1i; + qglProgramUniform1f = GLDSA_ProgramUniform1f; + qglProgramUniform2f = GLDSA_ProgramUniform2f; + qglProgramUniform3f = GLDSA_ProgramUniform3f; + qglProgramUniform4f = GLDSA_ProgramUniform4f; + qglProgramUniform1fv = GLDSA_ProgramUniform1fv; + qglProgramUniformMatrix4fv = GLDSA_ProgramUniformMatrix4fv; + + qglNamedRenderbufferStorage = GLDSA_NamedRenderbufferStorage; + qglNamedRenderbufferStorageMultisample = GLDSA_NamedRenderbufferStorageMultisample; + qglCheckNamedFramebufferStatus = GLDSA_CheckNamedFramebufferStatus; + qglNamedFramebufferTexture2D = GLDSA_NamedFramebufferTexture2D; + qglNamedFramebufferRenderbuffer = GLDSA_NamedFramebufferRenderbuffer; + + glRefConfig.directStateAccess = qfalse; + if (GLimp_HaveExtension(extension)) + { + if (r_ext_direct_state_access->integer) + { + glRefConfig.directStateAccess = qtrue; + qglBindMultiTexture = (void *)SDL_GL_GetProcAddress("glBindMultiTextureEXT"); + qglTextureParameterf = (void *)SDL_GL_GetProcAddress("glTextureParameterfEXT"); + qglTextureParameteri = (void *)SDL_GL_GetProcAddress("glTextureParameteriEXT"); + qglTextureImage2D = (void *)SDL_GL_GetProcAddress("glTextureImage2DEXT"); + qglTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glTextureSubImage2DEXT"); + qglCopyTextureImage2D = (void *)SDL_GL_GetProcAddress("glCopyTextureImage2DEXT"); + qglCompressedTextureImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureImage2DEXT"); + qglCompressedTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureSubImage2DEXT"); + qglGenerateTextureMipmap = (void *)SDL_GL_GetProcAddress("glGenerateTextureMipmapEXT"); + + qglProgramUniform1i = (void *)SDL_GL_GetProcAddress("glProgramUniform1iEXT"); + qglProgramUniform1f = (void *)SDL_GL_GetProcAddress("glProgramUniform1fEXT"); + qglProgramUniform2f = (void *)SDL_GL_GetProcAddress("glProgramUniform2fEXT"); + qglProgramUniform3f = (void *)SDL_GL_GetProcAddress("glProgramUniform3fEXT"); + qglProgramUniform4f = (void *)SDL_GL_GetProcAddress("glProgramUniform4fEXT"); + qglProgramUniform1fv = (void *)SDL_GL_GetProcAddress("glProgramUniform1fvEXT"); + qglProgramUniformMatrix4fv = (void *)SDL_GL_GetProcAddress("glProgramUniformMatrix4fvEXT"); + + qglNamedRenderbufferStorage = (void *)SDL_GL_GetProcAddress("glNamedRenderbufferStorageEXT"); + qglNamedRenderbufferStorageMultisample = (void *)SDL_GL_GetProcAddress("glNamedRenderbufferStorageMultisampleEXT"); + qglCheckNamedFramebufferStatus = (void *)SDL_GL_GetProcAddress("glCheckNamedFramebufferStatusEXT"); + qglNamedFramebufferTexture2D = (void *)SDL_GL_GetProcAddress("glNamedFramebufferTexture2DEXT"); + qglNamedFramebufferRenderbuffer = (void *)SDL_GL_GetProcAddress("glNamedFramebufferRenderbufferEXT"); + } + + ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess ? 1 : 0], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } } diff --git a/SP/code/rend2/tr_fbo.c b/SP/code/rend2/tr_fbo.c index c8ea0ae..59b1703 100644 --- a/SP/code/rend2/tr_fbo.c +++ b/SP/code/rend2/tr_fbo.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_fbo.c #include "tr_local.h" +#include "tr_dsa.h" + /* ============= R_CheckFBO @@ -30,19 +32,10 @@ R_CheckFBO */ qboolean R_CheckFBO(const FBO_t * fbo) { - int code; - int id; - - qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &id); - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer); - - code = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + GLenum code = qglCheckNamedFramebufferStatus(fbo->frameBuffer, GL_FRAMEBUFFER_EXT); if(code == GL_FRAMEBUFFER_COMPLETE_EXT) - { - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); return qtrue; - } // an error occured switch (code) @@ -83,13 +76,9 @@ qboolean R_CheckFBO(const FBO_t * fbo) default: ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code); - //ri.Error(ERR_FATAL, "R_CheckFBO: (%s) unknown error 0x%X", fbo->name, code); - //assert(0); break; } - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); - return qfalse; } @@ -133,6 +122,11 @@ FBO_t *FBO_Create(const char *name, int width, int height) return fbo; } +/* +================= +FBO_CreateBuffer +================= +*/ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample) { uint32_t *pRenderBuffer; @@ -189,115 +183,45 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample) if (absent) qglGenRenderbuffersEXT(1, pRenderBuffer); - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer); if (multisample && glRefConfig.framebufferMultisample) - { - qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, format, fbo->width, fbo->height); - } + qglNamedRenderbufferStorageMultisample(*pRenderBuffer, multisample, format, fbo->width, fbo->height); else - { - qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height); - } + qglNamedRenderbufferStorage(*pRenderBuffer, format, fbo->width, fbo->height); if(absent) { if (attachment == 0) { - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); } else - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer); - } -} - - -/* -================= -R_AttachFBOTexture1D -================= -*/ -void R_AttachFBOTexture1D(int texId, int index) -{ - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture1D: invalid attachment index %i\n", index); - return; + { + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer); + } } - - qglFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_1D, texId, 0); } -/* -================= -R_AttachFBOTexture2D -================= -*/ -void R_AttachFBOTexture2D(int target, int texId, int index) -{ - if(target != GL_TEXTURE_2D && (target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid target %i\n", target); - return; - } - - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid attachment index %i\n", index); - return; - } - - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, target, texId, 0); -} /* ================= -R_AttachFBOTexture3D +FBO_AttachImage ================= */ -void R_AttachFBOTexture3D(int texId, int index, int zOffset) +void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside) { - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture3D: invalid attachment index %i\n", index); - return; - } + GLenum target = GL_TEXTURE_2D; + int index; - qglFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_3D_EXT, texId, 0, zOffset); -} + if (image->flags & IMGFLAG_CUBEMAP) + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside; -/* -================= -R_AttachFBOTextureDepth -================= -*/ -void R_AttachFBOTextureDepth(int texId) -{ - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); + qglNamedFramebufferTexture2D(fbo->frameBuffer, attachment, target, image->texnum, 0); + index = attachment - GL_COLOR_ATTACHMENT0_EXT; + if (index >= 0 && index <= 15) + fbo->colorImage[index] = image; } -/* -================= -R_AttachFBOTexturePackedDepthStencil -================= -*/ -void R_AttachFBOTexturePackedDepthStencil(int texId) -{ - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); -} - -void FBO_AttachTextureImage(image_t *img, int index) -{ - if (!glState.currentFBO) - { - ri.Printf(PRINT_WARNING, "FBO: attempted to attach a texture image with no FBO bound!\n"); - return; - } - - R_AttachFBOTexture2D(GL_TEXTURE_2D, img->texnum, index); - glState.currentFBO->colorImage[index] = img; -} /* ============ @@ -312,38 +236,10 @@ void FBO_Bind(FBO_t * fbo) if (r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! - if (fbo) - GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo->name)); - else - GLimp_LogComment("--- FBO_Bind ( NULL ) ---\n"); - } - - if (!fbo) - { - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - glState.currentFBO = NULL; - - return; + GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL")); } - - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer); - - /* - if(fbo->colorBuffers[0]) - { - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]); - } - */ - - /* - if(fbo->depthBuffer) - { - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer); - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer); - } - */ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0); glState.currentFBO = fbo; } @@ -355,7 +251,6 @@ FBO_Init void FBO_Init(void) { int i; - // int width, height, hdrFormat, multisample; int hdrFormat, multisample; ri.Printf(PRINT_ALL, "------- FBO_Init -------\n"); @@ -369,73 +264,40 @@ void FBO_Init(void) R_IssuePendingRenderCommands(); -/* if(glRefConfig.textureNonPowerOfTwo) - { - width = glConfig.vidWidth; - height = glConfig.vidHeight; - } - else - { - width = NextPowerOfTwo(glConfig.vidWidth); - height = NextPowerOfTwo(glConfig.vidHeight); - } */ - hdrFormat = GL_RGBA8; if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) - { hdrFormat = GL_RGBA16F_ARB; - } qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample); if (r_ext_framebuffer_multisample->integer < multisample) - { multisample = r_ext_framebuffer_multisample->integer; - } if (multisample < 2 || !glRefConfig.framebufferBlit) multisample = 0; if (multisample != r_ext_framebuffer_multisample->integer) - { ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample); - } // only create a render FBO if we need to resolve MSAA or do HDR // otherwise just render straight to the screen (tr.renderFbo = NULL) if (multisample && glRefConfig.framebufferMultisample) { tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.renderFbo); - FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample); FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample); - R_CheckFBO(tr.renderFbo); - tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.msaaResolveFbo); - - //FBO_CreateBuffer(tr.msaaResolveFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.renderImage, 0); - - //FBO_CreateBuffer(tr.msaaResolveFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - + FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.msaaResolveFbo); } else if (r_hdr->integer) { tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.renderFbo); - - //FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.renderImage, 0); - - //FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - + FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.renderFbo); } @@ -443,20 +305,15 @@ void FBO_Init(void) // this fixes the corrupt screen bug with r_hdr 1 on older hardware if (tr.renderFbo) { - FBO_Bind(tr.renderFbo); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer); qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - FBO_Bind(NULL); } if (r_drawSunRays->integer) { tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.sunRaysFbo); - - FBO_AttachTextureImage(tr.sunRaysImage, 0); - - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - + FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunRaysFbo); } @@ -466,14 +323,8 @@ void FBO_Init(void) for( i = 0; i < MAX_DRAWN_PSHADOWS; i++) { tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height); - FBO_Bind(tr.pshadowFbos[i]); - - //FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0); - FBO_AttachTextureImage(tr.pshadowMaps[i], 0); - + FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0); FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0); - //R_AttachFBOTextureDepth(tr.textureDepthImage->texnum); - R_CheckFBO(tr.pshadowFbos[i]); } } @@ -483,104 +334,64 @@ void FBO_Init(void) for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); - FBO_Bind(tr.sunShadowFbo[i]); - - //FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0); - //FBO_AttachTextureImage(tr.sunShadowImage, 0); - qglDrawBuffer(GL_NONE); - qglReadBuffer(GL_NONE); - - //FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum); - + FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunShadowFbo[i]); - } tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height); - FBO_Bind(tr.screenShadowFbo); - - FBO_AttachTextureImage(tr.screenShadowImage, 0); - + FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenShadowFbo); } for (i = 0; i < 2; i++) { tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); - FBO_Bind(tr.textureScratchFbo[i]); - - //FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0, 0); - FBO_AttachTextureImage(tr.textureScratchImage[i], 0); - + FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.textureScratchFbo[i]); } { tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height); - FBO_Bind(tr.calcLevelsFbo); - - //FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.calcLevelsImage, 0); - + FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.calcLevelsFbo); } { tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height); - FBO_Bind(tr.targetLevelsFbo); - - //FBO_CreateBuffer(tr.targetLevelsFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.targetLevelsImage, 0); - + FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.targetLevelsFbo); } for (i = 0; i < 2; i++) { tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); - FBO_Bind(tr.quarterFbo[i]); - - //FBO_CreateBuffer(tr.quarterFbo[i], hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.quarterImage[i], 0); - + FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.quarterFbo[i]); } if (r_ssao->integer) { tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height); - FBO_Bind(tr.hdrDepthFbo); - - FBO_AttachTextureImage(tr.hdrDepthImage, 0); - + FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.hdrDepthFbo); tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height); - FBO_Bind(tr.screenSsaoFbo); - - FBO_AttachTextureImage(tr.screenSsaoImage, 0); - + FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenSsaoFbo); } if (tr.renderCubeImage) { tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height); - FBO_Bind(tr.renderCubeFbo); - - //FBO_AttachTextureImage(tr.renderCubeImage, 0); - R_AttachFBOTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tr.renderCubeImage->texnum, 0); - glState.currentFBO->colorImage[0] = tr.renderCubeImage; - + FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0); FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_CheckFBO(tr.renderCubeFbo); } GL_CheckErrors(); - FBO_Bind(NULL); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + glState.currentFBO = NULL; } /* @@ -663,7 +474,10 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS int width, height; if (!src) + { + ri.Printf(PRINT_WARNING, "Tried to blit from a NULL texture!\n"); return; + } if (inSrcBox) { @@ -849,12 +663,12 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]); } - qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, srcFb); - qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dstFb); + GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb); + GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb); qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3], dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3], buffers, filter); - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0); glState.currentFBO = NULL; } diff --git a/SP/code/rend2/tr_fbo.h b/SP/code/rend2/tr_fbo.h index b5ab18c..3f23a35 100644 --- a/SP/code/rend2/tr_fbo.h +++ b/SP/code/rend2/tr_fbo.h @@ -52,6 +52,7 @@ typedef struct FBO_s int height; } FBO_t; +void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside); void FBO_Bind(FBO_t *fbo); void FBO_Init(void); void FBO_Shutdown(void); diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c index ce83a62..9cfa025 100644 --- a/SP/code/rend2/tr_glsl.c +++ b/SP/code/rend2/tr_glsl.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_glsl.c #include "tr_local.h" -void GLSL_BindNullProgram(void); +#include "tr_dsa.h" extern const char *fallbackShader_bokeh_vp; extern const char *fallbackShader_bokeh_fp; @@ -328,17 +328,8 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha Q_strcat(dest, size, va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); - if (r_materialGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value)); - - if (r_lightGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value)); - - if (r_framebufferGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value)); - - if (r_tonemapGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value)); + if (r_pbr->integer) + Q_strcat(dest, size, "#define USE_PBR\n"); if (extra) { @@ -488,11 +479,6 @@ static void GLSL_ShowProgramUniforms(GLhandleARB program) GLenum type; char uniformName[1000]; - // install the executables in the program object as part of current state. - qglUseProgramObjectARB(program); - - // check for GL Errors - // query the number of active uniforms qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); @@ -503,8 +489,6 @@ static void GLSL_ShowProgramUniforms(GLhandleARB program) ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName); } - - qglUseProgramObjectARB(0); } static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int attribs, const char *vpCode, const char *fpCode) @@ -709,7 +693,7 @@ void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value) *compare = value; - qglUniform1iARB(uniforms[uniformNum], value); + qglProgramUniform1i(program->program, uniforms[uniformNum], value); } void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value) @@ -733,7 +717,7 @@ void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat valu *compare = value; - qglUniform1fARB(uniforms[uniformNum], value); + qglProgramUniform1f(program->program, uniforms[uniformNum], value); } void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v) @@ -758,7 +742,7 @@ void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t compare[0] = v[0]; compare[1] = v[1]; - qglUniform2fARB(uniforms[uniformNum], v[0], v[1]); + qglProgramUniform2f(program->program, uniforms[uniformNum], v[0], v[1]); } void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v) @@ -782,7 +766,7 @@ void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t VectorCopy(v, compare); - qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]); + qglProgramUniform3f(program->program, uniforms[uniformNum], v[0], v[1], v[2]); } void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v) @@ -806,7 +790,7 @@ void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t VectorCopy4(v, compare); - qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]); + qglProgramUniform4f(program->program, uniforms[uniformNum], v[0], v[1], v[2], v[3]); } void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_t v) @@ -830,7 +814,7 @@ void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_ VectorCopy5(v, compare); - qglUniform1fvARB(uniforms[uniformNum], 5, v); + qglProgramUniform1fv(program->program, uniforms[uniformNum], 5, v); } void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix) @@ -854,7 +838,7 @@ void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t Mat4Copy(matrix, compare); - qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix); + qglProgramUniformMatrix4fv(program->program, uniforms[uniformNum], 1, GL_FALSE, matrix); } void GLSL_DeleteGPUShader(shaderProgram_t *program) @@ -937,10 +921,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.genericShader[i]); - qglUseProgramObjectARB(tr.genericShader[i].program); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.genericShader[i]); @@ -957,9 +939,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.textureColorShader); - qglUseProgramObjectARB(tr.textureColorShader.program); GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.textureColorShader); @@ -1011,9 +991,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.dlightShader[i]); - qglUseProgramObjectARB(tr.dlightShader[i].program); GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.dlightShader[i]); @@ -1040,12 +1018,6 @@ void GLSL_InitGPUShaders(void) extradefines[0] = '\0'; - if (r_specularIsMetallic->value) - Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); - - if (r_glossIsRoughness->value) - Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); - if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); @@ -1141,7 +1113,6 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.lightallShader[i]); - qglUseProgramObjectARB(tr.lightallShader[i].program); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP, TB_NORMALMAP); @@ -1149,7 +1120,6 @@ void GLSL_InitGPUShaders(void) GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.lightallShader[i]); @@ -1182,9 +1152,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.pshadowShader); - qglUseProgramObjectARB(tr.pshadowShader.program); GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.pshadowShader); @@ -1201,9 +1169,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.down4xShader); - qglUseProgramObjectARB(tr.down4xShader.program); GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.down4xShader); @@ -1220,9 +1186,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.bokehShader); - qglUseProgramObjectARB(tr.bokehShader.program); GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.bokehShader); @@ -1239,10 +1203,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.tonemapShader); - qglUseProgramObjectARB(tr.tonemapShader.program); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP, TB_LEVELSMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.tonemapShader); @@ -1264,9 +1226,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.calclevels4xShader[i]); - qglUseProgramObjectARB(tr.calclevels4xShader[i].program); GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.calclevels4xShader[i]); @@ -1297,13 +1257,11 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.shadowmaskShader); - qglUseProgramObjectARB(tr.shadowmaskShader.program); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.shadowmaskShader); @@ -1320,9 +1278,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.ssaoShader); - qglUseProgramObjectARB(tr.ssaoShader.program); GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.ssaoShader); @@ -1347,10 +1303,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.depthBlurShader[i]); - qglUseProgramObjectARB(tr.depthBlurShader[i].program); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.depthBlurShader[i]); @@ -1368,9 +1322,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.testcubeShader); - qglUseProgramObjectARB(tr.testcubeShader.program); GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.testcubeShader); @@ -1394,7 +1346,7 @@ void GLSL_ShutdownGPUShaders(void) for (i = 0; i < ATTR_INDEX_COUNT; i++) qglDisableVertexAttribArrayARB(i); - GLSL_BindNullProgram(); + GL_BindNullProgram(); for ( i = 0; i < GENERICDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.genericShader[i]); @@ -1424,49 +1376,25 @@ void GLSL_ShutdownGPUShaders(void) for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.depthBlurShader[i]); - - glState.currentProgram = 0; - qglUseProgramObjectARB(0); } void GLSL_BindProgram(shaderProgram_t * program) { - if(!program) - { - GLSL_BindNullProgram(); - return; - } + GLuint programObject = program ? program->program : 0; + char *name = program ? program->name : "NULL"; if(r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! - GLimp_LogComment(va("--- GL_BindProgram( %s ) ---\n", program->name)); + GLimp_LogComment(va("--- GLSL_BindProgram( %s ) ---\n", name)); } - if(glState.currentProgram != program) - { - qglUseProgramObjectARB(program->program); - glState.currentProgram = program; + if (GL_UseProgramObject(programObject)) backEnd.pc.c_glslShaderBinds++; - } } -void GLSL_BindNullProgram(void) -{ - if(r_logFile->integer) - { - GLimp_LogComment("--- GL_BindNullProgram ---\n"); - } - - if(glState.currentProgram) - { - qglUseProgramObjectARB(0); - glState.currentProgram = NULL; - } -} - shaderProgram_t *GLSL_GetGenericShaderProgram(int stage, glfog_t *glFog) { diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c index aa228d3..12dc5ea 100644 --- a/SP/code/rend2/tr_image.c +++ b/SP/code/rend2/tr_image.c @@ -35,6 +35,8 @@ If you have questions concerning this license or the applicable additional terms #include "tr_local.h" +#include "tr_dsa.h" + static byte s_intensitytable[256]; static unsigned char s_gammatable[256]; @@ -132,9 +134,8 @@ void GL_TextureMode( const char *string ) { for ( i = 0 ; i < tr.numImages ; i++ ) { glt = tr.images[ i ]; if ( glt->flags & IMGFLAG_MIPMAP ) { - GL_Bind( glt ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max ); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } @@ -1973,7 +1974,7 @@ static void CompressMonoBlock(byte outdata[8], const byte indata[16]) } } -static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, int height, int mip) { int wBlocks, hBlocks, y, x, size; byte *compressedData, *p; @@ -2013,86 +2014,61 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } } - qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); ri.Hunk_FreeTempMemory(compressedData); } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static int CalculateMipSize(int width, int height, GLenum picFormat) { - int dataFormat, dataType; - qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + int numBlocks = ((width + 3) / 4) * ((height + 3) / 4); + int numPixels = width * height; - if (data && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + switch (picFormat) { - int bytesPer4x4Block = 0; - int miplevel = 0; - - switch (picFormat) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RED_RGTC1: - case GL_COMPRESSED_SIGNED_RED_RGTC1: - bytesPer4x4Block = 8; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - case GL_COMPRESSED_RG_RGTC2: - case GL_COMPRESSED_SIGNED_RG_RGTC2: - case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - bytesPer4x4Block = 16; - break; - default: - ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); - return; - break; - } - - if (flags & IMGFLAG_PICMIP) - { - for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; - - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } - } + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + return numBlocks * 8; - if (!(flags & IMGFLAG_MIPMAP)) - numMips = 1; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + return numBlocks * 16; - for (miplevel = 0; miplevel < numMips; miplevel++) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + case GL_RGBA8: + case GL_SRGB8_ALPHA8_EXT: + return numPixels * 4; - if (subtexture) - qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); - else - qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + default: + ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); + return 0; + } - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } + return 0; +} - return; - } +static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum target, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +{ + int dataFormat, dataType; + qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + qboolean compressed = (!(picFormat == GL_RGBA8) || (picFormat == GL_SRGB8_ALPHA8_EXT)); + qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); + qboolean picmip = !!(flags & IMGFLAG_PICMIP); + int size, miplevel; + qboolean lastMip = qfalse; - switch(internalFormat) + switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_ARB: @@ -2111,52 +2087,83 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei break; } - if ( subtexture ) - qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); - else + if (!data) { - if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, 0); - else - qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + miplevel = 0; + do + { + lastMip = (width == 1 && height == 1) || !mipmap; + qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, NULL); + + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + miplevel++; + } + while (!lastMip); + + return; } - if (flags & IMGFLAG_MIPMAP) + if (compressed && picmip) { - int miplevel = 0; - - while (width > 1 || height > 1) + for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) { - if (data) - { - if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - else - R_MipMapsRGB( data, width, height ); - } - + size = CalculateMipSize(width, height, picFormat); + x >>= 1; + y >>= 1; width = MAX(1, width >> 1); height = MAX(1, height >> 1); - miplevel++; + data += size; + } + } - if ( data && r_colorMipLevels->integer ) - R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] ); + miplevel = 0; + do + { + lastMip = (width == 1 && height == 1) || !mipmap; + size = CalculateMipSize(width, height, picFormat); - if ( subtexture ) - { - x >>= 1; - y >>= 1; - qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); - } + if (compressed) + { + if (subtexture) + qglCompressedTextureSubImage2D(texture, target, miplevel, x, y, width, height, picFormat, size, data); else + qglCompressedTextureImage2D(texture, target, miplevel, picFormat, width, height, 0, size, data); + } + else + { + if (miplevel != 0 && r_colorMipLevels->integer) + R_BlendOverTexture((byte *)data, width * height, mipBlendColors[miplevel]); + + if (rgtc) + RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); + else if (subtexture) + qglTextureSubImage2D(texture, target, miplevel, x, y, width, height, dataFormat, dataType, data); + else + qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + + if (!lastMip && numMips < 2) { - if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) + R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap); else - qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + R_MipMapsRGB(data, width, height); } } + + x >>= 1; + y >>= 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + miplevel++; + + if (numMips > 1) + { + data += size; + numMips--; + } } + while (!lastMip); } /* @@ -2190,19 +2197,35 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic GLenum internalFormat = image->internalFormat; qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height); qboolean notScaled = qtrue; - qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); + qboolean compressed = (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT); + qboolean mipmap = !!(flags & IMGFLAG_MIPMAP) && (!compressed || numMips > 1); + qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP); + GLenum uploadTarget = cubemap ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : GL_TEXTURE_2D; + GLenum textureTarget = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; + int depth = cubemap ? 6 : 1; if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + for (i = 0; i < depth; i++) + RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, uploadTarget + i, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { - if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + if (compressed || cubemap) { - RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + for (i = 0; i < depth; i++) + { + int w2 = width, h2 = height; + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget + i, picFormat, numMips, internalFormat, type, flags, qfalse); + for (c = numMips; c; c--) + { + data += CalculateMipSize(w2, h2, picFormat); + w2 = MAX(1, w2 >> 1); + h2 = MAX(1, h2 >> 1); + } + } goto done; } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); @@ -2242,12 +2265,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2256,20 +2279,20 @@ done: if (mipmap) { - if ( textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) ); + if (textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer)); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - if ( textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + if (textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Fix for sampling depth buffer on old nVidia cards @@ -2280,9 +2303,9 @@ done: case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT32_ARB: - qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + qglTextureParameterf(image->texnum, textureTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; default: break; @@ -2338,68 +2361,24 @@ image_t *R_CreateImageExt2( const char *name, byte *pic, int width, int height, glWrapClampMode = GL_REPEAT; if (!internalFormat) - { - if (image->flags & IMGFLAG_CUBEMAP) - internalFormat = GL_RGBA8; - else - internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); - } + internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); image->internalFormat = internalFormat; - // lightmaps are always allocated on TMU 1 - if ( qglActiveTextureARB && isLightmap ) { - image->TMU = 1; - } else { - image->TMU = 0; - } - - if ( qglActiveTextureARB ) { - GL_SelectTexture( image->TMU ); - } - - GL_Bind(image); + Upload32(pic, 0, 0, image->width, image->height, picFormat, numMips, image); if (image->flags & IMGFLAG_CUBEMAP) { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (image->flags & IMGFLAG_MIPMAP) - { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - else - { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - - if (image->flags & IMGFLAG_MIPMAP) - qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); - - image->uploadWidth = width; - image->uploadHeight = height; + qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, glWrapClampMode); + qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, glWrapClampMode); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, glWrapClampMode); } else { - Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode); } - GL_SelectTexture( 0 ); - hash = generateHashValue( name ); image->next = hashTable[hash]; hashTable[hash] = image; @@ -2425,15 +2404,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { - if (qglActiveTextureARB) { - GL_SelectTexture(image->TMU); - } - - GL_Bind(image); - Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); - - GL_SelectTexture(0); } //=================================================================== @@ -2578,6 +2549,7 @@ image_t *R_FindImageFileExt( const char *name, imgType_t type, imgFlags_t flags, GLenum picFormat; int picNumMips; long hash; + imgFlags_t checkFlagsTrue, checkFlagsFalse; if ( !name ) { return NULL; @@ -2611,7 +2583,10 @@ image_t *R_FindImageFileExt( const char *name, imgType_t type, imgFlags_t flags, return NULL; } - if (r_normalMapping->integer && (picFormat == GL_RGBA8) && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP)) + checkFlagsTrue = IMGFLAG_PICMIP | IMGFLAG_MIPMAP | IMGFLAG_GENNORMALMAP; + checkFlagsFalse = IMGFLAG_CUBEMAP; + if (r_normalMapping->integer && (picFormat == GL_RGBA8) && (type == IMGTYPE_COLORALPHA) && + ((flags & checkFlagsTrue) == checkFlagsTrue) && !(flags & checkFlagsFalse)) { char normalName[MAX_QPATH]; image_t *normalImage; @@ -2714,6 +2689,20 @@ image_t *R_FindImageFileExt( const char *name, imgType_t type, imgFlags_t flags, } } + // force mipmaps off if image is compressed but doesn't have enough mips + if ((flags & IMGFLAG_MIPMAP) && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + { + int wh = MAX(width, height); + int neededMips = 0; + while (wh) + { + neededMips++; + wh >>= 1; + } + if (neededMips > picNumMips) + flags &= ~IMGFLAG_MIPMAP; + } + image = R_CreateImageExt2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0, characterMIP ); ri.Free( pic ); return image; @@ -3010,11 +2999,10 @@ void R_CreateBuiltinImages( void ) { for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); - GL_Bind(tr.sunShadowDepthImage[x]); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); @@ -3052,6 +3040,11 @@ void R_SetColorMappings( void ) { tr.overbrightBits = 0; } + // don't allow more overbright bits than map overbright bits + if ( tr.overbrightBits > r_mapOverBrightBits->integer ) { + tr.overbrightBits = r_mapOverBrightBits->integer; + } + tr.identityLight = 1.0f / ( 1 << tr.overbrightBits ); tr.identityLightByte = 255 * tr.identityLight; @@ -3123,17 +3116,11 @@ void R_DeleteTextures( void ) { for ( i = 0; i < tr.numImages ; i++ ) { qglDeleteTextures( 1, &tr.images[i]->texnum ); } - memset( tr.images, 0, sizeof( tr.images ) ); + Com_Memset( tr.images, 0, sizeof( tr.images ) ); - memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - GL_SelectTexture( 0 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - } else { - qglBindTexture( GL_TEXTURE_2D, 0 ); - } + tr.numImages = 0; + + GL_BindNullTextures(); } /* diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c index c034449..b485415 100644 --- a/SP/code/rend2/tr_init.c +++ b/SP/code/rend2/tr_init.c @@ -30,6 +30,8 @@ If you have questions concerning this license or the applicable additional terms #include "tr_local.h" +#include "tr_dsa.h" + glconfig_t glConfig; glRefConfig_t glRefConfig; qboolean textureFilterAnisotropic = qfalse; @@ -130,6 +132,7 @@ cvar_t *r_ext_framebuffer_multisample; cvar_t *r_arb_seamless_cube_map; cvar_t *r_arb_vertex_type_2_10_10_10_rev; cvar_t *r_arb_vertex_array_object; +cvar_t *r_ext_direct_state_access; cvar_t *r_mergeMultidraws; cvar_t *r_mergeLeafSurfaces; @@ -153,11 +156,6 @@ cvar_t *r_forceAutoExposure; cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMax; -cvar_t *r_materialGamma; -cvar_t *r_lightGamma; -cvar_t *r_framebufferGamma; -cvar_t *r_tonemapGamma; - cvar_t *r_depthPrepass; cvar_t *r_ssao; @@ -167,8 +165,7 @@ cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_cubemapSize; -cvar_t *r_specularIsMetallic; -cvar_t *r_glossIsRoughness; +cvar_t *r_pbr; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; cvar_t *r_baseParallax; @@ -1029,19 +1026,11 @@ void GL_SetDefaultState( void ) { qglColor4f( 1,1,1,1 ); - // initialize downstream texture unit if we're running - // in a multitexture environment - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); - qglDisable( GL_TEXTURE_2D ); - GL_SelectTexture( 0 ); - } + GL_BindNullTextures(); + GL_BindNullFramebuffers(); qglEnable( GL_TEXTURE_2D ); GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); //qglShadeModel( GL_SMOOTH ); qglDepthFunc( GL_LEQUAL ); @@ -1054,8 +1043,7 @@ void GL_SetDefaultState( void ) { glState.faceCulling = CT_TWO_SIDED; glState.faceCullFront = qtrue; - glState.currentProgram = 0; - qglUseProgramObjectARB(0); + GL_BindNullProgram(); if (glRefConfig.vertexArrayObject) qglBindVertexArrayARB(0); @@ -1306,6 +1294,7 @@ void R_Register( void ) { 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); r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH); + r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_ext_max_anisotropy = ri.Cvar_Get( "r_ext_max_anisotropy", "2", CVAR_ARCHIVE | CVAR_LATCH ); @@ -1351,7 +1340,7 @@ void R_Register( void ) { r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE ); - r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE ); r_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT ); r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.0", CVAR_CHEAT ); r_forceToneMapAvg = ri.Cvar_Get( "r_forceToneMapAvg", "-2.0", CVAR_CHEAT ); @@ -1364,11 +1353,6 @@ void R_Register( void ) { r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); - r_materialGamma = ri.Cvar_Get( "r_materialGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_lightGamma = ri.Cvar_Get( "r_lightGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_framebufferGamma = ri.Cvar_Get( "r_framebufferGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_tonemapGamma = ri.Cvar_Get( "r_tonemapGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE ); r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE ); @@ -1378,8 +1362,7 @@ void R_Register( void ) { r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH ); - r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); - r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); + r_pbr = ri.Cvar_Get("r_pbr", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h index c6df856..0435b29 100644 --- a/SP/code/rend2/tr_local.h +++ b/SP/code/rend2/tr_local.h @@ -27,7 +27,6 @@ If you have questions concerning this license or the applicable additional terms */ - #ifndef TR_LOCAL_H #define TR_LOCAL_H @@ -35,10 +34,6 @@ If you have questions concerning this license or the applicable additional terms #include "../qcommon/qfiles.h" #include "../qcommon/qcommon.h" #include "../renderer/tr_public.h" -#include "tr_extratypes.h" -#include "tr_extramath.h" -#include "tr_fbo.h" -#include "tr_postprocess.h" #include "qgl.h" #include "../renderer/iqm.h" @@ -132,6 +127,11 @@ typedef struct image_s { struct image_s* next; } image_t; +#include "tr_extratypes.h" +#include "tr_extramath.h" +#include "tr_fbo.h" +#include "tr_postprocess.h" + // Ensure this is >= the ATTR_INDEX_COUNT enum below #define VAO_MAX_ATTRIBS 16 @@ -1496,8 +1496,6 @@ typedef struct { // the renderer front end should never modify glstate_t typedef struct { - int currenttextures[NUM_TEXTURE_BUNDLES]; - int currenttmu; qboolean finishCalled; int texEnv[2]; int faceCulling; @@ -1507,7 +1505,6 @@ typedef struct { float vertexAttribsInterpolation; qboolean vertexAnimation; uint32_t vertexAttribsEnabled; // global if no VAOs, tess only otherwise - shaderProgram_t *currentProgram; FBO_t *currentFBO; vao_t *currentVao; mat4_t modelview; @@ -1565,6 +1562,7 @@ typedef struct { qboolean floatLightmap; qboolean vertexArrayObject; + qboolean directStateAccess; } glRefConfig_t; typedef struct { @@ -1923,6 +1921,7 @@ 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; extern cvar_t *r_arb_vertex_array_object; +extern cvar_t *r_ext_direct_state_access; extern cvar_t *r_waterFogColor; //----(SA) added extern cvar_t *r_mapFogColor; //----(SA) added @@ -1995,11 +1994,6 @@ extern cvar_t *r_forceAutoExposureMax; extern cvar_t *r_cameraExposure; -extern cvar_t *r_materialGamma; -extern cvar_t *r_lightGamma; -extern cvar_t *r_framebufferGamma; -extern cvar_t *r_tonemapGamma; - extern cvar_t *r_depthPrepass; extern cvar_t *r_ssao; @@ -2009,8 +2003,7 @@ extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_cubemapSize; -extern cvar_t *r_specularIsMetallic; -extern cvar_t *r_glossIsRoughness; +extern cvar_t *r_pbr; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; @@ -2117,17 +2110,14 @@ void R_RotateForEntity( const trRefEntity_t * ent, const viewParms_t * viewParms /* ** GL wrapper/helper functions */ -void GL_Bind( image_t *image ); void GL_BindToTMU( image_t *image, int tmu ); void GL_SetDefaultState( void ); -void GL_SelectTexture( int unit ); void GL_TextureMode( const char *string ); void GL_CheckErrs( char *file, int line ); #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__) void GL_State( unsigned long stateVector ); void GL_SetProjectionMatrix(mat4_t matrix); void GL_SetModelviewMatrix(mat4_t matrix); -void GL_TexEnv( int env ); void GL_Cull( int cullType ); #define GLS_SRCBLEND_ZERO 0x00000001 @@ -2483,7 +2473,6 @@ void GLSL_InitGPUShaders(void); void GLSL_ShutdownGPUShaders(void); void GLSL_VertexAttribPointers(uint32_t attribBits); void GLSL_BindProgram(shaderProgram_t * program); -void GLSL_BindNullProgram(void); void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value); void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value); diff --git a/SP/code/rend2/tr_main.c b/SP/code/rend2/tr_main.c index 785b4d6..79a5d46 100644 --- a/SP/code/rend2/tr_main.c +++ b/SP/code/rend2/tr_main.c @@ -2348,7 +2348,7 @@ void R_DebugGraphics( void ) { R_IssuePendingRenderCommands(); - GL_Bind( tr.whiteImage ); + GL_BindToTMU(tr.whiteImage, TB_COLORMAP); GL_Cull( CT_FRONT_SIDED ); ri.CM_DrawDebugSurface( R_DebugPolygon ); } diff --git a/SP/code/rend2/tr_postprocess.c b/SP/code/rend2/tr_postprocess.c index 35982fc..1952ae9 100644 --- a/SP/code/rend2/tr_postprocess.c +++ b/SP/code/rend2/tr_postprocess.c @@ -183,7 +183,7 @@ void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0); } - FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0); + FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0); } #else // higher quality blur, but slower else if (blur > 1.0f) @@ -217,7 +217,7 @@ void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float FBO_Blit(tr.quarterFbo[0], NULL, blurTexScale, tr.quarterFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } - FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0); + FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0); } #endif } @@ -232,49 +232,44 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc const float mul = powf(stretch, inc); float scale; - { - vec2_t texScale; + alpha *= inc; + VectorSet4(color, alpha, alpha, alpha, 1.0f); - texScale[0] = - texScale[1] = 1.0f; + if (srcFbo) + VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); + else + VectorSet4(srcBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - alpha *= inc; - VectorSet4(color, alpha, alpha, alpha, 1.0f); + VectorSet4(dstBox, x, y, w, h); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0); - VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); - VectorSet4(dstBox, x, y, w, h); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0); + --passes; + scale = mul; + while (passes > 0) + { + float iscale = 1.f / scale; + float s0 = xcenter * (1.f - iscale); + float t0 = (1.0f - ycenter) * (1.f - iscale); - --passes; - scale = mul; - while (passes > 0) + if (srcFbo) { - float iscale = 1.f / scale; - float s0 = xcenter * (1.f - iscale); - float t0 = (1.0f - ycenter) * (1.f - iscale); - float s1 = iscale + s0; - float t1 = iscale + t0; - - if (srcFbo) - { - srcBox[0] = s0 * srcFbo->width; - srcBox[1] = t0 * srcFbo->height; - srcBox[2] = (s1 - s0) * srcFbo->width; - srcBox[3] = (t1 - t0) * srcFbo->height; - } - else - { - srcBox[0] = s0 * glConfig.vidWidth; - srcBox[1] = t0 * glConfig.vidHeight; - srcBox[2] = (s1 - s0) * glConfig.vidWidth; - srcBox[3] = (t1 - t0) * glConfig.vidHeight; - } + srcBox[0] = s0 * srcFbo->width; + srcBox[1] = t0 * srcFbo->height; + srcBox[2] = iscale * srcFbo->width; + srcBox[3] = iscale * srcFbo->height; + } + else + { + srcBox[0] = s0 * glConfig.vidWidth; + srcBox[1] = t0 * glConfig.vidHeight; + srcBox[2] = iscale * glConfig.vidWidth; + srcBox[3] = iscale * glConfig.vidHeight; + } - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); - scale *= mul; - --passes; - } + scale *= mul; + --passes; } } @@ -329,7 +324,7 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // From RB_DrawSun() { float dist; - mat4_t trans, model, mvp; + mat4_t trans, model; Mat4Translation( backEnd.viewParms.or.origin, trans ); Mat4Multiply( backEnd.viewParms.world.modelMatrix, trans, model ); @@ -353,12 +348,8 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // initialize quarter buffers { float mul = 1.f; - vec2_t texScale; ivec4_t rayBox, quarterBox; - texScale[0] = - texScale[1] = 1.0f; - VectorSet4(color, mul, mul, mul, 1); if (srcFbo) @@ -408,14 +399,10 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // add result back on top of the main buffer { float mul = 1.f; - vec2_t texScale; - - texScale[0] = - texScale[1] = 1.0f; VectorSet4(color, mul, mul, mul, 1); - FBO_Blit(tr.quarterFbo[0], NULL, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); + FBO_Blit(tr.quarterFbo[0], NULL, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); } } @@ -443,31 +430,27 @@ static void RB_BlurAxis(FBO_t *srcFbo, FBO_t *dstFbo, float strength, qboolean h { ivec4_t srcBox, dstBox; vec4_t color; - vec2_t texScale; - - texScale[0] = - texScale[1] = 1.0f; VectorSet4(color, weights[0], weights[0], weights[0], 1.0f); VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); VectorSet4(dstBox, 0, 0, dstFbo->width, dstFbo->height); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0); VectorSet4(color, weights[1], weights[1], weights[1], 1.0f); dx = offsets[1] * xmul; dy = offsets[1] * ymul; VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); VectorSet4(color, weights[2], weights[2], weights[2], 1.0f); dx = offsets[2] * xmul; dy = offsets[2] * ymul; VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height); - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); } } @@ -492,10 +475,6 @@ void RB_GaussianBlur(float blur) { ivec4_t srcBox, dstBox; vec4_t color; - vec2_t texScale; - - texScale[0] = - texScale[1] = 1.0f; VectorSet4(color, 1, 1, 1, 1); @@ -507,7 +486,7 @@ void RB_GaussianBlur(float blur) VectorSet4(srcBox, 0, 0, tr.whiteImage->width, tr.whiteImage->height); VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - FBO_BlitFromTexture(tr.whiteImage, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.textureColorShader, color, GLS_DEPTHTEST_DISABLE); + FBO_BlitFromTexture(tr.whiteImage, srcBox, NULL, tr.textureScratchFbo[0], dstBox, NULL, color, GLS_DEPTHTEST_DISABLE); qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // blur the tiny buffer horizontally and vertically @@ -518,6 +497,6 @@ void RB_GaussianBlur(float blur) VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); color[3] = factor; - FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, NULL, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } } diff --git a/SP/code/rend2/tr_scene.c b/SP/code/rend2/tr_scene.c index 7064df4..648173b 100644 --- a/SP/code/rend2/tr_scene.c +++ b/SP/code/rend2/tr_scene.c @@ -465,7 +465,7 @@ void RE_BeginScene(const refdef_t *fd) else { #if defined(USE_OVERBRIGHT) - float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); + float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f; #else float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; #endif diff --git a/SP/code/rend2/tr_shade.c b/SP/code/rend2/tr_shade.c index 855396f..c044e9d 100644 --- a/SP/code/rend2/tr_shade.c +++ b/SP/code/rend2/tr_shade.c @@ -100,11 +100,9 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) { int index; if ( bundle->isVideoMap ) { - int oldtmu = glState.currenttmu; - GL_SelectTexture(tmu); ri.CIN_RunCinematic(bundle->videoMapHandle); ri.CIN_UploadCinematic(bundle->videoMapHandle); - GL_SelectTexture(oldtmu); + GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu); return; } @@ -143,7 +141,7 @@ Draws triangle outlines for debugging ================ */ static void DrawTris (shaderCommands_t *input) { - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglDepthRange( 0, 0 ); @@ -443,7 +441,7 @@ static void ProjectDlightTexture( void ) { vector[3] = scale; GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector); - GL_Bind( tr.dlightImage ); + GL_BindToTMU( tr.dlightImage, TB_COLORMAP ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered @@ -954,11 +952,7 @@ static void ForwardDlight( void ) { } if (r_dlightMode->integer >= 2) - { - GL_SelectTexture(TB_SHADOWMAP); - GL_Bind(tr.shadowCubemaps[l]); - GL_SelectTexture(0); - } + GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP); ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); @@ -1556,7 +1550,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) if ( backEnd.depthFill ) { if (!(pStage->stateBits & GLS_ATEST_BITS)) - GL_BindToTMU( tr.whiteImage, 0 ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } diff --git a/SP/code/rend2/tr_shader.c b/SP/code/rend2/tr_shader.c index f593fdc..fe6a93a 100644 --- a/SP/code/rend2/tr_shader.c +++ b/SP/code/rend2/tr_shader.c @@ -910,9 +910,18 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name ); continue; } - stage->specularScale[0] = - stage->specularScale[1] = - stage->specularScale[2] = atof( token ); + + if (r_pbr->integer) + { + // interpret specularReflectance < 0.5 as nonmetal + stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f; + } + else + { + stage->specularScale[0] = + stage->specularScale[1] = + stage->specularScale[2] = atof( token ); + } } // // specularExponent <value> @@ -930,8 +939,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { exponent = atof( token ); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25); else { // Change shininess to gloss @@ -956,8 +965,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { gloss = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = exp2f(-3.0f * gloss); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss); else stage->specularScale[3] = gloss; } @@ -977,8 +986,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { roughness = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = roughness; + if (r_pbr->integer) + stage->specularScale[0] = 1.0 - roughness; else { if (roughness >= 0.125) @@ -1038,6 +1047,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { } // // specularScale <rgb> <gloss> + // or specularScale <metallic> <smoothness> with r_pbr 1 // or specularScale <r> <g> <b> // or specularScale <r> <g> <b> <gloss> // @@ -1064,10 +1074,19 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) { token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { - // two values, rgb then gloss - stage->specularScale[3] = stage->specularScale[1]; - stage->specularScale[1] = - stage->specularScale[2] = stage->specularScale[0]; + if (r_pbr->integer) + { + // two values, metallic then smoothness + float smoothness = stage->specularScale[1]; + stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f; + stage->specularScale[0] = smoothness; + } + { + // two values, rgb then gloss + stage->specularScale[3] = stage->specularScale[1]; + stage->specularScale[1] = + stage->specularScale[2] = stage->specularScale[0]; + } continue; } @@ -2955,10 +2974,17 @@ static void InitShader( const char *name, int lightmapIndex ) { // default normal/specular VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f); - stages[i].specularScale[0] = - stages[i].specularScale[1] = - stages[i].specularScale[2] = r_baseSpecular->value; - stages[i].specularScale[3] = r_baseGloss->value; + if (r_pbr->integer) + { + stages[i].specularScale[0] = r_baseGloss->value; + } + else + { + stages[i].specularScale[0] = + stages[i].specularScale[1] = + stages[i].specularScale[2] = r_baseSpecular->value; + stages[i].specularScale[3] = r_baseGloss->value; + } } } diff --git a/SP/code/rend2/tr_shadows.c b/SP/code/rend2/tr_shadows.c index 7f9f60e..79fe443 100644 --- a/SP/code/rend2/tr_shadows.c +++ b/SP/code/rend2/tr_shadows.c @@ -213,7 +213,7 @@ void RB_ShadowTessEnd( void ) { // draw the silhouette edges - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); qglColor3f( 0.2f, 0.2f, 0.2f ); @@ -262,7 +262,7 @@ void RB_ShadowFinish( void ) { qglDisable( GL_CLIP_PLANE0 ); GL_Cull( CT_TWO_SIDED ); - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); qglLoadIdentity(); diff --git a/SP/code/rend2/tr_sky.c b/SP/code/rend2/tr_sky.c index e029f8c..1eeb915 100644 --- a/SP/code/rend2/tr_sky.c +++ b/SP/code/rend2/tr_sky.c @@ -385,7 +385,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max //tess.numIndexes = 0; tess.firstIndex = tess.numIndexes; - GL_Bind( image ); + GL_BindToTMU( image, TB_COLORMAP ); GL_Cull( CT_TWO_SIDED ); for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) @@ -502,7 +502,7 @@ static void DrawSkySideInner( struct image_s *image, const int mins[2], const in //tess.numIndexes = 0; tess.firstIndex = tess.numIndexes; - GL_Bind( image ); + GL_BindToTMU( image, TB_COLORMAP ); GL_Cull( CT_TWO_SIDED ); for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) diff --git a/SP/code/rend2/tr_surface.c b/SP/code/rend2/tr_surface.c index cbd2040..bc66a67 100644 --- a/SP/code/rend2/tr_surface.c +++ b/SP/code/rend2/tr_surface.c @@ -601,7 +601,7 @@ static void RB_SurfaceBeam( void ) { VectorAdd( start_points[i], direction, end_points[i] ); } - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); @@ -1769,7 +1769,7 @@ Draws x/y/z lines from the origin for orientation debugging */ static void RB_SurfaceAxis( void ) { #if 0 - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_DEFAULT ); qglLineWidth( 3 ); qglBegin( GL_LINES ); diff --git a/SP/code/renderer/qgl.h b/SP/code/renderer/qgl.h index 0125c8a..98326eb 100644 --- a/SP/code/renderer/qgl.h +++ b/SP/code/renderer/qgl.h @@ -815,12 +815,12 @@ extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLs #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #endif -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #endif #ifndef GL_ARB_texture_compression_bptc @@ -874,6 +874,50 @@ extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5 #endif +// GL_EXT_direct_state_access +extern GLvoid(APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +extern GLvoid(APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +extern GLvoid(APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +extern GLvoid(APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +extern GLvoid(APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + +extern GLvoid(APIENTRY * qglProgramUniform1i)(GLuint program, GLint location, GLint v0); +extern GLvoid(APIENTRY * qglProgramUniform1f)(GLuint program, GLint location, GLfloat v0); +extern GLvoid(APIENTRY * qglProgramUniform2f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +extern GLvoid(APIENTRY * qglProgramUniform3f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +extern GLvoid(APIENTRY * qglProgramUniform4f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +extern GLvoid(APIENTRY * qglProgramUniform1fv)(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +extern GLvoid(APIENTRY * qglProgramUniformMatrix4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern GLvoid(APIENTRY * qglNamedRenderbufferStorage)(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +extern GLvoid(APIENTRY * qglNamedRenderbufferStorageMultisample)(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +extern GLenum(APIENTRY * qglCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target); +extern GLvoid(APIENTRY * qglNamedFramebufferTexture2D)(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +extern GLvoid(APIENTRY * qglNamedFramebufferRenderbuffer)(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + #if defined(WIN32) // WGL_ARB_create_context #ifndef WGL_ARB_create_context diff --git a/SP/code/renderer/tr_image.c b/SP/code/renderer/tr_image.c index 48bbc55..2893b58 100644 --- a/SP/code/renderer/tr_image.c +++ b/SP/code/renderer/tr_image.c @@ -1730,9 +1730,11 @@ void R_DeleteTextures( void ) { for ( i = 0; i < tr.numImages ; i++ ) { qglDeleteTextures( 1, &tr.images[i]->texnum ); } - memset( tr.images, 0, sizeof( tr.images ) ); + Com_Memset( tr.images, 0, sizeof( tr.images ) ); - memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); + tr.numImages = 0; + + Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); if ( qglActiveTextureARB ) { GL_SelectTexture( 1 ); qglBindTexture( GL_TEXTURE_2D, 0 ); diff --git a/SP/code/renderer/tr_local.h b/SP/code/renderer/tr_local.h index 17070d2..a23037d 100644 --- a/SP/code/renderer/tr_local.h +++ b/SP/code/renderer/tr_local.h @@ -27,7 +27,6 @@ If you have questions concerning this license or the applicable additional terms */ - #ifndef TR_LOCAL_H #define TR_LOCAL_H diff --git a/SP/rend2-readme.txt b/SP/rend2-readme.txt index 235d844..f7b6bbb 100644 --- a/SP/rend2-readme.txt +++ b/SP/rend2-readme.txt @@ -219,6 +219,12 @@ Cvars for advanced material usage: 0.05 - Standard depth. (default) 0.1 - Looks broken. + r_pbr - Enable physically based rendering. + Experimental, will not look correct without + assets meant for it. + 0 - No. (default) + 1 - Yes. + Cvars for image interpolation and generation: r_imageUpsample - Use interpolation to artifically increase the resolution of all textures. Looks good @@ -337,21 +343,6 @@ Cvars that you probably don't care about or shouldn't mess with: r_shadowCascadeZBias - Z-bias for shadow cascade frustums. -256 - Default. - r_materialGamma - Gamma level for material textures. - (diffuse, specular) - 1.0 - RTCW, fastest. (default) - - r_lightGamma - Gamma level for light. - (lightmap, lightgrid, vertex lights) - 1.0 - RTCW, fastest. (default) - - r_framebufferGamma - Gamma level for framebuffers. - 1.0 - RTCW, fastest. (default) - - r_tonemapGamma - Gamma applied after tonemapping. - 1.0 - RTCW, fastest. (default) - - Cvars that have broken bits: r_dlightMode - Change how dynamic lights look. 0 - RTCW style dlights, fake -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits