308 lines
13 KiB
C++
308 lines
13 KiB
C++
#pragma once
|
|
|
|
#include <renderer/rhi/rhi.h>
|
|
#include <glad/glad.h>
|
|
#include <utils/logger.h>
|
|
|
|
namespace extra2d {
|
|
|
|
/**
|
|
* @brief OpenGL 错误检查宏
|
|
*/
|
|
#define GL_CHECK(call) do { \
|
|
call; \
|
|
GLenum err = glGetError(); \
|
|
if (err != GL_NO_ERROR) { \
|
|
E2D_LOG_ERROR("OpenGL error in {}: {} ({})", #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
|