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() {
Log("MainState onEnter!");
camera->setType(nf::Camera::Type::FIRST_PERSON);
ap.load("CubeTest.nfpack");
ap.load("example.nfpack");
test.create(ap["spec.obj"]);
test.setPosition(0.0, 0.0, -5.0);
plane.create(nf::BaseAssets::plane);
plane.setPosition(0.0, -2.0, 0.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);
uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
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);
sound.create(ap["sound.wav"]);
}
void MainState::update(double deltaTime) {
@ -54,6 +57,9 @@ void MainState::update(double deltaTime) {
if (button.isClicked())
app->changeState("Main State");
if (button2.isClicked())
sound.play();
if (app->isKeyPressed(NFI_ESCAPE))
app->quit();
}
@ -65,6 +71,7 @@ void MainState::render(nf::Renderer& renderer) {
renderer.render(text);
renderer.render(uiTex);
renderer.render(button);
renderer.render(button2);
renderer.render(cm);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
# Material Count: 1
newmtl None
Ns 100
Ns 10
Ka 0.8 0.8 0.8
Kd 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 norm = normalize(normals);
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 reflectDir = reflect(-lightDir, norm);
@ -121,18 +121,18 @@ void main() {
vec3 lightDir = normalize(light[i].pos - fragPos);
vec3 norm = normalize(normals);
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 reflectDir = reflect(-lightDir, norm);
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 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);
color += (((diffuse + specular) * (1.0 - shadow)) * att) * light[i].strength;
color += ((diffuse + specular) * (1.0 - shadow) * att);
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;
extensions.insert({ "obj", "png", "jpg", "shader", "ttf" });
extensions.insert({ "shader", "obj", "png", "jpg", "ttf", "wav" });
unsigned int dirCount = 0;
const std::filesystem::path workingDir = std::filesystem::current_path();
@ -99,6 +99,8 @@ int main(int argc, char* argv[]) {
if (!currDir.is_directory())
continue;
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)"\"");
std::vector<std::string> packFilenames;
std::string currFileExtension;

View File

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

View File

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

View File

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

View File

@ -40,6 +40,10 @@ namespace nf {
}
ASound::~ASound() {
}
AssetPack::AssetPack() {
}
@ -182,6 +186,16 @@ namespace nf {
m_assets[assetName] = font;
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)"\"!");
}
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) {
if (m_constructed)
Error("Button already created!");
m_constructed = true;
m_position = position;
m_string = string;

View File

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

View File

@ -18,6 +18,8 @@ namespace nf {
}
void Entity::create(Asset* modelAsset) {
if (m_constructed)
Error("Entity already created!");
m_constructed = true;
AModel* model;
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) {
if (m_constructed)
Error("Light already created!");
m_constructed = true;
m_position = position;
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) {
if (m_constructed)
Error("Text already created!");
m_constructed = true;
m_string = string;
m_position = position;

View File

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

View File

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

View File

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

View File

@ -10,15 +10,14 @@ namespace nf {
struct Asset {
char* data = nullptr;
size_t size = 0;
bool alreadyLoaded = false;
bool isBaseAsset = false;
virtual ~Asset();
};
struct ATexture : Asset {
size_t size = 0;
Texture* loadedTexture = nullptr;
~ATexture() override;
};
@ -70,6 +69,10 @@ namespace nf {
~AShader() override;
};
struct ASound : Asset {
~ASound() override;
};
class AssetPack : public NFObject {
public:
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 "UITexture.h"
#include "Button.h"
#include "Sound.h"
#include "Input.h"
namespace nf {
class Drawable;
class Shader;
class Model;
class AudioEngine;
class Renderer {
public:
@ -86,7 +88,6 @@ namespace nf {
void setWindowIcon(HANDLE hIcon);
void setWindowCursor(HCURSOR hCursor);
Renderer* getRenderer() const;
void addState(Gamestate* state, const std::string& stateName);
void addDefaultState(const std::string& stateName);
const std::string& getDefaultState();
@ -159,5 +160,7 @@ namespace nf {
//Renderer object to use OpenGL to render the current state
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
#include <thread>
#include <chrono>
#include <string>
#include <Windows.h>