summaryrefslogtreecommitdiff
path: root/vgui2/matsys_controls/proceduraltexturepanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /vgui2/matsys_controls/proceduraltexturepanel.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'vgui2/matsys_controls/proceduraltexturepanel.cpp')
-rw-r--r--vgui2/matsys_controls/proceduraltexturepanel.cpp239
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 );
+}