Chinaunix首页 | 论坛 | 博客
  • 博客访问: 283659
  • 博文数量: 48
  • 博客积分: 2931
  • 博客等级: 少校
  • 技术积分: 720
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-19 22:12
文章分类

全部博文(48)

文章存档

2012年(1)

2011年(6)

2010年(33)

2009年(5)

2008年(3)

我的朋友

分类:

2010-01-05 12:59:59

openal教程(三)
   多源
  
   你好,在这一章中,我们将在上一章的例程中加入一些元素,使他能同时
   播放超过一种的音乐。
   通常在一个优秀的游戏中有各种不同的音夹(clip),这是怎样实现的呢?
   下面将介绍。
   #include
#include
#include
#include
#include
#include
#include

// 我们需要的最大的数据缓冲.
#define NUM_BUFFERS 3

// 我们需要放三种声音.
#define NUM_SOURCES 3

// 缓冲和源标志.
#define BATTLE      0
#define GUN1        1
#define GUN2        2

// 存储声音数据.
ALuint Buffers[NUM_BUFFERS];

// 用于播放声音.
ALuint Sources[NUM_SOURCES];

// 源声音的位置.
ALfloat SourcesPos[NUM_SOURCES][3];

// 源声音的速度.
ALfloat SourcesVel[NUM_SOURCES][3];


// 听者的位置.
ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };

// 听者的速度.
ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };

// 听者的方向 (first 3 elements are "at", second  3 are "up")
ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };

在这一章中,唯一的不同是多了3种将导入Openal系统的不同的声音效果 。

ALboolean LoadALData()
{
    // 载入变量.

    ALenum format;
    ALsizei size;
    ALvoid* data;
    ALsizei freq;
    ALboolean loop;

    // 载入WAV数据.

    alGenBuffers(NUM_BUFFERS, Buffers);

    if (alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    alutLoadWAVFile("wavdata/Battle.wav", &format, &data, &size, &freq, &loop);
    alBufferData(Buffers[BATTLE], format, data, size, freq);
    alutUnloadWAV(format, data, size, freq);

    alutLoadWAVFile("wavdata/Gun1.wav", &format, &data, &size, &freq, &loop);
    alBufferData(Buffers[GUN1], format, data, size, freq);
    alutUnloadWAV(format, data, size, freq);

    alutLoadWAVFile("wavdata/Gun2.wav", &format, &data, &size, &freq, &loop);
    alBufferData(Buffers[GUN2], format, data, size, freq);
    alutUnloadWAV(format, data, size, freq);

    // 捆绑源.

    alGenSources(NUM_SOURCES, Sources);

    if (alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    alSourcei (Sources[BATTLE], AL_BUFFER,   Buffers[BATTLE]  );
    alSourcef (Sources[BATTLE], AL_PITCH,    1.0              );
    alSourcef (Sources[BATTLE], AL_GAIN,     1.0              );
    alSourcefv(Sources[BATTLE], AL_POSITION, SourcePos[BATTLE]);
    alSourcefv(Sources[BATTLE], AL_VELOCITY, SourceVel[BATTLE]);
    alSourcei (Sources[BATTLE], AL_LOOPING,  AL_TRUE          );

    alSourcei (Sources[GUN1], AL_BUFFER,   Buffers[GUN1]  );
    alSourcef (Sources[GUN1], AL_PITCH,    1.0            );
    alSourcef (Sources[GUN1], AL_GAIN,     1.0            );
    alSourcefv(Sources[GUN1], AL_POSITION, SourcePos[GUN1]);
    alSourcefv(Sources[GUN1], AL_VELOCITY, SourceVel[GUN1]);
    alSourcei (Sources[GUN1], AL_LOOPING,  AL_FALSE       );

    alSourcei (Sources[GUN2], AL_BUFFER,   Buffers[GUN2]  );
    alSourcef (Sources[GUN2], AL_PITCH,    1.0            );
    alSourcef (Sources[GUN2], AL_GAIN,     1.0            );
    alSourcefv(Sources[GUN2], AL_POSITION, SourcePos[GUN2]);
    alSourcefv(Sources[GUN2], AL_VELOCITY, SourceVel[GUN2]);
    alSourcei (Sources[GUN2], AL_LOOPING,  AL_FALSE       );

    // 做错误检测并返回

    if( alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    return AL_TRUE;
}
首先,我们导入文件数据到3个缓冲区,然后把3个缓冲区和3个源锁在
一起。唯一的不同是文件“battle.wav”在不停止时循环。
void SetListenervalues()
{
    alListenerfv(AL_POSITION,    ListenerPos);
    alListenerfv(AL_VELOCITY,    ListenerVel);
    alListenerfv(AL_ORIENTATION, ListenerOri);
}

void KillALData()
{
    alDeleteBuffers(NUM_BUFFERS, &Buffers[0]);
    alDeleteSources(NUM_SOURCES, &Sources[0]);
    alutExit();
}
在这段代码中,我们没有改变。
int main(int argc, char *argv[])
{
    // Initialize OpenAL and clear the error bit.
    alutInit(NULL, 0);
    alGetError();

    // Load the wav data.
    if (LoadALData() == AL_FALSE)
        return 0;

    SetListenervalues();

    // Setup an exit procedure.
    atexit(KillALData);

    // Begin the battle sample to play.
    alSourcePlay(Sources[BATTLE]);

    // Go through all the sources and check that they are playing.
    // Skip the first source because it is looping anyway (will always be playing).
    ALint play;

    while (!kbhit())
    {
        for (int i = 1; i < NUM_SOURCES; i++)
        {
                alGetSourcei(Sources[i], AL_SOURCE_STATE, &play);

                if (play != AL_PLAYING)
                {
                    // Pick a random position around the listener to play the source.

                double theta = (double) (rand() % 360) * 3.14 / 180.0;

                SourcePos[i][0] = -float(cos(theta));
                SourcePos[i][1] = -float(rand()%2);
                SourcePos[i][2] = -float(sin(theta));

                alSourcefv(Sources[i], AL_POSITION, SourcePos[i] );

                alSourcePlay(Sourcev[i]);
            }
        }
    }

    return 0;
}
这段是这篇文章最有趣的地方。我们在这里将播放。如果他不播放,我们将
在3D空间中选一个点播放(点击)。
阅读(1730) | 评论(0) | 转发(0) |
0

上一篇:openal教程(二)

下一篇:OpenAL教程(四)

给主人留下些什么吧!~~