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.

738 lines
21 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "matsys_controls/vmtpreviewpanel.h"
  7. #include "matsys_controls/matsyscontrols.h"
  8. #include "matsys_controls/sheetsequencepanel.h"
  9. #include "VGuiMatSurface/IMatSystemSurface.h"
  10. #include "materialsystem/MaterialSystemUtil.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "materialsystem/imaterial.h"
  13. #include "materialsystem/itexture.h"
  14. #include "materialsystem/imesh.h"
  15. #include "tier1/keyvalues.h"
  16. #include "bitmap/psheet.h"
  17. #include "materialsystem/imaterialvar.h"
  18. #include "tier1/utlbuffer.h"
  19. // NOTE: This has to be the last file included!
  20. #include "tier0/memdbgon.h"
  21. using namespace vgui;
  22. #define FOV 90.0f
  23. #define ZNEAR 0.1f
  24. #define ZFAR 2000.0f
  25. #define ROTATION_SPEED 40.0f // degrees/sec
  26. #define VIEW_DISTANCE 12.0f
  27. //-----------------------------------------------------------------------------
  28. //
  29. // VMT Preview panel
  30. //
  31. //-----------------------------------------------------------------------------
  32. CVMTPreviewPanel::CVMTPreviewPanel( vgui::Panel *pParent, const char *pName ) :
  33. BaseClass( pParent, pName )
  34. {
  35. m_pMaterialSheet = NULL;
  36. SetVMT( "//platform/materials/vgui/vtfnotloaded" );
  37. m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
  38. m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
  39. m_LightDirection.Init( 0.0f, 1.0f, -1.0f );
  40. m_LightColor.SetColor( 255, 255, 255, 255 );
  41. m_flLightIntensity = 2.0f;
  42. m_bDrawIn3DMode = false;
  43. m_flSheetPreviewSpeed = 750.0f;
  44. m_nCurrentSheetSequence = 0;
  45. m_nCurrentSecondarySheetSequence = 0;
  46. // Reset the camera direction
  47. m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
  48. m_flLastRotationTime = Plat_FloatTime();
  49. m_flLastSwitchTime = Plat_FloatTime();
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Sets the current VMT
  53. //-----------------------------------------------------------------------------
  54. void CVMTPreviewPanel::SetVMT( const char *pMaterialName )
  55. {
  56. m_Material.Init( pMaterialName, "editor material" );
  57. m_VMTName = pMaterialName;
  58. m_flLastSwitchTime = Plat_FloatTime();
  59. if ( m_pMaterialSheet )
  60. {
  61. delete m_pMaterialSheet;
  62. }
  63. if ( m_bDrawIn3DMode )
  64. {
  65. m_pMaterialSheet = new CSheetExtended( m_Material );
  66. }
  67. else
  68. {
  69. m_pMaterialSheet = NULL;
  70. }
  71. m_nCurrentSheetSequence = 0;
  72. m_nCurrentSecondarySheetSequence = 0;
  73. }
  74. void CVMTPreviewPanel::SetSheetPreviewSpeed( float flPreviewSpeed )
  75. {
  76. m_flSheetPreviewSpeed = flPreviewSpeed;
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Gets the current VMT
  80. //-----------------------------------------------------------------------------
  81. const char *CVMTPreviewPanel::GetVMT() const
  82. {
  83. return m_VMTName;
  84. }
  85. CSheetExtended* CVMTPreviewPanel::GetSheet()
  86. {
  87. return m_pMaterialSheet;
  88. }
  89. IMaterial* CVMTPreviewPanel::GetMaterial()
  90. {
  91. return m_Material;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // View it in 3D or 2D mode
  95. //-----------------------------------------------------------------------------
  96. void CVMTPreviewPanel::DrawIn3DMode( bool b3DMode )
  97. {
  98. m_bDrawIn3DMode = b3DMode;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Sets up lighting state
  102. //-----------------------------------------------------------------------------
  103. void CVMTPreviewPanel::SetupLightingState()
  104. {
  105. MaterialLightingState_t state;
  106. memset( &state, 0, sizeof(state) );
  107. state.m_nLocalLightCount = 1;
  108. LightDesc_t &desc = state.m_pLocalLightDesc[0];
  109. desc.m_Type = MATERIAL_LIGHT_DIRECTIONAL;
  110. desc.m_Color[0] = m_LightColor.r();
  111. desc.m_Color[1] = m_LightColor.g();
  112. desc.m_Color[2] = m_LightColor.b();
  113. desc.m_Color *= m_flLightIntensity / 255.0f;
  114. desc.m_Attenuation0 = 1.0f;
  115. desc.m_Attenuation1 = 0.0f;
  116. desc.m_Attenuation2 = 0.0f;
  117. desc.m_Direction = m_LightDirection;
  118. VectorNormalize( desc.m_Direction );
  119. desc.m_Theta = 0.0f;
  120. desc.m_Phi = 0.0f;
  121. desc.m_Falloff = 1.0f;
  122. desc.RecalculateDerivedValues();
  123. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  124. pRenderContext->SetLightingState( state );
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Draw a sphere
  128. //-----------------------------------------------------------------------------
  129. void CVMTPreviewPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
  130. {
  131. int nVertices = nTheta * nPhi;
  132. int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
  133. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  134. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  135. CMeshBuilder meshBuilder;
  136. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
  137. bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
  138. bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
  139. int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
  140. float flHalfLuxel = 0.5f / nLightmapWidth;
  141. //
  142. // Build the index buffer.
  143. //
  144. int i, j;
  145. for ( i = 0; i < nPhi; ++i )
  146. {
  147. for ( j = 0; j < nTheta; ++j )
  148. {
  149. float u = j / ( float )(nTheta - 1);
  150. float v = i / ( float )(nPhi - 1);
  151. float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
  152. float phi = M_PI * v;
  153. Vector vecPos;
  154. vecPos.x = flRadius * sin(phi) * cos(theta);
  155. vecPos.y = flRadius * sin(phi) * sin(theta);
  156. vecPos.z = flRadius * cos(phi);
  157. Vector vecNormal = vecPos;
  158. VectorNormalize( vecNormal );
  159. Vector4D vecTangentS;
  160. Vector vecTangentT;
  161. vecTangentS.Init( vecPos.z, -vecPos.x, 0.0f, 1.0f );
  162. if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
  163. {
  164. vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
  165. }
  166. CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
  167. unsigned char red = (int)( u * 255.0f );
  168. unsigned char green = (int)( v * 255.0f );
  169. unsigned char blue = (int)( v * 255.0f );
  170. unsigned char alpha = (int)( v * 255.0f );
  171. vecPos += vCenter;
  172. float u1, u2, v1, v2;
  173. u1 = u2 = u;
  174. v1 = v2 = v;
  175. if ( bIsUsingLightmap )
  176. {
  177. u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
  178. if ( bIsUsingBumpedLightmap )
  179. {
  180. u2 = 0.25f;
  181. v2 = 0.0f;
  182. }
  183. }
  184. meshBuilder.Position3fv( vecPos.Base() );
  185. meshBuilder.Normal3fv( vecNormal.Base() );
  186. meshBuilder.Color4ub( red, green, blue, alpha );
  187. meshBuilder.TexCoord4f( 0, 2.0f * u, v, 0, 0 );
  188. meshBuilder.TexCoord4f( 1, u1, v1, 0, 0 );
  189. meshBuilder.TexCoord4f( 2, u2, v2, 0, 0 );
  190. meshBuilder.TexCoord4f( 3, u1, v1, 0, 0 );
  191. meshBuilder.TexCoord4f( 4, u2, v2, 0, 0 );
  192. meshBuilder.TangentS3fv( vecTangentS.Base() );
  193. meshBuilder.TangentT3fv( vecTangentT.Base() );
  194. meshBuilder.BoneWeight( 0, 1.0f );
  195. meshBuilder.BoneMatrix( 0, 0 );
  196. meshBuilder.UserData( vecTangentS.Base() );
  197. meshBuilder.AdvanceVertex();
  198. }
  199. }
  200. //
  201. // Emit the triangle strips.
  202. //
  203. int idx = 0;
  204. for ( i = 0; i < nPhi - 1; ++i )
  205. {
  206. for ( j = 0; j < nTheta; ++j )
  207. {
  208. idx = nTheta * i + j;
  209. meshBuilder.FastIndex( idx );
  210. meshBuilder.FastIndex( idx + nTheta );
  211. }
  212. //
  213. // Emit a degenerate triangle to skip to the next row without
  214. // a connecting triangle.
  215. //
  216. if ( i < nPhi - 2 )
  217. {
  218. meshBuilder.FastIndex( idx + 1 );
  219. meshBuilder.FastIndex( idx + 1 + nTheta );
  220. }
  221. }
  222. meshBuilder.End();
  223. pMesh->Draw();
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Draw sprite-card based materials
  227. //-----------------------------------------------------------------------------
  228. void CVMTPreviewPanel::RenderSheet( const Vector &vCenter, float flRadius )
  229. {
  230. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  231. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  232. if ( !m_pMaterialSheet->ValidSheetData() )
  233. return;
  234. float flAge = fmodf( Plat_FloatTime() - m_flLastSwitchTime, m_pMaterialSheet->GetSequenceTimeSpan( m_nCurrentSheetSequence ) );
  235. m_pMaterialSheet->DrawSheet( pMesh, vCenter, flRadius, m_nCurrentSheetSequence, flAge, m_flSheetPreviewSpeed, true, m_nCurrentSecondarySheetSequence );
  236. }
  237. //-----------------------------------------------------------------------------
  238. // Paints a regular texture
  239. //-----------------------------------------------------------------------------
  240. void CVMTPreviewPanel::DrawRectangle( void )
  241. {
  242. // Get the aspect ratio of the material
  243. int tw = m_Material->GetMappingWidth();
  244. int th = m_Material->GetMappingHeight();
  245. if ( tw <= 0 || th <= 0 )
  246. return;
  247. int w, h;
  248. GetSize( w, h );
  249. if ( w == 0 || h == 0 )
  250. return;
  251. SetupOrthoMatrix( w, h );
  252. SetupLightingState();
  253. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  254. pRenderContext->MatrixMode( MATERIAL_VIEW );
  255. pRenderContext->LoadIdentity();
  256. pRenderContext->MatrixMode( MATERIAL_MODEL );
  257. pRenderContext->LoadIdentity();
  258. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  259. CMeshBuilder meshBuilder;
  260. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 );
  261. bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
  262. bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
  263. int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
  264. float flHalfLuxel = 0.5f / nLightmapWidth;
  265. Vector2D halfTexel( 0.5f / tw, 0.5f / th );
  266. Vector vecNormal( 0.0f, 0.0f, 1.0f );
  267. Vector4D vecTangentS( 1.0f, 0.0f, 0.0f, 1.0f );
  268. Vector vecTangentT;
  269. CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
  270. float screenaspect = (float)tw / (float)th;
  271. float aspect = (float)w / (float)h;
  272. float ratio = screenaspect / aspect;
  273. // Screen is wider, need bars at top and bottom
  274. int x2, y2;
  275. int x, y;
  276. x = y = 0;
  277. int nXBorder = w > 15 ? 5 : w / 3;
  278. int nYBorder = h > 15 ? 5 : h / 3;
  279. w -= 2 * nXBorder;
  280. h -= 2 * nYBorder;
  281. if ( ratio > 1.0f )
  282. {
  283. int usetall = (float)w / screenaspect;
  284. y = ( h - usetall ) / 2;
  285. h = usetall;
  286. }
  287. // Screen is narrower, need bars at left/right
  288. else
  289. {
  290. int usewide = (float)h * screenaspect;
  291. x = ( w - usewide ) / 2;
  292. w = usewide;
  293. }
  294. x += nXBorder;
  295. y += nYBorder;
  296. x2 = x+w; y2 = y+h;
  297. float u = halfTexel.x;
  298. float v = halfTexel.y;
  299. float u1_l, u1_r, v1_t, v1_b;
  300. float u2_l, u2_r, v2_t, v2_b;
  301. u1_l = u2_l = u;
  302. u1_r = u2_r = 1.0f - u;
  303. v1_t = v2_t = v;
  304. v1_b = v2_b = 1.0f - v;
  305. if ( bIsUsingLightmap )
  306. {
  307. u1_l = v1_t = flHalfLuxel;
  308. u1_r = v1_b = 0.25 - flHalfLuxel;
  309. if ( bIsUsingBumpedLightmap )
  310. {
  311. u2_l = u2_r = 0.25f;
  312. v2_t = v2_b = 0.0f;
  313. }
  314. }
  315. bool m_bPreviewVertexColors = false;
  316. meshBuilder.Position3f( x, y2, 0.0f );
  317. meshBuilder.Normal3fv( vecNormal.Base() );
  318. if ( m_bPreviewVertexColors )
  319. {
  320. meshBuilder.Color4ub( 255, 0, 0, 255 );
  321. }
  322. else
  323. {
  324. meshBuilder.Color4ub( 255, 255, 255, 255 );
  325. }
  326. meshBuilder.TexCoord4f( 0, u, v, 0, 0 );
  327. meshBuilder.TexCoord4f( 1, u1_l, v1_t, 0, 0 );
  328. meshBuilder.TexCoord4f( 2, u2_l, v2_t, 0, 0 );
  329. meshBuilder.TexCoord4f( 3, u1_l, v1_t, 0, 0 );
  330. meshBuilder.TexCoord4f( 4, u2_l, v2_t, 0, 0 );
  331. meshBuilder.TexCoord4f( 5, u1_l, v1_t, 0, 0 );
  332. meshBuilder.TexCoord4f( 6, u2_l, v2_t, 0, 0 );
  333. meshBuilder.TexCoord4f( 7, u1_l, v1_t, 0, 0 );
  334. meshBuilder.TangentS3fv( vecTangentS.Base() );
  335. meshBuilder.TangentT3fv( vecTangentT.Base() );
  336. meshBuilder.BoneWeight( 0, 1.0f );
  337. meshBuilder.BoneMatrix( 0, 0 );
  338. meshBuilder.UserData( vecTangentS.Base() );
  339. meshBuilder.AdvanceVertex();
  340. meshBuilder.Position3f( x, y, 0.0f );
  341. meshBuilder.Normal3fv( vecNormal.Base() );
  342. if ( m_bPreviewVertexColors )
  343. {
  344. meshBuilder.Color4ub( 255, 255, 255, 64 );
  345. }
  346. else
  347. {
  348. meshBuilder.Color4ub( 255, 255, 255, 255 );
  349. }
  350. meshBuilder.TexCoord4f( 0, u, 1.0f - v, 0, 0 );
  351. meshBuilder.TexCoord4f( 1, u1_l, v1_b, 0, 0 );
  352. meshBuilder.TexCoord4f( 2, u2_l, v2_b, 0, 0 );
  353. meshBuilder.TexCoord4f( 3, u1_l, v1_b, 0, 0 );
  354. meshBuilder.TexCoord4f( 4, u2_l, v2_b, 0, 0 );
  355. meshBuilder.TexCoord4f( 5, u1_l, v1_b, 0, 0 );
  356. meshBuilder.TexCoord4f( 6, u2_l, v2_b, 0, 0 );
  357. meshBuilder.TexCoord4f( 7, u1_l, v1_b, 0, 0 );
  358. meshBuilder.TangentS3fv( vecTangentS.Base() );
  359. meshBuilder.TangentT3fv( vecTangentT.Base() );
  360. meshBuilder.BoneWeight( 0, 1.0f );
  361. meshBuilder.BoneMatrix( 0, 0 );
  362. meshBuilder.UserData( vecTangentS.Base() );
  363. meshBuilder.AdvanceVertex();
  364. meshBuilder.Position3f( x2, y2, 0.0f );
  365. meshBuilder.Normal3fv( vecNormal.Base() );
  366. if ( m_bPreviewVertexColors )
  367. {
  368. meshBuilder.Color4ub( 0, 0, 255, 255 );
  369. }
  370. else
  371. {
  372. meshBuilder.Color4ub( 255, 255, 255, 255 );
  373. }
  374. meshBuilder.TexCoord4f( 0, 1.0f - u, v, 0, 0 );
  375. meshBuilder.TexCoord4f( 1, u1_r, v1_t, 0, 0 );
  376. meshBuilder.TexCoord4f( 2, u2_r, v2_t, 0, 0 );
  377. meshBuilder.TexCoord4f( 3, u1_r, v1_t, 0, 0 );
  378. meshBuilder.TexCoord4f( 4, u2_r, v2_t, 0, 0 );
  379. meshBuilder.TexCoord4f( 5, u1_r, v1_t, 0, 0 );
  380. meshBuilder.TexCoord4f( 6, u2_r, v2_t, 0, 0 );
  381. meshBuilder.TexCoord4f( 7, u1_r, v1_t, 0, 0 );
  382. meshBuilder.TangentS3fv( vecTangentS.Base() );
  383. meshBuilder.TangentT3fv( vecTangentT.Base() );
  384. meshBuilder.BoneWeight( 0, 1.0f );
  385. meshBuilder.BoneMatrix( 0, 0 );
  386. meshBuilder.UserData( vecTangentS.Base() );
  387. meshBuilder.AdvanceVertex();
  388. meshBuilder.Position3f( x2, y, 0.0f );
  389. meshBuilder.Normal3fv( vecNormal.Base() );
  390. if ( m_bPreviewVertexColors )
  391. {
  392. meshBuilder.Color4ub( 0, 255, 0, 64 );
  393. }
  394. else
  395. {
  396. meshBuilder.Color4ub( 255, 255, 255, 255 );
  397. }
  398. meshBuilder.TexCoord4f( 0, 1.0f - u, 1.0f - v, 0, 0 );
  399. meshBuilder.TexCoord4f( 1, u1_r, v1_b, 0, 0 );
  400. meshBuilder.TexCoord4f( 2, u2_r, v2_b, 0, 0 );
  401. meshBuilder.TexCoord4f( 3, u1_r, v1_b, 0, 0 );
  402. meshBuilder.TexCoord4f( 4, u2_r, v2_b, 0, 0 );
  403. meshBuilder.TexCoord4f( 5, u1_r, v1_b, 0, 0 );
  404. meshBuilder.TexCoord4f( 6, u2_r, v2_b, 0, 0 );
  405. meshBuilder.TexCoord4f( 7, u1_r, v1_b, 0, 0 );
  406. meshBuilder.TangentS3fv( vecTangentS.Base() );
  407. meshBuilder.TangentT3fv( vecTangentT.Base() );
  408. meshBuilder.BoneWeight( 0, 1.0f );
  409. meshBuilder.BoneMatrix( 0, 0 );
  410. meshBuilder.UserData( vecTangentS.Base() );
  411. meshBuilder.AdvanceVertex();
  412. meshBuilder.FastIndex( 0 );
  413. meshBuilder.FastIndex( 1 );
  414. meshBuilder.FastIndex( 2 );
  415. meshBuilder.FastIndex( 3 );
  416. meshBuilder.End();
  417. pMesh->Draw();
  418. }
  419. //-----------------------------------------------------------------------------
  420. // Paints a cubemap texture
  421. //-----------------------------------------------------------------------------
  422. void CVMTPreviewPanel::DrawSphere( void )
  423. {
  424. float flNewTime = Plat_FloatTime();
  425. // Circle the camera around the origin
  426. VMatrix rot;
  427. MatrixBuildRotateZ( rot, ROTATION_SPEED * (flNewTime - m_flLastRotationTime ) );
  428. Vector vecTemp;
  429. Vector3DMultiply( rot, m_vecCameraDirection, vecTemp );
  430. m_vecCameraDirection = vecTemp;
  431. m_flLastRotationTime = flNewTime;
  432. int w, h;
  433. GetSize( w, h );
  434. SetupProjectionMatrix( w, h );
  435. SetupLightingState();
  436. LookAt( vec3_origin, VIEW_DISTANCE );
  437. // Draw a sphere at the origin
  438. // RenderSphere( vec3_origin, 10.0f, 20, 20 );
  439. if ( m_pMaterialSheet && m_pMaterialSheet->ValidSheetData() )
  440. {
  441. RenderSheet( vec3_origin, 10.0f );
  442. }
  443. else
  444. {
  445. RenderSphere( vec3_origin, 10.0f, 20, 20 );
  446. }
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Sets the camera to look at the the thing we're spinning around
  450. //-----------------------------------------------------------------------------
  451. void CVMTPreviewPanel::LookAt( const Vector &vecLookAt, float flRadius )
  452. {
  453. // Compute the distance to the camera for the object based on its
  454. // radius and fov.
  455. // since tan( fov/2 ) = f/d
  456. // cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
  457. // d/f = r'/d' where d' is distance of camera to sphere
  458. // d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
  459. float flFOVx = FOV;
  460. // Compute fov/2 in radians
  461. flFOVx *= M_PI / 360.0f;
  462. // Compute an effective fov based on the aspect ratio
  463. // if the height is smaller than the width
  464. int w, h;
  465. GetSize( w, h );
  466. if ( h < w )
  467. {
  468. flFOVx = atan( h * tan( flFOVx ) / w );
  469. }
  470. float flDistance = flRadius / sin( flFOVx );
  471. Vector vecMDLOrigin = vecLookAt;
  472. Vector vecCameraOrigin;
  473. VectorMA( vecMDLOrigin, -flDistance, m_vecCameraDirection, vecCameraOrigin );
  474. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  475. QAngle angles;
  476. VectorAngles( m_vecCameraDirection, angles );
  477. pRenderContext->MatrixMode( MATERIAL_VIEW );
  478. pRenderContext->LoadIdentity();
  479. // convert from a right handed system to a left handed system
  480. // since dx for wants it that way.
  481. // pRenderContext->Scale( 1.0f, 1.0f, -1.0f );
  482. pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
  483. pRenderContext->Rotate( 90, 0, 0, 1 ); // put Z going up
  484. pRenderContext->Rotate( -angles[2], 1, 0, 0 );
  485. pRenderContext->Rotate( -angles[0], 0, 1, 0 );
  486. pRenderContext->Rotate( -angles[1], 0, 0, 1 );
  487. pRenderContext->Translate( -vecCameraOrigin[0], -vecCameraOrigin[1], -vecCameraOrigin[2] );
  488. }
  489. //-----------------------------------------------------------------------------
  490. // Set up a projection matrix for a 90 degree fov
  491. //-----------------------------------------------------------------------------
  492. void CVMTPreviewPanel::SetupProjectionMatrix( int nWidth, int nHeight )
  493. {
  494. VMatrix proj;
  495. float flFOV = FOV;
  496. float flZNear = ZNEAR;
  497. float flZFar = ZFAR;
  498. float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
  499. float halfWidth = tan( flFOV * M_PI / 360.0 );
  500. float halfHeight = halfWidth / flApsectRatio;
  501. memset( proj.Base(), 0, sizeof( proj ) );
  502. proj[0][0] = 1.0f / halfWidth;
  503. proj[1][1] = 1.0f / halfHeight;
  504. proj[2][2] = flZFar / ( flZNear - flZFar );
  505. proj[3][2] = -1.0f;
  506. proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
  507. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  508. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  509. pRenderContext->LoadMatrix( proj );
  510. }
  511. //-----------------------------------------------------------------------------
  512. // Set up a orthographic projection matrix
  513. //-----------------------------------------------------------------------------
  514. void CVMTPreviewPanel::SetupOrthoMatrix( int nWidth, int nHeight )
  515. {
  516. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  517. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  518. pRenderContext->LoadIdentity();
  519. pRenderContext->Ortho( 0, 0, nWidth, nHeight, -1.0f, 1.0f );
  520. }
  521. //-----------------------------------------------------------------------------
  522. // Power of two FB texture
  523. //-----------------------------------------------------------------------------
  524. static CTextureReference s_pPowerOfTwoFrameBufferTexture;
  525. static ITexture *GetPowerOfTwoFrameBufferTexture( void )
  526. {
  527. if ( !s_pPowerOfTwoFrameBufferTexture )
  528. {
  529. s_pPowerOfTwoFrameBufferTexture.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
  530. }
  531. return s_pPowerOfTwoFrameBufferTexture;
  532. }
  533. //-----------------------------------------------------------------------------
  534. // Paints the texture
  535. //-----------------------------------------------------------------------------
  536. void CVMTPreviewPanel::Paint( void )
  537. {
  538. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  539. int w, h;
  540. GetSize( w, h );
  541. vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h );
  542. // Deal with refraction
  543. if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
  544. {
  545. ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
  546. if ( pTexture && !pTexture->IsError() )
  547. {
  548. pRenderContext->CopyRenderTargetToTexture( pTexture );
  549. pRenderContext->SetFrameBufferCopyTexture( pTexture );
  550. }
  551. }
  552. pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
  553. pRenderContext->ClearBuffers( true, true );
  554. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  555. pRenderContext->SetNumBoneWeights( 0 );
  556. pRenderContext->Bind( m_Material );
  557. pRenderContext->BindLightmapTexture( m_pLightmapTexture );
  558. pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
  559. if ( m_bDrawIn3DMode )
  560. {
  561. DrawSphere();
  562. }
  563. else
  564. {
  565. DrawRectangle();
  566. }
  567. vgui::MatSystemSurface()->End3DPaint( );
  568. }
  569. bool CVMTPreviewPanel::VMTUsesSheets()
  570. {
  571. return m_pMaterialSheet != NULL;
  572. }
  573. int CVMTPreviewPanel::GetSheetSequenceCount()
  574. {
  575. if ( m_pMaterialSheet == NULL )
  576. {
  577. return 0;
  578. }
  579. return m_pMaterialSheet->GetSheetSequenceCount();
  580. }
  581. // TODO: sort this out - sequence #n != nth sequence
  582. int CVMTPreviewPanel::GetCurrentSequence()
  583. {
  584. return m_nCurrentSheetSequence;
  585. }
  586. int CVMTPreviewPanel::GetCurrentSecondarySequence()
  587. {
  588. return m_nCurrentSecondarySheetSequence;
  589. }
  590. int CVMTPreviewPanel::GetRealSequenceNumber()
  591. {
  592. return m_nCurrentSheetSequence;
  593. }
  594. void CVMTPreviewPanel::SetSheetSequence( int nSequence )
  595. {
  596. if ( m_pMaterialSheet == NULL )
  597. {
  598. return;
  599. }
  600. m_nCurrentSheetSequence = m_pMaterialSheet->GetNthSequenceIndex(nSequence);
  601. }
  602. void CVMTPreviewPanel::SetSecondarySheetSequence( int nSequence )
  603. {
  604. if ( m_pMaterialSheet == NULL )
  605. {
  606. return;
  607. }
  608. m_nCurrentSecondarySheetSequence = m_pMaterialSheet->GetNthSequenceIndex(nSequence);
  609. }