Extra2D/include/renderer/rhi/opengl/gl_utils.h

494 lines
12 KiB
C
Raw Normal View History

#pragma once
#include <glad/glad.h>
#include <renderer/rhi/rhi.h>
#include <utils/logger.h>
namespace extra2d {
/**
* @brief OpenGL
*/
#define GL_CHECK(call) \
do { \
call; \
GLenum err = glGetError(); \
if (err != GL_NO_ERROR) { \
E2D_ERROR("OpenGL 错误在 {}: {} ({})", #call, getGLErrorString(err), \
err); \
} \
} while (0)
/**
* @brief OpenGL
* @param error OpenGL
* @return
*/
inline const char *getGLErrorString(GLenum error) {
switch (error) {
case GL_NO_ERROR:
return "GL_NO_ERROR";
case GL_INVALID_ENUM:
return "GL_INVALID_ENUM";
case GL_INVALID_VALUE:
return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION:
return "GL_INVALID_OPERATION";
case GL_STACK_OVERFLOW:
return "GL_STACK_OVERFLOW";
case GL_STACK_UNDERFLOW:
return "GL_STACK_UNDERFLOW";
case GL_OUT_OF_MEMORY:
return "GL_OUT_OF_MEMORY";
case GL_INVALID_FRAMEBUFFER_OPERATION:
return "GL_INVALID_FRAMEBUFFER_OPERATION";
default:
return "Unknown Error";
}
}
/**
* @brief BufferType OpenGL
*/
inline GLenum bufferTypeToGL(BufferType type) {
switch (type) {
case BufferType::Vertex:
return GL_ARRAY_BUFFER;
case BufferType::Index:
return GL_ELEMENT_ARRAY_BUFFER;
case BufferType::Uniform:
return GL_UNIFORM_BUFFER;
case BufferType::Storage:
return GL_SHADER_STORAGE_BUFFER;
case BufferType::Staging:
return GL_ARRAY_BUFFER;
default:
return GL_ARRAY_BUFFER;
}
}
/**
* @brief BufferUsage OpenGL 使
*/
inline GLenum bufferUsageToGL(BufferUsage usage) {
switch (usage) {
case BufferUsage::Static:
return GL_STATIC_DRAW;
case BufferUsage::Dynamic:
return GL_DYNAMIC_DRAW;
case BufferUsage::Stream:
return GL_STREAM_DRAW;
default:
return GL_STATIC_DRAW;
}
}
/**
* @brief TextureFormat OpenGL
*/
inline GLenum textureFormatToGLInternal(TextureFormat format) {
switch (format) {
case TextureFormat::R8:
return GL_R8;
case TextureFormat::RG8:
return GL_RG8;
case TextureFormat::RGB8:
return GL_RGB8;
case TextureFormat::RGBA8:
return GL_RGBA8;
case TextureFormat::RGBA8_SRGB:
return GL_SRGB8_ALPHA8;
case TextureFormat::Depth16:
return GL_DEPTH_COMPONENT16;
case TextureFormat::Depth24:
return GL_DEPTH_COMPONENT24;
case TextureFormat::Depth32F:
return GL_DEPTH_COMPONENT32F;
case TextureFormat::Depth24Stencil8:
return GL_DEPTH24_STENCIL8;
case TextureFormat::Depth32FStencil8:
return GL_DEPTH32F_STENCIL8;
case TextureFormat::BC1:
return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
case TextureFormat::BC3:
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case TextureFormat::BC5:
return 0x8DBD; // GL_COMPRESSED_RG_RGTC2
default:
return GL_RGBA8;
}
}
/**
* @brief TextureFormat OpenGL
*/
inline GLenum textureFormatToGLFormat(TextureFormat format) {
switch (format) {
case TextureFormat::R8:
return GL_RED;
case TextureFormat::RG8:
return GL_RG;
case TextureFormat::RGB8:
return GL_RGB;
case TextureFormat::RGBA8:
case TextureFormat::RGBA8_SRGB:
return GL_RGBA;
case TextureFormat::Depth16:
case TextureFormat::Depth24:
case TextureFormat::Depth32F:
return GL_DEPTH_COMPONENT;
case TextureFormat::Depth24Stencil8:
case TextureFormat::Depth32FStencil8:
return GL_DEPTH_STENCIL;
default:
return GL_RGBA;
}
}
/**
* @brief TextureFormat OpenGL
*/
inline GLenum textureFormatToGLType(TextureFormat format) {
switch (format) {
case TextureFormat::R8:
case TextureFormat::RG8:
case TextureFormat::RGB8:
case TextureFormat::RGBA8:
case TextureFormat::RGBA8_SRGB:
return GL_UNSIGNED_BYTE;
case TextureFormat::Depth16:
return GL_UNSIGNED_SHORT;
case TextureFormat::Depth24:
return GL_UNSIGNED_INT;
case TextureFormat::Depth32F:
return GL_FLOAT;
case TextureFormat::Depth24Stencil8:
return GL_UNSIGNED_INT_24_8;
case TextureFormat::Depth32FStencil8:
return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
default:
return GL_UNSIGNED_BYTE;
}
}
/**
* @brief TextureFilter OpenGL
*/
inline GLenum textureFilterToGLMin(TextureFilter filter) {
switch (filter) {
case TextureFilter::Nearest:
return GL_NEAREST;
case TextureFilter::Linear:
return GL_LINEAR;
case TextureFilter::NearestMipmapNearest:
return GL_NEAREST_MIPMAP_NEAREST;
case TextureFilter::LinearMipmapNearest:
return GL_LINEAR_MIPMAP_NEAREST;
case TextureFilter::NearestMipmapLinear:
return GL_NEAREST_MIPMAP_LINEAR;
case TextureFilter::LinearMipmapLinear:
return GL_LINEAR_MIPMAP_LINEAR;
default:
return GL_LINEAR;
}
}
inline GLenum textureFilterToGLMag(TextureFilter filter) {
// Mag filter doesn't support mipmaps
switch (filter) {
case TextureFilter::Nearest:
case TextureFilter::NearestMipmapNearest:
case TextureFilter::NearestMipmapLinear:
return GL_NEAREST;
case TextureFilter::Linear:
case TextureFilter::LinearMipmapNearest:
case TextureFilter::LinearMipmapLinear:
default:
return GL_LINEAR;
}
}
/**
* @brief TextureWrap OpenGL
*/
inline GLenum textureWrapToGL(TextureWrap wrap) {
switch (wrap) {
case TextureWrap::Repeat:
return GL_REPEAT;
case TextureWrap::ClampToEdge:
return GL_CLAMP_TO_EDGE;
case TextureWrap::ClampToBorder:
return GL_CLAMP_TO_BORDER;
case TextureWrap::MirroredRepeat:
return GL_MIRRORED_REPEAT;
default:
return GL_REPEAT;
}
}
/**
* @brief VertexFormat OpenGL
*/
inline void vertexFormatToGL(VertexFormat format, GLint &components,
GLenum &type, GLboolean &normalized) {
switch (format) {
case VertexFormat::Float1:
components = 1;
type = GL_FLOAT;
normalized = GL_FALSE;
break;
case VertexFormat::Float2:
components = 2;
type = GL_FLOAT;
normalized = GL_FALSE;
break;
case VertexFormat::Float3:
components = 3;
type = GL_FLOAT;
normalized = GL_FALSE;
break;
case VertexFormat::Float4:
components = 4;
type = GL_FLOAT;
normalized = GL_FALSE;
break;
case VertexFormat::Int1:
components = 1;
type = GL_INT;
normalized = GL_FALSE;
break;
case VertexFormat::Int2:
components = 2;
type = GL_INT;
normalized = GL_FALSE;
break;
case VertexFormat::Int3:
components = 3;
type = GL_INT;
normalized = GL_FALSE;
break;
case VertexFormat::Int4:
components = 4;
type = GL_INT;
normalized = GL_FALSE;
break;
case VertexFormat::UInt1:
components = 1;
type = GL_UNSIGNED_INT;
normalized = GL_FALSE;
break;
case VertexFormat::UInt2:
components = 2;
type = GL_UNSIGNED_INT;
normalized = GL_FALSE;
break;
case VertexFormat::UInt3:
components = 3;
type = GL_UNSIGNED_INT;
normalized = GL_FALSE;
break;
case VertexFormat::UInt4:
components = 4;
type = GL_UNSIGNED_INT;
normalized = GL_FALSE;
break;
case VertexFormat::Byte4:
components = 4;
type = GL_BYTE;
normalized = GL_FALSE;
break;
case VertexFormat::Byte4Normalized:
components = 4;
type = GL_BYTE;
normalized = GL_TRUE;
break;
case VertexFormat::UByte4:
components = 4;
type = GL_UNSIGNED_BYTE;
normalized = GL_FALSE;
break;
case VertexFormat::UByte4Normalized:
components = 4;
type = GL_UNSIGNED_BYTE;
normalized = GL_TRUE;
break;
default:
components = 4;
type = GL_FLOAT;
normalized = GL_FALSE;
break;
}
}
/**
* @brief IndexType OpenGL
*/
inline GLenum indexTypeToGL(IndexType type) {
switch (type) {
case IndexType::UInt16:
return GL_UNSIGNED_SHORT;
case IndexType::UInt32:
return GL_UNSIGNED_INT;
default:
return GL_UNSIGNED_SHORT;
}
}
/**
* @brief PrimitiveType OpenGL
*/
inline GLenum primitiveTypeToGL(PrimitiveType type) {
switch (type) {
case PrimitiveType::Points:
return GL_POINTS;
case PrimitiveType::Lines:
return GL_LINES;
case PrimitiveType::LineStrip:
return GL_LINE_STRIP;
case PrimitiveType::Triangles:
return GL_TRIANGLES;
case PrimitiveType::TriangleStrip:
return GL_TRIANGLE_STRIP;
case PrimitiveType::TriangleFan:
return GL_TRIANGLE_FAN;
default:
return GL_TRIANGLES;
}
}
/**
* @brief BlendFactor OpenGL
*/
inline GLenum blendFactorToGL(BlendFactor factor) {
switch (factor) {
case BlendFactor::Zero:
return GL_ZERO;
case BlendFactor::One:
return GL_ONE;
case BlendFactor::SrcColor:
return GL_SRC_COLOR;
case BlendFactor::OneMinusSrcColor:
return GL_ONE_MINUS_SRC_COLOR;
case BlendFactor::DstColor:
return GL_DST_COLOR;
case BlendFactor::OneMinusDstColor:
return GL_ONE_MINUS_DST_COLOR;
case BlendFactor::SrcAlpha:
return GL_SRC_ALPHA;
case BlendFactor::OneMinusSrcAlpha:
return GL_ONE_MINUS_SRC_ALPHA;
case BlendFactor::DstAlpha:
return GL_DST_ALPHA;
case BlendFactor::OneMinusDstAlpha:
return GL_ONE_MINUS_DST_ALPHA;
default:
return GL_ONE;
}
}
/**
* @brief BlendOp OpenGL
*/
inline GLenum blendOpToGL(BlendOp op) {
switch (op) {
case BlendOp::Add:
return GL_FUNC_ADD;
case BlendOp::Subtract:
return GL_FUNC_SUBTRACT;
case BlendOp::ReverseSubtract:
return GL_FUNC_REVERSE_SUBTRACT;
case BlendOp::Min:
return GL_MIN;
case BlendOp::Max:
return GL_MAX;
default:
return GL_FUNC_ADD;
}
}
/**
* @brief CompareFunc OpenGL
*/
inline GLenum compareFuncToGL(CompareFunc func) {
switch (func) {
case CompareFunc::Never:
return GL_NEVER;
case CompareFunc::Less:
return GL_LESS;
case CompareFunc::Equal:
return GL_EQUAL;
case CompareFunc::LessEqual:
return GL_LEQUAL;
case CompareFunc::Greater:
return GL_GREATER;
case CompareFunc::NotEqual:
return GL_NOTEQUAL;
case CompareFunc::GreaterEqual:
return GL_GEQUAL;
case CompareFunc::Always:
return GL_ALWAYS;
default:
return GL_LESS;
}
}
/**
* @brief ShaderType OpenGL
*/
inline GLenum shaderTypeToGL(ShaderType type) {
switch (type) {
case ShaderType::Vertex:
return GL_VERTEX_SHADER;
case ShaderType::Fragment:
return GL_FRAGMENT_SHADER;
case ShaderType::Geometry:
return GL_GEOMETRY_SHADER;
case ShaderType::Compute:
return GL_COMPUTE_SHADER;
default:
return GL_VERTEX_SHADER;
}
}
/**
* @brief VertexFormat
*/
inline uint32_t getVertexFormatSize(VertexFormat format) {
switch (format) {
case VertexFormat::Float1:
return sizeof(float) * 1;
case VertexFormat::Float2:
return sizeof(float) * 2;
case VertexFormat::Float3:
return sizeof(float) * 3;
case VertexFormat::Float4:
return sizeof(float) * 4;
case VertexFormat::Int1:
return sizeof(int32_t) * 1;
case VertexFormat::Int2:
return sizeof(int32_t) * 2;
case VertexFormat::Int3:
return sizeof(int32_t) * 3;
case VertexFormat::Int4:
return sizeof(int32_t) * 4;
case VertexFormat::UInt1:
return sizeof(uint32_t) * 1;
case VertexFormat::UInt2:
return sizeof(uint32_t) * 2;
case VertexFormat::UInt3:
return sizeof(uint32_t) * 3;
case VertexFormat::UInt4:
return sizeof(uint32_t) * 4;
case VertexFormat::Byte4:
case VertexFormat::Byte4Normalized:
return sizeof(int8_t) * 4;
case VertexFormat::UByte4:
case VertexFormat::UByte4Normalized:
return sizeof(uint8_t) * 4;
default:
return sizeof(float) * 4;
}
}
} // namespace extra2d