blob: 601b4921f48d5d2779bdd7ac8ca1ca2f3d6d6f7c [file] [log] [blame]
/*
* Copyright 2022 Rive
*/
#pragma once
#include "rive/pls/gl/gles3.hpp"
#include "rive/math/aabb.hpp"
#include <cstddef>
#include <utility>
namespace glutils
{
void CompileAndAttachShader(GLuint program, GLenum type, const char* source, const GLCapabilities&);
void CompileAndAttachShader(GLuint program,
GLenum type,
const char* defines[],
size_t numDefines,
const char* sources[],
size_t numSources,
const GLCapabilities&);
[[nodiscard]] GLuint CompileShader(GLuint type, const char* source, const GLCapabilities&);
[[nodiscard]] GLuint CompileShader(GLuint type,
const char* defines[],
size_t numDefines,
const char* sources[],
size_t numSources,
const GLCapabilities&);
[[nodiscard]] GLuint CompileRawGLSL(GLuint shaderType, const char* rawGLSL);
void LinkProgram(GLuint program);
class GLObject
{
public:
GLObject() = default;
GLObject(GLObject&& rhs) : m_id(std::exchange(rhs.m_id, 0)) {}
GLObject(const GLObject&) = delete;
GLObject& operator=(const GLObject&) = delete;
operator GLuint() const { return m_id; }
protected:
explicit GLObject(GLuint adoptedID) : m_id(adoptedID) {}
GLuint m_id = 0;
};
class Buffer : public GLObject
{
public:
Buffer() { glGenBuffers(1, &m_id); }
~Buffer() { glDeleteBuffers(1, &m_id); }
};
class Texture : public GLObject
{
public:
Texture() { glGenTextures(1, &m_id); }
Texture(Texture&& rhs) : GLObject(std::move(rhs)) {}
Texture& operator=(Texture&& rhs)
{
reset(std::exchange(rhs.m_id, 0));
return *this;
}
~Texture() { reset(0); }
static Texture Zero() { return Texture(0); }
private:
explicit Texture(GLuint adoptedID) : GLObject(adoptedID) {}
void reset(GLuint adoptedID)
{
if (m_id != 0)
{
glDeleteTextures(1, &m_id);
}
m_id = adoptedID;
}
};
class Framebuffer : public GLObject
{
public:
Framebuffer() { glGenFramebuffers(1, &m_id); }
Framebuffer(Framebuffer&& rhs) : GLObject(std::move(rhs)) {}
Framebuffer& operator=(Framebuffer&& rhs)
{
reset(std::exchange(rhs.m_id, 0));
return *this;
}
~Framebuffer() { reset(0); }
static Framebuffer Zero() { return Framebuffer(0); }
private:
explicit Framebuffer(GLuint adoptedID) : GLObject(adoptedID) {}
void reset(GLuint adoptedID)
{
if (m_id != 0)
{
glDeleteFramebuffers(1, &m_id);
}
m_id = adoptedID;
}
};
class Renderbuffer : public GLObject
{
public:
Renderbuffer() { glGenRenderbuffers(1, &m_id); }
Renderbuffer(Renderbuffer&& rhs) : GLObject(std::move(rhs)) {}
Renderbuffer& operator=(Renderbuffer&& rhs)
{
reset(std::exchange(rhs.m_id, 0));
return *this;
}
~Renderbuffer() { reset(0); }
static Renderbuffer Zero() { return Renderbuffer(0); }
private:
explicit Renderbuffer(GLuint adoptedID) : GLObject(adoptedID) {}
void reset(GLuint adoptedID)
{
if (m_id != 0)
{
glDeleteRenderbuffers(1, &m_id);
}
m_id = adoptedID;
}
};
class VAO : public GLObject
{
public:
VAO() { glGenVertexArrays(1, &m_id); }
~VAO() { glDeleteVertexArrays(1, &m_id); }
};
class Program : public GLObject
{
public:
Program() : GLObject(glCreateProgram()) {}
Program& operator=(Program&& rhs)
{
reset(std::exchange(rhs.m_id, 0));
m_vertexShaderID = std::exchange(rhs.m_vertexShaderID, 0);
m_fragmentShaderID = std::exchange(rhs.m_fragmentShaderID, 0);
return *this;
}
~Program() { reset(0); }
void compileAndAttachShader(GLenum type, const char* source, const GLCapabilities& capabilities)
{
compileAndAttachShader(type, nullptr, 0, &source, 1, capabilities);
}
void compileAndAttachShader(GLenum type,
const char* defines[],
size_t numDefines,
const char* sources[],
size_t numSources,
const GLCapabilities&);
void link() { LinkProgram(m_id); }
static Program Zero() { return Program(0); }
private:
explicit Program(GLuint adoptedID) : GLObject(adoptedID) {}
void reset(GLuint adoptedProgramID);
GLuint m_vertexShaderID = 0;
GLuint m_fragmentShaderID = 0;
};
void SetTexture2DSamplingParams(GLenum minFilter, GLenum magFilter);
void BlitFramebuffer(rive::IAABB bounds,
uint32_t renderTargetHeight,
GLbitfield mask = GL_COLOR_BUFFER_BIT);
} // namespace glutils