Added Sound; Only supports WAV for now

This commit is contained in:
Grayson Riffe (Laptop) 2021-09-16 02:04:18 -05:00
parent 1a8320feab
commit e7cd6d8132
39 changed files with 299 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

View File

@ -3,18 +3,21 @@
void MainState::onEnter() { void MainState::onEnter() {
Log("MainState onEnter!"); Log("MainState onEnter!");
camera->setType(nf::Camera::Type::FIRST_PERSON); camera->setType(nf::Camera::Type::FIRST_PERSON);
ap.load("CubeTest.nfpack"); ap.load("example.nfpack");
test.create(ap["spec.obj"]); test.create(ap["spec.obj"]);
test.setPosition(0.0, 0.0, -5.0); test.setPosition(0.0, 0.0, -5.0);
plane.create(nf::BaseAssets::plane); plane.create(nf::BaseAssets::plane);
plane.setPosition(0.0, -2.0, 0.0); plane.setPosition(0.0, -2.0, 0.0);
plane.setScale(10.0); plane.setScale(10.0);
text.create("This is a test text.", nf::Vec2(0.1, 0.025), nf::Vec3(0.7)); text.create("This is a test text.", nf::Vec2(0.1, 0.025), nf::Vec3(0.8));
text.centered(true); text.centered(true);
uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5); uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
button.create(nf::Vec2(0.8, 0.025), "Reset"); button.create(nf::Vec2(0.8, 0.025), "Reset");
light.create(nf::Vec3(0.0, 5.0, 0.0), nf::Vec3(1.0, 1.0, 1.0), 1.5); button2.create(nf::Vec2(0.6, 0.025), "Play Sound");
light.create(nf::Vec3(-5.0, 10.0, 5.0), nf::Vec3(1.0, 1.0, 1.0), 1.0);
cm.create(nf::BaseAssets::cubemap); cm.create(nf::BaseAssets::cubemap);
sound.create(ap["sound.wav"]);
} }
void MainState::update(double deltaTime) { void MainState::update(double deltaTime) {
@ -54,6 +57,9 @@ void MainState::update(double deltaTime) {
if (button.isClicked()) if (button.isClicked())
app->changeState("Main State"); app->changeState("Main State");
if (button2.isClicked())
sound.play();
if (app->isKeyPressed(NFI_ESCAPE)) if (app->isKeyPressed(NFI_ESCAPE))
app->quit(); app->quit();
} }
@ -65,6 +71,7 @@ void MainState::render(nf::Renderer& renderer) {
renderer.render(text); renderer.render(text);
renderer.render(uiTex); renderer.render(uiTex);
renderer.render(button); renderer.render(button);
renderer.render(button2);
renderer.render(cm); renderer.render(cm);
} }

View File

@ -16,8 +16,11 @@ private:
nf::Text text; nf::Text text;
nf::UITexture uiTex; nf::UITexture uiTex;
nf::Button button; nf::Button button;
nf::Button button2;
nf::Light light; nf::Light light;
nf::Cubemap cm; nf::Cubemap cm;
nf::Sound sound;
float xrot, yrot; float xrot, yrot;
}; };

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -2,7 +2,7 @@
# Material Count: 1 # Material Count: 1
newmtl None newmtl None
Ns 100 Ns 10
Ka 0.8 0.8 0.8 Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8 Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8 Ks 0.8 0.8 0.8

View File

@ -106,7 +106,7 @@ void main() {
vec3 lightDir = normalize(light[i].pos - fragPos); vec3 lightDir = normalize(light[i].pos - fragPos);
vec3 norm = normalize(normals); vec3 norm = normalize(normals);
float diff = max(dot(norm, lightDir), 0.0); float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light[i].color * (diff * matDiff) * (light[i].strength / 2.0f); vec3 diffuse = light[i].color * diff * matDiff * (light[i].strength / 2.0f);
vec3 viewDir = normalize(camera.pos - fragPos); vec3 viewDir = normalize(camera.pos - fragPos);
vec3 reflectDir = reflect(-lightDir, norm); vec3 reflectDir = reflect(-lightDir, norm);
@ -121,18 +121,18 @@ void main() {
vec3 lightDir = normalize(light[i].pos - fragPos); vec3 lightDir = normalize(light[i].pos - fragPos);
vec3 norm = normalize(normals); vec3 norm = normalize(normals);
float diff = max(dot(norm, lightDir), 0.0); float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light[i].color * (diff * matDiff); vec3 diffuse = light[i].color * diff * matDiff * light[i].strength;
vec3 viewDir = normalize(camera.pos - fragPos); vec3 viewDir = normalize(camera.pos - fragPos);
vec3 reflectDir = reflect(-lightDir, norm); vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower); float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
vec3 specular = light[i].color * spec * matSpec; vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.5f);
float length = length(light[i].pos - fragPos); float length = length(light[i].pos - fragPos);
float att = 1.0 / (1.0 + 0.09 * length + 0.032 * (length * length)); float att = clamp(10.0 / length, 0.0, 1.0) * light[i].strength;
float shadow = calcShadowPoint(i, norm, lightDir); float shadow = calcShadowPoint(i, norm, lightDir);
color += (((diffuse + specular) * (1.0 - shadow)) * att) * light[i].strength; color += ((diffuse + specular) * (1.0 - shadow) * att);
continue; continue;
} }
} }

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -91,7 +91,7 @@ int main(int argc, char* argv[]) {
} }
std::set<std::string> extensions; std::set<std::string> extensions;
extensions.insert({ "obj", "png", "jpg", "shader", "ttf" }); extensions.insert({ "shader", "obj", "png", "jpg", "ttf", "wav" });
unsigned int dirCount = 0; unsigned int dirCount = 0;
const std::filesystem::path workingDir = std::filesystem::current_path(); const std::filesystem::path workingDir = std::filesystem::current_path();
@ -99,6 +99,8 @@ int main(int argc, char* argv[]) {
if (!currDir.is_directory()) if (!currDir.is_directory())
continue; continue;
std::string filename = currDir.path().filename().string().append(".nfpack"); std::string filename = currDir.path().filename().string().append(".nfpack");
/*if (filename == "base.nfpack")
Error("Cannot create a pack called base.nfpack!");*/
Log("Creating pack \"" + filename + (std::string)"\""); Log("Creating pack \"" + filename + (std::string)"\"");
std::vector<std::string> packFilenames; std::vector<std::string> packFilenames;
std::string currFileExtension; std::string currFileExtension;

View File

@ -197,28 +197,31 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Application.cpp" /> <ClCompile Include="src\Application.cpp" />
<ClCompile Include="src\Assets.cpp" /> <ClCompile Include="src\Assets.cpp" />
<ClCompile Include="src\AudioEngine.cpp" />
<ClCompile Include="src\Gamestate.cpp" /> <ClCompile Include="src\Gamestate.cpp" />
<ClCompile Include="src\IntroGamestate.cpp" /> <ClCompile Include="src\IntroGamestate.cpp" />
<ClCompile Include="src\Renderer\Camera.cpp" /> <ClCompile Include="src\Renderer\Camera.cpp" />
<ClCompile Include="src\Renderer\Drawable\Button.cpp" /> <ClCompile Include="src\NFObject\Button.cpp" />
<ClCompile Include="src\Renderer\Drawable\Cubemap.cpp" /> <ClCompile Include="src\NFObject\Cubemap.cpp" />
<ClCompile Include="src\Renderer\Drawable\Drawable.cpp" /> <ClCompile Include="src\Renderer\Drawable.cpp" />
<ClCompile Include="src\Renderer\Drawable\Entity.cpp" /> <ClCompile Include="src\NFObject\Entity.cpp" />
<ClCompile Include="src\Renderer\Drawable\Light.cpp" /> <ClCompile Include="src\NFObject\Light.cpp" />
<ClCompile Include="src\Renderer\Drawable\Model.cpp" /> <ClCompile Include="src\Renderer\Model.cpp" />
<ClCompile Include="src\Renderer\Drawable\Text.cpp" /> <ClCompile Include="src\NFObject\Text.cpp" />
<ClCompile Include="src\Renderer\Drawable\UIElement.cpp" /> <ClCompile Include="src\Renderer\UIElement.cpp" />
<ClCompile Include="src\Renderer\Drawable\UITexture.cpp" /> <ClCompile Include="src\NFObject\UITexture.cpp" />
<ClCompile Include="src\Renderer\IndexBuffer.cpp" /> <ClCompile Include="src\Renderer\IndexBuffer.cpp" />
<ClCompile Include="src\Renderer\Renderer.cpp" /> <ClCompile Include="src\Renderer\Renderer.cpp" />
<ClCompile Include="src\Renderer\Shader.cpp" /> <ClCompile Include="src\Renderer\Shader.cpp" />
<ClCompile Include="src\Renderer\Texture.cpp" /> <ClCompile Include="src\Renderer\Texture.cpp" />
<ClCompile Include="src\Renderer\VertexArray.cpp" /> <ClCompile Include="src\Renderer\VertexArray.cpp" />
<ClCompile Include="src\Renderer\VertexBuffer.cpp" /> <ClCompile Include="src\Renderer\VertexBuffer.cpp" />
<ClCompile Include="src\NFObject\Sound.cpp" />
<ClCompile Include="src\Utility.cpp" /> <ClCompile Include="src\Utility.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\include\Assets.h" /> <ClInclude Include="src\include\Assets.h" />
<ClInclude Include="src\include\AudioEngine.h" />
<ClInclude Include="src\include\Button.h" /> <ClInclude Include="src\include\Button.h" />
<ClInclude Include="src\include\Camera.h" /> <ClInclude Include="src\include\Camera.h" />
<ClInclude Include="src\include\Cubemap.h" /> <ClInclude Include="src\include\Cubemap.h" />
@ -236,6 +239,7 @@
<ClInclude Include="src\include\NothinFancy.h" /> <ClInclude Include="src\include\NothinFancy.h" />
<ClInclude Include="src\include\Renderer.h" /> <ClInclude Include="src\include\Renderer.h" />
<ClInclude Include="src\include\Shader.h" /> <ClInclude Include="src\include\Shader.h" />
<ClInclude Include="src\include\Sound.h" />
<ClInclude Include="src\include\Text.h" /> <ClInclude Include="src\include\Text.h" />
<ClInclude Include="src\include\Texture.h" /> <ClInclude Include="src\include\Texture.h" />
<ClInclude Include="src\include\UIElement.h" /> <ClInclude Include="src\include\UIElement.h" />

View File

@ -39,16 +39,16 @@
<ClCompile Include="src\Renderer\Shader.cpp"> <ClCompile Include="src\Renderer\Shader.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Drawable.cpp"> <ClCompile Include="src\Renderer\Drawable.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Gamestate.cpp"> <ClCompile Include="src\Gamestate.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Model.cpp"> <ClCompile Include="src\Renderer\Model.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Entity.cpp"> <ClCompile Include="src\NFObject\Entity.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Texture.cpp"> <ClCompile Include="src\Renderer\Texture.cpp">
@ -60,22 +60,28 @@
<ClCompile Include="src\Renderer\Camera.cpp"> <ClCompile Include="src\Renderer\Camera.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\UIElement.cpp"> <ClCompile Include="src\Renderer\UIElement.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Text.cpp"> <ClCompile Include="src\NFObject\Text.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\UITexture.cpp"> <ClCompile Include="src\NFObject\UITexture.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Light.cpp"> <ClCompile Include="src\NFObject\Light.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Cubemap.cpp"> <ClCompile Include="src\NFObject\Cubemap.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Renderer\Drawable\Button.cpp"> <ClCompile Include="src\NFObject\Button.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\AudioEngine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\NFObject\Sound.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -155,6 +161,12 @@
<ClInclude Include="src\include\Button.h"> <ClInclude Include="src\include\Button.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\include\AudioEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\Sound.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Natvis Include="NatvisFile.natvis" /> <Natvis Include="NatvisFile.natvis" />

View File

@ -45,8 +45,8 @@ namespace nf {
SetClassLongPtr(m_window, GCLP_HCURSOR, (LONG_PTR)hCursor); SetClassLongPtr(m_window, GCLP_HCURSOR, (LONG_PTR)hCursor);
} }
Renderer* Application::getRenderer() const { AudioEngine* Application::getAudioEngine() const {
return m_renderer; return m_audio;
} }
void Application::addState(Gamestate* state, const std::string& stateName) { void Application::addState(Gamestate* state, const std::string& stateName) {
@ -280,6 +280,7 @@ namespace nf {
void Application::runMainGameThread() { void Application::runMainGameThread() {
m_sIntro = new IntroGamestate; m_sIntro = new IntroGamestate;
m_currentState = m_sIntro; m_currentState = m_sIntro;
m_audio = new AudioEngine(this);
m_renderer = new Renderer(this); m_renderer = new Renderer(this);
m_currentState->setup(this); m_currentState->setup(this);
m_currentState->onEnter(); m_currentState->onEnter();
@ -292,6 +293,7 @@ namespace nf {
if (m_deltaTime >= m_minFrametime) { if (m_deltaTime >= m_minFrametime) {
lastFrame = std::chrono::steady_clock::now(); lastFrame = std::chrono::steady_clock::now();
m_currentState->update(m_deltaTime); m_currentState->update(m_deltaTime);
m_audio->updateSources();
m_currentState->render(*m_renderer); m_currentState->render(*m_renderer);
m_renderer->doFrame(m_currentState->getCamera(), m_deltaTime); m_renderer->doFrame(m_currentState->getCamera(), m_deltaTime);
if (m_stateChange) if (m_stateChange)
@ -311,6 +313,7 @@ namespace nf {
} }
} }
m_currentState->onExit(); m_currentState->onExit();
delete m_audio;
m_currentState->cleanup(); m_currentState->cleanup();
delete m_renderer; delete m_renderer;
} }
@ -323,6 +326,7 @@ namespace nf {
} }
if (m_renderer->isFadeOutComplete()) { if (m_renderer->isFadeOutComplete()) {
m_audio->cleanup();
m_currentState->onExit(); m_currentState->onExit();
m_currentState->cleanup(); m_currentState->cleanup();
m_currentState = m_states[m_nextState]; m_currentState = m_states[m_nextState];

View File

@ -40,6 +40,10 @@ namespace nf {
} }
ASound::~ASound() {
}
AssetPack::AssetPack() { AssetPack::AssetPack() {
} }
@ -182,6 +186,16 @@ namespace nf {
m_assets[assetName] = font; m_assets[assetName] = font;
continue; continue;
} }
if (extension == "wav") {
ASound* sound = new ASound;
sound->data = new char[assetSize];
std::memcpy(sound->data, &assetContents[0], assetSize);
sound->size = assetSize;
if (packName == "base.nfpack")
sound->isBaseAsset = true;
m_assets[assetName] = sound;
continue;
}
Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!"); Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!");
} }
if (cubemapCount % 6 != 0) if (cubemapCount % 6 != 0)

View File

@ -0,0 +1,56 @@
#include "AudioEngine.h"
#include "Application.h"
namespace nf {
AudioEngine::AudioEngine(Application* app) :
m_app(app),
m_engine(nullptr),
m_masterVoice(nullptr)
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
XAudio2Create(&m_engine, XAUDIO2_DEBUG_ENGINE);
XAUDIO2_DEBUG_CONFIGURATION debug = { 0 };
debug.TraceMask = XAUDIO2_LOG_ERRORS | XAUDIO2_LOG_WARNINGS;
debug.BreakMask = XAUDIO2_LOG_ERRORS;
m_engine->SetDebugConfiguration(&debug, 0);
m_engine->CreateMasteringVoice(&m_masterVoice);
}
void AudioEngine::updateSources() {
for (unsigned int i = 0; i < m_voices.size(); i++) {
XAUDIO2_VOICE_STATE state;
m_voices[i]->GetState(&state);
if (state.BuffersQueued == 0) {
m_voices[i]->Stop();
m_voices[i]->FlushSourceBuffers();
m_voices[i]->DestroyVoice();
m_voices.erase(m_voices.begin() + i);
i = 0;
}
}
}
IXAudio2SourceVoice* AudioEngine::getNewSourceVoice(WAVEFORMATEXTENSIBLE* fmt) {
IXAudio2SourceVoice* s;
HRESULT hr = m_engine->CreateSourceVoice(&s, &fmt->Format);
m_voices.push_back(s);
return s;
}
void AudioEngine::cleanup() {
for (unsigned int i = 0; i < m_voices.size(); i++) {
m_voices[i]->Stop();
m_voices[i]->FlushSourceBuffers();
m_voices[i]->DestroyVoice();
}
m_voices.clear();
}
AudioEngine::~AudioEngine() {
cleanup();
m_masterVoice->DestroyVoice();
m_engine->Release();
CoUninitialize();
}
}

View File

@ -22,6 +22,8 @@ namespace nf {
} }
void Button::create(const Vec2& position, std::string string, Asset* buttonAsset, double scale, double opacity) { void Button::create(const Vec2& position, std::string string, Asset* buttonAsset, double scale, double opacity) {
if (m_constructed)
Error("Button already created!");
m_constructed = true; m_constructed = true;
m_position = position; m_position = position;
m_string = string; m_string = string;

View File

@ -17,6 +17,8 @@ namespace nf {
} }
void Cubemap::create(Asset* cubemapAsset) { void Cubemap::create(Asset* cubemapAsset) {
if (m_constructed)
Error("Cubemap already created!");
m_constructed = true; m_constructed = true;
ACubemap& cm = *(ACubemap*)cubemapAsset; ACubemap& cm = *(ACubemap*)cubemapAsset;
glGenTextures(1, &m_id); glGenTextures(1, &m_id);

View File

@ -18,6 +18,8 @@ namespace nf {
} }
void Entity::create(Asset* modelAsset) { void Entity::create(Asset* modelAsset) {
if (m_constructed)
Error("Entity already created!");
m_constructed = true; m_constructed = true;
AModel* model; AModel* model;
if ((model = dynamic_cast<AModel*>(modelAsset)) == nullptr) if ((model = dynamic_cast<AModel*>(modelAsset)) == nullptr)

View File

@ -13,6 +13,8 @@ namespace nf {
} }
void Light::create(const Vec3& position, const Vec3& color, double strength, Type type) { void Light::create(const Vec3& position, const Vec3& color, double strength, Type type) {
if (m_constructed)
Error("Light already created!");
m_constructed = true; m_constructed = true;
m_position = position; m_position = position;
m_color = color; m_color = color;

View File

@ -0,0 +1,85 @@
#include "Sound.h"
#include "Application.h"
#include "Assets.h"
#include "Utility.h"
namespace nf {
Sound::Sound() :
m_constructed(false),
m_dataSize(0),
m_volume(1.0f),
m_format({ 0 }),
m_buffer(nullptr),
m_currentVoice(nullptr)
{
}
void Sound::create(Asset* soundAsset) {
if (m_constructed)
Error("Sound already created!");
m_constructed = true;
ASound* sound;
if ((sound = dynamic_cast<ASound*>(soundAsset)) == nullptr)
Error("Non-sound asset passed to Sound::create!");
std::string data(sound->data, sound->size);
if(data.find("RIFF") == std::string::npos)
Error("Sound asset not of correct format!");
unsigned int fileSize = *(unsigned int*)&data[4];
unsigned int fmtPos;
if((fmtPos = data.find("fmt")) == std::string::npos)
Error("Sound asset not of correct format!");
std::memcpy(&m_format, &data[fmtPos + 8], 16);
unsigned int dataPos;
if ((dataPos = data.find("data")) == std::string::npos)
Error("Sound asset not of correct m_format!");
m_dataSize = *(unsigned int*)&data[dataPos + 4];
m_buffer = new unsigned char[m_dataSize];
std::memcpy(m_buffer, &data[dataPos + 8], m_dataSize);
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
void Sound::setVolume(double volume) {
m_volume = (float)volume;
}
void Sound::play(bool loop) {
m_currentVoice = Application::getApp()->getAudioEngine()->getNewSourceVoice(&m_format);
m_currentVoice->SetVolume(m_volume);
XAUDIO2_BUFFER xBuffer = { 0 };
xBuffer.pAudioData = m_buffer;
xBuffer.AudioBytes = m_dataSize;
if (loop)
xBuffer.LoopCount = XAUDIO2_LOOP_INFINITE;
m_currentVoice->SubmitSourceBuffer(&xBuffer);
m_currentVoice->Start();
}
void Sound::stop() {
if (m_currentVoice) {
XAUDIO2_VOICE_STATE state;
m_currentVoice->GetState(&state);
if (state.BuffersQueued > 0) {
m_currentVoice->Stop();
m_currentVoice->FlushSourceBuffers();
m_currentVoice = nullptr;
}
}
}
void Sound::destroy() {
m_constructed = false;
m_dataSize = 0;
m_volume = 1.0f;
m_format = { 0 };
delete m_buffer;
m_currentVoice = nullptr;
}
Sound::~Sound() {
destroy();
}
}

View File

@ -18,6 +18,8 @@ namespace nf {
} }
void Text::create(const std::string& string, const Vec2& position, const Vec3& color, double opacity, double scale, Asset* font) { void Text::create(const std::string& string, const Vec2& position, const Vec3& color, double opacity, double scale, Asset* font) {
if (m_constructed)
Error("Text already created!");
m_constructed = true; m_constructed = true;
m_string = string; m_string = string;
m_position = position; m_position = position;

View File

@ -17,6 +17,8 @@ namespace nf {
} }
void UITexture::create(Asset* textureAsset, const Vec2& position, double scale, double opacity) { void UITexture::create(Asset* textureAsset, const Vec2& position, double scale, double opacity) {
if (m_constructed)
Error("UITexture already created!");
m_constructed = true; m_constructed = true;
ATexture* tex; ATexture* tex;
if ((tex = dynamic_cast<ATexture*>(textureAsset)) == nullptr) if ((tex = dynamic_cast<ATexture*>(textureAsset)) == nullptr)

View File

@ -1,5 +1,4 @@
#include "Utility.h" #include "Utility.h"
#include <thread>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>

View File

@ -7,6 +7,7 @@
#include "Config.h" #include "Config.h"
#include "IntroGamestate.h" #include "IntroGamestate.h"
#include "Renderer.h" #include "Renderer.h"
#include "AudioEngine.h"
//TODO: Document ALL frontend functions //TODO: Document ALL frontend functions
namespace nf { namespace nf {
@ -18,7 +19,7 @@ namespace nf {
void setWindowIcon(HANDLE hIcon); void setWindowIcon(HANDLE hIcon);
void setWindowCursor(HCURSOR hCursor); void setWindowCursor(HCURSOR hCursor);
Renderer* getRenderer() const; AudioEngine* getAudioEngine() const;
void addState(Gamestate* state, const std::string& stateName); void addState(Gamestate* state, const std::string& stateName);
void addDefaultState(const std::string& stateName); void addDefaultState(const std::string& stateName);
const std::string& getDefaultState(); const std::string& getDefaultState();
@ -91,5 +92,7 @@ namespace nf {
//Renderer object to use OpenGL to render the current state //Renderer object to use OpenGL to render the current state
Renderer* m_renderer; Renderer* m_renderer;
AudioEngine* m_audio;
}; };
} }

View File

@ -10,15 +10,14 @@ namespace nf {
struct Asset { struct Asset {
char* data = nullptr; char* data = nullptr;
size_t size = 0;
bool alreadyLoaded = false; bool alreadyLoaded = false;
bool isBaseAsset = false; bool isBaseAsset = false;
virtual ~Asset(); virtual ~Asset();
}; };
struct ATexture : Asset { struct ATexture : Asset {
size_t size = 0;
Texture* loadedTexture = nullptr; Texture* loadedTexture = nullptr;
~ATexture() override; ~ATexture() override;
}; };
@ -70,6 +69,10 @@ namespace nf {
~AShader() override; ~AShader() override;
}; };
struct ASound : Asset {
~ASound() override;
};
class AssetPack : public NFObject { class AssetPack : public NFObject {
public: public:
AssetPack(); AssetPack();

View File

@ -0,0 +1,23 @@
#pragma once
#include <vector>
#include <xaudio2.h>
namespace nf {
class Application;
class AudioEngine {
public:
AudioEngine(Application* app);
void updateSources();
IXAudio2SourceVoice* getNewSourceVoice(WAVEFORMATEXTENSIBLE* fmt);
void cleanup();
~AudioEngine();
private:
Application* m_app;
IXAudio2* m_engine;
IXAudio2MasteringVoice* m_masterVoice;
std::vector<IXAudio2SourceVoice*> m_voices;
};
}

View File

@ -16,12 +16,14 @@
#include "Text.h" #include "Text.h"
#include "UITexture.h" #include "UITexture.h"
#include "Button.h" #include "Button.h"
#include "Sound.h"
#include "Input.h" #include "Input.h"
namespace nf { namespace nf {
class Drawable; class Drawable;
class Shader; class Shader;
class Model; class Model;
class AudioEngine;
class Renderer { class Renderer {
public: public:
@ -86,7 +88,6 @@ namespace nf {
void setWindowIcon(HANDLE hIcon); void setWindowIcon(HANDLE hIcon);
void setWindowCursor(HCURSOR hCursor); void setWindowCursor(HCURSOR hCursor);
Renderer* getRenderer() const;
void addState(Gamestate* state, const std::string& stateName); void addState(Gamestate* state, const std::string& stateName);
void addDefaultState(const std::string& stateName); void addDefaultState(const std::string& stateName);
const std::string& getDefaultState(); const std::string& getDefaultState();
@ -159,5 +160,7 @@ namespace nf {
//Renderer object to use OpenGL to render the current state //Renderer object to use OpenGL to render the current state
Renderer* m_renderer; Renderer* m_renderer;
AudioEngine* m_audio;
}; };
} }

View File

@ -0,0 +1,28 @@
#pragma once
#include <xaudio2.h>
#include "NFObject.h"
namespace nf {
struct Asset;
class Sound : public NFObject {
public:
Sound();
void create(Asset* soundAsset);
void setVolume(double volume);
void play(bool loop = false);
void stop();
void destroy() override;
~Sound();
private:
bool m_constructed;
unsigned int m_dataSize;
float m_volume;
WAVEFORMATEXTENSIBLE m_format;
unsigned char* m_buffer;
IXAudio2SourceVoice* m_currentVoice;
};
}

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <thread>
#include <chrono> #include <chrono>
#include <string> #include <string>
#include <Windows.h> #include <Windows.h>