1
This commit is contained in:
457
vguimatsurface/Clip2D.cpp
Normal file
457
vguimatsurface/Clip2D.cpp
Normal file
@ -0,0 +1,457 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Contains 2D clipping routines
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <vgui/ISurface.h>
|
||||
#include "Clip2D.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "utlvector.h"
|
||||
#if defined( _X360 )
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stretch texture to fit window ( before scissoring )
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool g_bStretchTexture = false;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Max # of vertices for clipping
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
VGUI_VERTEX_TEMP_COUNT = 48,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// For simulated scissor tests...
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ScissorRect_t
|
||||
{
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
};
|
||||
|
||||
static ScissorRect_t g_ScissorRect;
|
||||
static bool g_bScissor = false;
|
||||
static bool g_bFullScreenScissor = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enable/disable scissoring...
|
||||
//-----------------------------------------------------------------------------
|
||||
void EnableScissor( bool enable )
|
||||
{
|
||||
g_bScissor = enable;
|
||||
}
|
||||
|
||||
|
||||
void SetScissorRect( int left, int top, int right, int bottom )
|
||||
{
|
||||
// Check for a valid rectangle...
|
||||
Assert( left <= right );
|
||||
Assert( top <= bottom );
|
||||
|
||||
if ( g_ScissorRect.left == left && g_ScissorRect.right == right &&
|
||||
g_ScissorRect.top == top && g_ScissorRect.bottom == bottom )
|
||||
return;
|
||||
|
||||
g_ScissorRect.left = left;
|
||||
g_ScissorRect.top = top;
|
||||
g_ScissorRect.right = right;
|
||||
g_ScissorRect.bottom = bottom;
|
||||
|
||||
#if defined( _X360 )
|
||||
// no reason to waste cpu on full screen scissor, gpu does it
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
int vx, vy, vw, vh;
|
||||
pRenderContext->GetViewport( vx, vy, vw, vh );
|
||||
g_bFullScreenScissor = (left <= vx && top <= vy && right >= vw && bottom >= vh );
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetScissorRect( int &left, int &top, int &right, int &bottom, bool &enabled )
|
||||
{
|
||||
left = g_ScissorRect.left;
|
||||
top = g_ScissorRect.top;
|
||||
right = g_ScissorRect.right;
|
||||
bottom = g_ScissorRect.bottom;
|
||||
enabled = g_bScissor;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to clip the shadow decals
|
||||
//-----------------------------------------------------------------------------
|
||||
struct PolygonClipState_t
|
||||
{
|
||||
int m_CurrVert;
|
||||
int m_TempCount;
|
||||
int m_ClipCount;
|
||||
vgui::Vertex_t m_pTempVertices[VGUI_VERTEX_TEMP_COUNT];
|
||||
vgui::Vertex_t* m_ppClipVertices[2][VGUI_VERTEX_TEMP_COUNT];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clipping methods for 2D
|
||||
//-----------------------------------------------------------------------------
|
||||
class CClipTop
|
||||
{
|
||||
public:
|
||||
static inline bool Inside( vgui::Vertex_t const& vert )
|
||||
{
|
||||
return vert.m_Position.y >= g_ScissorRect.top;
|
||||
}
|
||||
static inline float Clip( const Vector2D& one, const Vector2D& two )
|
||||
{
|
||||
return (g_ScissorRect.top - one.y) / (two.y - one.y);
|
||||
}
|
||||
};
|
||||
|
||||
class CClipLeft
|
||||
{
|
||||
public:
|
||||
static inline bool Inside( vgui::Vertex_t const& vert )
|
||||
{
|
||||
return vert.m_Position.x >= g_ScissorRect.left;
|
||||
}
|
||||
static inline float Clip( const Vector2D& one, const Vector2D& two )
|
||||
{
|
||||
return (one.x - g_ScissorRect.left) / (one.x - two.x);
|
||||
}
|
||||
};
|
||||
|
||||
class CClipRight
|
||||
{
|
||||
public:
|
||||
static inline bool Inside( vgui::Vertex_t const& vert )
|
||||
{
|
||||
return vert.m_Position.x < g_ScissorRect.right;
|
||||
}
|
||||
static inline float Clip( const Vector2D& one, const Vector2D& two )
|
||||
{
|
||||
return (g_ScissorRect.right - one.x) / (two.x - one.x);
|
||||
}
|
||||
};
|
||||
|
||||
class CClipBottom
|
||||
{
|
||||
public:
|
||||
static inline bool Inside( vgui::Vertex_t const& vert )
|
||||
{
|
||||
return vert.m_Position.y < g_ScissorRect.bottom;
|
||||
}
|
||||
static inline float Clip( const Vector2D& one, const Vector2D& two )
|
||||
{
|
||||
return (one.y - g_ScissorRect.bottom) / (one.y - two.y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Clipper>
|
||||
static inline void Intersect( const vgui::Vertex_t& start, const vgui::Vertex_t& end, vgui::Vertex_t* pOut, Clipper& clipper )
|
||||
{
|
||||
// Clip to the scissor rectangle
|
||||
float t = Clipper::Clip( start.m_Position, end.m_Position );
|
||||
Vector2DLerp( start.m_Position, end.m_Position, t, pOut->m_Position );
|
||||
Vector2DLerp( start.m_TexCoord, end.m_TexCoord, t, pOut->m_TexCoord );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clips a line segment to a single plane
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class Clipper >
|
||||
bool ClipLineToPlane( Clipper &clipper, const vgui::Vertex_t *pInVerts, vgui::Vertex_t* pOutVerts )
|
||||
{
|
||||
bool startInside = Clipper::Inside( pInVerts[0] );
|
||||
bool endInside = Clipper::Inside( pInVerts[1] );
|
||||
|
||||
// Cull
|
||||
if (!startInside && !endInside)
|
||||
return false;
|
||||
|
||||
if (startInside && endInside)
|
||||
{
|
||||
pOutVerts[0] = pInVerts[0];
|
||||
pOutVerts[1] = pInVerts[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int inIndex = startInside ? 0 : 1;
|
||||
pOutVerts[inIndex] = pInVerts[inIndex];
|
||||
Intersect( pInVerts[0], pInVerts[1], &pOutVerts[1 - inIndex], clipper );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clips a line segment to the current scissor rectangle
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ClipLine( const vgui::Vertex_t *pInVerts, vgui::Vertex_t* pOutVerts )
|
||||
{
|
||||
if ( g_bScissor && !g_bFullScreenScissor )
|
||||
{
|
||||
// Clippers...
|
||||
CClipTop top;
|
||||
CClipBottom bottom;
|
||||
CClipLeft left;
|
||||
CClipRight right;
|
||||
|
||||
// Sutherland-hodgman clip, not particularly efficient but that's ok for now
|
||||
vgui::Vertex_t tempVerts[2];
|
||||
if (!ClipLineToPlane( top, pInVerts, tempVerts ))
|
||||
return false;
|
||||
if (!ClipLineToPlane( bottom, tempVerts, pOutVerts ))
|
||||
return false;
|
||||
if (!ClipLineToPlane( left, pOutVerts, tempVerts ))
|
||||
return false;
|
||||
if (!ClipLineToPlane( right, tempVerts, pOutVerts ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOutVerts[0] = pInVerts[0];
|
||||
pOutVerts[1] = pInVerts[1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods associated with clipping 2D polygons
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ScreenClipState_t
|
||||
{
|
||||
int m_iCurrVert;
|
||||
int m_iTempCount;
|
||||
int m_iClipCount;
|
||||
CUtlVector<vgui::Vertex_t> m_pTempVertices;
|
||||
CUtlVector<vgui::Vertex_t*> m_ppClipVertices[2];
|
||||
};
|
||||
|
||||
|
||||
template <class Clipper>
|
||||
static void ScreenClip( ScreenClipState_t& clip, Clipper& clipper )
|
||||
{
|
||||
if (clip.m_iClipCount < 3)
|
||||
return;
|
||||
|
||||
// Ye Olde Sutherland-Hodgman clipping algorithm
|
||||
int numOutVerts = 0;
|
||||
vgui::Vertex_t** pSrcVert = clip.m_ppClipVertices[clip.m_iCurrVert].Base();
|
||||
vgui::Vertex_t** pDestVert = clip.m_ppClipVertices[!clip.m_iCurrVert].Base();
|
||||
|
||||
int numVerts = clip.m_iClipCount;
|
||||
vgui::Vertex_t* pStart = pSrcVert[numVerts-1];
|
||||
bool startInside = Clipper::Inside( *pStart );
|
||||
for (int i = 0; i < numVerts; ++i)
|
||||
{
|
||||
vgui::Vertex_t* pEnd = pSrcVert[i];
|
||||
bool endInside = Clipper::Inside( *pEnd );
|
||||
if (endInside)
|
||||
{
|
||||
if (!startInside)
|
||||
{
|
||||
// Started outside, ended inside, need to clip the edge
|
||||
Assert( clip.m_iTempCount <= clip.m_pTempVertices.Count() );
|
||||
|
||||
// Allocate a new clipped vertex
|
||||
pDestVert[numOutVerts] = &clip.m_pTempVertices[clip.m_iTempCount++];
|
||||
|
||||
// Clip the edge to the clip plane
|
||||
Intersect( *pStart, *pEnd, pDestVert[numOutVerts], clipper );
|
||||
++numOutVerts;
|
||||
}
|
||||
pDestVert[numOutVerts++] = pEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startInside)
|
||||
{
|
||||
// Started inside, ended outside, need to clip the edge
|
||||
Assert( clip.m_iTempCount <= clip.m_pTempVertices.Count() );
|
||||
|
||||
// Allocate a new clipped vertex
|
||||
pDestVert[numOutVerts] = &clip.m_pTempVertices[clip.m_iTempCount++];
|
||||
|
||||
// Clip the edge to the clip plane
|
||||
Intersect( *pStart, *pEnd, pDestVert[numOutVerts], clipper );
|
||||
++numOutVerts;
|
||||
}
|
||||
}
|
||||
pStart = pEnd;
|
||||
startInside = endInside;
|
||||
}
|
||||
|
||||
// Switch source lists
|
||||
clip.m_iCurrVert = 1 - clip.m_iCurrVert;
|
||||
clip.m_iClipCount = numOutVerts;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clips a polygon to the screen area
|
||||
//-----------------------------------------------------------------------------
|
||||
int ClipPolygon( int iCount, vgui::Vertex_t *pVerts, int iTranslateX, int iTranslateY, vgui::Vertex_t ***pppOutVertex )
|
||||
{
|
||||
static ScreenClipState_t clip;
|
||||
|
||||
// Allocate enough room in the clip state...
|
||||
// Having no reallocations during clipping
|
||||
clip.m_pTempVertices.EnsureCount( iCount * 4 );
|
||||
clip.m_ppClipVertices[0].EnsureCount( iCount * 4 );
|
||||
clip.m_ppClipVertices[1].EnsureCount( iCount * 4 );
|
||||
|
||||
// Copy the initial verts in...
|
||||
for (int i = 0; i < iCount; ++i)
|
||||
{
|
||||
// NOTE: This only works because we EnsuredCount above
|
||||
clip.m_pTempVertices[i] = pVerts[i];
|
||||
clip.m_pTempVertices[i].m_Position.x += iTranslateX;
|
||||
clip.m_pTempVertices[i].m_Position.y += iTranslateY;
|
||||
clip.m_ppClipVertices[0][i] = &clip.m_pTempVertices[i];
|
||||
}
|
||||
|
||||
if ( !g_bScissor || g_bFullScreenScissor )
|
||||
{
|
||||
Assert(pppOutVertex);
|
||||
*pppOutVertex = clip.m_ppClipVertices[0].Base();
|
||||
return iCount;
|
||||
}
|
||||
|
||||
clip.m_iClipCount = iCount;
|
||||
clip.m_iTempCount = iCount;
|
||||
clip.m_iCurrVert = 0;
|
||||
|
||||
// Clippers...
|
||||
CClipTop top;
|
||||
CClipBottom bottom;
|
||||
CClipLeft left;
|
||||
CClipRight right;
|
||||
|
||||
// Sutherland-hodgman clip
|
||||
ScreenClip( clip, top );
|
||||
ScreenClip( clip, bottom );
|
||||
ScreenClip( clip, left );
|
||||
ScreenClip( clip, right );
|
||||
|
||||
if (clip.m_iClipCount < 3)
|
||||
return 0;
|
||||
|
||||
// Return a pointer to the array of clipped vertices...
|
||||
Assert(pppOutVertex);
|
||||
*pppOutVertex = clip.m_ppClipVertices[clip.m_iCurrVert].Base();
|
||||
return clip.m_iClipCount;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used for clipping, produces an interpolated texture coordinate
|
||||
//-----------------------------------------------------------------------------
|
||||
inline float InterpTCoord(float val, float mins, float maxs, float tMin, float tMax)
|
||||
{
|
||||
float flPercent;
|
||||
if (mins != maxs)
|
||||
flPercent = (float)(val - mins) / (maxs - mins);
|
||||
else
|
||||
flPercent = 0.5f;
|
||||
return tMin + (tMax - tMin) * flPercent;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Does a scissor clip of the input rectangle.
|
||||
// Returns false if it is completely clipped off.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ClipRect( const vgui::Vertex_t &inUL, const vgui::Vertex_t &inLR,
|
||||
vgui::Vertex_t *pOutUL, vgui::Vertex_t *pOutLR )
|
||||
{
|
||||
// Check for a valid rectangle...
|
||||
// Assert( inUL.m_Position.x <= inLR.m_Position.x );
|
||||
// Assert( inUL.m_Position.y <= inLR.m_Position.y );
|
||||
|
||||
if ( IsX360() && ( !g_bScissor || g_bFullScreenScissor ||
|
||||
( inUL.m_Position.x >= g_ScissorRect.left && inLR.m_Position.x <= g_ScissorRect.right && inUL.m_Position.y >= g_ScissorRect.top && inLR.m_Position.y <= g_ScissorRect.bottom ) ) )
|
||||
{
|
||||
// clipping is not needed
|
||||
// either full screen, and hw will do it or rect is inscribed, and operation is meaningless
|
||||
*pOutUL = inUL;
|
||||
*pOutLR = inLR;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( g_bScissor )
|
||||
{
|
||||
// Pick whichever left side is larger
|
||||
if (g_ScissorRect.left > inUL.m_Position.x)
|
||||
pOutUL->m_Position.x = g_ScissorRect.left;
|
||||
else
|
||||
pOutUL->m_Position.x = inUL.m_Position.x;
|
||||
|
||||
// Pick whichever right side is smaller
|
||||
if (g_ScissorRect.right <= inLR.m_Position.x)
|
||||
pOutLR->m_Position.x = g_ScissorRect.right;
|
||||
else
|
||||
pOutLR->m_Position.x = inLR.m_Position.x;
|
||||
|
||||
// Pick whichever top side is larger
|
||||
if (g_ScissorRect.top > inUL.m_Position.y)
|
||||
pOutUL->m_Position.y = g_ScissorRect.top;
|
||||
else
|
||||
pOutUL->m_Position.y = inUL.m_Position.y;
|
||||
|
||||
// Pick whichever bottom side is smaller
|
||||
if (g_ScissorRect.bottom <= inLR.m_Position.y)
|
||||
pOutLR->m_Position.y = g_ScissorRect.bottom;
|
||||
else
|
||||
pOutLR->m_Position.y = inLR.m_Position.y;
|
||||
|
||||
// Check for non-intersecting
|
||||
if ( (pOutUL->m_Position.x > pOutLR->m_Position.x) ||
|
||||
(pOutUL->m_Position.y > pOutLR->m_Position.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !g_bStretchTexture )
|
||||
{
|
||||
pOutUL->m_TexCoord.x = InterpTCoord(pOutUL->m_Position.x,
|
||||
inUL.m_Position.x, inLR.m_Position.x, inUL.m_TexCoord.x, inLR.m_TexCoord.x);
|
||||
pOutLR->m_TexCoord.x = InterpTCoord(pOutLR->m_Position.x,
|
||||
inUL.m_Position.x, inLR.m_Position.x, inUL.m_TexCoord.x, inLR.m_TexCoord.x);
|
||||
|
||||
pOutUL->m_TexCoord.y = InterpTCoord(pOutUL->m_Position.y,
|
||||
inUL.m_Position.y, inLR.m_Position.y, inUL.m_TexCoord.y, inLR.m_TexCoord.y);
|
||||
pOutLR->m_TexCoord.y = InterpTCoord(pOutLR->m_Position.y,
|
||||
inUL.m_Position.y, inLR.m_Position.y, inUL.m_TexCoord.y, inLR.m_TexCoord.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME, this isn't right
|
||||
pOutUL->m_TexCoord = inUL.m_TexCoord;
|
||||
pOutLR->m_TexCoord = inLR.m_TexCoord;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pOutUL = inUL;
|
||||
*pOutLR = inLR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
46
vguimatsurface/Clip2D.h
Normal file
46
vguimatsurface/Clip2D.h
Normal file
@ -0,0 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Contains 2D clipping routines
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CLIP2D_H
|
||||
#define CLIP2D_H
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
struct Vertex_t;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enable/disable scissoring...
|
||||
//-----------------------------------------------------------------------------
|
||||
void EnableScissor( bool enable );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// For simulated scissor tests...
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetScissorRect( int left, int top, int right, int bottom );
|
||||
void GetScissorRect( int &left, int &top, int &right, int &bottom, bool &enabled );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clips a line segment to the current scissor rectangle
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ClipLine( const vgui::Vertex_t *pInVerts, vgui::Vertex_t* pOutVerts );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Does a scissor clip of the input rectangle.
|
||||
// Returns false if it is completely clipped off.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ClipRect( const vgui::Vertex_t &inUL, const vgui::Vertex_t &inLR,
|
||||
vgui::Vertex_t *pOutUL, vgui::Vertex_t *pOutLR );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clips a polygon to the screen area
|
||||
//-----------------------------------------------------------------------------
|
||||
int ClipPolygon( int iCount, vgui::Vertex_t *pVerts, int iTranslateX, int iTranslateY, vgui::Vertex_t ***pppOutVertex );
|
||||
|
||||
#endif // CLIP2D_H
|
565
vguimatsurface/Cursor.cpp
Normal file
565
vguimatsurface/Cursor.cpp
Normal file
@ -0,0 +1,565 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Methods associated with the cursor
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#if !defined( _X360 )
|
||||
#define OEMRESOURCE //for OCR_* cursor junk
|
||||
#include "winlite.h"
|
||||
#endif
|
||||
#include <appframework/ilaunchermgr.h>
|
||||
|
||||
#if defined( USE_SDL )
|
||||
#undef M_PI
|
||||
#include "SDL.h"
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/vcrmode.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "Cursor.h"
|
||||
#include "vguimatsurface.h"
|
||||
#include "MatSystemSurface.h"
|
||||
#include "filesystem.h"
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
#if defined( USE_SDL )
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#endif
|
||||
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
#if defined( USE_SDL )
|
||||
static SDL_Cursor *s_pDefaultCursor[ dc_last ];
|
||||
static SDL_Cursor *s_hCurrentCursor = NULL;
|
||||
static SDL_Cursor *s_hCurrentlySetCursor = NULL;
|
||||
#elif defined( WIN32 )
|
||||
static HICON s_pDefaultCursor[ dc_last ];
|
||||
static HICON s_hCurrentCursor = NULL;
|
||||
#endif
|
||||
static bool s_bCursorLocked = false;
|
||||
static bool s_bCursorVisible = true;
|
||||
static int s_nForceCursorVisibleCount = 0;
|
||||
static bool s_bSoftwareCursorActive = false;
|
||||
static int s_nSoftwareCursorTexture = -1;
|
||||
static float s_fSoftwareCursorOffsetX = 0;
|
||||
static float s_fSoftwareCursorOffsetY = 0;
|
||||
static int s_rnSoftwareCursorID[20];
|
||||
static float s_rfSoftwareCursorOffset[20][2];
|
||||
static bool s_bSoftwareCursorsInitialized = false;
|
||||
|
||||
extern CMatSystemSurface g_MatSystemSurface;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes cursors
|
||||
//-----------------------------------------------------------------------------
|
||||
void InitCursors()
|
||||
{
|
||||
// load up all default cursors
|
||||
#if defined( USE_SDL )
|
||||
|
||||
s_pDefaultCursor[ dc_none ] = NULL;
|
||||
s_pDefaultCursor[ dc_arrow ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_ARROW );
|
||||
s_pDefaultCursor[ dc_ibeam ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_IBEAM );
|
||||
s_pDefaultCursor[ dc_hourglass ]= SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_WAIT );
|
||||
s_pDefaultCursor[ dc_crosshair ]= SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_CROSSHAIR );
|
||||
s_pDefaultCursor[ dc_waitarrow ]= SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_WAITARROW );
|
||||
s_pDefaultCursor[ dc_sizenwse ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_SIZENWSE );
|
||||
s_pDefaultCursor[ dc_sizenesw ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_SIZENESW );
|
||||
s_pDefaultCursor[ dc_sizewe ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_SIZEWE );
|
||||
s_pDefaultCursor[ dc_sizens ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_SIZENS );
|
||||
s_pDefaultCursor[ dc_sizeall ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_SIZEALL );
|
||||
s_pDefaultCursor[ dc_no ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_NO );
|
||||
s_pDefaultCursor[ dc_hand ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_HAND );
|
||||
|
||||
s_hCurrentCursor = s_pDefaultCursor[ dc_arrow ];
|
||||
|
||||
#elif defined( WIN32 )
|
||||
|
||||
s_pDefaultCursor[ dc_none ] = NULL;
|
||||
s_pDefaultCursor[ dc_arrow ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_NORMAL);
|
||||
s_pDefaultCursor[ dc_ibeam ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_IBEAM);
|
||||
s_pDefaultCursor[ dc_hourglass ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_WAIT);
|
||||
s_pDefaultCursor[ dc_crosshair ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_CROSS);
|
||||
s_pDefaultCursor[ dc_waitarrow ] =(HICON)LoadCursor(NULL, (LPCTSTR)32650);
|
||||
s_pDefaultCursor[ dc_up ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_UP);
|
||||
s_pDefaultCursor[ dc_sizenwse ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_SIZENWSE);
|
||||
s_pDefaultCursor[ dc_sizenesw ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_SIZENESW);
|
||||
s_pDefaultCursor[ dc_sizewe ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_SIZEWE);
|
||||
s_pDefaultCursor[ dc_sizens ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_SIZENS);
|
||||
s_pDefaultCursor[ dc_sizeall ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_SIZEALL);
|
||||
s_pDefaultCursor[ dc_no ] =(HICON)LoadCursor(NULL, (LPCTSTR)OCR_NO);
|
||||
s_pDefaultCursor[ dc_hand ] =(HICON)LoadCursor(NULL, (LPCTSTR)32649);
|
||||
|
||||
s_hCurrentCursor = s_pDefaultCursor[ dc_arrow ];
|
||||
|
||||
#endif
|
||||
|
||||
s_bCursorLocked = false;
|
||||
s_bCursorVisible = true;
|
||||
s_nForceCursorVisibleCount = 0;
|
||||
}
|
||||
|
||||
|
||||
#define USER_CURSOR_MASK 0x80000000
|
||||
|
||||
#ifdef WIN32
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple manager for user loaded windows cursors in vgui
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUserCursorManager
|
||||
{
|
||||
public:
|
||||
void Shutdown();
|
||||
vgui::HCursor CreateCursorFromFile( char const *curOrAniFile, char const *pPathID );
|
||||
bool LookupCursor( vgui::HCursor cursor, HCURSOR& handle );
|
||||
private:
|
||||
CUtlDict< HCURSOR, int > m_UserCursors;
|
||||
};
|
||||
|
||||
void CUserCursorManager::Shutdown()
|
||||
{
|
||||
for ( int i = m_UserCursors.First() ; i != m_UserCursors.InvalidIndex(); i = m_UserCursors.Next( i ) )
|
||||
{
|
||||
::DestroyCursor( m_UserCursors[ i ] );
|
||||
}
|
||||
m_UserCursors.RemoveAll();
|
||||
}
|
||||
|
||||
vgui::HCursor CUserCursorManager::CreateCursorFromFile( char const *curOrAniFile, char const *pPathID )
|
||||
{
|
||||
char fn[ 512 ];
|
||||
Q_strncpy( fn, curOrAniFile, sizeof( fn ) );
|
||||
Q_strlower( fn );
|
||||
Q_FixSlashes( fn );
|
||||
|
||||
int cursorIndex = m_UserCursors.Find( fn );
|
||||
if ( cursorIndex != m_UserCursors.InvalidIndex() )
|
||||
{
|
||||
return cursorIndex | USER_CURSOR_MASK;
|
||||
}
|
||||
|
||||
g_pFullFileSystem->GetLocalCopy( fn );
|
||||
|
||||
char fullpath[ 512 ];
|
||||
g_pFullFileSystem->RelativePathToFullPath( fn, pPathID, fullpath, sizeof( fullpath ) );
|
||||
|
||||
HCURSOR newCursor = (HCURSOR)LoadCursorFromFile( fullpath );
|
||||
cursorIndex = m_UserCursors.Insert( fn, newCursor );
|
||||
return cursorIndex | USER_CURSOR_MASK;
|
||||
}
|
||||
|
||||
bool CUserCursorManager::LookupCursor( vgui::HCursor cursor, HCURSOR& handle )
|
||||
{
|
||||
if ( !( (int)cursor & USER_CURSOR_MASK ) )
|
||||
{
|
||||
handle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int cursorIndex = (int)cursor & ~USER_CURSOR_MASK;
|
||||
if ( !m_UserCursors.IsValidIndex( cursorIndex ) )
|
||||
{
|
||||
handle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
handle = m_UserCursors[ cursorIndex ];
|
||||
return true;
|
||||
}
|
||||
|
||||
static CUserCursorManager g_UserCursors;
|
||||
#endif
|
||||
|
||||
vgui::HCursor Cursor_CreateCursorFromFile( char const *curOrAniFile, char const *pPathID )
|
||||
{
|
||||
#ifdef WIN32
|
||||
return g_UserCursors.CreateCursorFromFile( curOrAniFile, pPathID );
|
||||
#else
|
||||
return dc_user;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Cursor_ClearUserCursors()
|
||||
{
|
||||
#ifdef WIN32
|
||||
g_UserCursors.Shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes all the textures for software cursors
|
||||
//-----------------------------------------------------------------------------
|
||||
int InitSoftwareCursorTexture( const char *pchFilename )
|
||||
{
|
||||
if( !pchFilename || !*pchFilename )
|
||||
return -1;
|
||||
|
||||
int nTextureID = g_MatSystemSurface.DrawGetTextureId( pchFilename );
|
||||
if( nTextureID == -1 )
|
||||
{
|
||||
nTextureID = g_MatSystemSurface.CreateNewTextureID();
|
||||
g_MatSystemSurface.DrawSetTextureFile( nTextureID, pchFilename, true, false );
|
||||
}
|
||||
return nTextureID;
|
||||
}
|
||||
|
||||
void InitSoftwareCursors()
|
||||
{
|
||||
if( s_bSoftwareCursorsInitialized )
|
||||
return;
|
||||
|
||||
memset( s_rfSoftwareCursorOffset, 0, sizeof( s_rfSoftwareCursorOffset ) );
|
||||
|
||||
s_rnSoftwareCursorID[dc_none] = -1;
|
||||
s_rnSoftwareCursorID[dc_arrow] =InitSoftwareCursorTexture( "vgui/cursors/arrow" );
|
||||
s_rnSoftwareCursorID[dc_ibeam] =InitSoftwareCursorTexture( "vgui/cursors/ibeam" );
|
||||
s_rnSoftwareCursorID[dc_hourglass]=InitSoftwareCursorTexture( "vgui/cursors/hourglass" );
|
||||
s_rnSoftwareCursorID[dc_crosshair]=InitSoftwareCursorTexture( "vgui/cursors/crosshair" );
|
||||
s_rnSoftwareCursorID[dc_waitarrow]=InitSoftwareCursorTexture( "vgui/cursors/waitarrow" );
|
||||
s_rnSoftwareCursorID[dc_up] =InitSoftwareCursorTexture( "vgui/cursors/up" );
|
||||
s_rnSoftwareCursorID[dc_sizenwse] =InitSoftwareCursorTexture( "vgui/cursors/sizenwse" );
|
||||
s_rnSoftwareCursorID[dc_sizenesw] =InitSoftwareCursorTexture( "vgui/cursors/sizenesw" );
|
||||
s_rnSoftwareCursorID[dc_sizewe] =InitSoftwareCursorTexture( "vgui/cursors/sizewe" );
|
||||
s_rnSoftwareCursorID[dc_sizens] =InitSoftwareCursorTexture( "vgui/cursors/sizens" );
|
||||
s_rnSoftwareCursorID[dc_sizeall] =InitSoftwareCursorTexture( "vgui/cursors/sizeall" );
|
||||
s_rnSoftwareCursorID[dc_no] =InitSoftwareCursorTexture( "vgui/cursors/no" );
|
||||
s_rnSoftwareCursorID[dc_hand] =InitSoftwareCursorTexture( "vgui/cursors/hand" );
|
||||
|
||||
// handle the cursor hotspots not being at their origin
|
||||
s_rfSoftwareCursorOffset[dc_arrow][0] = -0.1;
|
||||
s_rfSoftwareCursorOffset[dc_arrow][1] = -0.1;
|
||||
s_rfSoftwareCursorOffset[dc_ibeam][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_ibeam][1] = -0.8;
|
||||
s_rfSoftwareCursorOffset[dc_hourglass][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_hourglass][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_crosshair][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_crosshair][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_waitarrow][0] = -0.1;
|
||||
s_rfSoftwareCursorOffset[dc_waitarrow][1] = -0.1;
|
||||
s_rfSoftwareCursorOffset[dc_up][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_up][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizenwse][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizenwse][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizenesw][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizenesw][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizewe][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizewe][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizens][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizens][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizeall][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_sizeall][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_no][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_no][1] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_hand][0] = -0.5;
|
||||
s_rfSoftwareCursorOffset[dc_hand][1] = -0.5;
|
||||
|
||||
s_bSoftwareCursorsInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects a cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CursorSelect(HCursor hCursor)
|
||||
{
|
||||
if ( ( hCursor == dc_alwaysvisible_push ) || ( hCursor == dc_alwaysvisible_pop ) )
|
||||
{
|
||||
// CConPanel in engine/console.cpp does a SetCursor(null). So when the TF2 chat window pops up
|
||||
// and there are console commands showing and fading out in the top left, our chat window
|
||||
// will have a cursor show/hide fight with them. So the cursor flickers or doesn't show up
|
||||
// at all. Unfortunately on Linux, it's even worse since we recenter the mouse when it's
|
||||
// not shown - so we added this API call which causes cursor.cpp to always show the cursor.
|
||||
s_nForceCursorVisibleCount += ( hCursor == dc_alwaysvisible_push ? 1 : -1 );
|
||||
Assert( s_nForceCursorVisibleCount >= 0 );
|
||||
|
||||
if( ( s_nForceCursorVisibleCount && !s_bCursorVisible ) ||
|
||||
( !s_nForceCursorVisibleCount && s_bCursorVisible ) )
|
||||
{
|
||||
ActivateCurrentCursor();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_bCursorLocked)
|
||||
return;
|
||||
|
||||
#if defined( WIN32 ) && !defined( USE_SDL )
|
||||
s_bCursorVisible = true;
|
||||
switch (hCursor)
|
||||
{
|
||||
case dc_user:
|
||||
case dc_none:
|
||||
case dc_blank:
|
||||
s_bCursorVisible = false;
|
||||
break;
|
||||
|
||||
case dc_arrow:
|
||||
case dc_waitarrow:
|
||||
case dc_ibeam:
|
||||
case dc_hourglass:
|
||||
case dc_crosshair:
|
||||
case dc_up:
|
||||
case dc_sizenwse:
|
||||
case dc_sizenesw:
|
||||
case dc_sizewe:
|
||||
case dc_sizens:
|
||||
case dc_sizeall:
|
||||
case dc_no:
|
||||
case dc_hand:
|
||||
if( !s_bSoftwareCursorActive )
|
||||
{
|
||||
s_hCurrentCursor = s_pDefaultCursor[hCursor];
|
||||
}
|
||||
else
|
||||
{
|
||||
s_nSoftwareCursorTexture = s_rnSoftwareCursorID[ hCursor ];
|
||||
s_fSoftwareCursorOffsetX = s_rfSoftwareCursorOffset[ hCursor ][0];
|
||||
s_fSoftwareCursorOffsetY = s_rfSoftwareCursorOffset[ hCursor ][1];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
HCURSOR custom = 0;
|
||||
if ( g_UserCursors.LookupCursor( hCursor, custom ) && custom != 0 )
|
||||
{
|
||||
s_hCurrentCursor = custom;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_bCursorVisible = false;
|
||||
Assert(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ActivateCurrentCursor();
|
||||
|
||||
#elif defined( USE_SDL )
|
||||
|
||||
switch (hCursor)
|
||||
{
|
||||
case dc_user:
|
||||
case dc_none:
|
||||
case dc_blank:
|
||||
s_bCursorVisible = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// We don't support custom cursors at the moment (but could, if necessary).
|
||||
// Fall through and use the arrow for now...
|
||||
Assert(0);
|
||||
hCursor = dc_arrow;
|
||||
|
||||
case dc_arrow:
|
||||
case dc_waitarrow:
|
||||
case dc_ibeam:
|
||||
case dc_hourglass:
|
||||
case dc_crosshair:
|
||||
case dc_up:
|
||||
case dc_sizenwse:
|
||||
case dc_sizenesw:
|
||||
case dc_sizewe:
|
||||
case dc_sizens:
|
||||
case dc_sizeall:
|
||||
case dc_no:
|
||||
case dc_hand:
|
||||
s_bCursorVisible = true;
|
||||
if( !s_bSoftwareCursorActive )
|
||||
{
|
||||
s_hCurrentCursor = s_pDefaultCursor[hCursor];
|
||||
}
|
||||
else
|
||||
{
|
||||
s_nSoftwareCursorTexture = s_rnSoftwareCursorID[ hCursor ];
|
||||
s_fSoftwareCursorOffsetX = s_rfSoftwareCursorOffset[ hCursor ][0];
|
||||
s_fSoftwareCursorOffsetY = s_rfSoftwareCursorOffset[ hCursor ][1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ActivateCurrentCursor();
|
||||
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hides the hardware cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void HideHardwareCursor()
|
||||
{
|
||||
#if defined( WIN32 ) && !defined( USE_SDL )
|
||||
::SetCursor(NULL);
|
||||
#elif defined( USE_SDL )
|
||||
//if ( s_hCurrentlySetCursor != s_pDefaultCursor[ dc_none ] )
|
||||
{
|
||||
s_hCurrentlySetCursor = s_pDefaultCursor[ dc_none ];
|
||||
g_pLauncherMgr->SetMouseCursor( s_hCurrentlySetCursor );
|
||||
g_pLauncherMgr->SetMouseVisible( false );
|
||||
}
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Activates the current cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void ActivateCurrentCursor()
|
||||
{
|
||||
if( s_bSoftwareCursorActive )
|
||||
{
|
||||
HideHardwareCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( s_bCursorVisible || ( s_nForceCursorVisibleCount > 0 ) )
|
||||
{
|
||||
#if defined( WIN32 ) && !defined( USE_SDL )
|
||||
::SetCursor(s_hCurrentCursor);
|
||||
#elif defined( USE_SDL )
|
||||
if (s_hCurrentlySetCursor != s_hCurrentCursor )
|
||||
{
|
||||
s_hCurrentlySetCursor = s_hCurrentCursor;
|
||||
g_pLauncherMgr->SetMouseCursor( s_hCurrentlySetCursor );
|
||||
g_pLauncherMgr->SetMouseVisible( true );
|
||||
}
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
HideHardwareCursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: prevents vgui from changing the cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void LockCursor( bool bEnable )
|
||||
{
|
||||
s_bCursorLocked = bEnable;
|
||||
ActivateCurrentCursor();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unlocks the cursor state
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsCursorLocked()
|
||||
{
|
||||
return s_bCursorLocked;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// handles mouse movement
|
||||
//-----------------------------------------------------------------------------
|
||||
void CursorSetPos( void *hwnd, int x, int y )
|
||||
{
|
||||
#if defined( USE_SDL )
|
||||
if ( s_bCursorVisible )
|
||||
#endif
|
||||
g_pInputSystem->SetCursorPosition( x, y );
|
||||
}
|
||||
|
||||
void CursorGetPos(void *hwnd, int &x, int &y)
|
||||
{
|
||||
#if defined ( USE_SDL ) && !defined( PLATFORM_WINDOWS )
|
||||
if ( s_bCursorVisible )
|
||||
{
|
||||
SDL_GetMouseState( &x, &y );
|
||||
|
||||
int windowHeight = 0;
|
||||
int windowWidth = 0;
|
||||
//unsigned int ignored;
|
||||
SDL_GetWindowSize( ( SDL_Window * )g_pLauncherMgr->GetWindowRef(), &windowWidth, &windowHeight );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
int rx, ry, width, height;
|
||||
pRenderContext->GetViewport( rx, ry, width, height );
|
||||
|
||||
if ( !s_bSoftwareCursorActive && (width != windowWidth || height != windowHeight ) )
|
||||
{
|
||||
// scale the x/y back into the co-ords of the back buffer, not the scaled up window
|
||||
//DevMsg( "Mouse x:%d y:%d %d %d %d %d\n", x, y, width, windowWidth, height, abs( height - windowHeight ) );
|
||||
x = x * (float)width/windowWidth;
|
||||
y = y * (float)height/windowHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cursor is invisible, just say we have it pinned to the middle of the screen
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
int rx, ry, width, height;
|
||||
pRenderContext->GetViewport( rx, ry, width, height );
|
||||
x = rx + width/2;
|
||||
y = ry + height/2;
|
||||
//printf( "Mouse(inv) x:%d y:%d %d %d\n", x, y, width, height );
|
||||
}
|
||||
#else
|
||||
POINT pt;
|
||||
|
||||
// Default implementation
|
||||
VCRHook_GetCursorPos( &pt );
|
||||
VCRHook_ScreenToClient((HWND)hwnd, &pt);
|
||||
x = pt.x; y = pt.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void EnableSoftwareCursor( bool bEnable )
|
||||
{
|
||||
if( bEnable )
|
||||
InitSoftwareCursors();
|
||||
|
||||
bool bWasEnabled = s_bSoftwareCursorActive;
|
||||
s_bSoftwareCursorActive = bEnable;
|
||||
|
||||
// set the cursor to the arrow (or none if appropriate) if we're activating the
|
||||
// software cursor. VGUI will likely update it again soon, but this will give
|
||||
// us some kind of cursor in the meantime
|
||||
if( !bWasEnabled && bEnable )
|
||||
{
|
||||
if( s_bCursorVisible )
|
||||
CursorSelect( dc_arrow );
|
||||
}
|
||||
}
|
||||
|
||||
bool ShouldDrawSoftwareCursor()
|
||||
{
|
||||
return s_bSoftwareCursorActive && s_bCursorVisible;
|
||||
}
|
||||
|
||||
int GetSoftwareCursorTexture( float *px, float *py )
|
||||
{
|
||||
if( px && py )
|
||||
{
|
||||
*px = s_fSoftwareCursorOffsetX;
|
||||
*py = s_fSoftwareCursorOffsetY;
|
||||
}
|
||||
return s_nSoftwareCursorTexture;
|
||||
}
|
||||
|
||||
|
75
vguimatsurface/Cursor.h
Normal file
75
vguimatsurface/Cursor.h
Normal file
@ -0,0 +1,75 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Methods associated with the cursor
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MATSURFACE_CURSOR_H
|
||||
#define MATSURFACE_CURSOR_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include <vgui/Cursor.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes cursors
|
||||
//-----------------------------------------------------------------------------
|
||||
void InitCursors();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects a cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CursorSelect(vgui::HCursor hCursor);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Activates the current cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void ActivateCurrentCursor();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles software cursors
|
||||
//-----------------------------------------------------------------------------
|
||||
void EnableSoftwareCursor( bool bEnable );
|
||||
bool ShouldDrawSoftwareCursor();
|
||||
int GetSoftwareCursorTexture( float *px, float *py );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// handles mouse movement
|
||||
//-----------------------------------------------------------------------------
|
||||
void CursorSetPos(void *hwnd, int x, int y);
|
||||
void CursorGetPos(void *hwnd, int &x, int &y);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: prevents vgui from changing the cursor
|
||||
//-----------------------------------------------------------------------------
|
||||
void LockCursor( bool bEnable );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unlocks the cursor state
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsCursorLocked();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads a custom cursor file from the file system
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::HCursor Cursor_CreateCursorFromFile( char const *curOrAniFile, char const *pPathID );
|
||||
|
||||
// Helper for shutting down cursors
|
||||
void Cursor_ClearUserCursors();
|
||||
|
||||
#endif // MATSURFACE_CURSOR_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
512
vguimatsurface/FontTextureCache.cpp
Normal file
512
vguimatsurface/FontTextureCache.cpp
Normal file
@ -0,0 +1,512 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if defined ( WIN32 ) && !defined( _X360 )
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined( OSX )
|
||||
#include <Carbon/Carbon.h>
|
||||
#elif defined( LINUX )
|
||||
//#error
|
||||
#elif defined( _X360 )
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
#include "FontTextureCache.h"
|
||||
#include "MatSystemSurface.h"
|
||||
#include <vgui_surfacelib/BitmapFont.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "vtf/vtf.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "pixelwriter.h"
|
||||
#include "tier0/icommandline.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern CMatSystemSurface g_MatSystemSurface;
|
||||
static int g_FontRenderBoundingBoxes = -1;
|
||||
|
||||
#define TEXTURE_PAGE_WIDTH 256
|
||||
#define TEXTURE_PAGE_HEIGHT 256
|
||||
|
||||
// row size
|
||||
int CFontTextureCache::s_pFontPageSize[FONT_PAGE_SIZE_COUNT] =
|
||||
{
|
||||
16,
|
||||
32,
|
||||
64,
|
||||
128,
|
||||
256,
|
||||
};
|
||||
|
||||
static bool g_mat_texture_outline_fonts = false;
|
||||
CON_COMMAND( mat_texture_outline_fonts, "Outline fonts textures." )
|
||||
{
|
||||
g_mat_texture_outline_fonts = !g_mat_texture_outline_fonts;
|
||||
Msg( "mat_texture_outline_fonts: %d\n", g_mat_texture_outline_fonts );
|
||||
g_MatSystemSurface.ResetFontCaches();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFontTextureCache::CFontTextureCache()
|
||||
: m_CharCache(0, 256, CacheEntryLessFunc)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFontTextureCache::~CFontTextureCache()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Resets the cache
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFontTextureCache::Clear()
|
||||
{
|
||||
// remove all existing data
|
||||
m_CharCache.RemoveAll();
|
||||
m_PageList.RemoveAll();
|
||||
|
||||
// reinitialize
|
||||
CacheEntry_t listHead = { 0, 0 };
|
||||
m_LRUListHeadIndex = m_CharCache.Insert(listHead);
|
||||
|
||||
m_CharCache[m_LRUListHeadIndex].nextEntry = m_LRUListHeadIndex;
|
||||
m_CharCache[m_LRUListHeadIndex].prevEntry = m_LRUListHeadIndex;
|
||||
|
||||
for (int i = 0; i < FONT_PAGE_SIZE_COUNT; ++i)
|
||||
{
|
||||
m_pCurrPage[i] = -1;
|
||||
}
|
||||
m_FontPages.SetLessFunc( DefLessFunc( vgui::HFont ) );
|
||||
m_FontPages.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: comparison function for cache entries
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFontTextureCache::CacheEntryLessFunc(CacheEntry_t const &lhs, CacheEntry_t const &rhs)
|
||||
{
|
||||
if (lhs.font < rhs.font)
|
||||
return true;
|
||||
else if (lhs.font > rhs.font)
|
||||
return false;
|
||||
|
||||
return (lhs.wch < rhs.wch);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the texture info for the given char & font
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFontTextureCache::GetTextureForChar( vgui::HFont font, vgui::FontDrawType_t type, wchar_t wch, int *textureID, float **texCoords )
|
||||
{
|
||||
// Ask for just one character
|
||||
return GetTextureForChars( font, type, &wch, textureID, texCoords, 1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the texture info for the given chars & font
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFontTextureCache::GetTextureForChars( vgui::HFont font, vgui::FontDrawType_t type, const wchar_t *wch, int *textureID, float **texCoords, int numChars )
|
||||
{
|
||||
Assert( wch && textureID && texCoords );
|
||||
Assert( numChars >= 1 );
|
||||
|
||||
if ( type == vgui::FONT_DRAW_DEFAULT )
|
||||
{
|
||||
type = g_MatSystemSurface.IsFontAdditive( font ) ? vgui::FONT_DRAW_ADDITIVE : vgui::FONT_DRAW_NONADDITIVE;
|
||||
}
|
||||
|
||||
int typePage = (int)type - 1;
|
||||
typePage = clamp( typePage, 0, (int)vgui::FONT_DRAW_TYPE_COUNT - 1 );
|
||||
|
||||
if ( FontManager().IsBitmapFont( font ) )
|
||||
{
|
||||
const int MAX_BITMAP_CHARS = 256;
|
||||
if ( numChars > MAX_BITMAP_CHARS )
|
||||
{
|
||||
// Increase MAX_BITMAP_CHARS
|
||||
Assert( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < numChars; i++ )
|
||||
{
|
||||
static float sTexCoords[ 4*MAX_BITMAP_CHARS ];
|
||||
CBitmapFont *pWinFont;
|
||||
float left, top, right, bottom;
|
||||
int index;
|
||||
Page_t *pPage;
|
||||
|
||||
pWinFont = reinterpret_cast< CBitmapFont* >( FontManager().GetFontForChar( font, wch[i] ) );
|
||||
if ( !pWinFont )
|
||||
{
|
||||
// bad font handle
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the texture coords
|
||||
pWinFont->GetCharCoords( wch[i], &left, &top, &right, &bottom );
|
||||
sTexCoords[i*4 + 0] = left;
|
||||
sTexCoords[i*4 + 1] = top;
|
||||
sTexCoords[i*4 + 2] = right;
|
||||
sTexCoords[i*4 + 3] = bottom;
|
||||
|
||||
// find font handle in our list of ready pages
|
||||
index = m_FontPages.Find( font );
|
||||
if ( index == m_FontPages.InvalidIndex() )
|
||||
{
|
||||
// not found, create the texture id and its materials
|
||||
index = m_FontPages.Insert( font );
|
||||
pPage = &m_FontPages.Element( index );
|
||||
|
||||
for (int type = 0; type < FONT_DRAW_TYPE_COUNT; ++type )
|
||||
{
|
||||
pPage->textureID[type] = g_MatSystemSurface.CreateNewTextureID( false );
|
||||
}
|
||||
CreateFontMaterials( *pPage, pWinFont->GetTexturePage(), true );
|
||||
}
|
||||
|
||||
texCoords[i] = &(sTexCoords[ i*4 ]);
|
||||
textureID[i] = m_FontPages.Element( index ).textureID[typePage];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct newPageEntry_t
|
||||
{
|
||||
int page; // The font page a new character will go in
|
||||
int drawX; // X location within the font page
|
||||
int drawY; // Y location within the font page
|
||||
};
|
||||
|
||||
// Determine how many characters need to have their texture generated
|
||||
int numNewChars = 0;
|
||||
int maxNewCharTexels = 0;
|
||||
int totalNewCharTexels = 0;
|
||||
newChar_t *newChars = (newChar_t *)_alloca( numChars*sizeof( newChar_t ) );
|
||||
newPageEntry_t *newEntries = (newPageEntry_t *)_alloca( numChars*sizeof( newPageEntry_t ) );
|
||||
|
||||
font_t *winFont = FontManager().GetFontForChar( font, wch[0] );
|
||||
if ( !winFont )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < numChars; i++ )
|
||||
{
|
||||
CacheEntry_t cacheItem;
|
||||
cacheItem.font = font;
|
||||
cacheItem.wch = wch[i];
|
||||
HCacheEntry cacheHandle = m_CharCache.Find( cacheItem );
|
||||
if ( ! m_CharCache.IsValidIndex( cacheHandle ) )
|
||||
{
|
||||
// All characters must come out of the same font
|
||||
if ( winFont != FontManager().GetFontForChar( font, wch[i] ) )
|
||||
return false;
|
||||
|
||||
// get the char details
|
||||
int a, b, c;
|
||||
winFont->GetCharABCWidths( wch[i], a, b, c );
|
||||
int fontWide = max( b, 1 );
|
||||
int fontTall = max( winFont->GetHeight(), 1 );
|
||||
if ( winFont->GetUnderlined() )
|
||||
{
|
||||
fontWide += ( a + c );
|
||||
}
|
||||
|
||||
// Get a texture to render into
|
||||
int page, drawX, drawY, twide, ttall;
|
||||
if ( !AllocatePageForChar( fontWide, fontTall, page, drawX, drawY, twide, ttall ) )
|
||||
return false;
|
||||
|
||||
// accumulate data to pass to GetCharsRGBA below
|
||||
newEntries[ numNewChars ].page = page;
|
||||
newEntries[ numNewChars ].drawX = drawX;
|
||||
newEntries[ numNewChars ].drawY = drawY;
|
||||
newChars[ numNewChars ].wch = wch[i];
|
||||
newChars[ numNewChars ].fontWide = fontWide;
|
||||
newChars[ numNewChars ].fontTall = fontTall;
|
||||
newChars[ numNewChars ].offset = 4*totalNewCharTexels;
|
||||
totalNewCharTexels += fontWide*fontTall;
|
||||
maxNewCharTexels = max( maxNewCharTexels, fontWide*fontTall );
|
||||
numNewChars++;
|
||||
|
||||
// set the cache info
|
||||
cacheItem.page = page;
|
||||
|
||||
// the 0.5 texel offset is done in CMatSystemTexture::SetMaterial() / CMatSystemSurface::StartDrawing()
|
||||
double adjust = 0.0f;
|
||||
|
||||
cacheItem.texCoords[0] = (float)( (double)drawX / ((double)twide + adjust) );
|
||||
cacheItem.texCoords[1] = (float)( (double)drawY / ((double)ttall + adjust) );
|
||||
cacheItem.texCoords[2] = (float)( (double)(drawX + fontWide) / (double)twide );
|
||||
cacheItem.texCoords[3] = (float)( (double)(drawY + fontTall) / (double)ttall );
|
||||
|
||||
m_CharCache.Insert(cacheItem);
|
||||
cacheHandle = m_CharCache.Find( cacheItem );
|
||||
Assert( m_CharCache.IsValidIndex( cacheHandle ) );
|
||||
}
|
||||
|
||||
int page = m_CharCache[cacheHandle].page;
|
||||
textureID[i] = m_PageList[page].textureID[typePage];
|
||||
texCoords[i] = m_CharCache[cacheHandle].texCoords;
|
||||
}
|
||||
|
||||
// Generate texture data for all newly-encountered characters
|
||||
if ( numNewChars > 0 )
|
||||
{
|
||||
|
||||
#ifdef _X360
|
||||
if ( numNewChars > 1 )
|
||||
{
|
||||
MEM_ALLOC_CREDIT();
|
||||
|
||||
// Use the 360 fast path that generates multiple characters at once
|
||||
int newCharDataSize = totalNewCharTexels*4;
|
||||
CUtlBuffer newCharData( newCharDataSize, newCharDataSize, 0 );
|
||||
unsigned char *pRGBA = (unsigned char *)newCharData.Base();
|
||||
winFont->GetCharsRGBA( newChars, numNewChars, pRGBA );
|
||||
|
||||
// Copy the data into our font pages
|
||||
for ( int i = 0; i < numNewChars; i++ )
|
||||
{
|
||||
newChar_t & newChar = newChars[i];
|
||||
newPageEntry_t & newEntry = newEntries[i];
|
||||
|
||||
// upload the new sub texture
|
||||
// NOTE: both textureIDs reference the same ITexture, so we're ok
|
||||
g_MatSystemSurface.DrawSetTexture( m_PageList[newEntry.page].textureID[typePage] );
|
||||
unsigned char *characterRGBA = pRGBA + newChar.offset;
|
||||
g_MatSystemSurface.DrawSetSubTextureRGBA( m_PageList[newEntry.page].textureID[typePage], newEntry.drawX, newEntry.drawY, characterRGBA, newChar.fontWide, newChar.fontTall );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// create a buffer for new characters to be rendered into
|
||||
int nByteCount = maxNewCharTexels * 4;
|
||||
unsigned char *pRGBA = (unsigned char *)_alloca( nByteCount );
|
||||
|
||||
// Generate characters individually
|
||||
for ( int i = 0; i < numNewChars; i++ )
|
||||
{
|
||||
newChar_t & newChar = newChars[i];
|
||||
newPageEntry_t & newEntry = newEntries[i];
|
||||
|
||||
// render the character into the buffer
|
||||
Q_memset( pRGBA, 0, nByteCount );
|
||||
|
||||
winFont->GetCharRGBA( newChar.wch, newChar.fontWide, newChar.fontTall, pRGBA );
|
||||
|
||||
if ( g_mat_texture_outline_fonts )
|
||||
{
|
||||
int width = newChar.fontWide;
|
||||
int height = newChar.fontTall;
|
||||
|
||||
CPixelWriter pixelWriter;
|
||||
pixelWriter.SetPixelMemory( IMAGE_FORMAT_RGBA8888, pRGBA, width * sizeof( BGRA8888_t ) );
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
pixelWriter.Seek( x, 0 );
|
||||
pixelWriter.WritePixel( 255, 0, 255, 255 );
|
||||
pixelWriter.Seek( x, height - 1 );
|
||||
pixelWriter.WritePixel( 255, 0, 255, 255 );
|
||||
}
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
if ( y < 4 || y > height - 4 )
|
||||
{
|
||||
pixelWriter.Seek( 0, y );
|
||||
pixelWriter.WritePixel( 255, 0, 255, 255 );
|
||||
pixelWriter.Seek( width - 1, y );
|
||||
pixelWriter.WritePixel( 255, 0, 255, 255 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// upload the new sub texture
|
||||
// NOTE: both textureIDs reference the same ITexture, so we're ok)
|
||||
g_MatSystemSurface.DrawSetTexture( m_PageList[newEntry.page].textureID[typePage] );
|
||||
g_MatSystemSurface.DrawSetSubTextureRGBA( m_PageList[newEntry.page].textureID[typePage], newEntry.drawX, newEntry.drawY, pRGBA, newChar.fontWide, newChar.fontTall );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates font materials
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFontTextureCache::CreateFontMaterials( Page_t &page, ITexture *pFontTexture, bool bitmapFont )
|
||||
{
|
||||
// The normal material
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetInt( "$vertexcolor", 1 );
|
||||
pVMTKeyValues->SetInt( "$vertexalpha", 1 );
|
||||
pVMTKeyValues->SetInt( "$ignorez", 1 );
|
||||
pVMTKeyValues->SetInt( "$no_fullbright", 1 );
|
||||
pVMTKeyValues->SetInt( "$translucent", 1 );
|
||||
pVMTKeyValues->SetString( "$basetexture", pFontTexture->GetName() );
|
||||
IMaterial *pMaterial = g_pMaterialSystem->CreateMaterial( "__fontpage", pVMTKeyValues );
|
||||
pMaterial->Refresh();
|
||||
|
||||
int typePageNonAdditive = (int)vgui::FONT_DRAW_NONADDITIVE-1;
|
||||
g_MatSystemSurface.DrawSetTextureMaterial( page.textureID[typePageNonAdditive], pMaterial );
|
||||
pMaterial->DecrementReferenceCount();
|
||||
|
||||
// The additive material
|
||||
pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetInt( "$vertexcolor", 1 );
|
||||
pVMTKeyValues->SetInt( "$vertexalpha", 1 );
|
||||
pVMTKeyValues->SetInt( "$ignorez", 1 );
|
||||
pVMTKeyValues->SetInt( "$no_fullbright", 1 );
|
||||
pVMTKeyValues->SetInt( "$translucent", 1 );
|
||||
pVMTKeyValues->SetInt( "$additive", 1 );
|
||||
pVMTKeyValues->SetString( "$basetexture", pFontTexture->GetName() );
|
||||
pMaterial = g_pMaterialSystem->CreateMaterial( "__fontpage_additive", pVMTKeyValues );
|
||||
pMaterial->Refresh();
|
||||
|
||||
int typePageAdditive = (int)vgui::FONT_DRAW_ADDITIVE-1;
|
||||
if ( bitmapFont )
|
||||
{
|
||||
g_MatSystemSurface.DrawSetTextureMaterial( page.textureID[typePageAdditive], pMaterial );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_MatSystemSurface.ReferenceProceduralMaterial( page.textureID[typePageAdditive], page.textureID[typePageNonAdditive], pMaterial );
|
||||
}
|
||||
pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes the page size given a character height
|
||||
//-----------------------------------------------------------------------------
|
||||
int CFontTextureCache::ComputePageType( int charTall ) const
|
||||
{
|
||||
for (int i = 0; i < FONT_PAGE_SIZE_COUNT; ++i)
|
||||
{
|
||||
if ( charTall < s_pFontPageSize[i] )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: allocates a new page for a given character
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFontTextureCache::AllocatePageForChar(int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall)
|
||||
{
|
||||
// see if there is room in the last page for this character
|
||||
int nPageType = ComputePageType( charTall );
|
||||
if ( nPageType < 0 )
|
||||
{
|
||||
Assert( !"Font is too tall for texture cache of glyphs\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
pageIndex = m_pCurrPage[nPageType];
|
||||
|
||||
int nNextX = 0;
|
||||
bool bNeedsNewPage = true;
|
||||
if ( pageIndex > -1 )
|
||||
{
|
||||
Page_t &page = m_PageList[ pageIndex ];
|
||||
|
||||
nNextX = page.nextX + charWide;
|
||||
|
||||
// make sure we have room on the current line of the texture page
|
||||
if ( nNextX > page.wide )
|
||||
{
|
||||
// move down a line
|
||||
page.nextX = 0;
|
||||
nNextX = charWide;
|
||||
page.nextY += page.tallestCharOnLine;
|
||||
page.tallestCharOnLine = charTall;
|
||||
}
|
||||
page.tallestCharOnLine = max( page.tallestCharOnLine, (short)charTall );
|
||||
|
||||
bNeedsNewPage = ((page.nextY + page.tallestCharOnLine) > page.tall);
|
||||
}
|
||||
|
||||
if ( bNeedsNewPage )
|
||||
{
|
||||
// allocate a new page
|
||||
pageIndex = m_PageList.AddToTail();
|
||||
Page_t &newPage = m_PageList[pageIndex];
|
||||
m_pCurrPage[nPageType] = pageIndex;
|
||||
|
||||
for (int i = 0; i < FONT_DRAW_TYPE_COUNT; ++i )
|
||||
{
|
||||
newPage.textureID[i] = g_MatSystemSurface.CreateNewTextureID( true );
|
||||
}
|
||||
|
||||
newPage.maxFontHeight = s_pFontPageSize[nPageType];
|
||||
newPage.wide = TEXTURE_PAGE_WIDTH;
|
||||
newPage.tall = TEXTURE_PAGE_HEIGHT;
|
||||
newPage.nextX = 0;
|
||||
newPage.nextY = 0;
|
||||
newPage.tallestCharOnLine = charTall;
|
||||
|
||||
nNextX = charWide;
|
||||
|
||||
static int nFontPageId = 0;
|
||||
char pTextureName[64];
|
||||
Q_snprintf( pTextureName, 64, "__font_page_%d", nFontPageId );
|
||||
++nFontPageId;
|
||||
|
||||
MEM_ALLOC_CREDIT();
|
||||
ITexture *pTexture = g_pMaterialSystem->CreateProceduralTexture(
|
||||
pTextureName,
|
||||
TEXTURE_GROUP_VGUI,
|
||||
newPage.wide,
|
||||
newPage.tall,
|
||||
IMAGE_FORMAT_RGBA8888,
|
||||
TEXTUREFLAGS_POINTSAMPLE | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT |
|
||||
TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY );
|
||||
|
||||
CreateFontMaterials( newPage, pTexture );
|
||||
|
||||
pTexture->DecrementReferenceCount();
|
||||
|
||||
if ( IsPC() || !IsDebug() )
|
||||
{
|
||||
// clear the texture from the inital checkerboard to black
|
||||
// allocate for 32bpp format
|
||||
int nByteCount = TEXTURE_PAGE_WIDTH * TEXTURE_PAGE_HEIGHT * 4;
|
||||
unsigned char *pRGBA = (unsigned char *)_alloca( nByteCount );
|
||||
Q_memset( pRGBA, 0, nByteCount );
|
||||
|
||||
int typePageNonAdditive = (int)(vgui::FONT_DRAW_NONADDITIVE)-1;
|
||||
g_MatSystemSurface.DrawSetTextureRGBA( newPage.textureID[typePageNonAdditive], pRGBA, newPage.wide, newPage.tall, false, false );
|
||||
}
|
||||
}
|
||||
|
||||
// output the position
|
||||
Page_t &page = m_PageList[ pageIndex ];
|
||||
drawX = page.nextX;
|
||||
drawY = page.nextY;
|
||||
twide = page.wide;
|
||||
ttall = page.tall;
|
||||
|
||||
// Update the next position to draw in
|
||||
page.nextX = nNextX + 1;
|
||||
return true;
|
||||
}
|
102
vguimatsurface/FontTextureCache.h
Normal file
102
vguimatsurface/FontTextureCache.h
Normal file
@ -0,0 +1,102 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef FONTTEXTURECACHE_H
|
||||
#define FONTTEXTURECACHE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui_surfacelib/FontManager.h"
|
||||
#include "utlrbtree.h"
|
||||
#include <vgui/ISurface.h>
|
||||
#include "utlmap.h"
|
||||
|
||||
class ITexture;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: manages texture memory for unicode fonts in vgui
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFontTextureCache
|
||||
{
|
||||
public:
|
||||
CFontTextureCache();
|
||||
~CFontTextureCache();
|
||||
|
||||
// returns a texture ID and a pointer to an array of 4 texture coords for the given character & font
|
||||
// generates+uploads more texture if necessary
|
||||
bool GetTextureForChar( vgui::HFont font, vgui::FontDrawType_t type, wchar_t wch, int *textureID, float **texCoords );
|
||||
|
||||
// for each character in an array (not assumed to be a NULL-terminated string), returns a
|
||||
// texture ID and a pointer to an array of 4 texture coords for the given character & font
|
||||
// generates+uploads more texture if necessary
|
||||
bool GetTextureForChars( vgui::HFont font, vgui::FontDrawType_t type, const wchar_t *wch, int *textureID, float **texCoords, int numChars = 1 );
|
||||
|
||||
// clears the cache
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
// NOTE: If you change this, change s_pFontPageSize
|
||||
enum
|
||||
{
|
||||
FONT_PAGE_SIZE_16,
|
||||
FONT_PAGE_SIZE_32,
|
||||
FONT_PAGE_SIZE_64,
|
||||
FONT_PAGE_SIZE_128,
|
||||
FONT_PAGE_SIZE_256,
|
||||
FONT_PAGE_SIZE_COUNT,
|
||||
};
|
||||
|
||||
// a single character in the cache
|
||||
typedef unsigned short HCacheEntry;
|
||||
struct CacheEntry_t
|
||||
{
|
||||
vgui::HFont font;
|
||||
wchar_t wch;
|
||||
unsigned char page;
|
||||
float texCoords[4];
|
||||
|
||||
// doubly-linked list for use in the LRU
|
||||
HCacheEntry nextEntry;
|
||||
HCacheEntry prevEntry;
|
||||
};
|
||||
|
||||
// a single texture page
|
||||
struct Page_t
|
||||
{
|
||||
short textureID[vgui::FONT_DRAW_TYPE_COUNT];
|
||||
short maxFontHeight;
|
||||
short tallestCharOnLine;
|
||||
short wide, tall; // total size of the page
|
||||
short nextX, nextY; // position to draw any new character positions
|
||||
};
|
||||
|
||||
// allocates a new page for a given character
|
||||
bool AllocatePageForChar(int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall);
|
||||
|
||||
// Creates font materials
|
||||
void CreateFontMaterials( Page_t &page, ITexture *pFontTexture, bool bitmapFont = false );
|
||||
|
||||
// Computes the page size given a character height
|
||||
int ComputePageType( int charTall ) const;
|
||||
|
||||
static bool CacheEntryLessFunc(const CacheEntry_t &lhs, const CacheEntry_t &rhs);
|
||||
|
||||
CUtlRBTree<CacheEntry_t, HCacheEntry> m_CharCache;
|
||||
|
||||
// cache
|
||||
typedef CUtlVector<Page_t> FontPageList_t;
|
||||
FontPageList_t m_PageList;
|
||||
|
||||
int m_pCurrPage[FONT_PAGE_SIZE_COUNT];
|
||||
HCacheEntry m_LRUListHeadIndex;
|
||||
static int s_pFontPageSize[FONT_PAGE_SIZE_COUNT];
|
||||
CUtlMap< vgui::HFont, Page_t > m_FontPages;
|
||||
};
|
||||
|
||||
|
||||
#endif // FONTTEXTURECACHE_H
|
524
vguimatsurface/Input.cpp
Normal file
524
vguimatsurface/Input.cpp
Normal file
@ -0,0 +1,524 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of the VGUI ISurface interface using the
|
||||
// material system to implement it
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#if defined( WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#include <zmouse.h>
|
||||
#endif
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "Input.h"
|
||||
#include "vguimatsurface.h"
|
||||
#include "../vgui2/src/VPanel.h"
|
||||
#include <vgui/KeyCode.h>
|
||||
#include <vgui/MouseCode.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IClientPanel.h>
|
||||
#include "inputsystem/ButtonCode.h"
|
||||
#include "Cursor.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "../vgui2/src/vgui_key_translation.h"
|
||||
#include <vgui/IInputInternal.h>
|
||||
#include "tier0/icommandline.h"
|
||||
#ifdef _X360
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vgui input events
|
||||
//-----------------------------------------------------------------------------
|
||||
enum VguiInputEventType_t
|
||||
{
|
||||
IE_Close = IE_FirstVguiEvent,
|
||||
IE_LocateMouseClick,
|
||||
IE_SetCursor,
|
||||
IE_KeyTyped,
|
||||
IE_KeyCodeTyped,
|
||||
IE_InputLanguageChanged,
|
||||
IE_IMESetWindow,
|
||||
IE_IMEStartComposition,
|
||||
IE_IMEComposition,
|
||||
IE_IMEEndComposition,
|
||||
IE_IMEShowCandidates,
|
||||
IE_IMEChangeCandidates,
|
||||
IE_IMECloseCandidates,
|
||||
IE_IMERecomputeModes,
|
||||
};
|
||||
|
||||
void InitInput()
|
||||
{
|
||||
EnableInput( true );
|
||||
}
|
||||
|
||||
|
||||
static bool s_bInputEnabled = true;
|
||||
#ifdef WIN32
|
||||
//-----------------------------------------------------------------------------
|
||||
// Translates actual keys into VGUI ids
|
||||
//-----------------------------------------------------------------------------
|
||||
static WNDPROC s_ChainedWindowProc = NULL;
|
||||
extern HWND thisWindow;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes the input system
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool s_bIMEComposing = false;
|
||||
static HWND s_hLastHWnd = 0;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles input messages
|
||||
//-----------------------------------------------------------------------------
|
||||
static LRESULT CALLBACK MatSurfaceWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if ( !s_bInputEnabled )
|
||||
goto chainWndProc;
|
||||
|
||||
InputEvent_t event;
|
||||
memset( &event, 0, sizeof(event) );
|
||||
event.m_nTick = g_pInputSystem->GetPollTick();
|
||||
|
||||
if ( hwnd != s_hLastHWnd )
|
||||
{
|
||||
s_hLastHWnd = hwnd;
|
||||
event.m_nType = IE_IMESetWindow;
|
||||
event.m_nData = (int)s_hLastHWnd;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
}
|
||||
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_QUIT:
|
||||
// According to windows docs, WM_QUIT should never be passed to wndprocs
|
||||
Assert( 0 );
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
// Handle close messages
|
||||
{
|
||||
LONG_PTR wndProc = GetWindowLongPtrW( hwnd, GWLP_WNDPROC );
|
||||
if ( wndProc == (LONG_PTR)MatSurfaceWindowProc )
|
||||
{
|
||||
event.m_nType = IE_Close;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
// All mouse messages need to mark where the click occurred before chaining down
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case MS_WM_XBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case MS_WM_XBUTTONUP:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case MS_WM_XBUTTONDBLCLK:
|
||||
event.m_nType = IE_LocateMouseClick;
|
||||
event.m_nData = (short)LOWORD(lParam);
|
||||
event.m_nData2 = (short)HIWORD(lParam);
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
event.m_nType = IE_SetCursor;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
break;
|
||||
|
||||
case WM_XCONTROLLER_KEY:
|
||||
if ( IsX360() )
|
||||
{
|
||||
// First have to insert the edge case event
|
||||
int nRetVal = 0;
|
||||
if ( s_ChainedWindowProc )
|
||||
{
|
||||
nRetVal = CallWindowProcW( s_ChainedWindowProc, hwnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
// xboxissue - as yet HL2 input hasn't been made aware of analog inputs or ports
|
||||
// so just digital step on the sample range
|
||||
int sample = LOWORD( lParam );
|
||||
if ( sample )
|
||||
{
|
||||
event.m_nType = IE_KeyCodeTyped;
|
||||
event.m_nData = (vgui::KeyCode)wParam;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Need to deal with key repeat for keydown since inputsystem doesn't
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
// First have to insert the edge case event
|
||||
int nRetVal = 0;
|
||||
if ( s_ChainedWindowProc )
|
||||
{
|
||||
nRetVal = CallWindowProcW( s_ChainedWindowProc, hwnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
int nKeyRepeat = LOWORD( lParam );
|
||||
for ( int i = 0; i < nKeyRepeat; ++i )
|
||||
{
|
||||
event.m_nType = IE_KeyCodeTyped;
|
||||
event.m_nData = KeyCode_VirtualKeyToVGUI( wParam );
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
}
|
||||
|
||||
return nRetVal;
|
||||
}
|
||||
|
||||
case WM_SYSCHAR:
|
||||
case WM_CHAR:
|
||||
if ( !s_bIMEComposing )
|
||||
{
|
||||
event.m_nType = IE_KeyTyped;
|
||||
event.m_nData = (int)wParam;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_INPUTLANGCHANGE:
|
||||
event.m_nType = IE_InputLanguageChanged;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
break;
|
||||
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
s_bIMEComposing = true;
|
||||
event.m_nType = IE_IMEStartComposition;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
return TRUE;
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
event.m_nType = IE_IMEComposition;
|
||||
event.m_nData = (int)lParam;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
return TRUE;
|
||||
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
s_bIMEComposing = false;
|
||||
event.m_nType = IE_IMEEndComposition;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
return TRUE;
|
||||
|
||||
case WM_IME_NOTIFY:
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case 14: // Chinese Traditional IMN_PRIVATE...
|
||||
break;
|
||||
|
||||
case IMN_OPENCANDIDATE:
|
||||
event.m_nType = IE_IMEShowCandidates;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
return 1;
|
||||
|
||||
case IMN_CHANGECANDIDATE:
|
||||
event.m_nType = IE_IMEChangeCandidates;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
return 0;
|
||||
|
||||
case IMN_CLOSECANDIDATE:
|
||||
event.m_nType = IE_IMECloseCandidates;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
break;
|
||||
|
||||
// To detect the change of IME mode, or the toggling of Japanese IME
|
||||
case IMN_SETCONVERSIONMODE:
|
||||
case IMN_SETSENTENCEMODE:
|
||||
case IMN_SETOPENSTATUS:
|
||||
event.m_nType = IE_IMERecomputeModes;
|
||||
g_pInputSystem->PostUserEvent( event );
|
||||
if ( wParam == IMN_SETOPENSTATUS )
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case IMN_CLOSESTATUSWINDOW:
|
||||
case IMN_GUIDELINE:
|
||||
case IMN_OPENSTATUSWINDOW:
|
||||
case IMN_SETCANDIDATEPOS:
|
||||
case IMN_SETCOMPOSITIONFONT:
|
||||
case IMN_SETCOMPOSITIONWINDOW:
|
||||
case IMN_SETSTATUSWINDOWPOS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case WM_IME_SETCONTEXT:
|
||||
// We draw all IME windows ourselves
|
||||
lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
|
||||
lParam &= ~ISC_SHOWUIGUIDELINE;
|
||||
lParam &= ~ISC_SHOWUIALLCANDIDATEWINDOW;
|
||||
break;
|
||||
|
||||
case WM_IME_CHAR:
|
||||
// We need to process this message so that the IME doesn't double convert the unicode IME characters into garbage characters and post
|
||||
// them to our window... (get ? marks after text entry ).
|
||||
return 0;
|
||||
}
|
||||
|
||||
chainWndProc:
|
||||
if ( s_ChainedWindowProc )
|
||||
return CallWindowProcW( s_ChainedWindowProc, hwnd, uMsg, wParam, lParam );
|
||||
|
||||
// This means the application is driving the messages (calling our window procedure manually)
|
||||
// rather than us hooking their window procedure. The engine needs to do this in order for VCR
|
||||
// mode to play back properly.
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enables/disables input (enabled by default)
|
||||
//-----------------------------------------------------------------------------
|
||||
void EnableInput( bool bEnable )
|
||||
{
|
||||
#if 0 // #ifdef BENCHMARK
|
||||
s_bInputEnabled = false;
|
||||
#else
|
||||
s_bInputEnabled = bEnable;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hooks input listening up to a window
|
||||
//-----------------------------------------------------------------------------
|
||||
void InputAttachToWindow(void *hwnd)
|
||||
{
|
||||
#if !defined( USE_SDL )
|
||||
s_ChainedWindowProc = (WNDPROC)GetWindowLongPtrW( (HWND)hwnd, GWLP_WNDPROC );
|
||||
SetWindowLongPtrW( (HWND)hwnd, GWLP_WNDPROC, (LONG_PTR)MatSurfaceWindowProc );
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputDetachFromWindow(void *hwnd)
|
||||
{
|
||||
if (!hwnd)
|
||||
return;
|
||||
if ( s_ChainedWindowProc )
|
||||
{
|
||||
SetWindowLongPtrW( (HWND)hwnd, GWLP_WNDPROC, (LONG_PTR) s_ChainedWindowProc );
|
||||
s_ChainedWindowProc = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void InputAttachToWindow(void *hwnd)
|
||||
{
|
||||
#if !defined( OSX ) && !defined( LINUX )
|
||||
if ( hwnd && !HushAsserts() )
|
||||
{
|
||||
// under OSX we use the Cocoa mgr to route events rather than hooking winprocs
|
||||
// and under Linux we use SDL
|
||||
Assert( !"Implement me" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputDetachFromWindow(void *hwnd)
|
||||
{
|
||||
#if !defined( OSX ) && !defined( LINUX )
|
||||
if ( hwnd && !HushAsserts() )
|
||||
{
|
||||
// under OSX we use the Cocoa mgr to route events rather than hooking winprocs
|
||||
// and under Linux we use SDL
|
||||
Assert( !"Implement me" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Converts an input system button code to a vgui key code
|
||||
// FIXME: Remove notion of vgui::KeyCode + vgui::MouseCode altogether
|
||||
//-----------------------------------------------------------------------------
|
||||
static vgui::KeyCode ButtonCodeToKeyCode( ButtonCode_t buttonCode )
|
||||
{
|
||||
return ( vgui::KeyCode )buttonCode;
|
||||
}
|
||||
|
||||
static vgui::MouseCode ButtonCodeToMouseCode( ButtonCode_t buttonCode )
|
||||
{
|
||||
return ( vgui::MouseCode )buttonCode;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles an input event, returns true if the event should be filtered
|
||||
// from the rest of the game
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InputHandleInputEvent( const InputEvent_t &event )
|
||||
{
|
||||
switch( event.m_nType )
|
||||
{
|
||||
case IE_ButtonPressed:
|
||||
{
|
||||
// NOTE: data2 is the virtual key code (data1 contains the scan-code one)
|
||||
ButtonCode_t code = (ButtonCode_t)event.m_nData2;
|
||||
if ( IsKeyCode( code ) || IsJoystickCode( code ) )
|
||||
{
|
||||
vgui::KeyCode keyCode = ButtonCodeToKeyCode( code );
|
||||
return g_pIInput->InternalKeyCodePressed( keyCode );
|
||||
}
|
||||
|
||||
if ( IsJoystickCode( code ) )
|
||||
{
|
||||
vgui::KeyCode keyCode = ButtonCodeToKeyCode( code );
|
||||
return g_pIInput->InternalKeyCodePressed( keyCode );
|
||||
}
|
||||
|
||||
if ( IsMouseCode( code ) )
|
||||
{
|
||||
vgui::MouseCode mouseCode = ButtonCodeToMouseCode( code );
|
||||
return g_pIInput->InternalMousePressed( mouseCode );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IE_ButtonReleased:
|
||||
{
|
||||
// NOTE: data2 is the virtual key code (data1 contains the scan-code one)
|
||||
ButtonCode_t code = (ButtonCode_t)event.m_nData2;
|
||||
if ( IsKeyCode( code ) || IsJoystickCode( code ) )
|
||||
{
|
||||
vgui::KeyCode keyCode = ButtonCodeToKeyCode( code );
|
||||
return g_pIInput->InternalKeyCodeReleased( keyCode );
|
||||
}
|
||||
|
||||
if ( IsJoystickCode( code ) )
|
||||
{
|
||||
vgui::KeyCode keyCode = ButtonCodeToKeyCode( code );
|
||||
return g_pIInput->InternalKeyCodeReleased( keyCode );
|
||||
}
|
||||
|
||||
if ( IsMouseCode( code ) )
|
||||
{
|
||||
vgui::MouseCode mouseCode = ButtonCodeToMouseCode( code );
|
||||
return g_pIInput->InternalMouseReleased( mouseCode );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IE_ButtonDoubleClicked:
|
||||
{
|
||||
// NOTE: data2 is the virtual key code (data1 contains the scan-code one)
|
||||
ButtonCode_t code = (ButtonCode_t)event.m_nData2;
|
||||
if ( IsMouseCode( code ) )
|
||||
{
|
||||
vgui::MouseCode mouseCode = ButtonCodeToMouseCode( code );
|
||||
return g_pIInput->InternalMouseDoublePressed( mouseCode );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IE_AnalogValueChanged:
|
||||
{
|
||||
if ( event.m_nData == MOUSE_WHEEL )
|
||||
return g_pIInput->InternalMouseWheeled( event.m_nData3 );
|
||||
if ( event.m_nData == MOUSE_XY )
|
||||
return g_pIInput->InternalCursorMoved( event.m_nData2, event.m_nData3 );
|
||||
}
|
||||
break;
|
||||
|
||||
case IE_KeyCodeTyped:
|
||||
{
|
||||
vgui::KeyCode code = (vgui::KeyCode)event.m_nData;
|
||||
g_pIInput->InternalKeyCodeTyped( code );
|
||||
}
|
||||
return true;
|
||||
|
||||
case IE_KeyTyped:
|
||||
{
|
||||
vgui::KeyCode code = (vgui::KeyCode)event.m_nData;
|
||||
g_pIInput->InternalKeyTyped( code );
|
||||
}
|
||||
return true;
|
||||
|
||||
case IE_Quit:
|
||||
g_pVGui->Stop();
|
||||
#if defined( USE_SDL )
|
||||
return false; // also let higher layers consume it
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
case IE_Close:
|
||||
// FIXME: Change this so we don't stop until 'save' occurs, etc.
|
||||
g_pVGui->Stop();
|
||||
return true;
|
||||
|
||||
case IE_SetCursor:
|
||||
ActivateCurrentCursor();
|
||||
return true;
|
||||
|
||||
case IE_IMESetWindow:
|
||||
g_pIInput->SetIMEWindow( (void *)event.m_nData );
|
||||
return true;
|
||||
|
||||
case IE_LocateMouseClick:
|
||||
g_pIInput->InternalCursorMoved( event.m_nData, event.m_nData2 );
|
||||
return true;
|
||||
|
||||
case IE_InputLanguageChanged:
|
||||
g_pIInput->OnInputLanguageChanged();
|
||||
return true;
|
||||
|
||||
case IE_IMEStartComposition:
|
||||
g_pIInput->OnIMEStartComposition();
|
||||
return true;
|
||||
|
||||
case IE_IMEComposition:
|
||||
g_pIInput->OnIMEComposition( event.m_nData );
|
||||
return true;
|
||||
|
||||
case IE_IMEEndComposition:
|
||||
g_pIInput->OnIMEEndComposition();
|
||||
return true;
|
||||
|
||||
case IE_IMEShowCandidates:
|
||||
g_pIInput->OnIMEShowCandidates();
|
||||
return true;
|
||||
|
||||
case IE_IMEChangeCandidates:
|
||||
g_pIInput->OnIMEChangeCandidates();
|
||||
return true;
|
||||
|
||||
case IE_IMECloseCandidates:
|
||||
g_pIInput->OnIMECloseCandidates();
|
||||
return true;
|
||||
|
||||
case IE_IMERecomputeModes:
|
||||
g_pIInput->OnIMERecomputeModes();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
47
vguimatsurface/Input.h
Normal file
47
vguimatsurface/Input.h
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Methods related to input
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct InputEvent_t;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes the input system
|
||||
//-----------------------------------------------------------------------------
|
||||
void InitInput();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hooks input listening up to a window
|
||||
//-----------------------------------------------------------------------------
|
||||
void InputAttachToWindow(void *hwnd);
|
||||
void InputDetachFromWindow(void *hwnd);
|
||||
|
||||
// If input isn't hooked, this forwards messages to vgui.
|
||||
void InputHandleWindowMessage( void *hwnd, unsigned int uMsg, unsigned int wParam, long lParam );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles an input event, returns true if the event should be filtered
|
||||
// from the rest of the game
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InputHandleInputEvent( const InputEvent_t &event );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enables/disables input (enabled by default)
|
||||
//-----------------------------------------------------------------------------
|
||||
void EnableInput( bool bEnable );
|
||||
|
||||
|
||||
#endif // INPUT_H
|
4614
vguimatsurface/MatSystemSurface.cpp
Normal file
4614
vguimatsurface/MatSystemSurface.cpp
Normal file
File diff suppressed because it is too large
Load Diff
643
vguimatsurface/MatSystemSurface.h
Normal file
643
vguimatsurface/MatSystemSurface.h
Normal file
@ -0,0 +1,643 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef MATSYSTEMSURFACE_H
|
||||
#define MATSYSTEMSURFACE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include <vgui/IClientPanel.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/IInput.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui/Point.h>
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlsymbol.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class IImage;
|
||||
|
||||
extern class IMaterialSystem *g_pMaterialSystem;
|
||||
//-----------------------------------------------------------------------------
|
||||
// The default material system embedded panel
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMatEmbeddedPanel : public vgui::Panel
|
||||
{
|
||||
typedef vgui::Panel BaseClass;
|
||||
public:
|
||||
CMatEmbeddedPanel();
|
||||
virtual void OnThink();
|
||||
|
||||
VPANEL IsWithinTraverse(int x, int y, bool traversePopups);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Implementation of the VGUI surface on top of the material system
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMatSystemSurface : public CTier3AppSystem< IMatSystemSurface >
|
||||
{
|
||||
typedef CTier3AppSystem< IMatSystemSurface > BaseClass;
|
||||
|
||||
public:
|
||||
CMatSystemSurface();
|
||||
virtual ~CMatSystemSurface();
|
||||
|
||||
// Methods of IAppSystem
|
||||
virtual bool Connect( CreateInterfaceFn factory );
|
||||
virtual void Disconnect();
|
||||
virtual void *QueryInterface( const char *pInterfaceName );
|
||||
virtual InitReturnVal_t Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
// initialization
|
||||
virtual void SetEmbeddedPanel(vgui::VPANEL pEmbeddedPanel);
|
||||
|
||||
// returns true if a panel is minimzed
|
||||
bool IsMinimized(vgui::VPANEL panel);
|
||||
|
||||
// Sets the only panel to draw. Set to NULL to clear.
|
||||
void RestrictPaintToSinglePanel(vgui::VPANEL panel);
|
||||
|
||||
// frame
|
||||
virtual void RunFrame();
|
||||
|
||||
// implementation of vgui::ISurface
|
||||
virtual vgui::VPANEL GetEmbeddedPanel();
|
||||
|
||||
// drawing context
|
||||
virtual void PushMakeCurrent(vgui::VPANEL panel,bool useInSets);
|
||||
virtual void PopMakeCurrent(vgui::VPANEL panel);
|
||||
|
||||
// rendering functions
|
||||
virtual void DrawSetColor(int r,int g,int b,int a);
|
||||
virtual void DrawSetColor(Color col);
|
||||
|
||||
virtual void DrawLine( int x0, int y0, int x1, int y1 );
|
||||
virtual void DrawTexturedLine( const vgui::Vertex_t &a, const vgui::Vertex_t &b );
|
||||
virtual void DrawPolyLine(int *px, int *py, int numPoints);
|
||||
virtual void DrawTexturedPolyLine( const vgui::Vertex_t *p, int n );
|
||||
|
||||
virtual void DrawFilledRect(int x0, int y0, int x1, int y1);
|
||||
virtual void DrawFilledRectArray( IntRect *pRects, int numRects );
|
||||
virtual void DrawFilledRectFastFade( int x0, int y0, int x1, int y1, int fadeStartPt, int fadeEndPt, unsigned int alpha0, unsigned int alpha1, bool bHorizontal );
|
||||
virtual void DrawFilledRectFade( int x0, int y0, int x1, int y1, unsigned int alpha0, unsigned int alpha1, bool bHorizontal );
|
||||
virtual void DrawOutlinedRect(int x0, int y0, int x1, int y1);
|
||||
virtual void DrawOutlinedCircle(int x, int y, int radius, int segments);
|
||||
|
||||
// textured rendering functions
|
||||
virtual int CreateNewTextureID( bool procedural = false );
|
||||
virtual bool IsTextureIDValid(int id);
|
||||
|
||||
virtual bool DrawGetTextureFile(int id, char *filename, int maxlen );
|
||||
virtual int DrawGetTextureId( char const *filename );
|
||||
virtual int DrawGetTextureId( ITexture *pTexture );
|
||||
virtual void DrawSetTextureFile(int id, const char *filename, int hardwareFilter, bool forceReload);
|
||||
virtual void DrawSetTexture(int id);
|
||||
virtual void DrawGetTextureSize(int id, int &wide, int &tall);
|
||||
virtual bool DeleteTextureByID(int id);
|
||||
|
||||
virtual IVguiMatInfo *DrawGetTextureMatInfoFactory(int id);
|
||||
|
||||
virtual void DrawSetTextureRGBA(int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload);
|
||||
|
||||
virtual void DrawTexturedRect(int x0, int y0, int x1, int y1);
|
||||
virtual void DrawTexturedSubRect( int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1 );
|
||||
|
||||
virtual void DrawTexturedPolygon(int n, vgui::Vertex_t *pVertices, bool bClipVertices = true );
|
||||
|
||||
virtual void DrawPrintText(const wchar_t *text, int textLen, FontDrawType_t drawType = FONT_DRAW_DEFAULT);
|
||||
virtual void DrawUnicodeChar(wchar_t wch, FontDrawType_t drawType = FONT_DRAW_DEFAULT );
|
||||
virtual void DrawUnicodeString( const wchar_t *pwString, FontDrawType_t drawType = FONT_DRAW_DEFAULT );
|
||||
virtual void DrawSetTextFont(vgui::HFont font);
|
||||
virtual void DrawFlushText();
|
||||
|
||||
virtual void DrawSetTextColor(int r, int g, int b, int a);
|
||||
virtual void DrawSetTextColor(Color col);
|
||||
virtual void DrawSetTextScale(float sx, float sy);
|
||||
virtual void DrawSetTextPos(int x, int y);
|
||||
virtual void DrawGetTextPos(int& x,int& y);
|
||||
|
||||
virtual vgui::IHTML *CreateHTMLWindow(vgui::IHTMLEvents *events,vgui::VPANEL context);
|
||||
virtual void PaintHTMLWindow(vgui::IHTML *htmlwin);
|
||||
virtual void DeleteHTMLWindow(vgui::IHTML *htmlwin);
|
||||
virtual bool BHTMLWindowNeedsPaint(IHTML *htmlwin);
|
||||
|
||||
virtual void GetScreenSize(int &wide, int &tall);
|
||||
virtual void SetAsTopMost(vgui::VPANEL panel, bool state);
|
||||
virtual void BringToFront(vgui::VPANEL panel);
|
||||
virtual void SetForegroundWindow (vgui::VPANEL panel);
|
||||
virtual void SetPanelVisible(vgui::VPANEL panel, bool state);
|
||||
virtual void SetMinimized(vgui::VPANEL panel, bool state);
|
||||
virtual void FlashWindow(vgui::VPANEL panel, bool state);
|
||||
virtual void SetTitle(vgui::VPANEL panel, const wchar_t *title);
|
||||
virtual const wchar_t *GetTitle( vgui::VPANEL panel );
|
||||
|
||||
virtual void SetAsToolBar(vgui::VPANEL panel, bool state); // removes the window's task bar entry (for context menu's, etc.)
|
||||
|
||||
// windows stuff
|
||||
virtual void CreatePopup(VPANEL panel, bool minimized, bool showTaskbarIcon = true, bool disabled = false, bool mouseInput = true , bool kbInput = true);
|
||||
|
||||
virtual void SwapBuffers(vgui::VPANEL panel);
|
||||
virtual void Invalidate(vgui::VPANEL panel);
|
||||
|
||||
virtual void SetCursor(vgui::HCursor cursor);
|
||||
virtual bool IsCursorVisible();
|
||||
virtual void SetCursorAlwaysVisible(bool visible);
|
||||
|
||||
virtual void ApplyChanges();
|
||||
virtual bool IsWithin(int x, int y);
|
||||
virtual bool HasFocus();
|
||||
|
||||
virtual bool SupportsFeature(SurfaceFeature_e feature);
|
||||
|
||||
// engine-only focus handling (replacing WM_FOCUS windows handling)
|
||||
virtual void SetTopLevelFocus(vgui::VPANEL panel);
|
||||
|
||||
// fonts
|
||||
virtual vgui::HFont CreateFont();
|
||||
virtual bool SetFontGlyphSet(vgui::HFont font, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int nRangeMin = 0, int nRangeMax = 0);
|
||||
virtual bool SetBitmapFontGlyphSet(vgui::HFont font, const char *windowsFontName, float scalex, float scaley, int flags);
|
||||
virtual int GetFontTall(HFont font);
|
||||
virtual int GetFontTallRequested(HFont font);
|
||||
virtual int GetFontAscent(HFont font, wchar_t wch);
|
||||
virtual bool IsFontAdditive(HFont font);
|
||||
virtual void GetCharABCwide(HFont font, int ch, int &a, int &b, int &c);
|
||||
virtual void GetTextSize(HFont font, const wchar_t *text, int &wide, int &tall);
|
||||
virtual int GetCharacterWidth(vgui::HFont font, int ch);
|
||||
virtual bool AddCustomFontFile(const char *fontName, const char *fontFileName);
|
||||
virtual bool AddBitmapFontFile(const char *fontFileName);
|
||||
virtual void SetBitmapFontName( const char *pName, const char *pFontFilename );
|
||||
virtual const char *GetBitmapFontName( const char *pName );
|
||||
virtual void PrecacheFontCharacters(HFont font, const wchar_t *pCharacters);
|
||||
virtual void ClearTemporaryFontCache( void );
|
||||
virtual const char *GetFontName( HFont font );
|
||||
virtual const char *GetFontFamilyName( HFont font );
|
||||
|
||||
// GameUI-only accessed functions
|
||||
// uploads a part of a texture, used for font rendering
|
||||
void DrawSetSubTextureRGBA(int textureID, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall);
|
||||
void DrawUpdateRegionTextureRGBA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall, ImageFormat imageFormat );
|
||||
|
||||
// notify icons?!?
|
||||
virtual vgui::VPANEL GetNotifyPanel();
|
||||
virtual void SetNotifyIcon(vgui::VPANEL context, vgui::HTexture icon, vgui::VPANEL panelToReceiveMessages, const char *text);
|
||||
|
||||
// plays a sound
|
||||
virtual void PlaySound(const char *fileName);
|
||||
|
||||
//!! these functions Should not be accessed directly, but only through other vgui items
|
||||
//!! need to move these to seperate interface
|
||||
virtual int GetPopupCount();
|
||||
virtual vgui::VPANEL GetPopup( int index );
|
||||
virtual bool ShouldPaintChildPanel(vgui::VPANEL childPanel);
|
||||
virtual bool RecreateContext(vgui::VPANEL panel);
|
||||
virtual void AddPanel(vgui::VPANEL panel);
|
||||
virtual void ReleasePanel(vgui::VPANEL panel);
|
||||
virtual void MovePopupToFront(vgui::VPANEL panel);
|
||||
|
||||
virtual void SolveTraverse(vgui::VPANEL panel, bool forceApplySchemeSettings);
|
||||
virtual void PaintTraverse(vgui::VPANEL panel);
|
||||
|
||||
virtual void EnableMouseCapture(vgui::VPANEL panel, bool state);
|
||||
|
||||
virtual void SetWorkspaceInsets( int left, int top, int right, int bottom );
|
||||
virtual void GetWorkspaceBounds(int &x, int &y, int &wide, int &tall);
|
||||
|
||||
// Hook needed to Get input to work
|
||||
virtual void AttachToWindow( void *hwnd, bool bLetAppDriveInput );
|
||||
virtual bool HandleInputEvent( const InputEvent_t &event );
|
||||
|
||||
void InitFullScreenBuffer( const char *pszRenderTargetName );
|
||||
virtual void Set3DPaintTempRenderTarget( const char *pRenderTargetName );
|
||||
virtual void Reset3DPaintTempRenderTarget( void );
|
||||
|
||||
// Begins, ends 3D painting
|
||||
virtual void Begin3DPaint( int iLeft, int iTop, int iRight, int iBottom, bool bRenderToTexture = true );
|
||||
virtual void End3DPaint();
|
||||
|
||||
virtual void BeginSkinCompositionPainting() OVERRIDE;
|
||||
virtual void EndSkinCompositionPainting() OVERRIDE;
|
||||
|
||||
// Disable clipping during rendering
|
||||
virtual void DisableClipping( bool bDisable ) OVERRIDE;
|
||||
virtual void GetClippingRect( int &left, int &top, int &right, int &bottom, bool &bClippingDisabled ) OVERRIDE;
|
||||
virtual void SetClippingRect( int left, int top, int right, int bottom ) OVERRIDE;
|
||||
|
||||
// Prevents vgui from changing the cursor
|
||||
virtual bool IsCursorLocked() const;
|
||||
|
||||
// Sets the mouse Get + Set callbacks
|
||||
virtual void SetMouseCallbacks( GetMouseCallback_t GetFunc, SetMouseCallback_t SetFunc );
|
||||
|
||||
// Tells the surface to ignore windows messages
|
||||
virtual void EnableWindowsMessages( bool bEnable );
|
||||
|
||||
// Installs a function to play sounds
|
||||
virtual void InstallPlaySoundFunc( PlaySoundFunc_t soundFunc );
|
||||
|
||||
// Some drawing methods that cannot be accomplished under Win32
|
||||
virtual void DrawColoredCircle( int centerx, int centery, float radius, int r, int g, int b, int a );
|
||||
virtual int DrawColoredText( vgui::HFont font, int x, int y, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
virtual void DrawColoredTextRect( vgui::HFont font, int x, int y, int w, int h, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
virtual void DrawTextHeight( vgui::HFont font, int w, int& h, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
// Returns the length in pixels of the text
|
||||
virtual int DrawTextLen( vgui::HFont font, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
// Draws a panel in 3D space.
|
||||
virtual void DrawPanelIn3DSpace( vgui::VPANEL pRootPanel, const VMatrix &panelCenterToWorld, int pw, int ph, float sw, float sh );
|
||||
|
||||
// Only visible within vguimatsurface
|
||||
void DrawSetTextureMaterial(int id, IMaterial *pMaterial);
|
||||
void ReferenceProceduralMaterial( int id, int referenceId, IMaterial *pMaterial );
|
||||
|
||||
// new stuff for Alfreds VGUI2 port!!
|
||||
virtual bool InEngine() { return true; }
|
||||
void GetProportionalBase( int &width, int &height ) { width = BASE_WIDTH; height = BASE_HEIGHT; }
|
||||
virtual bool HasCursorPosFunctions() { return true; }
|
||||
|
||||
virtual void SetModalPanel(VPANEL );
|
||||
virtual VPANEL GetModalPanel();
|
||||
virtual void UnlockCursor();
|
||||
virtual void LockCursor();
|
||||
virtual void SetTranslateExtendedKeys(bool state);
|
||||
virtual VPANEL GetTopmostPopup();
|
||||
virtual void GetAbsoluteWindowBounds(int &x, int &y, int &wide, int &tall);
|
||||
virtual void CalculateMouseVisible();
|
||||
virtual bool NeedKBInput();
|
||||
virtual void SurfaceGetCursorPos(int &x, int &y);
|
||||
virtual void SurfaceSetCursorPos(int x, int y);
|
||||
virtual void MovePopupToBack(VPANEL panel);
|
||||
|
||||
virtual bool IsInThink( VPANEL panel);
|
||||
|
||||
virtual bool DrawGetUnicodeCharRenderInfo( wchar_t ch, CharRenderInfo& info );
|
||||
virtual void DrawRenderCharFromInfo( const CharRenderInfo& info );
|
||||
|
||||
// global alpha setting functions
|
||||
// affect all subsequent draw calls - shouldn't normally be used directly, only in Panel::PaintTraverse()
|
||||
virtual void DrawSetAlphaMultiplier( float alpha /* [0..1] */ );
|
||||
virtual float DrawGetAlphaMultiplier();
|
||||
|
||||
// web browser
|
||||
virtual void SetAllowHTMLJavaScript( bool state );
|
||||
|
||||
// video mode changing
|
||||
virtual void OnScreenSizeChanged( int nOldWidth, int nOldHeight );
|
||||
|
||||
virtual vgui::HCursor CreateCursorFromFile( char const *curOrAniFile, char const *pPathID );
|
||||
|
||||
virtual void PaintTraverseEx(VPANEL panel, bool paintPopups = false );
|
||||
|
||||
virtual float GetZPos() const;
|
||||
|
||||
virtual void SetPanelForInput( VPANEL vpanel );
|
||||
|
||||
virtual vgui::IImage *GetIconImageForFullPath( char const *pFullPath );
|
||||
|
||||
virtual void DestroyTextureID( int id );
|
||||
|
||||
|
||||
virtual const char *GetResolutionKey( void ) const;
|
||||
|
||||
virtual bool ForceScreenSizeOverride( bool bState, int wide, int tall );
|
||||
// LocalToScreen, ParentLocalToScreen fixups for explicit PaintTraverse calls on Panels not at 0, 0 position
|
||||
virtual bool ForceScreenPosOffset( bool bState, int x, int y );
|
||||
|
||||
virtual void OffsetAbsPos( int &x, int &y );
|
||||
|
||||
virtual void GetKernedCharWidth( HFont font, wchar_t ch, wchar_t chBefore, wchar_t chAfter, float &wide, float &flabcA );
|
||||
|
||||
|
||||
virtual const char *GetWebkitHTMLUserAgentString() { return "Valve Client"; }
|
||||
|
||||
virtual void *Deprecated_AccessChromeHTMLController() { return NULL; }
|
||||
|
||||
virtual void SetFullscreenViewport( int x, int y, int w, int h ) OVERRIDE;
|
||||
virtual void SetFullscreenViewportAndRenderTarget( int x, int y, int w, int h, ITexture *pRenderTarget ) OVERRIDE;
|
||||
virtual void GetFullscreenViewportAndRenderTarget( int & x, int & y, int & w, int & h, ITexture **ppRenderTarget ) OVERRIDE;
|
||||
virtual void GetFullscreenViewport( int & x, int & y, int & w, int & h ) OVERRIDE;
|
||||
virtual void PushFullscreenViewport() OVERRIDE;
|
||||
virtual void PopFullscreenViewport() OVERRIDE;
|
||||
|
||||
// support for software cursors
|
||||
virtual void SetSoftwareCursor( bool bUseSoftwareCursor ) OVERRIDE;
|
||||
virtual void PaintSoftwareCursor() OVERRIDE;
|
||||
|
||||
// Methods of ILocalizeTextQuery
|
||||
public:
|
||||
//virtual int ComputeTextWidth( const wchar_t *pString );
|
||||
|
||||
// Causes fonts to get reloaded, etc.
|
||||
virtual void ResetFontCaches();
|
||||
|
||||
virtual bool IsScreenSizeOverrideActive( void );
|
||||
virtual bool IsScreenPosOverrideActive( void );
|
||||
|
||||
virtual IMaterial *DrawGetTextureMaterial( int id );
|
||||
|
||||
virtual int GetTextureNumFrames( int id );
|
||||
virtual void DrawSetTextureFrame( int id, int nFrame, unsigned int *pFrameCache );
|
||||
|
||||
private:
|
||||
//void DrawRenderCharInternal( const FontCharRenderInfo& info );
|
||||
void DrawRenderCharInternal( const CharRenderInfo& info );
|
||||
|
||||
private:
|
||||
enum { BASE_HEIGHT = 480, BASE_WIDTH = 640 };
|
||||
|
||||
struct PaintState_t
|
||||
{
|
||||
vgui::VPANEL m_pPanel;
|
||||
int m_iTranslateX;
|
||||
int m_iTranslateY;
|
||||
int m_iScissorLeft;
|
||||
int m_iScissorRight;
|
||||
int m_iScissorTop;
|
||||
int m_iScissorBottom;
|
||||
};
|
||||
|
||||
// material Setting method
|
||||
void InternalSetMaterial( IMaterial *material = NULL );
|
||||
|
||||
// Draws the fullscreen buffer into the panel
|
||||
void DrawFullScreenBuffer( int nLeft, int nTop, int nRight, int nBottom );
|
||||
|
||||
// Helper method to initialize vertices (transforms them into screen space too)
|
||||
void InitVertex( vgui::Vertex_t &vertex, int x, int y, float u, float v );
|
||||
|
||||
// Draws a quad + quad array
|
||||
void DrawQuad( const vgui::Vertex_t &ul, const vgui::Vertex_t &lr, unsigned char *pColor );
|
||||
void DrawQuadArray( int numQuads, vgui::Vertex_t *pVerts, unsigned char *pColor, bool bShouldClip = true );
|
||||
|
||||
// Necessary to wrap the rendering
|
||||
void StartDrawing( void );
|
||||
void StartDrawingIn3DSpace( const VMatrix &screenToWorld, int pw, int ph, float sw, float sh );
|
||||
void FinishDrawing( void );
|
||||
|
||||
// Sets up a particular painting state...
|
||||
void SetupPaintState( const PaintState_t &paintState );
|
||||
|
||||
void ResetPopupList();
|
||||
void AddPopup( vgui::VPANEL panel );
|
||||
void RemovePopup( vgui::VPANEL panel );
|
||||
void AddPopupsToList( vgui::VPANEL panel );
|
||||
|
||||
// Helper for drawing colored text
|
||||
int DrawColoredText( vgui::HFont font, int x, int y, int r, int g, int b, int a, const char *fmt, va_list argptr );
|
||||
void SearchForWordBreak( vgui::HFont font, char *text, int& chars, int& pixels );
|
||||
|
||||
void InternalThinkTraverse(VPANEL panel);
|
||||
void InternalSolveTraverse(VPANEL panel);
|
||||
void InternalSchemeSettingsTraverse(VPANEL panel, bool forceApplySchemeSettings);
|
||||
|
||||
// handles mouse movement
|
||||
void SetCursorPos(int x, int y);
|
||||
void GetCursorPos(int &x, int &y);
|
||||
|
||||
void DrawTexturedLineInternal( const Vertex_t &a, const Vertex_t &b );
|
||||
|
||||
// Gets texture coordinates for drawing the full screen buffer
|
||||
void GetFullScreenTexCoords( int x, int y, int w, int h, float *pMinU, float *pMinV, float *pMaxU, float *pMaxV );
|
||||
|
||||
// Is a panel under the restricted panel?
|
||||
bool IsPanelUnderRestrictedPanel( VPANEL panel );
|
||||
|
||||
// Point Translation for current panel
|
||||
int m_nTranslateX;
|
||||
int m_nTranslateY;
|
||||
|
||||
// alpha multiplier for current panel [0..1]
|
||||
float m_flAlphaMultiplier;
|
||||
|
||||
// The size of the window to draw into
|
||||
int m_pSurfaceExtents[4];
|
||||
|
||||
// Color for drawing all non-text things
|
||||
unsigned char m_DrawColor[4];
|
||||
|
||||
// Color for drawing text
|
||||
unsigned char m_DrawTextColor[4];
|
||||
|
||||
// Location of text rendering
|
||||
int m_pDrawTextPos[2];
|
||||
|
||||
// Meshbuilder used for drawing
|
||||
IMesh* m_pMesh;
|
||||
CMeshBuilder meshBuilder;
|
||||
|
||||
// White material used for drawing non-textured things
|
||||
CMaterialReference m_pWhite;
|
||||
|
||||
// Used for 3D-rendered images
|
||||
CTextureReference m_FullScreenBuffer;
|
||||
CMaterialReference m_FullScreenBufferMaterial;
|
||||
int m_nFullScreenBufferMaterialId;
|
||||
CUtlString m_FullScreenBufferName;
|
||||
|
||||
bool m_bUsingTempFullScreenBufferMaterial;
|
||||
|
||||
// Root panel
|
||||
vgui::VPANEL m_pEmbeddedPanel;
|
||||
vgui::Panel *m_pDefaultEmbeddedPanel;
|
||||
vgui::VPANEL m_pRestrictedPanel;
|
||||
|
||||
// List of pop-up panels based on the type enum above (draw order vs last clicked)
|
||||
CUtlVector<vgui::HPanel> m_PopupList;
|
||||
|
||||
// Stack of paint state...
|
||||
CUtlVector< PaintState_t > m_PaintStateStack;
|
||||
|
||||
vgui::HFont m_hCurrentFont;
|
||||
vgui::HCursor _currentCursor;
|
||||
bool m_cursorAlwaysVisible;
|
||||
|
||||
// The currently bound texture
|
||||
int m_iBoundTexture;
|
||||
|
||||
// font drawing batching code
|
||||
enum { MAX_BATCHED_CHAR_VERTS = 4096 };
|
||||
vgui::Vertex_t m_BatchedCharVerts[ MAX_BATCHED_CHAR_VERTS ];
|
||||
int m_nBatchedCharVertCount;
|
||||
|
||||
// What's the rectangle we're drawing in 3D paint mode?
|
||||
int m_n3DLeft, m_n3DRight, m_n3DTop, m_n3DBottom;
|
||||
|
||||
// Are we painting in 3D? (namely drawing 3D objects *inside* the vgui panel)
|
||||
bool m_bIn3DPaintMode : 1;
|
||||
|
||||
// If we are in 3d Paint mode, are we rendering to a texture? (Or directly to the screen)
|
||||
bool m_b3DPaintRenderToTexture : 1;
|
||||
|
||||
// Are we drawing the vgui panel in the 3D world somewhere?
|
||||
bool m_bDrawingIn3DWorld : 1;
|
||||
|
||||
// Is the app gonna call HandleInputEvent?
|
||||
bool m_bAppDrivesInput : 1;
|
||||
|
||||
// Are we currently in the think() loop
|
||||
bool m_bInThink : 1;
|
||||
|
||||
bool m_bNeedsKeyboard : 1;
|
||||
bool m_bNeedsMouse : 1;
|
||||
bool m_bAllowJavaScript : 1;
|
||||
|
||||
int m_nLastInputPollCount;
|
||||
|
||||
VPANEL m_CurrentThinkPanel;
|
||||
|
||||
// The attached HWND
|
||||
void *m_HWnd;
|
||||
|
||||
// Installed function to play sounds
|
||||
PlaySoundFunc_t m_PlaySoundFunc;
|
||||
|
||||
int m_WorkSpaceInsets[4];
|
||||
|
||||
class TitleEntry
|
||||
{
|
||||
public:
|
||||
TitleEntry()
|
||||
{
|
||||
panel = NULL;
|
||||
title[0] = 0;
|
||||
}
|
||||
|
||||
vgui::VPANEL panel;
|
||||
wchar_t title[128];
|
||||
};
|
||||
|
||||
CUtlVector< TitleEntry > m_Titles;
|
||||
CUtlVector< CUtlSymbol > m_CustomFontFileNames;
|
||||
CUtlVector< CUtlSymbol > m_BitmapFontFileNames;
|
||||
CUtlDict< int, int > m_BitmapFontFileMapping;
|
||||
|
||||
float m_flZPos;
|
||||
CUtlDict< vgui::IImage *, unsigned short > m_FileTypeImages;
|
||||
|
||||
int GetTitleEntry( vgui::VPANEL panel );
|
||||
|
||||
virtual void DrawSetTextureRGBAEx(int id, const unsigned char *rgba, int wide, int tall, ImageFormat format );
|
||||
|
||||
struct ScreenOverride_t
|
||||
{
|
||||
ScreenOverride_t() : m_bActive( false )
|
||||
{
|
||||
m_nValue[ 0 ] = m_nValue[ 1 ] = 0;
|
||||
}
|
||||
bool m_bActive;
|
||||
int m_nValue[ 2 ];
|
||||
};
|
||||
|
||||
ScreenOverride_t m_ScreenSizeOverride;
|
||||
ScreenOverride_t m_ScreenPosOverride;
|
||||
|
||||
int m_nFullscreenViewportX;
|
||||
int m_nFullscreenViewportY;
|
||||
int m_nFullscreenViewportWidth;
|
||||
int m_nFullscreenViewportHeight;
|
||||
ITexture *m_pFullscreenRenderTarget;
|
||||
|
||||
#ifdef LINUX
|
||||
struct font_entry
|
||||
{
|
||||
void *data;
|
||||
int size;
|
||||
};
|
||||
|
||||
static CUtlDict< font_entry, unsigned short > m_FontData;
|
||||
|
||||
static void *FontDataHelper( const char *pchFontName, int &size, const char *fontFileName );
|
||||
#endif
|
||||
};
|
||||
|
||||
#if GLMDEBUG
|
||||
class MatSurfFuncLogger // rip off of GLMFuncLogger - figure out a way to reunify these soon
|
||||
{
|
||||
public:
|
||||
|
||||
// simple function log
|
||||
MatSurfFuncLogger( char *funcName )
|
||||
{
|
||||
CMatRenderContextPtr prc( g_pMaterialSystem );
|
||||
|
||||
m_funcName = funcName;
|
||||
m_earlyOut = false;
|
||||
|
||||
prc->Printf( ">%s", m_funcName );
|
||||
};
|
||||
|
||||
// more advanced version lets you pass args (i.e. called parameters or anything else of interest)
|
||||
// no macro for this one, since no easy way to pass through the args as well as the funcname
|
||||
MatSurfFuncLogger( char *funcName, PRINTF_FORMAT_STRING const char *fmt, ... )
|
||||
{
|
||||
CMatRenderContextPtr prc( g_pMaterialSystem );
|
||||
|
||||
m_funcName = funcName;
|
||||
m_earlyOut = false;
|
||||
|
||||
// this acts like GLMPrintf here
|
||||
// all the indent policy is down in GLMPrintfVA
|
||||
// which means we need to inject a ">" at the front of the format string to make this work... sigh.
|
||||
|
||||
char modifiedFmt[2000];
|
||||
modifiedFmt[0] = '>';
|
||||
strcpy( modifiedFmt+1, fmt );
|
||||
|
||||
va_list vargs;
|
||||
va_start(vargs, fmt);
|
||||
prc->PrintfVA( modifiedFmt, vargs );
|
||||
va_end( vargs );
|
||||
}
|
||||
|
||||
~MatSurfFuncLogger( )
|
||||
{
|
||||
CMatRenderContextPtr prc( g_pMaterialSystem );
|
||||
if (m_earlyOut)
|
||||
{
|
||||
prc->Printf( "<%s (early out)", m_funcName );
|
||||
}
|
||||
else
|
||||
{
|
||||
prc->Printf( "<%s", m_funcName );
|
||||
}
|
||||
};
|
||||
|
||||
void EarlyOut( void )
|
||||
{
|
||||
m_earlyOut = true;
|
||||
};
|
||||
|
||||
|
||||
char *m_funcName; // set at construction time
|
||||
bool m_earlyOut;
|
||||
};
|
||||
|
||||
// handy macro to go with the helper class
|
||||
#define MAT_FUNC MatSurfFuncLogger _logger_ ( __FUNCTION__ )
|
||||
|
||||
#else
|
||||
|
||||
#define MAT_FUNC
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MATSYSTEMSURFACE_H
|
991
vguimatsurface/TextureDictionary.cpp
Normal file
991
vguimatsurface/TextureDictionary.cpp
Normal file
@ -0,0 +1,991 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Contains all texture state for the material system surface to use
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "TextureDictionary.h"
|
||||
#include "utllinkedlist.h"
|
||||
#include "checksum_crc.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "vguimatsurface.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "KeyValues.h"
|
||||
#include "pixelwriter.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "vtf/vtf.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define TEXTURE_ID_UNKNOWN -1
|
||||
|
||||
class CMatSystemTexture;
|
||||
|
||||
// Case-sensitive string checksum
|
||||
static CRC32_t Texture_CRCName( const char *string )
|
||||
{
|
||||
CRC32_t crc;
|
||||
|
||||
CRC32_Init( &crc );
|
||||
CRC32_ProcessBuffer( &crc, (void *)string, strlen( string ) );
|
||||
CRC32_Final( &crc );
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
class CFontTextureRegen;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMatSystemTexture
|
||||
{
|
||||
public:
|
||||
CMatSystemTexture( void );
|
||||
~CMatSystemTexture( void );
|
||||
|
||||
void SetId( int id ) { m_ID = id; };
|
||||
|
||||
CRC32_t GetCRC() const;
|
||||
void SetCRC( CRC32_t val );
|
||||
|
||||
void SetMaterial( const char *pFileName );
|
||||
void SetMaterial( IMaterial *pMaterial );
|
||||
|
||||
void SetTexture( ITexture *pTexture ) { SafeAssign( &m_pOverrideTexture, pTexture ); }
|
||||
|
||||
// This is used when we want different rendering state sharing the same procedural texture (fonts)
|
||||
void ReferenceOtherProcedural( CMatSystemTexture *pTexture, IMaterial *pMaterial );
|
||||
|
||||
IMaterial *GetMaterial() { return m_pMaterial; }
|
||||
int Width() const { return m_iWide; }
|
||||
int Height() const { return m_iTall; }
|
||||
|
||||
bool IsProcedural( void ) const;
|
||||
void SetProcedural( bool proc );
|
||||
|
||||
bool IsReference() const { return m_Flags & TEXTURE_IS_REFERENCE; }
|
||||
|
||||
void SetTextureRGBA( const char* rgba, int wide, int tall, ImageFormat format, bool bFixupTextCoordsForDimensions );
|
||||
void SetSubTextureRGBA( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall );
|
||||
void SetSubTextureRGBAEx( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat );
|
||||
void UpdateSubTextureRGBA( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat );
|
||||
|
||||
float m_s0, m_t0, m_s1, m_t1;
|
||||
|
||||
private:
|
||||
void CreateRegen( int nWidth, int nHeight, ImageFormat format );
|
||||
void ReleaseRegen( void );
|
||||
void CleanUpMaterial();
|
||||
|
||||
ITexture *GetTextureValue( void );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
TEXTURE_IS_PROCEDURAL = 0x1,
|
||||
TEXTURE_IS_REFERENCE = 0x2
|
||||
};
|
||||
|
||||
CRC32_t m_crcFile;
|
||||
IMaterial *m_pMaterial;
|
||||
ITexture *m_pTexture;
|
||||
ITexture *m_pOverrideTexture;
|
||||
|
||||
int m_iWide;
|
||||
int m_iTall;
|
||||
int m_iInputWide;
|
||||
int m_iInputTall;
|
||||
int m_ID;
|
||||
int m_Flags;
|
||||
CFontTextureRegen *m_pRegen;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A class that manages textures used by the material system surface
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTextureDictionary : public ITextureDictionary
|
||||
{
|
||||
public:
|
||||
CTextureDictionary( void );
|
||||
|
||||
// Create, destroy textures
|
||||
int CreateTexture( bool procedural = false );
|
||||
int CreateTextureByTexture( ITexture *pTexture, bool procedural = true ) OVERRIDE;
|
||||
void DestroyTexture( int id );
|
||||
void DestroyAllTextures();
|
||||
|
||||
// Is this a valid id?
|
||||
bool IsValidId( int id ) const;
|
||||
|
||||
// Binds a material to a texture
|
||||
virtual void BindTextureToFile( int id, const char *pFileName );
|
||||
virtual void BindTextureToMaterial( int id, IMaterial *pMaterial );
|
||||
virtual void BindTextureToMaterialReference( int id, int referenceId, IMaterial *pMaterial );
|
||||
|
||||
// Texture info
|
||||
IMaterial *GetTextureMaterial( int id );
|
||||
void GetTextureSize(int id, int& iWide, int& iTall );
|
||||
void GetTextureTexCoords( int id, float &s0, float &t0, float &s1, float &t1 );
|
||||
|
||||
void SetTextureRGBA( int id, const char* rgba, int wide, int tall );
|
||||
void SetTextureRGBAEx( int id, const char* rgba, int wide, int tall, ImageFormat format, bool bFixupTextCoordsForDimensions );
|
||||
void SetSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall );
|
||||
void SetSubTextureRGBAEx( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat );
|
||||
void UpdateSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat );
|
||||
|
||||
int FindTextureIdForTextureFile( char const *pFileName );
|
||||
|
||||
public:
|
||||
CMatSystemTexture *GetTexture( int id );
|
||||
|
||||
private:
|
||||
CUtlLinkedList< CMatSystemTexture, unsigned short > m_Textures;
|
||||
};
|
||||
|
||||
static CTextureDictionary s_TextureDictionary;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A texture regenerator that holds onto the bits at all times
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFontTextureRegen : public ITextureRegenerator
|
||||
{
|
||||
public:
|
||||
CFontTextureRegen( int nWidth, int nHeight, ImageFormat format )
|
||||
{
|
||||
m_nFormat = format;
|
||||
m_nWidth = nWidth;
|
||||
m_nHeight = nHeight;
|
||||
|
||||
if ( IsPC() )
|
||||
{
|
||||
int size = ImageLoader::GetMemRequired( m_nWidth, m_nHeight, 1, m_nFormat, false );
|
||||
m_pTextureBits = new unsigned char[size];
|
||||
memset( m_pTextureBits, 0, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
// will be allocated as needed
|
||||
m_pTextureBits = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~CFontTextureRegen( void )
|
||||
{
|
||||
DeleteTextureBits();
|
||||
}
|
||||
|
||||
void UpdateBackingBits( Rect_t &subRect, const unsigned char *pBits, Rect_t &uploadRect, ImageFormat format )
|
||||
{
|
||||
int size = ImageLoader::GetMemRequired( m_nWidth, m_nHeight, 1, m_nFormat, false );
|
||||
if ( IsPC() )
|
||||
{
|
||||
if ( !m_pTextureBits )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( !m_pTextureBits );
|
||||
m_pTextureBits = new unsigned char[size];
|
||||
memset( m_pTextureBits, 0, size );
|
||||
}
|
||||
|
||||
// Copy subrect into backing bits storage
|
||||
// source data is expected to be in same format as backing bits
|
||||
int y;
|
||||
if ( ImageLoader::SizeInBytes( m_nFormat ) == 4 )
|
||||
{
|
||||
bool bIsInputFullRect = ( subRect.width != uploadRect.width || subRect.height != uploadRect.height );
|
||||
Assert( (subRect.x >= 0) && (subRect.y >= 0) );
|
||||
Assert( (subRect.x + subRect.width <= m_nWidth) && (subRect.y + subRect.height <= m_nHeight) );
|
||||
for ( y=0; y < subRect.height; ++y )
|
||||
{
|
||||
int idx = ( (subRect.y + y) * m_nWidth + subRect.x ) << 2;
|
||||
unsigned int *pDst = (unsigned int*)(&m_pTextureBits[ idx ]);
|
||||
int offset = bIsInputFullRect ? (subRect.y+y)*uploadRect.width + subRect.x : y*uploadRect.width;
|
||||
const unsigned int *pSrc = (const unsigned int *)(&pBits[ offset << 2 ]);
|
||||
ImageLoader::ConvertImageFormat( (const unsigned char *)pSrc, format,(unsigned char *)pDst, m_nFormat, subRect.width, 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cannot subrect copy when format is not RGBA
|
||||
if ( subRect.width != m_nWidth || subRect.height != m_nHeight )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
Q_memcpy( m_pTextureBits, pBits, size );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pSubRect )
|
||||
{
|
||||
if ( !m_pTextureBits )
|
||||
return;
|
||||
|
||||
Assert( (pVTFTexture->Width() == m_nWidth) && (pVTFTexture->Height() == m_nHeight) );
|
||||
|
||||
int nFormatBytes = ImageLoader::SizeInBytes( m_nFormat );
|
||||
if ( nFormatBytes == 4 )
|
||||
{
|
||||
if ( m_nFormat == pVTFTexture->Format() )
|
||||
{
|
||||
int ymax = pSubRect->y + pSubRect->height;
|
||||
for( int y = pSubRect->y; y < ymax; ++y )
|
||||
{
|
||||
// copy each row across for the update
|
||||
char *pchData = (char *)pVTFTexture->ImageData( 0, 0, 0, 0, y ) + pSubRect->x *nFormatBytes;
|
||||
int size = ImageLoader::GetMemRequired( pSubRect->width, 1, 1, m_nFormat, false );
|
||||
V_memcpy( pchData, m_pTextureBits + (y * m_nWidth + pSubRect->x) * nFormatBytes, size );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// formats don't match so do a pixel by pixel swizel
|
||||
CPixelWriter pixelWriter;
|
||||
pixelWriter.SetPixelMemory(
|
||||
pVTFTexture->Format(),
|
||||
pVTFTexture->ImageData( 0, 0, 0 ),
|
||||
pVTFTexture->RowSizeInBytes( 0 ) );
|
||||
|
||||
// Now upload the part we've been asked for
|
||||
int xmax = pSubRect->x + pSubRect->width;
|
||||
int ymax = pSubRect->y + pSubRect->height;
|
||||
int x, y;
|
||||
|
||||
for( y = pSubRect->y; y < ymax; ++y )
|
||||
{
|
||||
pixelWriter.Seek( pSubRect->x, y );
|
||||
unsigned char *rgba = &m_pTextureBits[ (y * m_nWidth + pSubRect->x) * nFormatBytes ];
|
||||
|
||||
for ( x=pSubRect->x; x < xmax; ++x )
|
||||
{
|
||||
pixelWriter.WritePixel( rgba[0], rgba[1], rgba[2], rgba[3] );
|
||||
rgba += nFormatBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cannot subrect copy when format is not RGBA
|
||||
if ( pSubRect->width != m_nWidth || pSubRect->height != m_nHeight )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
int size = ImageLoader::GetMemRequired( m_nWidth, m_nHeight, 1, m_nFormat, false );
|
||||
Q_memcpy( pVTFTexture->ImageData( 0, 0, 0 ), m_pTextureBits, size );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Release()
|
||||
{
|
||||
// Called by the material system when this needs to go away
|
||||
DeleteTextureBits();
|
||||
}
|
||||
|
||||
void DeleteTextureBits()
|
||||
{
|
||||
if ( m_pTextureBits )
|
||||
{
|
||||
delete [] m_pTextureBits;
|
||||
m_pTextureBits = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char *m_pTextureBits;
|
||||
short m_nWidth;
|
||||
short m_nHeight;
|
||||
ImageFormat m_nFormat;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMatSystemTexture::CMatSystemTexture( void )
|
||||
{
|
||||
m_pMaterial = NULL;
|
||||
m_pTexture = NULL;
|
||||
m_pOverrideTexture = NULL;
|
||||
m_crcFile = (CRC32_t)0;
|
||||
m_iWide = m_iTall = 0;
|
||||
m_s0 = m_t0 = 0;
|
||||
m_s1 = m_t1 = 1;
|
||||
|
||||
m_Flags = 0;
|
||||
m_pRegen = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMatSystemTexture::~CMatSystemTexture( void )
|
||||
{
|
||||
if ( m_pOverrideTexture )
|
||||
{
|
||||
m_pOverrideTexture->Release();
|
||||
m_pOverrideTexture->DeleteIfUnreferenced();
|
||||
m_pOverrideTexture = NULL;
|
||||
}
|
||||
|
||||
CleanUpMaterial();
|
||||
}
|
||||
|
||||
bool CMatSystemTexture::IsProcedural( void ) const
|
||||
{
|
||||
return (m_Flags & TEXTURE_IS_PROCEDURAL) != 0;
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetProcedural( bool proc )
|
||||
{
|
||||
if (proc)
|
||||
{
|
||||
m_Flags |= TEXTURE_IS_PROCEDURAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Flags &= ~TEXTURE_IS_PROCEDURAL;
|
||||
}
|
||||
}
|
||||
|
||||
void CMatSystemTexture::CleanUpMaterial()
|
||||
{
|
||||
if ( m_pMaterial )
|
||||
{
|
||||
// causes the underlying texture (if unreferenced) to be deleted as well
|
||||
m_pMaterial->DecrementReferenceCount();
|
||||
m_pMaterial->DeleteIfUnreferenced();
|
||||
m_pMaterial = NULL;
|
||||
}
|
||||
|
||||
if ( m_pTexture )
|
||||
{
|
||||
m_pTexture->SetTextureRegenerator( NULL );
|
||||
m_pTexture->DecrementReferenceCount();
|
||||
m_pTexture->DeleteIfUnreferenced();
|
||||
m_pTexture = NULL;
|
||||
}
|
||||
|
||||
ReleaseRegen();
|
||||
}
|
||||
|
||||
void CMatSystemTexture::CreateRegen( int nWidth, int nHeight, ImageFormat format )
|
||||
{
|
||||
Assert( IsProcedural() );
|
||||
|
||||
if ( !m_pRegen )
|
||||
{
|
||||
m_pRegen = new CFontTextureRegen( nWidth, nHeight, format );
|
||||
}
|
||||
}
|
||||
|
||||
void CMatSystemTexture::ReleaseRegen( void )
|
||||
{
|
||||
if (m_pRegen)
|
||||
{
|
||||
if (!IsReference())
|
||||
{
|
||||
delete m_pRegen;
|
||||
}
|
||||
|
||||
m_pRegen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetTextureRGBA( const char *rgba, int wide, int tall, ImageFormat format, bool bFixupTextCoords )
|
||||
{
|
||||
Assert( IsProcedural() );
|
||||
if ( !IsProcedural() )
|
||||
return;
|
||||
|
||||
if ( !m_pMaterial )
|
||||
{
|
||||
int width = wide;
|
||||
int height = tall;
|
||||
|
||||
// find the minimum power-of-two to fit this in
|
||||
int i;
|
||||
for ( i = 0; i < 32 ; i++ )
|
||||
{
|
||||
width = (1<<i);
|
||||
if (width >= wide)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++ )
|
||||
{
|
||||
height= (1<<i);
|
||||
if (height >= tall)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// create a procedural material to fit this texture into
|
||||
static int nTextureId = 0;
|
||||
char pTextureName[64];
|
||||
Q_snprintf( pTextureName, sizeof( pTextureName ), "__vgui_texture_%d", nTextureId );
|
||||
++nTextureId;
|
||||
|
||||
ITexture *pTexture = g_pMaterialSystem->CreateProceduralTexture(
|
||||
pTextureName,
|
||||
TEXTURE_GROUP_VGUI,
|
||||
width,
|
||||
height,
|
||||
format,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT |
|
||||
TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD |
|
||||
TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_POINTSAMPLE );
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetInt( "$vertexcolor", 1 );
|
||||
pVMTKeyValues->SetInt( "$vertexalpha", 1 );
|
||||
pVMTKeyValues->SetInt( "$ignorez", 1 );
|
||||
pVMTKeyValues->SetInt( "$no_fullbright", 1 );
|
||||
pVMTKeyValues->SetInt( "$translucent", 1 );
|
||||
pVMTKeyValues->SetString( "$basetexture", pTextureName );
|
||||
|
||||
IMaterial *pMaterial = g_pMaterialSystem->CreateMaterial( pTextureName, pVMTKeyValues );
|
||||
pMaterial->Refresh();
|
||||
|
||||
// Has to happen after the refresh
|
||||
pTexture->DecrementReferenceCount();
|
||||
|
||||
SetMaterial( pMaterial );
|
||||
m_iInputTall = tall;
|
||||
m_iInputWide = wide;
|
||||
if ( bFixupTextCoords && ( wide != width || tall != height ) )
|
||||
{
|
||||
m_s1 = (double)wide / width;
|
||||
m_t1 = (double)tall / height;
|
||||
}
|
||||
|
||||
// undo the extra +1 refCount
|
||||
pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
|
||||
Assert( wide <= m_iWide );
|
||||
Assert( tall <= m_iTall );
|
||||
|
||||
// Just replace the whole thing
|
||||
SetSubTextureRGBAEx( 0, 0, (const unsigned char *)rgba, wide, tall, format );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
ITexture *CMatSystemTexture::GetTextureValue( void )
|
||||
{
|
||||
Assert( IsProcedural() );
|
||||
if ( !m_pMaterial )
|
||||
return NULL;
|
||||
|
||||
if ( m_pOverrideTexture )
|
||||
return m_pOverrideTexture;
|
||||
|
||||
return m_pTexture;
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetSubTextureRGBA( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall )
|
||||
{
|
||||
SetSubTextureRGBAEx( drawX, drawY, rgba, subTextureWide, subTextureTall, IMAGE_FORMAT_RGBA8888 );
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetSubTextureRGBAEx( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat format )
|
||||
{
|
||||
ITexture *pTexture = GetTextureValue();
|
||||
if ( !pTexture )
|
||||
return;
|
||||
|
||||
Assert( IsProcedural() );
|
||||
if ( !IsProcedural() )
|
||||
return;
|
||||
|
||||
Assert( drawX < m_iWide );
|
||||
Assert( drawY < m_iTall );
|
||||
Assert( drawX + subTextureWide <= m_iWide );
|
||||
Assert( drawY + subTextureTall <= m_iTall );
|
||||
|
||||
Assert( m_pRegen );
|
||||
|
||||
Assert( rgba );
|
||||
|
||||
Rect_t subRect;
|
||||
subRect.x = drawX;
|
||||
subRect.y = drawY;
|
||||
subRect.width = subTextureWide;
|
||||
subRect.height = subTextureTall;
|
||||
|
||||
Rect_t textureSize;
|
||||
textureSize.x = 0;
|
||||
textureSize.y = 0;
|
||||
textureSize.width = subTextureWide;
|
||||
textureSize.height = subTextureTall;
|
||||
|
||||
|
||||
m_pRegen->UpdateBackingBits( subRect, rgba, textureSize, format );
|
||||
pTexture->Download( &subRect );
|
||||
|
||||
if ( IsX360() )
|
||||
{
|
||||
// xboxissue - no need to persist "backing bits", saves memory
|
||||
// the texture (commonly font page) "backing bits" are allocated during UpdateBackingBits() which get blitted
|
||||
// into by procedural regeneration in preparation for download() which then subrect blits
|
||||
// out of and into target texture (d3d upload)
|
||||
// the "backing bits" are then no longer required
|
||||
m_pRegen->DeleteTextureBits();
|
||||
}
|
||||
}
|
||||
|
||||
void CMatSystemTexture::UpdateSubTextureRGBA( int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat )
|
||||
{
|
||||
ITexture *pTexture = GetTextureValue();
|
||||
if ( !pTexture )
|
||||
return;
|
||||
|
||||
Assert( IsProcedural() );
|
||||
if ( !IsProcedural() )
|
||||
return;
|
||||
|
||||
Assert( drawX < m_iWide );
|
||||
Assert( drawY < m_iTall );
|
||||
Assert( drawX + subTextureWide <= m_iWide );
|
||||
Assert( drawY + subTextureTall <= m_iTall );
|
||||
|
||||
Assert( m_pRegen );
|
||||
|
||||
Assert( rgba );
|
||||
|
||||
Rect_t subRect;
|
||||
subRect.x = drawX;
|
||||
subRect.y = drawY;
|
||||
subRect.width = subTextureWide;
|
||||
subRect.height = subTextureTall;
|
||||
|
||||
Rect_t textureSize;
|
||||
textureSize.x = 0;
|
||||
textureSize.y = 0;
|
||||
textureSize.width = m_iInputWide;
|
||||
textureSize.height = m_iInputTall;
|
||||
|
||||
m_pRegen->UpdateBackingBits( subRect, rgba, textureSize, imageFormat );
|
||||
pTexture->Download( &subRect );
|
||||
|
||||
if ( IsX360() )
|
||||
{
|
||||
// xboxissue - no need to persist "backing bits", saves memory
|
||||
// the texture (commonly font page) "backing bits" are allocated during UpdateBackingBits() which get blitted
|
||||
// into by procedural regeneration in preparation for download() which then subrect blits
|
||||
// out of and into target texture (d3d upload)
|
||||
// the "backing bits" are then no longer required
|
||||
m_pRegen->DeleteTextureBits();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMatSystemTexture::SetCRC( CRC32_t val )
|
||||
{
|
||||
m_crcFile = val;
|
||||
}
|
||||
|
||||
CRC32_t CMatSystemTexture::GetCRC() const
|
||||
{
|
||||
return m_crcFile;
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
// Decrement references to old texture
|
||||
CleanUpMaterial();
|
||||
|
||||
m_pMaterial = pMaterial;
|
||||
|
||||
if (!m_pMaterial)
|
||||
{
|
||||
m_iWide = m_iTall = 0;
|
||||
m_s0 = m_t0 = 0.0f;
|
||||
m_s1 = m_t1 = 1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment its reference count
|
||||
m_pMaterial->IncrementReferenceCount();
|
||||
|
||||
// Compute texture size
|
||||
m_iWide = m_pMaterial->GetMappingWidth();
|
||||
m_iTall = m_pMaterial->GetMappingHeight();
|
||||
|
||||
// Compute texture coordinates
|
||||
float flPixelCenterX = 0.0f;
|
||||
float flPixelCenterY = 0.0f;
|
||||
|
||||
if ( m_iWide > 0.0f && m_iTall > 0.0f)
|
||||
{
|
||||
flPixelCenterX = 0.5f / m_iWide;
|
||||
flPixelCenterY = 0.5f / m_iTall;
|
||||
}
|
||||
|
||||
m_s0 = flPixelCenterX;
|
||||
m_t0 = flPixelCenterY;
|
||||
|
||||
// FIXME: Old code used +, it should be - yes?!??!
|
||||
m_s1 = 1.0 - flPixelCenterX;
|
||||
m_t1 = 1.0 - flPixelCenterY;
|
||||
|
||||
if ( IsProcedural() )
|
||||
{
|
||||
bool bFound;
|
||||
IMaterialVar *tv = m_pMaterial->FindVar( "$baseTexture", &bFound );
|
||||
if ( bFound && tv->IsTexture() )
|
||||
{
|
||||
m_pTexture = tv->GetTextureValue();
|
||||
if ( m_pTexture )
|
||||
{
|
||||
m_pTexture->IncrementReferenceCount();
|
||||
|
||||
// Upload new data
|
||||
CreateRegen( m_iWide, m_iTall, m_pTexture->GetImageFormat() );
|
||||
m_pTexture->SetTextureRegenerator( m_pRegen );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is used when we want different rendering state sharing the same procedural texture (fonts)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMatSystemTexture::ReferenceOtherProcedural( CMatSystemTexture *pTexture, IMaterial *pMaterial )
|
||||
{
|
||||
// Decrement references to old texture
|
||||
CleanUpMaterial();
|
||||
|
||||
Assert( pTexture->IsProcedural() );
|
||||
|
||||
m_Flags |= TEXTURE_IS_REFERENCE;
|
||||
|
||||
m_pMaterial = pMaterial;
|
||||
|
||||
if (!m_pMaterial)
|
||||
{
|
||||
m_iWide = m_iTall = 0;
|
||||
m_s0 = m_t0 = 0.0f;
|
||||
m_s1 = m_t1 = 1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
m_iWide = pTexture->m_iWide;
|
||||
m_iTall = pTexture->m_iTall;
|
||||
m_s0 = pTexture->m_s0;
|
||||
m_t0 = pTexture->m_t0;
|
||||
m_s1 = pTexture->m_s1;
|
||||
m_t1 = pTexture->m_t1;
|
||||
|
||||
Assert( (pMaterial->GetMappingWidth() == m_iWide) && (pMaterial->GetMappingHeight() == m_iTall) );
|
||||
|
||||
// Increment its reference count
|
||||
m_pMaterial->IncrementReferenceCount();
|
||||
|
||||
bool bFound;
|
||||
IMaterialVar *tv = m_pMaterial->FindVar( "$baseTexture", &bFound );
|
||||
if ( bFound )
|
||||
{
|
||||
m_pTexture = tv->GetTextureValue();
|
||||
if ( m_pTexture )
|
||||
{
|
||||
m_pTexture->IncrementReferenceCount();
|
||||
Assert( m_pTexture == pTexture->m_pTexture );
|
||||
|
||||
// Reference, but do *not* create a new one!!!
|
||||
m_pRegen = pTexture->m_pRegen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMatSystemTexture::SetMaterial( const char *pFileName )
|
||||
{
|
||||
// Get a pointer to the new material
|
||||
IMaterial *pMaterial = g_pMaterialSystem->FindMaterial( pFileName, TEXTURE_GROUP_VGUI );
|
||||
|
||||
if ( IsErrorMaterial( pMaterial ) )
|
||||
{
|
||||
if (IsOSX())
|
||||
{
|
||||
printf( "\n ##### Missing Vgui material %s\n", pFileName );
|
||||
}
|
||||
Msg( "--- Missing Vgui material %s\n", pFileName );
|
||||
}
|
||||
|
||||
SetMaterial( pMaterial );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
ITextureDictionary *TextureDictionary()
|
||||
{
|
||||
return &s_TextureDictionary;
|
||||
}
|
||||
|
||||
CTextureDictionary::CTextureDictionary( void )
|
||||
{
|
||||
// First entry is bogus texture
|
||||
m_Textures.AddToTail();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create, destroy textures
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTextureDictionary::CreateTexture( bool procedural /*=false*/ )
|
||||
{
|
||||
int idx = m_Textures.AddToTail();
|
||||
CMatSystemTexture &texture = m_Textures[idx];
|
||||
texture.SetProcedural( procedural );
|
||||
texture.SetId( idx );
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int CTextureDictionary::CreateTextureByTexture( ITexture *pTexture, bool procedural /*= true*/ )
|
||||
{
|
||||
int idx = m_Textures.AddToTail();
|
||||
CMatSystemTexture &texture = m_Textures[idx];
|
||||
texture.SetProcedural( procedural );
|
||||
texture.SetId( idx );
|
||||
texture.SetTexture( pTexture );
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void CTextureDictionary::DestroyTexture( int id )
|
||||
{
|
||||
if ( m_Textures.Count() <= 1 )
|
||||
{
|
||||
// TextureDictionary already destroyed all the textures before this (something destructed late in shutdown)
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != INVALID_TEXTURE_ID)
|
||||
{
|
||||
Assert( id != m_Textures.InvalidIndex() );
|
||||
m_Textures.Remove( (unsigned short)id );
|
||||
}
|
||||
}
|
||||
|
||||
void CTextureDictionary::DestroyAllTextures()
|
||||
{
|
||||
m_Textures.RemoveAll();
|
||||
// First entry is bogus texture
|
||||
m_Textures.AddToTail();
|
||||
CMatSystemTexture &texture = m_Textures[0];
|
||||
texture.SetId( 0 );
|
||||
}
|
||||
|
||||
void CTextureDictionary::SetTextureRGBA( int id, const char* rgba, int wide, int tall )
|
||||
{
|
||||
SetTextureRGBAEx( id, rgba, wide, tall, IMAGE_FORMAT_RGBA8888, false );
|
||||
}
|
||||
|
||||
void CTextureDictionary::SetTextureRGBAEx( int id, const char* rgba, int wide, int tall, ImageFormat format, bool bFixupTextCoordsForDimensions )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
Msg( "SetTextureRGBA: Invalid texture id %i\n", id );
|
||||
return;
|
||||
}
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
texture.SetTextureRGBA( rgba, wide, tall, format, bFixupTextCoordsForDimensions );
|
||||
}
|
||||
|
||||
void CTextureDictionary::SetSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall )
|
||||
{
|
||||
SetSubTextureRGBAEx( id, drawX, drawY, rgba, subTextureWide, subTextureTall, IMAGE_FORMAT_RGBA8888 );
|
||||
}
|
||||
|
||||
|
||||
void CTextureDictionary::SetSubTextureRGBAEx( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat format )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
Msg( "SetSubTextureRGBA: Invalid texture id %i\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
texture.SetSubTextureRGBAEx( drawX, drawY, rgba, subTextureWide, subTextureTall, format );
|
||||
}
|
||||
|
||||
|
||||
void CTextureDictionary::UpdateSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
Msg( "UpdateSubTextureRGBA: Invalid texture id %i\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
texture.UpdateSubTextureRGBA( drawX, drawY, rgba, subTextureWide, subTextureTall, imageFormat );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the id is valid
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTextureDictionary::IsValidId( int id ) const
|
||||
{
|
||||
Assert( id != 0 );
|
||||
if ( id == 0 )
|
||||
return false;
|
||||
|
||||
return m_Textures.IsValidIndex( id );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Binds a file to a particular texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTextureDictionary::BindTextureToFile( int id, const char *pFileName )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
Msg( "BindTextureToFile: Invalid texture id for file %s\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
|
||||
// Reload from file if the material was never loaded, or if the filename has changed at all
|
||||
CRC32_t fileNameCRC = Texture_CRCName( pFileName );
|
||||
if ( !texture.GetMaterial() || fileNameCRC != texture.GetCRC() )
|
||||
{
|
||||
// New texture name
|
||||
texture.SetCRC( fileNameCRC );
|
||||
texture.SetMaterial( pFileName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Binds a material to a texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTextureDictionary::BindTextureToMaterial( int id, IMaterial *pMaterial )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
Msg( "BindTextureToFile: Invalid texture id %d\n", id );
|
||||
return;
|
||||
}
|
||||
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
texture.SetMaterial( pMaterial );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Binds a material to a texture reference
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTextureDictionary::BindTextureToMaterialReference( int id, int referenceId, IMaterial *pMaterial )
|
||||
{
|
||||
if (!IsValidId(id) || !IsValidId(referenceId))
|
||||
{
|
||||
Msg( "BindTextureToFile: Invalid texture ids %d %d\n", id, referenceId );
|
||||
return;
|
||||
}
|
||||
|
||||
CMatSystemTexture &texture = m_Textures[id];
|
||||
CMatSystemTexture &textureSource = m_Textures[referenceId];
|
||||
texture.ReferenceOtherProcedural( &textureSource, pMaterial );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the material associated with an id
|
||||
//-----------------------------------------------------------------------------
|
||||
IMaterial *CTextureDictionary::GetTextureMaterial( int id )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
return NULL;
|
||||
|
||||
return m_Textures[id].GetMaterial();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the material size associated with an id
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTextureDictionary::GetTextureSize(int id, int& iWide, int& iTall )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
iWide = iTall = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
iWide = m_Textures[id].Width();
|
||||
iTall = m_Textures[id].Height();
|
||||
}
|
||||
|
||||
void CTextureDictionary::GetTextureTexCoords( int id, float &s0, float &t0, float &s1, float &t1 )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
{
|
||||
s0 = t0 = 0.0f;
|
||||
s1 = t1 = 1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
s0 = m_Textures[id].m_s0;
|
||||
t0 = m_Textures[id].m_t0;
|
||||
s1 = m_Textures[id].m_s1;
|
||||
t1 = m_Textures[id].m_t1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : id -
|
||||
// Output : CMatSystemTexture
|
||||
//-----------------------------------------------------------------------------
|
||||
CMatSystemTexture *CTextureDictionary::GetTexture( int id )
|
||||
{
|
||||
if (!IsValidId(id))
|
||||
return NULL;
|
||||
|
||||
return &m_Textures[ id ];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pFileName -
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTextureDictionary::FindTextureIdForTextureFile( char const *pFileName )
|
||||
{
|
||||
for ( int i = m_Textures.Head(); i != m_Textures.InvalidIndex(); i = m_Textures.Next( i ) )
|
||||
{
|
||||
CMatSystemTexture *tex = &m_Textures[i];
|
||||
if ( !tex )
|
||||
continue;
|
||||
|
||||
IMaterial *mat = tex->GetMaterial();
|
||||
if ( !mat )
|
||||
continue;
|
||||
|
||||
if ( !stricmp( mat->GetName(), pFileName ) )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
63
vguimatsurface/TextureDictionary.h
Normal file
63
vguimatsurface/TextureDictionary.h
Normal file
@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Contains all texture state for the material system surface to use
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TEXTUREDICTIONARY_H
|
||||
#define TEXTUREDICTIONARY_H
|
||||
|
||||
class IMaterial;
|
||||
class ITexture;
|
||||
|
||||
enum
|
||||
{
|
||||
INVALID_TEXTURE_ID = -1
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A class that manages textures used by the material system surface
|
||||
//-----------------------------------------------------------------------------
|
||||
class ITextureDictionary
|
||||
{
|
||||
public:
|
||||
// Create, destroy textures
|
||||
virtual int CreateTexture( bool procedural = false ) = 0;
|
||||
virtual int CreateTextureByTexture( ITexture *pTexture, bool procedural = true ) = 0;
|
||||
virtual void DestroyTexture( int id ) = 0;
|
||||
virtual void DestroyAllTextures() = 0;
|
||||
|
||||
// Is this a valid id?
|
||||
virtual bool IsValidId( int id ) const = 0;
|
||||
|
||||
// Binds a material to a texture
|
||||
virtual void BindTextureToFile( int id, const char *pFileName ) = 0;
|
||||
|
||||
// Binds a material to a texture
|
||||
virtual void BindTextureToMaterial( int id, IMaterial *pMaterial ) = 0;
|
||||
|
||||
// Binds a material to a texture
|
||||
virtual void BindTextureToMaterialReference( int id, int referenceId, IMaterial *pMaterial ) = 0;
|
||||
|
||||
// Texture info
|
||||
virtual IMaterial *GetTextureMaterial( int id ) = 0;
|
||||
virtual void GetTextureSize(int id, int& iWide, int& iTall ) = 0;
|
||||
virtual void GetTextureTexCoords( int id, float &s0, float &t0, float &s1, float &t1 ) = 0;
|
||||
|
||||
virtual void SetTextureRGBA( int id, const char* rgba, int wide, int tall ) = 0;
|
||||
|
||||
virtual int FindTextureIdForTextureFile( char const *pFileName ) = 0;
|
||||
virtual void SetSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall ) = 0;
|
||||
virtual void SetSubTextureRGBAEx( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat format ) = 0;
|
||||
|
||||
virtual void SetTextureRGBAEx( int id, const char* rgba, int wide, int tall, ImageFormat format, bool bFixupTextCoordsForDimensions ) = 0;
|
||||
|
||||
virtual void UpdateSubTextureRGBA( int id, int drawX, int drawY, unsigned const char *rgba, int subTextureWide, int subTextureTall, ImageFormat imageFormat ) = 0;
|
||||
};
|
||||
|
||||
ITextureDictionary *TextureDictionary();
|
||||
|
||||
#endif // TEXTUREDICTIONARY_H
|
181
vguimatsurface/memorybitmap.cpp
Normal file
181
vguimatsurface/memorybitmap.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <vgui/ISurface.h>
|
||||
#include "memorybitmap.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "MatSystemSurface.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "vtf/vtf.h"
|
||||
#include "KeyValues.h"
|
||||
#include "TextureDictionary.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern CMatSystemSurface g_MatSystemSurface;
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : *filename - image file to load
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryBitmap::MemoryBitmap(unsigned char *texture,int wide, int tall)
|
||||
{
|
||||
_texture=texture;
|
||||
_uploaded = false;
|
||||
_color = Color(255, 255, 255, 255);
|
||||
_pos[0] = _pos[1] = 0;
|
||||
_valid = true;
|
||||
_w = wide;
|
||||
_h = tall;
|
||||
m_iTextureID = -1;
|
||||
|
||||
ForceUpload(texture,wide,tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryBitmap::~MemoryBitmap()
|
||||
{
|
||||
// Free the old texture ID.
|
||||
if ( m_iTextureID != -1 )
|
||||
{
|
||||
TextureDictionary()->DestroyTexture( m_iTextureID );
|
||||
m_iTextureID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::GetSize(int &wide, int &tall)
|
||||
{
|
||||
wide = 0;
|
||||
tall = 0;
|
||||
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
g_MatSystemSurface.DrawGetTextureSize(m_iTextureID, wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: size of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::GetContentSize(int &wide, int &tall)
|
||||
{
|
||||
GetSize(wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ignored
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetSize(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetPos(int x, int y)
|
||||
{
|
||||
_pos[0] = x;
|
||||
_pos[1] = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetColor(Color col)
|
||||
{
|
||||
_color = col;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the file name of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *MemoryBitmap::GetName()
|
||||
{
|
||||
return "MemoryBitmap";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Renders the loaded image, uploading it if necessary
|
||||
// Assumes a valid image is always returned from uploading
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::Paint()
|
||||
{
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
// if we have not uploaded yet, lets go ahead and do so
|
||||
if (!_uploaded)
|
||||
{
|
||||
ForceUpload(_texture,_w,_h);
|
||||
}
|
||||
|
||||
//set the texture current, set the color, and draw the biatch
|
||||
g_MatSystemSurface.DrawSetTexture(m_iTextureID);
|
||||
g_MatSystemSurface.DrawSetColor(_color[0], _color[1], _color[2], _color[3]);
|
||||
|
||||
int wide, tall;
|
||||
GetSize(wide, tall);
|
||||
g_MatSystemSurface.DrawTexturedRect( _pos[0], _pos[1], _pos[0] + wide, _pos[1] + tall);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ensures the bitmap has been uploaded
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::ForceUpload(unsigned char *texture,int wide, int tall)
|
||||
{
|
||||
_texture=texture;
|
||||
bool sizechanged = ( _w != wide || _h != tall );
|
||||
_w = wide;
|
||||
_h = tall;
|
||||
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
if(_w==0 || _h==0)
|
||||
return;
|
||||
|
||||
// Not our first time through and the size changed, destroy and recreate texture id...
|
||||
if ( m_iTextureID != -1 && sizechanged )
|
||||
{
|
||||
TextureDictionary()->DestroyTexture( m_iTextureID );
|
||||
m_iTextureID = -1;
|
||||
}
|
||||
|
||||
if ( m_iTextureID == -1 )
|
||||
{
|
||||
m_iTextureID = g_MatSystemSurface.CreateNewTextureID( true );
|
||||
}
|
||||
|
||||
g_MatSystemSurface.DrawSetTextureRGBA( m_iTextureID, texture, wide, tall, true, true );
|
||||
|
||||
_uploaded = true;
|
||||
_valid = g_MatSystemSurface.IsTextureIDValid(m_iTextureID);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
HTexture MemoryBitmap::GetID()
|
||||
{
|
||||
return m_iTextureID;
|
||||
}
|
||||
|
||||
|
63
vguimatsurface/memorybitmap.h
Normal file
63
vguimatsurface/memorybitmap.h
Normal file
@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MEMORYBITMAP_H
|
||||
#define MEMORYBITMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/IImage.h>
|
||||
#include <Color.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
typedef unsigned long HTexture;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Holds a single image created from a chunk of memory, internal to vgui only
|
||||
//-----------------------------------------------------------------------------
|
||||
class MemoryBitmap: public IImage
|
||||
{
|
||||
public:
|
||||
MemoryBitmap(unsigned char *texture,int wide, int tall);
|
||||
~MemoryBitmap();
|
||||
|
||||
// IImage implementation
|
||||
virtual void Paint();
|
||||
virtual void GetSize(int &wide, int &tall);
|
||||
virtual void GetContentSize(int &wide, int &tall);
|
||||
virtual void SetPos(int x, int y);
|
||||
virtual void SetSize(int x, int y);
|
||||
virtual void SetColor(Color col);
|
||||
|
||||
// methods
|
||||
void ForceUpload(unsigned char *texture,int wide, int tall); // ensures the bitmap has been uploaded
|
||||
HTexture GetID(); // returns the texture id
|
||||
const char *GetName();
|
||||
bool IsValid()
|
||||
{
|
||||
return _valid;
|
||||
}
|
||||
|
||||
private:
|
||||
// HTexture _id;
|
||||
bool _uploaded;
|
||||
bool _valid;
|
||||
unsigned char *_texture;
|
||||
int _pos[2];
|
||||
Color _color;
|
||||
int _w,_h; // size of the texture
|
||||
int m_iTextureID;
|
||||
};
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
#endif // MEMORYBITMAP_H
|
30
vguimatsurface/vguimatsurface.h
Normal file
30
vguimatsurface/vguimatsurface.h
Normal file
@ -0,0 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation of the VGUI ISurface interface using the
|
||||
// material system to implement it
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef VGUIMATSURFACE_H
|
||||
#define VGUIMATSURFACE_H
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class IInputInternal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals...
|
||||
//-----------------------------------------------------------------------------
|
||||
extern vgui::IInputInternal *g_pIInput;
|
||||
|
||||
|
||||
#endif // VGUIMATSURFACE_H
|
||||
|
||||
|
104
vguimatsurface/vguimatsurface.vpc
Normal file
104
vguimatsurface/vguimatsurface.vpc
Normal file
@ -0,0 +1,104 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VGUIMATSURFACE.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR ".."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;BENCHMARK;VGUIMATSURFACE_DLL_EXPORT;GAMEUI_EXPORTS;DONT_PROTECT_FILEIO_FUNCTIONS;PROTECTED_THINGS_ENABLE"
|
||||
$PreprocessorDefinitions "$BASE;fopen=dont_use_fopen" [$WIN32]
|
||||
$EnableC++Exceptions "Yes (/EHsc)"
|
||||
// $TreatWchar_tAsBuiltinType "No"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$SystemLibraries "iconv" [$OSXALL]
|
||||
$SystemFrameworks "Carbon" [$OSXALL]
|
||||
$GCC_ExtraLinkerFlags "-L/usr/lib32 -L/usr/lib -L/usr/lib/i386-linux-gnu" [$LINUXALL]
|
||||
$SystemLibraries "fontconfig;freetype" [$LINUXALL]
|
||||
$AdditionalDependencies "$BASE vgui_surfacelib_360.lib" [$X360]
|
||||
$AdditionalDependencies "$BASE vgui_surfacelib.lib nvtc.lib" [$WIN32]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "vguimatsurface"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "Clip2D.cpp"
|
||||
$File "Cursor.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "FontTextureCache.cpp"
|
||||
$File "Input.cpp"
|
||||
$File "MatSystemSurface.cpp"
|
||||
$File "memorybitmap.cpp" [$WIN32]
|
||||
$File "TextureDictionary.cpp"
|
||||
$File "$SRCDIR\vgui2\src\vgui_key_translation.cpp"
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "Clip2D.h"
|
||||
$File "Cursor.h"
|
||||
$File "Input.h"
|
||||
$File "memorybitmap.h" [$WIN32]
|
||||
$File "TextureDictionary.h"
|
||||
$File "vguimatsurface.h"
|
||||
$File "MatSystemSurface.h"
|
||||
$File "FontTextureCache.h"
|
||||
$File "$SRCDIR\vgui2\src\vgui_key_translation.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier1\characterset.h"
|
||||
$File "$SRCDIR\public\tier1\checksum_crc.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\FontAmalgam.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\FontManager.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\materialsystem\imaterial.h"
|
||||
$File "$SRCDIR\public\materialsystem\imaterialsystem.h"
|
||||
$File "$SRCDIR\public\materialsystem\imaterialvar.h"
|
||||
$File "$SRCDIR\public\VGuiMatSurface\IMatSystemSurface.h"
|
||||
$File "$SRCDIR\public\materialsystem\imesh.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\materialsystem\itexture.h"
|
||||
$File "$SRCDIR\public\pixelwriter.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlrbtree.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\mathlib\vector4d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
$File "$SRCDIR\public\vtf\vtf.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\Win32Font.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$Lib vgui_controls
|
||||
$Lib vgui_surfacelib
|
||||
$ImpLib SDL2 [$SDL]
|
||||
}
|
||||
}
|
3
vguimatsurface/xbox/xbox.def
Normal file
3
vguimatsurface/xbox/xbox.def
Normal file
@ -0,0 +1,3 @@
|
||||
LIBRARY vguimatsurface_360.dll
|
||||
EXPORTS
|
||||
CreateInterface @1
|
Reference in New Issue
Block a user