Added Sound; Only supports WAV for now
This commit is contained in:
1 parent
1a8320feab
commit
e7cd6d8132
39 files changed
+299
-40
No files matched your search
@@ -0,0 +1,139 @@
|
||||
#include "Button.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "Input.h"
|
||||
#include "Texture.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace nf {
|
||||
Button::Button() :
|
||||
m_idleTexture(nullptr),
|
||||
m_hoverTexture(nullptr),
|
||||
m_pressedTexture(nullptr),
|
||||
m_currentTexture(nullptr),
|
||||
m_scale(1.0f),
|
||||
m_opacity(1.0f),
|
||||
m_clicked(false),
|
||||
m_triggered(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
if (m_string.size()) {
|
||||
m_text.create(m_string, Vec2(0.0, 0.0));
|
||||
m_text.centered(true);
|
||||
}
|
||||
m_scale = (float)scale * 0.3f;
|
||||
m_opacity = (float)opacity;
|
||||
m_text.setOpacity(m_opacity);
|
||||
AButton* button;
|
||||
if ((button = dynamic_cast<AButton*>(buttonAsset)) == nullptr)
|
||||
Error("Non-button asset passed to Button::create!");
|
||||
m_idleTexture = new Texture(&button->idleTex);
|
||||
m_hoverTexture = new Texture(&button->hoverTex);
|
||||
m_pressedTexture = new Texture(&button->pressedTex);
|
||||
if (!((m_idleTexture->getDimensions() == m_hoverTexture->getDimensions()) && (m_idleTexture->getDimensions() == m_pressedTexture->getDimensions()))) {
|
||||
Error("Button images are not the same size!");
|
||||
}
|
||||
float tc[3][4] = {
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0
|
||||
};
|
||||
m_vao = new VertexArray;
|
||||
m_vao->addBuffer(nullptr, 0);
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
m_vao->addBuffer(tc, sizeof(tc));
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
|
||||
const char* Button::identity() {
|
||||
return "button";
|
||||
}
|
||||
|
||||
void Button::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, Application* app, Shader* textShader) {
|
||||
float posX = (float)m_position.x * windowWidth, posY = (float)m_position.y * windowHeight;
|
||||
float scale = windowWidth / 5.0f;
|
||||
|
||||
Vec2 texDim = m_idleTexture->getDimensions();
|
||||
float height = scale * m_scale;
|
||||
float width = ((float)texDim.x / (float)texDim.y) * scale * m_scale;
|
||||
if (m_centeredX)
|
||||
posX = ((float)windowWidth - width) / 2;
|
||||
if (m_centeredY)
|
||||
posY = ((float)windowHeight - height) / 2;
|
||||
|
||||
m_currentTexture = m_idleTexture;
|
||||
Vec2 mousePos = app->getMousePos();
|
||||
m_triggered = false;
|
||||
if (mousePos.x >= posX && mousePos.x <= posX + width && mousePos.y <= windowHeight - posY && mousePos.y >= (windowHeight - posY) - height) {
|
||||
m_currentTexture = m_hoverTexture;
|
||||
if (app->isMouse(NFI_LEFTMOUSE))
|
||||
m_clicked = true;
|
||||
else if (m_clicked) {
|
||||
m_triggered = true;
|
||||
m_clicked = false;
|
||||
}
|
||||
}
|
||||
else m_clicked = false;
|
||||
|
||||
if (m_clicked)
|
||||
m_currentTexture = m_pressedTexture;
|
||||
float vb[] = {
|
||||
posX, posY + height,
|
||||
posX, posY,
|
||||
posX + width, posY,
|
||||
posX, posY + height,
|
||||
posX + width, posY,
|
||||
posX + width, posY + height
|
||||
};
|
||||
|
||||
m_currentTexture->bind();
|
||||
m_vao->setBufferData(0, vb, sizeof(vb));
|
||||
shader->setUniform("opacity", m_opacity);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
if (m_string.size()) {
|
||||
Vec2 pos = Vec2(posX, posY);
|
||||
m_text.render(textShader, windowWidth, windowHeight, true, width, height, pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool Button::isClicked() {
|
||||
return m_triggered;
|
||||
}
|
||||
|
||||
void Button::destroy() {
|
||||
m_constructed = false;
|
||||
m_clicked = false;
|
||||
m_position = Vec2(0.0);
|
||||
m_centeredX = m_centeredY = false;
|
||||
if (!m_idleTexture->isBaseAsset())
|
||||
delete m_idleTexture;
|
||||
if (!m_hoverTexture->isBaseAsset())
|
||||
delete m_hoverTexture;
|
||||
if (!m_pressedTexture->isBaseAsset())
|
||||
delete m_pressedTexture;
|
||||
delete m_vao;
|
||||
}
|
||||
|
||||
Button::~Button() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
#include "Cubemap.h"
|
||||
|
||||
#include <vector>
|
||||
#include "GL/glew.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "Shader.h"
|
||||
#include "Assets.h"
|
||||
|
||||
namespace nf {
|
||||
Cubemap::Cubemap() :
|
||||
m_constructed(false),
|
||||
m_id(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cubemap::create(Asset* cubemapAsset) {
|
||||
if (m_constructed)
|
||||
Error("Cubemap already created!");
|
||||
m_constructed = true;
|
||||
ACubemap& cm = *(ACubemap*)cubemapAsset;
|
||||
glGenTextures(1, &m_id);
|
||||
glActiveTexture(GL_TEXTURE12);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
|
||||
struct CMFace {
|
||||
CMFace(unsigned char* d, unsigned int w, unsigned int h, unsigned int nc) :
|
||||
data(d),
|
||||
width(w),
|
||||
height(h),
|
||||
nChannels(nc)
|
||||
{
|
||||
|
||||
}
|
||||
unsigned char* data;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int nChannels;
|
||||
};
|
||||
std::vector<CMFace> faces;
|
||||
int tempWidth, tempHeight, tempNChannels;
|
||||
unsigned char* tempData;
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.leftData, cm.leftSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.rightData, cm.rightSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.topData, cm.topSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.bottomData, cm.bottomSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.backData, cm.backSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
tempData = stbi_load_from_memory((unsigned char*)cm.frontData, cm.frontSize, &tempWidth, &tempHeight, &tempNChannels, 0);
|
||||
faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
|
||||
for (unsigned int i = 0; i < faces.size(); i++) {
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, faces[i].width, faces[i].height, 0, faces[i].nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, faces[i].data);
|
||||
stbi_image_free(faces[i].data);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float vb[] = {
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f
|
||||
};
|
||||
m_vao = new VertexArray;
|
||||
m_vao->addBuffer(vb, sizeof(vb));
|
||||
m_vao->push<float>(3);
|
||||
m_vao->finishBufferLayout();
|
||||
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
|
||||
bool Cubemap::isConstructed() {
|
||||
return m_constructed;
|
||||
}
|
||||
|
||||
void Cubemap::render(Shader* shader) {
|
||||
m_vao->bind();
|
||||
glActiveTexture(GL_TEXTURE12);
|
||||
shader->setUniform("cm", 12);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
|
||||
void Cubemap::destroy() {
|
||||
if (m_constructed)
|
||||
glDeleteTextures(1, &m_id);
|
||||
m_constructed = false;
|
||||
m_id = 0;
|
||||
delete m_vao;
|
||||
}
|
||||
|
||||
Cubemap::~Cubemap() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "Entity.h"
|
||||
|
||||
#include<vector>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Model.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace nf {
|
||||
Entity::Entity() :
|
||||
m_constructed(false),
|
||||
m_model(nullptr),
|
||||
m_position(0.0),
|
||||
m_rotation(0.0),
|
||||
m_scale(1.0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Entity::create(Asset* modelAsset) {
|
||||
if (m_constructed)
|
||||
Error("Entity already created!");
|
||||
m_constructed = true;
|
||||
AModel* model;
|
||||
if ((model = dynamic_cast<AModel*>(modelAsset)) == nullptr)
|
||||
Error("Non-model asset passed to Entity::create!");
|
||||
if (model->alreadyLoaded) {
|
||||
m_model = model->loadedModel;
|
||||
}
|
||||
else {
|
||||
m_model = new Model(model);
|
||||
model->alreadyLoaded = true;
|
||||
model->loadedModel = m_model;
|
||||
}
|
||||
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
|
||||
bool Entity::isConstructed() {
|
||||
return m_constructed;
|
||||
}
|
||||
|
||||
void Entity::setPosition(double x, double y, double z) {
|
||||
m_position = { x, y, z };
|
||||
}
|
||||
|
||||
void Entity::setPosition(const Vec3& position) {
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
void Entity::setRotation(double x, double y, double z) {
|
||||
m_rotation = { x, y, z };
|
||||
}
|
||||
|
||||
void Entity::setRotation(const Vec3& rotation) {
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
void Entity::setScale(double x) {
|
||||
m_scale = { x, x, x };
|
||||
}
|
||||
|
||||
void Entity::setScale(double x, double y, double z) {
|
||||
m_scale = { x, y, z };
|
||||
}
|
||||
|
||||
void Entity::setScale(const Vec3& scale) {
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
void Entity::render(Shader* shader, bool onlyDepth) {
|
||||
shader->bind();
|
||||
setModelMatrix(shader);
|
||||
m_model->render(shader, onlyDepth);
|
||||
}
|
||||
|
||||
Model* Entity::getModel() const {
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void Entity::setModelMatrix(Shader* shader) {
|
||||
glm::mat4 model(1.0f);
|
||||
model = glm::translate(model, glm::vec3(m_position.x, m_position.y, m_position.z));
|
||||
model = glm::rotate(model, glm::radians((float)m_rotation.x), glm::vec3(1.0, 0.0, 0.0));
|
||||
model = glm::rotate(model, glm::radians((float)m_rotation.y), glm::vec3(0.0, 1.0, 0.0));
|
||||
model = glm::rotate(model, glm::radians((float)m_rotation.z), glm::vec3(0.0, 0.0, 1.0));
|
||||
model = glm::scale(model, glm::vec3(m_scale.x, m_scale.y, m_scale.z));
|
||||
shader->setUniform("model", model);
|
||||
}
|
||||
|
||||
void Entity::destroy() {
|
||||
m_constructed = false;
|
||||
if (m_model && !m_model->isBaseAsset())
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
m_position = Vec3(0.0);
|
||||
m_rotation = Vec3(0.0);
|
||||
m_scale = Vec3(1.0);
|
||||
}
|
||||
|
||||
Entity::~Entity() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "Light.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace nf {
|
||||
Light::Light() :
|
||||
m_constructed(false),
|
||||
m_type(Type::POINT),
|
||||
m_strength(1.0f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
m_type = type;
|
||||
m_strength = (float)strength;
|
||||
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
|
||||
bool Light::isConstructed() {
|
||||
return m_constructed;
|
||||
}
|
||||
|
||||
void Light::setPosition(const Vec3& position) {
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
void Light::setColor(const Vec3& color) {
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
void Light::setStrength(double strength) {
|
||||
m_strength = (float)strength;
|
||||
}
|
||||
|
||||
void Light::bind(Shader* shader, unsigned int lightNumber) {
|
||||
std::string stringPos = "light[";
|
||||
stringPos += std::to_string(lightNumber);
|
||||
stringPos += "].";
|
||||
std::string lightPos = stringPos + (std::string)"pos";
|
||||
std::string lightColor = stringPos + (std::string)"color";
|
||||
std::string lightStrength = stringPos + (std::string)"strength";
|
||||
glm::vec3 pos(m_position.x, m_position.y, m_position.z);
|
||||
glm::vec3 color(m_color.x, m_color.y, m_color.z);
|
||||
shader->setUniform(lightPos, pos);
|
||||
shader->setUniform(lightColor, color);
|
||||
shader->setUniform(lightStrength, m_strength);
|
||||
std::string lightType = stringPos + (std::string)"type";
|
||||
switch (m_type) {
|
||||
case Type::DIRECTIONAL: {
|
||||
shader->setUniform(lightType, 1);
|
||||
break;
|
||||
}
|
||||
case Type::POINT: {
|
||||
shader->setUniform(lightType, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Light::Type Light::getType() {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const Vec3& Light::getPosition() {
|
||||
return m_position;
|
||||
}
|
||||
|
||||
const Vec3& Light::getColor() {
|
||||
return m_color;
|
||||
}
|
||||
|
||||
const float Light::getStrength() {
|
||||
return m_strength;
|
||||
}
|
||||
|
||||
void Light::destroy() {
|
||||
m_constructed = false;
|
||||
m_type = Type::POINT;
|
||||
m_position = Vec3(0.0);
|
||||
m_color = Vec3(0.0);
|
||||
m_strength = 1.0f;
|
||||
}
|
||||
|
||||
Light::~Light() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
#include "Text.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "ft2build.h"
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "Application.h"
|
||||
#include "UIElement.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace nf {
|
||||
Text::Text() :
|
||||
m_font(nullptr),
|
||||
m_scale(1.0f),
|
||||
m_opacity(1.0f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
m_color = color;
|
||||
m_scale = (float)scale;
|
||||
m_opacity = (float)opacity;
|
||||
AFont& newFont = *(AFont*)font;
|
||||
if (newFont.alreadyLoaded) {
|
||||
m_font = newFont.loadedFont;
|
||||
}
|
||||
else {
|
||||
m_font = new Font;
|
||||
FT_Library ft;
|
||||
if (FT_Init_FreeType(&ft))
|
||||
Error("Could not initialize FreeType!");
|
||||
FT_Face face;
|
||||
if (FT_New_Memory_Face(ft, (const unsigned char*)newFont.data, newFont.size, 0, &face))
|
||||
Error("Could not load font!");
|
||||
FT_Set_Pixel_Sizes(face, 0, 160);
|
||||
for (unsigned char c = 0; c < 128; c++) {
|
||||
FT_Load_Char(face, c, FT_LOAD_RENDER);
|
||||
unsigned int tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
Character ch = { tex, Vec2((float)face->glyph->bitmap.width, (float)face->glyph->bitmap.rows), Vec2(face->glyph->bitmap_left, face->glyph->bitmap_top), (unsigned int)face->glyph->advance.x };
|
||||
m_font->m_characters[c] = ch;
|
||||
}
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(ft);
|
||||
newFont.alreadyLoaded = true;
|
||||
newFont.loadedFont = m_font;
|
||||
m_font->isBase = newFont.isBaseAsset;
|
||||
}
|
||||
m_vao = new VertexArray;
|
||||
m_vao->addBuffer(nullptr, 0);
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
m_vao->addBuffer(nullptr, 0);
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
|
||||
if (m_string == "NFLoadingText") {
|
||||
m_string = "Loading...";
|
||||
}
|
||||
else {
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Text::setText(const std::string& string) {
|
||||
m_string = string;
|
||||
}
|
||||
|
||||
void Text::setColor(const Vec3& color) {
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
void Text::setScale(double scale) {
|
||||
m_scale = (float)scale;
|
||||
}
|
||||
|
||||
void Text::setOpacity(double opacity) {
|
||||
m_opacity = (float)opacity;
|
||||
}
|
||||
|
||||
const char* Text::identity() {
|
||||
return "text";
|
||||
}
|
||||
|
||||
void Text::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, bool onButton, float buttonWidth, float buttonHeight, const Vec2& buttonPos) {
|
||||
float scale = windowWidth / 4000.0f;
|
||||
if (onButton)
|
||||
scale *= buttonWidth / 400.0f;
|
||||
float currX = (float)m_position.x * windowWidth, currY = (float)m_position.y * windowHeight;
|
||||
std::string::const_iterator si;
|
||||
if (m_centeredX || m_centeredY) {
|
||||
float textWidth = 0.0f;
|
||||
float textHeight = 0.0f;
|
||||
for (si = m_string.begin(); si != m_string.end(); si++) {
|
||||
Character& c = m_font->m_characters[*si];
|
||||
textWidth += (c.advance >> 6) * scale * m_scale;
|
||||
if (c.size.y >= textHeight)
|
||||
textHeight = (float)c.size.y * scale * m_scale;
|
||||
}
|
||||
if (m_centeredX)
|
||||
currX = ((float)windowWidth - textWidth) / 2;
|
||||
if (m_centeredY)
|
||||
currY = ((float)windowHeight - textHeight) / 2;
|
||||
|
||||
if (onButton) {
|
||||
while (textWidth > buttonWidth - 20) {
|
||||
scale -= 0.01f;
|
||||
textHeight = textWidth = 0.0f;
|
||||
for (si = m_string.begin(); si != m_string.end(); si++) {
|
||||
Character& c = m_font->m_characters[*si];
|
||||
textWidth += (c.advance >> 6) * scale * m_scale;
|
||||
if (c.size.y >= textHeight)
|
||||
textHeight = (float)c.size.y * scale * m_scale;
|
||||
}
|
||||
}
|
||||
currX = (((float)buttonWidth - textWidth) / 2) + (float)buttonPos.x;
|
||||
currY = (((float)buttonHeight - textHeight) / 2) + (float)buttonPos.y;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 color = { m_color.x, m_color.y, m_color.z };
|
||||
shader->setUniform("textColor", color);
|
||||
shader->setUniform("opacity", m_opacity);
|
||||
for (si = m_string.begin(); si != m_string.end(); si++) {
|
||||
Character& c = m_font->m_characters[*si];
|
||||
float x = currX + (float)c.bearing.x * scale * m_scale;
|
||||
float y = currY - float(c.size.y - c.bearing.y) * scale * m_scale;
|
||||
float w = (float)c.size.x * scale * m_scale;
|
||||
float h = (float)c.size.y * scale * m_scale;
|
||||
float vb[] = {
|
||||
x, y + h,
|
||||
x, y,
|
||||
x + w, y,
|
||||
x, y + h,
|
||||
x + w, y,
|
||||
x + w, y + h
|
||||
};
|
||||
float tc[] = {
|
||||
0.0, 0.0,
|
||||
0.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 1.0,
|
||||
1.0, 0.0
|
||||
};
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D, c.texID);
|
||||
m_vao->bind();
|
||||
m_vao->setBufferData(0, vb, sizeof(vb));
|
||||
m_vao->setBufferData(1, tc, sizeof(tc));
|
||||
shader->setUniform("text", 10);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
currX += (c.advance >> 6) * scale * m_scale;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::destroy() {
|
||||
m_constructed = false;
|
||||
m_position = Vec2(0.0);
|
||||
m_centeredX = m_centeredY = false;
|
||||
m_string = std::string();
|
||||
if (!m_font->isBase)
|
||||
delete m_font;
|
||||
m_color = Vec3(0.0);
|
||||
m_scale = 1.0f;
|
||||
m_opacity = 1.0f;
|
||||
}
|
||||
|
||||
Text::~Text() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
#include "UITexture.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "Assets.h"
|
||||
#include "Texture.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace nf {
|
||||
UITexture::UITexture() :
|
||||
m_texture(nullptr),
|
||||
m_scale(1.0f),
|
||||
m_opacity(1.0f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
Error("Non-texture asset passed to UITexture::create!");
|
||||
m_position = position;
|
||||
m_scale = (float)scale;
|
||||
m_opacity = (float)opacity;
|
||||
if (tex->alreadyLoaded) {
|
||||
m_texture = tex->loadedTexture;
|
||||
}
|
||||
else {
|
||||
m_texture = new Texture(tex);
|
||||
}
|
||||
|
||||
float tc[] = {
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0
|
||||
};
|
||||
m_vao = new VertexArray;
|
||||
m_vao->addBuffer(nullptr, 0);
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
m_vao->addBuffer(tc, sizeof(tc));
|
||||
m_vao->push<float>(2);
|
||||
m_vao->finishBufferLayout();
|
||||
|
||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
|
||||
}
|
||||
|
||||
const char* UITexture::identity() {
|
||||
return "texture";
|
||||
}
|
||||
|
||||
void UITexture::setScale(double scale) {
|
||||
m_scale = (float)scale;
|
||||
}
|
||||
|
||||
void UITexture::setOpacity(double opacity) {
|
||||
m_opacity = (float)opacity;
|
||||
}
|
||||
|
||||
void UITexture::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
|
||||
float posX = (float)m_position.x * windowWidth, posY = (float)m_position.y * windowHeight;
|
||||
float scale = windowWidth / 5.0f;
|
||||
|
||||
Vec2 texDim = m_texture->getDimensions();
|
||||
float height = scale * m_scale;
|
||||
float width = ((float)texDim.x / (float)texDim.y) * scale * m_scale;
|
||||
if (m_centeredX)
|
||||
posX = ((float)windowWidth - width) / 2;
|
||||
if (m_centeredY)
|
||||
posY = ((float)windowHeight - height) / 2;
|
||||
float vb[3][4] = {
|
||||
posX, posY + height,
|
||||
posX, posY,
|
||||
posX + width, posY,
|
||||
posX, posY + height,
|
||||
posX + width, posY,
|
||||
posX + width, posY + height
|
||||
};
|
||||
|
||||
m_texture->bind();
|
||||
m_vao->setBufferData(0, vb, sizeof(vb));
|
||||
shader->setUniform("opacity", m_opacity);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
void UITexture::destroy() {
|
||||
m_constructed = false;
|
||||
m_position = Vec2(0.0);
|
||||
m_centeredX = m_centeredY = false;
|
||||
if (!m_texture->isBaseAsset())
|
||||
delete m_texture;
|
||||
m_scale = 1.0f;
|
||||
m_opacity = 1.0f;
|
||||
delete m_vao;
|
||||
}
|
||||
|
||||
UITexture::~UITexture() {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user