Merge branch 'rk/example-opengl'

This commit is contained in:
Erik Faye-Lund 2011-01-15 16:29:43 +01:00
commit a3da5fe361
5 changed files with 133 additions and 344 deletions

13
README
View File

@ -14,18 +14,19 @@ select "Build" -> "Build Solution" from the menu to build the editor.
Compile Example
---------------
GNU Rocket contains an example client called example_bass. This is a simple
Direct3D 9.0 and BASS audio library application, that demonstrates how to
OpenGL, SDL 1.2 and BASS audio library application, that demonstrates how to
use the GNU Rocket API.
Before compiling the example, you need to make sure you have recent
Microsoft DirectX and BASS SDKs. These can be downloaded from the following
web-sites:
SDL and BASS libraries and includes. These can be downloaded from the
following web-sites:
http://msdn.microsoft.com/directx/
http://www.libsdl.org/
http://www.un4seen.com/
The BASS SDK is installed by copying bass.dll, bass.h and bass.lib to the
example_bass-folder.
The header files and libraries can be installed local to the project by
copying all .lib-files to the example_bass/lib/, all .h files to
example_bass/inclide/, and all .dll files to the example_bass/.
Once the prerequisites are installed, the example can be compiled much like
the editor; by opening examples.sln and selecting "Build" -> "Build Solution"

View File

@ -1,170 +0,0 @@
/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
* For conditions of distribution and use, see copyright notice in COPYING
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <memory>
#include <exception>
#include <cstdio>
#include <string>
#include "bass.h"
#include "sync-cpp.h"
class BassTimer : public sync::Timer {
public:
BassTimer(HSTREAM stream, float bpm, int rowsPerBeat) : stream(stream)
{
rowRate = (double(bpm) / 60) * rowsPerBeat;
}
// BASS hooks
void pause() { BASS_ChannelPause(stream); }
void play() { BASS_ChannelPlay(stream, false); }
float getTime() { return float(BASS_ChannelBytes2Seconds(stream, BASS_ChannelGetPosition(stream, BASS_POS_BYTE))); }
float getRow() { return float(getTime() * rowRate); }
void setRow(float row) { BASS_ChannelSetPosition(stream, BASS_ChannelSeconds2Bytes(stream, float(row / rowRate)), BASS_POS_BYTE); }
bool isPlaying() { return (BASS_ChannelIsActive(stream) == BASS_ACTIVE_PLAYING); }
private:
HSTREAM stream;
double rowRate;
};
#define WINDOWED 1
const unsigned int width = 800;
const unsigned int height = 600;
int main(int argc, char *argv[])
{
int ret = 0;
try {
// initialize directx
IDirect3D9 *d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d)
throw std::string("This application requires DirectX 9");
// create a window
HWND hwnd = CreateWindowEx(0, "static", "GNU Rocket Example",
WS_POPUP | WS_VISIBLE, 0, 0, width, height, 0, 0,
GetModuleHandle(0), 0);
// create the device
IDirect3DDevice9 *device = NULL;
static D3DPRESENT_PARAMETERS present_parameters = {width,
height, D3DFMT_X8R8G8B8, 3, D3DMULTISAMPLE_NONE, 0,
D3DSWAPEFFECT_DISCARD, 0, WINDOWED, 1, D3DFMT_D24S8,
0, WINDOWED ? 0 : D3DPRESENT_RATE_DEFAULT, 0
};
if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
&present_parameters, &device)))
throw std::string("Failed to create device");
// init BASS
int soundDevice = 1;
if (!BASS_Init(soundDevice, 44100, 0, hwnd, 0))
throw std::string("Failed to init bass");
// load tune
HSTREAM stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0,
BASS_MP3_SETPOS | (!soundDevice ? BASS_STREAM_DECODE : 0));
if (!stream)
throw std::string("Failed to open tune");
// let's just assume 150 BPM (this holds true for the included tune)
float bpm = 150.0f;
// setup timer and construct sync-device
BassTimer timer(stream, bpm, 8);
std::auto_ptr<sync::Device> syncDevice = std::auto_ptr<sync::Device>(
sync::createDevice("sync", timer));
if (!syncDevice.get())
throw std::string("Failed to connect to host?");
// get tracks
sync::Track &clearRTrack = syncDevice->getTrack("clear.r");
sync::Track &clearGTrack = syncDevice->getTrack("clear.g");
sync::Track &clearBTrack = syncDevice->getTrack("clear.b");
sync::Track &camRotTrack = syncDevice->getTrack("cam.rot");
sync::Track &camDistTrack = syncDevice->getTrack("cam.dist");
LPD3DXMESH cubeMesh = NULL;
if (FAILED(D3DXCreateBox(device, 1.0f, 1.0f, 1.0f, &cubeMesh, NULL)))
return -1;
// let's roll!
BASS_Start();
timer.play();
bool done = false;
while (!done) {
float row = float(timer.getRow());
if (!syncDevice->update(row))
done = true;
// setup clear color
D3DXCOLOR clearColor(clearRTrack.getValue(row), clearGTrack.getValue(row), clearBTrack.getValue(row), 0.0);
// paint the window
device->BeginScene();
device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, clearColor, 1.0f, 0);
/* D3DXMATRIX world;
device->SetTransform(D3DTS_WORLD, &world); */
float rot = camRotTrack.getValue(row);
float dist = camDistTrack.getValue(row);
D3DXVECTOR3 eye(sin(rot) * dist, 0, cos(rot) * dist);
D3DXVECTOR3 at(0, 0, 0);
D3DXVECTOR3 up(0, 1, 0);
D3DXMATRIX view;
D3DXMatrixLookAtLH(&view, &(eye + at), &at, &up);
device->SetTransform(D3DTS_WORLD, &view);
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DXToRadian(60), 4.0f / 3, 0.1f, 1000.f);
device->SetTransform(D3DTS_PROJECTION, &proj);
cubeMesh->DrawSubset(0);
device->EndScene();
device->Present(0, 0, 0, 0);
BASS_Update(0); // decrease the chance of missing vsync
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (WM_QUIT == msg.message) done = true;
if ((WM_KEYDOWN == msg.message) && (VK_ESCAPE == LOWORD(msg.wParam))) done = true;
}
}
BASS_StreamFree(stream);
BASS_Free();
device->Release();
d3d->Release();
DestroyWindow(hwnd);
} catch (const std::exception &e) {
#ifdef _CONSOLE
fprintf(stderr, "*** error: %s\n", e.what());
#else
MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
#endif
ret = -1;
} catch (const std::string &str) {
#ifdef _CONSOLE
fprintf(stderr, "*** error: %s\n", str.c_str());
#else
MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
#endif
ret = -1;
}
return ret;
}

View File

@ -1,75 +0,0 @@
#include "../sync/sync.h"
namespace sync {
class Timer {
public:
virtual void pause() = 0;
virtual void play() = 0;
virtual void setRow(float) = 0;
virtual bool isPlaying() = 0;
};
static void xpause(void *ptr, int flag)
{
Timer *timer = (Timer *)ptr;
if (flag)
timer->pause();
else
timer->play();
}
static void xset_row(void *ptr, int row)
{
Timer *timer = (Timer *)ptr;
timer->setRow(float(row));
}
static int xis_playing(void *ptr)
{
Timer *timer = (Timer *)ptr;
return timer->isPlaying();
}
class Track {
public:
float getValue(double row)
{
return sync_get_val(track, row);
}
sync_track *track;
};
class Device {
public:
Track getTrack(const char *name)
{
Track track;
track.track = sync_get_track(device, name);
return track;
}
bool update(double row)
{
sync_update(device, row);
return true;
}
sync_device *device;
sync_cb cb;
};
inline Device *createDevice(const char *prefix, Timer &timer)
{
Device *device = new Device;
device->device = sync_create_device(prefix);
if (!device->device) {
delete device;
return NULL;
}
device->cb.is_playing = xis_playing;
device->cb.pause = xpause;
device->cb.set_row = xset_row;
sync_set_callbacks(device->device, &device->cb, (void *)&timer);
return device;
}
}

View File

@ -1,25 +1,27 @@
/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
* For conditions of distribution and use, see copyright notice in COPYING
* sdl+opengl examle by rasmus/loonies http://visualizethis.tumblr.com 2011
*/
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <memory>
#include <exception>
#include <cstdio>
#include <string>
#endif
#include <SDL.h>
#undef main /* avoid SDL's nasty SDLmain hack */
#include <SDL_opengl.h>
#include <bass.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include "../sync/sync.h"
#include "bass.h"
const float bpm = 150.0f; /* beats per minute */
const int rpb = 8; /* rows per beat */
const double row_rate = (double(bpm) / 60) * rpb;
static const float bpm = 150.0f; /* beats per minute */
static const int rpb = 8; /* rows per beat */
static const double row_rate = (double(bpm) / 60) * rpb;
double bass_get_row(HSTREAM h)
static double bass_get_row(HSTREAM h)
{
QWORD pos = BASS_ChannelGetPosition(h, BASS_POS_BYTE);
double time = BASS_ChannelBytes2Seconds(h, pos);
@ -28,7 +30,7 @@ double bass_get_row(HSTREAM h)
#ifndef SYNC_PLAYER
void bass_pause(void *d, int flag)
static void bass_pause(void *d, int flag)
{
if (flag)
BASS_ChannelPause((HSTREAM)d);
@ -36,18 +38,18 @@ void bass_pause(void *d, int flag)
BASS_ChannelPlay((HSTREAM)d, false);
}
void bass_set_row(void *d, int row)
static void bass_set_row(void *d, int row)
{
QWORD pos = BASS_ChannelSeconds2Bytes((HSTREAM)d, row / row_rate);
BASS_ChannelSetPosition((HSTREAM)d, pos, BASS_POS_BYTE);
}
int bass_is_playing(void *d)
static int bass_is_playing(void *d)
{
return BASS_ChannelIsActive((HSTREAM)d) == BASS_ACTIVE_PLAYING;
}
struct sync_cb bass_cb = {
static struct sync_cb bass_cb = {
bass_pause,
bass_set_row,
bass_is_playing
@ -55,7 +57,7 @@ struct sync_cb bass_cb = {
#endif /* !defined(SYNC_PLAYER) */
void die(const char *fmt, ...)
static void die(const char *fmt, ...)
{
char temp[4096];
va_list va;
@ -63,7 +65,7 @@ void die(const char *fmt, ...)
vsnprintf(temp, sizeof(temp), fmt, va);
va_end(va);
#ifdef _CONSOLE
#if !defined(_WIN32) || defined(_CONSOLE)
fprintf(stderr, "*** error: %s\n", temp);
#else
MessageBox(NULL, temp, NULL, MB_OK | MB_ICONERROR);
@ -72,45 +74,86 @@ void die(const char *fmt, ...)
exit(EXIT_FAILURE);
}
const unsigned int width = 800;
const unsigned int height = 600;
static const unsigned int width = 800;
static const unsigned int height = 600;
SDL_Surface *setup_sdl()
{
if (SDL_Init(SDL_INIT_VIDEO))
die("%s", SDL_GetError());
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
return SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
}
void draw_cube()
{
glBegin(GL_QUADS);
// Front Face
glColor3ub(255, 0, 0);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glColor3ub(0, 255, 0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glColor3ub(0, 0, 255);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glColor3ub(255, 255, 0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glColor3ub(255, 0, 255);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glColor3ub(255, 255, 255);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
}
int main(int argc, char *argv[])
{
IDirect3D9 *d3d;
IDirect3DDevice9 *dev;
HWND hwnd;
SDL_Surface *screen;
HSTREAM stream;
static D3DPRESENT_PARAMETERS present_parameters = {
width, height, D3DFMT_X8R8G8B8, 3,
D3DMULTISAMPLE_NONE, 0, D3DSWAPEFFECT_DISCARD,
0, TRUE, 1, D3DFMT_D24S8, 0, 0
};
const struct sync_track *clear_r, *clear_g, *clear_b;
const struct sync_track *cam_rot, *cam_dist;
/* initialize directx */
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d)
die("update directx, fool.");
/* create a window */
hwnd = CreateWindowEx(0, "static", "GNU Rocket Example",
WS_POPUP | WS_VISIBLE, 0, 0, width, height, 0, 0,
GetModuleHandle(0), 0);
if (!hwnd)
die("failed to create window");
/* create the device */
if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters,
&dev)))
die("could not create device. you computer SUCKS!");
screen = setup_sdl();
/* init BASS */
if (!BASS_Init(-1, 44100, 0, hwnd, 0))
if (!BASS_Init(-1, 44100, 0, 0, 0))
die("failed to init bass");
stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0, 0);
if (!stream)
@ -133,11 +176,6 @@ int main(int argc, char *argv[])
cam_rot = sync_get_track(rocket, "cam.rot"),
cam_dist = sync_get_track(rocket, "cam.dist");
LPD3DXMESH cubeMesh = NULL;
if (FAILED(D3DXCreateBox(dev, 1.0f, 1.0f, 1.0f,
&cubeMesh, NULL)))
return -1;
/* let's roll! */
BASS_Start();
BASS_ChannelPlay(stream, false);
@ -152,44 +190,38 @@ int main(int argc, char *argv[])
/* draw */
D3DXCOLOR clearColor(
sync_get_val(clear_r, row),
sync_get_val(clear_g, row),
sync_get_val(clear_b, row),
0.0
);
dev->BeginScene();
dev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, clearColor, 1.0f, 0);
glClearColor(sync_get_val(clear_r, row),
sync_get_val(clear_g, row),
sync_get_val(clear_b, row), 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float rot = sync_get_val(cam_rot, row);
float dist = sync_get_val(cam_dist, row);
D3DXVECTOR3 eye(sin(rot) * dist, 0, cos(rot) * dist);
D3DXVECTOR3 at(0, 0, 0);
D3DXVECTOR3 up(0, 1, 0);
D3DXMATRIX view;
D3DXVECTOR3 dir = eye + at;
D3DXMatrixLookAtLH(&view, &dir, &at, &up);
dev->SetTransform(D3DTS_VIEW, &view);
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DXToRadian(60), 4.0f / 3, 0.1f, 1000.f);
dev->SetTransform(D3DTS_PROJECTION, &proj);
cubeMesh->DrawSubset(0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, 4.0f / 3, 0.1f, 100.0f);
dev->EndScene();
dev->Present(0, 0, 0, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
gluLookAt(sin(rot) * dist, 0, cos(rot) * dist,
0, 0, 0,
0, 1, 0);
glEnable(GL_DEPTH_TEST);
draw_cube();
glPopMatrix();
SDL_GL_SwapBuffers();
BASS_Update(0); /* decrease the chance of missing vsync */
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (WM_QUIT == msg.message ||
(WM_KEYDOWN == msg.message &&
VK_ESCAPE == LOWORD(msg.wParam)))
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT ||
(e.type == SDL_KEYDOWN &&
e.key.keysym.sym == SDLK_ESCAPE))
done = true;
}
}
@ -201,10 +233,7 @@ int main(int argc, char *argv[])
BASS_StreamFree(stream);
BASS_Free();
dev->Release();
d3d->Release();
DestroyWindow(hwnd);
SDL_Quit();
return 0;
}

View File

@ -41,6 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;SYNC_PLAYER"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -60,8 +61,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="d3dx9.lib d3d9.lib"
AdditionalDependencies="opengl32.lib glu32.lib SDL.lib bass.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="lib"
GenerateManifest="false"
GenerateDebugInformation="true"
SubSystem="1"
@ -117,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;SYNC_PLAYER"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -134,8 +137,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="d3dx9.lib d3d9.lib"
AdditionalDependencies="opengl32.lib glu32.lib SDL.lib bass.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
@ -191,6 +195,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -210,8 +215,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="d3dx9.lib d3d9.lib"
AdditionalDependencies="opengl32.lib glu32.lib SDL.lib bass.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="lib"
GenerateManifest="false"
GenerateDebugInformation="true"
SubSystem="1"
@ -267,6 +273,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -285,8 +292,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="d3dx9.lib d3d9.lib"
AdditionalDependencies="opengl32.lib glu32.lib SDL.lib bass.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
@ -343,10 +351,6 @@
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\bass.lib"
>
</File>
</Files>
<Globals>
</Globals>