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

📄 effect.cpp

📁 是《3D游戏编程》的代码 买了这本书
💻 CPP
字号:
//-----------------------------------------------------------------------------
// 名称: CreateDevice.cpp
// 
// 功能: 这个文件创建了一个Direct3D对象和一个Direct3D设备,并使用一个窗口作为
//       渲染目标表面。
//       
//-----------------------------------------------------------------------------

// 包含DirectMusic头文件
#include <d3d8.h>
#include <dmusicc.h>
#include <dmusici.h>

// Windows类的名称宏定义
#define  MY_WINCLASS_NAME      "DirectMusic"

// 定义键盘按键的宏
#define MYVK_NUM_01       0x31
#define MYVK_NUM_02       0x32
#define MYVK_NUM_03       0x33
#define MYVK_NUM_04       0x34


#define KEYDOWN(vk_code)  ((GetAsyncKeyState(vk_code) & 0x8000)? 1 : 0)
#define KEYUP(vk_code)    ((GetAsyncKeyState(vk_code) & 0x8000)? 0 : 1)

// 定义全局变量
IDirectMusicLoader8*      g_pLoader         = NULL;
IDirectMusicPerformance8* g_pPerformance    = NULL;
IDirectMusicSegment8*     g_pSegment        = NULL;
IDirectMusicAudioPath*    g_pAudioPath      = NULL;
IDirectSoundBuffer8*      g_pSoundBuffer    = NULL;

VOID SoundPlay();

//-----------------------------------------------------------------------------
// 名称: SoundEftEcho()
// 功能: 设置声音的回音效果
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftEcho()
{
	HRESULT      hr;
	
	IDirectSoundFXEcho8*   pEffectDMO;
	DSFXEcho               FXParams;
	DSEFFECTDESC		   FXDes;
	DWORD				   dwRes;

    ZeroMemory( &FXDes, sizeof(DSEFFECTDESC) );
    FXDes.dwSize         = sizeof(DSEFFECTDESC);
    FXDes.dwFlags        = 0;
	FXDes.guidDSFXClass  = GUID_DSFX_STANDARD_ECHO;

	if( g_pAudioPath )
        g_pAudioPath->Activate( FALSE );

    if( FAILED( hr = g_pSoundBuffer->SetFX( 1, &FXDes, &dwRes ) ) )
        return hr;

	hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
        0,
        IID_IDirectSoundFXEcho8,
        (LPVOID*) &pEffectDMO);
 
	hr = pEffectDMO->GetAllParameters(&FXParams);

	// 设置回音效果的延时为500毫秒,左右两个声道需要单独设置
	FXParams. fLeftDelay = 500; 
	FXParams. fRightDelay= 500;

	hr = pEffectDMO->SetAllParameters(&FXParams);

    if( g_pAudioPath )
        g_pAudioPath->Activate( TRUE );

    return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: SoundEftDistortion()
// 功能: 设置声音的变形效果
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftDistortion()
{
	HRESULT      hr;
	
	IDirectSoundFXDistortion8*   pEffectDMO;
	DSFXDistortion               FXParams;
	DSEFFECTDESC		   FXDes[2];
	DWORD				   dwRes;

    ZeroMemory( FXDes, 2*sizeof(DSEFFECTDESC) );
    FXDes[0].dwSize         = sizeof(DSEFFECTDESC);
    FXDes[0].dwFlags        = 0;
	FXDes[0].guidDSFXClass  = GUID_DSFX_STANDARD_ECHO;
    FXDes[1].dwSize         = sizeof(DSEFFECTDESC);
    FXDes[1].dwFlags        = 0;
	FXDes[1].guidDSFXClass  = GUID_DSFX_STANDARD_DISTORTION;
 
	if( g_pAudioPath )
        g_pAudioPath->Activate( FALSE );

    if( FAILED( hr = g_pSoundBuffer->SetFX( 2, FXDes, &dwRes ) ) )
        return hr;

	DSFXEcho    FXParamsEcho;
	IDirectSoundFXEcho8*   pEffectDMOEcho;

	hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
        0,
        IID_IDirectSoundFXEcho8,
        (LPVOID*) &pEffectDMOEcho);
 
	hr = pEffectDMOEcho->GetAllParameters(&FXParamsEcho);
	FXParamsEcho.fWetDryMix = 0; 
	hr = pEffectDMOEcho->SetAllParameters(&FXParamsEcho);

	hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_DISTORTION,
        0,
        IID_IDirectSoundFXDistortion8,
        (LPVOID*) &pEffectDMO);
 
	hr = pEffectDMO->GetAllParameters(&FXParams);

	// 设置变形效果中进行增强处理的中心频率为2000Hz
//	FXParams. fPostEQCenterFrequency = 2000; 

	// 设置变形效果中进行增强处理的频率范围,通过频率范围的宽度来决定,
	// 这里指定频率宽度为500Hz
//	FXParams. fPostEQBandwidth = 5000;

	// 设置变形效果中过滤掉的高频部分,指定4000Hz以上的声音频率被过滤掉
//	FXParams. fPreLowpassCutoff = 4000; 

	hr = pEffectDMO->SetAllParameters(&FXParams);

    if( g_pAudioPath )
        g_pAudioPath->Activate( TRUE );

    return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: SoundEftReverb()
// 功能: 设置声音的回音效果
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftReverb()
{
	HRESULT      hr;
	
	IDirectSoundFXI3DL2Reverb8*   pEffectDMO;
	DSFXI3DL2Reverb               FXParams;
	DSEFFECTDESC		   FXDes[2];
	DWORD				   dwRes;

    ZeroMemory( FXDes, 2*sizeof(DSEFFECTDESC) );
    FXDes[0].dwSize         = sizeof(DSEFFECTDESC);
    FXDes[0].dwFlags        = 0;
	FXDes[0].guidDSFXClass  = GUID_DSFX_STANDARD_ECHO;
    FXDes[1].dwSize         = sizeof(DSEFFECTDESC);
    FXDes[1].dwFlags        = 0;
	FXDes[1].guidDSFXClass  = GUID_DSFX_STANDARD_I3DL2REVERB;

	if( g_pAudioPath )
        g_pAudioPath->Activate( FALSE );

    if( FAILED( hr = g_pSoundBuffer->SetFX( 2, FXDes, &dwRes ) ) )
        return hr;

	DSFXEcho    FXParamsEcho;
	IDirectSoundFXEcho8*   pEffectDMOEcho;

	hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
        0,
        IID_IDirectSoundFXEcho8,
        (LPVOID*) &pEffectDMOEcho);
 
	hr = pEffectDMOEcho->GetAllParameters(&FXParamsEcho);
	FXParamsEcho.fWetDryMix = 0; 
	hr = pEffectDMOEcho->SetAllParameters(&FXParamsEcho);

	hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_I3DL2REVERB,
        0,
        IID_IDirectSoundFXI3DL2Reverb8,
        (LPVOID*) &pEffectDMO);
 
	hr = pEffectDMO->GetAllParameters(&FXParams);

	// 设置房间中声音的衰减值,单位是毫分贝
	FXParams. lRoom = -500; 

	// 设置第一次声波反射相对于直达声波的延时时间,单位是秒
	FXParams. flReflectionsDelay = 0.01f; 

	// 设置房间中声音早期反射相对于lRoom变量的衰减值,单位是毫分贝
	FXParams. lReflections = -1000; 

	// 设置早期反射和晚期反射相对于第一次声波反射的延时时间,单位是秒
	FXParams. flReverbDelay = 0.011f; 

	// 设置房间中声音晚期反射相对于lRoom变量的衰减值,单位是毫分贝
	FXParams. lReverb  = 100; 

	hr = pEffectDMO->SetAllParameters(&FXParams);

    if( g_pAudioPath )
        g_pAudioPath->Activate( TRUE );

    return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: SoundEffectOff()
// 功能: 关闭声音声音的回音效果
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEffectOff()
{
	HRESULT      hr;
	
	DWORD				   dwRes;

	if( g_pAudioPath )
        g_pAudioPath->Activate( FALSE );

    if( FAILED( hr = g_pSoundBuffer->SetFX( 0, NULL, &dwRes ) ) )
        return hr;

    if( g_pAudioPath )
        g_pAudioPath->Activate( TRUE );

    return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: ProcInput()
// 功能: 处理外部控制设备的输入
//-----------------------------------------------------------------------------
VOID ProcInput()
{
	if(KEYDOWN(MYVK_NUM_01))
	{
		// 设置回音效果
		SoundEftEcho();
	}
	else if(KEYDOWN(MYVK_NUM_02))
	{
		// 设置变形效果
		SoundEftDistortion();
	}
	else if(KEYDOWN(MYVK_NUM_03))
	{
		// 设置环境反射效果
		SoundEftReverb();
	}
	else if(KEYDOWN(MYVK_NUM_04))
	{
		// 关闭所有的声音效果
		SoundEffectOff();
	}

	if(KEYDOWN(VK_SPACE))
	{
		// 播放声音
		SoundPlay();
	}

	return;
}

//-----------------------------------------------------------------------------
// 名称: SoundInit()
// 功能: 初始化声音播放环境的函数,函数中创建了DirectMusic的载入器对象和
//       DirectMusic的演奏对象
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundInit()
{
    // 初始化COM
    CoInitialize(NULL);
    
    // 创建一个载入器对象
    CoCreateInstance( CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, 
                      IID_IDirectMusicLoader8, (void**)&g_pLoader );

    // 创建一个演奏对象
    CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, 
                      IID_IDirectMusicPerformance8, (void**)&g_pPerformance );

    // 初始化演奏对象
    g_pPerformance->InitAudio( NULL, NULL, NULL, 
                               DMUS_APATH_DYNAMIC_STEREO, 64,
                               DMUS_AUDIOF_ALL, NULL );

    g_pPerformance->GetDefaultAudioPath(&g_pAudioPath);

    return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: SoundLoad()
// 功能: 载入一个声音文件。文件为:
//                \Windows安装目录\media\The Microsoft Sound.wav
//-----------------------------------------------------------------------------
HRESULT SoundLoad()
{
	HRESULT    hr;

	TCHAR strPath[MAX_PATH];
    GetCurrentDirectory( MAX_PATH, strPath );

    // 下面的代码设置查找目录
	WCHAR wstrSearchPath[MAX_PATH];
    MultiByteToWideChar( CP_ACP, 0, strPath, -1, 
                         wstrSearchPath, MAX_PATH );

    g_pLoader->SetSearchDirectory( GUID_DirectMusicAllTypes,
		                           wstrSearchPath,
								   FALSE);
    
    // 从文件载入声音到一个声音段对象中
	
    WCHAR wstrFileName[MAX_PATH] = L"gun.wav";   

    if( FAILED( g_pLoader->LoadObjectFromFile( CLSID_DirectMusicSegment,
                                               IID_IDirectMusicSegment8,
                                               wstrFileName,
                                               (LPVOID*) &g_pSegment ) ) )
    {
        MessageBox( NULL, "Media not found, sample will now quit", 
                          "DirectMusic Tutorial", MB_OK );
        return S_FALSE;
    }

    if( FAILED( hr = g_pAudioPath->GetObjectInPath( DMUS_PCHANNEL_ALL,
                DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSoundBuffer8, 
                (LPVOID*) &g_pSoundBuffer )))
        return hr;
  
	return S_OK;
}


//-----------------------------------------------------------------------------
// 名称: SoundPlay()
// 功能: 播放声音文件
//-----------------------------------------------------------------------------
VOID SoundPlay()
{
    // 载入声音段到演奏中
    g_pSegment->Download( g_pPerformance );

	// 设置这个声音段为循环播放
	g_pSegment->SetRepeats(0);

    // 播放声音段
    g_pPerformance->PlaySegmentEx( g_pSegment, NULL, NULL, 0, 
                                   0, NULL, NULL, g_pAudioPath );

}


//-----------------------------------------------------------------------------
// 名称: SoundClean()
// 功能: 释放所有的DirectMusic资源
//-----------------------------------------------------------------------------
VOID SoundClean()
{
    // 停止声音播放,并关闭演奏
    g_pPerformance->Stop( NULL, NULL, 0, 0 );
    g_pPerformance->CloseDown();

    // 清除载入器、演奏和声音段对象
    g_pLoader->Release(); 
    g_pPerformance->Release();
    g_pSegment->Release();

    // 关闭COM
    CoUninitialize();

	return;
}


//-----------------------------------------------------------------------------
// 名称: MsgProc()
// 功能: Windows的消息处理函数
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            ValidateRect( hWnd, NULL );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

//-----------------------------------------------------------------------------
// 名称: WinMain()
// 功能: Windows主函数,程序启动时,从这里开始执行
//-----------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // 定义一个Windows类,指定消息的处理函数为MsgProc
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH), NULL,
                      MY_WINCLASS_NAME, NULL };
	// 注册这个窗口类
    RegisterClassEx( &wc );

    // 创建应用程序窗口
    HWND hWnd = CreateWindow( MY_WINCLASS_NAME, "3D游戏编程——播放声音文件", 
                              WS_OVERLAPPEDWINDOW, 100, 100, 400, 300,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    // 调用SoundInit函数进行DirectMusic对象的创建
    if( SUCCEEDED( SoundInit( ) ) )
    { 
        // 显示窗口
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        // 载入声音	
		SoundLoad();

        // 程序主循环,进行窗口消息的分发,消息的处理在MsgProc函数中完成
        MSG msg; 
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
			ProcInput();
        }
    }

    // 调用SoundClean函数清除DirectMusic对象
    SoundClean();

	// 注销窗口类
    UnregisterClass( MY_WINCLASS_NAME, wc.hInstance );
    return 0;
}



⌨️ 快捷键说明

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