You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.2 KiB
239 lines
7.2 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//===========================================================================// |
|
|
|
#include "matsys_controls/proceduraltexturepanel.h" |
|
#include "matsys_controls/matsyscontrols.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "materialsystem/itexture.h" |
|
#include "VGuiMatSurface/IMatSystemSurface.h" |
|
#include "tier1/KeyValues.h" |
|
#include "pixelwriter.h" |
|
|
|
|
|
using namespace vgui; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor |
|
//----------------------------------------------------------------------------- |
|
CProceduralTexturePanel::CProceduralTexturePanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName ) |
|
{ |
|
m_pImageBuffer = NULL; |
|
m_bMaintainProportions = false; |
|
m_bUsePaintRect = false; |
|
m_PaintRect.x = m_PaintRect.y = 0; |
|
m_PaintRect.width = m_PaintRect.height = 0; |
|
} |
|
|
|
CProceduralTexturePanel::~CProceduralTexturePanel() |
|
{ |
|
CleanUp(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// initialization, shutdown |
|
//----------------------------------------------------------------------------- |
|
bool CProceduralTexturePanel::Init( int nWidth, int nHeight, bool bAllocateImageBuffer ) |
|
{ |
|
m_nWidth = nWidth; |
|
m_nHeight = nHeight; |
|
if ( bAllocateImageBuffer ) |
|
{ |
|
m_pImageBuffer = new BGRA8888_t[nWidth * nHeight]; |
|
} |
|
|
|
m_TextureSubRect.x = m_TextureSubRect.y = 0; |
|
m_TextureSubRect.width = nWidth; |
|
m_TextureSubRect.height = nHeight; |
|
|
|
char pTemp[512]; |
|
Q_snprintf( pTemp, 512, "__%s", GetName() ); |
|
|
|
ITexture *pTex = MaterialSystem()->CreateProceduralTexture( pTemp, TEXTURE_GROUP_VGUI, |
|
m_nWidth, m_nHeight, IMAGE_FORMAT_BGRX8888, |
|
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_NOMIP | |
|
TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY ); |
|
pTex->SetTextureRegenerator( this ); |
|
m_ProceduralTexture.Init( pTex ); |
|
|
|
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); |
|
pVMTKeyValues->SetString( "$basetexture", pTemp ); |
|
pVMTKeyValues->SetInt( "$nocull", 1 ); |
|
pVMTKeyValues->SetInt( "$nodebug", 1 ); |
|
m_ProceduralMaterial.Init( MaterialSystem()->CreateMaterial( pTemp, pVMTKeyValues )); |
|
|
|
m_nTextureID = MatSystemSurface()->CreateNewTextureID( false ); |
|
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_ProceduralMaterial ); |
|
return true; |
|
} |
|
|
|
void CProceduralTexturePanel::Shutdown() |
|
{ |
|
CleanUp(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Maintain proportions when drawing |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::MaintainProportions( bool bEnable ) |
|
{ |
|
m_bMaintainProportions = bEnable; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the image buffer + dimensions |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::CleanUp() |
|
{ |
|
if ( (ITexture*)m_ProceduralTexture ) |
|
{ |
|
m_ProceduralTexture->SetTextureRegenerator( NULL ); |
|
} |
|
m_ProceduralTexture.Shutdown(); |
|
m_ProceduralMaterial.Shutdown(); |
|
|
|
if ( m_pImageBuffer ) |
|
{ |
|
delete[] m_pImageBuffer; |
|
m_pImageBuffer = NULL; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Default implementation of regenerate texture bits |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect ) |
|
{ |
|
Assert( m_pImageBuffer ); |
|
Assert( pVTFTexture->FrameCount() == 1 ); |
|
Assert( pVTFTexture->FaceCount() == 1 ); |
|
Assert( !pTexture->IsMipmapped() ); |
|
|
|
int nWidth, nHeight, nDepth; |
|
pVTFTexture->ComputeMipLevelDimensions( 0, &nWidth, &nHeight, &nDepth ); |
|
Assert( nDepth == 1 ); |
|
Assert( nWidth == m_nWidth && nHeight == m_nHeight ); |
|
|
|
CPixelWriter pixelWriter; |
|
pixelWriter.SetPixelMemory( pVTFTexture->Format(), |
|
pVTFTexture->ImageData( 0, 0, 0 ), pVTFTexture->RowSizeInBytes( 0 ) ); |
|
|
|
for ( int y = 0; y < nHeight; ++y ) |
|
{ |
|
pixelWriter.Seek( 0, y ); |
|
BGRA8888_t *pTexel = &m_pImageBuffer[y * m_nWidth]; |
|
for ( int x = 0; x < nWidth; ++x, ++pTexel ) |
|
{ |
|
pixelWriter.WritePixel( pTexel->r, pTexel->g, pTexel->b, pTexel->a ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the image buffer + dimensions |
|
//----------------------------------------------------------------------------- |
|
BGRA8888_t *CProceduralTexturePanel::GetImageBuffer() |
|
{ |
|
Assert( m_pImageBuffer ); |
|
return m_pImageBuffer; |
|
} |
|
|
|
int CProceduralTexturePanel::GetImageWidth() const |
|
{ |
|
return m_nWidth; |
|
} |
|
|
|
int CProceduralTexturePanel::GetImageHeight() const |
|
{ |
|
return m_nHeight; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the paint rect |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::SetPaintRect( const Rect_t *pPaintRect ) |
|
{ |
|
m_bUsePaintRect = ( pPaintRect != NULL ); |
|
if ( m_bUsePaintRect ) |
|
{ |
|
m_PaintRect = *pPaintRect; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the draw rect |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::SetTextureSubRect( const Rect_t &subRect ) |
|
{ |
|
m_TextureSubRect = subRect; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Redownloads the procedural texture |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::DownloadTexture() |
|
{ |
|
m_ProceduralTexture->Download(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Paints the texture |
|
//----------------------------------------------------------------------------- |
|
void CProceduralTexturePanel::Paint( void ) |
|
{ |
|
vgui::surface()->DrawSetTexture( m_nTextureID ); |
|
vgui::surface()->DrawSetColor( 255, 255, 255, 255 ); |
|
|
|
int x = 0; |
|
int y = 0; |
|
int w, h; |
|
GetSize( w, h ); |
|
if ( m_bUsePaintRect ) |
|
{ |
|
x = m_PaintRect.x; |
|
y = m_PaintRect.y; |
|
w = m_PaintRect.width; |
|
h = m_PaintRect.height; |
|
} |
|
|
|
if ( m_bMaintainProportions ) |
|
{ |
|
if ( m_TextureSubRect.width > m_TextureSubRect.height ) |
|
{ |
|
h = w * m_TextureSubRect.height / m_TextureSubRect.width; |
|
} |
|
else |
|
{ |
|
w = h * m_TextureSubRect.width / m_TextureSubRect.height; |
|
} |
|
} |
|
|
|
// Rotated version of the bitmap! |
|
// Rotate about the center of the bitmap |
|
vgui::Vertex_t verts[4]; |
|
verts[0].m_Position.Init( x, y ); |
|
verts[0].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)m_TextureSubRect.y / m_nHeight ); |
|
|
|
verts[1].m_Position.Init( w+x, y ); |
|
verts[1].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)m_TextureSubRect.y / m_nHeight ); |
|
|
|
verts[2].m_Position.Init( w+x, h+y ); |
|
verts[2].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight ); |
|
|
|
verts[3].m_Position.Init( x, h+y ); |
|
verts[3].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
}
|
|
|