diff --git a/src.cmake b/src.cmake index f18017e54e..e5d4eed5d4 100644 --- a/src.cmake +++ b/src.cmake @@ -157,7 +157,6 @@ set(GLSLSOURCELIST ${ENGINE_DIR}/renderer/glsl_source/vertexAnimation_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexSimple_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexSkinning_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexSprite_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/blurX_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/blurX_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/blurY_fp.glsl diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 1df69013a4..9de5390292 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -247,12 +247,12 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, drawSu gl_genericShaderMaterial->SetUniform_ColorMapBindless( BindAnimatedImage( 0, &pStage->bundle[TB_COLORMAP] ) ); } - bool needDepthMap = pStage->hasDepthFade || shader->autoSpriteMode; + bool needDepthMap = pStage->hasDepthFade; if ( needDepthMap ) { gl_genericShaderMaterial->SetUniform_DepthMapBindless( GL_BindToTMU( 1, tr.currentDepthImage ) ); } - bool hasDepthFade = pStage->hasDepthFade && !shader->autoSpriteMode; + bool hasDepthFade = pStage->hasDepthFade; if ( hasDepthFade ) { gl_genericShaderMaterial->SetUniform_DepthScale( pStage->depthFadeValue ); } @@ -959,7 +959,7 @@ void MaterialSystem::GenerateWorldCommandBuffer() { } shader = shader->remappedShader ? shader->remappedShader : shader; - if ( shader->isSky || shader->isPortal ) { + if ( shader->isSky || shader->isPortal || shader->autoSpriteMode ) { continue; } @@ -1067,13 +1067,12 @@ void BindShaderGeneric3D( Material* material ) { gl_genericShaderMaterial->SetTCGenEnvironment( material->tcGenEnvironment ); gl_genericShaderMaterial->SetTCGenLightmap( material->tcGen_Lightmap ); gl_genericShaderMaterial->SetDepthFade( material->hasDepthFade ); - gl_genericShaderMaterial->SetVertexSprite( material->vertexSprite ); // Bind shader program. gl_genericShaderMaterial->BindProgram( material->deformIndex ); // Set shader uniforms. - if ( material->tcGenEnvironment || material->vertexSprite ) { + if ( material->tcGenEnvironment ) { gl_genericShaderMaterial->SetUniform_ViewOrigin( backEnd.orientation.viewOrigin ); gl_genericShaderMaterial->SetUniform_ViewUp( backEnd.orientation.axis[2] ); } @@ -1146,17 +1145,11 @@ void BindShaderScreen( Material* material ) { void BindShaderHeatHaze( Material* material ) { // Select shader permutation. gl_heatHazeShaderMaterial->SetVertexAnimation( material->vertexAnimation ); - gl_heatHazeShaderMaterial->SetVertexSprite( material->vertexSprite ); // Bind shader program. gl_heatHazeShaderMaterial->BindProgram( material->deformIndex ); // Set shader uniforms. - if ( material->vertexSprite ) { - gl_heatHazeShaderMaterial->SetUniform_ViewOrigin( backEnd.orientation.viewOrigin ); - gl_heatHazeShaderMaterial->SetUniform_ViewUp( backEnd.orientation.axis[2] ); - } - gl_heatHazeShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); gl_heatHazeShaderMaterial->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[glState.stackIndex] ); } @@ -1184,15 +1177,12 @@ void ProcessMaterialNOP( Material*, shaderStage_t*, drawSurf_t* ) { // ProcessMaterial*() are essentially same as BindShader*(), but only set the GL program id to the material, // without actually binding it -void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSurf_t* drawSurf ) { - shader_t* shader = drawSurf->shader; - +void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSurf_t* ) { material->shader = gl_genericShaderMaterial; material->vertexAnimation = false; material->tcGenEnvironment = pStage->tcGen_Environment; material->tcGen_Lightmap = pStage->tcGen_Lightmap; - material->vertexSprite = shader->autoSpriteMode != 0; material->deformIndex = pStage->deformIndex; gl_genericShaderMaterial->SetVertexAnimation( false ); @@ -1200,10 +1190,9 @@ void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSu gl_genericShaderMaterial->SetTCGenEnvironment( pStage->tcGen_Environment ); gl_genericShaderMaterial->SetTCGenLightmap( pStage->tcGen_Lightmap ); - bool hasDepthFade = pStage->hasDepthFade && !shader->autoSpriteMode; + bool hasDepthFade = pStage->hasDepthFade; material->hasDepthFade = hasDepthFade; gl_genericShaderMaterial->SetDepthFade( hasDepthFade ); - gl_genericShaderMaterial->SetVertexSprite( shader->autoSpriteMode != 0 ); material->program = gl_genericShaderMaterial->GetProgram( pStage->deformIndex ); } @@ -1286,21 +1275,13 @@ void ProcessMaterialScreen( Material* material, shaderStage_t* pStage, drawSurf_ material->program = gl_screenShaderMaterial->GetProgram( pStage->deformIndex ); } -void ProcessMaterialHeatHaze( Material* material, shaderStage_t* pStage, drawSurf_t* drawSurf ) { - shader_t* shader = drawSurf->shader; - +void ProcessMaterialHeatHaze( Material* material, shaderStage_t* pStage, drawSurf_t* ) { material->shader = gl_heatHazeShaderMaterial; material->vertexAnimation = false; material->deformIndex = pStage->deformIndex; gl_heatHazeShaderMaterial->SetVertexAnimation( false ); - if ( shader->autoSpriteMode ) { - gl_heatHazeShaderMaterial->SetVertexSprite( true ); - } else { - gl_heatHazeShaderMaterial->SetVertexSprite( false ); - } - material->program = gl_heatHazeShaderMaterial->GetProgram( pStage->deformIndex ); } @@ -1447,7 +1428,7 @@ void MaterialSystem::GenerateWorldMaterials() { } shader = shader->remappedShader ? shader->remappedShader : shader; - if ( shader->isSky || shader->isPortal ) { + if ( shader->isSky || shader->isPortal || shader->autoSpriteMode ) { continue; } @@ -1807,6 +1788,7 @@ void MaterialSystem::Free() { generatedWorldCommandBuffer = false; dynamicDrawSurfs.clear(); + autospriteSurfaces.clear(); portalSurfaces.clear(); portalSurfacesTmp.clear(); portalBounds.clear(); @@ -1948,6 +1930,17 @@ void MaterialSystem::AddPortalSurfaces() { portalSurfacesSSBO.AreaIncr(); } +// autosprite[2] is not implemented in material system, draw them old-fashionedly +void MaterialSystem::AddAutospriteSurfaces() { + tr.currentEntity = &tr.worldEntity; + + for ( const drawSurf_t &drawSurf : autospriteSurfaces ) + { + R_AddDrawSurf( drawSurf.surface, drawSurf.shader, + drawSurf.lightmapNum(), drawSurf.fogNum(), drawSurf.bspSurface ); + } +} + void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderSort_t toSort, const uint32_t viewID ) { if ( !r_drawworld->integer ) { return; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index fe398d9ee1..f154575440 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -98,7 +98,6 @@ struct Material { bool tcGenEnvironment; bool tcGen_Lightmap; bool hasDepthFade; - bool vertexSprite; bool alphaTest; bool bspSurface; @@ -217,6 +216,7 @@ class MaterialSystem { std::vector portalSurfacesTmp; std::vector portalSurfaces; + std::vector autospriteSurfaces; std::vector portalBounds; uint32_t totalPortals; std::vector skyShaders; @@ -250,6 +250,7 @@ class MaterialSystem { const GLuint count, const GLuint firstIndex ); void AddPortalSurfaces(); + void AddAutospriteSurfaces(); void RenderMaterials( const shaderSort_t fromSort, const shaderSort_t toSort, const uint32_t viewID ); void UpdateDynamicSurfaces(); diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 6f8da6a9f3..d7a1731df6 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1592,7 +1592,7 @@ bool GLCompileMacro_USE_REFLECTIVE_SPECULAR::HasConflictingMacros( size_t permut { for (const GLCompileMacro* macro : macros) { - if ( ( permutation & macro->GetBit() ) != 0 && (macro->GetType() == USE_PHYSICAL_MAPPING || macro->GetType() == USE_VERTEX_SPRITE) ) + if ( ( permutation & macro->GetBit() ) != 0 && macro->GetType() == USE_PHYSICAL_MAPPING ) { //Log::Notice("conflicting macro! canceling '%s' vs. '%s'", GetName(), macro->GetName()); return true; @@ -1607,7 +1607,7 @@ bool GLCompileMacro_USE_VERTEX_SKINNING::HasConflictingMacros( size_t permutatio for (const GLCompileMacro* macro : macros) { //if(GLCompileMacro_USE_VERTEX_ANIMATION* m = dynamic_cast(macro)) - if ( ( permutation & macro->GetBit() ) != 0 && (macro->GetType() == USE_VERTEX_ANIMATION || macro->GetType() == USE_VERTEX_SPRITE) ) + if ( ( permutation & macro->GetBit() ) != 0 && macro->GetType() == USE_VERTEX_ANIMATION ) { //Log::Notice("conflicting macro! canceling '%s' vs. '%s'", GetName(), macro->GetName()); return true; @@ -1626,7 +1626,7 @@ bool GLCompileMacro_USE_VERTEX_ANIMATION::HasConflictingMacros( size_t permutati { for (const GLCompileMacro* macro : macros) { - if ( ( permutation & macro->GetBit() ) != 0 && (macro->GetType() == USE_VERTEX_SKINNING || macro->GetType() == USE_VERTEX_SPRITE) ) + if ( ( permutation & macro->GetBit() ) != 0 && macro->GetType() == USE_VERTEX_SKINNING ) { //Log::Notice("conflicting macro! canceling '%s' vs. '%s'", GetName(), macro->GetName()); return true; @@ -1643,20 +1643,6 @@ uint32_t GLCompileMacro_USE_VERTEX_ANIMATION::GetRequiredVertexAttributes() cons return attribs; } -bool GLCompileMacro_USE_VERTEX_SPRITE::HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const -{ - for (const GLCompileMacro* macro : macros) - { - if ( ( permutation & macro->GetBit() ) != 0 && (macro->GetType() == USE_VERTEX_SKINNING || macro->GetType() == USE_VERTEX_ANIMATION || macro->GetType() == USE_DEPTH_FADE)) - { - //Log::Notice("conflicting macro! canceling '%s' vs. '%s'", GetName(), macro->GetName()); - return true; - } - } - - return false; -} - bool GLCompileMacro_USE_TCGEN_ENVIRONMENT::HasConflictingMacros( size_t permutation, const std::vector ¯os) const { for (const GLCompileMacro* macro : macros) @@ -1685,20 +1671,6 @@ bool GLCompileMacro_USE_TCGEN_LIGHTMAP::HasConflictingMacros(size_t permutation, return false; } -bool GLCompileMacro_USE_DEPTH_FADE::HasConflictingMacros(size_t permutation, const std::vector ¯os) const -{ - for (const GLCompileMacro* macro : macros) - { - if ((permutation & macro->GetBit()) != 0 && (macro->GetType() == USE_VERTEX_SPRITE)) - { - //Log::Notice("conflicting macro! canceling '%s' vs. '%s'", GetName(), macro->GetName()); - return true; - } - } - - return false; -} - bool GLCompileMacro_USE_DELUXE_MAPPING::HasConflictingMacros(size_t permutation, const std::vector ¯os) const { for (const GLCompileMacro* macro : macros) @@ -1962,7 +1934,7 @@ void GLShader::DispatchComputeIndirect( const GLintptr indirectBuffer ) { glDispatchComputeIndirect( indirectBuffer ); } -void GLShader::SetRequiredVertexPointers( bool vertexSprite ) +void GLShader::SetRequiredVertexPointers() { uint32_t macroVertexAttribs = 0; @@ -1975,13 +1947,6 @@ void GLShader::SetRequiredVertexPointers( bool vertexSprite ) } uint32_t attribs = _vertexAttribsRequired | _vertexAttribs | macroVertexAttribs; // & ~_vertexAttribsUnsupported); - - if ( vertexSprite ) - { - attribs &= ~ATTR_QTANGENT; - attribs |= ATTR_ORIENTATION; - } - GL_VertexAttribsState( attribs ); } @@ -2040,7 +2005,6 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) : GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), - GLCompileMacro_USE_VERTEX_SPRITE( this ), GLCompileMacro_USE_TCGEN_ENVIRONMENT( this ), GLCompileMacro_USE_TCGEN_LIGHTMAP( this ), GLCompileMacro_USE_DEPTH_FADE( this ) @@ -2072,7 +2036,6 @@ GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : GLDeformStage( this ), // GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), - GLCompileMacro_USE_VERTEX_SPRITE( this ), GLCompileMacro_USE_TCGEN_ENVIRONMENT( this ), GLCompileMacro_USE_TCGEN_LIGHTMAP( this ), GLCompileMacro_USE_DEPTH_FADE( this ) { @@ -2615,8 +2578,7 @@ GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : u_VertexInterpolation( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), - GLCompileMacro_USE_VERTEX_ANIMATION( this ), - GLCompileMacro_USE_VERTEX_SPRITE( this ) + GLCompileMacro_USE_VERTEX_ANIMATION( this ) { } @@ -2647,8 +2609,8 @@ GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) u_VertexInterpolation( this ), GLDeformStage( this ), // GLCompileMacro_USE_VERTEX_SKINNING( this ), - GLCompileMacro_USE_VERTEX_ANIMATION( this ), - GLCompileMacro_USE_VERTEX_SPRITE( this ) { + GLCompileMacro_USE_VERTEX_ANIMATION( this ) +{ } void GLShader_heatHazeMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index a379a3d4ab..da1d325add 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -277,7 +277,7 @@ class GLShader void BindProgram( int deformIndex ); void DispatchCompute( const GLuint globalWorkgroupX, const GLuint globalWorkgroupY, const GLuint globalWorkgroupZ ); void DispatchComputeIndirect( const GLintptr indirectBuffer ); - void SetRequiredVertexPointers( bool vertexSprite = false ); + void SetRequiredVertexPointers(); bool IsMacroSet( int bit ) { @@ -1666,7 +1666,6 @@ class GLCompileMacro USE_BSP_SURFACE, USE_VERTEX_SKINNING, USE_VERTEX_ANIMATION, - USE_VERTEX_SPRITE, USE_TCGEN_ENVIRONMENT, USE_TCGEN_LIGHTMAP, USE_DELUXE_MAPPING, @@ -1812,37 +1811,6 @@ class GLCompileMacro_USE_VERTEX_ANIMATION : } }; -class GLCompileMacro_USE_VERTEX_SPRITE : - GLCompileMacro -{ -public: - GLCompileMacro_USE_VERTEX_SPRITE( GLShader *shader ) : - GLCompileMacro( shader ) - { - } - - const char *GetName() const override - { - return "USE_VERTEX_SPRITE"; - } - - EGLCompileMacro GetType() const override - { - return EGLCompileMacro::USE_VERTEX_SPRITE; - } - - bool HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; - uint32_t GetRequiredVertexAttributes() const override - { - return ATTR_QTANGENT; - } - - void SetVertexSprite( bool enable ) - { - SetMacro( enable ); - } -}; - class GLCompileMacro_USE_TCGEN_ENVIRONMENT : GLCompileMacro { @@ -2122,7 +2090,6 @@ class GLCompileMacro_USE_DEPTH_FADE : return "USE_DEPTH_FADE"; } - bool HasConflictingMacros(size_t permutation, const std::vector ¯os) const override; EGLCompileMacro GetType() const override { return EGLCompileMacro::USE_DEPTH_FADE; @@ -3945,7 +3912,6 @@ class GLShader_generic : public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, - public GLCompileMacro_USE_VERTEX_SPRITE, public GLCompileMacro_USE_TCGEN_ENVIRONMENT, public GLCompileMacro_USE_TCGEN_LIGHTMAP, public GLCompileMacro_USE_DEPTH_FADE @@ -3974,7 +3940,6 @@ class GLShader_genericMaterial : public GLDeformStage, // public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, - public GLCompileMacro_USE_VERTEX_SPRITE, public GLCompileMacro_USE_TCGEN_ENVIRONMENT, public GLCompileMacro_USE_TCGEN_LIGHTMAP, public GLCompileMacro_USE_DEPTH_FADE { @@ -4418,8 +4383,7 @@ class GLShader_heatHaze : public u_VertexInterpolation, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, - public GLCompileMacro_USE_VERTEX_ANIMATION, - public GLCompileMacro_USE_VERTEX_SPRITE + public GLCompileMacro_USE_VERTEX_ANIMATION { public: GLShader_heatHaze( GLShaderManager *manager ); @@ -4446,9 +4410,9 @@ class GLShader_heatHazeMaterial : public u_VertexInterpolation, public GLDeformStage, // public GLCompileMacro_USE_VERTEX_SKINNING, - public GLCompileMacro_USE_VERTEX_ANIMATION, - public GLCompileMacro_USE_VERTEX_SPRITE { - public: + public GLCompileMacro_USE_VERTEX_ANIMATION +{ +public: GLShader_heatHazeMaterial( GLShaderManager* manager ); void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; }; diff --git a/src/engine/renderer/glsl_source/generic_fp.glsl b/src/engine/renderer/glsl_source/generic_fp.glsl index c923d6a35c..42301f1998 100644 --- a/src/engine/renderer/glsl_source/generic_fp.glsl +++ b/src/engine/renderer/glsl_source/generic_fp.glsl @@ -34,7 +34,7 @@ uniform float u_InverseLightFactor; IN(smooth) vec2 var_TexCoords; IN(smooth) vec4 var_Color; -#if defined(USE_DEPTH_FADE) || defined(USE_VERTEX_SPRITE) +#if defined(USE_DEPTH_FADE) IN(smooth) vec2 var_FadeDepth; uniform sampler2D u_DepthMap; #endif @@ -53,7 +53,7 @@ void main() return; } -#if defined(USE_DEPTH_FADE) || defined(USE_VERTEX_SPRITE) +#if defined(USE_DEPTH_FADE) float depth = texture2D(u_DepthMap, gl_FragCoord.xy / r_FBufSize).x; float fadeDepth = 0.5 * var_FadeDepth.x / var_FadeDepth.y + 0.5; color.a *= smoothstep(gl_FragCoord.z, fadeDepth, depth); diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 3765151031..8de2de9e6f 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -25,12 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexSimple_vp #insert vertexSkinning_vp #insert vertexAnimation_vp -#insert vertexSprite_vp uniform mat4 u_TextureMatrix; -#if !defined(USE_VERTEX_SPRITE) uniform vec3 u_ViewOrigin; -#endif uniform float u_Time; @@ -41,9 +38,7 @@ uniform mat4 u_ModelMatrix; #endif uniform mat4 u_ModelViewProjectionMatrix; -#if defined(USE_VERTEX_SPRITE) -OUT(smooth) vec2 var_FadeDepth; -#elif defined(USE_DEPTH_FADE) +#if defined(USE_DEPTH_FADE) uniform float u_DepthScale; OUT(smooth) vec2 var_FadeDepth; #endif @@ -102,9 +97,6 @@ void main() // compute z of end of fading effect vec4 fadeDepth = u_ModelViewProjectionMatrix * (position - u_DepthScale * vec4(LB.normal, 0.0)); var_FadeDepth = fadeDepth.zw; -#elif defined(USE_VERTEX_SPRITE) - vec4 fadeDepth = u_ModelViewProjectionMatrix * (position - depthScale * vec4(LB.normal, 0.0)); - var_FadeDepth = fadeDepth.zw; #endif var_Color = color; diff --git a/src/engine/renderer/glsl_source/heatHaze_vp.glsl b/src/engine/renderer/glsl_source/heatHaze_vp.glsl index a9b4cd6544..29fd607409 100644 --- a/src/engine/renderer/glsl_source/heatHaze_vp.glsl +++ b/src/engine/renderer/glsl_source/heatHaze_vp.glsl @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexSimple_vp #insert vertexSkinning_vp #insert vertexAnimation_vp -#insert vertexSprite_vp uniform float u_Time; diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index 5a2ab6574d..32978b7b76 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexSimple_vp #insert vertexSkinning_vp #insert vertexAnimation_vp -#insert vertexSprite_vp #if !defined(USE_BSP_SURFACE) #define USE_MODEL_SURFACE diff --git a/src/engine/renderer/glsl_source/material_fp.glsl b/src/engine/renderer/glsl_source/material_fp.glsl index 6f4ac7107d..a721f10fe1 100644 --- a/src/engine/renderer/glsl_source/material_fp.glsl +++ b/src/engine/renderer/glsl_source/material_fp.glsl @@ -66,9 +66,9 @@ sampler2D u_ColorMap = sampler2D( u_ColorMap_initial ); #if defined(GENERIC_GLSL) sampler2D u_ColorMap = sampler2D( u_ColorMap_initial ); -#if defined(USE_DEPTH_FADE) || defined(USE_VERTEX_SPRITE) +#if defined(USE_DEPTH_FADE) sampler2D u_DepthMap = sampler2D( u_DepthMap_initial ); -#endif // !(USE_DEPTH_FADE || USE_VERTEX_SPRITE) +#endif #endif // !GENERIC_GLSL #if defined(HEATHAZE_GLSL) diff --git a/src/engine/renderer/glsl_source/vertexSimple_vp.glsl b/src/engine/renderer/glsl_source/vertexSimple_vp.glsl index b316351950..58eebaf142 100644 --- a/src/engine/renderer/glsl_source/vertexSimple_vp.glsl +++ b/src/engine/renderer/glsl_source/vertexSimple_vp.glsl @@ -38,7 +38,7 @@ void QTangentToLocalBasis( in vec4 qtangent, out localBasis LB ) { LB.binormal = QuatTransVec( qtangent, vec3( 0.0, 1.0, 0.0 ) ); } -#if !defined(USE_VERTEX_ANIMATION) && !defined(USE_VERTEX_SKINNING) && !defined(USE_VERTEX_SPRITE) +#if !defined(USE_VERTEX_ANIMATION) && !defined(USE_VERTEX_SKINNING) IN vec3 attr_Position; IN vec4 attr_Color; diff --git a/src/engine/renderer/glsl_source/vertexSprite_vp.glsl b/src/engine/renderer/glsl_source/vertexSprite_vp.glsl deleted file mode 100644 index 8b914c4307..0000000000 --- a/src/engine/renderer/glsl_source/vertexSprite_vp.glsl +++ /dev/null @@ -1,82 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2010 Robert Beckebans - -This file is part of XreaL source code. - -XreaL source code 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. - -XreaL source code 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 XreaL source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// vertexSprite_vp.glsl - sprite vertex fetch - -#if defined(USE_VERTEX_SPRITE) - -IN vec3 attr_Position; -IN vec4 attr_Color; -IN vec4 attr_TexCoord0; -IN vec4 attr_Orientation; - -uniform vec3 u_ViewOrigin; -uniform vec3 u_ViewUp; - -float depthScale; - -void VertexFetch(out vec4 position, - out localBasis normalBasis, - out vec4 color, - out vec2 texCoord, - out vec2 lmCoord) -{ - vec2 corner; - float radius = attr_Orientation.w; - vec3 normal = normalize( u_ViewOrigin - attr_Position ), up, left; - float s, c; // sin & cos of rotation factor - - corner = sign( attr_TexCoord0.zw ); - - if( radius <= 0.0 ) { - // autosprite2 mode, attr_Orientation.xyz contains the up-vector - up = attr_Orientation.xyz; - left = radius * normalize( cross( up, normal ) ); - position = vec4( attr_Position + corner.y * left, 1.0 ); - } else { - // autosprite mode, attr_Orientation.x contains the rotation angle - left = normalize( cross( u_ViewUp, normal ) ); - up = cross( left, normal ); - - s = radius * sin( radians( attr_Orientation.x ) ); - c = radius * cos( radians( attr_Orientation.x ) ); - - // rotate left and up vectors - vec3 leftOrig = left; - left = c * left + s * up; - up = c * up - s * leftOrig; - - left *= corner.x; - up *= corner.y; - - position = vec4( attr_Position + left + up, 1.0 ); - } - normalBasis.normal = normal; - normalBasis.tangent = normalize( up ); - normalBasis.binormal = normalize( left ); - - texCoord = 0.5 * corner + 0.5; //attr_TexCoord0.xy; - lmCoord = abs( attr_TexCoord0.zw ); - color = attr_Color; - - depthScale = 2.0 * radius; -} -#endif diff --git a/src/engine/renderer/shaders.cpp b/src/engine/renderer/shaders.cpp index 2953c09dc6..a41f284a9d 100644 --- a/src/engine/renderer/shaders.cpp +++ b/src/engine/renderer/shaders.cpp @@ -6,7 +6,6 @@ #include "vertexAnimation_vp.glsl.h" #include "vertexSimple_vp.glsl.h" #include "vertexSkinning_vp.glsl.h" -#include "vertexSprite_vp.glsl.h" #include "blurX_fp.glsl.h" #include "blurX_vp.glsl.h" #include "blurY_fp.glsl.h" @@ -131,5 +130,4 @@ std::unordered_map shadermap({ { "vertexAnimation_vp.glsl", std::string(reinterpret_cast(vertexAnimation_vp_glsl), sizeof(vertexAnimation_vp_glsl)) }, { "vertexSimple_vp.glsl", std::string(reinterpret_cast(vertexSimple_vp_glsl), sizeof(vertexSimple_vp_glsl)) }, { "vertexSkinning_vp.glsl", std::string(reinterpret_cast(vertexSkinning_vp_glsl), sizeof(vertexSkinning_vp_glsl)) }, - { "vertexSprite_vp.glsl", std::string(reinterpret_cast(vertexSprite_vp_glsl), sizeof(vertexSprite_vp_glsl)) }, }); diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index a5de777d17..a19e508cd4 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -1913,7 +1913,6 @@ static void RB_SetupLightForLighting( trRefLight_t *light ) gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); gl_genericShader->SetTCGenEnvironment( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); gl_genericShader->BindProgram( 0 ); @@ -2783,7 +2782,6 @@ void RB_RunVisTests( ) gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -3418,7 +3416,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -3579,7 +3576,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -3696,7 +3692,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -3764,7 +3759,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -3979,7 +3973,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -4101,7 +4094,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -4171,7 +4163,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -4264,7 +4255,6 @@ static void RB_RenderDebugUtils() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -4559,7 +4549,6 @@ void DebugDrawBegin( debugDrawMode_t mode, float size ) { gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -5695,7 +5684,6 @@ void RB_ShowImages() gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); - gl_genericShader->SetVertexSprite( false ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 3f6d39e53b..531f98854e 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -2974,7 +2974,7 @@ static void R_CreateWorldVBO() { surface = &s_worldData.surfaces[ k ]; - if ( surface->shader->isPortal ) + if ( surface->shader->isPortal || surface->shader->autoSpriteMode != 0 ) { continue; } @@ -3049,7 +3049,7 @@ static void R_CreateWorldVBO() shader1 = surf1->shader; - if ( shader1->isPortal ) + if ( shader1->isPortal || shader1->autoSpriteMode != 0 ) { continue; } @@ -3117,6 +3117,12 @@ static void R_CreateWorldVBO() continue; } + if ( surface->shader->autoSpriteMode != 0 ) + { + // don't use VBO because verts are rewritten each time based on view origin + continue; + } + if ( *surface->data == surfaceType_t::SF_FACE || *surface->data == surfaceType_t::SF_GRID || *surface->data == surfaceType_t::SF_TRIANGLES ) { surfaces[ numSurfaces++ ] = surface; @@ -3183,8 +3189,6 @@ static void R_CreateWorldVBO() } rb_surfaceTable[Util::ordinal(surfaceType_t::SF_FACE)](srf ); - Tess_AutospriteDeform( surface->shader->autoSpriteMode, srf->firstVert, srf->numVerts, - 3 * srf->firstTriangle, 3 * srf->numTriangles ); } else if ( *surface->data == surfaceType_t::SF_GRID ) { @@ -3219,8 +3223,6 @@ static void R_CreateWorldVBO() } rb_surfaceTable[Util::ordinal(surfaceType_t::SF_GRID)](srf ); - Tess_AutospriteDeform( surface->shader->autoSpriteMode, srf->firstVert, srf->numVerts, - 3 * srf->firstTriangle, 3 * srf->numTriangles ); } else if ( *surface->data == surfaceType_t::SF_TRIANGLES ) { @@ -3255,15 +3257,12 @@ static void R_CreateWorldVBO() } rb_surfaceTable[Util::ordinal(surfaceType_t::SF_TRIANGLES)](srf ); - Tess_AutospriteDeform( surface->shader->autoSpriteMode, srf->firstVert, srf->numVerts, - 3 * srf->firstTriangle, 3 * srf->numTriangles ); } } - // autosprite/autosprite2 surfaces have ATTR_ORIENTATION and everything else ATTR_QTANGENT. s_worldData.vbo = R_CreateStaticVBO2( "staticWorld_VBO %i", numVerts, vboVerts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_ORIENTATION | ATTR_COLOR ); + ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR ); s_worldData.ibo = R_CreateStaticIBO2( va( "staticWorld_IBO %i", 0 ), numTriangles, vboIdxs ); Tess_Clear(); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 75181ae996..f6e2bc1277 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -658,9 +658,6 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED }; ATTR_INDEX_QTANGENT, ATTR_INDEX_COLOR, - // Sprites - ATTR_INDEX_ORIENTATION, - // GPU vertex skinning ATTR_INDEX_BONE_FACTORS, @@ -677,7 +674,6 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED }; "attr_TexCoord0", "attr_QTangent", "attr_Color", - "attr_Orientation", "attr_BoneFactors", "attr_Position2", "attr_QTangent2" @@ -690,7 +686,6 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED }; ATTR_QTANGENT = BIT( ATTR_INDEX_QTANGENT ), ATTR_COLOR = BIT( ATTR_INDEX_COLOR ), - ATTR_ORIENTATION = BIT( ATTR_INDEX_ORIENTATION ), ATTR_BONE_FACTORS = BIT( ATTR_INDEX_BONE_FACTORS ), // for .md3 interpolation @@ -1300,8 +1295,6 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED }; bool interactLight; // this shader can interact with light shaders - // mode 1 can be used in BSP surfaces or with RT_SPRITE - // mode 2 can be used only in BSP surfaces int autoSpriteMode; uint8_t numDeforms; @@ -3276,10 +3269,7 @@ inline bool checkGLErrors() struct shaderVertex_t { vec3_t xyz; Color::Color32Bit color; - union { - i16vec4_t qtangents; - f16vec4_t spriteOrientation; - }; + i16vec4_t qtangents; f16vec4_t texCoords; }; @@ -3678,8 +3668,7 @@ inline bool checkGLErrors() void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t normalized, vec4_t window ); float R_ProjectRadius( float r, vec3_t location ); - void Tess_AutospriteDeform( int mode, int firstVertex, int numVertexes, - int firstIndex, int numIndexes ); + void Tess_AutospriteDeform( int mode ); float RB_EvalWaveForm( const waveForm_t *wf ); float RB_EvalWaveFormClamped( const waveForm_t *wf ); diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 34228980d8..2358a3a7e1 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -1949,7 +1949,7 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int lightmapNum, i tr.refdef.numDrawSurfs++; // Portal and sky surfaces are not handled by the material system at all - if ( materialSystem.generatingWorldCommandBuffer && ( shader->isPortal || shader->isSky ) ) { + if ( materialSystem.generatingWorldCommandBuffer && ( shader->isPortal || shader->isSky || shader->autoSpriteMode ) ) { if ( shader->isSky && std::find( materialSystem.skyShaders.begin(), materialSystem.skyShaders.end(), shader ) == materialSystem.skyShaders.end() ) { materialSystem.skyShaders.emplace_back( shader ); @@ -1963,6 +1963,11 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int lightmapNum, i materialSystem.portalSurfacesTmp.end() ); materialSystem.portalSurfacesTmp.emplace_back( drawSurf ); } + + if ( shader->autoSpriteMode ) { + materialSystem.autospriteSurfaces.push_back( *drawSurf ); + } + return; } @@ -2833,6 +2838,7 @@ void R_RenderView( viewParms_t *parms ) if ( glConfig2.materialSystemAvailable ) { tr.viewParms.viewID = tr.viewCount; materialSystem.QueueSurfaceCull( tr.viewCount, tr.viewParms.pvsOrigin, (frustum_t*) tr.viewParms.frustums[0] ); + materialSystem.AddAutospriteSurfaces(); } else { R_AddWorldSurfaces(); } diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 63375a6aa8..10530ad7ab 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -612,11 +612,8 @@ static void DrawTris() GLimp_LogComment( "--- DrawTris ---\n" ); - bool vertexSprite = tess.surfaceShader->autoSpriteMode != 0; - gl_genericShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_genericShader->SetVertexAnimation( tess.vboVertexAnimation ); - gl_genericShader->SetVertexSprite( vertexSprite ); gl_genericShader->SetTCGenEnvironment( false ); gl_genericShader->SetTCGenLightmap( false ); gl_genericShader->SetDepthFade( false ); @@ -667,7 +664,7 @@ static void DrawTris() GL_BindToTMU( 0, tr.whiteImage ) ); gl_genericShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); - gl_genericShader->SetRequiredVertexPointers( vertexSprite ); + gl_genericShader->SetRequiredVertexPointers(); glDepthRange( 0, 0 ); @@ -735,7 +732,7 @@ void Tess_Begin( void ( *stageIteratorFunc )(), tess.surfaceLastStage = nullptr; } - Tess_MapVBOs( false ); + Tess_MapVBOs( tess.surfaceShader && tess.surfaceShader->autoSpriteMode != 0 ); if ( !tess.stageIteratorFunc ) { @@ -783,9 +780,8 @@ static void Render_generic2D( shaderStage_t *pStage ) GL_State( pStage->stateBits ); - bool hasDepthFade = pStage->hasDepthFade && !tess.surfaceShader->autoSpriteMode; - bool needDepthMap = pStage->hasDepthFade || tess.surfaceShader->autoSpriteMode; - bool vertexSprite = tess.surfaceShader->autoSpriteMode != 0; + bool hasDepthFade = pStage->hasDepthFade; + bool needDepthMap = pStage->hasDepthFade; // choose right shader program ---------------------------------- gl_generic2DShader->SetDepthFade( hasDepthFade ); @@ -832,7 +828,7 @@ static void Render_generic2D( shaderStage_t *pStage ) ); } - gl_generic2DShader->SetRequiredVertexPointers( vertexSprite ); + gl_generic2DShader->SetRequiredVertexPointers(); Tess_DrawElements(); GL_CheckErrors(); @@ -856,9 +852,8 @@ void Render_generic3D( shaderStage_t *pStage ) GL_State( pStage->stateBits ); - bool hasDepthFade = pStage->hasDepthFade && !tess.surfaceShader->autoSpriteMode; - bool needDepthMap = pStage->hasDepthFade || tess.surfaceShader->autoSpriteMode; - bool vertexSprite = tess.surfaceShader->autoSpriteMode != 0; + bool hasDepthFade = pStage->hasDepthFade; + bool needDepthMap = pStage->hasDepthFade; // choose right shader program ---------------------------------- gl_genericShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); @@ -866,12 +861,11 @@ void Render_generic3D( shaderStage_t *pStage ) gl_genericShader->SetTCGenEnvironment( pStage->tcGen_Environment ); gl_genericShader->SetTCGenLightmap( pStage->tcGen_Lightmap ); gl_genericShader->SetDepthFade( hasDepthFade ); - gl_genericShader->SetVertexSprite( vertexSprite ); gl_genericShader->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ // set uniforms - if ( pStage->tcGen_Environment || vertexSprite ) + if ( pStage->tcGen_Environment ) { // calculate the environment texcoords in object space gl_genericShader->SetUniform_ViewOrigin( backEnd.orientation.viewOrigin ); @@ -938,7 +932,7 @@ void Render_generic3D( shaderStage_t *pStage ) ); } - gl_genericShader->SetRequiredVertexPointers( vertexSprite ); + gl_genericShader->SetRequiredVertexPointers(); Tess_DrawElements(); @@ -2151,20 +2145,11 @@ void Render_heatHaze( shaderStage_t *pStage ) // choose right shader program ---------------------------------- gl_heatHazeShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_heatHazeShader->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); - bool vertexSprite = tess.surfaceShader->autoSpriteMode != 0; - gl_heatHazeShader->SetVertexSprite( vertexSprite ); gl_heatHazeShader->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ // set uniforms - if ( vertexSprite ) - { - // calculate the environment texcoords in object space - gl_heatHazeShader->SetUniform_ViewOrigin( backEnd.orientation.viewOrigin ); - gl_heatHazeShader->SetUniform_ViewUp( backEnd.orientation.axis[ 2 ] ); - } - deformMagnitude = RB_EvalExpression( &pStage->deformMagnitudeExp, 1.0 ); gl_heatHazeShader->SetUniform_DeformMagnitude( deformMagnitude ); @@ -2215,7 +2200,7 @@ void Render_heatHaze( shaderStage_t *pStage ) GL_BindToTMU( 1, tr.currentRenderImage[backEnd.currentMainFBO] ) ); - gl_heatHazeShader->SetRequiredVertexPointers( vertexSprite ); + gl_heatHazeShader->SetRequiredVertexPointers(); Tess_DrawElements(); @@ -2754,6 +2739,11 @@ void Tess_StageIteratorColor() GL_CheckErrors(); + if ( tess.surfaceShader->autoSpriteMode != 0 ) + { + Tess_AutospriteDeform( tess.surfaceShader->autoSpriteMode ); + } + if ( !glState.currentVBO || !glState.currentIBO || glState.currentVBO == tess.vbo || glState.currentIBO == tess.ibo ) { Tess_UpdateVBOs( ); @@ -2819,6 +2809,11 @@ void Tess_StageIteratorPortal() { GL_CheckErrors(); + if ( tess.surfaceShader->autoSpriteMode != 0 ) + { + Tess_AutospriteDeform( tess.surfaceShader->autoSpriteMode ); + } + if ( !glState.currentVBO || !glState.currentIBO || glState.currentVBO == tess.vbo || glState.currentIBO == tess.ibo ) { Tess_UpdateVBOs(); } @@ -2854,6 +2849,11 @@ void Tess_StageIteratorShadowFill() GL_CheckErrors(); + if ( tess.surfaceShader->autoSpriteMode != 0 ) + { + Tess_AutospriteDeform( tess.surfaceShader->autoSpriteMode ); + } + if ( !glState.currentVBO || !glState.currentIBO || glState.currentVBO == tess.vbo || glState.currentIBO == tess.ibo ) { Tess_UpdateVBOs( ); @@ -2910,6 +2910,11 @@ void Tess_StageIteratorLighting() light = backEnd.currentLight; + if ( tess.surfaceShader->autoSpriteMode != 0 ) + { + Tess_AutospriteDeform( tess.surfaceShader->autoSpriteMode ); + } + if ( !glState.currentVBO || !glState.currentIBO || glState.currentVBO == tess.vbo || glState.currentIBO == tess.ibo ) { Tess_UpdateVBOs( ); diff --git a/src/engine/renderer/tr_shade_calc.cpp b/src/engine/renderer/tr_shade_calc.cpp index adf3531f8e..05e936c39e 100644 --- a/src/engine/renderer/tr_shade_calc.cpp +++ b/src/engine/renderer/tr_shade_calc.cpp @@ -463,87 +463,75 @@ DEFORMATIONS ==================================================================== */ +static void GlobalVectorToLocal( const vec3_t in, vec3_t out ) +{ + out[ 0 ] = DotProduct( in, backEnd.orientation.axis[ 0 ] ); + out[ 1 ] = DotProduct( in, backEnd.orientation.axis[ 1 ] ); + out[ 2 ] = DotProduct( in, backEnd.orientation.axis[ 2 ] ); +} + /* ===================== AutospriteDeform Assuming all the triangles for this shader are independent quads, rebuild them as forward facing sprites +They face toward the *view direction* like autosprite2 style 0. We could implement style +1 (toward viewer) here as well, but the difference seems less noticeable. ===================== */ -static void ComputeCorner( int firstVertex, int numVertexes ) +static void AutospriteDeform( uint32_t numVertexes ) { - int i, j; - shaderVertex_t *v; - vec4_t tc, midtc; + vec3_t leftDir, upDir; - for ( i = 0; i < numVertexes; i += 4 ) { - // find the midpoint - v = &tess.verts[ firstVertex + i ]; + if ( backEnd.currentEntity != &tr.worldEntity ) + { + GlobalVectorToLocal( backEnd.viewParms.orientation.axis[ 1 ], leftDir ); + GlobalVectorToLocal( backEnd.viewParms.orientation.axis[ 2 ], upDir ); + } + else + { + VectorCopy( backEnd.viewParms.orientation.axis[ 1 ], leftDir ); + VectorCopy( backEnd.viewParms.orientation.axis[ 2 ], upDir ); + } - Vector4Set( midtc, 0.0f, 0.0f, 0.0f, 0.0f ); - for( j = 0; j < 4; j++ ) { - halfToFloat( v[ j ].texCoords, tc ); - VectorAdd( tc, midtc, midtc ); - midtc[ 3 ] += tc[ 3 ]; - } + float scale = 1.0 / M_SQRT2; - midtc[ 0 ] = 0.25f * midtc[ 0 ]; - midtc[ 1 ] = 0.25f * midtc[ 1 ]; + if ( backEnd.currentEntity->e.nonNormalizedAxes ) + { + float axisLength = VectorLength( backEnd.currentEntity->e.axis[ 0 ] ); - for ( j = 0; j < 4; j++ ) { - halfToFloat( v[ j ].texCoords, tc ); - if( tc[ 0 ] < midtc[ 0 ] ) { - tc[ 2 ] = -tc[ 2 ]; - } - if( tc[ 1 ] < midtc[ 1 ] ) { - tc[ 3 ] = -tc[ 3 ]; - } - floatToHalf( tc, v[ j ].texCoords ); + if ( axisLength ) + { + scale /= axisLength; } } -} - -static void AutospriteDeform( int firstVertex, int numVertexes, int numIndexes ) -{ - int i, j; - shaderVertex_t *v; - vec3_t mid, delta; - float radius; - if ( numVertexes & 3 ) + for ( uint32_t i = 0; i < numVertexes; i += 4 ) { - Log::Warn("Autosprite shader %s had odd vertex count", tess.surfaceShader->name ); - } + const shaderVertex_t *v = tess.vertsBuffer + i; - if ( numIndexes != ( numVertexes >> 2 ) * 6 ) - { - Log::Warn("Autosprite shader %s had odd index count", tess.surfaceShader->name ); - } + // find the midpoint + vec3_t center; + VectorAdd( v[ 0 ].xyz, v[ 1 ].xyz, center ); + VectorAdd( center, v[ 2 ].xyz, center ); + VectorAdd( center, v[ 3 ].xyz, center ); + VectorScale( center, 0.25f, center ); - ComputeCorner( firstVertex, numVertexes ); + vec3_t delta; + VectorSubtract( v[ 0 ].xyz, center, delta ); + float radius = VectorLength( delta ) * scale; - for ( i = 0; i < numVertexes; i += 4 ) - { - // find the midpoint - v = &tess.verts[ firstVertex + i ]; - - mid[ 0 ] = 0.25f * ( v[ 0 ].xyz[ 0 ] + v[ 1 ].xyz[ 0 ] + v[ 2 ].xyz[ 0 ] + v[ 3 ].xyz[ 0 ] ); - mid[ 1 ] = 0.25f * ( v[ 0 ].xyz[ 1 ] + v[ 1 ].xyz[ 1 ] + v[ 2 ].xyz[ 1 ] + v[ 3 ].xyz[ 1 ] ); - mid[ 2 ] = 0.25f * ( v[ 0 ].xyz[ 2 ] + v[ 1 ].xyz[ 2 ] + v[ 2 ].xyz[ 2 ] + v[ 3 ].xyz[ 2 ] ); - - VectorSubtract( v[ 0 ].xyz, mid, delta ); - radius = VectorLength( delta ) * 0.5f * M_SQRT2; - - // add 4 identical vertices - for ( j = 0; j < 4; j++ ) { - VectorCopy( mid, v[ j ].xyz ); - Vector4Set( v[ j ].spriteOrientation, - floatToHalf( 0 ), - floatToHalf( 0 ), - floatToHalf( 0 ), - floatToHalf( radius ) ); + vec3_t left, up; + VectorScale( leftDir, radius, left ); + VectorScale( upDir, radius, up ); + + if ( backEnd.viewParms.mirrorLevel & 1 ) + { + VectorNegate( left, left ); } + + Tess_AddQuadStamp( center, left, up, v->color ); } } @@ -554,125 +542,106 @@ Autosprite2Deform Autosprite2 will pivot a rectangular quad along the center of its long axis ===================== */ -static const int edgeVerts[ 6 ][ 2 ] = -{ - { 0, 1 }, - { 0, 2 }, - { 0, 3 }, - { 1, 2 }, - { 1, 3 }, - { 2, 3 } -}; - -static void Autosprite2Deform( int firstVertex, int numVertexes, int numIndexes ) +// Style 0 is what Tremulous did but style 1 generally looks better, even with Tremulous assets. +// Style 0 looks stupid because you can see the sprite rotating if you stand still and move the +// mouse. Style 1 does a better job for making something look cylindrical, like the "pillar of flame" +// suggested in the Q3 manual. Either one will look bad beyond the ends of the long axis. +static Cvar::Range> r_autosprite2Style( + "r_autosprite2Style", "display autosprite2 surfaces facing (0) in view direction or (1) toward viewer", + Cvar::NONE, 1, 0, 1); +static void Autosprite2Deform( uint32_t numVertexes ) { - shaderVertex_t *v = &tess.verts[ firstVertex ]; - int i, j, k; - vec3_t oldPos[4]; - - if ( numVertexes & 3 ) - { - Log::Warn("Autosprite2 shader %s had odd vertex count", tess.surfaceShader->name ); - } - - if ( numIndexes != ( numVertexes >> 2 ) * 6 ) - { - Log::Warn("Autosprite2 shader %s had odd index count", tess.surfaceShader->name ); - } - - ComputeCorner( firstVertex, numVertexes ); + tess.numVertexes = numVertexes; + tess.numIndexes = ( numVertexes >> 2 ) * 6; + std::copy_n( tess.indexesBuffer, tess.numIndexes, tess.indexes ); // this is a lot of work for two triangles... // we could precalculate a lot of it is an issue, but it would mess up // the shader abstraction - for ( i = 0; i < numVertexes; i += 4, v += 4 ) + for ( uint32_t i = 0, indexes = 0; i < tess.numVertexes; i += 4, indexes += 6 ) { - float lengths[ 2 ]; - int nums[ 2 ]; - vec3_t mid[ 2 ]; - vec3_t normal, cross; - vec3_t major, minor; - shaderVertex_t *v1, *v2; - - VectorCopy( v[0].xyz, oldPos[0] ); - VectorCopy( v[1].xyz, oldPos[1] ); - VectorCopy( v[2].xyz, oldPos[2] ); - VectorCopy( v[3].xyz, oldPos[3] ); - - R_QtangentsToNormal( v->qtangents, normal ); - - // find the midpoint - - // identify the two shortest edges - nums[ 0 ] = nums[ 1 ] = 0; - lengths[ 0 ] = lengths[ 1 ] = 999999; - - for ( j = 0; j < 6; j++ ) + struct TriSide { + vec3_t firstVert; + float lengthSq; + vec3_t vector; // second point minus first point + }; + + TriSide sides[ 3 ]; + VectorCopy( tess.vertsBuffer[ tess.indexesBuffer[ indexes + 0 ] ].xyz, sides[ 0 ].firstVert ); + VectorCopy( tess.vertsBuffer[ tess.indexesBuffer[ indexes + 1 ] ].xyz, sides[ 1 ].firstVert ); + VectorCopy( tess.vertsBuffer[ tess.indexesBuffer[ indexes + 2 ] ].xyz, sides[ 2 ].firstVert ); + + for ( int j = 0; j < 3; j++ ) { - float l; - vec3_t temp; - - v1 = v + edgeVerts[ j ][ 0 ]; - v2 = v + edgeVerts[ j ][ 1 ]; - - VectorSubtract( v1->xyz, v2->xyz, temp ); + VectorSubtract( sides[ (j + 1) % 3 ].firstVert, sides[ j ].firstVert, sides[ j ].vector ); + sides[ j ].lengthSq = VectorLengthSquared( sides[ j ].vector ); + } - l = DotProduct( temp, temp ); + std::sort( std::begin( sides ), std::end( sides ), + []( TriSide &a, TriSide &b ) { return a.lengthSq < b.lengthSq; } ); + // Now sides[ 0 ] should be a short side of the rectangle, sides[ 1 ] a long side, + // and sides[ 2 ] a diagonal - if ( l < lengths[ 0 ] ) - { - nums[ 1 ] = nums[ 0 ]; - lengths[ 1 ] = lengths[ 0 ]; - nums[ 0 ] = j; - lengths[ 0 ] = l; - } - else if ( l < lengths[ 1 ] ) - { - nums[ 1 ] = j; - lengths[ 1 ] = l; - } + vec3_t forward; + if ( backEnd.currentEntity != &tr.worldEntity ) + { + // FIXME: implement style 1 here + GlobalVectorToLocal( backEnd.viewParms.orientation.axis[ 0 ], forward ); } - - for ( j = 0; j < 2; j++ ) + else if ( r_autosprite2Style.Get() == 0 ) { - v1 = v + edgeVerts[ nums[ j ] ][ 0 ]; - v2 = v + edgeVerts[ nums[ j ] ][ 1 ]; - - mid[ j ][ 0 ] = 0.5f * ( v1->xyz[ 0 ] + v2->xyz[ 0 ] ); - mid[ j ][ 1 ] = 0.5f * ( v1->xyz[ 1 ] + v2->xyz[ 1 ] ); - mid[ j ][ 2 ] = 0.5f * ( v1->xyz[ 2 ] + v2->xyz[ 2 ] ); + VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], forward ); } - - // find the vector of the major axis - VectorSubtract( mid[ 1 ], mid[ 0 ], major ); - CrossProduct( major, normal, cross ); - - // update the vertices - for ( j = 0; j < 4; j++ ) + else { - vec4_t orientation; - - v1 = v + j; - lengths[ 0 ] = Distance( mid[ 0 ], v1->xyz ); - lengths[ 1 ] = Distance( mid[ 1 ], v1->xyz ); + vec3_t quadCenter; + VectorMA( sides[ 2 ].firstVert, 0.5f, sides[ 2 ].vector, quadCenter ); + VectorSubtract( quadCenter, backEnd.viewParms.orientation.origin, forward ); + VectorNormalize( forward ); + } - // pick the closer midpoint - if ( lengths[ 0 ] <= lengths[ 1 ] ) - k = 0; - else - k = 1; - - VectorSubtract( v1->xyz, mid[ k ], minor ); - // I guess this works, since the sign bit is the MSB for both floating point and integers - if ( ( DotProduct( cross, minor ) * static_cast(v1->texCoords[ 3 ].bits) ) < 0 ) { - VectorNegate( major, orientation ); - } else { - VectorCopy( major, orientation ); + vec3_t newMinorAxis; + CrossProduct( sides[ 1 ].vector, forward, newMinorAxis); + VectorNormalize( newMinorAxis ); + plane_t projection; + VectorNormalize2( sides[ 0 ].vector, projection.normal ); + projection.dist = DotProduct( sides[ 0 ].firstVert, projection.normal ) + + 0.5f * sqrtf( sides[ 0 ].lengthSq ); + vec3_t minorAxisReplace; + VectorSubtract( newMinorAxis, projection.normal, minorAxisReplace ); + + if ( tess.skipTangents ) + { + for ( uint32_t j = i; j <= i + 4; j++ ) + { + shaderVertex_t v = tess.vertsBuffer[ j ]; + float d = DotProduct( projection.normal, v.xyz ) - projection.dist; + VectorMA( v.xyz, d, minorAxisReplace, v.xyz ); + tess.verts[ j ] = v; + } + } + else + { + i16vec4_t qtangents; + vec3_t normal; + CrossProduct( newMinorAxis, sides[ 1 ].vector, normal ); + if ( DotProduct( normal, forward ) > 0 ) + { + VectorNegate( normal, normal ); } - orientation[ 3 ] = -lengths[ k ]; + VectorNormalize( normal ); + // What the fuck are tangent and binormal even for? + // I'll just put in zeroes and let R_TBNtoQtangents make some up for me. + R_TBNtoQtangents( vec3_origin, vec3_origin, normal, qtangents ); - floatToHalf( orientation, v1->spriteOrientation ); - VectorCopy( mid[ k ], v1->xyz ); + for ( uint32_t j = i; j <= i + 4; j++ ) + { + shaderVertex_t v = tess.vertsBuffer[ j ]; + float d = DotProduct( projection.normal, v.xyz ) - projection.dist; + VectorMA( v.xyz, d, minorAxisReplace, v.xyz ); + Vector4Copy( qtangents, v.qtangents ); + tess.verts[ j ] = v; + } } } } @@ -681,24 +650,46 @@ static void Autosprite2Deform( int firstVertex, int numVertexes, int numIndexes ===================== Tess_AutospriteDeform -Set up vertices to be decoded by the vertexSprite_vp shader. -The ComputeCorner function used in here encodes information in the sign of the lightmap -coordinates, so it only works if there are positive lightmap tc's. Thus it does -not work on anything besides BSP surfaces. ===================== */ -void Tess_AutospriteDeform( int mode, int firstVertex, int numVertexes, - int firstIndex, int numIndexes ) +void Tess_AutospriteDeform( int mode ) { - (void)firstIndex; + if ( tess.verts != tess.vertsBuffer ) + { + Log::Warn( "Tess_AutospriteDeform: CPU vertex buffer not active" ); + return; + } + + uint32_t numVertexes = tess.numVertexes; + uint32_t numIndexes = tess.numIndexes; + + // Tess_MapVBOs( true ) should have been called previously. Now we take the original verts from + // the CPU-only buffer and write the rotated verts to the shared GPU buffer. (If the GPU buffer + // is not supported, the source and dest buffers are the same.) + Tess_Clear(); + Tess_MapVBOs( false ); + + if ( numVertexes & 3 ) + { + Log::Warn( "Autosprite shader %s had odd vertex count", tess.surfaceShader->name ); + return; // drop vertexes + } + + if ( numIndexes != ( numVertexes >> 2 ) * 6 ) + { + Log::Warn( "Autosprite shader %s had odd index count", tess.surfaceShader->name ); + return; // drop vertexes + } switch( mode ) { case 1: - AutospriteDeform( firstVertex, numVertexes, numIndexes ); + AutospriteDeform( numVertexes ); break; case 2: - Autosprite2Deform( firstVertex, numVertexes, numIndexes ); + Autosprite2Deform( numVertexes ); break; + default: + ASSERT_UNREACHABLE(); } } diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 57722b0744..4cb55db4cc 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -6329,10 +6329,6 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags ) implicitCullType = CT_FRONT_SIDED; } - if( flags & RSF_SPRITE ) { - shader.autoSpriteMode = 1; - } - // attempt to define shader from an explicit parameter file shaderText = FindShaderInShaderText( strippedName ); diff --git a/src/engine/renderer/tr_surface.cpp b/src/engine/renderer/tr_surface.cpp index 43868ac361..2a4c061419 100644 --- a/src/engine/renderer/tr_surface.cpp +++ b/src/engine/renderer/tr_surface.cpp @@ -410,46 +410,6 @@ void Tess_AddQuadStamp2WithNormals( vec4_t quadVerts[ 4 ], const Color::Color& c Tess_AddQuadStampExt2( quadVerts, color, 0, 0, 1, 1 ); } -// Defines ATTR_POSITION, ATTR_COLOR, ATTR_TEXCOORD, ATTR_ORIENTATION -void Tess_AddSprite( const vec3_t center, const Color::Color32Bit color, float radius, float rotation ) -{ - int i; - int ndx; - - GLimp_LogComment( "--- Tess_AddSprite ---\n" ); - - Tess_CheckOverflow( 4, 6 ); - - ndx = tess.numVertexes; - - // triangle indexes for a simple quad - tess.indexes[ tess.numIndexes ] = ndx; - tess.indexes[ tess.numIndexes + 1 ] = ndx + 1; - tess.indexes[ tess.numIndexes + 2 ] = ndx + 3; - - tess.indexes[ tess.numIndexes + 3 ] = ndx + 3; - tess.indexes[ tess.numIndexes + 4 ] = ndx + 1; - tess.indexes[ tess.numIndexes + 5 ] = ndx + 2; - - for ( i = 0; i < 4; i++ ) - { - vec4_t texCoord; - vec4_t orientation; - - Vector4Set( texCoord, 0.5f * (i & 2), 0.5f * ( (i + 1) & 2 ), - (i & 2) - 1.0f, ( (i + 1) & 2 ) - 1.0f ); - - VectorCopy( center, tess.verts[ ndx + i ].xyz ); - tess.verts[ ndx + i ].color = color; - floatToHalf( texCoord, tess.verts[ ndx + i ].texCoords ); - Vector4Set( orientation, rotation, 0.0f, 0.0f, radius ); - floatToHalf( orientation, tess.verts[ ndx + i ].spriteOrientation ); - } - - tess.numVertexes += 4; - tess.numIndexes += 6; -} - // Defines ATTR_POSITION, ATTR_COLOR void Tess_AddTetrahedron( vec4_t tetraVerts[ 4 ], const Color::Color& colorf ) { @@ -628,16 +588,12 @@ static void Tess_SurfaceSprite() radius = backEnd.currentEntity->e.radius; - if( tess.surfaceShader->autoSpriteMode == 1 ) { - // the calculations are done in GLSL shader - // FIXME why does this need a different codepath (other than to cope with USE_VERTEX_SPRITE - // shader variants being selected?) Aren't the semantics of deformvertexes autosprite the - // same as those of RT_SPRITE? - - Tess_AddSprite( backEnd.currentEntity->e.origin, - backEnd.currentEntity->e.shaderRGBA, - radius, backEnd.currentEntity->e.rotation ); - return; + if ( tess.surfaceShader->autoSpriteMode != 0 ) + { + // This function does similarly to autosprite mode 1. Autospriting it again would be a + // waste and would probably lose the rotation angle + Log::Warn( "RT_SPRITE entity should NOT configure its shader (%s) as autosprite", + tess.surfaceShader->name ); } VectorSubtract( backEnd.currentEntity->e.origin, backEnd.viewParms.pvsOrigin, delta ); diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 74940b7550..60abb87f59 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -210,13 +210,6 @@ static void R_SetAttributeLayoutsStatic( VBO_t *vbo ) vbo->attribs[ ATTR_INDEX_TEXCOORD ].stride = sizeShaderVertex; vbo->attribs[ ATTR_INDEX_TEXCOORD ].frameOffset = 0; - vbo->attribs[ ATTR_INDEX_ORIENTATION ].numComponents = 4; - vbo->attribs[ ATTR_INDEX_ORIENTATION ].componentType = GL_HALF_FLOAT; - vbo->attribs[ ATTR_INDEX_ORIENTATION ].normalize = GL_FALSE; - vbo->attribs[ ATTR_INDEX_ORIENTATION ].ofs = offsetof( shaderVertex_t, spriteOrientation ); - vbo->attribs[ ATTR_INDEX_ORIENTATION ].stride = sizeShaderVertex; - vbo->attribs[ ATTR_INDEX_ORIENTATION ].frameOffset = 0; - // total size vbo->vertexesSize = sizeShaderVertex * vbo->vertexesNum; } @@ -1007,9 +1000,7 @@ R_InitVBOs */ void R_InitVBOs() { - // ATTR_QTANGENT and ATTR_ORIENTATION are mutually exclusive, but we don't know in advance - // which attributes will be used as this buffer is used for many purposes. - uint32_t attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_ORIENTATION | ATTR_COLOR; + uint32_t attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR; Log::Debug("------- R_InitVBOs -------" );