From 1770acbfef82b0dc021fa867f2f23b24f70af394 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 20 Mar 2022 23:48:21 +0300 Subject: [PATCH] Audio module, simple text rendering --- src/Assets.cpp | 14 +++ src/Assets.h | 5 + src/audio/Audio.cpp | 180 ++++++++++++++++++++++++++++++++++++ src/audio/Audio.h | 61 ++++++++++++ src/audio/audioutil.cpp | 194 +++++++++++++++++++++++++++++++++++++++ src/audio/audioutil.h | 44 +++++++++ src/declarations.h | 19 ++++ src/graphics/Batch2D.cpp | 76 ++++++++++++++- src/graphics/Batch2D.h | 10 ++ src/graphics/Font.cpp | 40 ++++++++ src/graphics/Font.h | 18 ++++ src/voxel_engine.cpp | 29 +++--- src/window/Camera.cpp | 5 +- src/window/Camera.h | 1 + src/world_render.h | 23 +++++ 15 files changed, 702 insertions(+), 17 deletions(-) create mode 100644 src/audio/Audio.cpp create mode 100644 src/audio/Audio.h create mode 100644 src/audio/audioutil.cpp create mode 100644 src/audio/audioutil.h create mode 100644 src/graphics/Font.cpp create mode 100644 src/graphics/Font.h diff --git a/src/Assets.cpp b/src/Assets.cpp index fbaaa21e..64f7d6b5 100644 --- a/src/Assets.cpp +++ b/src/Assets.cpp @@ -2,6 +2,7 @@ #include "graphics/Texture.h" #include "graphics/Shader.h" +#include "graphics/Font.h" Assets::~Assets() { for (auto& iter : shaders){ @@ -11,6 +12,10 @@ Assets::~Assets() { for (auto& iter : textures){ delete iter.second; } + + for (auto& iter : fonts){ + delete iter.second; + } } Texture* Assets::getTexture(std::string name){ @@ -29,3 +34,12 @@ Shader* Assets::getShader(std::string name){ void Assets::store(Shader* shader, std::string name){ shaders[name] = shader; } + + +Font* Assets::getFont(std::string name){ + return fonts[name]; +} + +void Assets::store(Font* font, std::string name){ + fonts[name] = font; +} diff --git a/src/Assets.h b/src/Assets.h index daca7d19..3dc9fa5d 100644 --- a/src/Assets.h +++ b/src/Assets.h @@ -6,10 +6,12 @@ class Texture; class Shader; +class Font; class Assets { std::unordered_map textures; std::unordered_map shaders; + std::unordered_map fonts; public: ~Assets(); Texture* getTexture(std::string name); @@ -17,6 +19,9 @@ public: Shader* getShader(std::string name); void store(Shader* shader, std::string name); + + Font* getFont(std::string name); + void store(Font* font, std::string name); }; #endif /* SRC_ASSETS_H_ */ diff --git a/src/audio/Audio.cpp b/src/audio/Audio.cpp new file mode 100644 index 00000000..1dec8ff8 --- /dev/null +++ b/src/audio/Audio.cpp @@ -0,0 +1,180 @@ +#include "Audio.h" +#include "audioutil.h" +#include +#include + +#include +#include + +ALCdevice* Audio::device; +ALCcontext* Audio::context; +unsigned Audio::maxSources; +unsigned Audio::maxBuffers = 1024; +std::vector Audio::allsources; +std::vector Audio::freesources; +std::vector Audio::allbuffers; +std::vector Audio::freebuffers; + +bool ALSource::setBuffer(ALBuffer* buffer){ + alSourcei(id, AL_BUFFER, buffer->id); + return alCheck(); +} + +bool ALSource::play(){ + alSourcePlay(id); + return alCheck(); +} + +bool ALSource::setPosition(glm::vec3 position){ + alSource3f(id, AL_POSITION, position.x, position.y, position.z); + return alCheck(); +} + +bool ALSource::setVelocity(glm::vec3 velocity){ + alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z); + return alCheck(); +} + +bool ALSource::setLoop(bool loop){ + alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE); + return alCheck(); +} + +bool ALSource::setGain(float gain) { + alSourcef(id, AL_GAIN, gain); + return alCheck(); +} + + +bool ALSource::setPitch(float pitch) { + alSourcef(id, AL_PITCH, pitch); + return alCheck(); +} + +bool ALBuffer::load(int format, const char* data, int size, int freq){ + alBufferData(id, format, data, size, freq); + return alCheck(); +} + + +bool Audio::initialize(){ + device = alcOpenDevice(nullptr); + if (device == nullptr) + return false; + context = alcCreateContext(device, nullptr); + if (!alcMakeContextCurrent(context)){ + alcCloseDevice(device); + return false; + } + if (!alCheck()) + return false; + + ALCint size; + alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &size); + std::vector attrs(size); + alcGetIntegerv(device, ALC_ALL_ATTRIBUTES, size, &attrs[0]); + for(size_t i=0; iid); alCheck(); + alDeleteSources(1, &source->id); alCheck(); + } + + for (ALBuffer* buffer : allbuffers){ + alDeleteBuffers(1, &buffer->id); alCheck(); + } + + alcMakeContextCurrent(context); + alcDestroyContext(context); + if (!alcCloseDevice(device)){ + std::cerr << "device not closed!" << std::endl; + } + device = nullptr; + context = nullptr; +} + +ALSource* Audio::getFreeSource(){ + if (!freesources.empty()){ + ALSource* source = freesources.back(); + freesources.pop_back(); + return source; + } + if (allsources.size() == maxSources){ + std::cerr << "attempted to create new source, but limit is " << maxSources << std::endl; + return nullptr; + } + ALuint id; + alGenSources(1, &id); + if (!alCheck()) + return nullptr; + + ALSource* source = new ALSource(id); + allsources.push_back(source); + return source; +} + +ALBuffer* Audio::getFreeBuffer(){ + if (!freebuffers.empty()){ + ALBuffer* buffer = freebuffers.back(); + freebuffers.pop_back(); + return buffer; + } + if (allbuffers.size() == maxBuffers){ + std::cerr << "attempted to create new ALbuffer, but limit is " << maxBuffers << std::endl; + return nullptr; + } + ALuint id; + alGenBuffers(1, &id); + if (!alCheck()) + return nullptr; + + ALBuffer* buffer = new ALBuffer(id); + allbuffers.push_back(buffer); + return buffer; +} + +void Audio::freeSource(ALSource* source){ + freesources.push_back(source); +} + +void Audio::freeBuffer(ALBuffer* buffer){ + freebuffers.push_back(buffer); +} + +bool Audio::get_available_devices(std::vector& devicesVec){ + const ALCchar* devices; + devices = alcGetString(device, ALC_DEVICE_SPECIFIER); + if (!alCheck()) + return false; + + const char* ptr = devices; + + devicesVec.clear(); + + do { + devicesVec.push_back(std::string(ptr)); + ptr += devicesVec.back().size() + 1; + } + while(*(ptr + 1) != '\0'); + + return true; +} + +void Audio::setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){ + ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z }; + + alListener3f(AL_POSITION, position.x, position.y, position.z); + alCheck(); + alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); + alCheck(); + alListenerfv(AL_ORIENTATION, listenerOri); + alCheck(); +} diff --git a/src/audio/Audio.h b/src/audio/Audio.h new file mode 100644 index 00000000..9861c0bb --- /dev/null +++ b/src/audio/Audio.h @@ -0,0 +1,61 @@ +#ifndef SRC_AUDIO_AUDIO_H_ +#define SRC_AUDIO_AUDIO_H_ + +#include +#include + +#include +#include + +#include + + +struct ALBuffer; + +struct ALSource { + ALuint id; + ALSource(ALuint id) : id(id) {} + + bool setPosition(glm::vec3 position); + bool setVelocity(glm::vec3 velocity); + bool setBuffer(ALBuffer* buffer); + bool setLoop(bool loop); + bool setGain(float gain); + bool setPitch(float pitch); + bool play(); +}; + +struct ALBuffer { + ALuint id; + ALBuffer(ALuint id) : id(id) {} + bool load(int format, const char* data, int size, int freq); +}; + +class Audio { + static ALCdevice* device; + static ALCcontext* context; + + static std::vector allsources; + static std::vector freesources; + + static std::vector allbuffers; + static std::vector freebuffers; + + static unsigned maxSources; + static unsigned maxBuffers; + +public: + static ALSource* getFreeSource(); + static ALBuffer* getFreeBuffer(); + static void freeSource(ALSource* source); + static void freeBuffer(ALBuffer* buffer); + + static bool initialize(); + static void finalize(); + static bool get_available_devices(std::vector& devicesVec); + + static void setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up); + +}; + +#endif /* SRC_AUDIO_AUDIO_H_ */ diff --git a/src/audio/audioutil.cpp b/src/audio/audioutil.cpp new file mode 100644 index 00000000..cfedfdec --- /dev/null +++ b/src/audio/audioutil.cpp @@ -0,0 +1,194 @@ +#include "audioutil.h" + +#include +#include +#include +#include +#include +#include + + +bool is_big_endian(void){ + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + + return bint.c[0] == 1; +} + +std::int32_t convert_to_int(char* buffer, std::size_t len){ + std::int32_t a = 0; + if(!is_big_endian()) + std::memcpy(&a, buffer, len); + else + for(std::size_t i = 0; i < len; ++i) + reinterpret_cast(&a)[3 - i] = buffer[i]; + return a; +} + +bool check_al_errors(const std::string& filename, const std::uint_fast32_t line){ + ALenum error = alGetError(); + if(error != AL_NO_ERROR){ + std::cerr << "OpenAL ERROR (" << filename << ": " << line << ")\n" ; + switch(error){ + case AL_INVALID_NAME: + std::cerr << "AL_INVALID_NAME: a bad name (ID) was passed to an OpenAL function"; + break; + case AL_INVALID_ENUM: + std::cerr << "AL_INVALID_ENUM: an invalid enum value was passed to an OpenAL function"; + break; + case AL_INVALID_VALUE: + std::cerr << "AL_INVALID_VALUE: an invalid value was passed to an OpenAL function"; + break; + case AL_INVALID_OPERATION: + std::cerr << "AL_INVALID_OPERATION: the requested operation is not valid"; + break; + case AL_OUT_OF_MEMORY: + std::cerr << "AL_OUT_OF_MEMORY: the requested operation resulted in OpenAL running out of memory"; + break; + default: + std::cerr << "UNKNOWN AL ERROR: " << error; + } + std::cerr << std::endl; + return false; + } + return true; +} + +bool load_wav_file_header(std::ifstream& file, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size){ + char buffer[4]; + if(!file.is_open()) + return false; + + // the RIFF + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read RIFF" << std::endl; + return false; + } + if(std::strncmp(buffer, "RIFF", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (header doesn't begin with RIFF)" << std::endl; + return false; + } + + // the size of the file + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read size of file" << std::endl; + return false; + } + + // the WAVE + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read WAVE" << std::endl; + return false; + } + if(std::strncmp(buffer, "WAVE", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (header doesn't contain WAVE)" << std::endl; + return false; + } + + // "fmt/0" + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read fmt/0" << std::endl; + return false; + } + + // this is always 16, the size of the fmt data chunk + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read the 16" << std::endl; + return false; + } + + // PCM should be 1? + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read PCM" << std::endl; + return false; + } + + // the number of channels + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read number of channels" << std::endl; + return false; + } + channels = convert_to_int(buffer, 2); + + // sample rate + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read sample rate" << std::endl; + return false; + } + sampleRate = convert_to_int(buffer, 4); + + // (sampleRate * bitsPerSample * channels) / 8 + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read (sampleRate * bitsPerSample * channels) / 8" << std::endl; + return false; + } + + // ?? dafaq + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read dafaq" << std::endl; + return false; + } + + // bitsPerSample + if(!file.read(buffer, 2)){ + std::cerr << "ERROR: could not read bits per sample" << std::endl; + return false; + } + bitsPerSample = convert_to_int(buffer, 2); + + // data chunk header "data" + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read data chunk header" << std::endl; + return false; + } + if(std::strncmp(buffer, "data", 4) != 0){ + std::cerr << "ERROR: file is not a valid WAVE file (doesn't have 'data' tag)" << std::endl; + return false; + } + + // size of data + if(!file.read(buffer, 4)){ + std::cerr << "ERROR: could not read data size" << std::endl; + return false; + } + size = convert_to_int(buffer, 4); + + /* cannot be at the end of file */ + if(file.eof()){ + std::cerr << "ERROR: reached EOF on the file" << std::endl; + return false; + } + if(file.fail()){ + std::cerr << "ERROR: fail state set on the file" << std::endl; + return false; + } + return true; +} + +char* load_wav(const std::string& filename, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size){ + std::ifstream in(filename, std::ios::binary); + if(!in.is_open()){ + std::cerr << "ERROR: Could not open \"" << filename << "\"" << std::endl; + return nullptr; + } + if(!load_wav_file_header(in, channels, sampleRate, bitsPerSample, size)){ + std::cerr << "ERROR: Could not load wav header of \"" << filename << "\"" << std::endl; + return nullptr; + } + + char* data = new char[size]; + + in.read(data, size); + + return data; +} diff --git a/src/audio/audioutil.h b/src/audio/audioutil.h new file mode 100644 index 00000000..f62a06cb --- /dev/null +++ b/src/audio/audioutil.h @@ -0,0 +1,44 @@ +#ifndef SRC_AUDIO_AUDIOUTIL_H_ +#define SRC_AUDIO_AUDIOUTIL_H_ + +#include +#include + +#include + +#define alCheck() check_al_errors(__FILE__, __LINE__) + +bool check_al_errors(const std::string& filename, const std::uint_fast32_t line); + +bool load_wav_file_header(std::ifstream& file, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size); + +char* load_wav(const std::string& filename, + std::uint8_t& channels, + std::int32_t& sampleRate, + std::uint8_t& bitsPerSample, + ALsizei& size); + +static inline ALenum to_al_format(short channels, short samples){ + bool stereo = (channels > 1); + + switch (samples) { + case 16: + if (stereo) + return AL_FORMAT_STEREO16; + else + return AL_FORMAT_MONO16; + case 8: + if (stereo) + return AL_FORMAT_STEREO8; + else + return AL_FORMAT_MONO8; + default: + return -1; + } +} + +#endif /* SRC_AUDIO_AUDIOUTIL_H_ */ diff --git a/src/declarations.h b/src/declarations.h index b49304bf..2abce32e 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -5,6 +5,7 @@ #include "Assets.h" #include "graphics/Shader.h" #include "graphics/Texture.h" +#include "graphics/Font.h" #include "window/Window.h" #include "voxels/Block.h" @@ -32,6 +33,17 @@ bool _load_texture(Assets* assets, std::string filename, std::string name){ return true; } +bool _load_font(Assets* assets, std::string filename, std::string name){ + Texture* texture = load_texture(filename); + if (texture == nullptr){ + std::cerr << "failed to load bitmap font '" << name << "'" << std::endl; + return false; + } + Font* font = new Font(texture); + assets->store(font, name); + return true; +} + int initialize_assets(Assets* assets) { #define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \ if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\ @@ -39,12 +51,19 @@ int initialize_assets(Assets* assets) { #define LOAD_TEXTURE(FILENAME, NAME) \ if (!_load_texture(assets, FILENAME, NAME))\ return 1; +#define LOAD_FONT(FILENAME, NAME) \ + if (!_load_font(assets, FILENAME, NAME))\ + return 1; LOAD_SHADER("res/main.glslv", "res/main.glslf", "main"); LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair"); LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines"); + LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui"); LOAD_TEXTURE("res/block.png", "block"); + //LOAD_TEXTURE("res/font.png", "font"); + + LOAD_FONT("res/font.png", "normal"); return 0; } diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index e6b43770..9c114576 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -1,5 +1,8 @@ #include "Batch2D.h" #include "Mesh.h" +#include "Texture.h" + +#include Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), @@ -8,11 +11,80 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), 2, 2, 4, 0 //null terminator }; - buffer = new float[capacity]; - mesh = new Mesh(nullptr, 0, attrs); + buffer = new float[capacity * 8]; + mesh = new Mesh(buffer, 0, attrs); + index = 0; + + unsigned char pixels[] = { + 255, 255, 255, 255, + }; + blank = new Texture(pixels, 1, 1); + _texture = nullptr; } Batch2D::~Batch2D(){ + delete blank; delete buffer; delete mesh; } + +void Batch2D::begin(){ + _texture = nullptr; + blank->bind(); +} + +void Batch2D::vertex(float x, float y, + float u, float v, + float r, float g, float b, float a) { + buffer[index++] = x; + buffer[index++] = y; + buffer[index++] = u; + buffer[index++] = v; + buffer[index++] = r; + buffer[index++] = g; + buffer[index++] = b; + buffer[index++] = a; +} + +void Batch2D::texture(Texture* new_texture){ + if (_texture == new_texture) + return; + _texture = new_texture; + if (new_texture == nullptr) + blank->bind(); + else + new_texture->bind(); +} + +void Batch2D::rect(float x, float y, float w, float h){ + const float r = color.r; + const float g = color.g; + const float b = color.b; + const float a = color.a; + + vertex(x, y, 0, 0, r,g,b,a); + vertex(x+w, y+h, 1, 1, r,g,b,a); + vertex(x, y+h, 0, 1, r,g,b,a); + + vertex(x, y, 0, 0, r,g,b,a); + vertex(x+w, y, 1, 0, r,g,b,a); + vertex(x+w, y+h, 1, 1, r,g,b,a); +} + +void Batch2D::rect(float x, float y, float w, float h, + float u, float v, float tx, float ty, + float r, float g, float b, float a){ + vertex(x, y, u, v, r,g,b,a); + vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); + vertex(x, y+h, u, v+ty, r,g,b,a); + + vertex(x, y, u, v, r,g,b,a); + vertex(x+w, y, u+tx, v, r,g,b,a); + vertex(x+w, y+h, u+tx, v+ty, r,g,b,a); +} + +void Batch2D::render() { + mesh->reload(buffer, index / 8); + mesh->draw(GL_TRIANGLES); + index = 0; +} diff --git a/src/graphics/Batch2D.h b/src/graphics/Batch2D.h index 7e756eda..1ea7657a 100644 --- a/src/graphics/Batch2D.h +++ b/src/graphics/Batch2D.h @@ -5,6 +5,7 @@ #include class Mesh; +class Texture; class Batch2D { float* buffer; @@ -12,6 +13,10 @@ class Batch2D { size_t offset; glm::vec4 color; Mesh* mesh; + size_t index; + + Texture* blank; + Texture* _texture; void vertex(float x, float y, float u, float v, @@ -20,7 +25,12 @@ public: Batch2D(size_t capacity); ~Batch2D(); + void begin(); + void texture(Texture* texture); void rect(float x, float y, float w, float h); + void rect(float x, float y, float w, float h, + float u, float v, float tx, float ty, + float r, float g, float b, float a); void render(); }; diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp new file mode 100644 index 00000000..0947357b --- /dev/null +++ b/src/graphics/Font.cpp @@ -0,0 +1,40 @@ +#include "Font.h" +#include "Texture.h" +#include "Batch2D.h" + +Font::Font(Texture* texture) : texture(texture) { +} + +Font::~Font(){ + delete texture; +} + + +void Font::draw(Batch2D* batch, std::string text, int x, int y) { + for (char c : text){ + float u = (c % 16) / 16.0f; + float v = 1.0f - ((c / 16) / 16.0f) - 1.0f/16.0f; + batch->rect(x, y, 8, 8, u, v, 1.0f/16.0f, 1.0f/16.0f, 1,1,1,1); + + int gw = 7; + switch (c){ + case 'l': + case 'i': + case 'j': + case '|': + case '.': + case ',': + case ':': + case ';': + gw = 3; + break; + case 't': + gw = 5; + break; + case ' ': + gw = 3; + break; + } + x += gw; + } +} diff --git a/src/graphics/Font.h b/src/graphics/Font.h new file mode 100644 index 00000000..c771b3e4 --- /dev/null +++ b/src/graphics/Font.h @@ -0,0 +1,18 @@ +#ifndef GRAPHICS_FONT_H_ +#define GRAPHICS_FONT_H_ + +#include + +class Texture; +class Batch2D; + +class Font { +public: + Texture* texture; + Font(Texture* texture); + ~Font(); + + void draw(Batch2D* batch, std::string text, int x, int y); +}; + +#endif /* GRAPHICS_FONT_H_ */ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 3cb54bef..5fcdee75 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -2,6 +2,7 @@ // sudo apt install libgl-dev libglew-dev libglfw3-dev libpng-dev libglm-dev #include #include +#include #define GLEW_STATIC #include @@ -22,6 +23,7 @@ using namespace glm; #include "graphics/Mesh.h" #include "graphics/VoxelRenderer.h" #include "graphics/LineBatch.h" +#include "graphics/Batch2D.h" #include "window/Window.h" #include "window/Events.h" #include "window/Camera.h" @@ -40,6 +42,8 @@ using namespace glm; #include "physics/Hitbox.h" #include "physics/PhysicsSolver.h" +#include "audio/Audio.h" +#include "audio/audioutil.h" #include "Assets.h" #include "objects/Player.h" @@ -86,6 +90,9 @@ void update_controls(PhysicsSolver* physics, Player* player, float delta){ + if (Events::jpressed(GLFW_KEY_ESCAPE)){ + Window::setShouldClose(true); + } if (Events::jpressed(GLFW_KEY_TAB)){ Events::toogleCursor(); } @@ -244,16 +251,13 @@ void update_interaction(Chunks* chunks, PhysicsSolver* physics, Player* player, int WIDTH = 1280; int HEIGHT = 720; -#define GRAVITY 19.6f -#define DEFAULT_PLAYER_SPEED 4.0f - -vec3 spawnpoint(-320, 255, 32); - int main() { setup_definitions(); - Window::initialize(WIDTH, HEIGHT, "VoxelEngine Part-11"); + Audio::initialize(); + + Window::initialize(WIDTH, HEIGHT, "Window 2.0"); Events::initialize(); std::cout << "-- loading assets" << std::endl; @@ -266,12 +270,12 @@ int main() { } std::cout << "-- loading world" << std::endl; - Camera *camera = new Camera(spawnpoint, radians(90.0f)); + Camera *camera = new Camera(vec3(-320,255,32), radians(90.0f)); WorldFiles *wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8)); Chunks *chunks = new Chunks(34,1,34, 0,0,0); - Player* player = new Player(vec3(camera->position), DEFAULT_PLAYER_SPEED, camera); + Player* player = new Player(vec3(camera->position), 4.0f, camera); wfile->readPlayer(player); camera->rotation = mat4(1.0f); camera->rotate(player->camY, player->camX, 0); @@ -279,7 +283,7 @@ int main() { std::cout << "-- preparing systems" << std::endl; VoxelRenderer renderer(1024*1024); - PhysicsSolver physics(vec3(0,-GRAVITY,0)); + PhysicsSolver physics(vec3(0,-9.8f*2.0f,0)); Lighting lighting(chunks); init_renderer(); @@ -297,16 +301,13 @@ int main() { std::cout << "-- initializing finished" << std::endl; + while (!Window::isShouldClose()){ frame++; float currentTime = glfwGetTime(); delta = currentTime - lastTime; lastTime = currentTime; - if (Events::jpressed(GLFW_KEY_ESCAPE)){ - Window::setShouldClose(true); - } - if (Events::jpressed(GLFW_KEY_O)){ occlusion = !occlusion; } @@ -336,8 +337,8 @@ int main() { delete assets; finalize_renderer(); + Audio::finalize(); Events::finalize(); Window::terminate(); return 0; } - diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 4dfcc2b7..4875bd95 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -37,7 +37,10 @@ void Camera::rotate(float x, float y, float z){ mat4 Camera::getProjection(){ float aspect = (float)Window::width / (float)Window::height; - return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); + if (perspective) + return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f); + else + return glm::ortho(0.0f, fov*aspect, 0.0f, fov); } mat4 Camera::getView(){ diff --git a/src/window/Camera.h b/src/window/Camera.h index 91648adb..4d8a4462 100644 --- a/src/window/Camera.h +++ b/src/window/Camera.h @@ -23,6 +23,7 @@ public: float fov; float zoom; mat4 rotation; + bool perspective = true; Camera(vec3 position, float fov); void rotate(float x, float y, float z); diff --git a/src/world_render.h b/src/world_render.h index d2909d9a..890c4203 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -37,17 +37,26 @@ int attrs[] = { 2, 0 //null terminator }; +int uiscale = 2; + LineBatch *lineBatch; +Batch2D *batch; +Camera *uicamera; void init_renderer(){ crosshair = new Mesh(vertices, 4, attrs); lineBatch = new LineBatch(4096); + + batch = new Batch2D(1024); + uicamera = new Camera(glm::vec3(), Window::height / uiscale); + uicamera->perspective = false; } void finalize_renderer(){ delete crosshair; delete lineBatch; + delete batch; } void draw_chunk(size_t index, Camera* camera, Shader* shader, bool occlusion){ @@ -100,6 +109,7 @@ void draw_world(Camera* camera, Assets* assets, Chunks* chunks, bool occlusion){ glClearColor(0.7f,0.71f,0.73f,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); _chunks = chunks; @@ -151,6 +161,19 @@ void draw_world(Camera* camera, Assets* assets, lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x+0.1f, camera->position.y-0.5f, camera->position.z, 1, 0, 0, 1); lineBatch->line(camera->position.x, camera->position.y-0.5f, camera->position.z, camera->position.x, camera->position.y-0.5f, camera->position.z+0.1f, 0, 0, 1, 1); lineBatch->render(); + + + glDisable(GL_DEPTH_TEST); + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()); + + Font* font = assets->getFont("normal"); + batch->begin(); + batch->texture(font->texture); + font->draw(batch, "void Font::draw(Batch2D* batch, std::string text, int x, int y) {", 10, 10); + //batch->rect(0, 0, 256, 256); + batch->render(); } #endif // WORLD_RENDERER_CPP