Team Fortress 2 Source Code as on 22/4/2020
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.

1543 lines
42 KiB

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