Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions trinity/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,9 @@ set(_SOURCES
Sprite2d/Tr2Sprite2dContainer_Blue.cpp
Sprite2d/Tr2Sprite2dDisplayList.cpp
Sprite2d/Tr2Sprite2dDisplayList.h
Sprite2d/Tr2Sprite2dEffect.cpp
Sprite2d/Tr2Sprite2dEffect.h
Sprite2d/Tr2Sprite2dEffect_Blue.cpp
Sprite2d/Tr2Sprite2dFrame.cpp
Sprite2d/Tr2Sprite2dFrame.h
Sprite2d/Tr2Sprite2dFrame_Blue.cpp
Expand Down
7 changes: 5 additions & 2 deletions trinity/Sprite2d/Tr2Sprite2dDisplayList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ void Tr2Sprite2dDisplayList::Entry::SubmitGeometry( Tr2RenderContext& renderCont
transposedMatrixes[i] = Transpose( transformArray[i] );
}

renderContext.SetSrv( PIXEL_SHADER, textureRegisters[0], ( texture0 && texture0->GetTexture() ) ? *texture0->GetTexture() : Tr2TextureAL(), colorSpace );
renderContext.SetSrv( PIXEL_SHADER, textureRegisters[1], ( texture1 && texture1->GetTexture() ) ? *texture1->GetTexture() : Tr2TextureAL(), colorSpace );
if( bindTextures )
{
renderContext.SetSrv( PIXEL_SHADER, textureRegisters[0], ( texture0 && texture0->GetTexture() ) ? *texture0->GetTexture() : Tr2TextureAL(), colorSpace );
renderContext.SetSrv( PIXEL_SHADER, textureRegisters[1], ( texture1 && texture1->GetTexture() ) ? *texture1->GetTexture() : Tr2TextureAL(), colorSpace );
}

FillAndSetConstants(
*m_uiTransformsCb,
Expand Down
2 changes: 2 additions & 0 deletions trinity/Sprite2d/Tr2Sprite2dDisplayList.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ struct Tr2Sprite2dDisplayList : public Tr2DeviceResource
Tr2AtlasTexturePtr texture0;
Tr2AtlasTexturePtr texture1;
uint32_t textureRegisters[2];
// Whether to bind texture0 and texture1. False only for an override effect.
bool bindTextures;
Tr2RenderContextEnum::ColorSpace colorSpace;
Tr2EffectPtr effect;
//hardcoded due to need for CB slot//Tr2EffectConstant transformsHandle;
Expand Down
83 changes: 83 additions & 0 deletions trinity/Sprite2d/Tr2Sprite2dEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright © 2026 CCP ehf.

#include "StdAfx.h"
#include "Tr2Sprite2dEffect.h"
#include "Tr2Sprite2dScene.h"
#include "Tr2Sprite2dPickingMask.h"
#include "Shader/Tr2Effect.h"

static unsigned short s_quadIndices[6] = { 0, 1, 3, 3, 1, 2 };

Tr2Sprite2dEffect::Tr2Sprite2dEffect( IRoot* lockobj /*= NULL */ ) :
m_color( 1.0f, 1.0f, 1.0f, 1.0f ),
m_glowBrightness( 1.0f ),
m_target( Tr2SpriteTarget::COLOR )
{
}

void Tr2Sprite2dEffect::GatherSprites( Tr2Sprite2dScene* renderer )
{
TRINITY_STATS_ZONE( __FUNCTION__ );

if( !m_display || !m_effect )
{
return;
}

static const Vector2 s_corners[4] = {
Vector2( 0.0f, 0.0f ),
Vector2( 1.0f, 0.0f ),
Vector2( 1.0f, 1.0f ),
Vector2( 0.0f, 1.0f )
};

// Every field is set here, from the sprite or as a default Tr2SpriteObject
// would set it, so the effect gets the same vertices whatever the sprites
// before it left
renderer->SetDepth( 0.0f );

Tr2Sprite2dD3DVertex vertices[4];
for( int i = 0; i < 4; ++i )
{
Tr2Sprite2dD3DVertex& vertex = vertices[i];
vertex.position = Vector3( m_translation.x + s_corners[i].x * m_displayWidth, m_translation.y + s_corners[i].y * m_displayHeight, 0.0f );
vertex.color = m_color;
vertex.texCoord[0] = s_corners[i];
vertex.texCoord[1] = Vector2( m_displayWidth, m_displayHeight );
vertex.glowBrightness = m_glowBrightness;
vertex.transformIndex = 0;
vertex.blendMode = PackBlendMode( TR2_SBM_NONE, m_target );
vertex.spriteEffect = TR2_SFX_FILL;
vertex.tileMode = S2D_TS_NONE;
vertex.outlineColor = Color( 0.0f, 0.0f, 0.0f, 1.0f );
vertex.outlineThreshold = 0.0f;
}

renderer->RenderTriangleVerts( *m_effect, vertices, 4, s_quadIndices, 6 );
}

ITr2SpriteObject* Tr2Sprite2dEffect::PickPoint( float x, float y, Tr2Sprite2dScene* renderer )
{
if( !m_display )
{
return NULL;
}

if( m_pickState == TR2_SPS_ON )
{
if( renderer->IsInside( Vector2( x, y ), m_translation, m_displayWidth, m_displayHeight, 0.0f ) )
{
if( !m_pickingMask || m_pickingMask->SampleMask( renderer->InverseTransformPoint( Vector2( x, y ) ), m_translation, m_displayWidth, m_displayHeight ) )
{
return this;
}
}
}

return NULL;
}

unsigned int Tr2Sprite2dEffect::GetVertexCount()
{
return ( m_display && m_effect ) ? 4 : 0;
}
46 changes: 46 additions & 0 deletions trinity/Sprite2d/Tr2Sprite2dEffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright © 2026 CCP ehf.

#pragma once
#ifndef Tr2Sprite2dEffect_h
#define Tr2Sprite2dEffect_h

#include "ITr2SpriteObject.h"
#include "Tr2SpriteObject.h"

BLUE_DECLARE( Tr2Effect );
BLUE_DECLARE( Tr2Sprite2dEffect );

// A leaf sprite that draws one effect over its rect, in order with the other
// sprites, as a draw call of its own. The effect draws the sprite's quad in
// place of the scene's own shaders, so it gets the same vertices and
// constants (UIVertexInput, g_uiTransforms and UIViewportSize in
// Carbon/UI/UI.fxh), clips and transforms them as they do, and should write
// glow to SV_Target1 like them. Texcoord 0 runs 0 to 1 over the quad, texcoord
// 1 is the quad's width and height, and the vertex color is the sprite's color
// with its ancestors' opacity multiplied into alpha. The glow brightness and
// sprite target are the sprite's own, and the other vertex fields hold a
// default sprite's values, whatever was drawn before. The effect gets none of
// the scene's textures.
class Tr2Sprite2dEffect : public Tr2SpriteObjectBase
{
public:
EXPOSE_TO_BLUE();

Tr2Sprite2dEffect( IRoot* lockobj = NULL );

//////////////////////////////////////////////////////////////////////////
// ITr2SpriteObject
unsigned int GetVertexCount();
void GatherSprites( Tr2Sprite2dScene* renderer ) override;
ITr2SpriteObject* PickPoint( float x, float y, Tr2Sprite2dScene* renderer ) override;

private:
Tr2EffectPtr m_effect;
Color m_color;
float m_glowBrightness;
Tr2SpriteTarget m_target;
};

TYPEDEF_BLUECLASS( Tr2Sprite2dEffect );

#endif
41 changes: 41 additions & 0 deletions trinity/Sprite2d/Tr2Sprite2dEffect_Blue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © 2026 CCP ehf.

#include "StdAfx.h"
#include "Tr2Sprite2dEffect.h"

BLUE_DEFINE( Tr2Sprite2dEffect );

const Be::ClassInfo* Tr2Sprite2dEffect::ExposeToBlue()
{
EXPOSURE_BEGIN( Tr2Sprite2dEffect, "" )
MAP_INTERFACE( ITr2SpriteObject )
MAP_INTERFACE( Tr2Sprite2dEffect )

MAP_ATTRIBUTE(
"effect",
m_effect,
"The effect drawn over the sprite's quad in place of the scene's shaders, or None. It gets the\n"
"scene's vertices and constants (see Carbon/UI/UI.fxh), with texcoord 0 running 0 to 1 over the quad,\n"
"texcoord 1 holding the quad's width and height, and the sprite's color in the vertex color.",
Be::READWRITE | Be::NOTIFY )

MAP_ATTRIBUTE(
"color",
m_color,
"Color of the sprite, passed to the effect as the vertex color. Its alpha is multiplied with its ancestors' opacity.",
Be::READWRITE | Be::NOTIFY )

MAP_ATTRIBUTE(
"glowBrightness",
m_glowBrightness,
"Glow brightness passed to the effect in the vertices. See spriteTarget.",
Be::READWRITE | Be::NOTIFY )

MAP_ATTRIBUTE_WITH_CHOOSER(
"spriteTarget",
m_target,
"Render target passed to the effect in the vertices: either color or glow target",
Be::READWRITE | Be::ENUM | Be::NOTIFY,
Tr2SpriteTargetChooser )
EXPOSURE_CHAINTO( Tr2SpriteObjectBase )
}
45 changes: 36 additions & 9 deletions trinity/Sprite2d/Tr2Sprite2dScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Tr2Sprite2dScene::Tr2Sprite2dScene( IRoot* lockobj ) :
m_maxSpriteCount( 1024 ),
m_tileMode( S2D_TS_NONE ),
m_drawCallStartIndex( 0 ),
m_effectOverride( nullptr ),
m_transformsHandle(),
m_useLinearColorSpace( false ),
m_isGammaCorrectingText( true ),
Expand Down Expand Up @@ -1041,6 +1042,17 @@ void Tr2Sprite2dScene::RenderTriangleVerts( Tr2Sprite2dD3DVertex* verticesSrc, u
CopyIndicesWithOffset( indices, indexCount, vertexOffset );
}

void Tr2Sprite2dScene::RenderTriangleVerts( Tr2Effect& effect, Tr2Sprite2dD3DVertex* verticesSrc, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount )
{
// Draw what's already batched with the scene's shader, then batch the
// vertices on their own and draw them with the effect
IssueDrawCall();
m_effectOverride = &effect;
RenderTriangleVerts( verticesSrc, vertexCount, indices, indexCount );
IssueDrawCall();
m_effectOverride = nullptr;
}

void Tr2Sprite2dScene::RenderTriangleVerts( Tr2BufferAL& verticesSrc, unsigned int vertexCount, Tr2BufferAL& indices, unsigned int indexCount )
{
CCP_ASSERT( !m_captureDisplayList );
Expand Down Expand Up @@ -1103,6 +1115,7 @@ void Tr2Sprite2dScene::IssueDrawCall()
entry.texture0 = m_texture[0];
entry.texture1 = m_texture[1];
entry.effect = m_effect;
entry.bindTextures = !m_effectOverride;
Comment thread
hinrikg marked this conversation as resolved.
Resolved
m_texelSizeVar[0].GetValue( entry.texelSize0 );
m_texelSizeVar[1].GetValue( entry.texelSize1 );

Expand Down Expand Up @@ -1177,22 +1190,26 @@ void Tr2Sprite2dScene::SubmitGeometry( Tr2RenderContext& renderContext )
transposedMatrixes[i] = Transpose( m_transformArray[i] );
}

for( uint32_t i = 0; i < 2; ++i )
// An override effect gets none of the scene's textures
if( !m_effectOverride )
{
Tr2TextureAL* texAL = nullptr;
if( m_texture[i] )
for( uint32_t i = 0; i < 2; ++i )
{
texAL = m_texture[i]->GetTexture();
if( !texAL )
Tr2TextureAL* texAL = nullptr;
if( m_texture[i] )
{
if( m_texture[i]->GetRenderTarget() )
texAL = m_texture[i]->GetTexture();
if( !texAL )
{
texAL = m_texture[i]->GetRenderTarget();
if( m_texture[i]->GetRenderTarget() )
{
texAL = m_texture[i]->GetRenderTarget();
}
}
}
auto colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR;
renderContext.SetSrv( PIXEL_SHADER, m_textureRegisters[i], texAL ? *texAL : Tr2TextureAL(), colorSpace );
}
auto colorSpace = m_useLinearColorSpace ? Tr2RenderContextEnum::COLOR_SPACE_SRGB : Tr2RenderContextEnum::COLOR_SPACE_LINEAR;
renderContext.SetSrv( PIXEL_SHADER, m_textureRegisters[i], texAL ? *texAL : Tr2TextureAL(), colorSpace );
}

bool result = FillAndSetConstants(
Expand Down Expand Up @@ -1718,8 +1735,17 @@ void Tr2Sprite2dScene::SetOutlineThreshold( float outlineThreshold )
m_outlineThreshold = outlineThreshold;
}

// Selects the effect for the batched vertices and returns whether it can draw
// them. An override effect always can, even before its shader loads, so that
// a display list captured meanwhile still records its draw call.
bool Tr2Sprite2dScene::SelectEffect()
{
if( m_effectOverride )
{
m_effect = m_effectOverride;
return true;
}

Tr2Effect* newEffect;

newEffect = m_is2dRender ? m_uberShader2d : m_uberShader3d;
Expand Down Expand Up @@ -1791,6 +1817,7 @@ void Tr2Sprite2dScene::RunJob( TriRenderJob* job )
entry.primitiveCount = 0;
entry.texture0 = nullptr;
entry.texture1 = nullptr;
entry.bindTextures = true;
entry.texelSize0 = Vector4( 0, 0, 0, 0 );
entry.texelSize1 = Vector4( 0, 0, 0, 0 );

Expand Down
13 changes: 13 additions & 0 deletions trinity/Sprite2d/Tr2Sprite2dScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ class Tr2Sprite2dScene : public ITr2Scene,
unsigned short* indices,
unsigned int indexCount );

// Draws the vertices as a draw call of their own, with the given effect in
// place of the scene's shader and none of the scene's textures.
void RenderTriangleVerts(
Tr2Effect& effect,
Tr2Sprite2dD3DVertex* verticesSrc,
unsigned int vertexCount,
unsigned short* indices,
unsigned int indexCount );

void RenderTriangleVerts(
Tr2BufferAL& verticesSrc,
unsigned int vertexCount,
Expand Down Expand Up @@ -202,6 +211,10 @@ class Tr2Sprite2dScene : public ITr2Scene,
Tr2EffectPtr m_effect;
uint32_t m_textureRegisters[2];

// Effect to draw with instead of the scene's shader. Only set inside
// RenderTriangleVerts with an effect.
Tr2Effect* m_effectOverride;

Tr2EffectConstant m_transformsHandle;

// The desired visual effect
Expand Down
Loading