home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / samples / multimedia / direct3d / mfcpixelshader / pixelshader.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  25.2 KB  |  788 lines

  1. //-----------------------------------------------------------------------------
  2. // File: PixelShader.cpp
  3. //
  4. // Desc: Example code showing how to use pixel shaders in D3D
  5. //
  6. // Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include "stdafx.h"
  10. #include <tchar.h>
  11. #include <math.h>
  12. #include <time.h>
  13. #include <stdio.h>
  14. #include <D3DX8.h>
  15. #include "resource.h"
  16. #include "D3DApp.h"
  17. #include "D3DUtil.h"
  18. #include "DXUtil.h"
  19. #include "PixelShader.h"
  20.  
  21.  
  22.  
  23.  
  24. //-----------------------------------------------------------------------------
  25. // Global data and objects
  26. //-----------------------------------------------------------------------------
  27. CApp          g_App;
  28. CAppForm*     g_AppFormView = NULL;
  29. TCHAR*        g_strAppTitle = _T("MFCPixelShader");
  30.  
  31.  
  32.  
  33.  
  34. //-----------------------------------------------------------------------------
  35. // The MFC macros are all listed here
  36. //-----------------------------------------------------------------------------
  37. IMPLEMENT_DYNCREATE( CAppDoc,      CDocument )
  38. IMPLEMENT_DYNCREATE( CAppFrameWnd, CFrameWnd )
  39. IMPLEMENT_DYNCREATE( CAppForm,     CFormView )
  40.  
  41.  
  42. BEGIN_MESSAGE_MAP( CApp, CWinApp )
  43.     //{{AFX_MSG_MAP(CD3DApp)
  44.     //}}AFX_MSG_MAP
  45. END_MESSAGE_MAP()
  46.  
  47.  
  48. BEGIN_MESSAGE_MAP( CAppForm, CFormView )
  49.     //{{AFX_MSG_MAP(CAppForm)
  50.     ON_WM_HSCROLL()
  51.     ON_COMMAND(    IDC_VIEWFULLSCREEN,       OnToggleFullScreen )
  52.     ON_COMMAND(    IDM_CHANGEDEVICE,         OnChangeDevice )
  53.     ON_BN_CLICKED( IDC_OPEN,                 OnOpenPixelShaderFile )
  54.     ON_BN_CLICKED( IDC_PRESET_0,             OnPresets )
  55.     ON_BN_CLICKED( IDC_PRESET_1,             OnPresets )
  56.     ON_BN_CLICKED( IDC_PRESET_2,             OnPresets )
  57.     ON_BN_CLICKED( IDC_PRESET_3,             OnPresets )
  58.     ON_BN_CLICKED( IDC_PRESET_4,             OnPresets )
  59.     ON_BN_CLICKED( IDC_PRESET_5,             OnPresets )
  60.     ON_EN_CHANGE(  IDC_INSTRUCTIONS,         OnChangeInstructions )
  61.     //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63.  
  64.  
  65.  
  66.  
  67.  
  68. //-----------------------------------------------------------------------------
  69. // Function prototypes and global (or static) variables
  70. //-----------------------------------------------------------------------------
  71. struct CUSTOMVERTEX
  72. {
  73.     FLOAT x, y, z;
  74.     DWORD color1, color2;
  75.     FLOAT tu1, tv1;
  76.     FLOAT tu2, tv2;
  77. };
  78.  
  79. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2)
  80.  
  81. static CUSTOMVERTEX g_Vertices[]=
  82. {
  83.     // Color 0 (diffuse) is a color gradient
  84.     // Color 1 (specular) is a greyscale ramp
  85.     //  x      y     z     diffuse     specular    u1    v1    u2    v2
  86.     { -1.0f, -1.0f, 0.0f, 0xff00ffff, 0xffffffff, 1.0f, 1.0f, 1.0f, 1.0f },
  87.     { +1.0f, -1.0f, 0.0f, 0xffffff00, 0xffffffff, 0.0f, 1.0f, 0.0f, 1.0f },
  88.     { +1.0f, +1.0f, 0.0f, 0xffff0000, 0xff000000, 0.0f, 0.0f, 0.0f, 0.0f },
  89.     { -1.0f, +1.0f, 0.0f, 0xff0000ff, 0xff000000, 1.0f, 0.0f, 1.0f, 0.0f },
  90. };
  91.  
  92. inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
  93.  
  94.  
  95.  
  96. //-----------------------------------------------------------------------------
  97. // Name: AdjustWindowForChange()
  98. // Desc: Adjusts the window properties for windowed or fullscreen mode
  99. //-----------------------------------------------------------------------------
  100. HRESULT CAppForm::AdjustWindowForChange()
  101. {
  102.     if( m_bWindowed )
  103.     {
  104.         ::ShowWindow( m_hwndRenderFullScreen, SW_HIDE );
  105.         CD3DApplication::m_hWnd = m_hwndRenderWindow;
  106.     }
  107.     else
  108.     {
  109.         if( ::IsIconic( m_hwndRenderFullScreen ) )
  110.             ::ShowWindow( m_hwndRenderFullScreen, SW_RESTORE );
  111.         ::ShowWindow( m_hwndRenderFullScreen, SW_SHOW );
  112.         CD3DApplication::m_hWnd = m_hwndRenderFullScreen;
  113.     }
  114.     return S_OK;
  115. }
  116.  
  117.  
  118.  
  119.  
  120. //-----------------------------------------------------------------------------
  121. // Name: FullScreenWndProc()
  122. // Desc: The WndProc funtion used when the app is in fullscreen mode. This is
  123. //       needed simply to trap the ESC key.
  124. //-----------------------------------------------------------------------------
  125. LRESULT CALLBACK FullScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam,
  126.                                     LPARAM lParam )
  127. {
  128.     if( msg == WM_CLOSE )
  129.     {
  130.         // User wants to exit, so go back to windowed mode and exit for real
  131.         g_AppFormView->OnToggleFullScreen();
  132.         g_App.GetMainWnd()->PostMessage( WM_CLOSE, 0, 0 );
  133.     }
  134.  
  135.     if( msg == WM_SETCURSOR )
  136.     {
  137.         SetCursor( NULL );
  138.     }
  139.  
  140.     if( msg == WM_KEYUP && wParam == VK_ESCAPE )
  141.     {
  142.         // User wants to leave fullscreen mode
  143.         g_AppFormView->OnToggleFullScreen();
  144.     }
  145.  
  146.     return DefWindowProc( hWnd, msg, wParam, lParam );
  147. }
  148.  
  149.  
  150.  
  151.  
  152. //-----------------------------------------------------------------------------
  153. // Name: CheckForLostFullscreen()
  154. // Desc: If fullscreen and device was lost (probably due to alt-tab), 
  155. //       automatically switch to windowed mode
  156. //-----------------------------------------------------------------------------
  157. HRESULT CAppForm::CheckForLostFullscreen()
  158. {
  159.     HRESULT hr;
  160.  
  161.     if( m_bWindowed )
  162.         return S_OK;
  163.  
  164.     if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
  165.         ForceWindowed();
  166.  
  167.     return S_OK;
  168. }
  169.  
  170.  
  171.  
  172.  
  173. //-----------------------------------------------------------------------------
  174. // Name: PreCreateWindow()
  175. // Desc: Change the window style (so it cannot maximize or be sized) before
  176. //       the main frame window is created.
  177. //-----------------------------------------------------------------------------
  178. BOOL CAppFrameWnd::PreCreateWindow( CREATESTRUCT& cs )
  179. {
  180.     cs.style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
  181.  
  182.     return CFrameWnd::PreCreateWindow( cs );
  183. }
  184.  
  185.  
  186.  
  187.  
  188. //-----------------------------------------------------------------------------
  189. // Name: InitInstance()
  190. // Desc: This is the main entry point for the application. The MFC window stuff
  191. //       is initialized here. See also the main initialization routine for the
  192. //       CAppForm class, which is called indirectly from here.
  193. //-----------------------------------------------------------------------------
  194. BOOL CApp::InitInstance()
  195. {
  196.     // Asscociate the MFC app with the frame window and doc/view classes
  197.     AddDocTemplate( new CSingleDocTemplate( IDR_MAINFRAME, 
  198.                                             RUNTIME_CLASS(CAppDoc),
  199.                                             RUNTIME_CLASS(CAppFrameWnd),
  200.                                             RUNTIME_CLASS(CAppForm) ) );
  201.  
  202.     // Dispatch commands specified on the command line (req'd by MFC). This
  203.     // also initializes the the CAppDoc, CAppFrameWnd, and CAppForm classes.
  204.     CCommandLineInfo cmdInfo;
  205.     ParseCommandLine( cmdInfo );
  206.     if( !ProcessShellCommand( cmdInfo ) )
  207.         return FALSE;
  208.  
  209.     if( !g_AppFormView->IsReady() )
  210.         return FALSE;
  211.  
  212.     // The formview window has been initialized, so show and update it.
  213.     m_pMainWnd->MoveWindow( 4, 4, 634, 442, TRUE );
  214.     m_pMainWnd->SetWindowText( g_strAppTitle );
  215.     m_pMainWnd->UpdateWindow();
  216.  
  217.     return TRUE;
  218. }
  219.  
  220.  
  221.  
  222.  
  223. //-----------------------------------------------------------------------------
  224. // Name: OnIdle()
  225. // Desc: Uses idle time to render the 3D scene.
  226. //-----------------------------------------------------------------------------
  227. BOOL CApp::OnIdle( LONG )
  228. {
  229.     // Do not render if the app is minimized
  230.     if( m_pMainWnd->IsIconic() )
  231.         return FALSE;
  232.  
  233.     // Update and render a frame
  234.     if( g_AppFormView->IsReady() )
  235.     {
  236.         g_AppFormView->CheckForLostFullscreen();
  237.         g_AppFormView->RenderScene();
  238.     }
  239.  
  240.     // Keep requesting more idle time
  241.     return TRUE;
  242. }
  243.  
  244.  
  245.  
  246.  
  247. //-----------------------------------------------------------------------------
  248. // Name: CAppForm()
  249. // Desc: Constructor for the dialog resource form
  250. //-----------------------------------------------------------------------------
  251. CAppForm::CAppForm()
  252.          :CFormView( IDD_FORMVIEW )
  253. {
  254.     g_AppFormView     = this;
  255.  
  256.     m_pTexture0       = NULL;
  257.     m_pTexture1       = NULL;
  258.     m_pQuadVB         = NULL;
  259.     m_hPixelShader    = NULL;
  260.     m_pD3DXBufShader  = NULL;
  261. }
  262.  
  263.  
  264.  
  265.  
  266. //-----------------------------------------------------------------------------
  267. // Name: ~CAppForm()
  268. // Desc: Destructor for the dialog resource form. Shuts down the app
  269. //-----------------------------------------------------------------------------
  270. CAppForm::~CAppForm()
  271. {
  272.     Cleanup3DEnvironment();
  273. }
  274.  
  275.  
  276.  
  277.  
  278. //-----------------------------------------------------------------------------
  279. // Name: OnInitialUpdate()
  280. // Desc: When the AppForm object is created, this function is called to
  281. //       initialize it. Here we getting access ptrs to some of the controls,
  282. //       and setting the initial state of some of them as well.
  283. //-----------------------------------------------------------------------------
  284. VOID CAppForm::OnInitialUpdate()
  285. {
  286.     CFormView::OnInitialUpdate();
  287.  
  288.     // Save static reference to the render window
  289.     m_hwndRenderWindow = GetDlgItem(IDC_RENDERVIEW)->GetSafeHwnd();
  290.  
  291.     // Register a class for a fullscreen window
  292.     WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, FullScreenWndProc, 0, 0, NULL,
  293.                           NULL, NULL, (HBRUSH)GetStockObject(WHITE_BRUSH), NULL,
  294.                           _T("Fullscreen Window") };
  295.     RegisterClass( &wndClass );
  296.  
  297.     // We create the fullscreen window (not visible) at startup, so it can
  298.     // be the focus window.  The focus window can only be set at CreateDevice
  299.     // time, not in a Reset, so ToggleFullscreen wouldn't work unless we have
  300.     // already set up the fullscreen focus window.
  301.     m_hwndRenderFullScreen = CreateWindow( _T("Fullscreen Window"), NULL,
  302.                                            WS_POPUP, CW_USEDEFAULT,
  303.                                            CW_USEDEFAULT, 100, 100,
  304.                                            GetTopLevelParent()->GetSafeHwnd(), 0L, NULL, 0L );
  305.  
  306.     // Note that for the MFC samples, the device window and focus window
  307.     // are not the same.
  308.     CD3DApplication::m_hWnd = m_hwndRenderWindow;
  309.     CD3DApplication::m_hWndFocus = m_hwndRenderFullScreen;
  310.     CD3DApplication::Create( AfxGetInstanceHandle() );
  311.  
  312.     // Set up the form's UI
  313.     ((CButton*)GetDlgItem(IDC_PRESET_0))->SetCheck(TRUE);
  314.     OnPresets();
  315. }
  316.  
  317.  
  318.  
  319.  
  320. //-----------------------------------------------------------------------------
  321. // Name: SetPixelShader()
  322. // Desc:
  323. //-----------------------------------------------------------------------------
  324. HRESULT CAppForm::SetPixelShader( TCHAR* strOpcodes )
  325. {
  326.     HRESULT      hr;
  327.     LPD3DXBUFFER pBuffer = NULL;
  328.  
  329.     SAFE_RELEASE( m_pD3DXBufShader );
  330.  
  331.     // Build a DWORD array of opcodes from the text string
  332.     hr = D3DXAssembleShader( strOpcodes, lstrlen(strOpcodes), 0, NULL, 
  333.         &m_pD3DXBufShader, &pBuffer );
  334.     if( FAILED(hr) )
  335.     {
  336.         if( pBuffer != NULL)
  337.         {
  338.             TCHAR* pstr;
  339.             TCHAR strOut[4096];
  340.             TCHAR* pstrOut;
  341.             // Need to replace \n with \r\n so edit box shows newlines properly
  342.             pstr = (TCHAR*)pBuffer->GetBufferPointer();
  343.             strOut[0] = _T('\0');
  344.             pstrOut = strOut;
  345.             for( int i = 0; i < 4096; i++ )
  346.             {
  347.                 if( *pstr == _T('\n') )
  348.                     *pstrOut++ = _T('\r');
  349.                 *pstrOut = *pstr;
  350.                 if( *pstr == _T('\0') )
  351.                     break;
  352.                 if( i == 4095 )
  353.                     *pstrOut = _T('\0');
  354.                 pstrOut++;
  355.                 pstr++;
  356.             }
  357.             // remove any blank lines at the end
  358.             while( strOut[lstrlen(strOut) - 1] == _T('\n') ||
  359.                    strOut[lstrlen(strOut) - 1] == _T('\r') )
  360.             {
  361.                 strOut[lstrlen(strOut) - 1] = _T('\0');
  362.             }
  363.             SetDlgItemText( IDC_COMPRESULT, strOut );
  364.             SAFE_RELEASE( pBuffer );
  365.         }
  366.         return hr;
  367.     }
  368.     else
  369.     {
  370.         SAFE_RELEASE( pBuffer );
  371.         // Delete old pixel shader
  372.         if( m_hPixelShader )
  373.             m_pd3dDevice->DeletePixelShader( m_hPixelShader );
  374.         m_hPixelShader = NULL;
  375.  
  376.         // Create new pixel shader
  377.         hr = m_pd3dDevice->CreatePixelShader( (DWORD*)m_pD3DXBufShader->GetBufferPointer(),
  378.                                               &m_hPixelShader );
  379.  
  380.         if( FAILED(hr) )
  381.         {
  382.             ((CStatic*)GetDlgItem(IDC_COMPRESULT))->SetWindowText( _T("Failure (D3D)"));
  383.             return hr;
  384.         }
  385.         else
  386.         {
  387.             ((CStatic*)GetDlgItem(IDC_COMPRESULT))->SetWindowText( _T("Success"));
  388.         }
  389.     }
  390.  
  391.     return S_OK;
  392. }
  393.  
  394.  
  395.  
  396.  
  397. //-----------------------------------------------------------------------------
  398. // Name: OneTimeSceneInit()
  399. // Desc: Called during initial app startup, this function performs all the
  400. //       permanent initialization.
  401. //-----------------------------------------------------------------------------
  402. HRESULT CAppForm::OneTimeSceneInit()
  403. {
  404.     return S_OK;
  405. }
  406.  
  407.  
  408.  
  409.  
  410. //-----------------------------------------------------------------------------
  411. // Name: FrameMove()
  412. // Desc: Called once per frame, the call is the entry point for animating
  413. //       the scene.
  414. //-----------------------------------------------------------------------------
  415. HRESULT CAppForm::FrameMove()
  416. {
  417.     // Move the camera along an ellipse
  418.     D3DXVECTOR3 from( 3*sinf(m_fTime/3), 3*cosf(m_fTime/3), 5.0f );
  419.     D3DXVECTOR3 at( 0.0f, 0.0f, 0.0f );
  420.     D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f );
  421.  
  422.     D3DXMATRIX matWorld;
  423.     D3DXMatrixIdentity( &matWorld );
  424.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  425.  
  426.     D3DXMATRIX matView;
  427.     D3DXMatrixLookAtLH( &matView, &from, &at, &up );
  428.     m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  429.  
  430.     D3DXMATRIX matProj;
  431.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 0.5f, 1000.0f );
  432.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  433.     return S_OK;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. //-----------------------------------------------------------------------------
  440. // Name: Render()
  441. // Desc: Called once per frame, the call is the entry point for 3d
  442. //       rendering. This function sets up render states, clears the
  443. //       viewport, and renders the scene.
  444. //-----------------------------------------------------------------------------
  445. HRESULT CAppForm::Render()
  446. {
  447.     // Clear the viewport
  448.     m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0L );
  449.  
  450.     // Begin the scene
  451.     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  452.     {
  453.         // Set device state
  454.         m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  455.         m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, FALSE );
  456.         m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  457.         m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,  FALSE );
  458.  
  459.         // Set the textures
  460.         m_pd3dDevice->SetTexture( 0, m_pTexture0 );
  461.         m_pd3dDevice->SetTexture( 1, m_pTexture1 );
  462.  
  463.         // Set the pixel shader constants
  464.         FLOAT fPixelShaderConstants[8][4] =
  465.         { //  Red  Green  Blue  Alpha
  466.             { 1.0f, 0.0f, 0.0f, 1.0f, },  // red
  467.             { 0.0f, 1.0f, 0.0f, 1.0f, },  // green
  468.             { 0.0f, 0.0f, 1.0f, 1.0f, },  // blue
  469.             { 1.0f, 1.0f, 0.0f, 1.0f, },  // yellow
  470.             { 0.0f, 1.0f, 1.0f, 1.0f, },  // cyan
  471.             { 1.0f, 0.0f, 1.0f, 1.0f, },  // purple
  472.             { 1.0f, 1.0f, 1.0f, 1.0f, },  // white
  473.             { 0.0f, 0.0f, 0.0f, 1.0f, },  // black
  474.         };
  475.         m_pd3dDevice->SetPixelShaderConstant( 0, (VOID*)fPixelShaderConstants, 8 );
  476.  
  477.         // Render the quad with the pixel shader
  478.         m_pd3dDevice->SetStreamSource( 0, m_pQuadVB, sizeof(CUSTOMVERTEX) );
  479.         m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
  480.         m_pd3dDevice->SetPixelShader( m_hPixelShader );
  481.         m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
  482.  
  483.         // End the scene.
  484.         m_pd3dDevice->EndScene();
  485.     }
  486.  
  487.     return S_OK;
  488. }
  489.  
  490.  
  491.  
  492.  
  493. //-----------------------------------------------------------------------------
  494. // Name: InitDeviceObjects()
  495. // Desc: Initialize scene objects.
  496. //-----------------------------------------------------------------------------
  497. HRESULT CAppForm::InitDeviceObjects()
  498. {
  499.     HRESULT hr;
  500.  
  501.     // Create some textures
  502.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("DX5_Logo.bmp"),
  503.                                        &m_pTexture0, D3DFMT_R5G6B5 ) ) )
  504.     {
  505.         return E_FAIL;
  506.     }
  507.  
  508.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Tree01S.tga"),
  509.                                        &m_pTexture1, D3DFMT_R5G6B5 ) ) )
  510.     {
  511.         return E_FAIL;
  512.     }
  513.  
  514.     // Create quad VB
  515.     hr = m_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
  516.                                            D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX,
  517.                                            D3DPOOL_MANAGED, &m_pQuadVB );
  518.     if( FAILED(hr) )
  519.         return hr;
  520.  
  521.     return S_OK;
  522. }
  523.  
  524.  
  525.  
  526.  
  527. //-----------------------------------------------------------------------------
  528. // Name: RestoreDeviceObjects()
  529. // Desc:
  530. //-----------------------------------------------------------------------------
  531. HRESULT CAppForm::RestoreDeviceObjects()
  532. {
  533.     HRESULT hr;
  534.  
  535.     // Fill the quad VB
  536.     CUSTOMVERTEX* pVertices = NULL;
  537.     hr = m_pQuadVB->Lock( 0, 4*sizeof(CUSTOMVERTEX), (BYTE**)&pVertices, 0 );
  538.     if( FAILED(hr) )
  539.         return hr;
  540.  
  541.     for( DWORD i=0; i<4; i++ )
  542.         pVertices[i] = g_Vertices[i];
  543.  
  544.     m_pQuadVB->Unlock();
  545.  
  546.     // Delete old pixel shader (redundant if InvalidateDeviceObjects is called first)
  547.     if( m_hPixelShader )
  548.         m_pd3dDevice->DeletePixelShader( m_hPixelShader );
  549.  
  550.     m_hPixelShader = NULL;
  551.  
  552.     // Create new pixel shader
  553.     if( m_pD3DXBufShader ) 
  554.         hr = m_pd3dDevice->CreatePixelShader( 
  555.                                  (DWORD*)m_pD3DXBufShader->GetBufferPointer(),
  556.                                  &m_hPixelShader );
  557.  
  558.     return S_OK;
  559. }
  560.  
  561.  
  562.  
  563.  
  564. //-----------------------------------------------------------------------------
  565. // Name: InvalidateDeviceObjects()
  566. // Desc: Called when the device-dependent objects are about to be lost.
  567. //-----------------------------------------------------------------------------
  568. HRESULT CAppForm::InvalidateDeviceObjects()
  569. {
  570.     if( m_hPixelShader )
  571.         m_pd3dDevice->DeletePixelShader( m_hPixelShader );
  572.     m_hPixelShader = NULL;
  573.  
  574.     return S_OK;
  575. }
  576.  
  577.  
  578.  
  579.  
  580. //-----------------------------------------------------------------------------
  581. // Name: DeleteDeviceObjects()
  582. // Desc: Called when the app is exiting, or the device is being changed,
  583. //       this function deletes any device dependent objects.
  584. //-----------------------------------------------------------------------------
  585. HRESULT CAppForm::DeleteDeviceObjects()
  586. {
  587.     SAFE_RELEASE( m_pTexture0 );
  588.     SAFE_RELEASE( m_pTexture1 );
  589.     SAFE_RELEASE( m_pQuadVB );
  590.     SAFE_RELEASE( m_pD3DXBufShader );
  591.     return S_OK;
  592. }
  593.  
  594.  
  595.  
  596.  
  597. //-----------------------------------------------------------------------------
  598. // Name: FinalCleanup()
  599. // Desc: Called before the app exits, this function gives the app the chance
  600. //       to cleanup after itself.
  601. //-----------------------------------------------------------------------------
  602. HRESULT CAppForm::FinalCleanup()
  603. {
  604.     return S_OK;
  605. }
  606.  
  607.  
  608.  
  609.  
  610. //-----------------------------------------------------------------------------
  611. // Name: ConfirmDevice()
  612. // Desc: Called during device intialization, this code checks the device
  613. //       for some minimum set of capabilities
  614. //-----------------------------------------------------------------------------
  615. HRESULT CAppForm::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format )
  616. {
  617.     if( D3DSHADER_VERSION_MAJOR( pCaps->PixelShaderVersion ) < 1 )
  618.         return E_FAIL;
  619.  
  620.     return S_OK;
  621. }
  622.  
  623.  
  624.  
  625.  
  626.  
  627. //-----------------------------------------------------------------------------
  628. // The remaining code handles the UI for the MFC-based app.
  629. //-----------------------------------------------------------------------------
  630.  
  631.  
  632.  
  633.  
  634. //-----------------------------------------------------------------------------
  635. // Name: OnChangeDevice()
  636. // Desc: Use hit the "Change Device.." button. Display the dialog for the user
  637. //       to select a new device/mode, and call Change3DEnvironment to
  638. //       use the new device/mode.
  639. //-----------------------------------------------------------------------------
  640. VOID CAppForm::OnChangeDevice()
  641. {
  642.     UserSelectNewDevice();
  643.     GeneratePixelShaderOpcodes();
  644. }
  645.  
  646.  
  647.  
  648.  
  649. //-----------------------------------------------------------------------------
  650. // Name: OnToggleFullScreen()
  651. // Desc: Called when user toggles the fullscreen mode
  652. //-----------------------------------------------------------------------------
  653. void CAppForm::OnToggleFullScreen()
  654. {
  655.     ToggleFullscreen();
  656.     GeneratePixelShaderOpcodes();
  657. }
  658.  
  659.  
  660.  
  661.  
  662. //-----------------------------------------------------------------------------
  663. // Name: OnHScroll()
  664. // Desc: Called when the user moves any scroll bar. Check which scrollbar was
  665. //       moved, and extract the appropiate value to a global variable.
  666. //-----------------------------------------------------------------------------
  667. void CAppForm::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  668. {
  669.     CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
  670. }
  671.  
  672.  
  673.  
  674.  
  675. //-----------------------------------------------------------------------------
  676. // Name: UpdateUIForDeviceCapabilites()
  677. // Desc: Whenever we get a new device, call this function to enable/disable the
  678. //       appropiate UI controls to match the device's capabilities.
  679. //-----------------------------------------------------------------------------
  680. VOID CAppForm::UpdateUIForDeviceCapabilites()
  681. {
  682.     // Check the capabilities of the device
  683.  
  684.     // Update the UI checkbox states
  685. }
  686.  
  687.  
  688.  
  689.  
  690. //-----------------------------------------------------------------------------
  691. // Name: 
  692. // Desc: 
  693. //-----------------------------------------------------------------------------
  694. void CAppForm::OnPresets() 
  695. {
  696.     DWORD dwPreset = 0L;
  697.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_0))->GetCheck() ? 0 : dwPreset;
  698.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_1))->GetCheck() ? 1 : dwPreset;
  699.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_2))->GetCheck() ? 2 : dwPreset;
  700.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_3))->GetCheck() ? 3 : dwPreset;
  701.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_4))->GetCheck() ? 4 : dwPreset;
  702.     dwPreset = ((CButton*)GetDlgItem(IDC_PRESET_5))->GetCheck() ? 5 : dwPreset;
  703.  
  704.     CEdit* pEdit = (CEdit*)GetDlgItem(IDC_INSTRUCTIONS);
  705.     pEdit->SetWindowText( g_strPixelShaderPresets[dwPreset] );
  706.  
  707.     // Generate the opcodes and pass them to the app
  708.     GeneratePixelShaderOpcodes();
  709. }
  710.  
  711.  
  712.  
  713.  
  714.  
  715. //-----------------------------------------------------------------------------
  716. // Name: 
  717. // Desc: 
  718. //-----------------------------------------------------------------------------
  719. void CAppForm::GeneratePixelShaderOpcodes() 
  720. {
  721.     TCHAR strOpcodes[2048] = _T("");
  722.  
  723.     CEdit* pEdit = (CEdit*)GetDlgItem(IDC_INSTRUCTIONS);
  724.     pEdit->GetWindowText(strOpcodes, 2048);
  725.  
  726.     SetPixelShader( strOpcodes );
  727. }
  728.  
  729.  
  730.  
  731.  
  732. //-----------------------------------------------------------------------------
  733. // Name: 
  734. // Desc: 
  735. //-----------------------------------------------------------------------------
  736. void CAppForm::OnOpenPixelShaderFile() 
  737. {
  738.     ((CButton*)GetDlgItem(IDC_PRESET_0))->SetCheck( FALSE );
  739.     ((CButton*)GetDlgItem(IDC_PRESET_1))->SetCheck( FALSE );
  740.     ((CButton*)GetDlgItem(IDC_PRESET_2))->SetCheck( FALSE );
  741.     ((CButton*)GetDlgItem(IDC_PRESET_3))->SetCheck( FALSE );
  742.     ((CButton*)GetDlgItem(IDC_PRESET_4))->SetCheck( FALSE );
  743.     ((CButton*)GetDlgItem(IDC_PRESET_5))->SetCheck( FALSE );
  744.  
  745.  
  746.     static TCHAR g_strFileName[MAX_PATH] = _T("");
  747.     static TCHAR g_strInitialDir[MAX_PATH] = _T("");
  748.     TCHAR strFileName[MAX_PATH] = _T("");
  749.     TCHAR strBuffer[81];
  750.  
  751.     // Display the OpenFileName dialog. Then, try to load the specified file
  752.     OPENFILENAME ofn = { sizeof(OPENFILENAME), NULL, NULL,
  753.                          _T("Pixel Shader Text Files (.txt)\0*.txt\0\0"), 
  754.                          NULL, 0, 1, strFileName, MAX_PATH, g_strFileName, MAX_PATH, 
  755.                          g_strInitialDir, _T("Open Pixel Shader File"), 
  756.                          OFN_FILEMUSTEXIST, 0, 1, NULL, 0, NULL, NULL };
  757.  
  758.     if( FALSE == GetOpenFileName( &ofn ) )
  759.         return;
  760.     
  761.     FILE* file = fopen( strFileName, _T("r") );
  762.     if( file == NULL )
  763.         return;
  764.  
  765.     // Fill the list box with the preset's pixel shader instructions
  766.     CEdit* pEdit = (CEdit*)GetDlgItem(IDC_INSTRUCTIONS);
  767.     pEdit->SetSel(0, -1);
  768.     while( fgets( strBuffer, 80, file ) )
  769.     {
  770.         // Remove trailing newline char
  771.         if( strBuffer[max(1,strlen(strBuffer))-1] == '\n' )
  772.             strBuffer[max(1,strlen(strBuffer))-1] = '\0';
  773.         pEdit->ReplaceSel(strBuffer);
  774.         pEdit->ReplaceSel("\r\n");
  775.     }
  776.  
  777.     fclose(file);
  778.  
  779.     // Generater the opcodes and pass them to the app
  780.     GeneratePixelShaderOpcodes();
  781. }
  782.  
  783.  
  784. void CAppForm::OnChangeInstructions() 
  785. {
  786.     GeneratePixelShaderOpcodes();
  787. }
  788.