commit 13e092b36eb2b6402fbc7c26f7d2a6e61e3a9cbf Author: MrDev023 Date: Sat Jul 30 18:19:42 2016 +0200 Init,Add Window and 3D Sounds diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9739e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.* +!.gitignore +bin/* +CMakeFiles/* +cmake_install.cmake +CMakeCache.txt +Libraries_src/* +Makefile \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7f9b504 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,51 @@ +#require opengl,glew,glut,glu,al,alc,sndfile library + +cmake_minimum_required(VERSION 2.6) +cmake_policy(SET CMP0015 NEW) + +#Configuration du projet +project(TestSDL2) +set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE}) + + + +#Inclusion de Boost + +include_directories(/usr/include) + +link_directories(/usr/lib) + + + +#Configuration de l'exécutable + +file( + GLOB_RECURSE + source_files + src/* +) + +add_executable( + main + ${source_files} +) + + + +#Configuration de l'édition de liens + +target_link_libraries( + main + openal + alut + sndfile + SDL2main + SDL2 + SDL2_image + SDL2_ttf + SDL2_mixer + GLEW + glut + GL + GLU +) \ No newline at end of file diff --git a/a.ogg b/a.ogg new file mode 100644 index 0000000..a24cb20 Binary files /dev/null and b/a.ogg differ diff --git a/a.wav b/a.wav new file mode 100644 index 0000000..0d3cd57 Binary files /dev/null and b/a.wav differ diff --git a/clean.sh b/clean.sh new file mode 100644 index 0000000..43d5a69 --- /dev/null +++ b/clean.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm -rf CMakeFiles +rm -f CMakeCache.txt +rm -f cmake_install.cmake +rm -f Makefile diff --git a/src/audio.cpp b/src/audio.cpp new file mode 100644 index 0000000..2981b06 --- /dev/null +++ b/src/audio.cpp @@ -0,0 +1,236 @@ +#include "audio.h" + +ALCdevice* Audio::device; +ALCcontext* Audio::context; + +ALuint Audio::loadSound(const std::string Filename){ + // Ouverture du fichier audio avec libsndfile + SF_INFO FileInfos; + SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos); + if (File == NULL){ + printf("%s\n",sf_strerror(File)); + return 0; + } + + // Lecture du nombre d'échantillons et du taux d'échantillonnage (nombre d'échantillons à lire par seconde) + ALsizei NbSamples = static_cast(FileInfos.channels * FileInfos.frames); + ALsizei SampleRate = static_cast(FileInfos.samplerate); + + // Lecture des échantillons audio au format entier 16 bits signé (le plus commun) + std::vector Samples(NbSamples); + if (sf_read_short(File, &Samples[0], NbSamples) < NbSamples){ + printf("Error during load file data !\n"); + return 0; + } + + // Fermeture du fichier + sf_close(File); + + + // Détermination du format en fonction du nombre de canaux + ALenum Format; + switch (FileInfos.channels) + { + case 1 : Format = AL_FORMAT_MONO16; break; + case 2 : Format = AL_FORMAT_STEREO16; break; + case 4 : Format = alGetEnumValue("AL_FORMAT_QUAD16"); break; + case 6 : Format = alGetEnumValue("AL_FORMAT_51CHN16"); break; + case 7 : Format = alGetEnumValue("AL_FORMAT_61CHN16"); break; + case 8 : Format = alGetEnumValue("AL_FORMAT_71CHN16"); break; + default : return 0; + } + + // Création du tampon OpenAL + ALuint Buffer; + alGenBuffers(1, &Buffer); + int sec = NbSamples/FileInfos.channels/SampleRate; + int min = sec/60; + sec -= min * 60; + + // Remplissage avec les échantillons lus + alBufferData(Buffer, Format, &Samples[0], NbSamples * sizeof(ALushort), SampleRate); + + // Vérification des erreurs + if (alGetError() != AL_NO_ERROR){ + printf("OPENAL ERROR DURING LOAD FILE !\n"); + return 0; + } + + printf("Audio ressource %s loaded ! (channels: %d,SampleRate: %d,Time: %d:%d)\n",Filename.c_str(),FileInfos.channels,SampleRate,min,sec); + return Buffer; +} + +ALuint Audio::createSource(ALuint* Buffer){ + // Création d'une source + ALuint Source; + alGenSources(1, &Source); + + // On attache le tampon contenant les échantillons audio à la source + alSourcei(Source, AL_BUFFER, *Buffer); + + alSourcef(Source, AL_ROLLOFF_FACTOR, 1); + alSourcef(Source, AL_REFERENCE_DISTANCE, 5); + alSourcef(Source, AL_MAX_DISTANCE, 25); + + return Source; +} + +ALuint Audio::createSource(const std::string f){ + ALuint Buffer = Audio::loadSound(f); + ALuint a = Audio::createSource(&Buffer); + Audio::destroySound(&Buffer); + return a; +} + +void Audio::playSource(ALuint* Source){ + // Lecture du son + alSourcePlay(*Source); +} + +void Audio::destroySound(ALuint* Buffer){ + // Destruction du tampon + alDeleteBuffers(1, Buffer); +} + +void Audio::destroySource(ALuint* Source){ + // Destruction de la source + alSourcei(*Source, AL_BUFFER, 0); + alDeleteSources(1, Source); +} + +ALuint Audio::getSourceState(ALuint* Source){ + // Récupération de l'état du son + ALint Status; + alGetSourcei(*Source, AL_SOURCE_STATE, &Status); + return Status; +} + +ALfloat Audio::getSourceSecOffSet(ALuint* Source){ + // Récupération de l'état du son + ALfloat s = 0.f; + alGetSourcef(*Source, AL_SEC_OFFSET, &s); + return s; +} + +void Audio::initOpenAL(){ + if(Audio::device && Audio::context){ + printf("Audio already init"); + return; + } + + // Ouverture du device + Audio::device = alcOpenDevice(NULL); + if(!Audio::device){ + printf("Device not Open"); + exit(-1); + } + + // Création du contexte + Audio::context = alcCreateContext(Audio::device,NULL); + if(!Audio::context){ + printf("Context not created !"); + exit(-1); + } + + // Activation du contexte + if(!alcMakeContextCurrent(Audio::context)){ + printf("Context not activated !"); + exit(-1); + } + + printf("----------------------------------------------------------------\n"); + printf("Audio Successfully Initialized\n"); + printf("OpenAL Info\n"); + printf(" Version: %s\n", alGetString(AL_VERSION)); + printf(" Vendor: %s\n", alGetString(AL_VENDOR)); + printf(" Renderer: %s\n", alGetString(AL_RENDERER)); + printf("OpenAL Extensions:\n"); + std::string s(alGetString(AL_EXTENSIONS)); + std::string delimiter = " "; + size_t pos = 0; + std::string token; + while ((pos = s.find(delimiter)) != std::string::npos) { + token = s.substr(0, pos); + printf(" %s\n", token.c_str()); + s.erase(0, pos + delimiter.length()); + } + printf("----------------------------------------------------------------\n"); + + alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); + + // Définition de la position de l'écouteur (ici l'origine) + alListener3f(AL_POSITION, 0.f, 0.f, 0.f); + + // Définition de la vitesse de l'écouteur (ici nulle) + alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f); + + // Définition de l'orientation de l'écouteur (ici il regarde vers l'axe des Z) + ALfloat Orientation[] = {0.f, 0.f, 1.f, 0.f, 1.f, 0.f}; + alListenerfv(AL_ORIENTATION, Orientation); +} + +void Audio::destroyOpenAL(){ + if(!Audio::device && !Audio::context){ + printf("Audio not init"); + return; + } + // Désactivation du contexte + alcMakeContextCurrent(NULL); + + // Destruction du contexte + alcDestroyContext(Audio::context); + + // Fermeture du device + alcCloseDevice(Audio::device); +} + +bool Audio::isSourcePlaying(ALuint* Source){ + return AL_PLAYING == Audio::getSourceState(Source); +} + +void Audio::setListenerPosition(float x,float y,float z){ + // Définition de la position de l'écouteur (ici l'origine) + alListener3f(AL_POSITION, x, y, z); +} + +void Audio::setListenerVelocity(float x,float y,float z){ + // Définition de la vitesse de l'écouteur (ici nulle) + alListener3f(AL_VELOCITY, x, y, z); +} + +void Audio::setListenerRotation(float forwardx,float forwardy,float forwardz,float upx,float upy,float upz){ + // Définition de l'orientation de l'écouteur + float a[6]; + a[0] = forwardx; + a[1] = forwardy; + a[2] = forwardz; + a[3] = upx; + a[4] = upy; + a[5] = upz; + alListenerfv(AL_ORIENTATION, a); +} + +void Audio::set3DSource(ALuint* Source,bool sur){ + if(sur){ + alSourcei(*Source, AL_SOURCE_RELATIVE, AL_FALSE); + }else{ + alSourcei(*Source, AL_SOURCE_RELATIVE, AL_TRUE); + } +} + +void Audio::setSourcePosition(ALuint* Source,float x,float y,float z){ + alSource3f(*Source, AL_POSITION, x, y, z); +} + +void Audio::setSourceVelocity(ALuint* Source,float x,float y,float z){ + alSource3f(*Source, AL_VELOCITY, x, y, z); +} + + +void Audio::setSourceLooping(ALuint* Source,bool loop){ + alSourcei(*Source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); +} + +void Audio::setSourceGain(ALuint* Source,float gain){ + alSourcef(*Source, AL_GAIN, gain); +} \ No newline at end of file diff --git a/src/audio.h b/src/audio.h new file mode 100644 index 0000000..6245e08 --- /dev/null +++ b/src/audio.h @@ -0,0 +1,41 @@ +#ifndef AUDIO_H +#define AUDIO_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class Audio{ + + public: + static void initOpenAL(); + static void destroyOpenAL(); + static ALuint loadSound(const std::string); + static ALuint createSource(ALuint*); + static ALuint createSource(const std::string); + static void destroySound(ALuint*); + static void destroySource(ALuint*); + static void playSource(ALuint*); + static ALuint getSourceState(ALuint*); + static ALfloat getSourceSecOffSet(ALuint*); + static bool isSourcePlaying(ALuint*); + static void setListenerPosition(float,float,float); + static void setListenerVelocity(float,float,float); + static void setListenerRotation(float,float,float,float,float,float); + static void set3DSource(ALuint*,bool); + static void setSourcePosition(ALuint*,float,float,float); + static void setSourceVelocity(ALuint*,float,float,float); + static void setSourceLooping(ALuint*,bool); + static void setSourceGain(ALuint*,float); + + static ALCdevice* device; + static ALCcontext* context; + +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fa2e299 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,44 @@ +#include "window.h" +#include "audio.h" + +#include +#include + +void event(SDL_Event e){ + +} + +int main(int argc, char** argv){ + Window::initWindow(800,600,"Test"); + Audio::initOpenAL(); + float i = 0; + ALuint s = Audio::createSource("a.wav"); + Audio::set3DSource(&s,true); + Audio::playSource(&s); + float x,y,dis = 10.0f; + while(!Window::closeRequested){//main loop + x = cosf(i) * dis; + y = sinf(i) * dis; + + Window::pollEvent(&event); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); + glPointSize(12); + glBegin(GL_POINTS); + glColor3f(1,0,0); + glVertex2f(x/dis,y/dis); + glEnd(); + + Window::displayUpdate(); + + i+=1.0f/5000.0f; + Audio::setSourcePosition(&s,-x,0.0f,-y); + + } + Audio::destroySource(&s); + Audio::destroyOpenAL(); + Window::destroyWindow(); + return 0; +} diff --git a/src/math.cpp b/src/math.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/math.h b/src/math.h new file mode 100644 index 0000000..624e12d --- /dev/null +++ b/src/math.h @@ -0,0 +1,5 @@ +#ifndef MATH_H +#define MATH_H + + +#endif \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..96082d1 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,68 @@ +#include "window.h" + +SDL_Window* Window::pWindow = NULL; +SDL_Event Window::event; +SDL_GLContext Window::context; +bool Window::closeRequested = false; + + +void Window::initWindow(int width,int height,std::string title){ + /* Initialisation simple */ + if (SDL_Init(SDL_INIT_VIDEO) != 0 ){ + fprintf(stdout,"Échec de l'initialisation de la SDL (%s)\n",SDL_GetError()); + exit(-1); + } + + Window::pWindow = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, + height, + SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + if(!Window::pWindow){ + fprintf(stderr,"Erreur de création de la fenêtre: %s\n",SDL_GetError()); + exit(-1); + } + + context = SDL_GL_CreateContext(pWindow); + + glewExperimental = true; + GLenum err = glewInit(); + + printf("----------------------------------------------------------------\n"); + printf("Graphics Successfully Initialized\n"); + printf("OpenGL Info\n"); + printf(" Version: %s\n", glGetString(GL_VERSION)); + printf(" Vendor: %s\n", glGetString(GL_VENDOR)); + printf(" Renderer: %s\n", glGetString(GL_RENDERER)); + printf(" Shading: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + GLint n, i; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + printf("OpenGL Extensions:\n"); + for (i = 0; i < n; i++) { + printf(" %s\n", glGetStringi(GL_EXTENSIONS, i)); + } + printf("----------------------------------------------------------------\n"); + +} + +void Window::destroyWindow(){ + SDL_GL_DeleteContext ( context ) ; + SDL_DestroyWindow(pWindow); + SDL_Quit(); + exit(0); +} + +void Window::displayUpdate(){ + SDL_GL_SwapWindow(Window::pWindow); +} + +void Window::pollEvent(void(*f)(SDL_Event)){ + while (SDL_PollEvent(&Window::event)){ + switch(Window::event.type){ + case SDL_QUIT: + Window::closeRequested = true; + break; + } + f(Window::event); + } +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..0806145 --- /dev/null +++ b/src/window.h @@ -0,0 +1,28 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include + +#include +#include +#include + +class Window{ + + public: + static void initWindow(int,int,std::string); + static void destroyWindow(); + static void pollEvent(void(*f)(SDL_Event)); + static void displayUpdate(); + + static SDL_Window* pWindow; + static SDL_Event event; + static bool closeRequested; + static SDL_GLContext context; + +}; + +#endif \ No newline at end of file