Maddie Slockbower 366774622b Implemented Shader Function
- Updated License to GPL v3.0
- Added New Math Nodes
- Prototype Rendering Code for Debugging Functions
2024-11-03 12:57:12 -05:00

187 lines
5.8 KiB
C++

// =====================================================================================================================
// OpenShaderDesigner, an open source software utility to create materials and shaders.
// Copyright (C) 2024 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <Core/Window.h>
#include <Core/Console.h>
#include <Editor/EditorSystem.h>
#include <gl/glew.h>
using namespace OpenShaderDesigner;
Window::Window(const Configuration& config)
: Config_(config)
{
int flags = static_cast<int>(Config_.Video.Fullscreen) | SDL_WINDOW_OPENGL;
flags |= Config_.Video.Fullscreen == FullscreenMode::WINDOWED ? SDL_WINDOW_RESIZABLE : 0;
SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO);
#ifdef NDEBUG
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
#endif
// Set OpenGL APIVersion
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
if(Config_.Video.HDR)
{
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 10);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 10);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 10);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 2);
SDL_GL_SetAttribute(SDL_GL_FLOATBUFFERS, SDL_TRUE);
}
if(Config_.Video.Multisamples() && Config_.Video.Multisamples > 1)
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, SDL_TRUE);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, Config_.Video.Multisamples);
}
if((Handle_ = SDL_CreateWindow(
Config_.Application.Title.c_str(),
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
Config_.Video.Resolution.x, Config_.Video.Resolution.y,
flags)) == nullptr)
{
Console::Log(Console::Severity::Fatal, "Failed to create SDL Window: {}", SDL_GetError());
assert(false);
return;
}
Context_ = SDL_GL_CreateContext(Handle_);
if(Context_ == nullptr)
{
Console::Log(Console::Severity::Fatal, "Failed to create OpenGL Context: {}", SDL_GetError());
SDL_DestroyWindow(Handle_);
assert(false);
return;
}
if(SDL_GL_MakeCurrent(Handle_, Context_))
{
Console::Log(Console::Severity::Fatal, "Failed to set OpenGL Context: {}", SDL_GetError());
SDL_GL_DeleteContext(Context_);
SDL_DestroyWindow(Handle_);
assert(false);
return;
}
// Set VSync Mode
SDL_GL_SetSwapInterval(static_cast<int>(Config_.Video.VSync));
// Enable experimental features
glewExperimental = GL_TRUE;
// Initialize GLEW
GLenum error;
if((error = glewInit()) != GLEW_OK)
{
Console::Log(Console::Severity::Fatal, "Failed to Initialize GLEW: {}", reinterpret_cast<const char*>(glewGetErrorString(error)));
SDL_GL_DeleteContext(Context_);
SDL_DestroyWindow(Handle_);
assert(false);
return;
}
// Fill in black screen
glEnable(GL_MULTISAMPLE);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(Handle_);
// Set running
Open_ = true;
const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
const char* glewVersion = reinterpret_cast<const char*>(glewGetString(GLEW_VERSION));
SDL_version sdlVersion; SDL_GetVersion(&sdlVersion);
Console::Log(Console::Severity::Alert, "Initialized SDL ({}.{}.{})", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
Console::Log(Console::Severity::Alert, "Running OpenGL ({}), GLEW ({})", glVersion, glewVersion);
}
Window::~Window()
{
SDL_GL_DeleteContext(Context_);
SDL_DestroyWindow(Handle_);
SDL_Quit();
}
void Window::HandleEvents()
{
SDL_Event event;
// Poll for an event from SDL and check if it was received
while (SDL_PollEvent(&event))
{
// if event was a quit event, stop the system
if (event.type == SDL_QUIT)
{
Close();
return;
}
if (event.type == SDL_WINDOWEVENT)
{
switch(event.window.event)
{
case SDL_WINDOWEVENT_SIZE_CHANGED:
Config_.Video.Resolution.x = event.window.data1;
Config_.Video.Resolution.y = event.window.data2;
break;
default:
break;
}
}
EditorSystem::HandleEvents(&event);
SDLEvent sdlEvent(event);
EventSystem::PostEvent(&sdlEvent);
}
}
void Window::BeginFrame()
{
OpenShaderDesigner::BeginFrame event;
EventSystem::PostEvent(&event);
HandleEvents();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, Config_.Video.Resolution.x, Config_.Video.Resolution.y);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void Window::EndFrame()
{
SDL_GL_SwapWindow(Handle_);
OpenShaderDesigner::EndFrame event;
EventSystem::PostEvent(&event);
}