Lots of stuff, ending with Window restruct

This commit is contained in:
NaifBanana
2026-10-11 13:32:47 -05:00
parent ab56a2cc95
commit f49650744a
12 changed files with 412 additions and 40 deletions
@@ -74,12 +74,12 @@ class Buffer : public OpenGLObject {
if (!_id) {
OPENGL_CALL(glGenBuffers(1, &_id));
}
bind();
this->bind();
return _id;
}
virtual void remove() override {
if (_id) {
unbind();
this->unbind();
OPENGL_CALL(glDeleteBuffers(1, &_id));
_id = 0;
}
@@ -160,6 +160,18 @@ class ArrayBuffer : public Buffer {
}
};
class UniformBuffer : public Buffer {
protected:
GLuint _index;
public:
UniformBuffer();
void bind() const override;
GLuint bufferIndex() const;
GLuint bufferIndex(GLuint);
};
class ElementBuffer : protected Buffer {
protected:
GLenum _glslType;
+16 -7
View File
@@ -158,6 +158,8 @@ class Image<Pixel<T, Channels...>> {
using Codes = ImageError::Codes;
bool _data_managed;
T* _data;
Image(unsigned int x, unsigned int y, T* data, bool managed)
: width(x), height(y), _data(data), _data_managed(managed) {}
void clear() {
if (_data_managed) {
delete[] _data;
@@ -171,19 +173,21 @@ class Image<Pixel<T, Channels...>> {
static constexpr size_t NumberChannels = sizeof...(Channels);
const unsigned int width;
const unsigned int height;
static Image&& CreateImageStorage(
static Image CreateImageStorage(
unsigned int width,
unsigned int height,
T* data=nullptr
) {
unsigned int data_size = NumberChannels*width*height*sizeof(T);
T* data_ptr = new T[data_size];
auto& ret = Image(width, height, data_ptr);
Image ret(width, height, data_ptr, true);
if (data) {
std::memcpy(data_ptr, data, data_size);
} else {
std::memset(data_ptr, 0x00, data_size);
}
ret._data_managed = true;
return std::move(ret);
return ret;
}
Image(unsigned int x, unsigned int y, T* data=nullptr)
: width(x), height(y), _data(data), _data_managed(false) {}
@@ -201,8 +205,13 @@ class Image<Pixel<T, Channels...>> {
}
const Error<> sizeErr = sizeCompare(cpy);
if (sizeErr.code!=1) { THROW(sizeErr); }
_data = cpy._data;
return this;
if (!cpy._data_managed) {
_data = cpy._data;
_data_managed = false;
} else {
*this = cpy.copy();
}
return *this;
}
Image& operator=(Image&& mv) {
if (_data_managed) {
@@ -213,7 +222,7 @@ class Image<Pixel<T, Channels...>> {
_data = mv._data;
_data_managed = mv._data_managed;
mv._data_managed = false;
return this;
return *this;
}
virtual ~Image() {
@@ -221,7 +230,7 @@ class Image<Pixel<T, Channels...>> {
}
const T* data() const { return _data; }
Image<PixelType>&& copy() const {
Image<PixelType> copy() const {
return CreateImageStorage(width, height, _data);
}
PixelReference<PixelType> at(unsigned int x, unsigned int y) {
@@ -32,6 +32,7 @@ class OpenGLError : public Error<OpenGLError> {
static const std::string type;
static const ErrorCodeMap ErrorMessages;
static OpenGLError status();
static OpenGLError status(const std::string& note);
};
class OpenGLObjectError : public Error<OpenGLObjectError> {
@@ -41,7 +42,7 @@ class OpenGLObjectError : public Error<OpenGLObjectError> {
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, HANGING_OBJECT, INVALID_OBJECT
UNDEFINED, HANGING_OBJECT, INVALID_OBJECT, INVALID_CONTEXT
};
static const std::string type;
@@ -60,13 +61,16 @@ class OpenGLObject {
virtual void unbind() const = 0;
GLuint id() const { return _id; }
protected:
using Codes = OpenGLObjectError::Codes;
OpenGLObject() = default;
OpenGLObject();
void checkObjectContextValidity();
virtual GLuint declare() = 0;
virtual void remove() = 0;
const GLFWwindow* const _arena;
GLuint _id = 0;
};
@@ -80,21 +84,21 @@ class OpenGLObject {
unsigned int line,
Fn fn
) {
auto check_ = [file, line]() {
auto check_ = [file, line](const std::string& note="") {
const auto no_err = nb::OpenGLError::NO_ERROR;
auto stat = nb::OpenGLError::status();
auto stat = nb::OpenGLError::status(note);
if (stat.code != no_err) {
THROW_W_CODE_LOC(file, line, stat);
}
};
if constexpr(std::is_same_v<std::invoke_result_t<Fn>, void>) {
check_();
check_("Pre-call state");
fn();
check_();
check_("Post-call state");
} else {
check_();
check_("Pre-call state");
auto ret = fn();
check_();
check_("Post-call state");
return ret;
}
}
@@ -9,6 +9,7 @@
#include <NBCore/Errors.hpp>
#include <NBCore/Utils.hpp>
#include <NBGraphics/Buffers.hpp>
#include <NBGraphics/OGLObjects.hpp>
namespace nb {
@@ -112,17 +113,22 @@ class Program : public OpenGLObject {
Program& operator=(Program&&) = delete;
operator bool();
~Program() { remove(); }
virtual void bind() const override {
void bind() const override {
OPENGL_CALL(glUseProgram(_id));
}
virtual void unbind() const override { /* TODO: Some warning of some kind perhaps*/ }
void unbind() const override { /* TODO: Some warning of some kind perhaps*/ }
GLint status(GLenum) const;
std::string log() const;
void setUniform(const std::string& blockname, std::shared_ptr<UniformBuffer>);
void setUniformBinding(const std::string& blockname, GLuint index);
GLuint getUniformBinding(const std::string& blockname) const;
friend Base;
protected:
using Base::_id;
GLint _success;
std::unordered_map<std::string, GLuint> _uniformBindings;
virtual GLuint declare() override {
if (!_id) {
_id = OPENGL_CALL(glCreateProgram());
@@ -24,11 +24,11 @@ class RenderTarget : public OpenGLObject {
using Base = OpenGLObject;
using Base::_id;
RenderTarget(GLenum target) : Target(target) {}
RenderTarget(RenderTarget&& rhs)
: Target(rhs.Target), Base(std::move(rhs)) {}
public:
using Base::id;
RenderTarget(RenderTarget&& mv);
RenderTarget& operator=(RenderTarget&& mv);
const GLenum Target;
};
@@ -57,8 +57,10 @@ class Texture : public RenderTarget {
public:
using Base::id;
using Base::Target;
virtual void bind() const override {
Texture(Texture&& mv);
Texture& operator=(Texture&& mv);
void bind() const override {
if (_id) {
OPENGL_CALL(glBindTexture(Target, _id));
} else {
@@ -68,7 +70,7 @@ class Texture : public RenderTarget {
));
}
}
virtual void unbind() const override {
void unbind() const override {
OPENGL_CALL(glBindTexture(Target, 0));
}
@@ -119,13 +121,6 @@ struct OGLPixelFormat;
template<typename T, typename... Channels>
struct OGLPixelFormat<Pixel<T, Channels...>>;
template<>
struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue>> {
static constexpr GLenum glBase = GL_RGB;
static constexpr GLenum glFormat = GL_RGB8UI;
static constexpr GLenum glData = GL_UNSIGNED_BYTE;
};
template<>
struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue, Alpha>> {
static constexpr GLenum glBase = GL_RGBA;
@@ -133,6 +128,27 @@ struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue, Alpha>> {
static constexpr GLenum glData = GL_UNSIGNED_BYTE;
};
template<>
struct OGLPixelFormat<Pixel<float, Red, Green, Blue, Alpha>> {
static constexpr GLenum glBase = GL_RGBA;
static constexpr GLenum glFormat = GL_RGBA32F;
static constexpr GLenum glData = GL_FLOAT;
};
template<>
struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue>> {
static constexpr GLenum glBase = GL_RGB;
static constexpr GLenum glFormat = GL_RGB8UI;
static constexpr GLenum glData = GL_UNSIGNED_BYTE;
};
template<>
struct OGLPixelFormat<Pixel<float, Red, Green, Blue>> {
static constexpr GLenum glBase = GL_RGB;
static constexpr GLenum glFormat = GL_RGB32F;
static constexpr GLenum glData = GL_FLOAT;
};
template<>
struct OGLPixelFormat<Pixel<float, Red, Green>> {
static constexpr GLenum glBase = GL_RG;
@@ -140,6 +156,13 @@ struct OGLPixelFormat<Pixel<float, Red, Green>> {
static constexpr GLenum glData = GL_FLOAT;
};
template<>
struct OGLPixelFormat<Pixel<float, Red>> {
static constexpr GLenum glBase = GL_RED;
static constexpr GLenum glFormat = GL_R32F;
static constexpr GLenum glData = GL_FLOAT;
};
template<typename T>
class Texture2D;
@@ -226,5 +249,19 @@ class Texture1D<Pixel<T, Channels...>> : public Texture {
}
};
template <typename T>
class Texture1DArray;
template <typename... T>
class Texture1DArray<Pixel<T...>> : public Texture {
protected:
public:
using Texture::generateMipmaps;
Texture1DArray() : Texture(GL_TEXTURE_1D_ARRAY) {
}
};
} // namespace nb
#endif // _NB_TEXTURES
@@ -7,7 +7,9 @@
#include <array>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <NBCore/Errors.hpp>
#include <NBCore/Utils.hpp>
@@ -21,7 +23,8 @@ class GLFWError : public Error<GLFWError> {
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, INIT_FAILED, GLFW_INTIALIZED, GLAD_FAILED
UNDEFINED, INIT_FAILED, GLFW_INTIALIZED, GLAD_FAILED,
NOT_MAIN, WINDOW_FAILED
};
static const std::string type;
@@ -84,5 +87,69 @@ protected:
int gladResponse = -1;
};
class OGLObjectArena;
class OGLWindow {
using GLFWHint = std::array<int, 2>;
private:
static inline void CheckForMainThread() {
if (nb::CurrentTID != nb::MainTID) {
THROW(GLFWError(GLFWError::Codes::NOT_MAIN));
}
}
protected:
static std::atomic<unsigned int> _count;
static std::atomic<bool> _glfwInitialized;
static thread_local std::shared_ptr<OGLWindow> _currWindow;
static thread_local GLFWwindow* _currArena;
std::string _title;
GLFWwindow* _window_ptr;
GLFWwindow* _arena;
static void SetHintInteger(const std::array<int, 2>&);
static void SetHintString(const std::tuple<int, std::string>&);
OGLWindow(
unsigned int,
unsigned int,
const std::string&,
const std::vector<std::array<int, 2>>&,
const std::vector<std::tuple<int, std::string>>&
);
public:
static inline bool IsGLFWInitialized() { return _glfwInitialized; }
static bool InitGLFW(const std::vector<GLFWHint>& hints={});
static bool TerminateGLFW();
static inline std::shared_ptr<OGLWindow> getCurrentWindow() { return _currWindow; }
static inline const GLFWwindow* getCurrentObjectArena() { return _currArena; }
static std::shared_ptr<OGLWindow> MakeCurrent(const std::shared_ptr<OGLWindow>&);
static inline std::shared_ptr<OGLWindow> DropCurrent() { return MakeCurrent(nullptr); }
static std::shared_ptr<OGLWindow> CreateWindow(
unsigned int x,
unsigned int y,
const std::string& title,
const std::vector<std::array<int, 2>>& integerHints={},
const std::vector<std::tuple<int, std::string>>& stringHints={}
);
OGLWindow(OGLWindow&&) = delete;
OGLWindow(const OGLWindow&) = delete;
~OGLWindow();
inline bool operator==(const OGLWindow& rhs) { return _window_ptr==rhs._window_ptr; }
int getWindowAttribute(int) const;
inline GLFWwindow* getWindowPtr() const { return _window_ptr; }
inline std::string getTitle() const { return _title; }
std::array<int, 2> getSize() const;
std::shared_ptr<OGLWindow> makeSharedContext();
void makeCurrent() const;
void setSize(unsigned int x, unsigned int y);
void setTitle(const std::string&);
};
};
#endif