|
|
//===== Copyright � 1996-2005, 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"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialvar.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.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;
m_nTextureID = -1; }
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 ); pTex->DecrementReferenceCount();
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); pVMTKeyValues->SetString( "$basetexture", pTemp ); pVMTKeyValues->SetInt( "$nocull", 1 ); pVMTKeyValues->SetInt( "$nodebug", 1 ); IMaterial *pMaterial = MaterialSystem()->CreateMaterial( pTemp, pVMTKeyValues ); m_ProceduralMaterial.Init( pMaterial ); pMaterial->DecrementReferenceCount(); static unsigned int textureVarCache = 0; IMaterialVar *pTextureVar = m_ProceduralMaterial->FindVarFast( "$basetexture", &textureVarCache ); pTextureVar->SetTextureValue( pTex );
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 ( m_nTextureID != -1 ) { MatSystemSurface()->DestroyTextureID( m_nTextureID ); m_nTextureID = -1; }
if ( m_ProceduralMaterial ) { m_ProceduralMaterial.Shutdown( true ); }
if ( m_ProceduralTexture ) { m_ProceduralTexture->SetTextureRegenerator( NULL ); m_ProceduralTexture.Shutdown( true ); } 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 ) { if ( m_nTextureID == -1 ) return;
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 ); }
|