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.

624 lines
18 KiB

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