Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • gamedev/fggl
  • onuralpsezer/fggl
2 results
Show changes
Showing
with 2454 additions and 0 deletions
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 27/06/22.
//
#ifndef FGGL_GFX_INTERFACES_HPP
#define FGGL_GFX_INTERFACES_HPP
#include "fggl/gfx/paint.hpp"
#include "fggl/entity/entity.hpp"
#include "fggl/modules/module.hpp"
//! Classes responsible for rendering content
namespace fggl::gfx {
struct Bounds {
float top;
float right;
float bottom;
float left;
};
class Graphics {
public:
constexpr static const auto service = modules::make_service("fggl::gfx::Graphics");
virtual ~Graphics() = default;
virtual void clear() = 0;
virtual void resize(int width, int height) = 0;
virtual Bounds canvasBounds() = 0;
virtual void draw2D(const Paint &paint) = 0;
virtual void drawScene(entity::EntityManager &, bool debugMode = false) = 0;
};
} // namespace fggl::gfx
#endif //FGGL_GFX_INTERFACES_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_OGL_BACKEND_HPP
#define FGGL_GFX_OGL_BACKEND_HPP
#include "common.hpp"
#include "fggl/display/glfw/window.hpp"
#include <stdexcept>
/**
* FGGL OpenGL 4.x rendering backend.
*/
namespace fggl::gfx {
}
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_OGL_COMMON_HPP
#define FGGL_GFX_OGL_COMMON_HPP
/**
* Ensure Graphics libraries are in the right order.
*/
#ifdef _glfw_h_
#warning glfw included before opengl, bad things may happen
#endif
#include <glad/glad.h>
typedef void *(*GLADloadproc)(const char *name);
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_OGL_RENDERER_HPP
#define FGGL_GFX_OGL_RENDERER_HPP
#include <fggl/data/model.hpp>
#include <fggl/gfx/ogl/backend.hpp>
#include <fggl/gfx/ogl/shader.hpp>
#include "fggl/gfx/ogl4/models.hpp"
#include "fggl/gfx/ogl4/canvas.hpp"
#include "fggl/gfx/ogl4/debug.hpp"
#include <fggl/gfx/paint.hpp>
#include <memory>
#include <vector>
namespace fggl::gfx {
using GlFunctionLoader = GLADloadproc;
/**
* Class responsible for managing the OpenGL context.
*
* This class manages the OpenGL resources, all OpenGL resources are bound by its lifetime, and it is ultimately
* the class responsible for interacting with OpenGL. It is bound by the window it belongs to, and therefore if
* that window disappears so does this object.
*/
class OpenGL4Backend : public Graphics {
public:
explicit OpenGL4Backend(data::Storage *storage, gui::FontLibrary *fonts, assets::AssetManager *assets, GlFunctionLoader loader);
~OpenGL4Backend() override = default;
// copy bad
OpenGL4Backend(const OpenGL4Backend &) = delete;
OpenGL4Backend &operator=(const OpenGL4Backend &) = delete;
// move (probably) bad
OpenGL4Backend(OpenGL4Backend &&) = delete;
OpenGL4Backend &&operator=(OpenGL4Backend &&) = delete;
/**
* Clear the backing buffer.
*/
void clear() override;
/**
* Notify the graphics system the framebuffer size has changed.
*
* @param width the new framebuffer width
* @param height the new framebuffer height
*/
void resize(int width, int height) override;
/**
* Perform a 2D rendering pass.
*
* @param paint the objects to paint on screen
*/
void draw2D(const Paint &paint) override;
/**
* Perform a 3D rendering pass.
*
* @param world the world to render
*/
void drawScene(entity::EntityManager &world, bool debugMode=false) override;
/**
* Get the 2D canvas bounds.
*
* @return the canvas bounds
*/
inline Bounds canvasBounds() override {
return m_canvasRenderer->bounds();
}
private:
std::unique_ptr<ogl4::StaticModelRenderer> m_modelRenderer;
std::unique_ptr<ogl4::CanvasRenderer> m_canvasRenderer;
std::unique_ptr<ogl4::DebugRenderer> m_debugRenderer;
std::unique_ptr<ShaderCache> m_cache;
std::shared_ptr<ogl::Shader> m_canvasPipeline;
data::Storage *m_storage;
gui::FontLibrary *m_fontLibrary;
};
}; // namespace fggl::gfx
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_OGL_SHADER_HPP
#define FGGL_GFX_OGL_SHADER_HPP
#include <cstdio>
#include <fggl/gfx/ogl/backend.hpp>
#include "fggl/gfx/ogl/types.hpp"
#include <fggl/data/storage.hpp>
#include <filesystem>
#include <stdexcept>
#include <unordered_map>
namespace fggl::gfx {
constexpr GLuint INVALID_SHADER_ID = 0;
struct ShaderConfig {
// required
std::string name;
std::string vertex;
std::string fragment;
// optional parts
std::string geometry;
bool hasGeom = false;
static ShaderConfig named(const std::string &name, bool hasGeom = false) {
return {
.name = name,
.vertex = name + "_vert.glsl",
.fragment = name + "_frag.glsl",
.geometry = hasGeom ? name + "_geom.glsl" : "",
.hasGeom = hasGeom
};
}
};
struct ShaderSources {
std::string name;
std::string vertexSource;
std::string fragmentSource;
std::string geometrySource;
};
struct BinaryCache {
void *data = nullptr;
GLsizei size = 0;
GLenum format = GL_INVALID_ENUM;
};
class ShaderCache {
public:
using ShaderPtr = std::shared_ptr<ogl::Shader>;
ShaderCache(fggl::data::Storage *storage);
~ShaderCache() = default;
ShaderPtr load(const ShaderConfig &config);
ShaderPtr load(const ShaderSources &sources, bool allowBinaryCache);
ShaderPtr getOrLoad(const ShaderConfig &config);
ShaderPtr get(const std::string &name);
/**
* Fallback pipelines.
*
* All fallback pipelines are prefixed with "fallback_". They should be used as 'last resort' if there is
* no matching shader on disk for this game.
*/
void initFallbackPipelines();
private:
fggl::data::Storage* m_storage;
std::unordered_map<std::string, ShaderPtr> m_shaders;
// extensions
void setupIncludes();
// opengl operations
bool readAndCompileShader(const std::string &filename, GLuint shader);
bool compileShaderFromSource(const std::string &source, GLuint);
// file io operations
bool loadFromDisk(GLuint pid, const std::string &pipelineName);
void saveToDisk(GLuint pid, const std::string &pipelineName);
bool m_binary;
void cacheSave(GLuint pid, BinaryCache *cache);
bool cacheLoad(GLuint pid, const BinaryCache *cache);
};
}
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// uses RAII, with reference to https://www.khronos.org/opengl/wiki/Common_Mistakes#RAII_and_hidden_destructor_calls
//
#ifndef FGGL_GFX_OGL_TYPES_HPP
#define FGGL_GFX_OGL_TYPES_HPP
#include <cstdint>
#include <cassert>
#include <string_view>
#include <iostream>
#include <glm/gtc/type_ptr.hpp>
#include "fggl/gfx/ogl/common.hpp"
#include "fggl/math/types.hpp"
#include "fggl/data/texture.hpp"
namespace fggl::gfx::ogl {
// reset values into their 'empty' states
void deactivate_shader();
void deactivate_buffer();
void deactivate_vertex_array();
constexpr GLuint UNIFORM_NOOP = -1;
using Location = GLint;
class Shader {
private:
GLuint m_obj = 0;
void release();
public:
Shader() = default;
inline Shader(GLuint obj) : m_obj(obj) {}
// copy constructor bad
Shader(const Shader &) = delete;
Shader &operator=(const Shader &) = delete;
// Move ok - if handled properly
Shader(Shader &&other);
Shader &operator=(Shader &&other);
void use() {
glUseProgram(m_obj);
}
inline bool hasUniform(const std::string_view &name) const {
auto location = glGetUniformLocation(m_obj, name.data());
return location != -1;
}
inline Location uniform(const std::string_view &name) const {
auto location = glGetUniformLocation(m_obj, name.data());
if (location == -1) {
debug::warning("uniform {} does not exist", name);
}
return location;
}
inline GLuint shaderID() {
return m_obj;
}
// primatives
inline void setUniformF(Location name, GLfloat value) {
glProgramUniform1f(m_obj, name, value);
}
inline void setUniformI(Location name, GLint value) {
glProgramUniform1i(m_obj, name, value);
}
inline void setUniformU(Location name, GLuint value) {
glProgramUniform1ui(m_obj, name, value);
}
// vector versions (float)
inline void setUniformF(Location name, const math::vec2f &value) {
glProgramUniform2f(m_obj, name, value.x, value.y);
}
inline void setUniformF(Location name, const math::vec3f &value) {
glProgramUniform3f(m_obj, name, value.x, value.y, value.z);
}
inline void setUniformF(Location name, const math::vec4f &value) {
glProgramUniform4f(m_obj, name, value.x, value.y, value.z, value.w);
}
// vector versions (int)
inline void setUniformI(Location name, math::vec2i value) {
glProgramUniform2i(m_obj, name, value.x, value.y);
}
inline void setUniformI(Location name, math::vec3i value) {
glProgramUniform3i(m_obj, name, value.x, value.y, value.z);
}
inline void setUniformI(Location name, math::vec4i value) {
glProgramUniform4i(m_obj, name, value.x, value.y, value.z, value.w);
}
// matrix versions
inline void setUniformMtx(Location name, const math::mat2 &mtx) {
glProgramUniformMatrix2fv(m_obj, name, 1, GL_FALSE, glm::value_ptr(mtx));
}
void setUniformMtx(Location name, const math::mat3 &mtx) {
glProgramUniformMatrix3fv(m_obj, name, 1, GL_FALSE, glm::value_ptr(mtx));
}
void setUniformMtx(Location name, const math::mat4 &mtx) {
glProgramUniformMatrix4fv(m_obj, name, 1, GL_FALSE, glm::value_ptr(mtx));
}
};
enum class Wrapping {
REPEAT = GL_REPEAT,
MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER
};
enum class Filtering {
NEIGHBOUR = GL_NEAREST,
LINEAR = GL_LINEAR,
// these are their openGL names, but they are kinda bad, can we do better/alias?
NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR,
MIPMAP_CLOSEST_NEIGHBOUR = GL_NEAREST_MIPMAP_NEAREST,
MIPMAP_CLOSEST_LINEAR = GL_LINEAR_MIPMAP_NEAREST,
TWO_MIPMAP_NEIGHBOUR = GL_NEAREST_MIPMAP_LINEAR,
TWO_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
};
enum class TextureType {
Tex1D = GL_TEXTURE_1D,
Tex1DArray = GL_TEXTURE_1D_ARRAY,
Tex2D = GL_TEXTURE_2D,
Tex2DArray = GL_TEXTURE_2D_ARRAY,
Tex2DMultisample = GL_TEXTURE_2D_MULTISAMPLE,
Tex2DMultisampleArray = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
Tex3D = GL_TEXTURE_3D,
Rectangle = GL_TEXTURE_RECTANGLE,
CubeMap = GL_TEXTURE_CUBE_MAP,
CubeMapArray = GL_TEXTURE_CUBE_MAP_ARRAY,
Buffer = GL_TEXTURE_BUFFER,
};
enum class PixelFormat {
UNSIGNED_BYTE = GL_UNSIGNED_BYTE,
BYTE = GL_BYTE,
UNSIGNED_SHORT = GL_UNSIGNED_SHORT,
SHORT = GL_SHORT,
UNSIGNED_INT = GL_UNSIGNED_INT,
INT = GL_INT,
//HALF_FLOAT = GL_HALF_FLOAT,
FLOAT = GL_FLOAT,
/*
UNSIGNED_BYTE_3_3_2,
UNSIGNED_BYTE_2_3_3_REV,
UNSIGNED_SHORT_5_6_5,
UNSIGNED_SHORT_5_6_5_REV,
UNSINGED_SHORT_4_4_4_4,
UNSIGNED_SHORT_4_4_4_4_REV,
UNSIGNED_SHORT_5_5_5_1,
UNSIGNED_SHORT_1_5_5_5_REV,
UNSIGNED_INT_8_8_8_8,
UNSIGNED_INT_8_8_8_8_REV,
UNSIGNED_INT_10_10_10_10_2,
UNSIGNED_INT_10_10_10_10_2_REV,*/
};
enum class InternalImageFormat {
DepthComponent = GL_DEPTH_COMPONENT,
DepthStencil = GL_DEPTH_STENCIL,
Red = GL_RED,
RedGreen = GL_RG,
RedGreenBlue = GL_RGB,
RedGreenBlueAlpha = GL_RGBA
};
enum class ImageFormat {
R = GL_RED,
RG = GL_RG,
RGB = GL_RGB,
RGBA = GL_RGBA,
R_INT = GL_RED_INTEGER,
RG_INT = GL_RG_INTEGER,
RGB_INT = GL_RGB_INTEGER,
RGBA_INT = GL_RGBA_INTEGER,
BGR = GL_BGR,
BGRA = GL_BGRA,
BGR_INT = GL_BGR_INTEGER,
BGRA_INT = GL_BGRA_INTEGER,
STENTICL_INDEX = GL_STENCIL_INDEX,
DEPTH_COMPONENT = GL_DEPTH_COMPONENT,
DEPTH_STENCIL = GL_DEPTH_STENCIL
};
struct PixelDataArray {
PixelFormat type;
union {
unsigned char *uc;
char *c;
std::uint16_t *us;
std::int16_t *s;
float *f;
std::int32_t *i;
std::uint32_t *ui;
};
bool owning;
inline PixelDataArray(PixelFormat fmt, std::size_t size) : type(fmt), owning(true) {
switch (type) {
case PixelFormat::UNSIGNED_BYTE:
uc = new unsigned char[size];
break;
case PixelFormat::BYTE:
c = new char[size];
break;
case PixelFormat::UNSIGNED_SHORT:
us = new std::uint16_t[size];
break;
case PixelFormat::SHORT:
s = new std::int16_t[size];
break;
case PixelFormat::FLOAT:
f = new float[size];
break;
case PixelFormat::INT:
i = new std::int32_t[size];
break;
case PixelFormat::UNSIGNED_INT:
ui = new std::uint32_t[size];
break;
}
}
inline explicit PixelDataArray(unsigned char* data) : type(PixelFormat::UNSIGNED_BYTE), uc(data), owning(false) {}
inline explicit PixelDataArray(char* data) : type(PixelFormat::BYTE), c(data), owning(false) {}
// no copy
PixelDataArray(const PixelDataArray&) = delete;
PixelDataArray& operator=(const PixelDataArray&) = delete;
// move ok
PixelDataArray(PixelDataArray&& other) : type(other.type), owning(other.owning) {
switch (type) {
case PixelFormat::UNSIGNED_BYTE:
uc = other.uc;
other.uc = nullptr;
break;
case PixelFormat::BYTE:
c = other.c;
other.c = nullptr;
break;
case PixelFormat::UNSIGNED_SHORT:
us = other.us;
other.us = nullptr;
break;
case PixelFormat::SHORT:
s = other.s;
other.s = nullptr;
break;
case PixelFormat::FLOAT:
f = other.f;
other.f = nullptr;
break;
case PixelFormat::INT:
i = other.i;
other.i = nullptr;
break;
case PixelFormat::UNSIGNED_INT:
ui = other.ui;
other.ui = nullptr;
break;
}
}
inline ~PixelDataArray() {
if (owning) {
switch (type) {
case PixelFormat::UNSIGNED_BYTE: delete[] uc;
uc = nullptr;
break;
case PixelFormat::BYTE: delete[] c;
c = nullptr;
break;
case PixelFormat::UNSIGNED_SHORT: delete[] us;
us = nullptr;
break;
case PixelFormat::SHORT: delete[] s;
s = nullptr;
break;
case PixelFormat::FLOAT: delete[] f;
f = nullptr;
break;
case PixelFormat::INT: delete[] i;
i = nullptr;
break;
case PixelFormat::UNSIGNED_INT:
delete[] ui;
ui = nullptr;
break;
}
}
}
void* data() {
switch (type) {
case PixelFormat::UNSIGNED_BYTE:
return uc;
case PixelFormat::BYTE:
return c;
case PixelFormat::UNSIGNED_SHORT:
return us;
case PixelFormat::SHORT:
return s;
case PixelFormat::FLOAT:
return f;
case PixelFormat::INT:
return i;
case PixelFormat::UNSIGNED_INT:
return ui;
}
// unknown type?
return nullptr;
}
};
struct Image {
ImageFormat format;
math::vec2i size;
PixelDataArray data;
//Image() = default;
inline Image(ImageFormat fmt, PixelFormat pxFmt, math::vec2i asize) :
format(fmt),
size(asize),
data(pxFmt, asize.x * asize.y){}
inline Image(ImageFormat fmt, math::vec2i asize, PixelDataArray&& adata) :
format(fmt),
size(asize),
data(std::move(adata)) {}
Image(const Image&) = delete;
inline PixelFormat type() const {
return data.type;
}
void* dataPtr() {
return data.data();
}
};
class Texture {
public:
inline explicit Texture(TextureType type) : m_type(type) {
glGenTextures(1, &m_obj);
}
~Texture() {
glDeleteTextures(1, &m_obj);
}
void setup(InternalImageFormat iFmt, math::vec2i size) {
//bind();
glBindTexture((GLenum) m_type, m_obj);
if (iFmt == InternalImageFormat::DepthComponent) {
glTexImage2D((GLenum)m_type,
0,
(GLint) iFmt,
size.x,
size.y,
0,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE,
nullptr);
} else {
glTexImage2D((GLenum)
m_type, 0, (GLint) iFmt, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
}
}
void setData(InternalImageFormat iFmt, Image &image, PixelFormat extFormat) {
//bind();
glBindTexture((GLenum) m_type, m_obj);
glTexImage2D((GLenum) m_type,
0,
(GLint) iFmt,
image.size.x,
image.size.y,
0,
(GLenum) image.format,
(GLenum) extFormat,
image.dataPtr());
if ( m_type == TextureType::Tex2D ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
void setData(InternalImageFormat iFmt, Image &image) {
//bind();
glBindTexture((GLenum) m_type, m_obj);
glTexImage2D((GLenum) m_type,
0,
(GLint) iFmt,
image.size.x,
image.size.y,
0,
(GLenum) image.format,
(GLenum) image.type(),
image.dataPtr());
if ( m_type == TextureType::Tex2D ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
void setData(InternalImageFormat iFmt, const data::Texture2D *image) {
ImageFormat imageFormat;
if (image->channels == 1) {
imageFormat = ImageFormat::R;
} else if ( image->channels == 2) {
imageFormat = ImageFormat::RG;
} else if ( image->channels == 3) {
imageFormat = ImageFormat::RGB;
} else if ( image->channels == 4) {
imageFormat = ImageFormat::RGBA;
} else {
// unknown image format -> channels mapping, having a bad day!
return;
}
//bind();
glBindTexture((GLenum) m_type, m_obj);
glTexImage2D((GLenum) m_type,
0,
(GLint) iFmt,
image->size.x,
image->size.y,
0,
(GLenum) imageFormat,
GL_UNSIGNED_BYTE,
image->data);
if ( m_type == TextureType::Tex2D ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
void setDataPart(math::vec2i offset, Image &image) {
glTexImage2D((GLenum) m_type,
0,
offset.x,
offset.y,
image.size.x,
image.size.y,
(GLenum) image.format,
(GLenum) image.type(),
image.dataPtr());
}
void wrapMode(Wrapping wrap);
void filterModeMagnify(Filtering filter);
void filterModeMinify(Filtering filter);
/**
* Bind this texture to a texture unit.
*
* @param textureUnit the texture unit to bind to
*/
inline void bind(unsigned int textureUnit) {
assert(textureUnit < GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture((GLenum) m_type, m_obj);
}
private:
GLuint m_obj = 0;
TextureType m_type;
void release();
};
constexpr std::size_t NO_RESTART_IDX = 0;
enum class BuffAttrF {
HALF_FLOAT = GL_HALF_FLOAT,
FLOAT = GL_FLOAT,
DOUBLE = GL_DOUBLE,
FIXED = GL_FIXED
};
enum class BuffAttrI {
BYTE = GL_BYTE,
UBYTE = GL_UNSIGNED_BYTE,
SHORT = GL_SHORT,
USHORT = GL_UNSIGNED_SHORT,
INT = GL_INT,
UINT = GL_UNSIGNED_INT,
// these ones are oddly spesific...
INT_PACKED = GL_INT_2_10_10_10_REV,
UINT_PACKED = GL_UNSIGNED_INT_2_10_10_10_REV,
UINT_PACKED_F = GL_UNSIGNED_INT_10F_11F_11F_REV
};
enum class Primitive {
POINT = GL_POINT,
LINE = GL_LINES,
LINE_STRIP = GL_LINE_STRIP,
LINE_LOOP = GL_LINE_LOOP,
TRIANGLE = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
TRIANGLE_FAN = GL_TRIANGLE_FAN
};
enum class BufType {
ARRAY = GL_ARRAY_BUFFER,
ELEMENT_ARRAY = GL_ELEMENT_ARRAY_BUFFER,
COPY_READ = GL_COPY_READ_BUFFER,
COPY_WRITE = GL_COPY_WRITE_BUFFER,
PIXEL_UNPACK = GL_PIXEL_UNPACK_BUFFER,
PIXEL_PACK = GL_PIXEL_PACK_BUFFER,
QUERY = GL_QUERY_BUFFER,
TEXTURE = GL_TEXTURE_BUFFER,
TRANSFORM_FEEDBACK = GL_TRANSFORM_FEEDBACK_BUFFER,
UNIFORM = GL_UNIFORM_BUFFER,
DRAW_INDRECT = GL_DRAW_INDIRECT_BUFFER,
ATOMIC_COUNTER = GL_ATOMIC_COUNTER_BUFFER,
DISPATCH_INDIRECT = GL_DISPATCH_INDIRECT_BUFFER,
SHADER_STORAGE = GL_SHADER_STORAGE_BUFFER
};
enum class BufUsage {
STATIC_DRAW = GL_STATIC_DRAW,
STATIC_READ = GL_STATIC_READ,
STATIC_COPY = GL_STATIC_COPY,
DYNAMIC_DRAW = GL_DYNAMIC_DRAW,
DYNAMIC_READ = GL_DYNAMIC_READ,
DYNAMIC_COPY = GL_DYNAMIC_COPY,
STREAM_DRAW = GL_STREAM_DRAW,
STREAM_READ = GL_STREAM_READ,
STREAM_COPY = GL_STREAM_COPY,
};
template<BufType T>
class Buffer {
private:
GLuint m_obj = 0;
GLsizeiptr m_capacity = 0;
/**
* Free an underlying buffer.
*
* If this buffer object is already empty, this is a no-op (and the OpenGL spec guarntees that freeing buffer
* 0 has no effect.
*/
void release() {
glDeleteBuffers(1, &m_obj);
m_obj = 0;
}
public:
/**
* Create a new (unfilled) buffer object.
*/
Buffer() {
glGenBuffers(1, &m_obj);
}
~Buffer() {
release();
}
// copy constructor bad
Buffer(const Buffer &) = delete;
Buffer &operator=(const Buffer &) = delete;
Buffer(Buffer &&other) : m_obj(other.m_obj), m_capacity(other.m_capacity) {
other.obj_ = 0;
other.m_capacity = 0;
}
Buffer &operator=(Buffer &&other) {
if (this != &other) {
release();
std::swap(m_obj, other.m_obj);
std::swap(m_capacity, other.m_capacity);
}
}
void bind() const {
assert(m_obj != 0);
glBindBuffer((GLenum) T, m_obj);
}
inline bool isValid() const {
return m_obj != 0;
};
void write(GLsizeiptr size, const GLvoid *data, BufUsage usage) {
bind();
glBufferData((GLenum) T, size, data, (GLenum) usage);
}
void update(GLintptr offset, GLsizeiptr size, const void *data) {
}
template<typename D>
void replace(std::size_t size, const D *data) {
bind();
GLsizeiptr sizePtr = size * sizeof(D);
if (sizePtr > m_capacity) {
glBufferData((GLenum) T, sizePtr, data, GL_STREAM_DRAW);
m_capacity = sizePtr;
} else {
glBufferSubData((GLenum) T, 0, sizePtr, data);
}
glBindBuffer((GLenum) T, 0);
}
};
// common buffer types
using ArrayBuffer = Buffer<BufType::ARRAY>;
using ElementBuffer = Buffer<BufType::ELEMENT_ARRAY>;
struct AttributeF {
BuffAttrF attrType;
GLint elmCount;
GLsizei stride;
std::size_t offset;
};
struct AttributeI {
BuffAttrI attrType;
GLint elmCount;
GLsizei stride;
std::size_t offset;
};
// type intrinsics to make interface nicer
template<typename T>
struct attr_type {
const static BuffAttrF attr;
const static GLint size;
};
template<typename V, typename T>
AttributeF attribute(std::size_t offset) {
return AttributeF{
attr_type<T>::attr,
attr_type<T>::size,
sizeof(V),
offset
};
}
/**
* Represents an OpenGL vertex array object (VAO).
*
* This contains most information about an OpenGL state for supplying vertex data to the GPU. There is some basic
* debug checking to stop silly stuff happening, but this will be disabled in release mode.
*/
class VertexArray {
private:
GLuint m_obj = 0;
void release();
public:
VertexArray();
~VertexArray();
// copy constructors bad
VertexArray(const VertexArray &) = delete;
VertexArray &operator=(const VertexArray) = delete;
// move constructors might be ok
VertexArray(VertexArray &&other) noexcept;
VertexArray &operator=(VertexArray &&other);
inline void bind() const {
assert(m_obj != 0);
glBindVertexArray(m_obj);
}
void setAttribute(const ArrayBuffer &buffer, GLuint idx, AttributeF &attr);
void setAttribute(const ArrayBuffer &buffer, GLuint idx, AttributeI &attr, bool normalized);
void setAttributeI(const ArrayBuffer &buffer, GLuint idx, AttributeI &attr);
void drawElements(const ElementBuffer &buff, Primitive drawType, std::size_t size);
void draw(Primitive drawType, int first, std::size_t count);
};
// paranoid functions
void bind_vertex_array(GLuint &marker);
void unbind_vertex_array(GLuint &marker);
template<BufType T>
void bind_buffer(GLuint *marker, const Buffer<T> &buff) {
#ifdef FGGL_GL_PARANOID
assert( marker != nullptr );
glGetIntegerv( (GLenum)T, (GLint*) marker );
#endif
buff.bind();
}
template<BufType T>
void unbind_buffer(GLuint *marker, const Buffer<T> &buff) {
#ifdef GL_FGGL_PARANOID
assert( marker != nullptr );
glBindVertexArray(marker);
#endif
}
} // namespace fggl::gfx::ogl
#endif //FGGL_GFX_OGL_TYPES_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 17/04/22.
//
#ifndef FGGL_GFX_OGL4_CANVAS_HPP
#define FGGL_GFX_OGL4_CANVAS_HPP
#include "fggl/gfx/paint.hpp"
#include "fggl/gfx/ogl/types.hpp"
#include "fggl/gfx/interfaces.hpp"
#include "fggl/gui/fonts.hpp"
namespace fggl::gfx::ogl4 {
class CanvasRenderer {
public:
CanvasRenderer(gui::FontLibrary *fonts);
void render(ogl::Shader& shader, const gfx::Paint &paint);
inline gfx::Bounds bounds() const {
return m_bounds;
}
private:
gfx::Bounds m_bounds;
ogl::VertexArray m_vao;
ogl::ArrayBuffer m_vertexList;
ogl::ElementBuffer m_indexList;
gui::FontLibrary *m_fonts;
ogl::Texture m_fontTex;
void renderShapes(const Paint &paint, ogl::Shader& shader);
void renderText(const Paint &, ogl::Shader& shader);
};
} // namespace fggl::gfx::ogl4
#endif //FGGL_GFX_OGL4_CANVAS_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 30/05/22.
//
#ifndef FGGL_GFX_OGL4_DEBUG_HPP
#define FGGL_GFX_OGL4_DEBUG_HPP
#include "fggl/debug/draw.hpp"
namespace fggl::gfx::ogl4 {
class DebugRenderer : public dd::RenderInterface {
public:
explicit DebugRenderer(std::shared_ptr<ogl::Shader> shader);
~DebugRenderer() override = default;
void drawLineList(const dd::DrawVertex *lines, int count, bool depthEnabled) override;
math::mat4 mvpMatrix;
private:
std::shared_ptr<ogl::Shader> m_lineShader;
ogl::Location m_lineShaderMVP;
ogl::VertexArray m_lineVao;
ogl::ArrayBuffer m_lineVbo;
};
}
#endif //FGGL_GFX_OGL4_DEBUG_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 22/06/22.
//
#ifndef FGGL_GFX_OGL4_FALLBACK_HPP
#define FGGL_GFX_OGL4_FALLBACK_HPP
#include "fggl/assets/types.hpp"
/**
* Fallback shaders.
*
* Embedded in the library, so that the user can use the library without having to include the shaders.
*/
namespace fggl::gfx::ogl4 {
constexpr const char *FALLBACK_CANVAS_PIPELINE = "fallback_canvas";
constexpr const char *FALLBACK_CANVAS_VERTEX_SHADER = R"glsl(
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColour;
layout (location = 2) in vec2 aTexPos;
uniform mat4 projection;
out vec3 colour;
out vec2 texPos;
void main() {
gl_Position = projection * vec4(aPos, 0.0, 1.0);
colour = aColour;
texPos = aTexPos;
})glsl";
constexpr const char *FALLBACK_CANVAS_FRAGMENT_SHADER = R"glsl(
#version 330 core
uniform sampler2D tex;
in vec3 colour;
in vec2 texPos;
out vec4 fragColour;
void main() {
fragColour = vec4(colour.xyz, texture(tex, texPos).r);
})glsl";
constexpr const GLuint TEX_CHECKER = 0x11FF11FF; //FIXME pixel order is reversed?!
constexpr const GLuint TEX_WHITE = 0xFF0000FF;
constexpr const assets::AssetID FALLBACK_TEX = assets::make_asset_id("fallback", "FALLBACK_TEX");
constexpr const assets::AssetID FALLBACK_MAT = assets::make_asset_id("fallback", "FALLBACK_MAT");
constexpr const assets::AssetID SOLID_TEX = assets::make_asset_id("fallback", "SOLID_TEX");
constexpr const math::vec3 FALLBACK_COLOUR {1.0F, 0.0F, 1.0F};
} // namespace fggl::gfx::ogl4
#endif //FGGL_GFX_OGL4_FALLBACK_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 22/10/22.
//
#ifndef FGGL_GFX_OGL4_MESHES_HPP
#define FGGL_GFX_OGL4_MESHES_HPP
#include "fggl/mesh/components.hpp"
#include "fggl/entity/entity.hpp"
#include "fggl/assets/manager.hpp"
#include "fggl/gfx/ogl/types.hpp"
#include "fggl/gfx/ogl4/fallback.hpp"
#include "fggl/gfx/camera.hpp"
#include "fggl/gfx/phong.hpp"
namespace fggl::gfx::ogl4 {
struct DrawType {
ogl::Primitive mode;
std::size_t restartIndex = ogl::NO_RESTART_IDX;
};
struct Material {
math::vec3 m_diffCol{1.0F, 1.0F, 1.0F};
math::vec3 m_specCol{1.0F, 1.0F, 1.0F};
ogl::Texture* m_diffuse;
ogl::Texture* m_normals;
ogl::Texture* m_specular;
};
struct MeshData {
std::shared_ptr<ogl::VertexArray> vao;
std::shared_ptr<ogl::ElementBuffer> elements;
std::shared_ptr<ogl::ArrayBuffer> vertexData;
std::size_t elementCount;
DrawType drawInfo;
Material* material;
void draw(std::shared_ptr<ogl::Shader> shader) const;
};
struct StaticMesh {
constexpr static auto name = "StaticMultiMesh";
std::shared_ptr<ogl::Shader> pipeline;
MeshData mesh;
inline void draw() const {
mesh.draw(pipeline);
}
};
struct StaticMultiMesh {
constexpr static auto name = "StaticMultiMesh";
std::shared_ptr<ogl::Shader> pipeline;
std::vector<MeshData> meshes;
void draw() const;
};
void setup_material(const std::shared_ptr<ogl::Shader>& shader, const PhongMaterial* material);
void setup_lighting(const std::shared_ptr<ogl::Shader>& shader, const math::mat4& viewMatrix, const math::Transform& camTransform, const math::Transform& transform, math::vec3 lightPos);
void setup_lighting(const std::shared_ptr<ogl::Shader>& shader, const DirectionalLight* light);
template<typename T>
void forward_pass(const entity::EntityID& camera, const fggl::entity::EntityManager& world, const assets::AssetManager* assets) {
// enable required OpenGL state
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// enable depth testing
glEnable(GL_DEPTH_TEST);
// prep the fallback textures
auto *fallbackTex = assets->template get<ogl::Texture>(FALLBACK_TEX);
fallbackTex->bind(0);
fallbackTex->bind(1);
// set-up camera matrices
const auto &camTransform = world.get<fggl::math::Transform>(camera);
const auto &camComp = world.get<fggl::gfx::Camera>(camera);
const math::mat4 projectionMatrix = camComp.perspective();
const math::mat4 viewMatrix = glm::lookAt(camTransform.origin(), camComp.target, camTransform.up());
std::shared_ptr<ogl::Shader> shader = nullptr;
ogl::Location mvpMatrixUniform = 0;
ogl::Location mvMatrixUniform = 0;
auto entityView = world.find<T>();
// find directional light in scene
const DirectionalLight* light = nullptr;
auto lightEnts = world.find<DirectionalLight>();
if ( !lightEnts.empty() ) {
light = world.tryGet<DirectionalLight>(lightEnts[0]);
}
for (const auto &entity : entityView) {
// ensure that the model pipeline actually exists...
const auto &model = world.get<T>(entity);
if (model.pipeline == nullptr) {
debug::warning("shader was null, aborting render");
continue;
}
// check if we switched shaders
if (shader == nullptr || shader->shaderID() != model.pipeline->shaderID()) {
// new shader - need to re-send the view and projection matrices
shader = model.pipeline;
shader->use();
if (shader->hasUniform("projection")) {
shader->setUniformMtx(shader->uniform("view"), viewMatrix);
shader->setUniformMtx(shader->uniform("projection"), projectionMatrix);
}
mvpMatrixUniform = shader->uniform("MVPMatrix");
mvMatrixUniform = shader->uniform("MVMatrix");
if ( shader->hasUniform("diffuseTexture") ) {
shader->setUniformI(shader->uniform("diffuseTexture"), 0);
}
if ( shader->hasUniform("specularTexture") ) {
shader->setUniformI(shader->uniform("specularTexture"), 1);
}
}
// set model transform
const auto &transform = world.get<math::Transform>(entity);
shader->setUniformMtx(mvpMatrixUniform, projectionMatrix * viewMatrix * transform.model());
shader->setUniformMtx(mvMatrixUniform, viewMatrix * transform.model());
// setup lighting mode
if ( light != nullptr ) {
setup_lighting(shader, light);
}
setup_material(shader, world.tryGet<PhongMaterial>(entity, &DEFAULT_MATERIAL));
// actually draw it
model.draw();
}
}
template<typename T>
void forward_pass_normals(const entity::EntityID& camera, const fggl::entity::EntityManager& world, const std::shared_ptr<ogl::Shader>& shader) {
// enable required OpenGL state
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// enable depth testing
glEnable(GL_DEPTH_TEST);
// set-up camera matrices
const auto &camTransform = world.get<fggl::math::Transform>(camera);
const auto &camComp = world.get<fggl::gfx::Camera>(camera);
const math::mat4 projectionMatrix = camComp.perspective();
const math::mat4 viewMatrix = glm::lookAt(camTransform.origin(), camComp.target, camTransform.up());
ogl::Location modelUniform = shader->uniform("model");
ogl::Location viewUniform = shader->uniform("view");
ogl::Location projUniform = shader->uniform("projection");
shader->use();
shader->setUniformMtx(projUniform, projectionMatrix);
shader->setUniformMtx(viewUniform, viewMatrix);
auto entities = world.find<T>();
for (const auto &entity : entities) {
// ensure that the model pipeline actually exists...
const auto &model = world.get<T>(entity);
// set model transform
const auto &transform = world.get<math::Transform>(entity);
shader->setUniformMtx(modelUniform, transform.model());
// render model
model.draw();
}
}
MeshData upload_mesh(const mesh::Mesh3D& meshComponent, assets::AssetManager* manager);
std::vector<MeshData> upload_multi_mesh(const mesh::MultiMesh3D& meshComponent, assets::AssetManager* manager);
} // namespace fggl::gfx::ogl4
#endif //FGGL_GFX_OGL4_MESHES_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 17/04/22.
//
#ifndef FGGL_GFX_OGL4_MODELS_HPP
#define FGGL_GFX_OGL4_MODELS_HPP
#include <string>
#include <unordered_map>
#include "fggl/gfx/ogl/shader.hpp"
#include "fggl/gfx/ogl/backend.hpp"
#include "fggl/gfx/ogl/types.hpp"
#include "fggl/data/model.hpp"
#include "fggl/mesh/mesh.hpp"
#include "fggl/assets/manager.hpp"
#define FGGL_ALLOW_DEFERRED_UPLOAD
namespace fggl::gfx::ogl4 {
struct StaticModelGPU {
std::shared_ptr<ogl::VertexArray> vao;
std::shared_ptr<ogl::ElementBuffer> elements;
std::shared_ptr<ogl::ArrayBuffer> vertices;
std::size_t elementCount;
ogl::Primitive drawType = ogl::Primitive::TRIANGLE;
std::size_t restartIndex = ogl::NO_RESTART_IDX;
};
struct StaticModelInstance {
constexpr static auto name = "ogl::static::model";
std::string modelName;
StaticModelGPU* model = nullptr;
std::shared_ptr<ogl::Shader> pipeline;
};
struct StaticModel {
constexpr static auto name = "StaticModel";
std::shared_ptr<ogl::Shader> pipeline;
// element data
std::shared_ptr<ogl::VertexArray> vao;
std::shared_ptr<ogl::ElementBuffer> elements;
std::shared_ptr<ogl::ArrayBuffer> vertexData;
std::size_t elementCount;
ogl::Primitive drawType;
std::size_t restartIndex = ogl::NO_RESTART_IDX;
};
class StaticModelRenderer {
public:
inline StaticModelRenderer(gfx::ShaderCache *cache, assets::AssetManager *assets)
: m_assets(assets), m_shaders(cache), m_phong(nullptr), m_vao(), m_vertexList(), m_indexList() {
m_phong = cache->get("redbook/debug");
}
~StaticModelRenderer() = default;
StaticModelRenderer(const StaticModelRenderer &other) = delete;
StaticModelRenderer(StaticModelRenderer &&other) = delete;
StaticModelRenderer &operator=(const StaticModelRenderer &other) = delete;
StaticModelRenderer &operator=(StaticModelRenderer &&other) = delete;
StaticModel* uploadMesh(assets::AssetID guid, const data::Mesh& mesh, bool allowCache=true);
StaticModelGPU* uploadMesh2(const assets::AssetID& meshName, const data::Mesh& mesh);
void render(entity::EntityManager &world, bool debugMode = false) {
#ifdef FGGL_ALLOW_DEFERRED_UPLOAD
resolveModels(world);
#endif
renderModelsForward(world, debugMode);
}
private:
#ifdef FGGL_ALLOW_DEFERRED_UPLOAD
/**
* Attach any missing rendering components to models.
*/
void resolveModels(entity::EntityManager &world);
#endif
/**
* Render all visible objects according to their render tokens.
*/
void renderModelsForward(const entity::EntityManager &world, bool debugMode);
assets::AssetManager *m_assets;
gfx::ShaderCache *m_shaders;
std::shared_ptr<ogl::Shader> m_phong;
ogl::VertexArray m_vao;
ogl::ArrayBuffer m_vertexList;
ogl::ElementBuffer m_indexList;
};
}
#endif //FGGL_GFX_OGL4_MODELS_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 27/06/22.
//
#ifndef FGGL_GFX_OGL4_MODULE_HPP
#define FGGL_GFX_OGL4_MODULE_HPP
#include <array>
#include "fggl/modules/module.hpp"
#include "fggl/assets/manager.hpp"
#include "fggl/assets/packed/module.hpp"
#include "fggl/entity/loader/loader.hpp"
#include "fggl/gfx/interfaces.hpp"
#include "fggl/gfx/setup.hpp"
#include "fggl/gfx/ogl/renderer.hpp"
#include "fggl/gfx/ogl4/setup.hpp"
namespace fggl::gfx {
struct OpenGL4 {
constexpr static const char *name = "fggl::gfx::OpenGL4";
constexpr static const std::array<modules::ServiceName, 1> provides = {
WindowGraphics::service
};
constexpr static const std::array<modules::ServiceName, 5> depends = {
data::Storage::service,
assets::AssetManager::service,
assets::CheckinAdapted::service,
gui::FontLibrary::service,
entity::EntityFactory::service
};
static bool factory(modules::ServiceName name, modules::Services &serviceManager);
};
} //namespace fggl::gfx
#endif //FGGL_GFX_OGL4_MODULE_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 27/06/22.
//
#ifndef FGGL_GFX_OGL4_SETUP_HPP
#define FGGL_GFX_OGL4_SETUP_HPP
#include "fggl/gfx/setup.hpp"
#include "fggl/gfx/ogl/renderer.hpp"
namespace fggl::gfx::ogl4 {
constexpr GraphicsDetails OPENGL_4_3_PRODUCTION { GraphicsAPI::OpenGL, 4, 3, false };
constexpr GraphicsDetails OPENGL_4_3_DEBUG { GraphicsAPI::OpenGL, 4, 3, true };
class WindowGraphics : public gfx::WindowGraphics {
public:
WindowGraphics(data::Storage *storage, gui::FontLibrary *fonts, assets::AssetManager* assets) : m_storage(storage), m_fonts(fonts), m_assets(assets) {};
~WindowGraphics() override = default;
// no copy
WindowGraphics(WindowGraphics& gfx) = delete;
WindowGraphics& operator=(const WindowGraphics& gfx) = delete;
// no move
WindowGraphics(WindowGraphics&& gfx) = delete;
WindowGraphics& operator=(WindowGraphics&& gfx) = delete;
fggl::gfx::Graphics *create(display::Window &window) override;
[[nodiscard]]
inline GraphicsDetails config() const override {
#ifdef NDEBUG
return OPENGL_4_3_PRODUCTION;
#else
return OPENGL_4_3_DEBUG;
#endif
}
private:
data::Storage *m_storage;
gui::FontLibrary *m_fonts;
assets::AssetManager *m_assets;
};
} // namespace fggl::gfx::ogl4
#endif //FGGL_GFX_OGL4_SETUP_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_PAINT_HPP
#define FGGL_GFX_PAINT_HPP
#include <string>
#include <vector>
#include <fggl/math/types.hpp>
namespace fggl::gfx {
using RadianAngle = float;
constexpr float COLOUR_MAX = 255.0F;
constexpr uint32_t BYTE_MASK = 0xFF;
constexpr uint8_t ONE_BYTE = 8;
constexpr uint8_t TWO_BYTES = 16;
constexpr math::vec3 rgb(uint32_t value) {
uint8_t red = (value & BYTE_MASK);
uint8_t green = ((value >> ONE_BYTE ) & BYTE_MASK);
uint8_t blue = ((value >> TWO_BYTES ) & BYTE_MASK);
return { (float)red / COLOUR_MAX, (float)green / COLOUR_MAX, (float)blue / COLOUR_MAX};
}
namespace colours {
constexpr math::vec3 rgb_decimal(uint8_t red, uint8_t green, uint8_t blue) {
return { (float)red / COLOUR_MAX, (float)green / COLOUR_MAX, (float)blue / COLOUR_MAX};
}
constexpr math::vec3 rgb(uint32_t value) {
uint8_t red = ( (value >> TWO_BYTES) & BYTE_MASK);
uint8_t green = ( (value >> ONE_BYTE) & BYTE_MASK);
uint8_t blue = value & BYTE_MASK;
return rgb_decimal(red, green, blue);
}
//
// Extended (CSS3) Colours
//
// pinks
constexpr auto MEDIUM_VIOLET_RED = rgb(0xC71585);
constexpr auto DEEP_PINK = rgb(0xFF1493);
constexpr auto PALE_VIOLET_RED = rgb(0xDB7093);
constexpr auto HOT_PINK = rgb(0xFF69B4);
constexpr auto LIGHT_PINK = rgb(0xFFB6C1);
constexpr auto PINK = rgb(0xFFC0CB);
// Reds
constexpr auto DARK_RED = rgb(0x8B0000);
constexpr auto RED = rgb(0xFF0000);
constexpr auto FIRE_BRICK = rgb(0xB22222);
constexpr auto CRIMSON = rgb(0xDC143C);
constexpr auto INDIAN_RED = rgb(0xCD5C5C);
constexpr auto LIGHT_CORAL = rgb(0xF08080);
constexpr auto SALMON = rgb(0xFA8072);
constexpr auto DARK_SALMON = rgb(0xE9967A);
constexpr auto LIGHT_SALMON = rgb(0xFFA07A);
// Oranges
constexpr auto ORANGE_RED = rgb(0xFF4500);
constexpr auto TOMATO = rgb(0xFF9347);
constexpr auto DARK_ORANGE = rgb(0xFF8C00);
constexpr auto CORAL = rgb(0xFF7F50);
constexpr auto ORANGE = rgb(0xFFA500);
// Yellows
constexpr auto DARK_KHAKI = rgb(0xBDB76B);
constexpr auto GOLD = rgb(0xFFD700);
constexpr auto KHAKI = rgb(0xF0E68C);
constexpr auto PEACH_PUFF = rgb(0xFFDAB9);
constexpr auto YELLOW = rgb(0xFFFF00);
constexpr auto PALE_GOLDENROD = rgb(0xEEE8AA);
constexpr auto MOCCASIN = rgb(0xFFE4B5);
constexpr auto PAPAYA_WHIP = rgb(0xFFEFD5);
constexpr auto LIGHT_GOLDENROD_YELLOW = rgb(0xFAFAD2);
constexpr auto LEMON_CHIFFON = rgb(0xFFFACD);
constexpr auto LIGHT_YELLOW = rgb(0xFFFFE0);
// Browns
constexpr auto MAROON = rgb(0x800000);
constexpr auto BROWN = rgb(0xA52A2A);
constexpr auto SADDLE_BROWN = rgb(0x8B4513);
constexpr auto SIENNA = rgb(0xA0522D);
constexpr auto CHOCOLATE = rgb(0xD2691E);
constexpr auto DARK_GOLDENROD = rgb(0xB8860B);
constexpr auto PERU = rgb(0xCD853F);
constexpr auto ROSY_BROWN = rgb(0xBC8F8F);
constexpr auto GOLDENROD = rgb(0xDAA520);
constexpr auto SANDY_BROWN = rgb(0xF4A460);
constexpr auto TAN = rgb(0xD2B48C);
constexpr auto BURLYWOOD = rgb(0xDEB887);
constexpr auto WHEAT = rgb(0xF5DEB3);
constexpr auto NAVAJO_WHITE = rgb(0xFFDEAD);
constexpr auto BISQUE = rgb(0xFFEAC4);
constexpr auto BLANCHED_ALMOND = rgb(0xFFEBCD);
constexpr auto CORNSILK = rgb(0xFFF8DC);
// Greens
constexpr auto DARK_GREEN = rgb(0x006400);
constexpr auto GREEN = rgb(0x008000);
constexpr auto DARK_OLIVE_GREEN = rgb(0x556B2F);
constexpr auto FOREST_GREEN = rgb(0x228B22);
constexpr auto SEA_GREEN = rgb(0x2E8B57);
constexpr auto OLIVE = rgb(0x808000);
constexpr auto OLIVE_DRAB = rgb(0x6B8E23);
constexpr auto MEDIUM_SEA_GREEN = rgb(0x3CB371);
constexpr auto LIME_GREEN = rgb(0x32CD32);
constexpr auto LIME = rgb(0x00FF00);
constexpr auto SPRING_GREEN = rgb(0x00FF7F);
constexpr auto MEDIUM_SPRING_GREEN = rgb(0x00FA9A);
constexpr auto DARK_SEA_GREEN = rgb(0x8FBC8F);
constexpr auto MEDIUM_AQUAMARINE = rgb(0x66CDAA);
constexpr auto YELLOW_GREEN = rgb(0x9ACD32);
constexpr auto LAWN_GREEN = rgb(0x7FFF00);
constexpr auto CHARTREUSE = rgb(0x7FFF00);
constexpr auto LIGHT_GREEN = rgb(0x90EE90);
constexpr auto GREEN_YELLOW = rgb(0xADFF2F);
constexpr auto PALE_GREEN = rgb(0x98FB98);
// Cyans
// TODO finish writing out the cyan list
constexpr auto CYAN = rgb(0xFFFF);
// Blues
// TODO finish writing out the blue list
constexpr auto MIDNIGHT_BLUE = rgb(0x191970);
/// Purples, Violets, and Magentas
// TODO finish writing out the purple list
constexpr auto FUCHSIA = rgb(0xFF00FF);
constexpr auto MAGENTA = FUCHSIA;
// Whites
//TODO finish writing out the white list
constexpr auto WHITE = rgb(0xFFFFFF);
// Grays and Blacks
constexpr auto BLACK = rgb(0x000000);
constexpr auto DARK_SLATE_GRAY = rgb(0x2F4F4F);
constexpr auto DIM_GRAY = rgb(0x696969);
constexpr auto SLATE_GRAY = rgb(0x708090);
constexpr auto GRAY = rgb(0x808080);
constexpr auto LIGHT_SLATE_GRAY = rgb(0x778899);
constexpr auto DARK_GRAY = rgb(0xA9A9A9);
constexpr auto SILVER = rgb(0xC0C0C0);
constexpr auto LIGHT_GRAY = rgb(0xD3D3D3);
constexpr auto GAINSBORO = rgb(0xDCDCDC);
}
enum class PathType {
MOVE,
PATH,
BAZIER2,
BAZIER3,
COLOUR,
CLOSE
};
struct Path2D {
inline explicit Path2D(math::vec2 start) : m_points(), m_types() {
moveTo(start);
}
inline void moveTo(math::vec2 pos) {
m_points.push_back(pos);
m_types.push_back(PathType::MOVE);
}
inline void pathTo(math::vec2 pos) {
m_points.push_back(pos);
m_types.push_back(PathType::PATH);
}
void bezierTo(math::vec2 cp1, math::vec2 pos);
void bezierTo(math::vec2 cp1, math::vec2 cp2, math::vec2 pos);
void arc(math::vec2 center, float radius, RadianAngle startAngle, RadianAngle endAngle, bool ccw);
void colour(math::vec3 colour) {
m_colours.push_back(colour);
m_types.push_back(PathType::COLOUR);
}
void close() {
pathTo(m_points[0]);
m_types.push_back(PathType::CLOSE);
}
std::vector<math::vec2> m_points;
std::vector<PathType> m_types;
std::vector<math::vec3> m_colours;
};
inline Path2D make_rect(math::vec2 center, math::vec2 radius, math::vec3 colour = {1.0f, 1.0f, 1.0f}) {
fggl::gfx::Path2D tileGfx(center);
tileGfx.colour(colour);
tileGfx.moveTo(center - radius);
tileGfx.pathTo({center.x + radius.x, center.y - radius.y});
tileGfx.pathTo(center + radius);
tileGfx.pathTo({center.x - radius.x, center.y + radius.y});
tileGfx.close();
return tileGfx;
}
struct ShapeOpts {
float angleOffset = 0.0F;
bool sinFirst = true;
};
inline Path2D make_shape(math::vec2 center, float radius, int sides, math::vec3 colour = colours::WHITE, ShapeOpts opts = {}) {
float angle = ((math::PI * 2.0F) / sides);
fggl::gfx::Path2D tileGfx(center);
tileGfx.colour(colour);
for (int i=0; i < sides; ++i) {
math::vec2 pos (
(float)(cosf(i * angle + opts.angleOffset) * radius),
(float)(sinf(i * angle + opts.angleOffset) * radius)
);
pos += center;
if ( i == 0 ) {
tileGfx.moveTo( pos );
} else {
tileGfx.pathTo( pos );
}
}
tileGfx.close();
return tileGfx;
}
inline Path2D make_arc(math::vec2 center, float radius, float start, float end, math::vec3 colour = colours::WHITE, int slices = 25) {
const float angle = (M_PI * 2.0) / slices;
fggl::gfx::Path2D tileGfx(center);
tileGfx.colour(colour);
tileGfx.moveTo(center);
for (float totalAngle = start; totalAngle < end; totalAngle += angle) { // NOLINT(cert-flp30-c)
float xPos = (float)(sinf(totalAngle) * radius) + center.x;
float yPos = (float)(cosf(totalAngle) * radius) + center.y;
tileGfx.pathTo({xPos, yPos});
if ( (totalAngle + angle) > end) {
break;
}
}
{
float xPos = (float) (sinf(end) * radius) + center.x;
float yPos = (float) (cosf(end) * radius) + center.y;
tileGfx.pathTo( {xPos, yPos} );
}
tileGfx.close();
return tileGfx;
}
enum class PaintType {
FILL,
STROKE
};
struct PaintCmd {
PaintType type;
Path2D path;
};
struct TextCmd {
const std::string text;
const math::vec2 pos;
const math::vec3 colour;
};
class Paint {
public:
Paint() = default;
Paint(Paint &paint) = delete;
inline void fill(Path2D &path) {
m_cmds.push_back({PaintType::FILL, path});
}
void stroke(Path2D &path) {
m_cmds.push_back({PaintType::STROKE, path});
}
void text(const std::string &text, const math::vec2 &pos, const math::vec3f colour = fggl::gfx::colours::BLACK) {
m_text.push_back({text, pos, colour});
}
const std::vector<PaintCmd> &cmds() const {
return m_cmds;
}
const std::vector<TextCmd> &textCmds() const {
return m_text;
}
private:
std::vector<PaintCmd> m_cmds;
std::vector<TextCmd> m_text;
};
}
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 03/09/22.
//
#ifndef FGGL_GFX_PALLETS_HPP
#define FGGL_GFX_PALLETS_HPP
#include "fggl/gfx/paint.hpp"
namespace fggl::gfx::pallets {
// VGA pallet
namespace vga {
constexpr math::vec3 WHITE{1.0F, 1.0F, 1.0F};
constexpr math::vec3 SILVER{0.75F, 0.75F, 0.75F};
constexpr math::vec3 GRAY{0.5F, 0.5F, 0.5F};
constexpr math::vec3 BLACK{0.0F, 0.0F, 0.0F};
constexpr math::vec3 RED{1.0F, 0.0F, 0.0F};
constexpr math::vec3 MAROON{0.5F, 0.0F, 0.0F};
constexpr math::vec3 YELLOW{1.0F, 1.0F, 0.0F};
constexpr math::vec3 OLIVE{0.5F, 0.5F, 0.0F};
constexpr math::vec3 LIME{0.0F, 1.0F, 0.0F};
constexpr math::vec3 GREEN{0.0F, 0.5F, 0.0F};
constexpr math::vec3 AQUA{0.0F, 1.0F, 1.0F};
constexpr math::vec3 TEAL{0.0F, 0.5F, 0.5F};
constexpr math::vec3 BLUE{0.0F, 0.0F, 1.0F};
constexpr math::vec3 NAVY{0.0F, 0.0F, 0.5F};
constexpr math::vec3 FUCHSIA{1.0F, 0.0F, 1.0F};
constexpr math::vec3 PURPLE{0.5F, 0.0F, 0.5F};
}
// Tango Free Desktop Pallet
namespace tango {
constexpr auto BUTTER_0 = rgb(0xFCE94F);
constexpr auto BUTTER_1 = rgb(0xEDD400);
constexpr auto BUTTER_2 = rgb(0xC4A000);
constexpr auto ORANGE_0 = rgb(0xFCAF3E);
constexpr auto ORANGE_1 = rgb(0xF57900);
constexpr auto ORANGE_2 = rgb(0xCE5C00);
constexpr auto CHOCOLATE_0 = rgb(0xE9B96E);
constexpr auto CHOCOLATE_1 = rgb(0xC17D11);
constexpr auto CHOCOLATE_2 = rgb(0x8F5902);
constexpr auto CHAMELEON_0 = rgb(0x8AE234);
constexpr auto CHAMELEON_1 = rgb(0x73D216);
constexpr auto CHAMELEON_2 = rgb(0x4E9a06);
constexpr auto SKY_BLUE_0 = rgb(0x729FCF);
constexpr auto SKY_BLUE_1 = rgb(0x3456A4);
constexpr auto SKY_BLUE_2 = rgb(0x204A87);
constexpr auto PLUM_0 = rgb(0xAD7FA8);
constexpr auto PLUM_1 = rgb(0x75507B);
constexpr auto PLUM_2 = rgb(0x5C3566);
constexpr auto SCARLET_RED_0 = rgb(0xEF2929);
constexpr auto SCARLET_RED_1 = rgb(0xCC0000);
constexpr auto SCARLET_RED_2 = rgb(0xA40000);
constexpr auto ALUMINIUM_0 = rgb(0xEEEEEC);
constexpr auto ALUMINIUM_1 = rgb(0xD3D7CF);
constexpr auto ALUMINIUM_2 = rgb(0xBABDB6);
constexpr auto ALUMINIUM_3 = rgb(0x888a85);
constexpr auto ALUMINIUM_4 = rgb(0x555753);
constexpr auto ALUMINIUM_6 = rgb(0x2e3436);
}
// solarized
namespace solarized {
// backgrounds (dark)
constexpr auto BASE03 = rgb(0x002B36);
constexpr auto BASE02 = rgb(0x073642);
// content tones
constexpr auto BASE01 = rgb(0x586E75);
constexpr auto BASE00 = rgb(0x657B83);
constexpr auto BASE0 = rgb(0x839496);
constexpr auto BASE1 = rgb(0X93A1A1);
// backgrounds (light)
constexpr auto BASE2 = rgb(0xEEE8D5);
constexpr auto BASE3 = rgb(0xFDF6E3);
// accent colours
constexpr auto YELLOW = rgb(0xB58900);
constexpr auto ORANGE = rgb(0xCB4B16);
constexpr auto RED = rgb(0xDC322F);
constexpr auto MAGENTA = rgb(0xD33682);
constexpr auto VIOLET = rgb(0x6C71C4);
constexpr auto BLUE = rgb(0x268bd2);
constexpr auto CYAN = rgb(0x2AA198);
constexpr auto GREEN = rgb(0x859900);
}
} // namespace fggl::gfx::pallets
#endif //FGGL_GFX_PALLETS_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 05/06/22.
//
#ifndef FGGL_GFX_PHONG_HPP
#define FGGL_GFX_PHONG_HPP
#include "fggl/math/types.hpp"
#include "fggl/util/guid.hpp"
namespace fggl::gfx {
struct PhongMaterial {
constexpr static const char *name = "gfx::material";
constexpr static const util::GUID guid = util::make_guid("gfx::material");
math::vec3 emission;
math::vec3 ambient;
math::vec3 diffuse;
math::vec3 specular;
float shininess;
};
constexpr math::vec3 DEFAULT_EMISSION{0.0F, 0.0F, 0.0F};
constexpr math::vec3 DEFAULT_AMBIENT{0.05F, 0.05F, 0.05F};
constexpr math::vec3 DEFAULT_DIFFUSE{0.5F, 0.5F, 0.5F};
constexpr math::vec3 DEFAULT_SPECULAR{0.7F, 0.7F, 0.7F};
//constexpr float DEFAULT_SHININESS = .078125F;
constexpr float DEFAULT_SHININESS = 16.0F;
constexpr PhongMaterial DEFAULT_MATERIAL{
DEFAULT_EMISSION,
DEFAULT_AMBIENT,
DEFAULT_DIFFUSE,
DEFAULT_SPECULAR,
DEFAULT_SHININESS
};
struct Light {
math::vec3 position;
math::vec3 ambient;
math::vec3 specular;
math::vec3 diffuse;
};
struct DirectionalLight : public Light {
constexpr static const char *name = "gfx::phong::directional";
constexpr static const util::GUID guid = util::make_guid(name);
};
struct PointLight : public Light {
constexpr static const char *name = "gfx::phong::point";
constexpr static const util::GUID guid = util::make_guid(name);
float constant = 1.0F;
float linear;
float quadratic;
};
struct Light2 {
constexpr static const char *name = "gfx::light";
constexpr static const util::GUID guid = util::make_guid("gfx::light");
bool enabled;
bool local;
bool spot;
math::vec3 ambient;
math::vec3 colour;
math::vec3 position;
math::vec3 halfVector;
math::vec3 coneDirection;
float spotCosCutoff;
float spotExponent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
} // namespace fggl::gfx
#endif //FGGL_GFX_PHONG_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 27/06/22.
//
#ifndef FGGL_GFX_INTERFACES2_HPP
#define FGGL_GFX_INTERFACES2_HPP
#include "fggl/gfx/interfaces.hpp"
#include "fggl/display/window.hpp"
namespace fggl::gfx {
enum class GraphicsAPI {
OpenGL, Vulkan
};
struct GraphicsDetails {
GraphicsAPI api;
int majorVersion;
int minorVersion;
bool debug;
};
class WindowGraphics {
public:
constexpr const static auto service = modules::make_service("fggl::gfx::WindowGraphics");
WindowGraphics() = default;
virtual ~WindowGraphics() = default;
// no copy
WindowGraphics(const WindowGraphics& ) = delete;
WindowGraphics& operator=(const WindowGraphics&) = delete;
// no move
WindowGraphics(WindowGraphics&&) = delete;
WindowGraphics& operator=(WindowGraphics&&) = delete;
[[nodiscard]]
virtual GraphicsDetails config() const = 0;
[[nodiscard]]
virtual Graphics* create(display::Window &window) = 0;
inline Graphics* createMain(display::Window& window) {
assert( m_graphics == nullptr );
m_graphics = create(window);
return m_graphics;
}
inline void release() {
if ( m_graphics != nullptr ) {
delete m_graphics;
m_graphics = nullptr;
}
}
[[nodiscard]] inline Graphics* get() const {
return m_graphics;
}
private:
Graphics* m_graphics = nullptr;
};
} // namespace fggl::gfx
#endif //FGGL_GFX_INTERFACES2_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_VULKAN_COMMON_HPP
#define FGGL_GFX_VULKAN_COMMON_HPP
#include <vulkan/vulkan.hpp>
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FGGL_GFX_VULKAN_VULKAN_HPP
#define FGGL_GFX_VULKAN_VULKAN_HPP
#include <memory>
#include <fggl/app.hpp>
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_raii.hpp>
namespace fggl::gfx::vkgfx {
constexpr char const *EngineName = "FGGL";
class VulkanGraphics {
private:
vk::raii::Instance m_instance;
std::unique_ptr<vk::raii::SwapchainKHR> m_swapchain;
};
class VulkanContext {
public:
VulkanContext();
VulkanGraphics &createGraphics();
private:
vk::raii::Context m_context;
};
}
#endif
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 19/12/22.
//
#ifndef FGGL_GRID_ACTIONS_H
#define FGGL_GRID_ACTIONS_H
#include <cstdint>
#include <variant>
#include "fggl/grid/hexagon.hpp"
#include "fggl/grid/tokens.hpp"
#include "fggl/util/safety.hpp"
namespace fggl::grid {
template<typename State, typename Target>
class ActionType;
template<typename State, typename Target>
class Action {
public:
virtual void progress(State* state) = 0;
virtual bool isDone() = 0;
};
template<typename State, typename Target>
class InstantAction : public Action<State, Target> {
public:
void progress(State* state) final;
bool isDone() final;
private:
ActionType<State, Target>* m_action;
TokenIdentifer m_actor;
Target m_target;
};
template<typename State, typename Target>
class DurativeAction : public Action<State, Target> {
public:
void progress(State* state) final;
bool isDone() final;
private:
ActionType<State, Target>* m_action;
TokenIdentifer m_actor;
Target m_target;
uint64_t m_completionRound;
};
template<typename State, typename Target>
class ActionType {
public:
virtual bool canApply(const State* state, TokenIdentifer actor, Target target) = 0;
virtual void apply(State* state, TokenIdentifer actor, Target target) = 0;
virtual Action<State, Target> ground(TokenIdentifer actor, Target target) = 0;
};
} // namespace fggl::grid
#endif //FGGL_GRID_ACTIONS_H