#include "pch.h"

#include "RenderSystem.h"
#include "Texture.h"

#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>

#include <cassert>
#include <iostream>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <stdexcept>
#include <vector>

// ================== 静态成员变量初始化 ==================
std::thread::id RenderSystem::s_RenderThreadId;
std::atomic<bool> RenderSystem::s_IsInInit = false;
std::queue<std::function<void()>> RenderSystem::s_RenderQueue;
std::mutex RenderSystem::s_RenderQueueMutex;
std::atomic<bool> RenderSystem::s_IsReplayingQueue = false;
std::stack<RenderSystem::RenderState> RenderSystem::s_StateStack;
int RenderSystem::s_ViewportWidth = 800;
int RenderSystem::s_ViewportHeight = 600;
glm::vec4 RenderSystem::s_ClearColorValue = { 0.0f, 0.0f, 0.0f, 1.0f };
std::shared_ptr<spdlog::logger> RenderSystem::s_Logger;

// ================== 日志系统管理 ==================
void RenderSystem::InitializeLogging() {
    std::vector<spdlog::sink_ptr> sinks;

    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] %v");
    sinks.push_back(console_sink);

    try {
        auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/Vivid2D.log", true);
        file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread %t] %v");
        sinks.push_back(file_sink);
    }
    catch (const spdlog::spdlog_ex& ex) {
        std::cerr << "Log file creation failed: " << ex.what() << std::endl;
    }

    s_Logger = std::make_shared<spdlog::logger>("RenderSystem", begin(sinks), end(sinks));
    spdlog::register_logger(s_Logger);
    s_Logger->set_level(spdlog::level::trace);
    s_Logger->flush_on(spdlog::level::trace);

    s_Logger->info("Logging system initialized.");
}

void RenderSystem::ShutdownLogging() {
    s_Logger->info("Logging system shutting down.");
    s_Logger.reset();
    spdlog::shutdown();
}

// ================== 初始化与线程管理 ==================
void RenderSystem::loadGLFunctions(GLADloader loader) {
    if (!gladLoadGLLoader((GLADloadproc)loader)) {
        s_Logger->critical("Failed to initialize GLAD within RenderSystem DLL!");
        // 抛出异常或断言，以阻止程序继续执行
        throw std::runtime_error("Failed to load OpenGL functions in DLL.");
    }
    s_Logger->info("Successfully loaded OpenGL functions in RenderSystem DLL.");
}
void RenderSystem::initRenderThread() {
    if (s_RenderThreadId == std::thread::id()) {
        s_RenderThreadId = std::this_thread::get_id();
        s_Logger->info("Render thread initialized on thread ID: {}", std::hash<std::thread::id>{}(s_RenderThreadId));
    }
    else if (s_RenderThreadId != std::this_thread::get_id()) {
        s_Logger->critical("Render thread already initialized by another thread!");
        throw std::runtime_error("Render thread already initialized by another thread");
    }
}
void RenderSystem::beginInitialization() { s_IsInInit = true; }
void RenderSystem::finishInitialization() {
    s_IsInInit = false;
}
bool RenderSystem::isOnRenderThread() { return std::this_thread::get_id() == s_RenderThreadId; }
bool RenderSystem::isInInitPhase() { return s_IsInInit; }
void RenderSystem::assertOnRenderThread() {
    if (s_RenderThreadId == std::thread::id()) {
        if (!s_IsInInit && !isOnRenderThread()) {
            throw std::runtime_error("RenderSystem called from wrong thread!");
        }
    }
    else if (!isOnRenderThread()) {
        throw std::runtime_error("RenderSystem called from wrong thread!");
    }
}
void RenderSystem::assertOnRenderThreadOrInit() { if (!isInInitPhase() && !isOnRenderThread()) { throw std::runtime_error("RenderSystem called from wrong thread!"); } }

// ================== 渲染命令队列 ==================
void RenderSystem::recordRenderCall(std::function<void()>&& renderCall) {
    std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
    s_RenderQueue.push(std::move(renderCall));
}
void RenderSystem::replayQueue() {
    s_IsReplayingQueue = true;
    std::queue<std::function<void()>> localQueue;
    {
        std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
        s_RenderQueue.swap(localQueue);
    }
    while (!localQueue.empty()) {
        auto& call = localQueue.front();
        if (call) { call(); }
        localQueue.pop();
    }
    s_IsReplayingQueue = false;
}

// ================== OpenGL 状态管理封装 ==================
#define RENDER_SYSTEM_QUEUE_CALL(FunctionName, ...) \
    if (!isOnRenderThread()) { \
        recordRenderCall([=] { FunctionName(__VA_ARGS__); }); \
    } else { \
        FunctionName(__VA_ARGS__); \
    }

#define RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(FunctionName) \
    if (!isOnRenderThread()) { \
        recordRenderCall([=] { FunctionName(); }); \
    } else { \
        FunctionName(); \
    }

void RenderSystem::enable(GLenum capability) { RENDER_SYSTEM_QUEUE_CALL(_enable, capability); }
void RenderSystem::_enable(GLenum c) { assertOnRenderThread(); glEnable(c); }

void RenderSystem::disable(GLenum capability) { RENDER_SYSTEM_QUEUE_CALL(_disable, capability); }
void RenderSystem::_disable(GLenum c) { assertOnRenderThread(); glDisable(c); }

void RenderSystem::pushState() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_pushState); }
void RenderSystem::_pushState() {
    assertOnRenderThread();
    _checkGLError("before pushState");
    s_StateStack.push(RenderState());
    _checkGLError("after pushState");
}

void RenderSystem::popState() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_popState); }
void RenderSystem::_popState() {
    assertOnRenderThread();
    if (!s_StateStack.empty()) {
        s_StateStack.top().restore();
        s_StateStack.pop();
        _checkGLError("after popState");
    }
    else {
        s_Logger->warn("popState called with empty state stack.");
    }
}
size_t RenderSystem::getStateStackSize() { return s_StateStack.size(); }

void RenderSystem::clearColor(float r, float g, float b, float a) { RENDER_SYSTEM_QUEUE_CALL(_clearColor, r, g, b, a); }
void RenderSystem::_clearColor(float r, float g, float b, float a) {
    assertOnRenderThread();
    glClearColor(r, g, b, a);
    s_ClearColorValue = { r, g, b, a };
}

void RenderSystem::clear(GLbitfield mask) { RENDER_SYSTEM_QUEUE_CALL(_clear, mask); }
void RenderSystem::_clear(GLbitfield m) { assertOnRenderThread(); glClear(m); }

void RenderSystem::viewport(int x, int y, int width, int height) { RENDER_SYSTEM_QUEUE_CALL(_viewport, x, y, width, height); }
void RenderSystem::_viewport(int x, int y, int w, int h) {
    assertOnRenderThread();
    glViewport(x, y, w, h);
    s_ViewportWidth = w;
    s_ViewportHeight = h;
}

// ================== VAO / VBO / EBO 操作 ==================
GLuint RenderSystem::GenVertexArrays() { assertOnRenderThreadOrInit(); GLuint vao = 0; glGenVertexArrays(1, &vao); return vao; }
void RenderSystem::DeleteVertexArrays(GLuint vao) { RENDER_SYSTEM_QUEUE_CALL(_glDeleteVertexArrays, vao); }
void RenderSystem::_glDeleteVertexArrays(GLuint v) { assertOnRenderThreadOrInit(); glDeleteVertexArrays(1, &v); }
void RenderSystem::BindVertexArray(GLuint vao) { RENDER_SYSTEM_QUEUE_CALL(_glBindVertexArray, vao); }
void RenderSystem::_glBindVertexArray(GLuint v) { assertOnRenderThreadOrInit(); glBindVertexArray(v); }
GLuint RenderSystem::GenBuffers() { assertOnRenderThreadOrInit(); GLuint buf; glGenBuffers(1, &buf); return buf; }
void RenderSystem::DeleteBuffers(GLuint buffer) { RENDER_SYSTEM_QUEUE_CALL(_glDeleteBuffers, buffer); }
void RenderSystem::_glDeleteBuffers(GLuint b) { assertOnRenderThreadOrInit(); glDeleteBuffers(1, &b); }
void RenderSystem::BindBuffer(GLenum target, GLuint buffer) { RENDER_SYSTEM_QUEUE_CALL(_glBindBuffer, target, buffer); }
void RenderSystem::_glBindBuffer(GLenum t, GLuint b) { assertOnRenderThreadOrInit(); glBindBuffer(t, b); }
void RenderSystem::BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
    assertOnRenderThreadOrInit();
    glBufferData(target, size, data, usage);
}

// [新增] _glBufferData 的定义
void RenderSystem::_glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
    assertOnRenderThread();
    glBufferData(target, size, data, usage);
}

// ================== Uniform 设置 ==================
void RenderSystem::uniform1i(GLint location, int value) { RENDER_SYSTEM_QUEUE_CALL(_uniform1i, location, value); }
void RenderSystem::_uniform1i(GLint l, int v) { assertOnRenderThread(); glUniform1i(l, v); }
void RenderSystem::uniform1f(GLint location, float value) { RENDER_SYSTEM_QUEUE_CALL(_uniform1f, location, value); }
void RenderSystem::_uniform1f(GLint l, float v) { assertOnRenderThread(); glUniform1f(l, v); }
void RenderSystem::uniform2f(GLint location, float x, float y) { RENDER_SYSTEM_QUEUE_CALL(_uniform2f, location, x, y); }
void RenderSystem::_uniform2f(GLint l, float x, float y) { assertOnRenderThread(); glUniform2f(l, x, y); }
void RenderSystem::uniform3f(GLint location, float x, float y, float z) { RENDER_SYSTEM_QUEUE_CALL(_uniform3f, location, x, y, z); }
void RenderSystem::_uniform3f(GLint l, float x, float y, float z) { assertOnRenderThread(); glUniform3f(l, x, y, z); }
void RenderSystem::uniform4f(GLint location, float x, float y, float z, float w) { RENDER_SYSTEM_QUEUE_CALL(_uniform4f, location, x, y, z, w); }
void RenderSystem::_uniform4f(GLint l, float x, float y, float z, float w) { assertOnRenderThread(); glUniform4f(l, x, y, z, w); }
void RenderSystem::uniformMatrix3fv(GLint l, GLsizei c, GLboolean t, const GLfloat* v) { assertOnRenderThread(); glUniformMatrix3fv(l, c, t, v); }
void RenderSystem::uniformMatrix4fv(GLint l, GLsizei c, GLboolean t, const GLfloat* v) { assertOnRenderThread(); glUniformMatrix4fv(l, c, t, v); }

// [新增] _uniformMatrix3fv 的定义
void RenderSystem::_uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
    assertOnRenderThread();
    glUniformMatrix3fv(location, count, transpose, value);
}

// [新增] _uniformMatrix4fv 的定义
void RenderSystem::_uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
    assertOnRenderThread();
    glUniformMatrix4fv(location, count, transpose, value);
}

void RenderSystem::uniform2f(GLint location, const glm::vec2& vec) { uniform2f(location, vec.x, vec.y); }
void RenderSystem::uniform3f(GLint location, const glm::vec3& vec) { uniform3f(location, vec.x, vec.y, vec.z); }
void RenderSystem::uniform4f(GLint location, const glm::vec4& vec) { uniform4f(location, vec.x, vec.y, vec.z, vec.w); }
void RenderSystem::uniformMatrix3(GLint location, const glm::mat3& matrix, bool transpose) {
    if (!isOnRenderThread()) { recordRenderCall([=] { _uniformMatrix3fv(location, 1, transpose, glm::value_ptr(matrix)); }); }
    else { _uniformMatrix3fv(location, 1, transpose, glm::value_ptr(matrix)); }
}
void RenderSystem::uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose) {
    if (!isOnRenderThread()) { recordRenderCall([=] { _uniformMatrix4fv(location, 1, transpose, glm::value_ptr(matrix)); }); }
    else { _uniformMatrix4fv(location, 1, transpose, glm::value_ptr(matrix)); }
}
GLint RenderSystem::getUniformLocation(GLuint program, const std::string& name) { assertOnRenderThread(); return glGetUniformLocation(program, name.c_str()); }

// ================== 绘制命令 ==================
void RenderSystem::lineWidth(float width) { RENDER_SYSTEM_QUEUE_CALL(_lineWidth, width); }
void RenderSystem::_lineWidth(float w) { assertOnRenderThread(); glLineWidth(w); }
void RenderSystem::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { RENDER_SYSTEM_QUEUE_CALL(_drawElements, mode, count, type, indices); }
void RenderSystem::_drawElements(GLenum m, GLsizei c, GLenum t, const void* i) { assertOnRenderThread(); glDrawElements(m, c, t, i); }
void RenderSystem::drawArrays(GLenum mode, GLint first, GLsizei count) { RENDER_SYSTEM_QUEUE_CALL(_drawArrays, mode, first, count); }
void RenderSystem::_drawArrays(GLenum m, GLint f, GLsizei c) { assertOnRenderThread(); glDrawArrays(m, f, c); }

// ================== 混合模式 ==================
void RenderSystem::enableBlend() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_enableBlend); }
void RenderSystem::_enableBlend() { assertOnRenderThread(); glEnable(GL_BLEND); }
void RenderSystem::disableBlend() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_disableBlend); }
void RenderSystem::_disableBlend() { assertOnRenderThread(); glDisable(GL_BLEND); }
void RenderSystem::blendFunc(GLenum sfactor, GLenum dfactor) { RENDER_SYSTEM_QUEUE_CALL(_blendFunc, sfactor, dfactor); }
void RenderSystem::_blendFunc(GLenum s, GLenum d) { assertOnRenderThread(); glBlendFunc(s, d); }
void RenderSystem::defaultBlendFunc() { blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }

// ================== 着色器程序管理 ==================
GLuint RenderSystem::createProgram() { assertOnRenderThread(); return glCreateProgram(); }
GLint RenderSystem::getCurrentProgram() { assertOnRenderThread(); GLint p; glGetIntegerv(GL_CURRENT_PROGRAM, &p); return p; }
void RenderSystem::attachShader(GLuint p, GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_attachShader, p, s); }
void RenderSystem::_attachShader(GLuint p, GLuint s) { assertOnRenderThread(); glAttachShader(p, s); }
void RenderSystem::linkProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_linkProgram, p); }
void RenderSystem::_linkProgram(GLuint p) { assertOnRenderThread(); glLinkProgram(p); }
GLint RenderSystem::getProgrami(GLuint p, GLenum n) { assertOnRenderThread(); GLint i; glGetProgramiv(p, n, &i); return i; }
std::string RenderSystem::getProgramInfoLog(GLuint program) {
    assertOnRenderThread();
    GLint len = 0;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
    if (len > 1) {
        std::vector<char> log(len);
        glGetProgramInfoLog(program, len, nullptr, log.data());
        return std::string(log.begin(), log.end());
    }
    return "";
}
void RenderSystem::detachShader(GLuint p, GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_detachShader, p, s); }
void RenderSystem::_detachShader(GLuint p, GLuint s) { assertOnRenderThread(); glDetachShader(p, s); }
void RenderSystem::deleteProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_deleteProgram, p); }
void RenderSystem::_deleteProgram(GLuint p) { assertOnRenderThread(); glDeleteProgram(p); }
GLuint RenderSystem::linkProgram(GLuint vertexShader, GLuint fragmentShader) {
    assertOnRenderThread();
    GLuint program = createProgram();
    _attachShader(program, vertexShader);
    _attachShader(program, fragmentShader);
    _linkProgram(program);
    if (getProgrami(program, GL_LINK_STATUS) != GL_TRUE) {
        std::string log = getProgramInfoLog(program);
        s_Logger->error("Program link failed: {}", log);
        _deleteProgram(program);
        throw std::runtime_error("Program link failed: " + log);
    }
    _detachShader(program, vertexShader);
    _detachShader(program, fragmentShader);
    return program;
}
GLuint RenderSystem::linkProgram(GLuint v, GLuint g, GLuint f) {
    assertOnRenderThread();
    GLuint p = createProgram();
    _attachShader(p, v);
    if (g != 0) _attachShader(p, g);
    _attachShader(p, f);
    _linkProgram(p);
    if (getProgrami(p, GL_LINK_STATUS) != GL_TRUE) {
        std::string log = getProgramInfoLog(p);
        s_Logger->error("Program link failed: {}", log);
        _deleteProgram(p);
        throw std::runtime_error("Program link failed: " + log);
    }
    _detachShader(p, v);
    if (g != 0) _detachShader(p, g);
    _detachShader(p, f);
    return p;
}
void RenderSystem::useProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_useProgram, p); }
void RenderSystem::_useProgram(GLuint p) { assertOnRenderThread(); glUseProgram(p); }

// ================== 着色器管理 ==================
GLuint RenderSystem::createShader(GLenum type) { assertOnRenderThread(); return glCreateShader(type); }
void RenderSystem::shaderSource(GLuint shader, const std::string& source) {
    if (!isOnRenderThread()) { recordRenderCall([=] { _shaderSource(shader, source); }); }
    else { _shaderSource(shader, source); }
}
void RenderSystem::_shaderSource(GLuint s, const std::string& src) {
    assertOnRenderThread();
    const char* c_str = src.c_str();
    glShaderSource(s, 1, &c_str, nullptr);
}
void RenderSystem::compileShader(GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_compileShader, s); }
void RenderSystem::_compileShader(GLuint s) { assertOnRenderThread(); glCompileShader(s); }
GLint RenderSystem::getShaderi(GLuint s, GLenum p) { assertOnRenderThread(); GLint i; glGetShaderiv(s, p, &i); return i; }
std::string RenderSystem::getShaderInfoLog(GLuint shader) {
    assertOnRenderThread();
    GLint len = 0;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
    if (len > 1) {
        std::vector<char> log(len);
        glGetShaderInfoLog(shader, len, nullptr, log.data());
        return std::string(log.begin(), log.end());
    }
    return "";
}
void RenderSystem::deleteShader(GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_deleteShader, s); }
void RenderSystem::_deleteShader(GLuint s) { assertOnRenderThread(); glDeleteShader(s); }
GLuint RenderSystem::compileShader(GLenum type, const std::string& source) {
    assertOnRenderThread();
    GLuint shader = createShader(type);
    _shaderSource(shader, source);
    _compileShader(shader);
    if (getShaderi(shader, GL_COMPILE_STATUS) != GL_TRUE) {
        std::string log = getShaderInfoLog(shader);
        s_Logger->error("Shader compilation failed: {}", log);
        _deleteShader(shader);
        throw std::runtime_error("Shader compilation failed: " + log);
    }
    return shader;
}

// ================== 深度测试 ==================
void RenderSystem::depthFunc(GLenum func) { RENDER_SYSTEM_QUEUE_CALL(_depthFunc, func); }
void RenderSystem::_depthFunc(GLenum f) { assertOnRenderThread(); glDepthFunc(f); }
void RenderSystem::depthMask(bool flag) { RENDER_SYSTEM_QUEUE_CALL(_depthMask, flag); }
void RenderSystem::_depthMask(bool f) { assertOnRenderThread(); glDepthMask(f ? GL_TRUE : GL_FALSE); }
void RenderSystem::clearDepth(double depth) { RENDER_SYSTEM_QUEUE_CALL(_clearDepth, depth); }
void RenderSystem::_clearDepth(double d) { assertOnRenderThread(); glClearDepth(d); }
void RenderSystem::enableDepthTest() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_enableDepthTest); }
void RenderSystem::_enableDepthTest() { assertOnRenderThread(); glEnable(GL_DEPTH_TEST); }
void RenderSystem::disableDepthTest() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_disableDepthTest); }
void RenderSystem::_disableDepthTest() { assertOnRenderThread(); glDisable(GL_DEPTH_TEST); }

// ================== 纹理管理 ==================
void RenderSystem::bindTexture(GLuint texture) { RENDER_SYSTEM_QUEUE_CALL(_bindTexture, texture); }
void RenderSystem::bindTexture(const Vivid2D::Render::Texture::Texture& texture, int textureUnit) {
    GLuint textureId = texture.getTextureId();
    if (textureUnit < 0 || textureUnit >= 32) {
        textureUnit = 0;
    }
    GLenum glTextureUnit = GL_TEXTURE0 + textureUnit;
    recordRenderCall([glTextureUnit, textureId]() {
        _activeTexture(glTextureUnit);
        _bindTexture(textureId);
        });
}
void RenderSystem::_bindTexture(GLuint t) { assertOnRenderThread(); glBindTexture(GL_TEXTURE_2D, t); }
void RenderSystem::getTexImage(GLenum t, GLint l, GLenum f, GLenum ty, void* p) { assertOnRenderThread(); glGetTexImage(t, l, f, ty, p); }

// _getTexImage 的定义
void RenderSystem::_getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) {
    assertOnRenderThread();
    glGetTexImage(target, level, format, type, pixels);
}

void RenderSystem::activeTexture(GLenum texture) { RENDER_SYSTEM_QUEUE_CALL(_activeTexture, texture); }
void RenderSystem::_activeTexture(GLenum t) { assertOnRenderThread(); glActiveTexture(t); }
GLuint RenderSystem::genTextures() { assertOnRenderThread(); GLuint t; glGenTextures(1, &t); return t; }
void RenderSystem::deleteTextures(GLuint texture) { RENDER_SYSTEM_QUEUE_CALL(_deleteTextures, texture); }
void RenderSystem::_deleteTextures(GLuint t) { assertOnRenderThread(); glDeleteTextures(1, &t); }
void RenderSystem::texImage2D(GLenum t, GLint l, GLint iF, GLsizei w, GLsizei h, GLint b, GLenum f, GLenum ty, const void* p) { assertOnRenderThread(); glTexImage2D(t, l, iF, w, h, b, f, ty, p); }

// [新增] _texImage2D 的定义
void RenderSystem::_texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) {
    assertOnRenderThread();
    glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
}

void RenderSystem::texParameteri(GLenum target, GLenum pname, GLint param) { RENDER_SYSTEM_QUEUE_CALL(_texParameteri, target, pname, param); }
void RenderSystem::_texParameteri(GLenum t, GLenum p, GLint v) { assertOnRenderThread(); glTexParameteri(t, p, v); }
void RenderSystem::setTextureMinFilter(GLenum filter) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); }
void RenderSystem::setTextureMagFilter(GLenum filter) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); }
void RenderSystem::setTextureWrapS(GLenum wrap) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); }
void RenderSystem::setTextureWrapT(GLenum wrap) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); }
GLuint RenderSystem::createDefaultTexture() {
    assertOnRenderThread();
    GLuint textureId = genTextures();
    _bindTexture(textureId);
    unsigned char whitePixel[] = { 255, 255, 255, 255 };
    texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixel);
    _texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    _texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    _texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    _texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    _bindTexture(0);
    return textureId;
}

// ================== 顶点属性 ==================
void RenderSystem::enableVertexAttribArray(GLuint i) { RENDER_SYSTEM_QUEUE_CALL(_enableVertexAttribArray, i); }
void RenderSystem::_enableVertexAttribArray(GLuint i) { assertOnRenderThread(); glEnableVertexAttribArray(i); }
void RenderSystem::disableVertexAttribArray(GLuint i) { RENDER_SYSTEM_QUEUE_CALL(_disableVertexAttribArray, i); }
void RenderSystem::_disableVertexAttribArray(GLuint i) { assertOnRenderThread(); glDisableVertexAttribArray(i); }
void RenderSystem::vertexAttribPointer(GLuint i, GLint s, GLenum t, GLboolean n, GLsizei st, const void* p) { RENDER_SYSTEM_QUEUE_CALL(_vertexAttribPointer, i, s, t, n, st, p); }
void RenderSystem::_vertexAttribPointer(GLuint i, GLint s, GLenum t, GLboolean n, GLsizei st, const void* p) { assertOnRenderThread(); glVertexAttribPointer(i, s, t, n, st, p); }

// ================== 工具方法 ==================
void RenderSystem::readPixels(int x, int y, int w, int h, GLenum f, GLenum t, void* p) { assertOnRenderThread(); glReadPixels(x, y, w, h, f, t, p); }

// [新增] _readPixels 的定义
void RenderSystem::_readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels) {
    assertOnRenderThread();
    glReadPixels(x, y, width, height, format, type, pixels);
}

bool RenderSystem::isExtensionSupported(const std::string& ext) {
    assertOnRenderThread();
    const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
    return strstr(extensions, ext.c_str()) != nullptr;
}
void RenderSystem::pixelStore(GLenum pname, GLint param) { RENDER_SYSTEM_QUEUE_CALL(_pixelStore, pname, param); }
void RenderSystem::_pixelStore(GLenum p, GLint v) { assertOnRenderThread(); glPixelStorei(p, v); }
std::string RenderSystem::getVendor() { assertOnRenderThread(); return (const char*)glGetString(GL_VENDOR); }
std::string RenderSystem::getRenderer() { assertOnRenderThread(); return (const char*)glGetString(GL_RENDERER); }
std::string RenderSystem::getOpenGLVersion() { assertOnRenderThread(); return (const char*)glGetString(GL_VERSION); }
std::string RenderSystem::getGLSLVersion() { assertOnRenderThread(); return (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); }
void RenderSystem::logDetailedGLInfo() {
    assertOnRenderThread();
    s_Logger->info("=== OpenGL System Information ===");
    s_Logger->info("Vendor: {}", getVendor());
    s_Logger->info("Renderer: {}", getRenderer());
    s_Logger->info("OpenGL Version: {}", getOpenGLVersion());
    s_Logger->info("GLSL Version: {}", getGLSLVersion());
    GLint val;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
    s_Logger->info("Max Texture Size: {}", val);
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &val);
    s_Logger->info("Max Vertex Attributes: {}", val);
    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &val);
    s_Logger->info("Max Texture Units: {}", val);
}
void RenderSystem::setupDefaultState() {
    beginInitialization();
    clearColor(0.0f, 0.0f, 0.0f, 1.0f);
    viewport(0, 0, s_ViewportWidth, s_ViewportHeight);
    enableBlend();
    defaultBlendFunc();
    disableDepthTest();
    finishInitialization();
}
void RenderSystem::checkGLError(const std::string& operation) { RENDER_SYSTEM_QUEUE_CALL(_checkGLError, operation); }
void RenderSystem::_checkGLError(const std::string& op) {
    assertOnRenderThread();
    GLenum error;
    while ((error = glGetError()) != GL_NO_ERROR) {
        s_Logger->error("OpenGL error during [{}]: {} ({})", op, getGLErrorString(error), error);
    }
}
std::string RenderSystem::getGLErrorString(GLenum error) {
    switch (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_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
    case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
    default: return "Unknown (" + std::to_string(error) + ")";
    }
}

// ================== 获取状态 ==================
int RenderSystem::getViewportWidth() { return s_ViewportWidth; }
int RenderSystem::getViewportHeight() { return s_ViewportHeight; }
glm::vec4 RenderSystem::getClearColor() { return s_ClearColorValue; }
size_t RenderSystem::getQueueSize() {
    std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
    return s_RenderQueue.size();
}