From 0707a6d5cdfd80b8d62756a723affddd4b496edd Mon Sep 17 00:00:00 2001 From: tzdwindows 7 <3076584115@qq.com> Date: Fri, 14 Nov 2025 22:27:38 +0800 Subject: [PATCH] =?UTF-8?q?Refactor=20(renderer)=EF=BC=9A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=BC=93=E5=86=B2=E5=8C=BA=E4=B8=8A=E4=BC=A0=E5=92=8C?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E7=AE=A1=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除多余的注释并简化applyRenderState逻辑 - 增强了丢失着色器制服和程序的错误记录 改进了绘制调用中的VAO/VBO绑定和属性管理 在渲染系统中增加了高兴功能的加载支持 - 调整线程断言逻辑以更好地处理初始化 - 在缓冲区绑定期间启用顶点属性数组 - 禁用深度测试并启用2D渲染的混合 - 更新了着色器源代码定义和正确的行结束符 - 导出ShaderProgram类以实现DLL可见性 - 通过删除不必要的注释简化纯色着色器 - 集成GLFW窗口管理和OpenGL上下文设置 - 实现了framebuffer resize回调来调整视口 - 添加了基本的渲染循环矩形镶嵌示例 - 确保在退出时正确清理着色器和渲染资源 --- Vivid2D/Vivid2D.cpp | 207 +++++++++++++++--- Vivid2DRenderer/systems/RenderSystem.cpp | 34 ++- Vivid2DRenderer/systems/RenderSystem.h | 5 +- .../systems/buffer/BufferUploader.cpp | 31 ++- .../systems/sources/ShaderProgram.h | 2 +- .../systems/sources/def/Shader2D.cpp | 121 +--------- .../systems/sources/def/SolidColorShader.cpp | 5 - 7 files changed, 225 insertions(+), 180 deletions(-) diff --git a/Vivid2D/Vivid2D.cpp b/Vivid2D/Vivid2D.cpp index 95437ce..e6a3311 100644 --- a/Vivid2D/Vivid2D.cpp +++ b/Vivid2D/Vivid2D.cpp @@ -4,53 +4,202 @@ #ifdef VIVID_2D_MYDLL_API #undef VIVID_2D_MYDLL_API #endif -#define VIVID_2D_MYDLL_API __declspec(dllexport) +#define VIVID_2D_MYDLL_API __declspec(dllimport) #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846f +#endif + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) { + RenderSystem::viewport(0, 0, width, height); +} int main() { - // ---------------------------------------------------- - // GLM 向量操作 (与 RenderSystem 无关,保持原样) - // ---------------------------------------------------- - glm::vec2 position(100.0f, 200.0f); - glm::vec2 velocity(5.0f, -2.0f); - position += velocity; - std::cout << "New Position: (" << position.x << ", " << position.y << ")" << std::endl; - std::cout << "---------------------------------------" << std::endl; + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW" << std::endl; + return -1; + } + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - // ---------------------------------------------------- - // RenderSystem 静态方法调用 (无需实例化) - // ---------------------------------------------------- + GLFWwindow* window = glfwCreateWindow(800, 600, "Vivid2D Circle Test", NULL, NULL); + if (window == NULL) { + std::cerr << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return -1; + } + glfwMakeContextCurrent(window); - // 1. 初始化日志系统 (假设已实现) - std::cout << "Initializing RenderSystem Logging..." << std::endl; + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + std::cerr << "Failed to initialize GLAD" << std::endl; + glfwTerminate(); + return -1; + } RenderSystem::InitializeLogging(); - // 2. 开始渲染线程初始化阶段 (假设已实现) + try { + typedef RenderSystem::GLADloader GLADloaderType; + RenderSystem::loadGLFunctions(reinterpret_cast(glfwGetProcAddress)); + } + catch (const std::runtime_error& e) { + std::cerr << "FATAL ERROR during GL function loading in DLL: " << e.what() << std::endl; + glfwTerminate(); + return -1; + } + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + std::cout << "Initializing RenderSystem Logging..." << std::endl; + RenderSystem::initRenderThread(); RenderSystem::beginInitialization(); - // 3. 记录一个渲染指令到队列中 - std::cout << "Recording a clear color command..." << std::endl; - // 这是一个 lambda 函数,捕获了要执行的 GL 命令 - RenderSystem::recordRenderCall([]() { - // 在实际的 RenderSystem 实现中,这会调用 glClearColor(1.0f, 0.5f, 0.0f, 1.0f); - std::cout << "-> (Render Thread) Executing glClearColor(Orange)" << std::endl; - }); + RenderSystem::viewport(0, 0, 800, 600); - // 4. 执行队列中的渲染指令 - std::cout << "Replaying render queue (" << RenderSystem::getQueueSize() << " calls)..." << std::endl; - RenderSystem::replayQueue(); // 假设这个调用会执行上面的 lambda + // ---------------------------------------------------------------------- + // 步骤 1: 记录编译指令,但不立即执行 + // ---------------------------------------------------------------------- + std::cout << "Compiling all shaders..." << std::endl; + RenderSystem::recordRenderCall([]() { ShaderManagement::compileAllShaders(); }); + + // ---------------------------------------------------------------------- + // 步骤 2: 立即执行队列,编译着色器 + // ---------------------------------------------------------------------- + std::cout << "Executing initialization queue (Shader compilation)..." << std::endl; + RenderSystem::replayQueue(); + std::cout << "Shader compilation executed. Queue size: " << RenderSystem::getQueueSize() << std::endl; + + // ---------------------------------------------------------------------- + // 步骤 3: 在主线程上安全地获取已编译的着色器 ID 和设置 Uniforms + // ---------------------------------------------------------------------- + glm::mat4 projection = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f); + glm::mat4 viewMatrix = glm::mat4(1.0f); + glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(400.0f, 300.0f, 0.0f)); + ShaderProgram* circleProgram = ShaderManagement::getShaderProgram("Solid Color Shader"); + + if (circleProgram) { + + // 记录设置 Uniforms 的指令 + RenderSystem::recordRenderCall([=]() { + circleProgram->use(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + // 设置 Projection Matrix (mat3) + GLint projLoc = circleProgram->getUniformLocation("uProjectionMatrix"); + if (projLoc != -1) { + RenderSystem::uniformMatrix3(projLoc, projection, false); + } + + // 设置 View Matrix (mat3) + GLint viewLoc = circleProgram->getUniformLocation("uViewMatrix"); + if (viewLoc != -1) { + RenderSystem::uniformMatrix3(viewLoc, viewMatrix, false); + } + + // 设置 Model Matrix (mat3) + GLint modelLoc = circleProgram->getUniformLocation("uModelMatrix"); + if (modelLoc != -1) { + RenderSystem::uniformMatrix3(modelLoc, modelMatrix, false); + } + + circleProgram->stop(); + }); + } + else { + std::cerr << "FATAL ERROR: Solid Color Shader not found after compilation. Please check the name or compilation logs." << std::endl; + glfwTerminate(); + return -1; + } + + + // ---------------------------------------------------------------------- + // 步骤 4: 记录绘制命令,使用已获取的 ID + // ---------------------------------------------------------------------- + std::cout << "Recording Circle drawing command..." << std::endl; + + // ---------------------------------------------------------------------- + // 步骤 5: 执行队列,设置 Uniforms 并记录几何体到 VBO + // ---------------------------------------------------------------------- + std::cout << "Executing final initialization queue (Uniforms and Geometry)..." << std::endl; + RenderSystem::replayQueue(); // 再次执行队列,此时执行 Uniform 设置和绘制命令 + std::cout << "Final initialization executed. Queue size: " << RenderSystem::getQueueSize() << std::endl; - // 5. 结束初始化阶段 RenderSystem::finishInitialization(); - // 6. 关闭日志系统 (确保日志被刷新) - std::cout << "Shutting down RenderSystem Logging." << std::endl; - RenderSystem::ShutdownLogging(); + if (RenderSystem::getQueueSize() > 0) { + throw std::runtime_error("FATAL ERROR: Initialization failed to clear the render queue before main loop."); + } + std::cout << "\nStarting main render loop..." << std::endl; + + while (!glfwWindowShouldClose(window)) { + + RenderSystem::clearColor(0.2f, 0.3f, 0.3f, 1.0f); + RenderSystem::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + Buffer::Tesselator& t = Buffer::Tesselator::getInstance(); + Buffer::BufferBuilder& builder = t.getBuilder(); + + // 矩形的位置和大小 + const float rectX = 0; // 矩形左上角的 X 坐标 + const float rectY = 0; // 矩形左上角的 Y 坐标 + const float rectWidth = 200.0f; // 矩形宽度 + const float rectHeight = 150.0f; // 矩形高度 + + // 确保深度测试被禁用,混合被启用 + RenderSystem::disableDepthTest(); + RenderSystem::enableBlend(); + RenderSystem::defaultBlendFunc(); + + // 【关键修正】:设置绘制模式为实心填充 + // 如果你希望画线框,可以使用 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + RenderSystem::recordRenderCall([]() { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 实心填充模式 + }); + + + // 【关键修正】:开始绘制矩形 + // 使用 GL_TRIANGLE_STRIP 绘制一个填充的矩形 (4个顶点) + builder.begin(GL_TRIANGLE_STRIP, 4); // 绘制两个三角形形成一个矩形 + builder.setShader(circleProgram->getProgramId()); + builder.setColor(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 红色 + builder.setTexture(0, 0); // 不需要纹理 + + // 矩形的四个顶点(顺序很重要,对于 GL_TRIANGLE_STRIP) + // 左上角 (X, Y) + builder.vertex(rectX, rectY, 0.0f, 0.0f); + // 右上角 (X + Width, Y) + builder.vertex(rectX + rectWidth, rectY, 1.0f, 0.0f); + // 左下角 (X, Y + Height) + builder.vertex(rectX, rectY + rectHeight, 0.0f, 1.0f); + // 右下角 (X + Width, Y + Height) + builder.vertex(rectX + rectWidth, rectY + rectHeight, 1.0f, 1.0f); + + t.end(); + + // 确保 GL 状态记录被执行 + RenderSystem::replayQueue(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + std::cout << "\nShutting down RenderSystem Logging." << std::endl; + RenderSystem::recordRenderCall([]() { ShaderManagement::cleanup(); }); + RenderSystem::replayQueue(); + RenderSystem::ShutdownLogging(); return 0; } \ No newline at end of file diff --git a/Vivid2DRenderer/systems/RenderSystem.cpp b/Vivid2DRenderer/systems/RenderSystem.cpp index 7a98ac4..3072803 100644 --- a/Vivid2DRenderer/systems/RenderSystem.cpp +++ b/Vivid2DRenderer/systems/RenderSystem.cpp @@ -57,6 +57,14 @@ void RenderSystem::ShutdownLogging() { } // ================== ʼ̹߳ ================== +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(); @@ -70,11 +78,19 @@ void RenderSystem::initRenderThread() { void RenderSystem::beginInitialization() { s_IsInInit = true; } void RenderSystem::finishInitialization() { s_IsInInit = false; - if (getQueueSize() > 0) { replayQueue(); } } bool RenderSystem::isOnRenderThread() { return std::this_thread::get_id() == s_RenderThreadId; } bool RenderSystem::isInInitPhase() { return s_IsInInit; } -void RenderSystem::assertOnRenderThread() { if (!isOnRenderThread()) { throw std::runtime_error("RenderSystem called from wrong thread!"); } } +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!"); } } // ================== Ⱦ ================== @@ -159,18 +175,18 @@ void RenderSystem::_viewport(int x, int y, int w, int h) { } // ================== VAO / VBO / EBO ================== -GLuint RenderSystem::GenVertexArrays() { assertOnRenderThread(); GLuint vao = 0; glGenVertexArrays(1, &vao); return vao; } +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) { assertOnRenderThread(); glDeleteVertexArrays(1, &v); } +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) { assertOnRenderThread(); glBindVertexArray(v); } -GLuint RenderSystem::GenBuffers() { assertOnRenderThread(); GLuint buf; glGenBuffers(1, &buf); return buf; } +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) { assertOnRenderThread(); glDeleteBuffers(1, &b); } +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) { assertOnRenderThread(); glBindBuffer(t, b); } +void RenderSystem::_glBindBuffer(GLenum t, GLuint b) { assertOnRenderThreadOrInit(); glBindBuffer(t, b); } void RenderSystem::BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) { - assertOnRenderThread(); + assertOnRenderThreadOrInit(); glBufferData(target, size, data, usage); } diff --git a/Vivid2DRenderer/systems/RenderSystem.h b/Vivid2DRenderer/systems/RenderSystem.h index b2f7cf6..c0589d3 100644 --- a/Vivid2DRenderer/systems/RenderSystem.h +++ b/Vivid2DRenderer/systems/RenderSystem.h @@ -24,7 +24,7 @@ public: ~RenderSystem() = delete; RenderSystem(const RenderSystem&) = delete; RenderSystem& operator=(const RenderSystem&) = delete; - + using GLADloader = void* (*)(const char* name); // ================== ־ϵͳ ================== /** @@ -45,7 +45,8 @@ public: static bool isInInitPhase(); static void assertOnRenderThread(); static void assertOnRenderThreadOrInit(); - + static void loadGLFunctions(GLADloader loader); + // ================== Ⱦ ================== static void recordRenderCall(std::function&& renderCall); static void replayQueue(); diff --git a/Vivid2DRenderer/systems/buffer/BufferUploader.cpp b/Vivid2DRenderer/systems/buffer/BufferUploader.cpp index e174d06..c761a77 100644 --- a/Vivid2DRenderer/systems/buffer/BufferUploader.cpp +++ b/Vivid2DRenderer/systems/buffer/BufferUploader.cpp @@ -9,17 +9,14 @@ namespace Buffer { void BufferUploader::applyRenderState(const RenderState& state) { - // 1. Ӧ if (state.textureId != 0) { RenderSystem::activeTexture(GL_TEXTURE0 + state.textureUnit); RenderSystem::bindTexture(state.textureId); } - - // 2. Ӧɫ unsigned int currentProgram = 0; if (state.shaderProgram != 0) { currentProgram = state.shaderProgram; - RenderSystem::useProgram(state.shaderProgram); + RenderSystem::useProgram(state.shaderProgram); // <--- ʹ Program } else { // ״̬ûָɫԻȡǰ󶨵ɫ @@ -27,19 +24,18 @@ namespace Buffer { glGetIntegerv(GL_CURRENT_PROGRAM, &programId); currentProgram = static_cast(programId); } - - // 3. uColor Uniform ( Program ʱ) if (currentProgram != 0) { GLint colorLoc = RenderSystem::getUniformLocation(currentProgram, "uColor"); - if (colorLoc != -1) { - // ʹ RenderSystem::uniform4f ɫ RenderSystem::uniform4f(colorLoc, state.color.x, state.color.y, state.color.z, state.color.w); } + else { + spdlog::warn("BufferUploader::applyRenderState: Uniform 'uColor' not found in program ID: {}.", currentProgram); + } } else { - spdlog::debug("BufferUploader::applyRenderState: No shader program available for color setting."); + spdlog::warn("BufferUploader::applyRenderState: No shader program available for color setting."); } // 4. Ӧûģʽ @@ -62,7 +58,6 @@ namespace Buffer { } void BufferUploader::restoreRenderState(const RenderState& previousState) { - // ָ֮ǰ״̬ RenderState::applyState() ʵ֡ previousState.applyState(); } @@ -72,28 +67,28 @@ namespace Buffer { // ========================================================== void BufferUploader::drawWithShader(std::unique_ptr buffer) { - - // Ϊգֱӷ if (!buffer) return; - RenderSystem::assertOnRenderThread(); RenderState currentState; currentState.saveCurrentState(); - try { - // ʹ -> unique_ptr ָ BuiltBuffer Ա const RenderState& bufferState = buffer->renderState; applyRenderState(bufferState); - - if (buffer->vao != 0) { + if (buffer->vao != 0 && buffer->vbo != 0) { RenderSystem::BindVertexArray(buffer->vao); + RenderSystem::BindBuffer(GL_ARRAY_BUFFER, buffer->vbo); + RenderSystem::enableVertexAttribArray(0); + RenderSystem::enableVertexAttribArray(1); } + if (buffer->vertexCount > 0) { RenderSystem::drawArrays(buffer->mode, 0, buffer->vertexCount); } - // VAO if (buffer->vao != 0) { + RenderSystem::disableVertexAttribArray(0); + RenderSystem::disableVertexAttribArray(1); + RenderSystem::BindBuffer(GL_ARRAY_BUFFER, 0); RenderSystem::BindVertexArray(0); } } diff --git a/Vivid2DRenderer/systems/sources/ShaderProgram.h b/Vivid2DRenderer/systems/sources/ShaderProgram.h index 80ee4ab..4147bf7 100644 --- a/Vivid2DRenderer/systems/sources/ShaderProgram.h +++ b/Vivid2DRenderer/systems/sources/ShaderProgram.h @@ -11,7 +11,7 @@ * * һ࣬ڹOpenGLɫ򣬰ͳһ(uniform)úͻ档 * ǵ̳ԣΪ麯 */ -class ShaderProgram +class VIVID_2D_MYDLL_API ShaderProgram { public: // 캯 diff --git a/Vivid2DRenderer/systems/sources/def/Shader2D.cpp b/Vivid2DRenderer/systems/sources/def/Shader2D.cpp index 72f5b94..a2243d5 100644 --- a/Vivid2DRenderer/systems/sources/def/Shader2D.cpp +++ b/Vivid2DRenderer/systems/sources/def/Shader2D.cpp @@ -1,123 +1,12 @@ -#include "pch.h" +#include "pch.h" #include "Shader2D.h" -// ɫ GLSL (Ӧ VertexShaders.java) -static const std::string VERTEX_SHADER_SRC = R"""( -#version 330 core -layout(location = 0) in vec2 aPosition; -layout(location = 1) in vec2 aTexCoord; -out vec2 vTexCoord; -out vec2 vWorldPos; - -uniform mat3 uModelMatrix; -uniform mat3 uViewMatrix; -uniform mat3 uProjectionMatrix; - -void main() { - // ʹ 3x3 Ļλ - vec3 p = uProjectionMatrix * uViewMatrix * uModelMatrix * vec3(aPosition, 1.0); - gl_Position = vec4(p.xy, 0.0, 1.0); - vTexCoord = aTexCoord; - // world-space λù fragment shader ʹã xy - vWorldPos = (uModelMatrix * vec3(aPosition, 1.0)).xy; -} -)"""; - -// Ƭɫ GLSL (Ӧ FragmentShaders.java) -static const std::string FRAGMENT_SHADER_SRC = R"""( -#version 330 core -in vec2 vTexCoord; -in vec2 vWorldPos; -out vec4 FragColor; - -uniform sampler2D uTexture; -uniform vec4 uColor; -uniform float uOpacity; -uniform int uBlendMode; -uniform int uDebugMode; - -#define MAX_LIGHTS 8 -uniform vec2 uLightsPos[MAX_LIGHTS]; -uniform vec3 uLightsColor[MAX_LIGHTS]; -uniform float uLightsIntensity[MAX_LIGHTS]; -uniform int uLightsIsAmbient[MAX_LIGHTS]; -uniform int uLightCount; - -// ˥ϵ -const float ATT_CONST = 1.0; -const float ATT_LINEAR = 0.09; -const float ATT_QUAD = 0.032; - -void main() { - // 1. ͼ͸ - vec4 tex = texture(uTexture, vTexCoord); - float alpha = tex.a * uOpacity; - if (alpha <= 0.001) discard; - - // 2. ޹ԴŻ· - if (uLightCount == 0) { - vec3 base = tex.rgb * uColor.rgb; - base = clamp(base, 0.0, 1.0); - FragColor = vec4(base, alpha); - return; - } - - // 3. ռ· - vec3 baseColor = tex.rgb * uColor.rgb; - vec3 ambient = vec3(0.06); // Сⲹ - vec3 lighting = vec3(0.0); - vec3 specularAccum = vec3(0.0); - - // ۻ - for (int i = 0; i < uLightCount; ++i) { - if (uLightsIsAmbient[i] == 1) { - lighting += uLightsColor[i] * uLightsIntensity[i]; - } - } - lighting += ambient; - - // Դ/ǻ - for (int i = 0; i < uLightCount; ++i) { - if (uLightsIsAmbient[i] == 1) continue; - - vec2 toLight = uLightsPos[i] - vWorldPos; - float dist = length(toLight); - // ׼˥ - float attenuation = ATT_CONST / (ATT_CONST + ATT_LINEAR * dist + ATT_QUAD * dist * dist); - - float radiance = uLightsIntensity[i] * attenuation; - - // (ھ) - float diffuseFactor = clamp(1.0 - (dist * 0.0015), 0.0, 1.0); - vec3 diff = uLightsColor[i] * radiance * diffuseFactor; - lighting += diff; - - // 򵥸߹ - vec3 lightDir3 = normalize(vec3(toLight, 0.0)); - vec3 viewDir = vec3(0.0, 0.0, 1.0); - vec3 normal = vec3(0.0, 0.0, 1.0); - vec3 reflectDir = reflect(-lightDir3, normal); - float specFactor = pow(max(dot(viewDir, reflectDir), 0.0), 16.0); - float specIntensity = 0.2; - specularAccum += uLightsColor[i] * radiance * specFactor * specIntensity; - } - - // Ӧù - vec3 totalLighting = min(lighting + specularAccum, vec3(2.0)); - vec3 finalColor = baseColor * totalLighting; - - // 4. 򵥻ģʽ - if (uBlendMode == 1) finalColor = tex.rgb + uColor.rgb; - else if (uBlendMode == 2) finalColor = tex.rgb * uColor.rgb; - else if (uBlendMode == 3) finalColor = 1.0 - (1.0 - tex.rgb) * (1.0 - uColor.rgb); - - // 5. - finalColor = clamp(finalColor, 0.0, 1.0); - FragColor = vec4(finalColor, alpha); -} -)"""; +// 顶点着色器 GLSL 代码 (对应 VertexShaders.java) +static const std::string VERTEX_SHADER_SRC = "\r\n#version 330 core\r\nlayout(location = 0) in vec2 aPosition;\r\nlayout(location = 1) in vec2 aTexCoord;\r\nout vec2 vTexCoord;\r\nout vec2 vWorldPos;\r\n\r\nuniform mat3 uModelMatrix;\r\nuniform mat3 uViewMatrix;\r\nuniform mat3 uProjectionMatrix;\r\n\r\nvoid main() {\r\n vec3 p = uProjectionMatrix * uViewMatrix * uModelMatrix * vec3(aPosition, 1.0);\r\n gl_Position = vec4(p.xy, 0.0, 1.0);\r\n vTexCoord = aTexCoord;\r\n vWorldPos = (uModelMatrix * vec3(aPosition, 1.0)).xy;\r\n}\r\n"; +// 片段着色器 GLSL 代码 (对应 FragmentShaders.java) +static const std::string FRAGMENT_SHADER_SRC = "\r\n#version 330 core\r\nin vec2 vTexCoord;\r\nin vec2 vWorldPos;\r\nout vec4 FragColor;\r\n\r\nuniform sampler2D uTexture;\r\nuniform vec4 uColor;\r\nuniform float uOpacity;\r\nuniform int uBlendMode;\r\nuniform int uDebugMode;\r\n\r\n#define MAX_LIGHTS 8\r\nuniform vec2 uLightsPos[MAX_LIGHTS];\r\nuniform vec3 uLightsColor[MAX_LIGHTS];\r\nuniform float uLightsIntensity[MAX_LIGHTS];\r\nuniform int uLightsIsAmbient[MAX_LIGHTS];\r\nuniform int uLightCount;\r\n\r\nconst float ATT_CONST = 1.0;\r\nconst float ATT_LINEAR = 0.09;\r\nconst float ATT_QUAD = 0.032;\r\n\r\nvoid main() {\r\n int i;\r\n\r\n vec4 tex = texture(uTexture, vTexCoord);\r\n float alpha = tex.a * uOpacity;\r\n if (alpha <= 0.001) discard;\r\n\r\n if (uLightCount == 0) {\r\n vec3 base = tex.rgb * uColor.rgb;\r\n base = clamp(base, 0.0, 1.0);\r\n FragColor = vec4(base, alpha);\r\n return;\r\n }\r\n\r\n vec3 baseColor = tex.rgb * uColor.rgb;\r\n vec3 ambient = vec3(0.06);\r\n vec3 lighting = vec3(0.0);\r\n vec3 specularAccum = vec3(0.0);\r\n\r\n for (i = 0; i < uLightCount; ++i) {\r\n if (uLightsIsAmbient[i] == 1) {\r\n lighting += uLightsColor[i] * uLightsIntensity[i];\r\n }\r\n }\r\n lighting += ambient;\r\n\r\n for (i = 0; i < uLightCount; ++i) {\r\n if (uLightsIsAmbient[i] == 1) continue;\r\n\r\n vec2 toLight = uLightsPos[i] - vWorldPos;\r\n float dist = length(toLight);\r\n float attenuation = ATT_CONST / (ATT_CONST + ATT_LINEAR * dist + ATT_QUAD * dist * dist);\r\n\r\n float radiance = uLightsIntensity[i] * attenuation;\r\n\r\n float diffuseFactor = clamp(1.0 - (dist * 0.0015), 0.0, 1.0); \r\n vec3 diff = uLightsColor[i] * radiance * diffuseFactor;\r\n lighting += diff;\r\n\r\n vec3 lightDir3 = normalize(vec3(toLight, 0.0));\r\n vec3 viewDir = vec3(0.0, 0.0, 1.0);\r\n vec3 normal = vec3(0.0, 0.0, 1.0);\r\n vec3 reflectDir = reflect(-lightDir3, normal);\r\n float specFactor = pow(max(dot(viewDir, reflectDir), 0.0), 16.0); \r\n float specIntensity = 0.2; \r\n specularAccum += uLightsColor[i] * radiance * specFactor * specIntensity;\r\n }\r\n\r\n vec3 totalLighting = min(lighting + specularAccum, vec3(2.0));\r\n vec3 finalColor = baseColor * totalLighting;\r\n\r\n if (uBlendMode == 1) finalColor = tex.rgb + uColor.rgb;\r\n else if (uBlendMode == 2) finalColor = tex.rgb * uColor.rgb;\r\n else if (uBlendMode == 3) finalColor = 1.0 - (1.0 - tex.rgb) * (1.0 - uColor.rgb);\r\n\r\n finalColor = clamp(finalColor, 0.0, 1.0);\r\n FragColor = vec4(finalColor, alpha);\r\n}\r\n"; class Shader2D::VertexShaders final : public Shader { public: diff --git a/Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp b/Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp index 1faeeab..4fe9088 100644 --- a/Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp +++ b/Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp @@ -14,7 +14,6 @@ uniform mat3 uViewMatrix; uniform mat3 uProjectionMatrix; void main() { - // ʹ 3x3 Ļλ vec3 p = uProjectionMatrix * uViewMatrix * uModelMatrix * vec3(aPosition, 1.0); gl_Position = vec4(p.xy, 0.0, 1.0); } @@ -28,13 +27,9 @@ uniform vec4 uColor; uniform float uOpacity; void main() { - // ֱʹɫ vec4 finalColor = uColor; finalColor.a *= uOpacity; - - // ͸̫Ƭ if (finalColor.a <= 0.001) discard; - FragColor = finalColor; } )""";