diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj index 1e7f637..dec759b 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -104,6 +104,7 @@ + @@ -145,6 +146,7 @@ + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index f603064..ef3542e 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -44,6 +44,7 @@ GUI + @@ -142,6 +143,7 @@ + diff --git a/Escape-the-Dawn/GameWorld.h b/Escape-the-Dawn/GameWorld.h index 7d51816..166d283 100644 --- a/Escape-the-Dawn/GameWorld.h +++ b/Escape-the-Dawn/GameWorld.h @@ -93,6 +93,9 @@ void GameWorld::Initialize() transform->Position = glm::vec3(10.f, 0.f, 0.f); model = AddComponent(ent, "Model"); model->ModelFile = "ship.obj"; + soundEmitter->MaxDistance = FLT_MAX; + soundEmitter->ReferenceDistance = 10; + soundEmitter->ReferenceDistance = 0.1; ent = CreateEntity(); transform = AddComponent(ent, "Transform"); diff --git a/Escape-the-Dawn/GameWorld.h.orig b/Escape-the-Dawn/GameWorld.h.orig new file mode 100644 index 0000000..2a5ebb8 --- /dev/null +++ b/Escape-the-Dawn/GameWorld.h.orig @@ -0,0 +1,167 @@ +#ifndef GameWorld_h__ +#define GameWorld_h__ + +#include "World.h" +#include "Renderer.h" + +#include "Systems/CollisionSystem.h" +#include "Systems/InputSystem.h" +#include "Systems/LevelGenerationSystem.h" +#include "Systems/ParticleSystem.h" +#include "Systems/PlayerSystem.h" +#include "Systems/RenderSystem.h" +#include "Systems/SoundSystem.h" + +#include "Components/Bounds.h" +#include "Components/Camera.h" +#include "Components/Collision.h" +#include "Components/DirectionalLight.h" +#include "Components/Input.h" +#include "Components/Model.h" +#include "Components/ParticleEmitter.h" +#include "Components/PointLight.h" +#include "Components/PowerUp.h" +#include "Components/SoundEmitter.h" +#include "Components/Sprite.h" +#include "Components/Stat.h" +#include "Components/Template.h" +#include "Components/Transform.h" + +class GameWorld : public World +{ +public: + GameWorld(std::shared_ptr renderer); + void Initialize() override; + + void RegisterSystems() override; + void RegisterComponents() override; + + void Update(double dt) override; + +private: + std::shared_ptr m_Renderer; +}; + +GameWorld::GameWorld(std::shared_ptr renderer) + : m_Renderer(renderer), World() +{ + +} + +void GameWorld::Initialize() +{ + World::Initialize(); + + //AddSystem("LevelGenerationSystem"); + AddSystem("InputSystem"); + //AddSystem("CollisionSystem"); + //AddSystem("ParticleSystem"); + AddSystem("PlayerSystem"); + AddSystem("SoundSystem"); + AddSystem("RenderSystem"); + + std::shared_ptr transform; + std::shared_ptr model; + std::shared_ptr pointLight; + std::shared_ptr camera; + EntityID ent; + + ent = CreateEntity(); + transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(0.f, 4.f, 0.f); + pointLight = AddComponent(ent, "PointLight"); + pointLight->Specular = glm::vec3(1.0, 1.0, 1.0); + pointLight->Diffuse = glm::vec3(1.0, 1.0, 1.0); + pointLight->constantAttenuation = 0.f; + pointLight->linearAttenuation = 1.f; + pointLight->quadraticAttenuation = 0.f; + pointLight->spotExponent = 0.0f; + + ent = CreateEntity(); + transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(10.f, 4.f, 0.f); + pointLight = AddComponent(ent, "PointLight"); + pointLight->Specular = glm::vec3(1.0, 1.0, 1.0); + pointLight->Diffuse = glm::vec3(1.0, 1.0, 1.0); + pointLight->constantAttenuation = 0.f; + pointLight->linearAttenuation = 1.f; + pointLight->quadraticAttenuation = 0.f; + pointLight->spotExponent = 0.0f; + + ent = CreateEntity(); + transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(10.f, 0.f, 0.f); + model = AddComponent(ent, "Model"); + model->ModelFile = "ship.obj"; + + ent = CreateEntity(); + transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(0.f, 0.f, 0.f); + model = AddComponent(ent, "Model"); + model->ModelFile = "ship.obj"; +<<<<<<< HEAD +// auto soundEmitter = AddComponent(ent, "SoundEmitter"); +// soundEmitter->Gain = 1; +// soundEmitter->MaxDistance = 10; +// soundEmitter->Loop = true; +// soundEmitter->ReferenceDistance = 0.1; +// soundEmitter->Pitch = 1; +// GetSystem("SoundSystem")->PlaySound(soundEmitter, "Sounds/hallelujah.wav"); +======= + auto soundEmitter = AddComponent(ent, "SoundEmitter"); + soundEmitter->Gain = 1; + soundEmitter->MaxDistance = FLT_MAX; + soundEmitter->ReferenceDistance = 10; + soundEmitter->Loop = true; + + soundEmitter->Pitch = 1; + GetSystem("SoundSystem")->PlaySound(soundEmitter, "Sounds/hallelujah.wav"); +>>>>>>> 2c4d8fde9951da98e1e8527bba48ce3cd16d309c + + ent = CreateEntity(); + SetProperty(ent, "Name", std::string("Camera")); + transform = AddComponent(ent, "Transform"); + AddComponent(ent, "Input"); + transform->Position = glm::vec3(0.f, 2.f, 10.f); + camera = AddComponent(ent, "Camera"); + camera->FOV = 45.f; + camera->FarClip = 1000.f; + camera->NearClip = 0.01f; + transform->Orientation = glm::angleAxis(glm::radians(25.0f),glm::vec3(1,0,0)); +} + +void GameWorld::RegisterSystems() +{ + //m_SystemFactory.Register("LevelGenerationSystem", [this]() { return new Systems::LevelGenerationSystem(this); }); + m_SystemFactory.Register("InputSystem", [this]() { return new Systems::InputSystem(this, m_Renderer); }); + //m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); }); + //m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this); }); + m_SystemFactory.Register("PlayerSystem", [this]() { return new Systems::PlayerSystem(this); }); + m_SystemFactory.Register("SoundSystem", [this]() { return new Systems::SoundSystem(this); }); + m_SystemFactory.Register("RenderSystem", [this]() { return new Systems::RenderSystem(this, m_Renderer); }); +} + +void GameWorld::RegisterComponents() +{ + m_ComponentFactory.Register("Bounds", []() { return new Components::Bounds(); }); + m_ComponentFactory.Register("Camera", []() { return new Components::Camera(); }); + m_ComponentFactory.Register("Collision", []() { return new Components::Collision(); }); + m_ComponentFactory.Register("DirectionalLight", []() { return new Components::DirectionalLight(); }); + m_ComponentFactory.Register("Input", []() { return new Components::Input(); }); + m_ComponentFactory.Register("Model", []() { return new Components::Model(); }); + m_ComponentFactory.Register("ParticleEmitter", []() { return new Components::ParticleEmitter(); }); + m_ComponentFactory.Register("PointLight", []() { return new Components::PointLight(); }); + m_ComponentFactory.Register("PowerUp", []() { return new Components::PowerUp(); }); + m_ComponentFactory.Register("SoundEmitter", []() { return new Components::SoundEmitter(); }); + m_ComponentFactory.Register("Sprite", []() { return new Components::Sprite(); }); + m_ComponentFactory.Register("Stat", []() { return new Components::Stat(); }); + m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); + m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); +} + +void GameWorld::Update(double dt) +{ + World::Update(dt); +} + +#endif // GameWorld_h__ diff --git a/Escape-the-Dawn/OBJ.cpp b/Escape-the-Dawn/OBJ.cpp new file mode 100644 index 0000000..fb1ae79 --- /dev/null +++ b/Escape-the-Dawn/OBJ.cpp @@ -0,0 +1,217 @@ +#include "OBJ.h" + +OBJ::OBJ() +{ + m_CurrentMaterial = nullptr; +} + +void OBJ::LoadFromFile(std::string filename) +{ + m_Path = boost::filesystem::path(filename); + LOG_INFO("Parsing .obj \"%s\"", m_Path.c_str()); + + // http://paulbourke.net/dataformats/obj/ + std::ifstream file(m_Path.string()); + + std::string line; + while (std::getline(file, line)) { + if (line.length() == 0) + continue; + + std::stringstream ss(line); + + std::string prefix; + ss >> prefix; + + // Ignore comments + if (prefix == "#") + continue; + + // Material files + if (prefix == "mtllib") { + std::string materialFilename; + ss >> materialFilename; + m_MaterialPath = m_Path.branch_path() / materialFilename; + ParseMaterial(); + continue; + } + + // Material statement + if (prefix == "usemtl") { + std::string material; + ss >> material; + m_CurrentMaterial = &Materials[material]; + continue; + } + + // Vertices + if (prefix == "v") { + float x, y, z; + ss >> x >> y >> z; + Vertices.push_back(std::make_tuple(x, y, z)); + continue; + } + + // Normals + if (prefix == "vn") { + float x, y, z; + ss >> x >> y >> z; + Normals.push_back(std::make_tuple(x, y, z)); + } + + // Texture coordinates + if (prefix == "vt") { + float u, v, w; + ss >> u >> v >> w; + TextureCoords.push_back(std::make_tuple(u, v, w)); + } + + // Face definitions + if (prefix == "f") { + Face face; + face.Material = m_CurrentMaterial; + + std::string faceDefString; + while (ss >> faceDefString) { + std::stringstream ss2(faceDefString); + FaceDefinition faceDef = { -1, -1, -1 }; + + ss2 >> faceDef.VertexIndex; + ss2.ignore(); // Ignore first delimiter + if (!ss2) + continue; + + if (ss2.peek() == '/') { + ss2.ignore(); + ss2 >> faceDef.NormalIndex; + } else { + ss2 >> faceDef.TextureCoordIndex; + ss2.ignore(); + ss2 >> faceDef.NormalIndex; + } + face.Definitions.push_back(faceDef); + } + Faces.push_back(face); + } + } +} + +void OBJ::ParseMaterial() +{ + // http://paulbourke.net/dataformats/mtl/ + std::ifstream file(m_MaterialPath.string()); + + std::string currentMaterialName; + MaterialInfo* currentMaterial = nullptr; + + std::string line; + while (std::getline(file, line)) { + if (line.length() == 0) + continue; + + std::stringstream ss(line); + + std::string prefix; + ss >> prefix; + + // Create a new material definition + if (prefix == "newmtl") { + MaterialInfo mat = + { + "", + std::make_tuple(0.2f, 0.2f, 0.2f), + std::make_tuple(0.8f, 0.8f, 0.8f), + std::make_tuple(1.0f, 1.0f, 1.0f), + std::make_tuple(1.0f, 1.0f, 1.0f), + 1.0f, + 1.0f, + 0.0f, + 0, + }; + + ss >> currentMaterialName; + LOG_INFO("Parsing material %s", currentMaterialName); + Materials[currentMaterialName] = mat; + currentMaterial = &Materials[currentMaterialName]; + continue; + } + + if (!currentMaterial) + continue; + + // Ambient color + if (prefix == "Ka") { + float r, g, b; + ss >> r >> g >> b; + currentMaterial->AmbientColor = std::make_tuple(r, g, b); + continue; + } + // Diffuse color + if (prefix == "Kd") { + float r, g, b; + ss >> r >> g >> b; + currentMaterial->DiffuseColor = std::make_tuple(r, g, b); + continue; + } + // Specular color + if (prefix == "Ks") { + float r, g, b; + ss >> r >> g >> b; + currentMaterial->SpecularColor = std::make_tuple(r, g, b); + continue; + } + // Transmission filter + if (prefix == "Tf") { + std::stringstream ss2; + ss2 << ss.str(); + + std::string command; + ss2 >> command; + if (command == "xyz") { + // TODO: "The "Ks xyz" statement specifies the specular reflectivity using CIEXYZ values." + } + else if (command == "spectral") { + // TODO: "The "Tf spectral" statement specifies the transmission filter using a spectral curve." + } else { + float r, g, b; + ss >> r; + // G and B are optional + if (!(ss >> g >> b)) + { + g = r; + b = r; + } + currentMaterial->TransmissionFilter = std::make_tuple(r, g, b); + } + continue; + } + // Optical density + if (prefix == "Ni") { + ss >> currentMaterial->OpticalDensity; + continue; + } + // Alpha + if (prefix == "d" || prefix == "Tr") { + ss >> currentMaterial->Alpha; + continue; + } + // Shininess + if (prefix == "Ns") { + ss >> currentMaterial->Shininess; + continue; + } + // Illumination model + if (prefix == "illum") { + int illum = 0; + ss >> illum; + currentMaterial->IlluminationModel = illum; + continue; + } + // Texture file + // TODO: + if (prefix == "map_Ka" || prefix == "map_Kd") { + ss >> currentMaterial->TextureFile; + continue; + } + } +} diff --git a/Escape-the-Dawn/OBJ.h b/Escape-the-Dawn/OBJ.h new file mode 100644 index 0000000..a8f241f --- /dev/null +++ b/Escape-the-Dawn/OBJ.h @@ -0,0 +1,64 @@ +#ifndef OBJ_h__ +#define OBJ_h__ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "logging.h" + +class OBJ +{ +public: + struct MaterialInfo + { + std::string TextureFile; + std::tuple AmbientColor; + std::tuple DiffuseColor; + std::tuple SpecularColor; + std::tuple TransmissionFilter; + float OpticalDensity; + float Alpha; + float Shininess; + int IlluminationModel; + }; + + struct FaceDefinition + { + int VertexIndex; + int TextureCoordIndex; + int NormalIndex; + }; + + struct Face + { + std::vector Definitions; + MaterialInfo* Material; + }; + + OBJ(); + OBJ(std::string filename) { LoadFromFile(filename); } + + std::vector> Vertices; + std::vector> Normals; + std::vector> TextureCoords; + std::vector Faces; + std::map Materials; + + void LoadFromFile(std::string filename); + +private: + boost::filesystem::path m_Path; + boost::filesystem::path m_MaterialPath; + MaterialInfo* m_CurrentMaterial; + + void ParseMaterial(); +}; + +#endif // OBJ_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Systems/SoundSystem.h b/Escape-the-Dawn/Systems/SoundSystem.h index d56faf3..7284ad1 100644 --- a/Escape-the-Dawn/Systems/SoundSystem.h +++ b/Escape-the-Dawn/Systems/SoundSystem.h @@ -23,11 +23,10 @@ public: void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void OnComponentCreated(std::string type, std::shared_ptr component) override; void PlaySound(std::shared_ptr emitter, std::string fileName); - ALuint LoadFile(std::string fileName); - ALuint CreateSource(); private: - ALCcontext* context; + ALuint LoadFile(std::string fileName); + ALuint CreateSource(); //File-info char type[4]; @@ -37,7 +36,7 @@ private: short bytesPerSample, bitsPerSample; DWORD dataSize; - + std::map m_Source; std::map m_BufferCache; // string = fileName }; diff --git a/Escape-the-Dawn/Systems/SoundsSystem.cpp b/Escape-the-Dawn/Systems/SoundsSystem.cpp index 6f34e8c..d35e322 100644 --- a/Escape-the-Dawn/Systems/SoundsSystem.cpp +++ b/Escape-the-Dawn/Systems/SoundsSystem.cpp @@ -1,14 +1,12 @@ #include "SoundSystem.h" #include "World.h" -//#include - Systems::SoundSystem::SoundSystem(World* world) : System(world) { //initialize OpenAL ALCdevice* Device = alcOpenDevice(NULL); - + ALCcontext* context; if(Device) { context = alcCreateContext(Device, NULL); @@ -24,7 +22,7 @@ Systems::SoundSystem::SoundSystem(World* world) void Systems::SoundSystem::Update(double dt) { - + } void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) @@ -57,6 +55,7 @@ void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID par if(soundEmitter != nullptr) { ALuint source = m_Source[soundEmitter.get()]; + alSourcei(source, AL_GAIN, soundEmitter->Gain); alSourcei(source, AL_MAX_DISTANCE, soundEmitter->MaxDistance); alSourcei(source, AL_REFERENCE_DISTANCE, soundEmitter->ReferenceDistance); alSourcef(source, AL_PITCH, soundEmitter->Pitch); @@ -65,7 +64,7 @@ void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID par glm::vec3 emitterPos = transformComponent->Position; ALfloat sourcePos[3] = { emitterPos.x, emitterPos.y, -emitterPos.z }; - glm::vec3 emitterVel= transformComponent->Position; + glm::vec3 emitterVel= transformComponent->Velocity; ALfloat sourceVel[3] = { emitterVel.x, emitterVel.y, -emitterVel.z }; alSourcefv(source, AL_POSITION, sourcePos); @@ -159,7 +158,7 @@ ALuint Systems::SoundSystem::LoadFile(std::string fileName) ALuint buffer; alGenBuffers(1, &buffer); alBufferData(buffer, format, buf, dataSize, sampleRate); - //delete[] buf; + delete[] buf; m_BufferCache[fileName] = buffer; return buffer; diff --git a/Escape-the-Dawn/logging.h b/Escape-the-Dawn/logging.h index e23be53..c83bdfa 100644 --- a/Escape-the-Dawn/logging.h +++ b/Escape-the-Dawn/logging.h @@ -46,10 +46,10 @@ static void _LOG(_LOG_LEVEL logLevel, char* file, char* func, unsigned int line, if (logLevel > LOG_LEVEL) return; - char message[512]; + char message[2048]; va_list args; va_start(args, format); - vsnprintf_s(message, 512, format, args); + vsnprintf_s(message, 2048, format, args); va_end(args); if (logLevel == LOG_LEVEL_ERROR)