ADD: OpenGLWrapper
This commit is contained in:
parent
7c7ac67fc8
commit
4ada346252
@ -80,6 +80,13 @@ target_include_directories(glad PUBLIC third_party/glad/include)
|
||||
add_library(Engine STATIC
|
||||
engine/src/core/Window.h
|
||||
engine/src/core/Window.cpp
|
||||
engine/src/core/Application.cpp
|
||||
engine/src/core/Application.h
|
||||
engine/src/core/EngineConfig.h
|
||||
engine/src/utils/openglWrapper/GLStateCache.cpp
|
||||
engine/src/utils/openglWrapper/GLStateCache.h
|
||||
engine/src/utils/openglWrapper/GLRenderState.cpp
|
||||
engine/src/utils/openglWrapper/GLRenderState.h
|
||||
)
|
||||
target_include_directories(Engine PUBLIC engine/src)
|
||||
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui)
|
||||
@ -87,6 +94,8 @@ target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui)
|
||||
# --- Executable ---
|
||||
add_executable(ColorRace
|
||||
game/src/main.cpp
|
||||
game/src/ColorRaceApp.cpp
|
||||
game/src/ColorRaceApp.h
|
||||
)
|
||||
|
||||
target_link_libraries(ColorRace PRIVATE
|
||||
|
||||
37
engine/src/core/Application.cpp
Normal file
37
engine/src/core/Application.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "utils/openglWrapper/GLStateCache.h"
|
||||
|
||||
namespace engine {
|
||||
Application::Application(const EngineConfig& config) : m_config(config) {
|
||||
m_window = std::make_unique<Window>(config);
|
||||
}
|
||||
|
||||
Application::~Application() = default;
|
||||
|
||||
void Application::run() {
|
||||
auto lastTime = static_cast<float>(glfwGetTime());
|
||||
|
||||
while (!m_window->shouldClose()) {
|
||||
const auto currentTime = static_cast<float>(glfwGetTime());
|
||||
const float deltaTime = currentTime - lastTime;
|
||||
lastTime = currentTime;
|
||||
|
||||
m_window->pollEvents();
|
||||
|
||||
onUpdate(deltaTime);
|
||||
|
||||
GLStateCache::clearFrameBuffer(m_config.clearColor);
|
||||
|
||||
onRender();
|
||||
|
||||
m_window->swapBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
37
engine/src/core/Application.h
Normal file
37
engine/src/core/Application.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_APPLICATION_H
|
||||
#define COLORRACE_APPLICATION_H
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "EngineConfig.h"
|
||||
#include "Window.h"
|
||||
|
||||
|
||||
|
||||
namespace engine {
|
||||
class Application {
|
||||
public:
|
||||
Application(const EngineConfig& config);
|
||||
virtual ~Application();
|
||||
|
||||
void run();
|
||||
|
||||
protected:
|
||||
virtual void onUpdate(float deltaTime) {}
|
||||
virtual void onRender() {}
|
||||
|
||||
private:
|
||||
EngineConfig m_config;
|
||||
std::unique_ptr<Window> m_window;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //COLORRACE_APPLICATION_H
|
||||
28
engine/src/core/EngineConfig.h
Normal file
28
engine/src/core/EngineConfig.h
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_ENGINECONFIG_H
|
||||
#define COLORRACE_ENGINECONFIG_H
|
||||
#include <string>
|
||||
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
namespace engine {
|
||||
struct EngineConfig {
|
||||
int windowWidth = 1280;
|
||||
int windowHeight = 720;
|
||||
std::string windowTitle = "Engine";
|
||||
|
||||
bool fullscreen = false;
|
||||
bool vsync = true;
|
||||
bool msaa = true;
|
||||
int msaaSamples = 4;
|
||||
|
||||
glm::vec4 clearColor = {0.1f, 0.1f, 0.15f, 1.0f};
|
||||
|
||||
bool debugContext = true; // GL_DEBUG_OUTPUT an/aus
|
||||
};
|
||||
}
|
||||
|
||||
#endif //COLORRACE_ENGINECONFIG_H
|
||||
@ -6,8 +6,10 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "EngineConfig.h"
|
||||
#include "glad/glad.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "utils/openglWrapper/GLStateCache.h"
|
||||
|
||||
namespace engine {
|
||||
static void GLAPIENTRY DebugCallback(GLenum source, GLenum type, GLuint id,
|
||||
@ -17,31 +19,47 @@ namespace engine {
|
||||
std::cerr << "[GL DEBUG] " << message << "\n";
|
||||
}
|
||||
|
||||
Window::Window(int width, int height, const std::string& title) {
|
||||
Window::Window(const EngineConfig& config) {
|
||||
if (!glfwInit()) throw std::runtime_error("GLFW init failed");
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, config.debugContext ? GLFW_TRUE : GLFW_FALSE);
|
||||
|
||||
m_handle = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
|
||||
if (config.msaa) {
|
||||
glfwWindowHint(GLFW_SAMPLES, config.msaaSamples);
|
||||
}
|
||||
|
||||
GLFWmonitor* monitor = config.fullscreen ? glfwGetPrimaryMonitor() : nullptr;
|
||||
m_handle = glfwCreateWindow(config.windowWidth, config.windowHeight, config.windowTitle.c_str(), monitor, nullptr);
|
||||
if (!m_handle) {
|
||||
glfwTerminate();
|
||||
throw std::runtime_error("Window creation failed");
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(m_handle);
|
||||
glfwSwapInterval(config.vsync ? 1 : 0); // VSync
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
throw std::runtime_error("GLAD init failed");
|
||||
}
|
||||
|
||||
GLStateCache::init();
|
||||
|
||||
if (config.debugContext) {
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
glDebugMessageCallback(DebugCallback, nullptr);
|
||||
}
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
if (config.msaa) {
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
glViewport(0, 0, config.windowWidth, config.windowHeight);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
|
||||
@ -8,12 +8,14 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#include "EngineConfig.h"
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace engine {
|
||||
class Window {
|
||||
public:
|
||||
Window(int width, int height, const std::string& title);
|
||||
Window(const EngineConfig& config);
|
||||
~Window();
|
||||
|
||||
bool shouldClose() const;
|
||||
|
||||
17
engine/src/utils/openglWrapper/GLRenderState.cpp
Normal file
17
engine/src/utils/openglWrapper/GLRenderState.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#include "GLRenderState.h"
|
||||
|
||||
#include "GLStateCache.h"
|
||||
|
||||
namespace engine {
|
||||
void GLRenderState::apply() const {
|
||||
GLStateCache::setFaceCulling(backfaceCulling || frontFaceCulling, frontFaceCulling);
|
||||
GLStateCache::setAntialiasing(antialiasing);
|
||||
GLStateCache::setAlphaBlending(alphaBlending);
|
||||
GLStateCache::setDepthTest(depthTesting);
|
||||
GLStateCache::setDepthWriting(depthWriting);
|
||||
}
|
||||
}
|
||||
22
engine/src/utils/openglWrapper/GLRenderState.h
Normal file
22
engine/src/utils/openglWrapper/GLRenderState.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_GLRENDERSTATE_H
|
||||
#define COLORRACE_GLRENDERSTATE_H
|
||||
|
||||
namespace engine {
|
||||
struct GLRenderState {
|
||||
bool backfaceCulling = false;
|
||||
bool frontFaceCulling = false;
|
||||
bool alphaBlending = false;
|
||||
bool antialiasing = false;
|
||||
bool depthTesting = true; // in 3D meist sinnvoller Default
|
||||
bool depthWriting = true;
|
||||
|
||||
void apply() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COLORRACE_GLRENDERSTATE_H
|
||||
115
engine/src/utils/openglWrapper/GLStateCache.cpp
Normal file
115
engine/src/utils/openglWrapper/GLStateCache.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#include "GLStateCache.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
namespace engine {
|
||||
void GLStateCache::init() {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void GLStateCache::setFaceCulling(bool enabled, bool frontFace) {
|
||||
if (enabled) {
|
||||
if (!s_cullingFaces) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
s_cullingFaces = true;
|
||||
}
|
||||
if (frontFace != s_frontFaceCulling) {
|
||||
glCullFace(frontFace ? GL_FRONT : GL_BACK);
|
||||
s_frontFaceCulling = frontFace;
|
||||
}
|
||||
} else if (s_cullingFaces) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
s_cullingFaces = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLStateCache::setAntialiasing(bool enabled) {
|
||||
if (enabled == s_antialiasing) return;
|
||||
enabled ? glEnable(GL_MULTISAMPLE) : glDisable(GL_MULTISAMPLE);
|
||||
s_antialiasing = enabled;
|
||||
}
|
||||
|
||||
void GLStateCache::setAlphaBlending(bool enabled) {
|
||||
if (enabled == s_alphaBlending && !s_additiveBlending) return;
|
||||
if (enabled) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
s_alphaBlending = true;
|
||||
s_additiveBlending = false;
|
||||
} else if (s_alphaBlending) {
|
||||
glDisable(GL_BLEND);
|
||||
s_alphaBlending = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLStateCache::setAdditiveBlending(bool enabled) {
|
||||
if (enabled && !s_additiveBlending) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
s_additiveBlending = true;
|
||||
s_alphaBlending = false;
|
||||
} else if (!enabled && s_additiveBlending) {
|
||||
glDisable(GL_BLEND);
|
||||
s_additiveBlending = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLStateCache::setDepthTest(bool enabled) {
|
||||
if (enabled == s_depthTest) return;
|
||||
enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||
s_depthTest = enabled;
|
||||
}
|
||||
|
||||
void GLStateCache::setDepthWriting(bool enabled) {
|
||||
if (enabled == s_depthWriting) return;
|
||||
glDepthMask(enabled ? GL_TRUE : GL_FALSE);
|
||||
s_depthWriting = enabled;
|
||||
}
|
||||
|
||||
void GLStateCache::setScissorTest(bool enabled, int x, int y, int width, int height) {
|
||||
if (enabled && !s_scissorTest) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
s_scissorTest = true;
|
||||
} else if (!enabled && s_scissorTest) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
s_scissorTest = false;
|
||||
return;
|
||||
}
|
||||
if (enabled && (x != s_scissorBounds[0] || y != s_scissorBounds[1] ||
|
||||
width != s_scissorBounds[2] || height != s_scissorBounds[3])) {
|
||||
glScissor(x, y, width, height);
|
||||
s_scissorBounds[0] = x; s_scissorBounds[1] = y;
|
||||
s_scissorBounds[2] = width; s_scissorBounds[3] = height;
|
||||
}
|
||||
}
|
||||
|
||||
void GLStateCache::setWireframe(bool enabled) {
|
||||
if (enabled == s_wireframe) return;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, enabled ? GL_LINE : GL_FILL);
|
||||
s_wireframe = enabled;
|
||||
}
|
||||
|
||||
void GLStateCache::bindTexture2D(unsigned int textureId, int slot) {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
}
|
||||
|
||||
void GLStateCache::clearColorBuffer() { glClear(GL_COLOR_BUFFER_BIT); }
|
||||
void GLStateCache::clearDepthBuffer() { glClear(GL_DEPTH_BUFFER_BIT); }
|
||||
void GLStateCache::clearFrameBuffer() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
|
||||
|
||||
void GLStateCache::clearFrameBuffer(glm::vec4 color) {
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
clearFrameBuffer();
|
||||
}
|
||||
}
|
||||
44
engine/src/utils/openglWrapper/GLStateCache.h
Normal file
44
engine/src/utils/openglWrapper/GLStateCache.h
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_GLSTATECACHE_H
|
||||
#define COLORRACE_GLSTATECACHE_H
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
namespace engine {
|
||||
class GLStateCache {
|
||||
public:
|
||||
static void init(); // einmal nach GLAD-Init aufrufen, um Startzustand zu setzen
|
||||
|
||||
static void setFaceCulling(bool enabled, bool frontFace);
|
||||
static void setAntialiasing(bool enabled);
|
||||
static void setAlphaBlending(bool enabled);
|
||||
static void setAdditiveBlending(bool enabled);
|
||||
static void setDepthTest(bool enabled);
|
||||
static void setDepthWriting(bool enabled);
|
||||
static void setScissorTest(bool enabled, int x = 0, int y = 0, int width = 0, int height = 0);
|
||||
static void setWireframe(bool enabled);
|
||||
|
||||
static void bindTexture2D(unsigned int textureId, int slot);
|
||||
|
||||
static void clearColorBuffer();
|
||||
static void clearDepthBuffer();
|
||||
static void clearFrameBuffer();
|
||||
static void clearFrameBuffer(glm::vec4 color);
|
||||
private:
|
||||
inline static bool s_cullingFaces = false;
|
||||
inline static bool s_frontFaceCulling = false;
|
||||
inline static bool s_antialiasing = false;
|
||||
inline static bool s_alphaBlending = false;
|
||||
inline static bool s_additiveBlending = false;
|
||||
inline static bool s_depthTest = false;
|
||||
inline static bool s_depthWriting = true;
|
||||
inline static bool s_scissorTest = false;
|
||||
inline static bool s_wireframe = false;
|
||||
inline static int s_scissorBounds[4] = {0, 0, 0, 0};
|
||||
inline static glm::vec4 s_clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //COLORRACE_GLSTATECACHE_H
|
||||
12
game/src/ColorRaceApp.cpp
Normal file
12
game/src/ColorRaceApp.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#include "ColorRaceApp.h"
|
||||
void ColorRaceApp::onUpdate(float deltaTime) {
|
||||
|
||||
}
|
||||
|
||||
void ColorRaceApp::onRender() {
|
||||
|
||||
}
|
||||
29
game/src/ColorRaceApp.h
Normal file
29
game/src/ColorRaceApp.h
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by sebastian on 29.07.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_COLORRACEAPP_H
|
||||
#define COLORRACE_COLORRACEAPP_H
|
||||
#include "core/Application.h"
|
||||
|
||||
|
||||
class ColorRaceApp : public engine::Application {
|
||||
public:
|
||||
static engine::EngineConfig makeConfig() {
|
||||
engine::EngineConfig config;
|
||||
|
||||
config.windowWidth = 1280;
|
||||
config.windowHeight = 720;
|
||||
config.windowTitle = "ColorRace";
|
||||
config.clearColor = glm::vec4(0.1f, 0.1f, 0.15f, 1.0f);
|
||||
config.vsync = true;
|
||||
return config;
|
||||
}
|
||||
ColorRaceApp() : Application(makeConfig()) {}
|
||||
protected:
|
||||
void onUpdate(float deltaTime) override;
|
||||
void onRender() override;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_COLORRACEAPP_H
|
||||
@ -1,20 +1,8 @@
|
||||
#include <iostream>
|
||||
#include "core/Window.h"
|
||||
#include "glad/glad.h"
|
||||
|
||||
|
||||
#include "ColorRaceApp.h"
|
||||
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||
|
||||
int main() {
|
||||
engine::Window window(1280, 720, "ColorRace");
|
||||
|
||||
while (!window.shouldClose()) {
|
||||
window.pollEvents();
|
||||
|
||||
glClearColor(0.1f, 0.1f, 0.15f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
window.swapBuffers();
|
||||
}
|
||||
ColorRaceApp app;
|
||||
app.run();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user