0001:
0002:
0003:
0004:
0005:
0006: #define STRICT
0007: #include <windows.h>
0008: #include <commctrl.h>
0009: #include <commdlg.h>
0010: #include <basetsd.h>
0011: #include <math.h>
0012: #include <stdio.h>
0013: #include <d3dx9.h>
0014: #include <dxerr9.h>
0015: #include <tchar.h>
0016: #include "DXUtil.h"
0017: #include "D3DEnumeration.h"
0018: #include "D3DSettings.h"
0019: #include "D3DApp.h"
0020: #include "D3DFont.h"
0021: #include "D3DFile.h"
0022: #include "D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025:
0026: #define MAP_SIZE 256
0027:
0028:
0029: D3DVERTEXELEMENT9 decl[] =
0030: {
0031: {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
0032: {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
0033: D3DDECL_END()
0034: };
0035:
0036:
0037: #define RS m_pd3dDevice->SetRenderState
0038: #define TSS m_pd3dDevice->SetTextureStageState
0039: #define SAMP m_pd3dDevice->SetSamplerState
0040:
0041:
0042:
0043:
0044:
0045: typedef struct {
0046: FLOAT p[4];
0047: FLOAT tu, tv;
0048: } TVERTEX;
0049:
0050:
0051:
0052:
0053: CMyD3DApplication* g_pApp = NULL;
0054: HINSTANCE g_hInst = NULL;
0055:
0056:
0057:
0058:
0059:
0060:
0061: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0062: {
0063: CMyD3DApplication d3dApp;
0064:
0065: g_pApp = &d3dApp;
0066: g_hInst = hInst;
0067:
0068: InitCommonControls();
0069: if( FAILED( d3dApp.Create( hInst ) ) )
0070: return 0;
0071:
0072: return d3dApp.Run();
0073: }
0074:
0075:
0076:
0077:
0078:
0079:
0080:
0081:
0082: VOID WINAPI SinTan (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord,
0083: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0084: {
0085: FLOAT x = pTexCoord->x;
0086: FLOAT y = pTexCoord->y;
0087: FLOAT min = 2.0f*((x<y)?x:y)-1.0f;
0088: FLOAT max = 2.0f*((x<y)?y:x)-1.0f;
0089: pOut->x = sinf( acosf(min) ) * tanf( acosf(max) );
0090: }
0091:
0092:
0093:
0094:
0095:
0096:
0097:
0098:
0099: CMyD3DApplication::CMyD3DApplication()
0100: {
0101: m_pMesh = new CD3DMesh();
0102: m_pTex = NULL;
0103:
0104: m_pEffect = NULL;
0105: m_hTechnique = NULL;
0106: m_hmWVP = NULL;
0107: m_hvCol = NULL;
0108: m_hvLightPos = NULL;
0109: m_hvCamPos = NULL;
0110: m_hfA = NULL;
0111: m_hfB = NULL;
0112: m_pDecl = NULL;
0113:
0114: m_fWorldRotX = -0.41271535f;
0115: m_fWorldRotY = 0.5f * D3DX_PI;
0116: m_fViewZoom = 2.5f;
0117: m_fRoughness = 0.7f;
0118:
0119: m_dwCreationWidth = 512;
0120: m_dwCreationHeight = 512;
0121: m_strWindowTitle = TEXT( "main" );
0122: m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
0123: m_bStartFullscreen = false;
0124: m_bShowCursorWhenFullscreen = false;
0125:
0126: m_LightPos = D3DXVECTOR4(-0.6f, 2.2f, -2.0f, 0.0f);
0127:
0128: m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0129: m_bLoadingApp = TRUE;
0130:
0131: ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0132: }
0133:
0134:
0135:
0136:
0137:
0138:
0139:
0140:
0141: CMyD3DApplication::~CMyD3DApplication()
0142: {
0143: }
0144:
0145:
0146:
0147:
0148:
0149:
0150:
0151:
0152:
0153:
0154: HRESULT CMyD3DApplication::OneTimeSceneInit()
0155: {
0156:
0157: SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0158:
0159: m_bLoadingApp = FALSE;
0160:
0161: return S_OK;
0162: }
0163:
0164:
0165:
0166:
0167:
0168:
0169:
0170:
0171: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps,
0172: DWORD dwBehavior, D3DFORMAT Format )
0173: {
0174: UNREFERENCED_PARAMETER( Format );
0175: UNREFERENCED_PARAMETER( dwBehavior );
0176: UNREFERENCED_PARAMETER( pCaps );
0177:
0178:
0179:
0180: if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0181: return E_FAIL;
0182:
0183:
0184: if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0185: && 0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0186: return E_FAIL;
0187:
0188: return S_OK;
0189: }
0190:
0191:
0192:
0193:
0194:
0195:
0196:
0197:
0198:
0199:
0200:
0201: HRESULT CMyD3DApplication::InitDeviceObjects()
0202: {
0203: HRESULT hr;
0204: D3DXVECTOR4 offset;
0205:
0206:
0207: if(FAILED(hr=m_pMesh ->Create( m_pd3dDevice, _T("dog.x"))))
0208: return DXTRACE_ERR( "LoadCar", hr );
0209:
0210:
0211: if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ) ) )
0212: return DXTRACE_ERR( "CreateVertexDeclaration", hr );
0213:
0214:
0215: LPD3DXBUFFER pErr;
0216: if( FAILED( hr = D3DXCreateEffectFromFile(
0217: m_pd3dDevice, "hlsl.fx", NULL, NULL,
0218: D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0219: MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0220: , "ERROR", MB_OK);
0221: return DXTRACE_ERR( "CreateEffectFromFile", hr );
0222: }
0223: m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0224: m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" );
0225: m_hvCol = m_pEffect->GetParameterByName( NULL, "vCol" );
0226: m_hvLightPos = m_pEffect->GetParameterByName( NULL, "vLightPos" );
0227: m_hvCamPos = m_pEffect->GetParameterByName( NULL, "vCamPos" );
0228: m_hfA = m_pEffect->GetParameterByName( NULL, "A" );
0229: m_hfB = m_pEffect->GetParameterByName( NULL, "B" );
0230:
0231:
0232: m_pFont->InitDeviceObjects( m_pd3dDevice );
0233:
0234: return S_OK;
0235: }
0236:
0237:
0238:
0239:
0240:
0241:
0242: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0243: {
0244: HRESULT hr;
0245:
0246: if( FAILED(hr = m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1
0247: , D3DUSAGE_RENDERTARGET, D3DFMT_R32F
0248: , D3DPOOL_DEFAULT, &m_pTex, NULL)))
0249: return hr;
0250: if( FAILED(hr = D3DXFillTexture(m_pTex, SinTan, NULL)))
0251: return hr;
0252: m_pEffect->SetTexture( "tSinTan", m_pTex );
0253:
0254:
0255:
0256: m_pMesh ->RestoreDeviceObjects( m_pd3dDevice );
0257:
0258:
0259: D3DMATERIAL9 mtrl;
0260: D3DUtil_InitMaterial( mtrl, 0.0f, 0.0f, 0.0f );
0261: m_pd3dDevice->SetMaterial( &mtrl );
0262:
0263:
0264: D3DLIGHT9 light;
0265: D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -0.5f, -2.0f, 1.0f );
0266: m_pd3dDevice->SetLight( 0, &light );
0267: m_pd3dDevice->LightEnable( 0, TRUE );
0268: m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
0269:
0270:
0271: RS( D3DRS_DITHERENABLE, FALSE );
0272: RS( D3DRS_SPECULARENABLE, FALSE );
0273: RS( D3DRS_ZENABLE, TRUE );
0274: RS( D3DRS_AMBIENT, 0x000F0F0F );
0275:
0276: TSS( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
0277: TSS( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0278: TSS( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0279: TSS( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
0280: TSS( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
0281: SAMP( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0282: SAMP( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0283: SAMP( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0284: SAMP( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0285:
0286:
0287: D3DXMATRIX matIdentity;
0288: D3DXMatrixIdentity( &m_mWorld );
0289:
0290:
0291: D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0292: D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0293: D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0294: D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0295:
0296:
0297: FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0298: D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0299:
0300:
0301: m_pFont->RestoreDeviceObjects();
0302:
0303: m_pEffect->OnResetDevice();
0304:
0305: return S_OK;
0306: }
0307:
0308:
0309:
0310:
0311:
0312:
0313:
0314:
0315: HRESULT CMyD3DApplication::FrameMove()
0316: {
0317:
0318: UpdateInput( &m_UserInput );
0319:
0320:
0321:
0322:
0323:
0324: D3DXMATRIX matRotY;
0325: D3DXMATRIX matRotX;
0326:
0327: if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0328: m_fWorldRotY += m_fElapsedTime;
0329: else
0330: if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0331: m_fWorldRotY -= m_fElapsedTime;
0332:
0333: if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0334: m_fWorldRotX += m_fElapsedTime;
0335: else
0336: if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0337: m_fWorldRotX -= m_fElapsedTime;
0338:
0339: D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0340: D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0341:
0342: D3DXMatrixMultiply( &m_mWorld, &matRotY, &matRotX );
0343:
0344:
0345:
0346:
0347:
0348: if( m_UserInput.bZoomIn && !m_UserInput.bZoomOut )
0349: m_fViewZoom += m_fElapsedTime;
0350: else if( m_UserInput.bZoomOut && !m_UserInput.bZoomIn )
0351: m_fViewZoom -= m_fElapsedTime;
0352:
0353: D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -m_fViewZoom );
0354: D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0355: D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0356: D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0357:
0358:
0359:
0360:
0361:
0362: if( m_UserInput.bRoughnessUp && !m_UserInput.bRoughnessDown )
0363: m_fRoughness += 0.1f*m_fElapsedTime;
0364: else if( m_UserInput.bRoughnessDown && !m_UserInput.bRoughnessUp )
0365: m_fRoughness -= 0.1f*m_fElapsedTime;
0366:
0367: if(m_fRoughness < 0.0f) m_fRoughness = 0.0f;
0368: if(1.0f < m_fRoughness) m_fRoughness = 1.0f;
0369:
0370: return S_OK;
0371: }
0372:
0373:
0374:
0375:
0376: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0377: {
0378: pUserInput->bRotateUp = ( m_bActive && (GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000 );
0379: pUserInput->bRotateDown = ( m_bActive && (GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000 );
0380: pUserInput->bRotateLeft = ( m_bActive && (GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000 );
0381: pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0382:
0383: pUserInput->bZoomIn = ( m_bActive && (GetAsyncKeyState( 'Z' ) & 0x8000) == 0x8000 );
0384: pUserInput->bZoomOut = ( m_bActive && (GetAsyncKeyState( 'X' ) & 0x8000) == 0x8000 );
0385:
0386: pUserInput->bRoughnessUp = ( m_bActive && (GetAsyncKeyState( 'Q' ) & 0x8000) == 0x8000 );
0387: pUserInput->bRoughnessDown= ( m_bActive && (GetAsyncKeyState( 'W' ) & 0x8000) == 0x8000 );
0388: }
0389:
0390:
0391:
0392:
0393:
0394:
0395: HRESULT CMyD3DApplication::Render()
0396: {
0397: D3DXMATRIX m, mW;
0398: D3DXVECTOR4 v;
0399:
0400:
0401:
0402:
0403: if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0404: {
0405: m_pd3dDevice->Clear(0L, NULL
0406: , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0407: , 0x202040, 1.0f, 0L);
0408:
0409: if(m_pEffect != NULL)
0410: {
0411: m_pEffect->SetTechnique( m_hTechnique );
0412: m_pEffect->Begin( NULL, 0 );
0413: m_pEffect->Pass( 0 );
0414:
0415: D3DXMatrixTranslation ( &mW, 0, -0.5f, 0 );
0416: mW = mW * m_mWorld;
0417: m = mW * m_mView * m_mProj;
0418: m_pEffect->SetMatrix( m_hmWVP, &m );
0419:
0420:
0421: D3DXMatrixInverse( &m, NULL, &mW);
0422: D3DXVec4Transform( &v, &m_LightPos, &m );
0423: m_pEffect->SetVector( m_hvLightPos, &v );
0424:
0425:
0426: v = D3DXVECTOR4( 0.0f, 0.0f, -m_fViewZoom, 1.0f );
0427: D3DXVec4Transform( &v, &v, &m );
0428: m_pEffect->SetVector( m_hvCamPos, &v );
0429:
0430:
0431: FLOAT fRoughness2 = m_fRoughness*m_fRoughness;
0432: FLOAT A = 1.0f - 0.5f*(fRoughness2 / (fRoughness2 + 0.33f));
0433: FLOAT B = 0.45f * (fRoughness2 / (fRoughness2 + 0.09f));
0434: m_pEffect->SetFloat( m_hfA, A );
0435: m_pEffect->SetFloat( m_hfB, B );
0436:
0437: TSS( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
0438: TSS( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
0439:
0440:
0441:
0442:
0443: D3DMATERIAL9 *pMtrl = m_pMesh->m_pMaterials;
0444: for( DWORD i=0; i<m_pMesh->m_dwNumMaterials; i++ ) {
0445:
0446: v.x = pMtrl->Diffuse.r;
0447: v.y = pMtrl->Diffuse.g;
0448: v.z = pMtrl->Diffuse.b;
0449: v.w = pMtrl->Diffuse.a;
0450: m_pEffect->SetVector( m_hvCol, &v );
0451:
0452: m_pMesh->m_pLocalMesh->DrawSubset( i );
0453: pMtrl++;
0454: }
0455:
0456: m_pEffect->End();
0457: }
0458:
0459:
0460: RenderText();
0461:
0462: #if 1
0463: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0464: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0465: m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
0466: m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0467: m_pd3dDevice->SetVertexShader(NULL);
0468: m_pd3dDevice->SetPixelShader(0);
0469: for(DWORD loop = 0; loop < 1; loop++){
0470: const float scale =128.0f;
0471: typedef struct {FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0472: FLOAT X = (FLOAT)this->m_rcWindowClient.bottom;
0473: FLOAT Y = (FLOAT)this->m_rcWindowClient.bottom;
0474: TVERTEX Vertex[4] = {
0475:
0476: {X-scale,Y-scale,0, 1, 0.0f, 0.0f,},
0477: {X ,Y-scale,0, 1, 1.0f, 0.0f,},
0478: {X ,Y ,0, 1, 1.0f, 1.0f,},
0479: {X-scale,Y ,0, 1, 0.0f, 1.0f,},
0480: };
0481: switch(loop){
0482: case 0: m_pd3dDevice->SetTexture( 0, m_pTex ); break;
0483: }
0484: m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0485: }
0486: #endif
0487:
0488: m_pd3dDevice->EndScene();
0489: }
0490:
0491: return S_OK;
0492: }
0493:
0494:
0495:
0496:
0497:
0498:
0499:
0500:
0501: HRESULT CMyD3DApplication::RenderText()
0502: {
0503: D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0);
0504: TCHAR szMsg[MAX_PATH] = TEXT("");
0505:
0506: FLOAT fNextLine = 40.0f;
0507:
0508:
0509: fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;
0510: lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0511: fNextLine -= 20.0f;
0512: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0513:
0514: sprintf( szMsg, TEXT("Roughness = %f (Change[Q]-[W])"), m_fRoughness );
0515: fNextLine -= 20.0f;
0516: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0517:
0518: lstrcpy( szMsg, m_strDeviceStats );
0519: fNextLine -= 20.0f;
0520: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0521: lstrcpy( szMsg, m_strFrameStats );
0522: fNextLine -= 20.0f;
0523: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0524:
0525: return S_OK;
0526: }
0527:
0528:
0529:
0530:
0531:
0532:
0533:
0534:
0535: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg,
0536: WPARAM wParam, LPARAM lParam )
0537: {
0538: switch( msg )
0539: {
0540: case WM_PAINT:
0541: {
0542: if( m_bLoadingApp )
0543: {
0544:
0545: HDC hDC = GetDC( hWnd );
0546: TCHAR strMsg[MAX_PATH];
0547: wsprintf(strMsg, TEXT("Loading... Please wait"));
0548: RECT rct;
0549: GetClientRect( hWnd, &rct );
0550: DrawText( hDC, strMsg, -1, &rct
0551: , DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0552: ReleaseDC( hWnd, hDC );
0553: }
0554: break;
0555: }
0556:
0557: }
0558:
0559: return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0560: }
0561:
0562:
0563:
0564:
0565:
0566:
0567:
0568:
0569: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0570: {
0571: SAFE_RELEASE(m_pTex);
0572:
0573: m_pMesh ->InvalidateDeviceObjects();
0574:
0575: m_pFont->InvalidateDeviceObjects();
0576:
0577:
0578: if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
0579:
0580: return S_OK;
0581: }
0582:
0583:
0584:
0585:
0586:
0587:
0588:
0589:
0590: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0591: {
0592:
0593: SAFE_RELEASE( m_pEffect );
0594: SAFE_RELEASE( m_pDecl );
0595:
0596:
0597: m_pMesh ->Destroy();
0598:
0599:
0600: m_pFont->DeleteDeviceObjects();
0601:
0602: return S_OK;
0603: }
0604:
0605:
0606:
0607:
0608:
0609:
0610:
0611:
0612: HRESULT CMyD3DApplication::FinalCleanup()
0613: {
0614: SAFE_DELETE( m_pMesh );
0615:
0616: SAFE_DELETE( m_pFont );
0617:
0618: return S_OK;
0619: }
0620:
0621:
0622:
0623:
0624: