1
0
Fork 0
spectre/source/Window/Window.cpp

199 lines
3.5 KiB
C++

#include <iostream>
#include <Spectre/System/Event.h>
#include <Spectre/System/MessageQueue.h>
#include <Spectre/System/Log.h>
#include <Spectre/Window/Window.h>
#include <Spectre/Window/GLContext.h>
#include <Spectre/Graphics/Image.h>
#include <Platform/PlatformApplication.h>
#include <Platform/PlatformWindow.h>
#include <Graphics/GL/gl.h>
namespace sp {
#define CAPTION_DEFAULT "Spectre"
#define ICON_DEFAULT "./assets/app.ico"
Window::Window()
{
m_caption = CAPTION_DEFAULT;
m_fmode = WINDOWED;
m_context = GLContext::create();
m_impl = PlatformApplication::get()->createWindow(this);
}
Window::~Window()
{
delete m_context;
delete m_impl;
}
bool Window::create(WindowDescription description)
{
destroy();
if (!m_impl->create(description)) {
return false;
}
if (!m_context->create(m_impl)) {
return false;
}
init();
m_description = description;
return true;
}
void Window::init()
{
m_impl->setCaption(m_caption);
setIcon(ICON_DEFAULT);
activate(true);
enableVSync(false);
showCursor(true);
}
void Window::destroy()
{
m_context->destroy();
m_impl->destroy();
}
void Window::setCaption(const std::string& caption)
{
m_caption = caption;
m_impl->setCaption(m_caption);
}
const std::string& Window::getCaption() const
{
return m_caption;
}
void Window::setIcon(const std::string& filename)
{
Image img;
if (img.loadFromFile(filename)) {
setIcon(img.getWidth(), img.getHeight(), img.getPixels());
}
}
void Window::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels)
{
m_impl->setIcon(width, height, pixels);
}
void Window::setSize(unsigned int width, unsigned int height)
{
m_description.mode.width = width;
m_description.mode.height = height;
m_impl->setSize(width, height);
}
sp::Vector2u Window::getSize() const
{
return m_impl->getSize();
}
void Window::setVideoMode(Mode mode)
{
if (m_fmode == mode) {
return;
}
if (mode != FULLSCREEN) {
m_impl->exitFullscreen();
}
// Cache window position when entering fullscreen.
if (mode == FULLSCREEN || mode == WINDOWEDFULLSCREEN) {
m_cachePos = m_impl->getPosition();
}
// True fullscreen
if (mode == FULLSCREEN) {
m_impl->enterFullscreen(m_description.mode);
}
// Windowed fullscreen.
else if (mode == WINDOWEDFULLSCREEN) {
DisplayMode desktop = DisplayMode::getDesktopMode();
m_impl->setDecoration(WindowDecorate::Empty);
m_impl->setSize(desktop.width, desktop.height);
m_impl->setPosition(0, 0);
}
// Window mode.
else {
// Set stored decoration.
m_impl->setDecoration(m_description.decoration);
// Restore size and position.
m_impl->setSize(m_description.mode.width, m_description.mode.height);
m_impl->setPosition(m_cachePos.x, m_cachePos.y);
}
m_fmode = mode;
}
enum Window::Mode Window::getVideoMode() const
{
return m_fmode;
}
void Window::setVisible(bool visible)
{
m_impl->setVisible(visible);
}
void Window::showCursor(bool value)
{
m_impl->showCursor(value);
}
void Window::grabCursor(bool value)
{
m_impl->grabCursor(value);
}
bool Window::activate(bool value)
{
if (value) {
return m_context->activate();
}
return m_context->deactivate();
}
bool Window::enableVSync(bool value)
{
return m_context->setSwapInterval(value ? 1 : 0);
}
void Window::swapBuffers()
{
if (activate(true)) {
m_context->swapBuffers();
}
}
void Window::onReshape(int width, int height)
{
// TODO: This should even not be here.
// Generic Display should not have any GL calls.
// But it's better to have it here then in the platform specific GLContext
if (activate(true)) {
glViewport(0, 0, width, height);
}
}
} // namespace sp