You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
767 lines
24 KiB
767 lines
24 KiB
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
|
//
|
|
// The copyright to the contents herein is the property of Valve, L.L.C.
|
|
// The contents may be used and/or copied only with the written permission of
|
|
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
|
// the agreement/contract under which the contents have been supplied.
|
|
//
|
|
// $Header: $
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "gameuisystem.h"
|
|
#include "materialsystem/imaterialsystem.h"
|
|
#include "materialsystem/imesh.h"
|
|
#include "gameuidefinition.h"
|
|
#include "gamelayer.h"
|
|
#include "tier0/vprof.h"
|
|
#include "rendersystem/irenderdevice.h"
|
|
#include "rendersystem/irendercontext.h"
|
|
#include "gameuisystemsurface.h"
|
|
#include "inputgameui.h"
|
|
#include "gameuisystemmgr.h"
|
|
#include "gameuiscript.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#define MAX_LAYERS 10
|
|
|
|
#define DEBUG_DRAW_REPORT 1
|
|
#define HIDE_ALL_TEXT 0
|
|
#define HIDE_FONT_TEXTURES 1
|
|
|
|
|
|
// A list of script handles exposed by the system
|
|
static int32 g_iSerialHandle = 0;
|
|
static CUtlMap< int32, CGameUISystem * > g_mapScriptHandles( DefLessFunc( int32 ) );
|
|
|
|
|
|
CGameUISystem::CGameUISystem() :
|
|
m_GameUIDef( this ),
|
|
m_iScriptHandle( ++g_iSerialHandle )
|
|
{
|
|
m_bDrawReport = true;
|
|
g_mapScriptHandles.InsertOrReplace( m_iScriptHandle, this );
|
|
}
|
|
|
|
CGameUISystem::~CGameUISystem()
|
|
{
|
|
g_mapScriptHandles.Remove( m_iScriptHandle );
|
|
}
|
|
|
|
CGameUISystem * CGameUISystem::FromScriptHandle( int32 iScriptHandle )
|
|
{
|
|
unsigned short usIdx = g_mapScriptHandles.Find( iScriptHandle );
|
|
return ( usIdx == g_mapScriptHandles.InvalidIndex() ) ? NULL : g_mapScriptHandles.Element( usIdx );
|
|
}
|
|
|
|
char const * CGameUISystem::GetName()
|
|
{
|
|
return m_GameUIDef.GetName();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Init, shutdown
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameUISystem::Init( KeyValues *kvLoadSettings )
|
|
{
|
|
DevMsg( "CGameUISystem[%p]::Init( name = %s )\n", this, GetName() );
|
|
KeyValuesDumpAsDevMsg( kvLoadSettings );
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGameUISystem::Release()
|
|
{
|
|
DevMsg( "CGameUISystem[%p]::Release( name = %s )\n", this, GetName() );
|
|
|
|
g_pGameUISystemMgrImpl->OnScreenReleased( this );
|
|
|
|
m_GameUIDef.Shutdown();
|
|
|
|
delete this;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates an empty game UI.
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::LoadEmptyGameUI( const char *pName )
|
|
{
|
|
m_GameUIDef.Shutdown();
|
|
m_GameUIDef.CreateDefault( pName );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Read the game UI config file from a utlbuffer
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameUISystem::LoadGameUIDefinition( CUtlBuffer &buf, const char *pFileName )
|
|
{
|
|
DECLARE_DMX_CONTEXT();
|
|
|
|
CDmxElement *pRoot = NULL;
|
|
if ( !UnserializeDMX( buf, &pRoot, pFileName ) )
|
|
{
|
|
Warning( "Unable to read game UI config %s! UtlBuffer is the wrong type!\n", pFileName );
|
|
return false;
|
|
}
|
|
|
|
bool bOk = m_GameUIDef.Unserialize( pRoot );
|
|
CleanupDMX( pRoot );
|
|
if ( !bOk )
|
|
return false;
|
|
|
|
m_GameUIDef.InitializeScripts();
|
|
|
|
// Start the animations all at the same time.
|
|
//Start();
|
|
|
|
//TextTest();
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameUISystem::ExecuteScript( KeyValues *kvEvent, KeyValues **ppResult )
|
|
{
|
|
return m_GameUIDef.ExecuteScript( kvEvent, ppResult );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::SetStageSize( int nWide, int nTall )
|
|
{
|
|
m_GameUIDef.SetStageSize( nWide, nTall);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::GetStageSize( Vector2D &stageSize )
|
|
{
|
|
m_GameUIDef.GetStageSize( stageSize );
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 3 draw calls per layer.
|
|
// Render in source 1
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::Render( const Rect_t &viewport )
|
|
{
|
|
if ( !m_GameUIDef.GetVisible() )
|
|
return;
|
|
|
|
VPROF_BUDGET( "Render", "Render" );
|
|
Assert( g_pMaterialSystem );
|
|
|
|
m_GameUIDef.UpdateGeometry();
|
|
m_GameUIDef.UpdateRenderTransforms( viewport );
|
|
CUtlVector< LayerRenderLists_t > renderLists;
|
|
m_GameUIDef.GetRenderData( renderLists );
|
|
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
|
|
// Clear back buffer to green. Useful for debugging graphics that you think should be there and are not.
|
|
//pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
|
//pRenderContext->ClearBuffers( true, true );
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
pRenderContext->Scale( 1, -1, 1 );
|
|
float flPixelOffsetX = .5;
|
|
float flPixelOffsetY = .5;
|
|
pRenderContext->Ortho( viewport.x + flPixelOffsetX, viewport.y + flPixelOffsetY, viewport.width + flPixelOffsetX, viewport.height + flPixelOffsetY, -1.0f, 1.0f );
|
|
|
|
// make sure there is no translation and rotation laying around
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
|
|
int nStaticDrawCalls = 0;
|
|
int nDynamicDrawCalls = 0;
|
|
int nFontDrawCalls = 0;
|
|
|
|
int nLists = renderLists.Count();
|
|
for ( int i = 0; i < nLists; ++i )
|
|
{
|
|
if ( renderLists[i].m_LayerType == SUBLAYER_STATIC )
|
|
{
|
|
for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
|
|
{
|
|
RenderStaticLayer( renderLists[i], j );
|
|
nStaticDrawCalls++;
|
|
}
|
|
|
|
}
|
|
else if ( renderLists[i].m_LayerType == SUBLAYER_DYNAMIC )
|
|
{
|
|
// For dynamic texture viewing.
|
|
//int x = 900;
|
|
//int y = 0;
|
|
for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
|
|
{
|
|
RenderDynamicLayer( renderLists[i], j );
|
|
nDynamicDrawCalls++;
|
|
|
|
// For dynamic texture viewing.
|
|
//g_pGameUISystemMgrImpl->DrawDynamicTexture( renderLists[i].m_RenderGeometryLists[j][0].m_pImageAlias, x, y );
|
|
//y += 256 + 30;
|
|
}
|
|
}
|
|
else if ( renderLists[i].m_LayerType == SUBLAYER_FONT )
|
|
{
|
|
// For font texture viewing.
|
|
//int x = 900;
|
|
//int y = 30;
|
|
for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
|
|
{
|
|
RenderTextLayer( renderLists[i].m_RenderGeometryLists[j] );
|
|
nFontDrawCalls++;
|
|
|
|
// For font texture viewing.
|
|
//g_pGameUISystemSurface->DrawFontTexture( renderLists[i].m_RenderGeometryLists[j][0].m_FontTextureID, x, y );
|
|
//y += 256 + 30;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#if ( DEBUG_DRAW_REPORT )
|
|
if ( m_bDrawReport )
|
|
{
|
|
m_bDrawReport = false;
|
|
|
|
Msg( "Total static draw calls in UI: %d\n", nStaticDrawCalls );
|
|
Msg( "Total dynamic draw calls in UI: %d\n", nDynamicDrawCalls );
|
|
Msg( "Total font draw calls in UI: %d\n", nFontDrawCalls );
|
|
Msg( "Total draw calls in UI: %d\n", nStaticDrawCalls + nDynamicDrawCalls + nFontDrawCalls );
|
|
}
|
|
#endif
|
|
|
|
// Restore the matrices
|
|
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
|
pRenderContext->PopMatrix();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
|
pRenderContext->PopMatrix();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Render a static layer in source 1
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::RenderStaticLayer( LayerRenderLists_t &renderList, int geometryIndex )
|
|
{
|
|
// Do not call draw on an empty mesh.
|
|
int nTotalTriCount = 0;
|
|
for( int i = 0; i < renderList.m_RenderGeometryLists[geometryIndex].Count(); ++i )
|
|
{
|
|
nTotalTriCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount();
|
|
}
|
|
|
|
if ( nTotalTriCount == 0 )
|
|
return;
|
|
|
|
if ( renderList.m_pSheet == NULL )
|
|
{
|
|
Assert(0);
|
|
return;
|
|
}
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->Bind( renderList.m_pMaterial, NULL );
|
|
IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
|
|
GenerateUIMesh( pRenderContext, pMesh, renderList.m_RenderGeometryLists[geometryIndex],
|
|
renderList.m_pSheet );
|
|
pMesh->Draw();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Render a dynamic layer in source 1
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::RenderDynamicLayer( LayerRenderLists_t &renderList, int geometryIndex )
|
|
{
|
|
// Do not call draw on an empty mesh.
|
|
int nTotalTriCount = 0;
|
|
for( int i = 0; i < renderList.m_RenderGeometryLists[geometryIndex].Count(); ++i )
|
|
{
|
|
nTotalTriCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount();
|
|
}
|
|
|
|
if ( nTotalTriCount == 0 )
|
|
return;
|
|
|
|
if ( renderList.m_pMaterial == NULL )
|
|
return;
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, renderList.m_pMaterial ); // this fxn will also bind the material
|
|
if ( !pMesh )
|
|
return;
|
|
|
|
|
|
CMeshBuilder meshBuilder;
|
|
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, nTotalTriCount );
|
|
|
|
CUtlVector< CRenderGeometry > &renderGeometry = renderList.m_RenderGeometryLists[geometryIndex];
|
|
int nGraphicCount = renderGeometry.Count();
|
|
int nIndex = 0;
|
|
for( int i = 0; i < nGraphicCount; ++i )
|
|
{
|
|
for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
|
|
{
|
|
// First anim frame
|
|
float flX = renderGeometry[i].m_Positions[j].x;
|
|
float flY = renderGeometry[i].m_Positions[j].y;
|
|
meshBuilder.Position3f( flX, flY, 0.0f );
|
|
color32 c = renderGeometry[i].m_VertexColors[j];
|
|
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
|
|
|
float texCoordX = renderGeometry[i].m_TextureCoords[j].x;
|
|
float texCoordY = renderGeometry[i].m_TextureCoords[j].y;
|
|
|
|
meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
Assert( renderGeometry[i].m_Positions.Count() == 4 );
|
|
|
|
|
|
// FIXME make this work with generic convex shapes.
|
|
// Quads only.
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 1 );
|
|
meshBuilder.FastIndex( nIndex + 2 );
|
|
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 2 );
|
|
meshBuilder.FastIndex( nIndex + 3 );
|
|
|
|
nIndex += (4);
|
|
}
|
|
|
|
|
|
meshBuilder.End();
|
|
pMesh->Draw();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Render a font layer in source 1
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::RenderTextLayer( CUtlVector< CRenderGeometry > &renderGeometry )
|
|
{
|
|
if ( renderGeometry.Count() == 0 )
|
|
return;
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
// get the character texture from the cache
|
|
IMaterial *pMaterial = g_pGameUISystemSurface->GetMaterial( renderGeometry[0].m_FontTextureID ); /// Everything in a text rendering layer uses the same font texture, and the texture id is in the seq #
|
|
IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); // this fxn will also bind the material
|
|
if ( !pMesh )
|
|
return;
|
|
|
|
CMeshBuilder meshBuilder;
|
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, renderGeometry.Count() );
|
|
|
|
for ( int i = 0; i < renderGeometry.Count(); ++i )
|
|
{
|
|
Assert( renderGeometry[i].m_Positions.Count() == 4 );
|
|
for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
|
|
{
|
|
meshBuilder.Position3f( renderGeometry[i].m_Positions[j].x, renderGeometry[i].m_Positions[j].y, 0.0f );
|
|
meshBuilder.Color4ub( renderGeometry[i].m_VertexColors[j].r, renderGeometry[i].m_VertexColors[j].g, renderGeometry[i].m_VertexColors[j].b, renderGeometry[i].m_VertexColors[j].a );
|
|
meshBuilder.TexCoord3f( 0, renderGeometry[i].m_TextureCoords[j].x, renderGeometry[i].m_TextureCoords[j].y, 0 );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
}
|
|
|
|
meshBuilder.End();
|
|
pMesh->Draw();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Create geometry mesh in source 1
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::GenerateUIMesh( IMatRenderContext *pRenderContext,
|
|
IMesh* pMesh,
|
|
CUtlVector< CRenderGeometry > &renderGeometry,
|
|
CSheet *pSheet )
|
|
{
|
|
int nTotalTriCount = 0;
|
|
for( int i = 0; i < renderGeometry.Count(); ++i )
|
|
{
|
|
nTotalTriCount += renderGeometry[i].GetTriangleCount();
|
|
}
|
|
|
|
Assert( nTotalTriCount != 0 );
|
|
CMeshBuilder meshBuilder;
|
|
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, nTotalTriCount * 2 );
|
|
|
|
int x, y, width, height;
|
|
pRenderContext->GetViewport( x, y, width, height);
|
|
|
|
static long flAge = 0;
|
|
{
|
|
VPROF_BUDGET( "meshBuilder", "meshBuilder" );
|
|
|
|
int nGraphicCount = renderGeometry.Count();
|
|
int nIndex = 0;
|
|
for( int i = 0; i < nGraphicCount; ++i )
|
|
{
|
|
const SheetSequenceSample_t *pSample = NULL;
|
|
int seqNum = renderGeometry[i].m_SheetSequenceNumber;
|
|
if ( renderGeometry[i].m_bAnimate )
|
|
{
|
|
DmeTime_t flStartTime = renderGeometry[i].GetAnimStartTime();
|
|
DmeTime_t flAgeInSeconds = ( g_pGameUISystemMgrImpl->GetTime() - flStartTime );
|
|
float m_flAnimationRate = renderGeometry[i].m_AnimationRate;
|
|
float flAgeScale = m_flAnimationRate * SEQUENCE_SAMPLE_COUNT;
|
|
flAgeScale /= pSheet->m_SheetInfo[seqNum].m_flFrameSpan;
|
|
|
|
pSample = pSheet->GetSampleForSequence( flAgeInSeconds.GetSeconds(), flAgeScale, seqNum, true );
|
|
}
|
|
else
|
|
{
|
|
pSample = pSheet->m_SheetInfo[seqNum].m_pSamples;
|
|
}
|
|
|
|
Assert( pSample );
|
|
const SequenceSampleTextureCoords_t *pSample0 = &(pSample->m_TextureCoordData[0]);
|
|
Assert( pSample0 );
|
|
|
|
for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
|
|
{
|
|
// First anim frame
|
|
float flX = renderGeometry[i].m_Positions[j].x;
|
|
float flY = renderGeometry[i].m_Positions[j].y;
|
|
meshBuilder.Position3f( flX, flY, 0.0f );
|
|
color32 c = renderGeometry[i].m_VertexColors[j];
|
|
c.a *= ( 1 - pSample->m_fBlendFactor );
|
|
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
|
float sampleWidth = pSample0->m_fRight_U0 - pSample0->m_fLeft_U0;
|
|
float sampleHeight = pSample0->m_fBottom_V0 - pSample0->m_fTop_V0;
|
|
float texCoordX = pSample0->m_fLeft_U0 + renderGeometry[i].m_TextureCoords[j].x * sampleWidth;
|
|
float texCoordY = pSample0->m_fTop_V0 + renderGeometry[i].m_TextureCoords[j].y * sampleHeight;
|
|
meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
// Ugh, right now we have to do this second frame because of the total triangle count being set before we figure out if we need it.
|
|
// Second anim frame
|
|
//if ( pSample->m_fBlendFactor < 1.0 )
|
|
{
|
|
meshBuilder.Position3f( flX, flY, 0.0f );
|
|
c = renderGeometry[i].m_VertexColors[j];
|
|
c.a *= ( pSample->m_fBlendFactor );
|
|
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
|
float texCoordX = pSample0->m_fLeft_U1 + renderGeometry[i].m_TextureCoords[j].x * sampleWidth;
|
|
float texCoordY = pSample0->m_fTop_V1 + renderGeometry[i].m_TextureCoords[j].y * sampleHeight;
|
|
meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
}
|
|
|
|
//if ( pSample->m_fBlendFactor < 1.0 )
|
|
{
|
|
// FIME make this work with generic convex shapes.
|
|
// Quads only.
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 2 );
|
|
meshBuilder.FastIndex( nIndex + 4 );
|
|
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 4 );
|
|
meshBuilder.FastIndex( nIndex + 6 );
|
|
|
|
meshBuilder.FastIndex( nIndex + 1 );
|
|
meshBuilder.FastIndex( nIndex + 3 );
|
|
meshBuilder.FastIndex( nIndex + 5 );
|
|
|
|
meshBuilder.FastIndex( nIndex + 1 );
|
|
meshBuilder.FastIndex( nIndex + 5 );
|
|
meshBuilder.FastIndex( nIndex + 7 );
|
|
|
|
nIndex += (4 * 2);
|
|
}
|
|
/*
|
|
else
|
|
{
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 1 );
|
|
meshBuilder.FastIndex( nIndex + 2 );
|
|
|
|
meshBuilder.FastIndex( nIndex );
|
|
meshBuilder.FastIndex( nIndex + 2 );
|
|
meshBuilder.FastIndex( nIndex + 3 );
|
|
nIndex += (4 * 1);
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
meshBuilder.End();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 3 draw calls per layer.
|
|
// Render the UI in source 2
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::Render( IRenderContext *pRenderContext, const Rect_t &viewport )
|
|
{
|
|
if ( !m_GameUIDef.GetVisible() )
|
|
return;
|
|
|
|
m_GameUIDef.UpdateGeometry();
|
|
m_GameUIDef.UpdateRenderTransforms( viewport );
|
|
|
|
CUtlVector< LayerRenderLists_t > renderLists;
|
|
m_GameUIDef.GetRenderData( renderLists );
|
|
|
|
// Note this is not scaling correctly!
|
|
|
|
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_NONE );
|
|
pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
|
|
|
|
pRenderContext->BindVertexShader( g_pGameUISystemMgrImpl->m_hVertexShader, g_pGameUISystemMgrImpl->m_hInputLayout );
|
|
pRenderContext->BindShader( RENDER_PIXEL_SHADER, g_pGameUISystemMgrImpl->m_hPixelShader );
|
|
|
|
float pViewportInfo[4] = { viewport.x + 0.5f, viewport.y + 0.5f, viewport.width, viewport.height };
|
|
pRenderContext->SetConstantBufferData( g_pGameUISystemMgrImpl->m_hConstBuffer, pViewportInfo, 4 * sizeof( float ) );
|
|
pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, g_pGameUISystemMgrImpl->m_hConstBuffer, 0, 0 );
|
|
|
|
int nLists = renderLists.Count();
|
|
for ( int i = 0; i < nLists; ++i )
|
|
{
|
|
if ( renderLists[i].m_LayerType == SUBLAYER_STATIC )
|
|
{
|
|
for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
|
|
{
|
|
RenderStaticLayer( pRenderContext, renderLists[i], j );
|
|
}
|
|
}
|
|
else if ( renderLists[i].m_LayerType == SUBLAYER_FONT )
|
|
{
|
|
for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
|
|
{
|
|
RenderTextLayer( pRenderContext, renderLists[i].m_RenderGeometryLists[j] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Render a font layer in source 2
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::RenderTextLayer( IRenderContext *pRenderContext, CUtlVector< CRenderGeometry > &renderGeometry )
|
|
{
|
|
if ( renderGeometry.Count() == 0 )
|
|
return;
|
|
|
|
// get the character texture from the cache
|
|
HRenderTexture fontTextureHandle = g_pGameUISystemSurface->GetTextureHandle( renderGeometry[0].m_FontTextureID );
|
|
pRenderContext->BindTexture( 0, fontTextureHandle );
|
|
|
|
CDynamicVertexData< GameUIVertex_t > vb( pRenderContext, renderGeometry.Count() * 4, "gamelayer", "game_controls" );
|
|
vb.Lock();
|
|
|
|
for ( int i = 0; i < renderGeometry.Count(); ++i )
|
|
{
|
|
Assert( renderGeometry[i].m_Positions.Count() == 4 );
|
|
for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
|
|
{
|
|
vb->m_vecPosition.Init( renderGeometry[i].m_Positions[j].x, renderGeometry[i].m_Positions[j].y, 0.0f );
|
|
vb->m_color = renderGeometry[i].m_VertexColors[j];
|
|
vb->m_vecTexCoord.Init( renderGeometry[i].m_TextureCoords[j].x, renderGeometry[i].m_TextureCoords[j].y );
|
|
vb.AdvanceVertex();
|
|
}
|
|
}
|
|
|
|
vb.Unlock();
|
|
vb.Bind( 0, 0 );
|
|
|
|
CDynamicIndexData< uint16 > ib( pRenderContext, renderGeometry.Count() * 6, "gamelayer", "game_controls" );
|
|
ib.Lock();
|
|
int nIndex = 0;
|
|
for( int i = 0; i < renderGeometry.Count(); ++i )
|
|
{
|
|
ib.Index( nIndex );
|
|
ib.Index( nIndex + 1 );
|
|
ib.Index( nIndex + 2 );
|
|
|
|
ib.Index( nIndex );
|
|
ib.Index( nIndex + 2 );
|
|
ib.Index( nIndex + 3 );
|
|
|
|
nIndex += 4;
|
|
}
|
|
ib.Unlock();
|
|
ib.Bind( 0 );
|
|
|
|
pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, renderGeometry.Count() * 6 );
|
|
|
|
// For debugging.
|
|
//int x = 300;
|
|
//int y = 300;
|
|
//g_pGameUISystemSurface->DrawFontTexture( pRenderContext, renderGeometry[0].m_FontTextureID, x, y );
|
|
//x += 256;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Renders the static layer in source 2
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISystem::RenderStaticLayer( IRenderContext *pRenderContext, LayerRenderLists_t &renderList, int geometryIndex )
|
|
{
|
|
int nGraphicCount = renderList.m_RenderGeometryLists[geometryIndex].Count();
|
|
if ( !nGraphicCount )
|
|
return;
|
|
|
|
int nTotalIndexCount = 0;
|
|
int nTotalVertexCount = 0;
|
|
int nGeometryCount = renderList.m_RenderGeometryLists[geometryIndex].Count();
|
|
for( int i = 0; i < nGeometryCount; ++i )
|
|
{
|
|
nTotalIndexCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount() * 3;
|
|
nTotalVertexCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetVertexCount();
|
|
}
|
|
if ( nTotalIndexCount == 0 )
|
|
return;
|
|
|
|
pRenderContext->BindTexture( 0, renderList.m_hTexture );
|
|
|
|
CDynamicVertexData< GameUIVertex_t > vb( pRenderContext, nTotalVertexCount * 2, "gamelayer", "game_controls" );
|
|
vb.Lock();
|
|
for( int i = 0; i < nGeometryCount; ++i )
|
|
{
|
|
CRenderGeometry *pGeometry = &renderList.m_RenderGeometryLists[geometryIndex][i];
|
|
|
|
const SheetSequenceSample_t *pSample = NULL;
|
|
int seqNum = pGeometry->m_SheetSequenceNumber;
|
|
if ( pGeometry->m_bAnimate )
|
|
{
|
|
DmeTime_t flStartTime = pGeometry->GetAnimStartTime();
|
|
DmeTime_t flAgeInSeconds = ( g_pGameUISystemMgrImpl->GetTime() - flStartTime );
|
|
float m_flAnimationRate = pGeometry->m_AnimationRate;
|
|
float flAgeScale = m_flAnimationRate * SEQUENCE_SAMPLE_COUNT;
|
|
flAgeScale /= renderList.m_pSheet->m_SheetInfo[seqNum].m_flFrameSpan;
|
|
|
|
pSample = renderList.m_pSheet->GetSampleForSequence( flAgeInSeconds.GetSeconds(), flAgeScale, seqNum, true );
|
|
}
|
|
else
|
|
{
|
|
pSample = renderList.m_pSheet->m_SheetInfo[seqNum].m_pSamples;
|
|
}
|
|
|
|
Assert( pSample );
|
|
const SequenceSampleTextureCoords_t *pSample0 = &(pSample->m_TextureCoordData[0]);
|
|
Assert( pSample0 );
|
|
|
|
for ( int j = 0; j < pGeometry->m_Positions.Count(); ++j )
|
|
{
|
|
// First anim frame
|
|
float flX = pGeometry->m_Positions[j].x;
|
|
float flY = pGeometry->m_Positions[j].y;
|
|
vb->m_vecPosition.Init( flX, flY, 0.0f );
|
|
color32 c = pGeometry->m_VertexColors[j];
|
|
c.a *= ( 1 - pSample->m_fBlendFactor );
|
|
vb->m_color = c;
|
|
float sampleWidth = pSample0->m_fRight_U0 - pSample0->m_fLeft_U0;
|
|
float sampleHeight = pSample0->m_fBottom_V0 - pSample0->m_fTop_V0;
|
|
float texCoordX = pSample0->m_fLeft_U0 + pGeometry->m_TextureCoords[j].x * sampleWidth;
|
|
float texCoordY = pSample0->m_fTop_V0 + pGeometry->m_TextureCoords[j].y * sampleHeight;
|
|
vb->m_vecTexCoord.Init( texCoordX, texCoordY );
|
|
vb.AdvanceVertex();
|
|
|
|
// Second anim frame
|
|
//if ( pSample->m_fBlendFactor < 1.0 )
|
|
{
|
|
c = pGeometry->m_VertexColors[j];
|
|
c.a *= ( pSample->m_fBlendFactor );
|
|
vb->m_color = c;
|
|
float texCoordX = pSample0->m_fLeft_U1 + pGeometry->m_TextureCoords[j].x * sampleWidth;
|
|
float texCoordY = pSample0->m_fTop_V1 + pGeometry->m_TextureCoords[j].y * sampleHeight;
|
|
vb->m_vecTexCoord.Init( texCoordX, texCoordY );
|
|
vb.AdvanceVertex();
|
|
}
|
|
}
|
|
}
|
|
vb.Unlock();
|
|
vb.Bind( 0, 0 );
|
|
|
|
CDynamicIndexData< uint16 > ib( pRenderContext, nTotalIndexCount * 2, "gamelayer", "game_controls" );
|
|
ib.Lock();
|
|
int nIndex = 0;
|
|
for( int i = 0; i < nGeometryCount; ++i )
|
|
{
|
|
ib.Index( nIndex );
|
|
ib.Index( nIndex + 2 );
|
|
ib.Index( nIndex + 4 );
|
|
|
|
ib.Index( nIndex );
|
|
ib.Index( nIndex + 4 );
|
|
ib.Index( nIndex + 6 );
|
|
|
|
ib.Index( nIndex + 1 );
|
|
ib.Index( nIndex + 3 );
|
|
ib.Index( nIndex + 5 );
|
|
|
|
ib.Index( nIndex + 1 );
|
|
ib.Index( nIndex + 5 );
|
|
ib.Index( nIndex + 7 );
|
|
|
|
nIndex += (4 * 2);
|
|
|
|
|
|
/*
|
|
// FIXME: Deal with sometimes only rendering 1 triangle above
|
|
CGeometry *pGeometry = geometry[i];
|
|
int nTriangleCount = pGeometry->m_Triangles.Count();
|
|
for ( int j = 0; j < nTriangleCount; ++j )
|
|
{
|
|
CTriangle *pTriangle = &pGeometry->m_Triangles[j];
|
|
//if ( pSample->m_fBlendFactor < 1.0 )
|
|
{
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[0] * 2 );
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[1] * 2 );
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[2] * 2 );
|
|
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[0] * 2 + 1 );
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[1] * 2 + 1 );
|
|
ib.Index( nIndex + pTriangle->m_PointIndex[2] * 2 + 1 );
|
|
}
|
|
else
|
|
{
|
|
//ib.Index( nIndex + pTriangle->m_PointIndex[0] );
|
|
//ib.Index( nIndex + pTriangle->m_PointIndex[1] );
|
|
//ib.Index( nIndex + pTriangle->m_PointIndex[2] );
|
|
//nIndex += 3;
|
|
}
|
|
|
|
}
|
|
nIndex += (3 * 2) * nTriangleCount;
|
|
*/
|
|
|
|
}
|
|
ib.Unlock();
|
|
ib.Bind( 0 );
|
|
|
|
pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nTotalIndexCount * 2 );
|
|
}
|