Commit 136057e2 authored by Dario Seyb's avatar Dario Seyb

actual sound output and a basic camera system

parent 20b320d7
......@@ -3,21 +3,45 @@
#include <engine/core/Context.hpp>
#include <engine/core/System.hpp>
#include <engine/events/EventSystem.hpp>
#include <engine/scene/SceneGraphSystem.hpp>
#include <engine/core/SettingsSystem.hpp>
#include <fmod.hpp>
#include <tuple>
#include <ACGL/Math/Math.hh>
#include <engine/audio/Sound.hpp>
enum class SoundMode : uint8_t {
MODE_3D,
MODE_2D
};
class AudioSystem : public System {
private:
EventSystem* m_events;
friend class Sound;
EventSystem *m_events;
SceneGraphSystem *m_scene;
SettingsSystem *m_settings;
FMOD::System *m_fmodSystem;
FMOD::Sound *sound1, *sound2, *sound3;
FMOD::Channel *channel = 0;
SoundId m_nextId;
bool m_isActive;
Entity m_listener;
FMOD::Channel* playSound(Sound* sound);
void release(FMOD::Sound* sound);
public:
CONSTRUCT_SYSTEM(AudioSystem) { }
CONSTRUCT_SYSTEM(AudioSystem), m_nextId(1), m_isActive(false) {}
void update();
void setListener(Entity listener) { m_listener = listener; }
std::shared_ptr<Sound> createSound(std::string filename, SoundMode mode);
bool startup() override;
void shutdown() override;
};
\ No newline at end of file
#pragma once;
typedef size_t SoundId;
class AudioSystem;
namespace FMOD {
class Sound;
class Channel;
}
struct Sound {
friend class AudioSystem;
public:
inline SoundId id() const { return m_id; };
~Sound();
FMOD::Channel* play();
private:
Sound(SoundId id, FMOD::Sound* ptr, AudioSystem* system) : m_id(id), m_soundPtr(ptr), m_system(system) {}
SoundId m_id;
AudioSystem* m_system;
FMOD::Sound* m_soundPtr;
};
#pragma once
#include <engine/scene/Entity.hpp>
#include <engine/audio/Sound.hpp>
namespace FMOD {
class Channel;
}
class AudioSystem;
struct SoundSource : Component<SoundSource> {
friend class AudioSystem;
public:
SoundSource() : m_sound(nullptr), m_channel(nullptr) {}
SoundSource(std::shared_ptr<Sound> sound) : m_sound(sound), m_channel(nullptr) {}
void stop();
void pause();
void play();
private:
std::shared_ptr<Sound> m_sound;
FMOD::Channel *m_channel;
};
\ No newline at end of file
......@@ -5,7 +5,7 @@
#include <engine/graphics/RendererSystem.hpp>
#include <engine/audio/AudioSystem.hpp>
#include <engine/events/EventSystem.hpp>
#include <engine/core/SimulateEvent.hpp>
class GameLoopSystem : public System {
private:
......
#pragma once
#include <engine/core/Context.hpp>
#include <engine/core/System.hpp>
class SettingsSystem : public System {
private:
std::string m_resourcePath;
std::string m_texturePath;
std::string m_geometryPath;
std::string m_shaderPath;
std::string m_soundPath;
public:
CONSTRUCT_SYSTEM(SettingsSystem, std::string resourcePath,
std::string texturePath, std::string geometryPath,
std::string shaderPath, std::string soundPath)
, m_resourcePath(resourcePath), m_texturePath(texturePath),
m_geometryPath(geometryPath), m_shaderPath(shaderPath),
m_soundPath(soundPath) {}
inline std::string getResourcePath() const { return m_resourcePath; }
inline std::string getFullTexturePath() const { return m_resourcePath + m_texturePath; }
inline std::string getFullGeometryPath() const { return m_resourcePath + m_geometryPath; }
inline std::string getFullShaderPath() const { return m_resourcePath + m_shaderPath; }
inline std::string getFullSoundPath() const { return m_resourcePath + m_soundPath; }
bool startup() override;
void shutdown() override;
};
\ No newline at end of file
#pragma once
#include <engine/events/Event.hpp>
struct SimulateEvent : public Event<SimulateEvent> {
SimulateEvent(float dt, float totalTime) : dt(dt), totalTime(totalTime) {};
float dt;
float totalTime;
};
\ No newline at end of file
#pragma once
#include <engine/scene/Entity.hpp>
#undef near
#undef far
struct Camera : Component<Camera> {
explicit Camera() : fov(75), near(0.1f), far(100) {}
explicit Camera(float fov, float near, float far) : fov(fov), near(near), far(far) { }
float fov;
float near;
float far;
};
......@@ -6,6 +6,8 @@
#include <engine/utils/Stack.hpp>
#include <engine/graphics/DrawCall.hpp>
#include <engine/graphics/Camera.hpp>
#include <engine/scene/Transform.hpp>
class RendererSystem : public System {
private:
......@@ -13,14 +15,16 @@ private:
WindowSystem *m_window;
Stack<DrawCall> m_submittedDrawCalls;
void draw(const DrawCall &drawCall);
void draw(const DrawCall &drawCall, glm::mat4 view, glm::mat4 proj);
Entity m_mainCamera;
public:
CONSTRUCT_SYSTEM(RendererSystem), m_submittedDrawCalls(kilobytes(4)) {}
bool startup() override;
void shutdown() override;
void setMainCamera(Entity cam) { m_mainCamera = cam; }
void submit(DrawCall drawCall);
void frame(double interp);
......
......@@ -26,6 +26,11 @@ public:
Entity create();
void destroy(Entity::Id id);
template <typename... Components>
EntityManager::View<Components...> entities_with_components() {
return m_entityManager.entities_with_components<Components...>();
}
void prepareDraw();
void endFrame();
......
#include <engine/audio/AudioSystem.hpp>
#include <ACGL/ACGL.hh>
#include <engine/audio/SoundSource.hpp>
#include <engine/scene/Transform.hpp>
#include <assert.h>
#define CHECK_RESULT(res, msg) if(res != FMOD_OK) {ACGL::Utils::error() << msg << std::endl; return false; }
bool AudioSystem::startup() {
RESOLVE_DEPENDENCY(m_events);
RESOLVE_DEPENDENCY(m_scene);
RESOLVE_DEPENDENCY(m_settings);
FMOD_RESULT result;
unsigned int version;
......@@ -20,13 +25,73 @@ bool AudioSystem::startup() {
result = m_fmodSystem->init(32, FMOD_INIT_NORMAL, 0);
CHECK_RESULT(result, "Could not init fmod system.");
m_isActive = true;
return true;
}
std::shared_ptr<Sound> AudioSystem::createSound(std::string filename, SoundMode mode) {
FMOD::Sound* sound;
auto result = m_fmodSystem->createSound((m_settings->getFullSoundPath() + filename).c_str(), mode == SoundMode::MODE_2D ? FMOD_2D : FMOD_3D, 0, &sound);
assert(result == FMOD_OK);
return std::shared_ptr<Sound>(new Sound(m_nextId++, sound, this));
}
FMOD::Channel* AudioSystem::playSound(Sound* sound) {
FMOD::Channel* resultChannel;
m_fmodSystem->playSound(sound->m_soundPtr, 0, false, &resultChannel);
return resultChannel;
}
void AudioSystem::update() {
if (m_listener.valid()) {
auto transform = m_listener.component<Transform>();
if (transform.valid()) {
auto pos = transform->position;
auto rot = transform->rotation;
FMOD_VECTOR fmodPos = { pos.x, pos.y, pos.z };
FMOD_VECTOR fmodVel = { 0, 0, 0 };
auto up = rot * glm::vec4(0, 1, 0, 0);
auto forward = rot * glm::vec4(0, 0, -1, 0);
FMOD_VECTOR fmodUp = { up.x, up.y, up.z };
FMOD_VECTOR fmodForward = { forward.x, forward.y, forward.z };
m_fmodSystem->set3DListenerAttributes(0, &fmodPos, &fmodVel, &fmodForward, &fmodUp);
}
}
auto drawableEntities = m_scene->entities_with_components<SoundSource, Transform>();
SoundSource::Handle soundSource;
Transform::Handle transform;
for (auto e : drawableEntities) {
e.unpack<SoundSource, Transform>(soundSource, transform);
FMOD::Sound* currentSound;
auto result = soundSource->m_channel->getCurrentSound(&currentSound);
if (result != FMOD_OK || currentSound != soundSource->m_sound->m_soundPtr) {
continue;
}
;
FMOD_VECTOR fmodPos = { transform->position.x, transform->position.y, transform->position.z };
FMOD_VECTOR fmodVel = { 0, 0, 0 };
soundSource->m_channel->set3DAttributes(&fmodPos, &fmodVel);
}
m_fmodSystem->update();
}
void AudioSystem::release(FMOD::Sound* sound) {
if (m_isActive) {
sound->release();
}
}
void AudioSystem::shutdown() {
m_isActive = false;
m_fmodSystem->release();
}
#include <engine/audio/Sound.hpp>
#include <engine/audio/AudioSystem.hpp>
#include <fmod.hpp>
Sound::~Sound() { m_system->release(m_soundPtr); }
FMOD::Channel* Sound::play() {
return m_system->playSound(this);
}
\ No newline at end of file
#include <engine/audio/SoundSource.hpp>
#include <fmod.hpp>
void SoundSource::stop() {
m_channel->stop();
}
void SoundSource::pause() {
m_channel->setPaused(true);
}
void SoundSource::play() {
bool isPaused;
m_channel->getPaused(&isPaused);
if (isPaused && m_channel) {
m_channel->setPaused(false);
} else {
m_channel = m_sound->play();
}
}
\ No newline at end of file
......@@ -94,7 +94,7 @@ void GameLoopSystem::run() {
}
while (accumulator >= dt) {
m_events->fire<"Simulate"_sh>();
m_events->fire<SimulateEvent>({float(dt)/1000, float(t)/1000});
m_audio->update();
t += dt;
accumulator -= dt;
......
#pragma once
#include <engine/core/SettingsSystem.hpp>
#include <ACGL/ACGL.hh>
#include <ACGL/Base/Settings.hh>
using namespace ACGL::Base;
bool SettingsSystem::startup() {
Settings::the()->setResourcePath(m_resourcePath);
Settings::the()->setTexturePath(m_texturePath);
Settings::the()->setGeometryPath(m_geometryPath);
Settings::the()->setShaderPath(m_shaderPath);
return true;
}
void SettingsSystem::shutdown() {
}
\ No newline at end of file
......@@ -5,6 +5,7 @@
#include <ACGL/OpenGL/Objects.hh>
#include <engine/graphics/DrawCall.hpp>
#include <engine/events/DrawEvent.hpp>
#include <glm/ext.hpp>
bool RendererSystem::startup() {
RESOLVE_DEPENDENCY(m_events);
......@@ -18,13 +19,12 @@ void RendererSystem::submit(DrawCall drawCall) {
m_submittedDrawCalls.push(drawCall);
}
void RendererSystem::draw(const DrawCall &drawCall) {
auto windowSize = m_window->getSize();
void RendererSystem::draw(const DrawCall &drawCall, glm::mat4 view, glm::mat4 proj) {
drawCall.geometry.vao->bind();
drawCall.material.prog->use();
glm::mat4 viewMatrix = glm::translate(glm::vec3(0.0f, -5.0f, -20.0f)) * drawCall.transform;
glm::mat4 viewMatrix = view * drawCall.transform;
drawCall.material.prog->setUniform("uViewMatrix", viewMatrix);
drawCall.material.prog->setUniform("uProjectionMatrix", glm::perspectiveFov<float>(75.0f, windowSize.x, windowSize.y, 0.1f, 100.0f));
drawCall.material.prog->setUniform("uProjectionMatrix", proj );
drawCall.geometry.vao->render();
}
......@@ -33,8 +33,26 @@ void RendererSystem::frame(double interp) {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!m_mainCamera.valid()) {
return;
}
Camera::Handle cam;
Transform::Handle trans;
m_mainCamera.unpack<Camera, Transform>(cam, trans);
if (!cam.valid() || !trans.valid()) {
return;
}
auto windowSize = m_window->getSize();
auto projectioMatrix = glm::perspectiveFov<float>(cam->fov, windowSize.x, windowSize.y, cam->near, cam->far);
auto viewMatrix = glm::translate<float>(trans->position) * trans->rotation;
for (size_t i = 0; i < m_submittedDrawCalls.size(); i++) {
draw(m_submittedDrawCalls[i]);
draw(m_submittedDrawCalls[i], viewMatrix, projectioMatrix);
}
openGLCriticalError();
......
......@@ -27,7 +27,7 @@ void SceneGraphSystem::prepareDraw() {
Transform::Handle transform;
for (auto e : drawableEntities) {
e.unpack<Drawable, Transform>(drawable, transform);
auto trans = transform->rotation * glm::translate(transform->position);
auto trans = glm::translate(transform->position) * transform->rotation;
m_renderer->submit({ drawable->material, drawable->geometry, trans });
}
}
......
......@@ -14,6 +14,7 @@
#include <engine/core/Context.hpp>
#include <engine/events/EventSystem.hpp>
#include <engine/core/SettingsSystem.hpp>
#include <engine/core/WindowSystem.hpp>
#include <engine/audio/AudioSystem.hpp>
#include <engine/graphics/RendererSystem.hpp>
......@@ -22,10 +23,13 @@
#include <engine/scene/Transform.hpp>
#include <engine/scene/Drawable.hpp>
#include <engine/audio/SoundSource.hpp>
#include <engine/events/MouseEvent.hpp>
#include <engine/events/KeyboardEvent.hpp>
#include <glm/ext.hpp>
using namespace ACGL::OpenGL;
using namespace ACGL::Base;
using namespace ACGL::Utils;
......@@ -35,11 +39,12 @@ int main(int argc, char *argv[]) {
Context context;
WindowSystem window(&context, 640, 480);
SettingsSystem settings(&context, "data/", "geometry/", "geometry/", "shader/", "sound/");
EventSystem events(&context);
AudioSystem audio(&context);
RendererSystem renderer(&context);
SceneGraphSystem sceneGraph(&context);
GameLoopSystem gameLoop(&context, 55, 250);
AudioSystem audio(&context);
GameLoopSystem gameLoop(&context, 60, 250);
if (!context.startup()) {
ACGL::Utils::error() << "Some systems failed to start up. Exiting!"
......@@ -47,33 +52,6 @@ int main(int argc, char *argv[]) {
return -1;
}
events.subscribe<KeyboardEvent>([](const KeyboardEvent& e) {
if (e.originalEvent.key.type == SDL_KEYDOWN) {
std::cout << (char)e.originalEvent.key.keysym.sym << std::endl;
}
});
events.subscribe<MouseEvent>([](const MouseEvent& e) {
switch (e.originalEvent.type) {
case SDL_MOUSEBUTTONDOWN:
std::cout << "Pressed button " << e.originalEvent.button.button;
break;
case SDL_MOUSEBUTTONUP:
std::cout << "Released button " << e.originalEvent.button.button;
break;
case SDL_MOUSEMOTION:
std::cout << "Moved mouse";
break;
}
std::cout << " at (" << e.originalEvent.button.x << "," << e.originalEvent.button.y << ")" << std::endl;
});
// define where shaders and textures can be found:
Settings::the()->setResourcePath("data/");
Settings::the()->setTexturePath("geometry/");
Settings::the()->setGeometryPath("geometry/");
Settings::the()->setShaderPath("shader/");
// load the geometry of the stanford bunny and build a VAO:
auto vaoBunny = VertexArrayObjectCreator("Bunny.obj").create();
vaoBunny->bind();
......@@ -94,13 +72,54 @@ int main(int argc, char *argv[]) {
Material mat;
mat.prog = normalsAsColorShader;
auto go = sceneGraph.create();
go.assign<Transform>();
go.assign<Drawable>(geom, mat);
auto bunnyObject = sceneGraph.create();
auto bunnyTransform = bunnyObject.assign<Transform>();
bunnyTransform->rotation = glm::rotate<float>(M_PI, glm::vec3(1, 0, 0));
bunnyObject.assign<Drawable>(geom, mat);
auto testSound = audio.createSound("test.wav", SoundMode::MODE_3D);
auto soundSource = bunnyObject.assign<SoundSource>(testSound);
soundSource->play();
auto playerObj = sceneGraph.create();
auto camTransform = playerObj.assign<Transform>();
playerObj.assign<Camera>(75, 0.1f, 100);
renderer.setMainCamera(playerObj);
audio.setListener(playerObj);
events.subscribe<KeyboardEvent>([](const KeyboardEvent& e) {
if (e.originalEvent.key.type == SDL_KEYDOWN) {
std::cout << (char)e.originalEvent.key.keysym.sym << std::endl;
}
});
auto windowSize = window.getSize();
events.subscribe<MouseEvent>([&soundSource, &camTransform, windowSize](const MouseEvent& e) {
switch (e.originalEvent.type) {
case SDL_MOUSEBUTTONDOWN:
std::cout << "Pressed button " << e.originalEvent.button.button;
soundSource->pause();
break;
case SDL_MOUSEBUTTONUP:
std::cout << "Released button " << e.originalEvent.button.button;
soundSource->play();
break;
case SDL_MOUSEMOTION:
break;
}
});
events.subscribe<SimulateEvent>([&bunnyTransform, &camTransform](const SimulateEvent& e) {
//bunnyTransform->rotation = glm::rotate(bunnyTransform->rotation, e.dt, glm::vec3(0, 1, 0));
camTransform->position = glm::vec3(sin(e.totalTime) * 5, 3, -10);
camTransform->rotation = glm::lookAt(camTransform->position, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
});
gameLoop.run();
sceneGraph.destroy(go.id());
sceneGraph.destroy(bunnyObject.id());
context.shutdown();
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment