diff options
Diffstat (limited to 'vgui2/matsys_controls/proceduraltexturepanel.cpp')
| -rw-r--r-- | vgui2/matsys_controls/proceduraltexturepanel.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/vgui2/matsys_controls/proceduraltexturepanel.cpp b/vgui2/matsys_controls/proceduraltexturepanel.cpp new file mode 100644 index 0000000..a198dd5 --- /dev/null +++ b/vgui2/matsys_controls/proceduraltexturepanel.cpp @@ -0,0 +1,239 @@ +//========= 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 ); +} |