[glutils] Move glutils to deps
This commit is contained in:
@ -2,8 +2,5 @@ include_directories(".")
|
||||
|
||||
set(OLYMPIC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/olympic")
|
||||
|
||||
if(TURBINE_BUILD_TYPE STREQUAL "Native")
|
||||
add_subdirectory(glutils)
|
||||
endif()
|
||||
add_subdirectory(nostalgia)
|
||||
add_subdirectory(olympic)
|
||||
|
@ -1,25 +0,0 @@
|
||||
add_library(
|
||||
GlUtils
|
||||
glutils.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
GlUtils PUBLIC
|
||||
OxStd
|
||||
glad
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
glutils.hpp
|
||||
DESTINATION
|
||||
include/glutils
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
GlUtils
|
||||
DESTINATION
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/std/assert.hpp>
|
||||
#include <ox/std/bstring.hpp>
|
||||
#include <ox/std/trace.hpp>
|
||||
|
||||
#include "glutils.hpp"
|
||||
|
||||
namespace glutils {
|
||||
|
||||
void deleteBuffer(GLuint b) noexcept {
|
||||
glDeleteBuffers(1, &b);
|
||||
}
|
||||
|
||||
void deleteFrameBuffer(GLuint b) noexcept {
|
||||
glDeleteFramebuffers(1, &b);
|
||||
}
|
||||
|
||||
void deleteRenderBuffer(GLuint b) noexcept {
|
||||
glDeleteRenderbuffers(1, &b);
|
||||
}
|
||||
|
||||
void deleteTexture(GLuint t) noexcept {
|
||||
glDeleteTextures(1, &t);
|
||||
}
|
||||
|
||||
void deleteVertexArray(GLuint v) noexcept {
|
||||
glDeleteVertexArrays(1, &v);
|
||||
}
|
||||
|
||||
void deleteProgram(GLuint p) noexcept {
|
||||
glDeleteProgram(p);
|
||||
}
|
||||
|
||||
void deleteShader(GLuint s) noexcept {
|
||||
glDeleteShader(s);
|
||||
}
|
||||
|
||||
template struct GLObject<deleteBuffer>;
|
||||
template struct GLObject<deleteFrameBuffer>;
|
||||
template struct GLObject<deleteRenderBuffer>;
|
||||
template struct GLObject<deleteTexture, TextureBase>;
|
||||
template struct GLObject<deleteVertexArray>;
|
||||
template struct GLObject<deleteProgram>;
|
||||
template struct GLObject<deleteShader>;
|
||||
|
||||
const FrameBuffer *FrameBufferBind::s_activeFb = nullptr;
|
||||
|
||||
FrameBufferBind::FrameBufferBind(const FrameBuffer &fb) noexcept: m_restoreFb(s_activeFb) {
|
||||
s_activeFb = &fb;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
glViewport(0, 0, fb.width, fb.height);
|
||||
}
|
||||
|
||||
FrameBufferBind::~FrameBufferBind() noexcept {
|
||||
s_activeFb = m_restoreFb;
|
||||
if (s_activeFb) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, *s_activeFb);
|
||||
glViewport(0, 0, s_activeFb->width, s_activeFb->height);
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void bind(const FrameBuffer &fb) noexcept {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
glViewport(0, 0, fb.width, fb.height);
|
||||
}
|
||||
|
||||
|
||||
static ox::Result<GLShader> buildShader(
|
||||
GLuint shaderType,
|
||||
const GLchar *src,
|
||||
ox::CRStringView shaderName) noexcept {
|
||||
GLShader shader(glCreateShader(shaderType));
|
||||
glShaderSource(shader, 1, &src, nullptr);
|
||||
glCompileShader(shader);
|
||||
GLint status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE) {
|
||||
ox::Vector<char> errMsg(ox::units::KB);
|
||||
glGetShaderInfoLog(shader, static_cast<GLsizei>(errMsg.size()), nullptr, errMsg.data());
|
||||
oxErrorf("shader compile error in {}: {}", shaderName, errMsg.data());
|
||||
return OxError(1, "shader compile error");
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
ox::Result<GLProgram> buildShaderProgram(
|
||||
ox::CStringView const&vert,
|
||||
ox::CStringView const&frag,
|
||||
ox::CStringView const&geo) noexcept {
|
||||
GLProgram prgm(glCreateProgram());
|
||||
oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
|
||||
glAttachShader(prgm, vs);
|
||||
if (geo.c_str() && geo.bytes() != 0) {
|
||||
oxRequire(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
|
||||
glAttachShader(prgm, gs);
|
||||
}
|
||||
oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
|
||||
glAttachShader(prgm, fs);
|
||||
glLinkProgram(prgm);
|
||||
return prgm;
|
||||
}
|
||||
|
||||
GLVertexArray generateVertexArrayObject() noexcept {
|
||||
GLVertexArray vao;
|
||||
glGenVertexArrays(1, &vao.id);
|
||||
return vao;
|
||||
}
|
||||
|
||||
GLBuffer generateBuffer() noexcept {
|
||||
GLBuffer buff;
|
||||
glGenBuffers(1, &buff.id);
|
||||
return buff;
|
||||
}
|
||||
|
||||
FrameBuffer generateFrameBuffer(int width, int height) noexcept {
|
||||
width = ox::max(1, width);
|
||||
height = ox::max(1, height);
|
||||
FrameBuffer fb;
|
||||
fb.width = width;
|
||||
fb.height = height;
|
||||
glGenFramebuffers(1, &fb.fbo.id);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
// color texture
|
||||
glGenTextures(1, &fb.color.id);
|
||||
glBindTexture(GL_TEXTURE_2D, fb.color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
|
||||
// depth texture
|
||||
glGenRenderbuffers(1, &fb.depth.id);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depth);
|
||||
// verify FBO
|
||||
oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
|
||||
// restore primary FB
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
return fb;
|
||||
}
|
||||
|
||||
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
|
||||
if (!fb) {
|
||||
fb = generateFrameBuffer(width, height);
|
||||
return;
|
||||
}
|
||||
width = ox::max(1, width);
|
||||
height = ox::max(1, height);
|
||||
fb.width = width;
|
||||
fb.height = height;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
// color texture
|
||||
glBindTexture(GL_TEXTURE_2D, fb.color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// depth texture
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
// restore primary FB
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept {
|
||||
resizeInitFrameBuffer(fb, sz.width, sz.height);
|
||||
}
|
||||
|
||||
void sendVbo(BufferSet const&bs) noexcept {
|
||||
const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bs.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
void sendEbo(BufferSet const&bs) noexcept {
|
||||
const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size());
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void clearScreen() noexcept {
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/defines.hpp>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <ox/std/bounds.hpp>
|
||||
#include <ox/std/cstringview.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/size.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/vector.hpp>
|
||||
|
||||
namespace glutils {
|
||||
|
||||
struct Empty {
|
||||
virtual ~Empty() noexcept = default;
|
||||
};
|
||||
|
||||
struct TextureBase {
|
||||
|
||||
GLsizei width = 0;
|
||||
GLsizei height = 0;
|
||||
|
||||
constexpr TextureBase() noexcept = default;
|
||||
|
||||
constexpr TextureBase(TextureBase &&tb) noexcept {
|
||||
width = tb.width;
|
||||
height = tb.height;
|
||||
tb.width = 0;
|
||||
tb.height = 0;
|
||||
}
|
||||
|
||||
constexpr TextureBase &operator=(TextureBase &&tb) noexcept {
|
||||
width = tb.width;
|
||||
height = tb.height;
|
||||
tb.width = 0;
|
||||
tb.height = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~TextureBase() noexcept = default;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<auto del, typename Base = Empty>
|
||||
struct GLObject: public Base {
|
||||
|
||||
GLuint id = 0;
|
||||
|
||||
constexpr GLObject() noexcept = default;
|
||||
|
||||
explicit constexpr GLObject(GLuint id) noexcept {
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
constexpr GLObject(GLObject &&o) noexcept: Base(std::move(o)) {
|
||||
id = o.id;
|
||||
o.id = 0;
|
||||
}
|
||||
|
||||
~GLObject() noexcept override {
|
||||
del(id);
|
||||
}
|
||||
|
||||
GLObject &operator=(GLObject &&o) noexcept {
|
||||
if (this != &o) {
|
||||
del(id);
|
||||
Base::operator=(std::move(o));
|
||||
id = o.id;
|
||||
o.id = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr GLuint release() noexcept {
|
||||
auto out = id;
|
||||
id = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
constexpr operator GLuint&() noexcept {
|
||||
return id;
|
||||
}
|
||||
|
||||
constexpr operator const GLuint&() const noexcept {
|
||||
return id;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void deleteBuffer(GLuint b) noexcept;
|
||||
void deleteFrameBuffer(GLuint b) noexcept;
|
||||
void deleteRenderBuffer(GLuint b) noexcept;
|
||||
void deleteTexture(GLuint t) noexcept;
|
||||
void deleteVertexArray(GLuint v) noexcept;
|
||||
void deleteProgram(GLuint p) noexcept;
|
||||
void deleteShader(GLuint s) noexcept;
|
||||
|
||||
extern template struct GLObject<deleteBuffer>;
|
||||
extern template struct GLObject<deleteFrameBuffer>;
|
||||
extern template struct GLObject<deleteRenderBuffer>;
|
||||
extern template struct GLObject<deleteTexture, TextureBase>;
|
||||
extern template struct GLObject<deleteVertexArray>;
|
||||
extern template struct GLObject<deleteProgram>;
|
||||
extern template struct GLObject<deleteShader>;
|
||||
|
||||
using GLBuffer = GLObject<deleteBuffer>;
|
||||
using GLFrameBuffer = GLObject<deleteBuffer>;
|
||||
using GLRenderBuffer = GLObject<deleteRenderBuffer>;
|
||||
using GLShader = GLObject<deleteShader>;
|
||||
using GLProgram = GLObject<deleteProgram>;
|
||||
using GLTexture = GLObject<deleteTexture, TextureBase>;
|
||||
using GLVertexArray = GLObject<deleteVertexArray>;
|
||||
|
||||
/**
|
||||
* FrameBuffer holds everything needed for a usable frame buffer to exist.
|
||||
* It differs from GLFrameBuffer in that GLFrameBuffer only manages the FBO
|
||||
* and not its dependencies.
|
||||
*/
|
||||
struct FrameBuffer {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
GLFrameBuffer fbo;
|
||||
GLTexture color;
|
||||
GLRenderBuffer depth;
|
||||
|
||||
constexpr operator GLuint&() noexcept {
|
||||
return fbo.id;
|
||||
}
|
||||
|
||||
constexpr operator const GLuint&() const noexcept {
|
||||
return fbo.id;
|
||||
}
|
||||
};
|
||||
|
||||
class FrameBufferBind {
|
||||
private:
|
||||
static const FrameBuffer *s_activeFb;
|
||||
const FrameBuffer *m_restoreFb = nullptr;
|
||||
public:
|
||||
explicit FrameBufferBind(const FrameBuffer &fb) noexcept;
|
||||
~FrameBufferBind() noexcept;
|
||||
};
|
||||
|
||||
void bind(const FrameBuffer &fb) noexcept;
|
||||
|
||||
|
||||
ox::Result<GLProgram> buildShaderProgram(ox::CStringView const&vert, ox::CStringView const&frag, ox::CStringView const&geo = "") noexcept;
|
||||
|
||||
glutils::GLVertexArray generateVertexArrayObject() noexcept;
|
||||
|
||||
glutils::GLBuffer generateBuffer() noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
FrameBuffer generateFrameBuffer(int width, int height) noexcept;
|
||||
|
||||
/**
|
||||
* Resizes a FrameBuffer, and creates if it does not already exist.
|
||||
*/
|
||||
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
|
||||
|
||||
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept;
|
||||
|
||||
struct BufferSet {
|
||||
glutils::GLVertexArray vao;
|
||||
glutils::GLBuffer vbo;
|
||||
glutils::GLBuffer ebo;
|
||||
glutils::GLTexture tex;
|
||||
ox::Vector<float> vertices;
|
||||
ox::Vector<GLuint> elements;
|
||||
};
|
||||
|
||||
void sendVbo(BufferSet const&bs) noexcept;
|
||||
|
||||
void sendEbo(BufferSet const&bs) noexcept;
|
||||
|
||||
void clearScreen() noexcept;
|
||||
|
||||
}
|
Reference in New Issue
Block a user