Adds binary file buffer and the basics of the Window class

Gui_Panel_Refactor
Joeyrp 4 years ago
parent 6efe491453
commit a92e55ee01

@ -7,6 +7,10 @@ project(Lunarium VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# specify the opengl version
set(OpenGL_MAJOR_VERSION 4)
set(OpenGL_MINOR_VERSION 5)
configure_file(LunariumConfig.h.in LunariumConfig.h)
# Source Files
@ -20,6 +24,8 @@ set(LUNARIUM_SRC
"src/utils/helpers.cpp"
"src/utils/OpRes.cpp"
"src/utils/Args.cpp"
"src/utils/BinaryFileBuffer.cpp"
"src/graphics/window.cpp"
)
# add the executable

@ -1,4 +1,7 @@
// the configured options and settings for GLFW_Testing
// the configured options and settings for Lunarium
#define Lunarium_VERSION_MAJOR @Lunarium_VERSION_MAJOR@
#define Lunarium_VERSION_MINOR @Lunarium_VERSION_MINOR@
#define Lunarium_VERSION_PATCH @Lunarium_VERSION_PATCH@
#define OPENGL_MAJOR_VERSION @OpenGL_MAJOR_VERSION@
#define OPENGL_MINOR_VERSION @OpenGL_MINOR_VERSION@

@ -13,7 +13,7 @@ namespace lunarium
{
Core* Core::mpInstance = nullptr;
Core::Core()
: mbIsInit(false)
: mbIsInit(false), mpArgs(nullptr)
{
}
@ -35,20 +35,50 @@ namespace lunarium
// Shutdown subsystems
delete mpInstance->mpArgs;
mpInstance->mpArgs = nullptr;
delete mpInstance;
mpInstance = nullptr;
}
void Core::Initialize(int argc, char** argv, std::vector<LogListener*>& listeners)
{
// Setup the log system and add any listeners
mpLog = Logger::GetInstance();
mMasterLogFile.open("Element2D_Master.log", std::ios_base::app);
mMasterLogFile << "\n\n";
mErrorLogFile.open("Element2D_Errors.log", std::ios_base::app);
mErrorLogFile << "\n\n";
if (mMasterLogFile.is_open())
mpLog->AddListener(new FileListener(mMasterLogFile));
if (mErrorLogFile.is_open())
mpLog->AddListener(new FileListener(mErrorLogFile, LogLevel::ERROR | LogLevel::FATAL_ERROR));
for (unsigned i = 0; i < listeners.size(); i++)
{
mpLog->AddListener(listeners[i]);
}
mpLog->Log(LogCategory::CORE, LogLevel::INFO, "Running Lunarium version %s", Version::GetVersion().ToString().c_str());
// Attempt to load the engine state file. This file should be placed in the same directory as the lunarium program.
mpLog->Log(LogCategory::CORE, LogLevel::INFO, "Attempting to load state file: lunarium_state.xml");
if (Failed(State::CreateFromFile("lunarium_state.xml", mState)))
{
mpLog->Log(LogCategory::CORE, LogLevel::WARNING, "Unable to load state file: lunarium_state.xml. Loading default state.");
mState = State::CreateDefault();
}
// Parse command line args -- None right now
std::vector<Args::SwitchDesc> sd;
mpArgs = new Args(argc, argv, '-', sd);
}
bool Core::IsInit() const

@ -26,12 +26,19 @@ namespace lunarium
bool IsInit() const;
const State& GetState() const;
void ApplyState(State newState);
private: // DATA
static Core* mpInstance;
bool mbIsInit;
State mState;
Args* mpArgs;
Logger* mpLog;
// Log Files
std::ofstream mMasterLogFile;
std::ofstream mErrorLogFile;
private: // HIDDEN METHODS
Core();

@ -18,6 +18,7 @@ namespace lunarium
s.DataDirectory = "";
s.Display.FullScreenResolution.Width = 0;
s.Display.FullScreenResolution.Height = 0;
s.Display.RenderFramework = Renderer::OPENGL;
s.Display.IsFullScreen = false;
s.Display.VSyncEnabled = false;
s.Display.WindowedSize.Width = 0;
@ -34,9 +35,10 @@ namespace lunarium
State s;
s.DataDirectory = "data/";
Sizei size = GetScreenResolution();
Sizei size = System::GetScreenResolution();
s.Display.FullScreenResolution.Width = size.Width;
s.Display.FullScreenResolution.Height = size.Height;
s.Display.RenderFramework = Renderer::OPENGL;
s.Display.IsFullScreen = false;
s.Display.VSyncEnabled = true;
s.Display.WindowedSize.Width = 800;
@ -74,9 +76,10 @@ namespace lunarium
pugi::xml_node display = root.child("Display");
if (pugi::node_null == display.type())
{
Sizei size = GetScreenResolution();
Sizei size = System::GetScreenResolution();
state.Display.FullScreenResolution.Width = size.Width;
state.Display.FullScreenResolution.Height = size.Height;
state.Display.RenderFramework = Renderer::OPENGL;
state.Display.IsFullScreen = false;
state.Display.VSyncEnabled = true;
state.Display.WindowedSize.Width = 800;
@ -88,6 +91,21 @@ namespace lunarium
{
state.Display.FullScreenResolution.Width = display.child("FullScreenResolution").attribute("Width").as_int();
state.Display.FullScreenResolution.Height = display.child("FullScreenResolution").attribute("Height").as_int();
std::string framework = display.attribute("RenderFramework").as_string();
if (String::StringToLower(framework) == "opengl")
{
state.Display.RenderFramework = Renderer::OPENGL;
}
else if (String::StringToLower(framework) == "vulkan")
{
state.Display.RenderFramework = Renderer::VULKAN;
}
else
{
state.Display.RenderFramework = Renderer::UNKNOWN;
}
state.Display.IsFullScreen = display.attribute("IsFullScreen").as_bool();
state.Display.VSyncEnabled = display.attribute("VSyncEnabled").as_bool();
state.Display.WindowedSize.Width = display.child("WindowedSize").attribute("Width").as_int();
@ -125,6 +143,9 @@ namespace lunarium
display.append_attribute("IsFullScreen").set_value(Display.IsFullScreen);
display.append_attribute("VSyncEnabled").set_value(Display.VSyncEnabled);
char* names[] = { "opengl", "vulkan", "unknown" };
display.append_attribute("RenderFramework").set_value(names[Display.RenderFramework]);
pugi::xml_node fsr = display.append_child("FullScreenResolution");
fsr.append_attribute("Width").set_value(Display.FullScreenResolution.Width);
fsr.append_attribute("Height").set_value(Display.FullScreenResolution.Height);

@ -14,6 +14,13 @@
namespace lunarium
{
enum Renderer
{
OPENGL,
VULKAN,
UNKNOWN
};
struct State
{
std::string DataDirectory;
@ -38,6 +45,7 @@ namespace lunarium
int Height;
} FullScreenResolution;
Renderer RenderFramework;
bool IsFullScreen;
bool VSyncEnabled;
} Display;

@ -0,0 +1,183 @@
/******************************************************************************
* File - window.h
* Author - Joey Pollack
* Date - 2021/09/01 (y/m/d)
* Mod Date - 2021/09/01 (y/m/d)
* Description - Manages the window system using GLFW. This is where GLFW
* is initialized. I think this file can completely hide GLFW
* but I'm not yet sure...
******************************************************************************/
#include "window.h"
#include <LunariumConfig.h>
#include <utils\logger.h>
#include <utils\helpers.h>
#include <sstream>
namespace lunarium
{
bool Window::mbIsInit = false;
Window::Window()
{
}
OpRes Window::Initialize(const State& state)
{
if (mbIsInit)
{
return OpRes::Fail("A window is already initialized. Multiple windows is not yet supported");
}
if (state.Display.RenderFramework == Renderer::VULKAN)
{
return OpRes::Fail("Render Framework VULKAN is not yet implemented");
}
if (state.Display.RenderFramework == Renderer::OPENGL)
{
int width, height;
if( !glfwInit() )
{
char buffer[1024];
glfwGetError((char**)&buffer);
std::ostringstream oss;
oss << "Failed to initialize GLFW: " << buffer;
return OpRes::Fail(oss.str().c_str());
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OPENGL_MAJOR_VERSION);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, OPENGL_MINOR_VERSION);
Logger::GetInstance()->Log(LogCategory::GRAPHICS, LogLevel::INFO,
"Creating OpenGL Context version %d, %d and glsl %s",
OPENGL_MAJOR_VERSION, OPENGL_MINOR_VERSION, System::GetGLSLVersionString().c_str());
mpWindow = glfwCreateWindow( state.Display.WindowedSize.Width, state.Display.WindowedSize.Height, "Lunarium", NULL, NULL );
if (!mpWindow)
{
glfwTerminate();
char buffer[1024];
glfwGetError((char**)&buffer);
std::ostringstream oss;
oss << "Failed to initialize GLFWFailed to open GLFW window: " << buffer;
return OpRes::Fail(oss.str().c_str());
}
glfwSetWindowPos(mpWindow, state.Display.WindowStartPosition.X, state.Display.WindowStartPosition.Y);
glfwMakeContextCurrent(mpWindow);
if (state.Display.VSyncEnabled)
{
glfwSwapInterval(1); // Enable vsync
}
// Use glad2 to load extensions
int version = gladLoadGL(glfwGetProcAddress);
Logger::GetInstance()->Log(LogCategory::GRAPHICS, LogLevel::INFO,
"Glad2 Loaded version: %d.%d", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version));
}
else
{
return OpRes::Fail("No Render Framework selected");
}
glfwSetWindowUserPointer(mpWindow, this);
mbIsInit = true;
return OpRes::OK();
}
bool Window::IsInit() const
{
return mbIsInit;
}
GLFWwindow* Window::GetWindow()
{
return mpWindow;
}
void Window::Resize(int width, int height)
{
glfwSetWindowSize(mpWindow, width, height);
}
// If fullscreen is true but we're already in fullscreen mode this function will change the
// resolution. If fullscreen is false but we're not fullscreen this function will change
// the window position and size.
void Window::ChangeDisplayMode(bool fullscreen, int xPos, int yPos, int width, int height)
{
// TODO: Allow the user to select which monitor to use
// https://www.glfw.org/docs/latest/monitor_guide.html
// For now just use the primary monitor
GLFWmonitor* pMonitor = glfwGetWindowMonitor(mpWindow);
if (fullscreen)
{
if (pMonitor)
{
// Requsting fullscreen but we're already fullscreen so
// just set the size
glfwSetWindowSize(mpWindow, width, height);
return;
}
else
{
// Otherwise we need to switch to fullscreen mode
// TODO: Allow the user to select the refresh rate
glfwSetWindowMonitor(mpWindow, glfwGetPrimaryMonitor(), 0, 0, width, height, 60);
}
}
else
{
if (pMonitor)
{
// Go to windowed mode
glfwSetWindowMonitor(mpWindow, nullptr, xPos, yPos, width, height, 60);
}
else
{
// Already in windowed mode so just change the size and position
glfwSetWindowSize(mpWindow, width, height);
glfwSetWindowPos(mpWindow, xPos, yPos);
}
}
}
void Window::GetFramebufferSize(int* width, int* height) const
{
glfwGetFramebufferSize(mpWindow, width, height);
}
bool Window::ShouldWindowClose() const
{
return glfwWindowShouldClose(mpWindow);
}
void Window::PollEvents()
{
glfwPollEvents();
}
void Window::SwapBuffers()
{
glfwSwapBuffers(mpWindow);
}
void Window::Shutdown()
{
glfwDestroyWindow(mpWindow);
glfwTerminate();
mbIsInit = false;
}
}

@ -0,0 +1,54 @@
/******************************************************************************
* File - window.h
* Author - Joey Pollack
* Date - 2021/09/01 (y/m/d)
* Mod Date - 2021/09/01 (y/m/d)
* Description - Manages the window system using GLFW. This is where GLFW
* is initialized. I think this file can completely hide GLFW
* but I'm not yet sure...
******************************************************************************/
#ifndef WINDOW_H_
#define WINDOW_H_
#include <glad/gl.h>
#include <GLFW/glfw3.h>
#include <core/state.h>
#include <utils/opRes.h>
namespace lunarium
{
class Window
{
public:
Window();
OpRes Initialize(const State& state);
bool IsInit() const;
GLFWwindow* GetWindow();
void Resize(int width, int height);
// TODO: See https://www.glfw.org/docs/latest/window_guide.html#window_full_screen
void ChangeDisplayMode(bool fullscreen, int xPos, int yPos, int width, int height);
void GetFramebufferSize(int* width, int* height) const;
bool ShouldWindowClose() const;
static void PollEvents();
void SwapBuffers();
void Shutdown();
private:
// There can only be 1 window for now
static bool mbIsInit;
GLFWwindow* mpWindow;
};
}
#endif // WINDOW_H_

@ -0,0 +1,108 @@
/******************************************************************************
* File - BinaryFileBuffer.cpp
* Author - Joey Pollack
* Date - 2020/01/24 (y/m/d)
* Mod Date - 2020/01/24 (y/m/d)
* Description - Reads an entire binary file into memory and allows for
* extracting the data in chunks. Much faster than reading
* large files chunk by chunk.
******************************************************************************/
#include "BinaryFileBuffer.h"
#include <fstream>
namespace lunarium
{
BinaryFileBuffer::BinaryFileBuffer()
: mbIsLoaded(false), mpData(nullptr), mFileSize(0), mReadPos(0), mFileName("")
{
}
BinaryFileBuffer::~BinaryFileBuffer()
{
Unload();
}
bool BinaryFileBuffer::LoadFile(const char * filename)
{
if (mbIsLoaded)
{
return false;
}
std::ifstream ifs(filename, std::ios_base::binary);
if (!ifs.is_open())
{
return false;
}
int start = ifs.tellg();
ifs.seekg(0, std::ios_base::end);
int end = ifs.tellg();
ifs.seekg(0, std::ios_base::beg);
mFileSize = end - start;
mpData = new unsigned char[mFileSize];
ifs.read((char*)mpData, mFileSize);
ifs.close();
ifs.clear();
mFileName = filename;
mbIsLoaded = true;
return true;
}
void BinaryFileBuffer::Unload()
{
if (!mbIsLoaded)
return;
delete[] mpData;
mpData = nullptr;
mFileSize = 0;
mFileName = "";
mReadPos = 0;
mbIsLoaded = false;
}
bool BinaryFileBuffer::IsLoaded() const
{
return mbIsLoaded;
}
const std::string& BinaryFileBuffer::LoadedFileName() const
{
return mFileName;
}
int BinaryFileBuffer::GetFileSize() const
{
return mFileSize;
}
bool BinaryFileBuffer::Read(char * buffer, int numBytes)
{
if (!mbIsLoaded || mReadPos >= mFileSize)
return false;
memcpy_s(buffer, numBytes, &mpData[mReadPos], numBytes);
mReadPos += numBytes;
return true;
}
void BinaryFileBuffer::SeekTo(int pos)
{
mReadPos = pos;
if (mReadPos < 0)
mReadPos = 0;
if (mReadPos >= mFileSize)
mReadPos = mFileSize - 1;
}
}

@ -0,0 +1,44 @@
/******************************************************************************
* File - BinaryFileBuffer.h
* Author - Joey Pollack
* Date - 2020/01/24 (y/m/d)
* Mod Date - 2020/01/24 (y/m/d)
* Description - Reads an entire binary file into memory and allows for
* extracting the data in chunks. Much faster than reading
* large files chunk by chunk.
******************************************************************************/
#ifndef BINARY_FILE_BUFFER_H_
#define BINARY_FILE_BUFFER_H_
#include <string>
namespace lunarium
{
class BinaryFileBuffer
{
public:
BinaryFileBuffer();
~BinaryFileBuffer();
bool LoadFile(const char* filename);
void Unload();
bool IsLoaded() const;
const std::string& LoadedFileName() const;
int GetFileSize() const;
bool Read(char* buffer, int numBytes);
void SeekTo(int pos);
private:
bool mbIsLoaded;
std::string mFileName;
int mFileSize;
unsigned char* mpData;
int mReadPos;
};
}
#endif // BINARY_FILE_BUFFER_H_

@ -7,6 +7,7 @@
******************************************************************************/
#include "helpers.h"
#include <LunariumConfig.h>
#ifdef WIN32
#include <windows.h>
@ -16,7 +17,7 @@
namespace lunarium
{
Sizei GetScreenResolution()
Sizei System::GetScreenResolution()
{
#ifdef WIN32
return Sizei { GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN) };
@ -27,25 +28,142 @@ namespace lunarium
#endif // WIN32
}
std::string System::GetGLSLVersionString()
{
std::string glsl_version = "#version ";
glsl_version += OPENGL_MAJOR_VERSION;
glsl_version += OPENGL_MINOR_VERSION;
glsl_version += "0";
return glsl_version;
}
std::vector<std::string> String::Split(std::string str, char delim, int maxSplits)
{
std::vector<std::string> splits;
int startPos = 0;
for (int i = 0; i < (signed)str.length(); i++)
{
if (str[i] == delim)
{
if (startPos == i)
continue;
std::string s = str.substr(startPos, i - startPos);
splits.push_back(s);
startPos = i + 1;
if (maxSplits > 0 && (signed)splits.size() >= (maxSplits - 1))
{
break;
}
}
}
std::string s = str.substr(startPos);
splits.push_back(s);
return splits;
}
std::string String::Trim(std::string str, std::string delims)
{
str = TrimStart(str, delims);
str = TrimEnd(str, delims);
return str;
}
std::string String::TrimStart(std::string str, std::string delims)
{
bool isDelim = true;
while (isDelim && str.length() > 0)
{
isDelim = false;
for (int i = 0; i < (signed)delims.length(); i++)
{
if (str[0] == delims[i])
{
isDelim = true;
break;
}
}
if (isDelim)
str.erase(str.begin());
}
return str;
}
std::string String::TrimEnd(std::string str, std::string delims)
{
bool isDelim = true;
while (isDelim && str.length() > 0)
{
isDelim = false;
for (int i = 0; i < (signed)delims.length(); i++)
{
if (*(str.rbegin()) == delims[i])
{
isDelim = true;
break;
}
}
if (isDelim)
str.erase((str.rbegin() + 1).base());
}
return str;
}
//template <typename T>
std::string AsString(int value)
std::string String::AsString(int value)
{
std::string str = "";
str += value;
return str;
}
std::string AsString(bool value)
std::string String::AsString(bool value)
{
std::string str = "";
str += value;
return str;
}
std::string AsString(float value)
std::string String::AsString(float value)
{
std::string str = "";
str += value;
return str;
}
std::string String::StringToUpper(std::string str)
{
for (int i = 0; i < str.size(); i++)
{
if (str[i] >= 97 && str[i] <= 122)
{
str[i] -= 32;
}
}
return str;
}
std::string String::StringToLower(std::string str)
{
for (int i = 0; i < str.size(); i++)
{
if (str[i] >= 65 && str[i] <= 90)
{
str[i] += 32;
}
}
return str;
}
}

@ -11,15 +11,41 @@
#include "types.h"
#include <string>
#include <vector>
namespace lunarium
{
Sizei GetScreenResolution();
class System
{
public:
static Sizei GetScreenResolution();
static std::string GetGLSLVersionString();
};
//template <typename T>
std::string AsString(int value);
std::string AsString(bool value);
std::string AsString(float value);
class String
{
public:
// Splits the string based on the given delimiter,
// maxSplit = -1 for unlimited number of splits
static std::vector<std::string> Split(std::string str, char delim = ' ', int maxSplits = -1);
// Trim given delimiters from start and end of string
static std::string Trim(std::string str, std::string delims = " \r\n\t");
// Trim given delimiters from start of string
static std::string TrimStart(std::string str, std::string delims = " \r\n\t");
// Trim given delimiters from end of string
static std::string TrimEnd(std::string str, std::string delims);
static std::string AsString(int value);
static std::string AsString(bool value);
static std::string AsString(float value);
static std::string StringToUpper(std::string str);
static std::string StringToLower(std::string str);
};
}
#endif // HELPERS_H_

@ -1,6 +1,6 @@
<State>
<DataDirectory>data/</DataDirectory>
<Display IsFullScreen="false" VSyncEnabled="true">
<Display RenderFramework="opengl" IsFullScreen="false" VSyncEnabled="true">
<FullScreenResolution Width="1920" Height="1080" />
<WindowedSize Width="800" Height="600" />
<WindowStartPosition X="100" Y="100" />

Loading…
Cancel
Save