diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/Render.cpp | |
| download | archived-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.cpp | 1543 |
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 ]; +} |