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.

462 lines
13 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "matsys_controls/vmtpanel.h"
  8. #include "materialsystem/imesh.h"
  9. #include "materialsystem/imaterial.h"
  10. #include "materialsystem/itexture.h"
  11. #include "VGuiMatSurface/IMatSystemSurface.h"
  12. #include "vgui_controls/ScrollBar.h"
  13. #include "matsys_controls/matsyscontrols.h"
  14. #include "vgui/IVGui.h"
  15. #include "vgui_controls/ToolWindow.h"
  16. #include "tier2/renderutils.h"
  17. // NOTE: This has to be the last file included!
  18. #include "tier0/memdbgon.h"
  19. using namespace vgui;
  20. //-----------------------------------------------------------------------------
  21. // Enums
  22. //-----------------------------------------------------------------------------
  23. enum
  24. {
  25. SCROLLBAR_SIZE=18, // the width of a scrollbar
  26. WINDOW_BORDER_WIDTH=2 // the width of the window's border
  27. };
  28. #define SPHERE_RADIUS 10.0f
  29. //-----------------------------------------------------------------------------
  30. // Constructor, destructor
  31. //-----------------------------------------------------------------------------
  32. CVMTPanel::CVMTPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  33. {
  34. m_bUseActualSize = true;
  35. m_pMaterial = NULL;
  36. m_pHorizontalBar = new ScrollBar( this, "HorizScrollBar", false );
  37. m_pHorizontalBar->AddActionSignalTarget(this);
  38. m_pHorizontalBar->SetVisible(false);
  39. m_pVerticalBar = new ScrollBar( this, "VertScrollBar", true );
  40. m_pVerticalBar->AddActionSignalTarget(this);
  41. m_pVerticalBar->SetVisible(false);
  42. LookAt( SPHERE_RADIUS );
  43. m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
  44. m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
  45. }
  46. CVMTPanel::~CVMTPanel()
  47. {
  48. m_pLightmapTexture.Shutdown();
  49. m_DefaultEnvCubemap.Shutdown();
  50. if (m_pMaterial)
  51. {
  52. m_pMaterial->DecrementReferenceCount();
  53. }
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Scheme
  57. //-----------------------------------------------------------------------------
  58. void CVMTPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  59. {
  60. BaseClass::ApplySchemeSettings( pScheme );
  61. SetBorder( pScheme->GetBorder( "MenuBorder") );
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Set the material to draw
  65. //-----------------------------------------------------------------------------
  66. void CVMTPanel::SetMaterial( IMaterial *pMaterial )
  67. {
  68. if (pMaterial)
  69. {
  70. pMaterial->IncrementReferenceCount();
  71. }
  72. if (m_pMaterial)
  73. {
  74. m_pMaterial->DecrementReferenceCount();
  75. }
  76. m_pMaterial = pMaterial;
  77. InvalidateLayout();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Set rendering mode (stretch to full screen, or use actual size)
  81. //-----------------------------------------------------------------------------
  82. void CVMTPanel::RenderUsingActualSize( bool bEnable )
  83. {
  84. m_bUseActualSize = bEnable;
  85. InvalidateLayout();
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose: relayouts out the panel after any internal changes
  89. //-----------------------------------------------------------------------------
  90. void CVMTPanel::PerformLayout()
  91. {
  92. BaseClass::PerformLayout();
  93. return;
  94. // Get the current size, see if it's big enough to view the entire thing
  95. int iWidth, iHeight;
  96. GetSize( iWidth, iHeight );
  97. // In the case of stretching, just stretch to the size and blow off
  98. // the scrollbars. Same holds true if there's no material
  99. if (!m_bUseActualSize || !m_pMaterial)
  100. {
  101. m_iViewableWidth = iWidth;
  102. m_iViewableHeight = iHeight;
  103. m_pHorizontalBar->SetVisible(false);
  104. m_pVerticalBar->SetVisible(false);
  105. return;
  106. }
  107. // Check the size of the material...
  108. int iMaterialWidth = m_pMaterial->GetMappingWidth();
  109. int iMaterialHeight = m_pMaterial->GetMappingHeight();
  110. // Check if the scroll bars are visible
  111. bool bHorizScrollVisible = (iMaterialWidth > iWidth);
  112. bool bVertScrollVisible = (iMaterialHeight > iHeight);
  113. m_pHorizontalBar->SetVisible(bHorizScrollVisible);
  114. m_pVerticalBar->SetVisible(bVertScrollVisible);
  115. // Shrink the bars if both are visible
  116. m_iViewableWidth = bVertScrollVisible ? iWidth - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iWidth;
  117. m_iViewableHeight = bHorizScrollVisible ? iHeight - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iHeight;
  118. // Set the position of the horizontal bar...
  119. if (bHorizScrollVisible)
  120. {
  121. m_pHorizontalBar->SetPos(0, iHeight - SCROLLBAR_SIZE);
  122. m_pHorizontalBar->SetSize( m_iViewableWidth, SCROLLBAR_SIZE );
  123. m_pHorizontalBar->SetRangeWindow( m_iViewableWidth );
  124. m_pHorizontalBar->SetRange( 0, iMaterialWidth );
  125. // FIXME: Change scroll amount based on how much is not visible?
  126. m_pHorizontalBar->SetButtonPressedScrollValue( 5 );
  127. }
  128. // Set the position of the vertical bar...
  129. if (bVertScrollVisible)
  130. {
  131. m_pVerticalBar->SetPos(iWidth - SCROLLBAR_SIZE, 0);
  132. m_pVerticalBar->SetSize(SCROLLBAR_SIZE, m_iViewableHeight);
  133. m_pVerticalBar->SetRangeWindow( m_iViewableHeight );
  134. m_pVerticalBar->SetRange( 0, iMaterialHeight);
  135. m_pVerticalBar->SetButtonPressedScrollValue( 5 );
  136. }
  137. }
  138. //-----------------------------------------------------------------------------
  139. // paint it stretched to the window size
  140. //-----------------------------------------------------------------------------
  141. void CVMTPanel::DrawStretchedToPanel( CMeshBuilder &meshBuilder )
  142. {
  143. // Draw a polygon the size of the panel
  144. meshBuilder.Color4ub( 255, 255, 255, 255 );
  145. meshBuilder.Position3f( 0, 0, 0 );
  146. meshBuilder.TexCoord2f( 0, 0, 0 );
  147. meshBuilder.AdvanceVertex();
  148. meshBuilder.Color4ub( 255, 255, 255, 255 );
  149. meshBuilder.Position3f( 0, m_iViewableHeight, 0 );
  150. meshBuilder.TexCoord2f( 0, 0, 1 );
  151. meshBuilder.AdvanceVertex();
  152. meshBuilder.Color4ub( 255, 255, 255, 255 );
  153. meshBuilder.Position3f( m_iViewableWidth, m_iViewableHeight, 0 );
  154. meshBuilder.TexCoord2f( 0, 1, 1 );
  155. meshBuilder.AdvanceVertex();
  156. meshBuilder.Color4ub( 255, 255, 255, 255 );
  157. meshBuilder.Position3f( m_iViewableWidth, 0, 0 );
  158. meshBuilder.TexCoord2f( 0, 0, 1 );
  159. meshBuilder.AdvanceVertex();
  160. }
  161. //-----------------------------------------------------------------------------
  162. // paint it actual size
  163. //-----------------------------------------------------------------------------
  164. void CVMTPanel::DrawActualSize( CMeshBuilder &meshBuilder )
  165. {
  166. // Check the size of the material...
  167. int iMaterialWidth = m_pMaterial->GetMappingWidth();
  168. int iMaterialHeight = m_pMaterial->GetMappingHeight();
  169. Vector2D ul;
  170. Vector2D lr;
  171. Vector2D tul;
  172. Vector2D tlr;
  173. if (m_iViewableWidth >= iMaterialWidth)
  174. {
  175. // Center the material if we've got enough horizontal space
  176. ul.x = (m_iViewableWidth - iMaterialWidth) * 0.5f;
  177. lr.x = ul.x + iMaterialWidth;
  178. tul.x = 0.0f; tlr.x = 1.0f;
  179. }
  180. else
  181. {
  182. // Use the scrollbars here...
  183. int val = m_pHorizontalBar->GetValue();
  184. tul.x = (float)val / (float)iMaterialWidth;
  185. tlr.x = tul.x + (float)m_iViewableWidth / (float)iMaterialWidth;
  186. ul.x = 0;
  187. lr.x = m_iViewableWidth;
  188. }
  189. if (m_iViewableHeight >= iMaterialHeight)
  190. {
  191. // Center the material if we've got enough vertical space
  192. ul.y = (m_iViewableHeight - iMaterialHeight) * 0.5f;
  193. lr.y = ul.y + iMaterialHeight;
  194. tul.y = 0.0f; tlr.y = 1.0f;
  195. }
  196. else
  197. {
  198. // Use the scrollbars here...
  199. int val = m_pVerticalBar->GetValue();
  200. tul.y = (float)val / (float)iMaterialHeight;
  201. tlr.y = tul.y + (float)m_iViewableHeight / (float)iMaterialHeight;
  202. ul.y = 0;
  203. lr.y = m_iViewableHeight;
  204. }
  205. meshBuilder.Color4ub( 255, 255, 255, 255 );
  206. meshBuilder.Position3f( ul.x, ul.y, 0 );
  207. meshBuilder.TexCoord2f( 0, tul.x, tul.y );
  208. meshBuilder.AdvanceVertex();
  209. meshBuilder.Color4ub( 255, 255, 255, 255 );
  210. meshBuilder.Position3f( lr.x, ul.y, 0 );
  211. meshBuilder.TexCoord2f( 0, tlr.x, tul.y );
  212. meshBuilder.AdvanceVertex();
  213. meshBuilder.Color4ub( 255, 255, 255, 255 );
  214. meshBuilder.Position3f( lr.x, lr.y, 0 );
  215. meshBuilder.TexCoord2f( 0, tlr.x, tlr.y );
  216. meshBuilder.AdvanceVertex();
  217. meshBuilder.Color4ub( 255, 255, 255, 255 );
  218. meshBuilder.Position3f( ul.x, lr.y, 0 );
  219. meshBuilder.TexCoord2f( 0, tul.x, tlr.y );
  220. meshBuilder.AdvanceVertex();
  221. }
  222. //-----------------------------------------------------------------------------
  223. // Draw it on a sphere
  224. //-----------------------------------------------------------------------------
  225. void CVMTPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
  226. {
  227. int nVertices = nTheta * nPhi;
  228. int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
  229. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  230. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  231. pRenderContext->SetNumBoneWeights( 0 );
  232. pRenderContext->Bind( m_pMaterial );
  233. pRenderContext->BindLightmapTexture( m_pLightmapTexture );
  234. pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
  235. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  236. CMeshBuilder meshBuilder;
  237. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
  238. bool bIsUsingLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
  239. bool bIsUsingBumpedLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
  240. int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
  241. float flHalfLuxel = 0.5f / nLightmapWidth;
  242. //
  243. // Build the index buffer.
  244. //
  245. int i, j;
  246. for ( i = 0; i < nPhi; ++i )
  247. {
  248. for ( j = 0; j < nTheta; ++j )
  249. {
  250. float u = j / ( float )(nTheta - 1);
  251. float v = i / ( float )(nPhi - 1);
  252. float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
  253. float phi = M_PI * v;
  254. Vector vecPos;
  255. vecPos.x = flRadius * sin(phi) * cos(theta);
  256. vecPos.y = flRadius * sin(phi) * sin(theta);
  257. vecPos.z = flRadius * cos(phi);
  258. Vector vecNormal = vecPos;
  259. VectorNormalize( vecNormal );
  260. Vector4D vecTangentS;
  261. Vector vecTangentT;
  262. vecTangentS.Init( -vecPos.y, vecPos.x, 0.0f, 1.0f );
  263. if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
  264. {
  265. vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
  266. }
  267. CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
  268. unsigned char red = (int)( u * 255.0f );
  269. unsigned char green = (int)( v * 255.0f );
  270. unsigned char blue = (int)( v * 255.0f );
  271. unsigned char alpha = (int)( v * 255.0f );
  272. vecPos += vCenter;
  273. float u1, u2, v1, v2;
  274. u1 = u2 = u;
  275. v1 = v2 = v;
  276. if ( bIsUsingLightmap )
  277. {
  278. u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
  279. if ( bIsUsingBumpedLightmap )
  280. {
  281. u2 = 0.25f;
  282. v2 = 0.0f;
  283. }
  284. }
  285. meshBuilder.Position3fv( vecPos.Base() );
  286. meshBuilder.Normal3fv( vecNormal.Base() );
  287. meshBuilder.Color4ub( red, green, blue, alpha );
  288. meshBuilder.TexCoord2f( 0, u, v );
  289. meshBuilder.TexCoord2f( 1, u1, v1 );
  290. meshBuilder.TexCoord2f( 2, u2, v2 );
  291. meshBuilder.TangentS3fv( vecTangentS.Base() );
  292. meshBuilder.TangentT3fv( vecTangentT.Base() );
  293. meshBuilder.UserData( vecTangentS.Base() );
  294. meshBuilder.AdvanceVertex();
  295. }
  296. }
  297. //
  298. // Emit the triangle strips.
  299. //
  300. int idx = 0;
  301. for ( i = 0; i < nPhi - 1; ++i )
  302. {
  303. for ( j = 0; j < nTheta; ++j )
  304. {
  305. idx = nTheta * i + j;
  306. meshBuilder.FastIndex( idx );
  307. meshBuilder.FastIndex( idx + nTheta );
  308. }
  309. //
  310. // Emit a degenerate triangle to skip to the next row without
  311. // a connecting triangle.
  312. //
  313. if ( i < nPhi - 2 )
  314. {
  315. meshBuilder.FastIndex( idx + 1 );
  316. meshBuilder.FastIndex( idx + 1 + nTheta );
  317. }
  318. }
  319. meshBuilder.End();
  320. pMesh->Draw();
  321. }
  322. //-----------------------------------------------------------------------------
  323. // Power of two FB texture
  324. //-----------------------------------------------------------------------------
  325. static CTextureReference s_pPowerOfTwoFrameBufferTexture;
  326. static ITexture *GetPowerOfTwoFrameBufferTexture( void )
  327. {
  328. if( !s_pPowerOfTwoFrameBufferTexture )
  329. {
  330. s_pPowerOfTwoFrameBufferTexture.Init( materials->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
  331. }
  332. return s_pPowerOfTwoFrameBufferTexture;
  333. }
  334. //-----------------------------------------------------------------------------
  335. // paint it!
  336. //-----------------------------------------------------------------------------
  337. void CVMTPanel::OnPaint3D()
  338. {
  339. if (!m_pMaterial)
  340. return;
  341. // Deal with refraction
  342. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  343. if ( m_pMaterial->NeedsPowerOfTwoFrameBufferTexture() )
  344. {
  345. ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
  346. if ( pTexture && !pTexture->IsError() )
  347. {
  348. pRenderContext->CopyRenderTargetToTexture( pTexture );
  349. pRenderContext->SetFrameBufferCopyTexture( pTexture );
  350. }
  351. }
  352. // Draw a background (translucent objects will appear that way)
  353. // FIXME: Draw the outline of this panel?
  354. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  355. RenderSphere( vec3_origin, SPHERE_RADIUS, 20, 20 );
  356. /*
  357. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  358. pRenderContext->LoadIdentity();
  359. pRenderContext->Ortho( 0, 0, m_iViewableWidth, m_iViewableHeight, 0, 1 );
  360. pRenderContext->Bind( m_pMaterial );
  361. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  362. CMeshBuilder meshBuilder;
  363. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  364. if (!m_bUseActualSize)
  365. {
  366. DrawStretchedToPanel( meshBuilder );
  367. }
  368. else
  369. {
  370. DrawActualSize( meshBuilder );
  371. }
  372. meshBuilder.End();
  373. pMesh->Draw();
  374. */
  375. }