/***************************************************
Music is played first (need to synch with billboard)
***************************************************/
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Resource files no longer necessary
//
#define IDD_ENUM 101
#define IDD_MP3Play 101
#define IDC_ADAPTERS 1000
#define IDC_DEVICES 1000
#define IDC_OUTPUT 1000
#define IDC_MODES 1001
#define IDC_STATIC1 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
///////////////////////////////////////////////////////
// Include files
#include <windows.h>
#include <stdio.h>
#include "d3d9.h"
#include "d3dx9.h"
//Music include
#include <dshow.h>
// Window handles, class and caption text
HWND g_hWnd;
HINSTANCE g_hInst;
static char g_szClass[] = "BillboardClass";
static char g_szCaption[] = "Billboard Demo by teh_pwnerer";
// The Direct3D and Device object
IDirect3D9 *g_pD3D = NULL;
IDirect3DDevice9 *g_pD3DDevice = NULL;
// DirectShow components
IGraphBuilder *g_pDSGraphBuilder = NULL;
IMediaControl *g_pDSMediaControl = NULL;
IMediaEvent *g_pDSMediaEvent = NULL;
// The 3D vertex format and descriptor
typedef struct {
FLOAT x, y, z; // 3D coordinates
FLOAT u, v; // Texture coordinates
} s3DVertex;
#define FVF3D (D3DFVF_XYZ | D3DFVF_TEX1)
// The billboard vertex buffer and texture
IDirect3DVertexBuffer9 *g_pBillboardVB = NULL;
IDirect3DTexture9 *g_pBillboardTexture = NULL;
// The floor vertex buffer and texture
IDirect3DVertexBuffer9 *g_pFloorVB = NULL;
IDirect3DTexture9 *g_pFloorTexture = NULL;
// Function prototypes
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow);
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL DoInit();
BOOL DoShutdown();
BOOL DoFrame();
BOOL SetupMeshes();
// Application prototypes ///////////////////////
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow);
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL PlaySong(char *Filename);
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
MSG Msg;
g_hInst = hInst;
// Create the window class here and register it
wcex.cbSize = sizeof(wcex);
wcex.style = CS_CLASSDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_szClass;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex))
return FALSE;
//Music
WNDCLASS wc;
// Initialize COM
CoInitialize(0);
// Register window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClass;
RegisterClass(&wc);
// Create the dialog box window and show it
g_hWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_MP3Play), 0, NULL);
UpdateWindow(g_hWnd);
ShowWindow(g_hWnd, nCmdShow);
// Create the Main Window
g_hWnd = CreateWindow(g_szClass, g_szCaption,
WS_CAPTION | WS_SYSMENU,
0, 0, 1024, 768,
NULL, NULL,
hInst, NULL );
if(!g_hWnd)
return FALSE;
ShowWindow(g_hWnd, SW_NORMAL);
UpdateWindow(g_hWnd);
// Initialize and configure DirectShow
if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&g_pDSGraphBuilder))) {
MessageBox(NULL, "Unable to create DirectShow Graph Builder object", "Error", MB_OK);
return FALSE;
}
// Query for the media control and event objects
g_pDSGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&g_pDSMediaControl);
g_pDSGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&g_pDSMediaEvent);
////////////////////////////////////////////////////////////////////////////////////////////
// Play some music
PlaySong("Doom 3 Intro.mp3");
// Clean up
UnregisterClass(g_szClass, hInst);
// Release COM system
CoUninitialize();
////////////////////////////////////////////////////////////////////////////////////////////////
// Run init function and return on error
if(DoInit() == FALSE)
return FALSE;
// Start message pump, waiting for signal to quit
ZeroMemory(&Msg, sizeof(MSG));
while(Msg.message != WM_QUIT) {
if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
if(DoFrame() == FALSE)
break;
}
// Run shutdown function
DoShutdown();
UnregisterClass(g_szClass, hInst);
return Msg.wParam;
}
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////////////
BOOL PlaySong(char *Filename)
{
// Convert filename to wide-character string
WCHAR wFilename[MAX_PATH];
mbstowcs(wFilename, Filename, MAX_PATH);
// Render the file
g_pDSGraphBuilder->RenderFile(wFilename, NULL);
// Play the file
g_pDSMediaControl->Run();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOL DoInit()
{
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
D3DXMATRIX matView, matProj;
// Do a windowed mode initialization of Direct3D
if((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
return FALSE;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
return FALSE;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pD3DDevice)))
return FALSE;
// Set the render states
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
g_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
// Create and set the projection transformation
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
// Create the meshes
SetupMeshes();
return TRUE;
}
BOOL DoShutdown()
{
// Release textures and vertex buffers
if(g_pBillboardTexture != NULL)
g_pBillboardTexture->Release();
if(g_pBillboardVB != NULL)
g_pBillboardVB->Release();
if(g_pFloorTexture != NULL)
g_pFloorTexture->Release();
if(g_pFloorVB != NULL)
g_pFloorVB->Release();
// Release device and 3D objects
if(g_pD3DDevice != NULL)
g_pD3DDevice->Release();
if(g_pD3D != NULL)
g_pD3D->Release();
return TRUE;
}
BOOL DoFrame()
{
D3DXMATRIX matView, matWorld;
float Angle;
short i, j;
// Clear device backbuffer
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0,64,128,255), 1.0f, 0);
// Update the view position
Angle = (float)timeGetTime() / 2000.0f;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3((float)cos(Angle) * 400.0f, 150.0f, (float)sin(Angle) * 200.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
if(SUCCEEDED(g_pD3DDevice->BeginScene())) {
// Draw the floor
g_pD3DDevice->SetStreamSource(0, g_pFloorVB, 0, sizeof(s3DVertex));
g_pD3DDevice->SetFVF(FVF3D);
g_pD3DDevice->SetTexture(0, g_pFloorTexture);
D3DXMatrixIdentity(&matWorld);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// Draw the billboards
g_pD3DDevice->SetStreamSource(0, g_pBillboardVB, 0, sizeof(s3DVertex));
g_pD3DDevice->SetTexture(0, g_pBillboardTexture);
g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
D3DXMatrixTranspose(&matWorld, &matView);
for(i=0;i<3;i++) {
for(j=0;j<3;j++) {
matWorld._41 = (float)i * 80.0f - 80.0f;
matWorld._42 = 0.0f;
matWorld._43 = (float)j * 80.0f - 80.0f;
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
}
}
g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
// Clear the texture usage
g_pD3DDevice->SetTexture(0, NULL);
// End the scene
g_pD3DDevice->EndScene();
}
// Display the scene
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
return TRUE;
}
BOOL SetupMeshes()
{
BYTE *Ptr;
s3DVertex BillboardVerts[4] = {
{ -42.0f, 80.0f, 0.0f, 0.0f, 0.0f },
{ 40.0f, 80.0f, 0.0f, 1.0f, 0.0f },
{ -40.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{ 40.0f, 0.0f, 0.0f, 1.0f, 1.0f }
};
s3DVertex FloorVerts[4] = {
{ -100.0f, 0.0f, 100.0f, 0.0f, 0.0f },
{ 100.0f, 0.0f, 100.0f, 1.0f, 0.0f },
{ -100.0f, 0.0f, -100.0f, 0.0f, 1.0f },
{ 100.0f, 0.0f, -100.0f, 1.0f, 1.0f }
};
// Create vertex buffers and stuff in data
// Billboard
if(FAILED(g_pD3DDevice->CreateVertexBuffer( sizeof(BillboardVerts), 0, FVF3D, D3DPOOL_DEFAULT, &g_pBillboardVB, NULL)))
return FALSE;
if(FAILED(g_pBillboardVB->Lock(0,0, (void**)&Ptr, 0)))
return FALSE;
memcpy(Ptr, BillboardVerts, sizeof(BillboardVerts));
g_pBillboardVB->Unlock();
// Floor
if(FAILED(g_pD3DDevice->CreateVertexBuffer( sizeof(FloorVerts), 0, FVF3D, D3DPOOL_DEFAULT, &g_pFloorVB, NULL)))
return FALSE;
if(FAILED(g_pFloorVB->Lock(0,0, (void**)&Ptr, 0)))
return FALSE;
memcpy(Ptr, FloorVerts, sizeof(FloorVerts));
g_pFloorVB->Unlock();
// Get textures
D3DXCreateTextureFromFile(g_pD3DDevice, "Floor.bmp", &g_pFloorTexture);
D3DXCreateTextureFromFileEx(g_pD3DDevice, "Billboard.bmp",
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A1R5G5B5,
D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE, D3DX_FILTER_TRIANGLE,
D3DCOLOR_RGBA(0,0,0,255), NULL, NULL, &g_pBillboardTexture);
return TRUE;
}
How to loop music?
I have taken an example from the book Programming Role Playing Games With DirectX (2nd Edition) and have not yet been anle to fully integrate looping music into my project. I have the full source code and .bmp, .mp3 files here (right-click). Any help would be appreciated. I'll also post my code here:
[Edited by - teh_programerer on January 28, 2006 2:40:22 PM]
It looks like you are using DirectShow there. As I recall, I used the IMediaSeeking interface of DirectShow to continually poll the play position of the song as well as move the play position around. When it reached the end-loop-point I'd reset back to the begin-loop-point.
It's been a year or so and I don't have the code with me here to check, so I really can't be sure. It sounds right though. Hope this helps.
It's been a year or so and I don't have the code with me here to check, so I really can't be sure. It sounds right though. Hope this helps.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement