summaryrefslogtreecommitdiff
path: root/hammer/Render.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 /hammer/Render.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/Render.cpp')
-rw-r--r--hammer/Render.cpp1543
1 files changed, 1543 insertions, 0 deletions
diff --git a/hammer/Render.cpp b/hammer/Render.cpp
new file mode 100644
index 0000000..abe73c9
--- /dev/null
+++ b/hammer/Render.cpp
@@ -0,0 +1,1543 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Base rendering utilities for all views
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "stdafx.h"
+#include "MapDoc.h"
+#include <VGuiMatSurface/IMatSystemSurface.h>
+#include "mathlib/vmatrix.h"
+#include "Render.h"
+#include "Camera.h"
+#include "Material.h"
+#include "materialsystem/imesh.h"
+#include "datacache\imdlcache.h"
+#include "hammer.h"
+#include "hammer_mathlib.h"
+#include "vgui_controls/Controls.h"
+#include "vgui/IScheme.h"
+#include "texturesystem.h"
+#include "IStudioRender.h"
+#include "builddisp.h"
+#include "mapview.h"
+#include "material.h"
+#include <renderparm.h>
+#include "materialsystem/IMaterialSystemHardwareConfig.h"
+#include "vphysics_interface.h"
+#include "materialsystem/MaterialSystem_Config.h"
+#include "VGuiWnd.h"
+#include "Box3D.h"
+#include "MapInstance.h"
+
+extern IMatSystemSurface *g_pMatSystemSurface;
+
+static float s_fOneUnitLength = 1;
+
+CRender::CRender(void)
+{
+ m_pView = NULL;
+
+ // returns a handle to the default (first loaded) scheme
+ vgui::IScheme * pScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetDefaultScheme() );
+ if ( pScheme )
+ {
+ m_DefaultFont = pScheme->GetFont( "Default" );
+ }
+ else
+ {
+ m_DefaultFont = vgui::INVALID_FONT;
+
+ static bool s_bOnce = false;
+ if ( !s_bOnce )
+ {
+ s_bOnce = true;
+ MessageBox( NULL, "Failed to load the default scheme file. The map views may be missing some visual elements.", "Error", MB_OK | MB_ICONEXCLAMATION );
+ }
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ m_pFlat[i] = NULL;
+ m_pWireframe[i] = NULL;
+ m_pTranslucentFlat[i] = NULL;
+ m_pLightmapGrid[i] = NULL;
+ m_pSelectionOverlay[i] = NULL;
+ m_pDotted[i] = NULL;
+ m_pFlatNoZ[i] = NULL;
+ m_pFlatNoCull[i] = NULL;
+ }
+
+ m_pCurrentMaterial = NULL;
+ m_pBoundMaterial = NULL;
+
+ m_nDecalMode = 0;
+
+ m_bIsRendering = false;
+ m_bIsClientSpace = false;
+ m_bIsLocalTransform = false;
+ m_bIsRenderingIntoVGUI = false;
+
+ VMatrix IdentityMatrix;
+
+ IdentityMatrix.Identity();
+ m_LocalMatrix.AddToHead( IdentityMatrix );
+
+ m_OrthoMatrix.Identity();
+ m_eCurrentRenderMode = m_eDefaultRenderMode = RENDER_MODE_FLAT;
+
+ m_bInstanceRendering = false;
+ m_nInstanceCount = 0;
+ m_InstanceSelectionDepth = 0;
+
+ PushInstanceData( NULL, Vector( 0.0f, 0.0f, 0.0f ), QAngle( 0.0f, 0.0f, 0.0f ) ); // always add a default state
+
+ UpdateStudioRenderConfig( false, false );
+}
+
+CRender::~CRender(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this function will push all of the instance data
+// Input : pInstanceClass - the func_instance entity
+// InstanceOrigin - the translation of the instance
+// InstanceAngles - the rotation of the instance
+// Output : none
+//-----------------------------------------------------------------------------
+void CRender::PushInstanceData( CMapInstance *pInstanceClass, Vector &InstanceOrigin, QAngle &InstanceAngles )
+{
+ TInstanceState InstanceState;
+ matrix3x4_t Instance3x4Matrix;
+
+ InstanceState.m_InstanceOrigin = InstanceOrigin;
+ InstanceState.m_InstanceAngles = InstanceAngles;
+ InstanceState.m_pInstanceClass = pInstanceClass;
+ InstanceState.m_pTopInstanceClass = NULL;
+
+ AngleMatrix( InstanceState.m_InstanceAngles, InstanceState.m_InstanceOrigin, Instance3x4Matrix );
+ InstanceState.m_InstanceMatrix.Init( Instance3x4Matrix );
+
+ Vector vecTransformedOrigin;
+ TransformInstanceVector( InstanceState.m_InstanceOrigin, vecTransformedOrigin );
+ m_CurrentInstanceState.m_InstanceOrigin = vecTransformedOrigin;
+ // RotateInstanceVector( ( Vector )InstanceState.m_InstanceAngles, m_CurrentInstanceState.m_InstanceAngles ); no one uses this right now make sure to store it in the same fashion as vecTransformedOrigin
+
+ if ( m_InstanceState.Count() > 0 )
+ { // first push is just a default state
+ m_bInstanceRendering = true;
+ BeginLocalTransfrom( InstanceState.m_InstanceMatrix, true );
+ if ( m_CurrentInstanceState.m_pTopInstanceClass == NULL )
+ {
+ if ( pInstanceClass->IsEditable() == false )
+ {
+ InstanceState.m_pTopInstanceClass = pInstanceClass;
+ }
+ }
+ else
+ {
+ InstanceState.m_pTopInstanceClass = m_CurrentInstanceState.m_pTopInstanceClass;
+ }
+ if ( pInstanceClass->IsSelected() || m_InstanceSelectionDepth )
+ {
+ m_InstanceSelectionDepth++;
+ }
+ InstanceState.m_InstanceMatrix = m_CurrentInstanceState.m_InstanceMatrix * InstanceState.m_InstanceMatrix;
+ InstanceState.m_bIsEditable = pInstanceClass->IsEditable();
+ }
+ else
+ {
+ m_bInstanceRendering = false;
+ InstanceState.m_bIsEditable = true;
+ }
+
+ InstanceState.m_InstanceRenderMatrix = m_LocalMatrix.Head();
+ m_InstanceState.AddToHead( InstanceState );
+ m_CurrentInstanceState = InstanceState;
+
+ if ( !pInstanceClass )
+ {
+ }
+ else if ( m_InstanceSelectionDepth > 0 )
+ {
+ PushInstanceRendering( INSTANCE_STACE_SELECTED );
+ }
+ else if ( pInstanceClass->IsEditable() || CMapDoc::GetActiveMapDoc()->GetShowInstance() == INSTANCES_SHOW_NORMAL )
+ {
+ PushInstanceRendering( INSTANCE_STATE_OFF );
+ }
+ else
+ {
+ PushInstanceRendering( GetInstanceClass()->IsSelected() ? INSTANCE_STACE_SELECTED : INSTANCE_STATE_ON );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this function will pop off the top most instance data
+//-----------------------------------------------------------------------------
+void CRender::PopInstanceData( void )
+{
+ if ( m_CurrentInstanceState.m_pInstanceClass )
+ {
+ PopInstanceRendering();
+ }
+
+ m_InstanceState.Remove( 0 );
+ m_CurrentInstanceState = m_InstanceState.Head();
+
+ if ( m_InstanceState.Count() > 1 )
+ { // first push is just a default state
+ m_bInstanceRendering = true;
+ }
+ else
+ {
+ m_bInstanceRendering = false;
+ }
+
+ if ( m_InstanceSelectionDepth > 0 )
+ {
+ m_InstanceSelectionDepth--;
+ }
+
+ EndLocalTransfrom();
+
+ // m_CurrentInstanceState.m_InstanceRenderMatrix = m_LocalMatrix.Head();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this function initializes the stencil buffer for instance rendering
+//-----------------------------------------------------------------------------
+void CRender::PrepareInstanceStencil( void )
+{
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilEnable( true );
+ pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_ALWAYS );
+ pRenderContext->SetStencilFailOperation( STENCILOPERATION_KEEP );
+ pRenderContext->SetStencilZFailOperation( STENCILOPERATION_KEEP );
+ pRenderContext->SetStencilWriteMask( 0xff );
+ pRenderContext->SetStencilTestMask( 0xff );
+ pRenderContext->SetStencilReferenceValue( 0x01 );
+ pRenderContext->SetStencilPassOperation( STENCILOPERATION_ZERO);
+#else
+ m_ShaderStencilState.m_bEnable = true;
+ m_ShaderStencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
+ m_ShaderStencilState.m_FailOp = SHADER_STENCILOP_KEEP;
+ m_ShaderStencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
+ m_ShaderStencilState.m_nWriteMask = 0xff;
+ m_ShaderStencilState.m_nTestMask = 0xff;
+ m_ShaderStencilState.m_nReferenceValue = 0x01;
+ m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_ZERO;
+ pRenderContext->SetStencilState( m_ShaderStencilState );
+#endif // STENCIL_AS_CALLS
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this function will draw the various alpha color 2d rectangles for the instance states
+//-----------------------------------------------------------------------------
+void CRender::DrawInstanceStencil( void )
+{
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+ CCamera *pCamera = GetCamera();
+
+ if ( m_nNumInstancesRendered > 0 )
+ {
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilPassOperation( STENCILOPERATION_KEEP );
+ pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL );
+#else
+ m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_KEEP;
+ m_ShaderStencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
+#endif // STENCIL_AS_CALLS
+
+ Color InstanceColoring;
+ int width, height;
+
+ pCamera->GetViewPort( width, height );
+ PushRenderMode( RENDER_MODE_INSTANCE_OVERLAY );
+
+ BeginClientSpace();
+ InstanceColor( InstanceColoring, false );
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilReferenceValue( 0x01 );
+#else
+ m_ShaderStencilState.m_nReferenceValue = 0x01;
+ pRenderContext->SetStencilState( m_ShaderStencilState );
+#endif // STENCIL_AS_CALLS
+ DrawFilledRect( Vector2D( 0.0f, 0.0f ), Vector2D( width, height ), ( byte * )&InstanceColoring, false );
+
+ InstanceColor( InstanceColoring, true );
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilTestMask( 0xff );
+ pRenderContext->SetStencilReferenceValue( 0x02 );
+#else
+ m_ShaderStencilState.m_nReferenceValue = 0x02;
+ pRenderContext->SetStencilState( m_ShaderStencilState );
+#endif // STENCIL_AS_CALLS
+ DrawFilledRect( Vector2D( 0.0f, 0.0f ), Vector2D( width, height ), ( byte * )&InstanceColoring, false );
+
+ EndClientSpace();
+ PopRenderMode();
+ }
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilEnable( false );
+#else
+ m_ShaderStencilState.m_bEnable = false;
+ pRenderContext->SetStencilState( m_ShaderStencilState );
+#endif // STENCIL_AS_CALLS
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: this function will push all of the instance data
+// Input : pInstanceClass - the func_instance entity
+// InstanceOrigin - the translation of the instance
+// InstanceAngles - the rotation of the instance
+// Output : none
+//-----------------------------------------------------------------------------
+void CRender::PushInstanceRendering( InstanceRenderingState_t State )
+{
+ SetInstanceRendering( State );
+
+ m_InstanceRenderingState.AddToHead( State );
+
+ if ( State != INSTANCE_STATE_OFF )
+ {
+ m_nNumInstancesRendered++;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this function will pop off the top most instance data
+//-----------------------------------------------------------------------------
+void CRender::PopInstanceRendering( void )
+{
+ m_InstanceRenderingState.Remove( 0 );
+ if ( m_InstanceRenderingState.Count() > 0 )
+ {
+ SetInstanceRendering( m_InstanceRenderingState.Head() );
+ }
+ else
+ {
+ SetInstanceRendering( INSTANCE_STATE_OFF );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the instance rendering state for stencil buffer operations.
+// 0 in stencil buffer = normal drawing
+// 1 in stencil buffer = instance shaded pass
+// 2 in stencil buffer = instance selected shaded pass
+// Input : State - the state at which the next drawing operations should impact
+// the stencil buffer
+//-----------------------------------------------------------------------------
+void CRender::SetInstanceRendering( InstanceRenderingState_t State )
+{
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+ switch( State )
+ {
+ case INSTANCE_STATE_OFF:
+#ifdef STENCIL_AS_CALLS
+ pRenderContext->SetStencilPassOperation( STENCILOPERATION_ZERO );
+#else
+ m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_ZERO;
+#endif // STENCIL_AS_CALLS
+ break;
+
+ case INSTANCE_STATE_ON:
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilPassOperation( STENCILOPERATION_REPLACE );
+ pRenderContext->SetStencilReferenceValue( 0x01 );
+#else
+ m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
+ m_ShaderStencilState.m_nReferenceValue = 0x01;
+#endif // STENCIL_AS_CALLS
+ break;
+
+ case INSTANCE_STACE_SELECTED:
+#if STENCIL_AS_CALLS
+ pRenderContext->SetStencilPassOperation( STENCILOPERATION_REPLACE );
+ pRenderContext->SetStencilReferenceValue( 0x02 );
+#else
+ m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
+ m_ShaderStencilState.m_nReferenceValue = 0x02;
+#endif // STENCIL_AS_CALLS
+ break;
+ }
+
+#ifndef STENCIL_AS_CALLS
+ pRenderContext->SetStencilState( m_ShaderStencilState );
+#endif // STENCIL_AS_CALLS
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: This function renders a text string at the given position, width,
+// height, and format
+// Input: text - the string to print
+// pos - the screen space position of the text (the is the top-left of
+// a screen space rect)
+// width - the width to render the text into
+// height - the height to render the text into
+// nFlags - define the text format -- see SetTextFormat
+//-----------------------------------------------------------------------------
+void CRender::DrawText( const char *text, int x, int y, int nFlags )
+{
+ wchar_t unicode[ 128 ];
+
+ mbstowcs( unicode, text, ARRAYSIZE(unicode) );
+
+ int len = min( 127, Q_strlen( text ) );
+
+ Assert( m_DefaultFont != vgui::INVALID_FONT );
+ bool bJustifyText = nFlags & ( TEXT_JUSTIFY_LEFT | TEXT_JUSTIFY_TOP | TEXT_JUSTIFY_HORZ_CENTER | TEXT_JUSTIFY_VERT_CENTER );
+ if ( bJustifyText && m_DefaultFont != vgui::INVALID_FONT )
+ {
+ int wide,tall;
+ g_pMatSystemSurface->GetTextSize( m_DefaultFont, unicode, wide, tall );
+
+ if ( nFlags & TEXT_JUSTIFY_LEFT )
+ x -= wide;
+
+ if ( nFlags & TEXT_JUSTIFY_TOP )
+ y -= tall;
+
+ if ( nFlags & TEXT_JUSTIFY_HORZ_CENTER )
+ x -= wide/2;
+
+ if ( nFlags & TEXT_JUSTIFY_VERT_CENTER )
+ y -= tall/2;
+ }
+
+ PushRenderMode( RENDER_MODE_EXTERN );
+
+ bool bPopMode = BeginClientSpace();
+
+ g_pMatSystemSurface->DrawSetTextPos( x, y );
+ g_pMatSystemSurface->DrawPrintText( unicode, len );
+
+ if ( bPopMode )
+ EndClientSpace();
+
+ PopRenderMode();
+}
+
+
+//-----------------------------------------------------------------------------
+// Uses "world" coordinates
+//-----------------------------------------------------------------------------
+void CRender::DrawText( const char *text, const Vector2D &vPos, int nOffsetX, int nOffsetY, int nFlags )
+{
+ Vector vecActualPos( vPos.x, vPos.y, 0.0f );
+ if ( IsInLocalTransformMode() )
+ {
+ VMatrix matrix;
+ GetLocalTranform( matrix );
+ Vector vWorld = vecActualPos;
+ Vector3DMultiplyPosition( matrix, vWorld, vecActualPos );
+ }
+
+ Vector2D pt;
+ m_pView->WorldToClient( pt, vecActualPos );
+ DrawText( text, (int)pt.x + nOffsetX, (int)pt.y + nOffsetY, nFlags );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: set the text and background (behind text) colors
+// Input: tR, tG, tB - text red, green, and blue values : [0...255]
+// bkR, bkG, bkB - background red, green, blue values : [0...255]
+//-----------------------------------------------------------------------------
+void CRender::SetTextColor( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
+{
+ m_TextColor.SetColor( r,g,b,a );
+ if ( m_bIsRenderingIntoVGUI )
+ {
+ g_pMatSystemSurface->DrawSetTextColor( m_TextColor );
+ }
+}
+
+void CRender::SetHandleColor( unsigned char r, unsigned char g, unsigned char b )
+{
+ m_HandleColor.SetColor( r, g, b, 255 );
+}
+
+void CRender::UpdateStudioRenderConfig( bool bFlat, bool bWireframe )
+{
+ StudioRenderConfig_t config;
+ memset( &config, 0, sizeof( config ) );
+ config.fEyeShiftX = 0.0f;
+ config.fEyeShiftY = 0.0f;
+ config.fEyeShiftZ = 0.0f;
+ config.fEyeSize = 0;
+ config.drawEntities = 1;
+ config.skin = 0;
+ config.fullbright = MaterialSystemConfig().nFullbright;
+ config.bEyeMove = true;
+ config.bSoftwareSkin = bWireframe;
+ config.bNoHardware = false;
+ config.bNoSoftware = false;
+ config.bTeeth = false;
+ config.bEyes = true;
+ config.bFlex = true;
+ config.bSoftwareLighting = true;
+ config.bWireframe = bWireframe;
+ config.bDrawNormals = false;
+ config.bShowEnvCubemapOnly = false;
+ g_pStudioRender->UpdateConfig( config );
+}
+
+void CRender::StartRenderFrame()
+{
+ Assert( !m_bIsRendering );
+
+ m_nNumInstancesRendered = 0;
+
+ m_bIsRenderingIntoVGUI = dynamic_cast<CVGuiWnd*>( GetView() );
+ if ( m_bIsRenderingIntoVGUI )
+ {
+ g_pMatSystemSurface->DrawSetTextFont( m_DefaultFont );
+ g_pMatSystemSurface->DrawSetTextColor( m_TextColor );
+ g_pMatSystemSurface->DrawSetColor( m_DrawColor );
+ }
+
+ int width, height;
+ VMatrix matrix;
+ CCamera *pCamera = GetCamera();
+
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+ // build ortho matrix for client space mode
+ pCamera->GetViewPort( width, height );
+ pRenderContext->MatrixMode(MATERIAL_PROJECTION);
+ pRenderContext->LoadIdentity();
+ pRenderContext->Scale( 1, -1, 1 );
+ pRenderContext->Ortho(0, 0, width, height, -99999, 99999 );
+ pRenderContext->GetMatrix( MATERIAL_PROJECTION, &m_OrthoMatrix );
+
+ // setup world camera
+ pCamera->GetProjMatrix(matrix);
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->LoadMatrix( matrix );
+
+ pCamera->GetViewMatrix(matrix);
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->LoadMatrix( matrix );
+
+ pRenderContext->MatrixMode(MATERIAL_MODEL);
+ pRenderContext->LoadIdentity();
+
+ pRenderContext->SetAmbientLight( 1.0, 1.0, 1.0 );
+
+ pCamera->GetViewMatrix( m_CurrentMatrix );
+
+ // Disable all the lights..
+ for( int i = 0; i < MaterialSystemHardwareConfig()->MaxNumLights(); ++i)
+ {
+ LightDesc_t desc;
+ desc.m_Type = MATERIAL_LIGHT_DISABLE;
+ pRenderContext->SetLight( i, desc );
+ }
+
+ m_bIsClientSpace = false;
+
+ // reset render mode
+ m_RenderModeStack.Clear();
+ SetRenderMode( m_eDefaultRenderMode, true );
+
+ // reset colors
+ m_DrawColor.SetColor( 255,255,255,255 );
+ m_TextColor.SetColor( 255,255,255,255 );
+ m_HandleColor.SetColor( 255,255,255,255 );
+
+ s_fOneUnitLength = 1/pCamera->GetZoom();
+
+ // tell studiorender that we've updated the camera.
+ if( g_pStudioRender )
+ {
+ g_pStudioRender->BeginFrame();
+
+ Vector viewOrigin, viewRight, viewUp, viewForward;
+ pCamera->GetViewPoint( viewOrigin );
+ pCamera->GetViewRight( viewRight );
+ pCamera->GetViewUp( viewUp );
+ pCamera->GetViewForward( viewForward );
+
+ g_pStudioRender->SetViewState( viewOrigin, viewRight, viewUp, viewForward );
+
+ static Vector white[6] =
+ {
+ Vector( 1.0, 1.0, 1.0 ),
+ Vector( 1.0, 1.0, 1.0 ),
+ Vector( 1.0, 1.0, 1.0 ),
+ Vector( 1.0, 1.0, 1.0 ),
+ Vector( 1.0, 1.0, 1.0 ),
+ Vector( 1.0, 1.0, 1.0 ),
+ };
+
+ g_pStudioRender->SetAmbientLightColors( white );
+ }
+
+ m_bIsRendering = true;
+}
+
+void CRender::EndRenderFrame()
+{
+ Assert( m_bIsRendering );
+ Assert( !m_bIsClientSpace );
+ Assert( m_RenderModeStack.Count() == 0 );
+ Assert( !m_bIsLocalTransform );
+
+ if ( g_pStudioRender )
+ {
+ g_pStudioRender->BeginFrame();
+ }
+
+ // turn off lighting preview shader state
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+ pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,0);
+
+ m_nFrameCount++;
+ m_bIsRendering = false;
+ m_bIsRenderingIntoVGUI = false;
+}
+
+void CRender::DrawLine( const Vector &vStart, const Vector &vEnd )
+{
+ float scale = VectorLength( vEnd-vStart ) / ( s_fOneUnitLength * 16 );
+
+ meshBuilder.Begin(m_pMesh, MATERIAL_LINES, 1);
+
+ meshBuilder.Position3fv(vStart.Base());
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.TexCoord2f(0, 0, 0);
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv(vEnd.Base());
+ meshBuilder.Color4ubv((byte*)&m_DrawColor);
+ meshBuilder.TexCoord2f(0, scale, scale);
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::BeginLocalTransfrom( const VMatrix &matrix, bool MultiplyCurrent )
+{
+ Assert( !m_bIsClientSpace );
+
+ VMatrix LocalCopy = matrix;
+
+ if ( MultiplyCurrent )
+ {
+ LocalCopy = m_LocalMatrix.Head() * LocalCopy;
+ }
+ m_LocalMatrix.AddToHead( LocalCopy );
+
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+ pRenderContext->MatrixMode(MATERIAL_MODEL);
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadMatrix( m_LocalMatrix.Head() );
+
+ CCamera *pCamera = GetCamera();
+ pCamera->GetViewMatrix( m_CurrentMatrix );
+ m_CurrentMatrix = m_CurrentMatrix * LocalCopy;
+
+ m_bIsLocalTransform = true;
+}
+
+void CRender::EndLocalTransfrom()
+{
+ Assert( m_bIsLocalTransform );
+ Assert( !m_bIsClientSpace );
+
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+ pRenderContext->MatrixMode(MATERIAL_MODEL);
+ pRenderContext->PopMatrix();
+
+ m_LocalMatrix.Remove( 0 );
+
+ CCamera *pCamera = GetCamera();
+ pCamera->GetViewMatrix( m_CurrentMatrix );
+ if ( m_LocalMatrix.Count() > 1 )
+ {
+ m_CurrentMatrix = m_CurrentMatrix * m_LocalMatrix.Head();
+ m_bIsLocalTransform = true;
+ }
+ else
+ {
+ m_bIsLocalTransform = false;
+ }
+}
+
+bool CRender::IsInLocalTransformMode()
+{
+ return m_bIsLocalTransform;
+}
+
+void CRender::GetLocalTranform( VMatrix &matrix )
+{
+ matrix = m_LocalMatrix.Head();
+}
+
+bool CRender::BeginClientSpace(void)
+{
+ if ( m_bIsClientSpace )
+ return false;
+
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadMatrix( m_OrthoMatrix );
+
+ pRenderContext->MatrixMode(MATERIAL_VIEW);
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadIdentity();
+
+ if ( m_bIsLocalTransform )
+ {
+ pRenderContext->MatrixMode(MATERIAL_MODEL);
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadIdentity();
+ }
+
+ m_bIsClientSpace = true;
+
+ return true;
+}
+
+void CRender::EndClientSpace(void)
+{
+ Assert( m_bIsClientSpace );
+
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+
+ pRenderContext->MatrixMode(MATERIAL_VIEW);
+ pRenderContext->PopMatrix();
+
+ pRenderContext->MatrixMode(MATERIAL_PROJECTION);
+ pRenderContext->PopMatrix();
+
+ if ( m_bIsLocalTransform )
+ {
+ pRenderContext->MatrixMode(MATERIAL_MODEL);
+ pRenderContext->PopMatrix();
+ }
+
+ m_bIsClientSpace = false;
+}
+
+void CRender::TransformPoint( Vector2D &vClient, const Vector& vWorld )
+{
+ Vector vecActualPos;
+
+ if ( !m_bIsLocalTransform )
+ {
+ vecActualPos = vWorld;
+ }
+ else
+ {
+ m_LocalMatrix.Head().V3Mul( vWorld, vecActualPos );
+ }
+
+ m_pView->WorldToClient( vClient, vecActualPos );
+}
+
+
+void CRender::TransformNormal( Vector2D &vClient, const Vector& vWorld )
+{
+ Vector2D originClient, normalClient;
+ TransformPoint( originClient, vec3_origin );
+ TransformPoint( normalClient, vWorld );
+ vClient = normalClient- originClient;
+}
+
+void CRender::DrawCircle( const Vector &vCenter, const Vector &vNormal, float flRadius, int nSegments)
+{
+ Vector vx,vy;
+
+ if ( !BuildAxesFromNormal( vNormal, vx, vy ) )
+ return;
+
+ vx *= flRadius;
+ vy *= flRadius;
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nSegments );
+
+ float invDelta = 2.0f * M_PI / nSegments;
+ for ( int i = 0; i < nSegments; ++i )
+ {
+ float flRadians = i * invDelta;
+ float ca = cos( flRadians );
+ float sa = sin( flRadians );
+
+ // Rotate it around the circle
+ Vector vertex = vCenter + (ca*vx) + (sa*vy);
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.Position3fv( &vertex.x );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawCircle( Vector2D &vCenter, float fRadius, int nSegments, unsigned char *pColor )
+{
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nSegments );
+
+ float invDelta = 2.0f * M_PI / nSegments;
+ for ( int i = 0; i < nSegments; ++i )
+ {
+ float flRadians = i * invDelta;
+ float ca = cos( flRadians );
+ float sa = sin( flRadians );
+
+ // Rotate it around the circle
+ float x = vCenter.x + (fRadius * ca);
+ float y = vCenter.y + (fRadius * sa);
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( x, y, 0 );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawCross( Vector2D& ul, Vector2D& lr, unsigned char *pColor )
+{
+ // just sizes
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 2 );
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, ul.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, lr.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, lr.y-1, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, ul.y-1, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawRect( Vector2D& ul, Vector2D& lr, unsigned char *pColor )
+{
+ Vector2D vScale = (lr-ul)/16;
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, 4 );
+
+ Vector2D tex(0,0);
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, ul.y, 0 );
+ meshBuilder.TexCoord2f(0, tex.x, tex.y );
+ meshBuilder.AdvanceVertex();
+
+ tex.x += vScale.x;
+ tex.y += vScale.x;
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, ul.y, 0 );
+ meshBuilder.TexCoord2f(0, tex.x, tex.y );
+ meshBuilder.AdvanceVertex();
+
+ tex.x += vScale.y;
+ tex.y -= vScale.y;
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, lr.y, 0 );
+ meshBuilder.TexCoord2f(0, tex.x, tex.y );
+ meshBuilder.AdvanceVertex();
+
+ tex.x -= vScale.x;
+ tex.y -= vScale.x;
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, lr.y, 0 );
+ meshBuilder.TexCoord2f(0, tex.x, tex.y );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawPlane( const Vector &p0, const Vector &p1, const Vector &p2, const Vector &p3, bool bFill )
+{
+ if ( bFill )
+ {
+ meshBuilder.Begin( m_pMesh, MATERIAL_QUADS, 1 );
+ }
+ else
+ {
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, 4 );
+ }
+
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.Position3fv( &p0.x );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.Position3fv( &p1.x );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.Position3fv( &p2.x );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.Position3fv( &p3.x );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawFilledRect( Vector2D& ul, Vector2D& lr, unsigned char *pColor, bool bBorder )
+{
+ static Color black(0,0,0,255);
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_QUADS, bBorder?2:1 );
+
+ if ( bBorder )
+ {
+ meshBuilder.Color4ubv( (byte*)&black );
+ meshBuilder.Position3f( ul.x, ul.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&black );
+ meshBuilder.Position3f( lr.x, ul.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&black );
+ meshBuilder.Position3f( lr.x, lr.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( (byte*)&black );
+ meshBuilder.Position3f( ul.x, lr.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+
+ ul.x+=1;
+ ul.y+=1;
+ lr.x-=1;
+ lr.y-=1;
+ }
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, ul.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, ul.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( lr.x, lr.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv( pColor );
+ meshBuilder.Position3f( ul.x, lr.y, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawHandle( const Vector &vCenter, const Vector2D *vOffset )
+{
+ if ( !m_CurrentInstanceState.m_bIsEditable )
+ {
+ return;
+ }
+
+ int size = m_nHandleSize;
+
+ bool bPopMode = BeginClientSpace();
+
+ Vector2D vCenter2D;
+
+ TransformPoint( vCenter2D, vCenter );
+
+ if ( vOffset )
+ {
+ vCenter2D += *vOffset;
+ }
+
+ RoundVector( vCenter2D );
+
+ if ( m_nHandleType == HANDLE_CROSS )
+ size--;
+
+ Vector2D ul( vCenter2D.x-size, vCenter2D.y-size );
+ Vector2D lr( vCenter2D.x+size+1, vCenter2D.y+size+1 );
+
+ switch ( m_nHandleType )
+ {
+ case HANDLE_SQUARE : DrawFilledRect( ul, lr, (byte*)&m_HandleColor, true );break;
+ case HANDLE_CIRCLE : DrawCircle( vCenter2D, size, 16, (byte*)&m_HandleColor ); break;
+ case HANDLE_DIAMOND : break;
+ case HANDLE_CROSS : DrawCross( ul, lr, (byte*)&m_HandleColor );break;
+ }
+
+ if ( bPopMode )
+ EndClientSpace();
+}
+
+CCamera *CRender::GetCamera()
+{
+ return m_pView->GetCamera();
+}
+
+bool CRender::SetView( CMapView * pView )
+{
+ Assert( pView );
+
+ m_pView = pView;
+
+ // Store off the three materials we use most often...
+ if ( !GetRequiredMaterial( "editor/wireframe", m_pWireframe[0] ) ||
+ !GetRequiredMaterial( "editor/flat", m_pFlat[0] ) ||
+ !GetRequiredMaterial( "editor/flatdecal", m_pFlat[1] ) ||
+ !GetRequiredMaterial( "editor/translucentflat", m_pTranslucentFlat[0] ) ||
+ !GetRequiredMaterial( "editor/translucentflatdecal", m_pTranslucentFlat[1] ) ||
+ !GetRequiredMaterial( "editor/lightmapgrid", m_pLightmapGrid[0] ) ||
+ !GetRequiredMaterial( "editor/lightmapgriddecal", m_pLightmapGrid[1] ) ||
+ !GetRequiredMaterial( "editor/selectionoverlay", m_pSelectionOverlay[0] ) ||
+ !GetRequiredMaterial( "editor/flatignorez", m_pFlatNoZ[0] ) ||
+ !GetRequiredMaterial( "editor/flatnocull", m_pFlatNoCull[0] ) ||
+ !GetRequiredMaterial( "editor/dotted", m_pDotted[0] )
+ )
+ {
+ return false;
+ }
+
+ // Some materials don't have a separate decal version.
+ m_pFlatNoZ[1] = m_pFlatNoZ[0];
+ m_pFlatNoCull[1] = m_pFlatNoCull[0];
+ m_pWireframe[1] = m_pWireframe[0];
+ m_pDotted[1] = m_pDotted[0];
+ m_pSelectionOverlay[1] = m_pSelectionOverlay[0];
+
+ return true;
+
+}
+
+bool CRender::IsActiveView()
+{
+ return m_pView->IsActive();
+}
+
+void CRender::SetDrawColor( const Color &color )
+{
+ m_DrawColor = color;
+ if ( m_bIsRenderingIntoVGUI )
+ {
+ g_pMatSystemSurface->DrawSetColor( m_DrawColor );
+ }
+}
+
+void CRender::GetDrawColor( Color &color )
+{
+ color = m_DrawColor;
+}
+
+void CRender::SetDrawColor( unsigned char r, unsigned char g, unsigned char b )
+{
+ // current draw color, keep the alpha value
+ m_DrawColor.SetColor( r, g, b, m_DrawColor.a() );
+ if ( m_bIsRenderingIntoVGUI )
+ {
+ g_pMatSystemSurface->DrawSetColor( m_DrawColor );
+ }
+}
+
+void CRender::SetHandleStyle( int size, int type )
+{
+ m_nHandleType = type;
+ m_nHandleSize = size;
+}
+
+void CRender::DrawArrow( Vector const &vStart, Vector const &vEnd )
+{
+ Assert(0);
+}
+
+void CRender::DrawPolyLine( int nPoints, const Vector *Points )
+{
+ // Draw the box bottom, top, and one corner edge.
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nPoints );
+
+ for (int i= 0; i<nPoints;i++ )
+ {
+ meshBuilder.Position3fv( &Points[i].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawDisplacement( CCoreDispInfo *pMapDisp )
+{
+ int numVerts = pMapDisp->GetSize();
+ int numIndices = pMapDisp->GetRenderIndexCount();
+ bool bWireFrame = m_eCurrentRenderMode == RENDER_MODE_WIREFRAME;
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_TRIANGLES, numVerts, numIndices );
+
+ Color color = m_DrawColor;
+
+ CoreDispVert_t *pVert = pMapDisp->GetDispVertList();
+ for (int i = 0; i < numVerts; ++i )
+ {
+ if ( bWireFrame )
+ {
+ meshBuilder.Position3fv( pVert[i].m_Vert.Base() );
+ meshBuilder.Color4ubv( (byte*)&color );
+ meshBuilder.TexCoord2fv( 0, pVert[i].m_TexCoord.Base() );
+ meshBuilder.TexCoord2fv( 1, pVert[i].m_LuxelCoords[0].Base() );
+ meshBuilder.AdvanceVertex();
+ }
+ else
+ {
+ meshBuilder.Position3fv( pVert[i].m_Vert.Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], 255 - ( unsigned char )( pVert[i].m_Alpha ) );
+ meshBuilder.Normal3fv( pVert[i].m_Normal.Base() );
+ meshBuilder.TangentS3fv( pVert[i].m_TangentS.Base() );
+ meshBuilder.TangentT3fv( pVert[i].m_TangentT.Base() );
+ meshBuilder.TexCoord2fv( 0, pVert[i].m_TexCoord.Base() );
+ meshBuilder.TexCoord2fv( 1, pVert[i].m_LuxelCoords[0].Base() );
+ meshBuilder.AdvanceVertex();
+ }
+ }
+
+ unsigned short *pIndex = pMapDisp->GetRenderIndexList();
+ for ( int i = 0; i < numIndices; ++i )
+ {
+ meshBuilder.Index( pIndex[i] );
+ meshBuilder.AdvanceIndex();
+ }
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+void CRender::DrawModel( DrawModelInfo_t* pInfo, matrix3x4_t *pBoneToWorld, const Vector &vOrigin, float fAlpha, bool bWireFrame )
+{
+ UpdateStudioRenderConfig( true, bWireFrame );
+
+ g_pStudioRender->SetAlphaModulation( fAlpha );
+
+ Vector viewOrigin;
+ GetCamera()->GetViewPoint( viewOrigin );
+
+ g_pStudioRender->SetEyeViewTarget( pInfo->m_pStudioHdr, pInfo->m_Body, viewOrigin );
+
+ g_pStudioRender->DrawModel( NULL, *pInfo, pBoneToWorld, NULL, NULL, vOrigin, STUDIORENDER_DRAW_ENTIRE_MODEL );
+
+ g_pStudioRender->SetAlphaModulation( 1.0f );
+
+ // force rendermode reset
+ SetRenderMode( RENDER_MODE_CURRENT, true );
+}
+
+void CRender::DrawCollisionModel( MDLHandle_t mdlHandle, const VMatrix &mViewMatrix )
+{
+ vcollide_t *pCollide =g_pMDLCache->GetVCollide( mdlHandle );
+
+ if ( !pCollide || pCollide->solidCount <= 0 )
+ return;
+
+ Vector *outVerts;
+ int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[0], &outVerts );
+
+ if ( vertCount )
+ {
+ PushRenderMode( RENDER_MODE_WIREFRAME );
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_TRIANGLES, vertCount/3 );
+
+ for ( int j = 0; j < vertCount; j++ )
+ {
+ Vector out;
+ mViewMatrix.V3Mul( outVerts[j], out );
+ meshBuilder.Position3fv( out.Base() );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.TexCoord2f( 0, 0, 0 );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+
+ PopRenderMode();
+ }
+
+ g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts );
+}
+
+void CRender::DrawSphere( const Vector &vCenter, int nRadius )
+{
+ Assert(0);
+}
+
+void CRender::DrawBoxExt( const Vector &vCenter, float extend, bool bFill)
+{
+ Vector vExtent( extend, extend, extend );
+ Vector vMins = vCenter - vExtent;
+ Vector vMax = vCenter + vExtent;
+
+ DrawBox( vMins, vMax, bFill );
+}
+
+void CRender::DrawHandles( int nPoints, const Vector *Points )
+{
+ Assert(0);
+}
+
+void CRender::DrawBox( const Vector &vMins, const Vector &vMaxs, bool bFill)
+{
+ Vector points[8];
+ PointsFromBox( vMins, vMaxs, points );
+
+ if ( bFill )
+ {
+ Assert(0);
+ }
+ else
+ {
+ // Draw the box bottom, top, and one corner edge.
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINE_STRIP, 9 );
+
+ meshBuilder.Position3fv( &points[0].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[1].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[3].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[2].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[6].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[7].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[5].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[4].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[0].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[2].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+
+ // Draw the three missing edges.
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 3 );
+
+ meshBuilder.Position3fv( &points[4].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[6].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[1].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[5].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[3].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( &points[7].x );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+ }
+}
+
+void CRender::DrawPoint( const Vector &vPoint )
+{
+ // HACK HACK, MATERIAL_POINTS doesnt work somehow
+
+ meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 1 );
+
+ meshBuilder.Position3f( vPoint.x, vPoint.y, vPoint.z );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( vPoint.x+1, vPoint.y+1, vPoint.z );
+ meshBuilder.Color4ubv( (byte*)&m_DrawColor );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ m_pMesh->Draw();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Binds a texture for rendering. If the texture has never been bound
+// to this rendering context, it is uploaded to the driver.
+// Input : pTexture - Pointer to the texture object being bound.
+//-----------------------------------------------------------------------------
+void CRender::BindTexture(IEditorTexture *pTexture)
+{
+ // These textures must be CMaterials....
+ BindMaterial( pTexture->GetMaterial() );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Binds a material for rendering. If the material has never been bound
+// to this rendering context, it is uploaded to the driver.
+// Input : pMaterial - Pointer to the material object being bound.
+//-----------------------------------------------------------------------------
+void CRender::BindMaterial( IMaterial *pMaterial )
+{
+ if ( m_pBoundMaterial != pMaterial )
+ {
+ m_pBoundMaterial = pMaterial;
+ SetRenderMode( RENDER_MODE_CURRENT, true );
+ }
+}
+
+
+bool CRender::GetRequiredMaterial( const char *pName, IMaterial* &pMaterial )
+{
+ pMaterial = NULL;
+ IEditorTexture *pTex = g_Textures.FindActiveTexture( pName );
+ if ( pTex )
+ pMaterial = pTex->GetMaterial();
+
+ if ( pMaterial )
+ {
+ return true;
+ }
+ else
+ {
+ char str[512];
+ Q_snprintf( str, sizeof( str ), "Missing material '%s'. Go to Tools | Options | Game Configurations and verify that your game directory is correct.", pName );
+ MessageBox( NULL, str, "FATAL ERROR", MB_OK );
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : eRenderMode -
+//-----------------------------------------------------------------------------
+void CRender::SetRenderMode(EditorRenderMode_t eRenderMode, bool bForce)
+{
+ if (eRenderMode == RENDER_MODE_DEFAULT)
+ {
+ eRenderMode = m_eDefaultRenderMode;
+ }
+
+ if ( eRenderMode == RENDER_MODE_CURRENT )
+ {
+ eRenderMode = m_eCurrentRenderMode;
+ }
+
+ if (m_eCurrentRenderMode == eRenderMode && !bForce)
+ return;
+
+ // Bind the appropriate material based on our mode
+ CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
+ switch(eRenderMode)
+ {
+ case RENDER_MODE_DOTTED:
+ m_pCurrentMaterial = m_pDotted[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_FLAT:
+ // Ensures we get red even for decals
+ m_pCurrentMaterial = m_pFlat[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_TRANSLUCENT_FLAT:
+ m_pCurrentMaterial = m_pTranslucentFlat[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_FLAT_NOZ:
+ // flat mode but not depth check
+ m_pCurrentMaterial = m_pFlatNoZ[m_nDecalMode];
+ break;
+ case RENDER_MODE_FLAT_NOCULL:
+ // flat mode but not depth check
+ m_pCurrentMaterial = m_pFlatNoCull[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_WIREFRAME:
+ m_pCurrentMaterial = m_pWireframe[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_SMOOTHING_GROUP:
+ m_pCurrentMaterial = m_pFlat[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_LIGHTMAP_GRID:
+ m_pCurrentMaterial = m_pLightmapGrid[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_SELECTION_OVERLAY:
+ case RENDER_MODE_INSTANCE_OVERLAY:
+ // Ensures we get red even for decals
+ m_pCurrentMaterial = m_pSelectionOverlay[m_nDecalMode];
+ break;
+
+ case RENDER_MODE_TEXTURED:
+ case RENDER_MODE_TEXTURED_SHADED:
+ case RENDER_MODE_LIGHT_PREVIEW2:
+ case RENDER_MODE_LIGHT_PREVIEW_RAYTRACED:
+ if (m_pBoundMaterial)
+ {
+ if( m_pBoundMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS ) )
+ {
+ pRenderContext->BindLightmapPage( MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE_BUMP );
+ }
+ else
+ {
+ pRenderContext->BindLightmapPage( MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE );
+ }
+
+ m_pCurrentMaterial = m_pBoundMaterial;
+ }
+ else
+ {
+ m_pCurrentMaterial = m_pFlat[m_nDecalMode];
+ }
+ break;
+ }
+
+ Assert( m_pCurrentMaterial != NULL );
+
+ pRenderContext->Bind( m_pCurrentMaterial );
+
+ pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,0);
+ if (eRenderMode==RENDER_MODE_TEXTURED_SHADED)
+ pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,1);
+
+ if (
+ (eRenderMode==RENDER_MODE_LIGHT_PREVIEW2) ||
+ (eRenderMode==RENDER_MODE_LIGHT_PREVIEW_RAYTRACED)
+ )
+ pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,2);
+
+ m_pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pCurrentMaterial );
+
+ Assert( m_pMesh );
+
+ m_eCurrentRenderMode = eRenderMode;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : eRenderMode -
+//-----------------------------------------------------------------------------
+void CRender::SetDefaultRenderMode(EditorRenderMode_t eRenderMode)
+{
+ Assert( eRenderMode != RENDER_MODE_DEFAULT );
+ m_eDefaultRenderMode = eRenderMode;
+}
+
+void CRender::PushRenderMode( EditorRenderMode_t eRenderMode )
+{
+ m_RenderModeStack.Push( m_eCurrentRenderMode );
+ SetRenderMode( eRenderMode );
+}
+
+void CRender::PopRenderMode()
+{
+ SetRenderMode( m_RenderModeStack.Top() );
+ m_RenderModeStack.Pop();
+}
+
+#define CAMERA_RIGHT 0
+#define CAMERA_UP 1
+#define CAMERA_FORWARD 2
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a vector indicating the camera's forward axis.
+//-----------------------------------------------------------------------------
+void CRender::GetViewForward( Vector &ViewForward ) const
+{
+ ViewForward[ 0 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 0 ];
+ ViewForward[ 1 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 1 ];
+ ViewForward[ 2 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 2 ];
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a vector indicating the camera's up axis.
+//-----------------------------------------------------------------------------
+void CRender::GetViewUp(Vector& ViewUp) const
+{
+ ViewUp[ 0 ] = m_CurrentMatrix[ CAMERA_UP ][ 0 ];
+ ViewUp[ 1 ] = m_CurrentMatrix[ CAMERA_UP ][ 1 ];
+ ViewUp[ 2 ] = m_CurrentMatrix[ CAMERA_UP ][ 2 ];
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a vector indicating the camera's right axis.
+//-----------------------------------------------------------------------------
+void CRender::GetViewRight(Vector& ViewRight) const
+{
+ ViewRight[ 0 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 0 ];
+ ViewRight[ 1 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 1 ];
+ ViewRight[ 2 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 2 ];
+}