Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1620 lines
45 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Base rendering utilities for all views
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "stdafx.h"
  8. #include "MapDoc.h"
  9. #include <VGuiMatSurface/IMatSystemSurface.h>
  10. #include "mathlib/vmatrix.h"
  11. #include "Render.h"
  12. #include "Camera.h"
  13. #include "Material.h"
  14. #include "materialsystem/imesh.h"
  15. #include "datacache\imdlcache.h"
  16. #include "hammer.h"
  17. #include "hammer_mathlib.h"
  18. #include "vgui_controls/Controls.h"
  19. #include "vgui/IScheme.h"
  20. #include "texturesystem.h"
  21. #include "IStudioRender.h"
  22. #include "builddisp.h"
  23. #include "mapview.h"
  24. #include "material.h"
  25. #include <renderparm.h>
  26. #include "materialsystem/IMaterialSystemHardwareConfig.h"
  27. #include "vphysics_interface.h"
  28. #include "materialsystem/MaterialSystem_Config.h"
  29. #include "VGuiWnd.h"
  30. #include "Box3D.h"
  31. #include "MapInstance.h"
  32. #include "foundrytool.h"
  33. #include "tier3/tier3.h"
  34. static float s_fOneUnitLength = 1;
  35. CRender::CRender(void)
  36. {
  37. m_pView = NULL;
  38. // returns a handle to the default (first loaded) scheme
  39. vgui::IScheme * pScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetDefaultScheme() );
  40. if ( pScheme )
  41. {
  42. m_DefaultFont = pScheme->GetFont( "Default" );
  43. }
  44. else
  45. {
  46. m_DefaultFont = vgui::INVALID_FONT;
  47. static bool s_bOnce = false;
  48. if ( !s_bOnce )
  49. {
  50. s_bOnce = true;
  51. MessageBox( NULL, "Failed to load the default scheme file. The map views may be missing some visual elements.", "Error", MB_OK | MB_ICONEXCLAMATION );
  52. }
  53. }
  54. for (int i = 0; i < 2; ++i)
  55. {
  56. m_pFlat[i] = NULL;
  57. m_pWireframe[i] = NULL;
  58. m_pTranslucentFlat[i] = NULL;
  59. m_pLightmapGrid[i] = NULL;
  60. m_pSelectionOverlay[i] = NULL;
  61. m_pDotted[i] = NULL;
  62. m_pFlatNoZ[i] = NULL;
  63. m_pFlatNoCull[i] = NULL;
  64. }
  65. m_pCurrentMaterial = NULL;
  66. m_pBoundMaterial = NULL;
  67. m_nDecalMode = 0;
  68. m_bIsRendering = false;
  69. m_bIsClientSpace = false;
  70. m_bIsLocalTransform = false;
  71. m_bIsRenderingIntoVGUI = false;
  72. VMatrix IdentityMatrix;
  73. IdentityMatrix.Identity();
  74. m_LocalMatrix.AddToHead( IdentityMatrix );
  75. m_OrthoMatrix.Identity();
  76. m_eCurrentRenderMode = m_eDefaultRenderMode = RENDER_MODE_FLAT;
  77. m_bInstanceRendering = false;
  78. m_nInstanceCount = 0;
  79. m_InstanceSelectionDepth = 0;
  80. PushInstanceData( NULL, Vector( 0.0f, 0.0f, 0.0f ), QAngle( 0.0f, 0.0f, 0.0f ) ); // always add a default state
  81. if ( !APP()->IsFoundryMode() )
  82. {
  83. UpdateStudioRenderConfig( false, false );
  84. }
  85. }
  86. CRender::~CRender(void)
  87. {
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: this function will push all of the instance data
  91. // Input : pInstanceClass - the func_instance entity
  92. // InstanceOrigin - the translation of the instance
  93. // InstanceAngles - the rotation of the instance
  94. // Output : none
  95. //-----------------------------------------------------------------------------
  96. void CRender::PushInstanceData( CMapInstance *pInstanceClass, Vector &InstanceOrigin, QAngle &InstanceAngles )
  97. {
  98. TInstanceState InstanceState;
  99. matrix3x4_t Instance3x4Matrix;
  100. InstanceState.m_InstanceOrigin = InstanceOrigin;
  101. InstanceState.m_InstanceAngles = InstanceAngles;
  102. InstanceState.m_pInstanceClass = pInstanceClass;
  103. InstanceState.m_pTopInstanceClass = NULL;
  104. matrix3x4_t TransMatrix;
  105. matrix3x4_t RotMatrix;
  106. matrix3x4_t TransRotMatrix;
  107. AngleMatrix( InstanceState.m_InstanceAngles, RotMatrix );
  108. SetIdentityMatrix( TransMatrix );
  109. PositionMatrix( InstanceState.m_InstanceOrigin, TransMatrix );
  110. MatrixMultiply( TransMatrix, RotMatrix, TransRotMatrix );
  111. Vector vLocalOrigin = vec3_origin;
  112. if ( pInstanceClass != NULL && pInstanceClass->GetInstancedMap() != NULL )
  113. {
  114. CMapEntityList entityList;
  115. pInstanceClass->GetInstancedMap()->FindEntitiesByClassName( entityList, "func_instance_origin", false );
  116. if ( entityList.Count() == 1 )
  117. {
  118. entityList.Element( 0 )->GetOrigin( vLocalOrigin );
  119. }
  120. }
  121. matrix3x4_t LocalTransRotMatrix;
  122. Vector vOut;
  123. VectorRotate( -vLocalOrigin, RotMatrix, vOut );
  124. SetIdentityMatrix( TransMatrix );
  125. PositionMatrix( vOut, TransMatrix );
  126. MatrixMultiply( TransMatrix, TransRotMatrix, Instance3x4Matrix );
  127. InstanceState.m_InstanceMatrix.Init( Instance3x4Matrix );
  128. Vector vecTransformedOrigin;
  129. TransformInstanceVector( InstanceState.m_InstanceOrigin, vecTransformedOrigin );
  130. m_CurrentInstanceState.m_InstanceOrigin = vecTransformedOrigin;
  131. // 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
  132. if ( m_InstanceState.Count() > 0 )
  133. { // first push is just a default state
  134. m_bInstanceRendering = true;
  135. BeginLocalTransfrom( InstanceState.m_InstanceMatrix, true );
  136. if ( m_CurrentInstanceState.m_pTopInstanceClass == NULL )
  137. {
  138. if ( pInstanceClass->IsEditable() == false )
  139. {
  140. InstanceState.m_pTopInstanceClass = pInstanceClass;
  141. }
  142. }
  143. else
  144. {
  145. InstanceState.m_pTopInstanceClass = m_CurrentInstanceState.m_pTopInstanceClass;
  146. }
  147. if ( pInstanceClass->IsSelected() || m_InstanceSelectionDepth )
  148. {
  149. m_InstanceSelectionDepth++;
  150. }
  151. InstanceState.m_InstanceMatrix = m_CurrentInstanceState.m_InstanceMatrix * InstanceState.m_InstanceMatrix;
  152. InstanceState.m_bIsEditable = pInstanceClass->IsEditable();
  153. }
  154. else
  155. {
  156. m_bInstanceRendering = false;
  157. InstanceState.m_bIsEditable = true;
  158. }
  159. InstanceState.m_InstanceRenderMatrix = m_LocalMatrix.Head();
  160. m_InstanceState.AddToHead( InstanceState );
  161. m_CurrentInstanceState = InstanceState;
  162. if ( !pInstanceClass )
  163. {
  164. }
  165. else if ( m_InstanceSelectionDepth > 0 )
  166. {
  167. PushInstanceRendering( INSTANCE_STACE_SELECTED );
  168. }
  169. else if ( pInstanceClass->IsEditable() || CMapDoc::GetActiveMapDoc()->GetShowInstance() == INSTANCES_SHOW_NORMAL )
  170. {
  171. PushInstanceRendering( INSTANCE_STATE_OFF );
  172. }
  173. else
  174. {
  175. PushInstanceRendering( GetInstanceClass()->IsSelected() ? INSTANCE_STACE_SELECTED : INSTANCE_STATE_ON );
  176. }
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose: this function will pop off the top most instance data
  180. //-----------------------------------------------------------------------------
  181. void CRender::PopInstanceData( void )
  182. {
  183. if ( m_CurrentInstanceState.m_pInstanceClass )
  184. {
  185. PopInstanceRendering();
  186. }
  187. m_InstanceState.Remove( 0 );
  188. m_CurrentInstanceState = m_InstanceState.Head();
  189. if ( m_InstanceState.Count() > 1 )
  190. { // first push is just a default state
  191. m_bInstanceRendering = true;
  192. }
  193. else
  194. {
  195. m_bInstanceRendering = false;
  196. }
  197. if ( m_InstanceSelectionDepth > 0 )
  198. {
  199. m_InstanceSelectionDepth--;
  200. }
  201. EndLocalTransfrom();
  202. // m_CurrentInstanceState.m_InstanceRenderMatrix = m_LocalMatrix.Head();
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose: this function initializes the stencil buffer for instance rendering
  206. //-----------------------------------------------------------------------------
  207. void CRender::PrepareInstanceStencil( void )
  208. {
  209. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  210. #if STENCIL_AS_CALLS
  211. pRenderContext->SetStencilEnable( true );
  212. pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_ALWAYS );
  213. pRenderContext->SetStencilFailOperation( STENCILOPERATION_KEEP );
  214. pRenderContext->SetStencilZFailOperation( STENCILOPERATION_KEEP );
  215. pRenderContext->SetStencilWriteMask( 0xff );
  216. pRenderContext->SetStencilTestMask( 0xff );
  217. pRenderContext->SetStencilReferenceValue( 0x01 );
  218. pRenderContext->SetStencilPassOperation( STENCILOPERATION_ZERO);
  219. #else
  220. m_ShaderStencilState.m_bEnable = true;
  221. m_ShaderStencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
  222. m_ShaderStencilState.m_FailOp = SHADER_STENCILOP_KEEP;
  223. m_ShaderStencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
  224. m_ShaderStencilState.m_nWriteMask = 0xff;
  225. m_ShaderStencilState.m_nTestMask = 0xff;
  226. m_ShaderStencilState.m_nReferenceValue = 0x01;
  227. m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_ZERO;
  228. pRenderContext->SetStencilState( m_ShaderStencilState );
  229. #endif // STENCIL_AS_CALLS
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose: this function will draw the various alpha color 2d rectangles for the instance states
  233. //-----------------------------------------------------------------------------
  234. void CRender::DrawInstanceStencil( void )
  235. {
  236. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  237. CCamera *pCamera = GetCamera();
  238. if ( m_nNumInstancesRendered > 0 )
  239. {
  240. #if STENCIL_AS_CALLS
  241. pRenderContext->SetStencilPassOperation( STENCILOPERATION_KEEP );
  242. pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL );
  243. #else
  244. m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_KEEP;
  245. m_ShaderStencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
  246. #endif // STENCIL_AS_CALLS
  247. Color InstanceColoring;
  248. int width, height;
  249. pCamera->GetViewPort( width, height );
  250. PushRenderMode( RENDER_MODE_INSTANCE_OVERLAY );
  251. BeginClientSpace();
  252. InstanceColor( InstanceColoring, false );
  253. #if STENCIL_AS_CALLS
  254. pRenderContext->SetStencilReferenceValue( 0x01 );
  255. #else
  256. m_ShaderStencilState.m_nReferenceValue = 0x01;
  257. pRenderContext->SetStencilState( m_ShaderStencilState );
  258. #endif // STENCIL_AS_CALLS
  259. DrawFilledRect( Vector2D( 0.0f, 0.0f ), Vector2D( width, height ), ( byte * )&InstanceColoring, false );
  260. InstanceColor( InstanceColoring, true );
  261. #if STENCIL_AS_CALLS
  262. pRenderContext->SetStencilTestMask( 0xff );
  263. pRenderContext->SetStencilReferenceValue( 0x02 );
  264. #else
  265. m_ShaderStencilState.m_nReferenceValue = 0x02;
  266. pRenderContext->SetStencilState( m_ShaderStencilState );
  267. #endif // STENCIL_AS_CALLS
  268. DrawFilledRect( Vector2D( 0.0f, 0.0f ), Vector2D( width, height ), ( byte * )&InstanceColoring, false );
  269. EndClientSpace();
  270. PopRenderMode();
  271. }
  272. #if STENCIL_AS_CALLS
  273. pRenderContext->SetStencilEnable( false );
  274. #else
  275. m_ShaderStencilState.m_bEnable = false;
  276. pRenderContext->SetStencilState( m_ShaderStencilState );
  277. #endif // STENCIL_AS_CALLS
  278. }
  279. //-----------------------------------------------------------------------------
  280. // Purpose: this function will push all of the instance data
  281. // Input : pInstanceClass - the func_instance entity
  282. // InstanceOrigin - the translation of the instance
  283. // InstanceAngles - the rotation of the instance
  284. // Output : none
  285. //-----------------------------------------------------------------------------
  286. void CRender::PushInstanceRendering( InstanceRenderingState_t State )
  287. {
  288. SetInstanceRendering( State );
  289. m_InstanceRenderingState.AddToHead( State );
  290. if ( State != INSTANCE_STATE_OFF )
  291. {
  292. m_nNumInstancesRendered++;
  293. }
  294. }
  295. //-----------------------------------------------------------------------------
  296. // Purpose: this function will pop off the top most instance data
  297. //-----------------------------------------------------------------------------
  298. void CRender::PopInstanceRendering( void )
  299. {
  300. m_InstanceRenderingState.Remove( 0 );
  301. if ( m_InstanceRenderingState.Count() > 0 )
  302. {
  303. SetInstanceRendering( m_InstanceRenderingState.Head() );
  304. }
  305. else
  306. {
  307. SetInstanceRendering( INSTANCE_STATE_OFF );
  308. }
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose: Sets the instance rendering state for stencil buffer operations.
  312. // 0 in stencil buffer = normal drawing
  313. // 1 in stencil buffer = instance shaded pass
  314. // 2 in stencil buffer = instance selected shaded pass
  315. // Input : State - the state at which the next drawing operations should impact
  316. // the stencil buffer
  317. //-----------------------------------------------------------------------------
  318. void CRender::SetInstanceRendering( InstanceRenderingState_t State )
  319. {
  320. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  321. switch( State )
  322. {
  323. case INSTANCE_STATE_OFF:
  324. #ifdef STENCIL_AS_CALLS
  325. pRenderContext->SetStencilPassOperation( STENCILOPERATION_ZERO );
  326. #else
  327. m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_ZERO;
  328. #endif // STENCIL_AS_CALLS
  329. break;
  330. case INSTANCE_STATE_ON:
  331. #if STENCIL_AS_CALLS
  332. pRenderContext->SetStencilPassOperation( STENCILOPERATION_REPLACE );
  333. pRenderContext->SetStencilReferenceValue( 0x01 );
  334. #else
  335. m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
  336. m_ShaderStencilState.m_nReferenceValue = 0x01;
  337. #endif // STENCIL_AS_CALLS
  338. break;
  339. case INSTANCE_STACE_SELECTED:
  340. #if STENCIL_AS_CALLS
  341. pRenderContext->SetStencilPassOperation( STENCILOPERATION_REPLACE );
  342. pRenderContext->SetStencilReferenceValue( 0x02 );
  343. #else
  344. m_ShaderStencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
  345. m_ShaderStencilState.m_nReferenceValue = 0x02;
  346. #endif // STENCIL_AS_CALLS
  347. break;
  348. }
  349. #ifndef STENCIL_AS_CALLS
  350. pRenderContext->SetStencilState( m_ShaderStencilState );
  351. #endif // STENCIL_AS_CALLS
  352. }
  353. //-----------------------------------------------------------------------------
  354. // Purpose: This function renders a text string at the given position, width,
  355. // height, and format
  356. // Input: text - the string to print
  357. // pos - the screen space position of the text (the is the top-left of
  358. // a screen space rect)
  359. // width - the width to render the text into
  360. // height - the height to render the text into
  361. // nFlags - define the text format -- see SetTextFormat
  362. //-----------------------------------------------------------------------------
  363. void CRender::DrawText( const char *text, int x, int y, int nFlags )
  364. {
  365. wchar_t unicode[ 128 ];
  366. mbstowcs( unicode, text, sizeof(unicode) );
  367. int len = min( 127, Q_strlen( text ) );
  368. Assert( m_DefaultFont != vgui::INVALID_FONT );
  369. bool bJustifyText = ( nFlags & ( TEXT_JUSTIFY_LEFT | TEXT_JUSTIFY_TOP | TEXT_JUSTIFY_HORZ_CENTER | TEXT_JUSTIFY_VERT_CENTER ) ) ? true : false;
  370. if ( bJustifyText && m_DefaultFont != vgui::INVALID_FONT )
  371. {
  372. int wide,tall;
  373. g_pMatSystemSurface->GetTextSize( m_DefaultFont, unicode, wide, tall );
  374. if ( nFlags & TEXT_JUSTIFY_LEFT )
  375. x -= wide;
  376. if ( nFlags & TEXT_JUSTIFY_TOP )
  377. y -= tall;
  378. if ( nFlags & TEXT_JUSTIFY_HORZ_CENTER )
  379. x -= wide/2;
  380. if ( nFlags & TEXT_JUSTIFY_VERT_CENTER )
  381. y -= tall/2;
  382. }
  383. PushRenderMode( RENDER_MODE_EXTERN );
  384. bool bPopMode = BeginClientSpace();
  385. g_pMatSystemSurface->DrawSetTextPos( x, y );
  386. g_pMatSystemSurface->DrawPrintText( unicode, len );
  387. if ( bPopMode )
  388. EndClientSpace();
  389. PopRenderMode();
  390. }
  391. //-----------------------------------------------------------------------------
  392. // Uses "world" coordinates
  393. //-----------------------------------------------------------------------------
  394. void CRender::DrawText( const char *text, const Vector2D &vPos, int nOffsetX, int nOffsetY, int nFlags )
  395. {
  396. Vector vecActualPos( vPos.x, vPos.y, 0.0f );
  397. if ( IsInLocalTransformMode() )
  398. {
  399. VMatrix matrix;
  400. GetLocalTranform( matrix );
  401. Vector vWorld = vecActualPos;
  402. Vector3DMultiplyPosition( matrix, vWorld, vecActualPos );
  403. }
  404. Vector2D pt;
  405. m_pView->WorldToClient( pt, vecActualPos );
  406. DrawText( text, (int)pt.x + nOffsetX, (int)pt.y + nOffsetY, nFlags );
  407. }
  408. //-----------------------------------------------------------------------------
  409. // Purpose: set the text and background (behind text) colors
  410. // Input: tR, tG, tB - text red, green, and blue values : [0...255]
  411. // bkR, bkG, bkB - background red, green, blue values : [0...255]
  412. //-----------------------------------------------------------------------------
  413. void CRender::SetTextColor( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
  414. {
  415. m_TextColor.SetColor( r,g,b,a );
  416. if ( m_bIsRenderingIntoVGUI )
  417. {
  418. g_pMatSystemSurface->DrawSetTextColor( m_TextColor );
  419. }
  420. }
  421. void CRender::SetHandleColor( unsigned char r, unsigned char g, unsigned char b )
  422. {
  423. m_HandleColor.SetColor( r, g, b, 255 );
  424. }
  425. void CRender::UpdateStudioRenderConfig( bool bFlat, bool bWireframe )
  426. {
  427. StudioRenderConfig_t config;
  428. memset( &config, 0, sizeof( config ) );
  429. config.fEyeShiftX = 0.0f;
  430. config.fEyeShiftY = 0.0f;
  431. config.fEyeShiftZ = 0.0f;
  432. config.fEyeSize = 0;
  433. config.drawEntities = 1;
  434. config.skin = 0;
  435. config.fullbright = MaterialSystemConfig().nFullbright;
  436. config.bEyeMove = true;
  437. config.bSoftwareSkin = bWireframe;
  438. config.bNoHardware = false;
  439. config.bNoSoftware = false;
  440. config.bTeeth = false;
  441. config.bEyes = true;
  442. config.bFlex = true;
  443. config.bSoftwareLighting = true;
  444. config.bWireframe = bWireframe;
  445. config.bDrawNormals = false;
  446. config.bShowEnvCubemapOnly = false;
  447. g_pStudioRender->UpdateConfig( config );
  448. }
  449. void CRender::StartRenderFrame( bool bRenderingOverEngine )
  450. {
  451. Assert( !m_bIsRendering );
  452. m_bRenderingOverEngine = bRenderingOverEngine;
  453. m_nNumInstancesRendered = 0;
  454. m_bIsRenderingIntoVGUI = dynamic_cast<CVGuiWnd*>( GetView() ) ? true : false;
  455. if ( m_bIsRenderingIntoVGUI )
  456. {
  457. g_pMatSystemSurface->DrawSetTextFont( m_DefaultFont );
  458. g_pMatSystemSurface->DrawSetTextColor( m_TextColor );
  459. g_pMatSystemSurface->DrawSetColor( m_DrawColor );
  460. }
  461. CCamera *pCamera = GetCamera();
  462. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  463. // build ortho matrix for client space mode
  464. if ( !bRenderingOverEngine )
  465. {
  466. int width, height;
  467. VMatrix matrix;
  468. pCamera->GetViewPort( width, height );
  469. pRenderContext->MatrixMode(MATERIAL_PROJECTION);
  470. pRenderContext->LoadIdentity();
  471. pRenderContext->Scale( 1, -1, 1 );
  472. pRenderContext->Ortho(0, 0, width, height, -99999, 99999 );
  473. pRenderContext->GetMatrix( MATERIAL_PROJECTION, &m_OrthoMatrix );
  474. // setup world camera
  475. pCamera->GetProjMatrix(matrix);
  476. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  477. pRenderContext->LoadMatrix( matrix );
  478. pCamera->GetViewMatrix(matrix);
  479. pRenderContext->MatrixMode( MATERIAL_VIEW );
  480. pRenderContext->LoadMatrix( matrix );
  481. pRenderContext->MatrixMode(MATERIAL_MODEL);
  482. pRenderContext->LoadIdentity();
  483. // specular is turned off in the multiblend shader though for the editor
  484. Vector vLightDir( 0.0f, 0.0f, -1.0f );
  485. pRenderContext->SetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_LIGHT_DIRECTION, vLightDir );
  486. pRenderContext->SetFloatRenderingParameter( FLOAT_RENDERPARM_SPECULAR_POWER, 8.0f );
  487. }
  488. pCamera->GetViewMatrix( m_CurrentMatrix );
  489. // Disable all the lights..
  490. pRenderContext->DisableAllLocalLights();
  491. m_bIsClientSpace = false;
  492. // reset render mode
  493. m_RenderModeStack.Clear();
  494. SetRenderMode( m_eDefaultRenderMode, true );
  495. // reset colors
  496. m_DrawColor.SetColor( 255,255,255,255 );
  497. m_TextColor.SetColor( 255,255,255,255 );
  498. m_HandleColor.SetColor( 255,255,255,255 );
  499. s_fOneUnitLength = 1/pCamera->GetZoom();
  500. // tell studiorender that we've updated the camera.
  501. if( !bRenderingOverEngine && g_pStudioRender )
  502. {
  503. g_pStudioRender->BeginFrame();
  504. Vector viewOrigin, viewRight, viewUp, viewForward;
  505. pCamera->GetViewPoint( viewOrigin );
  506. pCamera->GetViewRight( viewRight );
  507. pCamera->GetViewUp( viewUp );
  508. pCamera->GetViewForward( viewForward );
  509. g_pStudioRender->SetViewState( viewOrigin, viewRight, viewUp, viewForward );
  510. static Vector white[6] =
  511. {
  512. Vector( 1.0, 1.0, 1.0 ),
  513. Vector( 1.0, 1.0, 1.0 ),
  514. Vector( 1.0, 1.0, 1.0 ),
  515. Vector( 1.0, 1.0, 1.0 ),
  516. Vector( 1.0, 1.0, 1.0 ),
  517. Vector( 1.0, 1.0, 1.0 ),
  518. };
  519. g_pStudioRender->SetAmbientLightColors( white );
  520. }
  521. m_bIsRendering = true;
  522. }
  523. void CRender::EndRenderFrame()
  524. {
  525. Assert( m_bIsRendering );
  526. Assert( !m_bIsClientSpace );
  527. Assert( m_RenderModeStack.Count() == 0 );
  528. Assert( !m_bIsLocalTransform );
  529. if ( g_pStudioRender )
  530. {
  531. g_pStudioRender->BeginFrame();
  532. }
  533. // turn off lighting preview shader state
  534. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  535. pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,0);
  536. m_nFrameCount++;
  537. m_bIsRendering = false;
  538. m_bIsRenderingIntoVGUI = false;
  539. }
  540. void CRender::DrawLine( const Vector &vStart, const Vector &vEnd )
  541. {
  542. float scale = VectorLength( vEnd-vStart ) / ( s_fOneUnitLength * 16 );
  543. meshBuilder.Begin(m_pMesh, MATERIAL_LINES, 1);
  544. meshBuilder.Position3fv(vStart.Base());
  545. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  546. meshBuilder.TexCoord2f(0, 0, 0);
  547. meshBuilder.AdvanceVertex();
  548. meshBuilder.Position3fv(vEnd.Base());
  549. meshBuilder.Color4ubv((byte*)&m_DrawColor);
  550. meshBuilder.TexCoord2f(0, scale, scale);
  551. meshBuilder.AdvanceVertex();
  552. meshBuilder.End();
  553. m_pMesh->Draw();
  554. }
  555. void CRender::BeginLocalTransfrom( const VMatrix &matrix, bool MultiplyCurrent )
  556. {
  557. Assert( !m_bIsClientSpace );
  558. VMatrix LocalCopy = matrix;
  559. if ( MultiplyCurrent )
  560. {
  561. LocalCopy = m_LocalMatrix.Head() * LocalCopy;
  562. }
  563. m_LocalMatrix.AddToHead( LocalCopy );
  564. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  565. pRenderContext->MatrixMode(MATERIAL_MODEL);
  566. pRenderContext->PushMatrix();
  567. pRenderContext->LoadMatrix( m_LocalMatrix.Head() );
  568. CCamera *pCamera = GetCamera();
  569. pCamera->GetViewMatrix( m_CurrentMatrix );
  570. m_CurrentMatrix = m_CurrentMatrix * LocalCopy;
  571. m_bIsLocalTransform = true;
  572. }
  573. void CRender::EndLocalTransfrom()
  574. {
  575. Assert( m_bIsLocalTransform );
  576. Assert( !m_bIsClientSpace );
  577. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  578. pRenderContext->MatrixMode(MATERIAL_MODEL);
  579. pRenderContext->PopMatrix();
  580. m_LocalMatrix.Remove( 0 );
  581. CCamera *pCamera = GetCamera();
  582. pCamera->GetViewMatrix( m_CurrentMatrix );
  583. if ( m_LocalMatrix.Count() > 1 )
  584. {
  585. m_CurrentMatrix = m_CurrentMatrix * m_LocalMatrix.Head();
  586. m_bIsLocalTransform = true;
  587. }
  588. else
  589. {
  590. m_bIsLocalTransform = false;
  591. }
  592. }
  593. bool CRender::IsInLocalTransformMode()
  594. {
  595. return m_bIsLocalTransform;
  596. }
  597. void CRender::GetLocalTranform( VMatrix &matrix )
  598. {
  599. matrix = m_LocalMatrix.Head();
  600. }
  601. bool CRender::BeginClientSpace(void)
  602. {
  603. if ( m_bIsClientSpace )
  604. return false;
  605. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  606. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  607. pRenderContext->PushMatrix();
  608. pRenderContext->LoadMatrix( m_OrthoMatrix );
  609. pRenderContext->MatrixMode(MATERIAL_VIEW);
  610. pRenderContext->PushMatrix();
  611. // For DX9, we need to offset vertex positions by 1/2 pixel, so that pixel and texel centers fall on the same spot.
  612. // If we don't do this, we are at relying on undefined behavior in the various GPUs' texture units, and e.g. the 4800 series
  613. // will render garbage text because of it. If Hammer ever needs to run on top of GL or D3D10/11, this translate has to
  614. // become conditional based on the API we're using.
  615. pRenderContext->LoadIdentity();
  616. pRenderContext->Translate( -.5f, .5f, 0.0f );
  617. if ( m_bIsLocalTransform )
  618. {
  619. pRenderContext->MatrixMode(MATERIAL_MODEL);
  620. pRenderContext->PushMatrix();
  621. pRenderContext->LoadIdentity();
  622. }
  623. m_bIsClientSpace = true;
  624. return true;
  625. }
  626. void CRender::EndClientSpace(void)
  627. {
  628. Assert( m_bIsClientSpace );
  629. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  630. pRenderContext->MatrixMode(MATERIAL_VIEW);
  631. pRenderContext->PopMatrix();
  632. pRenderContext->MatrixMode(MATERIAL_PROJECTION);
  633. pRenderContext->PopMatrix();
  634. if ( m_bIsLocalTransform )
  635. {
  636. pRenderContext->MatrixMode(MATERIAL_MODEL);
  637. pRenderContext->PopMatrix();
  638. }
  639. m_bIsClientSpace = false;
  640. }
  641. void CRender::TransformPoint( Vector2D &vClient, const Vector& vWorld )
  642. {
  643. Vector vecActualPos;
  644. if ( !m_bIsLocalTransform )
  645. {
  646. vecActualPos = vWorld;
  647. }
  648. else
  649. {
  650. m_LocalMatrix.Head().V3Mul( vWorld, vecActualPos );
  651. }
  652. m_pView->WorldToClient( vClient, vecActualPos );
  653. }
  654. void CRender::TransformNormal( Vector2D &vClient, const Vector& vWorld )
  655. {
  656. Vector2D originClient, normalClient;
  657. TransformPoint( originClient, vec3_origin );
  658. TransformPoint( normalClient, vWorld );
  659. vClient = normalClient- originClient;
  660. }
  661. void CRender::DrawCircle( const Vector &vCenter, const Vector &vNormal, float flRadius, int nSegments)
  662. {
  663. Vector vx,vy;
  664. if ( !BuildAxesFromNormal( vNormal, vx, vy ) )
  665. return;
  666. vx *= flRadius;
  667. vy *= flRadius;
  668. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nSegments );
  669. float invDelta = 2.0f * M_PI / nSegments;
  670. for ( int i = 0; i < nSegments; ++i )
  671. {
  672. float flRadians = i * invDelta;
  673. float ca = cos( flRadians );
  674. float sa = sin( flRadians );
  675. // Rotate it around the circle
  676. Vector vertex = vCenter + (ca*vx) + (sa*vy);
  677. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  678. meshBuilder.Position3fv( &vertex.x );
  679. meshBuilder.AdvanceVertex();
  680. }
  681. meshBuilder.End();
  682. m_pMesh->Draw();
  683. }
  684. void CRender::DrawCircle( Vector2D &vCenter, float fRadius, int nSegments, unsigned char *pColor )
  685. {
  686. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nSegments );
  687. float invDelta = 2.0f * M_PI / nSegments;
  688. for ( int i = 0; i < nSegments; ++i )
  689. {
  690. float flRadians = i * invDelta;
  691. float ca = cos( flRadians );
  692. float sa = sin( flRadians );
  693. // Rotate it around the circle
  694. float x = vCenter.x + (fRadius * ca);
  695. float y = vCenter.y + (fRadius * sa);
  696. meshBuilder.Color4ubv( pColor );
  697. meshBuilder.Position3f( x, y, 0 );
  698. meshBuilder.AdvanceVertex();
  699. }
  700. meshBuilder.End();
  701. m_pMesh->Draw();
  702. }
  703. void CRender::DrawCross( Vector2D& ul, Vector2D& lr, unsigned char *pColor )
  704. {
  705. // just sizes
  706. meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 2 );
  707. meshBuilder.Color4ubv( pColor );
  708. meshBuilder.Position3f( ul.x, ul.y, 0 );
  709. meshBuilder.AdvanceVertex();
  710. meshBuilder.Color4ubv( pColor );
  711. meshBuilder.Position3f( lr.x, lr.y, 0 );
  712. meshBuilder.AdvanceVertex();
  713. meshBuilder.Color4ubv( pColor );
  714. meshBuilder.Position3f( ul.x, lr.y-1, 0 );
  715. meshBuilder.AdvanceVertex();
  716. meshBuilder.Color4ubv( pColor );
  717. meshBuilder.Position3f( lr.x, ul.y-1, 0 );
  718. meshBuilder.AdvanceVertex();
  719. meshBuilder.End();
  720. m_pMesh->Draw();
  721. }
  722. void CRender::DrawRect( Vector2D& ul, Vector2D& lr, unsigned char *pColor )
  723. {
  724. Vector2D vScale = (lr-ul)/16;
  725. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, 4 );
  726. Vector2D tex(0,0);
  727. meshBuilder.Color4ubv( pColor );
  728. meshBuilder.Position3f( ul.x, ul.y, 0 );
  729. meshBuilder.TexCoord2f(0, tex.x, tex.y );
  730. meshBuilder.AdvanceVertex();
  731. tex.x += vScale.x;
  732. tex.y += vScale.x;
  733. meshBuilder.Color4ubv( pColor );
  734. meshBuilder.Position3f( lr.x, ul.y, 0 );
  735. meshBuilder.TexCoord2f(0, tex.x, tex.y );
  736. meshBuilder.AdvanceVertex();
  737. tex.x += vScale.y;
  738. tex.y -= vScale.y;
  739. meshBuilder.Color4ubv( pColor );
  740. meshBuilder.Position3f( lr.x, lr.y, 0 );
  741. meshBuilder.TexCoord2f(0, tex.x, tex.y );
  742. meshBuilder.AdvanceVertex();
  743. tex.x -= vScale.x;
  744. tex.y -= vScale.x;
  745. meshBuilder.Color4ubv( pColor );
  746. meshBuilder.Position3f( ul.x, lr.y, 0 );
  747. meshBuilder.TexCoord2f(0, tex.x, tex.y );
  748. meshBuilder.AdvanceVertex();
  749. meshBuilder.End();
  750. m_pMesh->Draw();
  751. }
  752. void CRender::DrawPlane( const Vector &p0, const Vector &p1, const Vector &p2, const Vector &p3, bool bFill )
  753. {
  754. if ( bFill )
  755. {
  756. meshBuilder.Begin( m_pMesh, MATERIAL_QUADS, 1 );
  757. }
  758. else
  759. {
  760. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, 4 );
  761. }
  762. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  763. meshBuilder.Position3fv( &p0.x );
  764. meshBuilder.AdvanceVertex();
  765. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  766. meshBuilder.Position3fv( &p1.x );
  767. meshBuilder.AdvanceVertex();
  768. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  769. meshBuilder.Position3fv( &p2.x );
  770. meshBuilder.AdvanceVertex();
  771. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  772. meshBuilder.Position3fv( &p3.x );
  773. meshBuilder.AdvanceVertex();
  774. meshBuilder.End();
  775. m_pMesh->Draw();
  776. }
  777. void CRender::DrawFilledRect( Vector2D& ul, Vector2D& lr, unsigned char *pColor, bool bBorder )
  778. {
  779. static Color black(0,0,0,255);
  780. meshBuilder.Begin( m_pMesh, MATERIAL_QUADS, bBorder?2:1 );
  781. if ( bBorder )
  782. {
  783. meshBuilder.Color4ubv( (byte*)&black );
  784. meshBuilder.Position3f( ul.x, ul.y, 0 );
  785. meshBuilder.AdvanceVertex();
  786. meshBuilder.Color4ubv( (byte*)&black );
  787. meshBuilder.Position3f( lr.x, ul.y, 0 );
  788. meshBuilder.AdvanceVertex();
  789. meshBuilder.Color4ubv( (byte*)&black );
  790. meshBuilder.Position3f( lr.x, lr.y, 0 );
  791. meshBuilder.AdvanceVertex();
  792. meshBuilder.Color4ubv( (byte*)&black );
  793. meshBuilder.Position3f( ul.x, lr.y, 0 );
  794. meshBuilder.AdvanceVertex();
  795. ul.x+=1;
  796. ul.y+=1;
  797. lr.x-=1;
  798. lr.y-=1;
  799. }
  800. meshBuilder.Color4ubv( pColor );
  801. meshBuilder.Position3f( ul.x, ul.y, 0 );
  802. meshBuilder.AdvanceVertex();
  803. meshBuilder.Color4ubv( pColor );
  804. meshBuilder.Position3f( lr.x, ul.y, 0 );
  805. meshBuilder.AdvanceVertex();
  806. meshBuilder.Color4ubv( pColor );
  807. meshBuilder.Position3f( lr.x, lr.y, 0 );
  808. meshBuilder.AdvanceVertex();
  809. meshBuilder.Color4ubv( pColor );
  810. meshBuilder.Position3f( ul.x, lr.y, 0 );
  811. meshBuilder.AdvanceVertex();
  812. meshBuilder.End();
  813. m_pMesh->Draw();
  814. }
  815. void CRender::DrawHandle( const Vector &vCenter, const Vector2D *vOffset )
  816. {
  817. if ( !m_CurrentInstanceState.m_bIsEditable )
  818. {
  819. return;
  820. }
  821. int size = m_nHandleSize;
  822. bool bPopMode = BeginClientSpace();
  823. Vector2D vCenter2D;
  824. TransformPoint( vCenter2D, vCenter );
  825. if ( vOffset )
  826. {
  827. vCenter2D += *vOffset;
  828. }
  829. RoundVector( vCenter2D );
  830. if ( m_nHandleType == HANDLE_CROSS )
  831. size--;
  832. Vector2D ul( vCenter2D.x-size, vCenter2D.y-size );
  833. Vector2D lr( vCenter2D.x+size+1, vCenter2D.y+size+1 );
  834. switch ( m_nHandleType )
  835. {
  836. case HANDLE_SQUARE : DrawFilledRect( ul, lr, (byte*)&m_HandleColor, true );break;
  837. case HANDLE_CIRCLE : DrawCircle( vCenter2D, size, 16, (byte*)&m_HandleColor ); break;
  838. case HANDLE_DIAMOND : break;
  839. case HANDLE_CROSS : DrawCross( ul, lr, (byte*)&m_HandleColor );break;
  840. }
  841. if ( bPopMode )
  842. EndClientSpace();
  843. }
  844. CCamera *CRender::GetCamera()
  845. {
  846. return m_pView->GetCamera();
  847. }
  848. bool CRender::SetView( CMapView * pView )
  849. {
  850. Assert( pView );
  851. m_pView = pView;
  852. // Store off the three materials we use most often...
  853. if ( !GetRequiredMaterial( "editor/wireframe", m_pWireframe[0] ) ||
  854. !GetRequiredMaterial( "editor/flat", m_pFlat[0] ) ||
  855. !GetRequiredMaterial( "editor/flatdecal", m_pFlat[1] ) ||
  856. !GetRequiredMaterial( "editor/translucentflat", m_pTranslucentFlat[0] ) ||
  857. !GetRequiredMaterial( "editor/translucentflatdecal", m_pTranslucentFlat[1] ) ||
  858. !GetRequiredMaterial( "editor/lightmapgrid", m_pLightmapGrid[0] ) ||
  859. !GetRequiredMaterial( "editor/lightmapgriddecal", m_pLightmapGrid[1] ) ||
  860. !GetRequiredMaterial( "editor/selectionoverlay", m_pSelectionOverlay[0] ) ||
  861. !GetRequiredMaterial( "editor/flatignorez", m_pFlatNoZ[0] ) ||
  862. !GetRequiredMaterial( "editor/flatnocull", m_pFlatNoCull[0] ) ||
  863. !GetRequiredMaterial( "editor/dotted", m_pDotted[0] )
  864. )
  865. {
  866. return false;
  867. }
  868. // Some materials don't have a separate decal version.
  869. m_pFlatNoZ[1] = m_pFlatNoZ[0];
  870. m_pFlatNoCull[1] = m_pFlatNoCull[0];
  871. m_pWireframe[1] = m_pWireframe[0];
  872. m_pWireframe[1] = m_pDotted[0];
  873. m_pSelectionOverlay[1] = m_pSelectionOverlay[0];
  874. return true;
  875. }
  876. bool CRender::IsActiveView()
  877. {
  878. return m_pView->IsActive();
  879. }
  880. void CRender::SetDrawColor( const Color &color )
  881. {
  882. m_DrawColor = color;
  883. if ( m_bIsRenderingIntoVGUI )
  884. {
  885. g_pMatSystemSurface->DrawSetColor( m_DrawColor );
  886. }
  887. }
  888. void CRender::GetDrawColor( Color &color )
  889. {
  890. color = m_DrawColor;
  891. }
  892. void CRender::SetDrawColor( unsigned char r, unsigned char g, unsigned char b )
  893. {
  894. // current draw color, keep the alpha value
  895. m_DrawColor.SetColor( r, g, b, m_DrawColor.a() );
  896. if ( m_bIsRenderingIntoVGUI )
  897. {
  898. g_pMatSystemSurface->DrawSetColor( m_DrawColor );
  899. }
  900. }
  901. void CRender::SetHandleStyle( int size, int type )
  902. {
  903. m_nHandleType = type;
  904. m_nHandleSize = size;
  905. }
  906. void CRender::DrawArrow( Vector const &vStart, Vector const &vEnd )
  907. {
  908. Assert(0);
  909. }
  910. void CRender::DrawPolyLine( int nPoints, const Vector *Points )
  911. {
  912. // Draw the box bottom, top, and one corner edge.
  913. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_LOOP, nPoints );
  914. for (int i= 0; i<nPoints;i++ )
  915. {
  916. meshBuilder.Position3fv( &Points[i].x );
  917. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  918. meshBuilder.AdvanceVertex();
  919. }
  920. meshBuilder.End();
  921. m_pMesh->Draw();
  922. }
  923. void CRender::DrawDisplacement( CCoreDispInfo *pMapDisp )
  924. {
  925. int numVerts = pMapDisp->GetSize();
  926. int numIndices = pMapDisp->GetRenderIndexCount();
  927. bool bWireFrame = m_eCurrentRenderMode == RENDER_MODE_WIREFRAME;
  928. meshBuilder.Begin( m_pMesh, MATERIAL_TRIANGLES, numVerts, numIndices );
  929. Color color = m_DrawColor;
  930. CoreDispVert_t *pVert = pMapDisp->GetDispVertList();
  931. for (int i = 0; i < numVerts; ++i )
  932. {
  933. if ( bWireFrame )
  934. {
  935. meshBuilder.Position3fv( pVert[i].m_Vert.Base() );
  936. meshBuilder.Color4ubv( (byte*)&color );
  937. meshBuilder.TexCoord2fv( 0, pVert[i].m_TexCoord.Base() );
  938. meshBuilder.TexCoord2fv( 1, pVert[i].m_LuxelCoords[0].Base() );
  939. meshBuilder.AdvanceVertex();
  940. }
  941. else
  942. {
  943. meshBuilder.Position3fv( pVert[i].m_Vert.Base() );
  944. meshBuilder.Color4ub( color[0], color[1], color[2], 255 - ( unsigned char )( pVert[i].m_Alpha ) );
  945. meshBuilder.Normal3fv( pVert[i].m_Normal.Base() );
  946. meshBuilder.TangentS3fv( pVert[i].m_TangentS.Base() );
  947. meshBuilder.TangentT3fv( pVert[i].m_TangentT.Base() );
  948. meshBuilder.TexCoord2fv( 0, pVert[i].m_TexCoord.Base() );
  949. meshBuilder.TexCoord2fv( 1, pVert[i].m_LuxelCoords[0].Base() );
  950. meshBuilder.AdvanceVertex();
  951. }
  952. }
  953. unsigned short *pIndex = pMapDisp->GetRenderIndexList();
  954. for ( int i = 0; i < numIndices; ++i )
  955. {
  956. meshBuilder.Index( pIndex[i] );
  957. meshBuilder.AdvanceIndex();
  958. }
  959. meshBuilder.End();
  960. m_pMesh->Draw();
  961. }
  962. void CRender::DrawModel( DrawModelInfo_t* pInfo, matrix3x4_t *pBoneToWorld, const Vector &vOrigin, float fAlpha, bool bWireFrame, const Color &color )
  963. {
  964. if ( m_bRenderingOverEngine && g_pFoundryTool && !g_pFoundryTool->ShouldRender3DModels() )
  965. return;
  966. // In Foundry mode, the engine owns the studiorender config, so we must restore it after we draw a model.
  967. StudioRenderConfig_t oldConfig;
  968. if ( APP()->IsFoundryMode() )
  969. {
  970. g_pStudioRender->GetCurrentConfig( oldConfig );
  971. }
  972. UpdateStudioRenderConfig( true, bWireFrame );
  973. g_pStudioRender->SetAlphaModulation( fAlpha );
  974. float col[3];
  975. col[0] = color.r() / 255.0f;
  976. col[1] = color.g() / 255.0f;
  977. col[2] = color.b() / 255.0f;
  978. g_pStudioRender->SetColorModulation( col );
  979. Vector viewOrigin;
  980. GetCamera()->GetViewPoint( viewOrigin );
  981. g_pStudioRender->SetEyeViewTarget( pInfo->m_pStudioHdr, pInfo->m_Body, viewOrigin );
  982. if ( m_bRenderingOverEngine )
  983. {
  984. IMaterial *pMat = MaterialSystemInterface()->FindMaterial( "models/editor/white_model_outline", TEXTURE_GROUP_OTHER );
  985. g_pStudioRender->ForcedMaterialOverride( pMat, OVERRIDE_NORMAL );
  986. g_pStudioRender->SetAlphaModulation( 0.3f );
  987. g_pStudioRender->DrawModel( NULL, *pInfo, pBoneToWorld, NULL, NULL, vOrigin, STUDIORENDER_DRAW_ENTIRE_MODEL );
  988. g_pStudioRender->SetAlphaModulation( 1 );
  989. g_pStudioRender->ForcedMaterialOverride( NULL, OVERRIDE_NORMAL );
  990. }
  991. else
  992. {
  993. g_pStudioRender->DrawModel( NULL, *pInfo, pBoneToWorld, NULL, NULL, vOrigin, STUDIORENDER_DRAW_ENTIRE_MODEL );
  994. }
  995. g_pStudioRender->SetAlphaModulation( 1.0f );
  996. col[0] = col[1] = col[2] = 1.0f;
  997. g_pStudioRender->SetColorModulation( col );
  998. // force rendermode reset
  999. SetRenderMode( RENDER_MODE_CURRENT, true );
  1000. // Restore the studiorender config.
  1001. if ( APP()->IsFoundryMode() )
  1002. {
  1003. g_pStudioRender->UpdateConfig( oldConfig );
  1004. }
  1005. }
  1006. void CRender::DrawCollisionModel( MDLHandle_t mdlHandle, const VMatrix &mViewMatrix )
  1007. {
  1008. vcollide_t *pCollide =g_pMDLCache->GetVCollide( mdlHandle );
  1009. if ( !pCollide || pCollide->solidCount <= 0 )
  1010. return;
  1011. Vector *outVerts;
  1012. int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[0], &outVerts );
  1013. if ( vertCount )
  1014. {
  1015. PushRenderMode( RENDER_MODE_WIREFRAME );
  1016. meshBuilder.Begin( m_pMesh, MATERIAL_TRIANGLES, vertCount/3 );
  1017. for ( int j = 0; j < vertCount; j++ )
  1018. {
  1019. Vector out;
  1020. mViewMatrix.V3Mul( outVerts[j], out );
  1021. meshBuilder.Position3fv( out.Base() );
  1022. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1023. meshBuilder.TexCoord2f( 0, 0, 0 );
  1024. meshBuilder.AdvanceVertex();
  1025. }
  1026. meshBuilder.End();
  1027. m_pMesh->Draw();
  1028. PopRenderMode();
  1029. }
  1030. g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts );
  1031. }
  1032. void CRender::DrawSphere( const Vector &vCenter, int nRadius )
  1033. {
  1034. Assert(0);
  1035. }
  1036. void CRender::DrawBoxExt( const Vector &vCenter, float extend, bool bFill)
  1037. {
  1038. Vector vExtent( extend, extend, extend );
  1039. Vector vMins = vCenter - vExtent;
  1040. Vector vMax = vCenter + vExtent;
  1041. DrawBox( vMins, vMax, bFill );
  1042. }
  1043. void CRender::DrawHandles( int nPoints, const Vector *Points )
  1044. {
  1045. Assert(0);
  1046. }
  1047. void CRender::DrawBox( const Vector &vMins, const Vector &vMaxs, bool bFill)
  1048. {
  1049. Vector points[8];
  1050. PointsFromBox( vMins, vMaxs, points );
  1051. if ( bFill )
  1052. {
  1053. Assert(0);
  1054. }
  1055. else
  1056. {
  1057. // Draw the box bottom, top, and one corner edge.
  1058. meshBuilder.Begin( m_pMesh, MATERIAL_LINE_STRIP, 9 );
  1059. meshBuilder.Position3fv( &points[0].x );
  1060. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1061. meshBuilder.AdvanceVertex();
  1062. meshBuilder.Position3fv( &points[1].x );
  1063. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1064. meshBuilder.AdvanceVertex();
  1065. meshBuilder.Position3fv( &points[3].x );
  1066. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1067. meshBuilder.AdvanceVertex();
  1068. meshBuilder.Position3fv( &points[2].x );
  1069. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1070. meshBuilder.AdvanceVertex();
  1071. meshBuilder.Position3fv( &points[6].x );
  1072. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1073. meshBuilder.AdvanceVertex();
  1074. meshBuilder.Position3fv( &points[7].x );
  1075. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1076. meshBuilder.AdvanceVertex();
  1077. meshBuilder.Position3fv( &points[5].x );
  1078. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1079. meshBuilder.AdvanceVertex();
  1080. meshBuilder.Position3fv( &points[4].x );
  1081. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1082. meshBuilder.AdvanceVertex();
  1083. meshBuilder.Position3fv( &points[0].x );
  1084. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1085. meshBuilder.AdvanceVertex();
  1086. meshBuilder.Position3fv( &points[2].x );
  1087. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1088. meshBuilder.AdvanceVertex();
  1089. meshBuilder.End();
  1090. m_pMesh->Draw();
  1091. // Draw the three missing edges.
  1092. meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 3 );
  1093. meshBuilder.Position3fv( &points[4].x );
  1094. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1095. meshBuilder.AdvanceVertex();
  1096. meshBuilder.Position3fv( &points[6].x );
  1097. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1098. meshBuilder.AdvanceVertex();
  1099. meshBuilder.Position3fv( &points[1].x );
  1100. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1101. meshBuilder.AdvanceVertex();
  1102. meshBuilder.Position3fv( &points[5].x );
  1103. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1104. meshBuilder.AdvanceVertex();
  1105. meshBuilder.Position3fv( &points[3].x );
  1106. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1107. meshBuilder.AdvanceVertex();
  1108. meshBuilder.Position3fv( &points[7].x );
  1109. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1110. meshBuilder.AdvanceVertex();
  1111. meshBuilder.End();
  1112. m_pMesh->Draw();
  1113. }
  1114. }
  1115. void CRender::DrawPoint( const Vector &vPoint )
  1116. {
  1117. // HACK HACK, MATERIAL_POINTS doesnt work somehow
  1118. meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 1 );
  1119. meshBuilder.Position3f( vPoint.x, vPoint.y, vPoint.z );
  1120. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1121. meshBuilder.AdvanceVertex();
  1122. meshBuilder.Position3f( vPoint.x+1, vPoint.y+1, vPoint.z );
  1123. meshBuilder.Color4ubv( (byte*)&m_DrawColor );
  1124. meshBuilder.AdvanceVertex();
  1125. meshBuilder.End();
  1126. m_pMesh->Draw();
  1127. }
  1128. //-----------------------------------------------------------------------------
  1129. // Purpose: Binds a texture for rendering. If the texture has never been bound
  1130. // to this rendering context, it is uploaded to the driver.
  1131. // Input : pTexture - Pointer to the texture object being bound.
  1132. //-----------------------------------------------------------------------------
  1133. void CRender::BindTexture(IEditorTexture *pTexture)
  1134. {
  1135. // These textures must be CMaterials....
  1136. BindMaterial( pTexture->GetMaterial() );
  1137. }
  1138. //-----------------------------------------------------------------------------
  1139. // Purpose: Binds a material for rendering. If the material has never been bound
  1140. // to this rendering context, it is uploaded to the driver.
  1141. // Input : pMaterial - Pointer to the material object being bound.
  1142. //-----------------------------------------------------------------------------
  1143. void CRender::BindMaterial( IMaterial *pMaterial )
  1144. {
  1145. if ( m_pBoundMaterial != pMaterial )
  1146. {
  1147. m_pBoundMaterial = pMaterial;
  1148. SetRenderMode( RENDER_MODE_CURRENT, true );
  1149. }
  1150. }
  1151. bool CRender::GetRequiredMaterial( const char *pName, IMaterial* &pMaterial )
  1152. {
  1153. pMaterial = NULL;
  1154. IEditorTexture *pTex = g_Textures.FindActiveTexture( pName );
  1155. if ( pTex )
  1156. pMaterial = pTex->GetMaterial();
  1157. if ( pMaterial )
  1158. {
  1159. return true;
  1160. }
  1161. else
  1162. {
  1163. char str[512];
  1164. Q_snprintf( str, sizeof( str ), "Missing material '%s'. Go to Tools | Options | Game Configurations and verify that your game directory is correct.", pName );
  1165. MessageBox( NULL, str, "FATAL ERROR", MB_OK );
  1166. return false;
  1167. }
  1168. }
  1169. //-----------------------------------------------------------------------------
  1170. // Purpose:
  1171. // Input : eRenderMode -
  1172. //-----------------------------------------------------------------------------
  1173. void CRender::SetRenderMode(EditorRenderMode_t eRenderMode, bool bForce)
  1174. {
  1175. if (eRenderMode == RENDER_MODE_DEFAULT)
  1176. {
  1177. eRenderMode = m_eDefaultRenderMode;
  1178. }
  1179. if ( eRenderMode == RENDER_MODE_CURRENT )
  1180. {
  1181. eRenderMode = m_eCurrentRenderMode;
  1182. }
  1183. if (m_eCurrentRenderMode == eRenderMode && !bForce)
  1184. return;
  1185. // Bind the appropriate material based on our mode
  1186. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  1187. switch(eRenderMode)
  1188. {
  1189. case RENDER_MODE_DOTTED:
  1190. m_pCurrentMaterial = m_pDotted[m_nDecalMode];
  1191. break;
  1192. case RENDER_MODE_FLAT:
  1193. // Ensures we get red even for decals
  1194. m_pCurrentMaterial = m_pFlat[m_nDecalMode];
  1195. break;
  1196. case RENDER_MODE_TRANSLUCENT_FLAT:
  1197. m_pCurrentMaterial = m_pTranslucentFlat[m_nDecalMode];
  1198. break;
  1199. case RENDER_MODE_FLAT_NOZ:
  1200. // flat mode but not depth check
  1201. m_pCurrentMaterial = m_pFlatNoZ[m_nDecalMode];
  1202. break;
  1203. case RENDER_MODE_FLAT_NOCULL:
  1204. // flat mode but not depth check
  1205. m_pCurrentMaterial = m_pFlatNoCull[m_nDecalMode];
  1206. break;
  1207. case RENDER_MODE_WIREFRAME:
  1208. m_pCurrentMaterial = m_pWireframe[m_nDecalMode];
  1209. break;
  1210. case RENDER_MODE_SMOOTHING_GROUP:
  1211. m_pCurrentMaterial = m_pFlat[m_nDecalMode];
  1212. break;
  1213. case RENDER_MODE_LIGHTMAP_GRID:
  1214. m_pCurrentMaterial = m_pLightmapGrid[m_nDecalMode];
  1215. break;
  1216. case RENDER_MODE_SELECTION_OVERLAY:
  1217. case RENDER_MODE_INSTANCE_OVERLAY:
  1218. // Ensures we get red even for decals
  1219. m_pCurrentMaterial = m_pSelectionOverlay[m_nDecalMode];
  1220. break;
  1221. case RENDER_MODE_TEXTURED:
  1222. case RENDER_MODE_TEXTURED_SHADED:
  1223. case RENDER_MODE_LIGHT_PREVIEW2:
  1224. case RENDER_MODE_LIGHT_PREVIEW_RAYTRACED:
  1225. if (m_pBoundMaterial)
  1226. {
  1227. if( m_pBoundMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS ) )
  1228. {
  1229. pRenderContext->BindLightmapPage( MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE_BUMP );
  1230. }
  1231. else
  1232. {
  1233. pRenderContext->BindLightmapPage( MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE );
  1234. }
  1235. m_pCurrentMaterial = m_pBoundMaterial;
  1236. }
  1237. else
  1238. {
  1239. m_pCurrentMaterial = m_pFlat[m_nDecalMode];
  1240. }
  1241. break;
  1242. }
  1243. Assert( m_pCurrentMaterial != NULL );
  1244. pRenderContext->Bind( m_pCurrentMaterial );
  1245. pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,0);
  1246. if (eRenderMode==RENDER_MODE_TEXTURED_SHADED)
  1247. pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,1);
  1248. if (
  1249. (eRenderMode==RENDER_MODE_LIGHT_PREVIEW2) ||
  1250. (eRenderMode==RENDER_MODE_LIGHT_PREVIEW_RAYTRACED)
  1251. )
  1252. pRenderContext->SetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING,2);
  1253. m_pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pCurrentMaterial );
  1254. Assert( m_pMesh );
  1255. m_eCurrentRenderMode = eRenderMode;
  1256. }
  1257. //-----------------------------------------------------------------------------
  1258. // Purpose:
  1259. // Input : eRenderMode -
  1260. //-----------------------------------------------------------------------------
  1261. void CRender::SetDefaultRenderMode(EditorRenderMode_t eRenderMode)
  1262. {
  1263. Assert( eRenderMode != RENDER_MODE_DEFAULT );
  1264. m_eDefaultRenderMode = eRenderMode;
  1265. }
  1266. void CRender::PushRenderMode( EditorRenderMode_t eRenderMode )
  1267. {
  1268. m_RenderModeStack.Push( m_eCurrentRenderMode );
  1269. SetRenderMode( eRenderMode );
  1270. }
  1271. void CRender::PopRenderMode()
  1272. {
  1273. SetRenderMode( m_RenderModeStack.Top() );
  1274. m_RenderModeStack.Pop();
  1275. }
  1276. #define CAMERA_RIGHT 0
  1277. #define CAMERA_UP 1
  1278. #define CAMERA_FORWARD 2
  1279. //-----------------------------------------------------------------------------
  1280. // Purpose: Returns a vector indicating the camera's forward axis.
  1281. //-----------------------------------------------------------------------------
  1282. void CRender::GetViewForward( Vector &ViewForward ) const
  1283. {
  1284. ViewForward[ 0 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 0 ];
  1285. ViewForward[ 1 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 1 ];
  1286. ViewForward[ 2 ] = -m_CurrentMatrix[ CAMERA_FORWARD ][ 2 ];
  1287. }
  1288. //-----------------------------------------------------------------------------
  1289. // Purpose: Returns a vector indicating the camera's up axis.
  1290. //-----------------------------------------------------------------------------
  1291. void CRender::GetViewUp(Vector& ViewUp) const
  1292. {
  1293. ViewUp[ 0 ] = m_CurrentMatrix[ CAMERA_UP ][ 0 ];
  1294. ViewUp[ 1 ] = m_CurrentMatrix[ CAMERA_UP ][ 1 ];
  1295. ViewUp[ 2 ] = m_CurrentMatrix[ CAMERA_UP ][ 2 ];
  1296. }
  1297. //-----------------------------------------------------------------------------
  1298. // Purpose: Returns a vector indicating the camera's right axis.
  1299. //-----------------------------------------------------------------------------
  1300. void CRender::GetViewRight(Vector& ViewRight) const
  1301. {
  1302. ViewRight[ 0 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 0 ];
  1303. ViewRight[ 1 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 1 ];
  1304. ViewRight[ 2 ] = m_CurrentMatrix[ CAMERA_RIGHT ][ 2 ];
  1305. }