⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example.cpp

📁 3d 游戏编程入门教程之例子源码-高光反射
💻 CPP
字号:
//-----------------------------------------------------------------------------
// File: Example.cpp
//
// Desc: Example code shows how to use a HLSL shader in an effect file
//
//
// Last modification: February 2nd, 2003
//
// Copyright (c) Wolfgang F. Engel (wolf@direct3d.net)
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <Windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <D3DX9.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "resource.h"

#include "Trackball.h"

//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Application class. The base class (CD3DApplication) provides the 
//       generic functionality needed in all Direct3D samples. CMyD3DApplication 
//       adds functionality specific to this sample program.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
    CD3DFont* m_pFont;
	CD3DFont* m_pFontSmall;

	LPD3DXEFFECT     m_pEffect;    

	ID3DXMesh*  m_pD3DXMesh;            // D3DX mesh to store teapot
	D3DXMATRIX  m_matWorld;
	D3DXMATRIX  m_matView;
	D3DXMATRIX  m_matProj;

	D3DXVECTOR4 m_LightDir;

	BYTE  m_bKey[256];

	trackball_t m_pTrackball;	// trackball to turn the model
	bool m_bZoomDrag;			// zooming
	float m_fZoom;
	FLOAT m_fTheta;
	FLOAT m_fTheta2;
	BOOL m_bLMouseDown;
	BOOL m_bRMouseDown;
	FLOAT m_xPos, m_yPos;
	FLOAT m_oPosX, m_oPosY;

	TCHAR m_strStats[1024];	// help string

protected:
    HRESULT OneTimeSceneInit();
    HRESULT InitDeviceObjects();
    HRESULT RestoreDeviceObjects();
    HRESULT InvalidateDeviceObjects();
    HRESULT DeleteDeviceObjects();
    HRESULT FinalCleanup();
    HRESULT Render();
    HRESULT FrameMove();
    HRESULT ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, 
		D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat );
	LRESULT MsgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

	HRESULT LoadXFile(TCHAR*);


public:
    CMyD3DApplication();
	~CMyD3DApplication();
};

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
//       message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    CMyD3DApplication d3dApp;

    InitCommonControls();
    if( FAILED( d3dApp.Create( hInst ) ) )
        return 0;

    return d3dApp.Run();
}

//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
    m_strWindowTitle  = _T("High-Level-Shading Language");
    m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
	m_dwCreationWidth		= 800;   // Width used to create window
	m_dwCreationHeight		= 600;
	m_bShowCursorWhenFullscreen = TRUE;
	m_pFont					= new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
	m_pFontSmall			= new CD3DFont( _T("Arial"),  9, D3DFONT_BOLD );
	memset (m_bKey, 0, sizeof (m_bKey));
	m_bLMouseDown			= FALSE;
	m_bRMouseDown			= FALSE;
	m_bZoomDrag				= false;
	m_fZoom					= -50.0f;			// initial zoom
	m_fTheta				= 0;
	m_fTheta2				= 0;
	m_LightDir				= D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f );
	D3DXMatrixIdentity(&m_matWorld);
	m_pEffect				= NULL;
	m_pD3DXMesh             = NULL;
}

//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application denstructor
//-----------------------------------------------------------------------------
CMyD3DApplication::~CMyD3DApplication()
{
	SAFE_DELETE(m_pFont);
	SAFE_DELETE(m_pFontSmall);
}

//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
//       permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
	m_pTrackball.TrackMouse(m_hWnd, m_bZoomDrag, &m_fZoom); // track mouse movements and move object
	m_pTrackball.SetMatrix(m_matWorld); // get the world matrix for the trackball

	// setup view matrix
	D3DXVECTOR3 vUpVec(0,1,0);
	D3DXVECTOR3 vEyePt(0,0,m_fZoom);
	D3DXVECTOR3 vLookatPt(0,0,0);
	D3DXMatrixLookAtLH(&m_matView, &vEyePt, &vLookatPt, &vUpVec);

	if(m_bKey['W']) m_fZoom += 10.0f * m_fElapsedTime; // Move Forward
	if(m_bKey['S']) m_fZoom -= 10.0f * m_fElapsedTime; // Move Backward

	// move light
	if(m_bKey[VK_UP])	m_LightDir.y -= 1.5f  * m_fElapsedTime;
	if(m_bKey[VK_DOWN]) m_LightDir.y += 1.5f  * m_fElapsedTime;
	if(m_bKey[VK_LEFT])	m_LightDir.x += 1.5f  * m_fElapsedTime;
	if(m_bKey[VK_RIGHT]) m_LightDir.x -= 1.5f  * m_fElapsedTime;
	if(m_bKey[VK_HOME])	m_LightDir.z += 1.0f  * m_fElapsedTime;
	if(m_bKey[VK_END]) m_LightDir.z -= 1.0f  * m_fElapsedTime;
	if (m_LightDir.z >= 2.7f) m_LightDir.z = 2.7f; 
	if (m_LightDir.z <= -5.7f) m_LightDir.z = -5.7f; 

	// set light direction
	m_pEffect->SetVector("vecLightDir", &-m_LightDir);
	m_pEffect->SetVector("vecEye", &D3DXVECTOR4(vEyePt.x,vEyePt.y,vEyePt.z,0));

	D3DXMATRIX mWorldViewProj = m_matWorld * m_matView * m_matProj;
	m_pEffect->SetMatrix( "matWorldViewProj", &mWorldViewProj );
	m_pEffect->SetMatrix( "matWorld", &m_matWorld);

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{	
		m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
							D3DCOLOR_ARGB( 0x00, 0x00, 0x00, 0x00), 1.0, 0);
        UINT nPasses;
        UINT iPass;

		// Begin the scene
		if( SUCCEEDED( m_pd3dDevice->BeginScene() ))
		{
			if( m_pEffect != NULL )
			{
				D3DXHANDLE hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
				m_pEffect->SetTechnique( hTechnique );

				m_pEffect->Begin( &nPasses, 0 );

				for( iPass = 0; iPass < nPasses; iPass ++ )
				{
					m_pEffect->Pass( iPass );
					m_pD3DXMesh->DrawSubset( 0 );
				}
				m_pEffect->End();
			}

			// Output statistics
			m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
			m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
			sprintf(m_strStats, 
				"W -     Zoom In \
				\nS -     Zoom Out \
				\nHome/End -     Moves Light -z/+z\
				\nUp/Down -     Moves Light -y/+y\
				\nLeft/Right -     Moves Light -x/+x");
			m_pFontSmall->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,255), m_strStats);


			// End the scene.
			m_pd3dDevice->EndScene();
		}

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
	m_pFont->InitDeviceObjects( m_pd3dDevice );
	m_pFontSmall->InitDeviceObjects( m_pd3dDevice );

	HRESULT hr;

	TCHAR strFile[160];
	DXUtil_FindMediaFileCb(strFile, sizeof(strFile),_T("teapot.x"));
	LoadXFile(strFile);

	if( FAILED( hr = D3DXCreateEffectFromFile( m_pd3dDevice, "hlsl.fx", NULL, NULL, 
		D3DXSHADER_DEBUG, NULL, &m_pEffect, NULL ) ) )
		return hr;

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
	m_pFont->RestoreDeviceObjects();
    m_pFontSmall->RestoreDeviceObjects();
	if( m_pEffect != NULL ) m_pEffect->OnResetDevice();

    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
	m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

	D3DXMATRIX matProjection;
	D3DXMatrixPerspectiveFovLH(&m_matProj, 0.05f, 
		(FLOAT)m_d3dsdBackBuffer.Width /(FLOAT)m_d3dsdBackBuffer.Height, 
		5.0f, 500.0f);

	// init trackball 
	m_pTrackball.Init(m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height);

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
    m_pFont->InvalidateDeviceObjects();
    m_pFontSmall->InvalidateDeviceObjects();
	if( m_pEffect != NULL ) m_pEffect->OnLostDevice();

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
    m_pFont->DeleteDeviceObjects();
    m_pFontSmall->DeleteDeviceObjects();
	SAFE_RELEASE( m_pEffect );
	SAFE_RELEASE( m_pD3DXMesh );

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
//       to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: ConfirmDevice()
// Desc: Called during device initialization, this code checks the device
//       for some minimum set of capabilities
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
                                          D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat )
{
	if( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
		(dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) )
	{
		if(!( pCaps->VertexShaderVersion >= D3DVS_VERSION(1,1) ))
			return E_FAIL;
	}
	if(!( pCaps->PixelShaderVersion >= D3DPS_VERSION(1,1) ))
		return E_FAIL;

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Message proc function to handle key and menu input
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // Trap the context menu
    if( WM_CONTEXTMENU==uMsg )
        return 0;

    switch(uMsg)
    {
    case WM_LBUTTONDOWN:
		SetCapture(hwnd);
        return 0;
    case WM_LBUTTONUP:
		ReleaseCapture();
        return 0;

	// track mouse movement to rotate sphere
    case WM_MOUSEMOVE:
	{
	    RECT r;
		FLOAT dx,dy;
		D3DXMATRIX mat1,mat2,mat3;

		GetWindowRect(m_hWnd,&r);
	    dx = ((FLOAT)m_xPos)/((FLOAT)r.right-r.left) * 2 - 1.0f;
	    dy = ((FLOAT)m_yPos)/((FLOAT)r.right-r.left) * 2 - 0.7f;
    
	    // left button rotates the object
	    if(m_bLMouseDown)
		{   
	      m_fTheta  = -dy+m_oPosY;
	      m_fTheta2 = -dx+m_oPosX;
    
	      D3DXMatrixRotationX(&mat1,m_fTheta * 0.1f);
	      D3DXMatrixRotationY(&mat2,m_fTheta2 * 0.1f);
	      D3DXMatrixMultiply(&mat3,&mat1,&mat2);
	      D3DXMatrixMultiply(&m_matWorld,&m_matWorld,&mat3);
		}
	}
    break;

    case WM_KEYUP:
        // mark a key up
        m_bKey[wParam] = FALSE;
        break;

    case WM_KEYDOWN:
        // mark a key down
         m_bKey[wParam] = TRUE;
       break;
   }

    return CD3DApplication::MsgProc( hwnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: LoadXFile()
// Desc: loads the x-file
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::LoadXFile(TCHAR* name)
{
	HRESULT		hr;
	LPD3DXMESH	pMeshSysMem = NULL, pMeshSysMem2 = NULL;

	if (FAILED (D3DXLoadMeshFromX(name, D3DXMESH_SYSTEMMEM, 
				m_pd3dDevice, NULL, NULL, NULL, NULL, &pMeshSysMem)))
		return E_FAIL;

	D3DVERTEXELEMENT9 decl[]=
	{
		// stream, offset, type, method, semantic type (for example normal), ?
		{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
		{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
		D3DDECL_END()
	};

	hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, decl, m_pd3dDevice, &m_pD3DXMesh);

	// compute the normals
	hr = D3DXComputeNormals(m_pD3DXMesh,NULL);
	if(FAILED(hr))
		return E_FAIL;

	// cleanup
	SAFE_RELEASE(pMeshSysMem);


	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -