📄 main.cpp
字号:
#define WIN32_LEAN_AND_MEAN // trim the excess fat from Windows
/*******************************************************************
* Program: Chapter 17 DirectX Audio - DirectMusic Example 2
* Author: Kevin Hawkins
* Description: Illustrates how to use DirectX Audio for 3D
* audio effects. An object making a sound
* moves close to and away from the camera.
********************************************************************/
#define INITGUID // we use GUID's with DMusic
////// Includes
#include <windows.h> // standard Windows app include
#include <dmusicc.h> // DirectMusic includes
#include <dmusici.h>
#include <d3d8types.h> // for D3DVECTOR
#include <cguid.h> // for GUID_NULL
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h> // standard OpenGL include
#include <gl/glu.h> // OpenGL utilties
////// Global Variables
HDC g_HDC; // global device context
bool fullScreen = false; // true = fullscreen; false = windowed
bool keyPressed[256]; // holds true for keys that are pressed
float angle = 0.0f;
unsigned int listBase; // display list base
GLYPHMETRICSFLOAT gmf[256]; // holds orientation and placement
// info for display lists
////// DirectMusic variables
IDirectMusicLoader8 *dmusicLoader = NULL; // the loader
IDirectMusicPerformance8 *dmusicPerformance = NULL; // the performance
IDirectMusicSegment8 *dmusicSegment = NULL; // the segment
IDirectMusicAudioPath *dmusic3DAudioPath = NULL; // the audiopath
IDirectSound3DBuffer *ds3DBuffer = NULL; // 3d buffer
IDirectSound3DListener *ds3DListener = NULL; // 3d listener
DS3DBUFFER dsBufferParams; // 3d buffer properties
DS3DLISTENER dsListenerParams; // 3d listener properties
/*******************************************************
* DirectMusic Interfaces
*******************************************************/
// InitDirectXAudio()
// desc: initializes the DirectX Audio component for playback
bool InitDirectXAudio(HWND hwnd)
{
char pathStr[MAX_PATH]; // path for audio file
WCHAR wcharStr[MAX_PATH];
// create the loader object
if (FAILED(CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
IID_IDirectMusicLoader8, (void**)&dmusicLoader)))
{
MessageBox(hwnd, "Unable to create the IDirectMusicLoader8 object!\nPress OK to exit",
"ERROR!", MB_OK);
return false;
}
// create the performance object
if (FAILED(CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
IID_IDirectMusicPerformance8, (void**)&dmusicPerformance)))
{
MessageBox(hwnd, "Unable to create the IDirectMusicPerformance8 object!\nPress OK to exit",
"ERROR!", MB_OK);
return false;
}
// intialize DirectMusic and DirectSound
if (FAILED(dmusicPerformance->InitAudio(NULL, NULL, NULL, DMUS_APATH_DYNAMIC_STEREO, 64,
DMUS_AUDIOF_ALL, NULL)))
{
MessageBox(hwnd, "Unable to initialize audio! Press OK to exit", "ERROR!", MB_OK);
return false;
}
// create a standard 3D audiopath
if (FAILED(dmusicPerformance->CreateStandardAudioPath(DMUS_APATH_DYNAMIC_3D,
64, TRUE, &dmusic3DAudioPath)))
{
MessageBox(hwnd, "Unable to create standard 3D audiopath! Press OK to exit",
"ERROR!", MB_OK);
return false;
}
// get the 3D buffer in the audiopath
if (FAILED(dmusic3DAudioPath->GetObjectInPath(0, DMUS_PATH_BUFFER, 0, GUID_NULL, 0,
IID_IDirectSound3DBuffer,
(void**)&ds3DBuffer)))
{
MessageBox(hwnd, "Unable to retrieve 3D buffer from audiopath! Press OK to exit",
"ERROR!", MB_OK);
return false;
}
// get the 3D buffer parameters
dsBufferParams.dwSize = sizeof(DS3DBUFFER);
ds3DBuffer->GetAllParameters(&dsBufferParams);
// set the new 3D buffer parameters
dsBufferParams.dwMode = DS3DMODE_HEADRELATIVE; // relative to the listener
ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE);
// retrieve the listener from the audiopath
if (FAILED(dmusic3DAudioPath->GetObjectInPath(0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0,
IID_IDirectSound3DListener,
(void**)&ds3DListener)))
{
MessageBox(hwnd, "Unable to retrieve the listener! Press OK to exit",
"ERROR!", MB_OK);
return false;
}
// get the listener parameters
dsListenerParams.dwSize = sizeof(DS3DLISTENER);
ds3DListener->GetAllParameters(&dsListenerParams);
// set position of listener
dsListenerParams.vPosition.x = 0.0f;
dsListenerParams.vPosition.y = 0.0f;
dsListenerParams.vPosition.z = 0.0f;
ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE);
// retrieve the current directory
GetCurrentDirectory(MAX_PATH, pathStr);
// convert to unicode string
MultiByteToWideChar(CP_ACP, 0, pathStr, -1, wcharStr, MAX_PATH);
// set the search directory
dmusicLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wcharStr, FALSE);
return true;
}
// LoadSegment()
// desc: load a segment from a file
bool LoadSegment(HWND hwnd, char *filename)
{
WCHAR wcharStr[MAX_PATH];
// convert filename to unicode string
MultiByteToWideChar(CP_ACP, 0, filename, -1, wcharStr, MAX_PATH);
// load the segment from file
if (FAILED(dmusicLoader->LoadObjectFromFile(CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wcharStr,
(void**)&dmusicSegment)))
{
MessageBox(hwnd, "Audio file not found! Press OK to exit",
"ERROR!", MB_OK);
return false;
}
// set the number of repeats for the segment to infinite
dmusicSegment->SetRepeats(DMUS_SEG_REPEAT_INFINITE);
// download the segment's instruments to the audiopath
dmusicSegment->Download(dmusic3DAudioPath);
return true;
}
// PlaySegment()
// desc: start playing a segment
void PlaySegment(IDirectMusicPerformance8* dmPerf, IDirectMusicSegment8* dmSeg)
{
// play the segment on the next beat
dmPerf->PlaySegmentEx(dmSeg, NULL, NULL, DMUS_SEGF_DEFAULT, 0,
NULL, NULL, dmusic3DAudioPath);
}
// StopSegment()
// desc: stop a segment from playing
void StopSegment(IDirectMusicPerformance8* dmPerf, IDirectMusicSegment8* dmSeg)
{
// stop the dmSeg from playing
dmPerf->StopEx(dmSeg, 0, 0);
}
// CloseDown()
// desc: shutdown music performance
void CloseDown(IDirectMusicPerformance8* dmPerf)
{
// stop the music
dmPerf->Stop(NULL, NULL, 0, 0);
// close down DirectMusic
dmPerf->CloseDown();
}
// Set3DSoundParams()
// desc: sets the 3d buffer parameters
void Set3DSoundParams(float doppler, float rolloff, float minDist, float maxDist)
{
// set doppler and rolloff parameters
dsListenerParams.flDopplerFactor = doppler;
dsListenerParams.flRolloffFactor = rolloff;
if (ds3DListener)
ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE);
// set minimum and maximum distances
dsBufferParams.flMinDistance = minDist;
dsBufferParams.flMaxDistance = maxDist;
if (ds3DBuffer)
ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE);
}
// Set3DSoundPos()
// desc: updates position of sound source (accepts OpenGL coordinates)
void Set3DSoundPos(IDirectSound3DBuffer* dsBuff, float x, float y, float z)
{
// we use -z because DirectX and OpenGL z-axes are flipped
if (dsBuff != NULL)
{
dsBuff->SetPosition(x, y, -z, DS3D_IMMEDIATE);
}
}
/******************************************************
* OpenGL Interfaces
******************************************************/
// CreateOutlineFont()
// desc: creates the outline font using the CreateFont() function
unsigned int CreateOutlineFont(char *fontName, int fontSize, float depth)
{
HFONT hFont; // windows font
unsigned int base;
base = glGenLists(256); // create storage for 96 characters
if (stricmp(fontName, "symbol") == 0)
{
hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, SYMBOL_CHARSET,
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
FF_DONTCARE | DEFAULT_PITCH, fontName);
}
else
{
hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
FF_DONTCARE | DEFAULT_PITCH, fontName);
}
if (!hFont)
return 0;
SelectObject(g_HDC, hFont);
wglUseFontOutlines(g_HDC, 0, 255, base, 0.0f, depth, WGL_FONT_POLYGONS, gmf);
return base;
}
// ClearFont()
// desc: deletes the display list for the font
void ClearFont(unsigned int base)
{
glDeleteLists(base, 256);
}
// PrintString()
// desc: displays the text in str from the font indicated by base
void PrintString(unsigned int base, char *str)
{
float length = 0;
if ((str == NULL))
return;
// center the text
for (unsigned int loop=0;loop<(strlen(str));loop++) // find length of text
{
length+=gmf[str[loop]].gmfCellIncX; // increase length by character's width
}
glTranslatef(-length/2,0.0f,0.0f); // translate to center text
// draw the text
glPushAttrib(GL_LIST_BIT);
glListBase(base);
glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
glPopAttrib();
}
// CleanUp()
// desc: application cleanup
void CleanUp()
{
ClearFont(listBase);
dmusic3DAudioPath->Release();
dmusicLoader->Release();
dmusicPerformance->Release();
dmusicSegment->Release();
}
// Initialize
// desc: initializes OpenGL
void Initialize()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // clear to black
glShadeModel(GL_SMOOTH); // use smooth shading
glEnable(GL_DEPTH_TEST); // hidden surface removal
glEnable(GL_LIGHT0); // enable light0
glEnable(GL_LIGHTING); // enable lighting
glEnable(GL_COLOR_MATERIAL); // enable color for material
listBase = CreateOutlineFont("Arial", 10, 0.25f); // load 10pt Arial font
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -