From 6dcd006f0e19bacb6b9f8f08c33abe7bace157c2 Mon Sep 17 00:00:00 2001
From: tzdwindows 7 <3076584115@qq.com>
Date: Sat, 15 Nov 2025 16:22:14 +0800
Subject: [PATCH] feat(renderer): implement texture binding with texture unit
support
- Added generate_new_uuid function for unique identifier generation
- Included stduuid/uuid.h and declared generate_new_uuid in pch.h
- Added bindTexture overload to accept Texture object and texture unit
- Implemented texture unit validation and OpenGL texture activation
- Added Texture class declaration in RenderSystem header
- Updated project files to include new model and utility headers/sources
- Configured C++20 standard in Vivid2D project settings
- Fixed namespace references in Vivid2D.cpp for Buffer classes
---
Vivid2D/Vivid2D.cpp | 4 +-
Vivid2D/Vivid2D.vcxproj | 1 +
Vivid2DRenderer/Vivid2DRenderer.vcxproj | 14 +
.../Vivid2DRenderer.vcxproj.filters | 42 +++
Vivid2DRenderer/dllmain.cpp | 7 +
Vivid2DRenderer/pch.h | 3 +
Vivid2DRenderer/systems/RenderSystem.cpp | 15 +-
Vivid2DRenderer/systems/RenderSystem.h | 294 +++++++++++++++++-
8 files changed, 376 insertions(+), 4 deletions(-)
diff --git a/Vivid2D/Vivid2D.cpp b/Vivid2D/Vivid2D.cpp
index e6a3311..7643713 100644
--- a/Vivid2D/Vivid2D.cpp
+++ b/Vivid2D/Vivid2D.cpp
@@ -150,8 +150,8 @@ int main() {
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();
+ Vivid2D::Render::Buffer::Tesselator& t = Vivid2D::Render::Buffer::Tesselator::getInstance();
+ Vivid2D::Render::Buffer::BufferBuilder& builder = t.getBuilder();
// 矩形的位置和大小
const float rectX = 0; // 矩形左上角的 X 坐标
diff --git a/Vivid2D/Vivid2D.vcxproj b/Vivid2D/Vivid2D.vcxproj
index 4e75e7e..79667dd 100644
--- a/Vivid2D/Vivid2D.vcxproj
+++ b/Vivid2D/Vivid2D.vcxproj
@@ -122,6 +122,7 @@
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
+ stdcpp20
Console
diff --git a/Vivid2DRenderer/Vivid2DRenderer.vcxproj b/Vivid2DRenderer/Vivid2DRenderer.vcxproj
index 5adb64d..f483a41 100644
--- a/Vivid2DRenderer/Vivid2DRenderer.vcxproj
+++ b/Vivid2DRenderer/Vivid2DRenderer.vcxproj
@@ -210,9 +210,16 @@ endlocal
+
+
+
+
+
+
+
@@ -233,9 +240,16 @@ endlocal
+
+
+
+
+
+
+
diff --git a/Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters b/Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters
index 3ccf8be..097b17f 100644
--- a/Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters
+++ b/Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters
@@ -78,6 +78,27 @@
头文件
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
@@ -137,5 +158,26 @@
源文件
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
\ No newline at end of file
diff --git a/Vivid2DRenderer/dllmain.cpp b/Vivid2DRenderer/dllmain.cpp
index daed8c8..039b8cc 100644
--- a/Vivid2DRenderer/dllmain.cpp
+++ b/Vivid2DRenderer/dllmain.cpp
@@ -1,6 +1,13 @@
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
+uuids::uuid generate_new_uuid() {
+ static std::random_device rd;
+ static std::mt19937 engine(rd());
+ static uuids::uuid_random_generator generator(engine);
+ return generator();
+}
+
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
diff --git a/Vivid2DRenderer/pch.h b/Vivid2DRenderer/pch.h
index 1698246..c5b0c56 100644
--- a/Vivid2DRenderer/pch.h
+++ b/Vivid2DRenderer/pch.h
@@ -17,6 +17,9 @@
// 作用:告诉编译器,使用此宏标记的类、函数或变量,必须从当前 DLL 中导出。
// 这是在编译 DLL 自身源代码时,确保其接口能够被外部应用程序使用的关键步骤。
#define VIVID_2D_MYDLL_API __declspec(dllexport)
+#include
+
+uuids::uuid generate_new_uuid();
// 添加要在此处预编译的标头
#include "framework.h"
diff --git a/Vivid2DRenderer/systems/RenderSystem.cpp b/Vivid2DRenderer/systems/RenderSystem.cpp
index 3072803..b672214 100644
--- a/Vivid2DRenderer/systems/RenderSystem.cpp
+++ b/Vivid2DRenderer/systems/RenderSystem.cpp
@@ -1,5 +1,7 @@
#include "pch.h"
+
#include "RenderSystem.h"
+#include "Texture.h"
#include
#include
@@ -367,10 +369,21 @@ void RenderSystem::_disableDepthTest() { assertOnRenderThread(); glDisable(GL_DE
// ================== ==================
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 Ķ
+// _getTexImage Ķ
void RenderSystem::_getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) {
assertOnRenderThread();
glGetTexImage(target, level, format, type, pixels);
diff --git a/Vivid2DRenderer/systems/RenderSystem.h b/Vivid2DRenderer/systems/RenderSystem.h
index c0589d3..0af9e80 100644
--- a/Vivid2DRenderer/systems/RenderSystem.h
+++ b/Vivid2DRenderer/systems/RenderSystem.h
@@ -13,13 +13,30 @@
#include
#include
+namespace Vivid2D::Render::Texture
+{
+ class Texture;
+}
+
// ǰ spdlog::logger Աͷļа
namespace spdlog {
class logger;
}
+/**
+ * @class RenderSystem
+ * @brief ṩһ̰߳ȫġе OpenGL API װ㡣
+ * @details
+ * һȫּ̬࣬ڽκ̵߳ȾŶӣһרõȾִ߳ǡ
+ * ȷ OpenGL ̰߳ȫԡṩ˶ OpenGL ״̬ɫ
+ * ܣԼһڵԵĴơ
+ * ʹ÷̻߳߳еùľ̬ RenderSystem::drawElements
+ * ЩὫȾ¼СȾ̵߳ѭУ RenderSystem::replayQueue()
+ * ִŶӵ
+ */
class VIVID_2D_MYDLL_API RenderSystem {
public:
+ // RenderSystem һ̬࣬˽ֹʵ
RenderSystem() = delete;
~RenderSystem() = delete;
RenderSystem(const RenderSystem&) = delete;
@@ -38,36 +55,151 @@ public:
static void ShutdownLogging();
// ================== ʼ̹߳ ==================
+ /**
+ * @brief ʼרõȾ̡߳
+ */
static void initRenderThread();
+
+ /**
+ * @brief ʼȾϵͳijʼΡڴ˽Σÿֱڵִ߳С
+ */
static void beginInitialization();
+
+ /**
+ * @brief ȾϵͳijʼΡ˺еöŶӡ
+ */
static void finishInitialization();
+
+ /**
+ * @brief 鵱ǰ߳ǷȾ̡߳
+ * @return Ⱦ̣߳ true
+ */
static bool isOnRenderThread();
+
+ /**
+ * @brief 鵱ǰǷڳʼΡ
+ * @return dzʼΣ true
+ */
static bool isInInitPhase();
+
+ /**
+ * @brief Եǰ̱߳Ⱦֹ̣߳
+ */
static void assertOnRenderThread();
+
+ /**
+ * @brief Եǰ̱߳Ⱦ̻߳ڳʼΡ
+ */
static void assertOnRenderThreadOrInit();
+
+ /**
+ * @brief ʹ GLAD OpenGL ָ롣
+ * @param loader һָ룬ڻȡ OpenGL ĵַ glfwGetProcAddress
+ */
static void loadGLFunctions(GLADloader loader);
-
+
// ================== Ⱦ ==================
+ /**
+ * @brief һȾãΪ lambda ¼УԱԺȾִ߳С
+ * @param renderCall ҪִеȾ
+ */
static void recordRenderCall(std::function&& renderCall);
+
+ /**
+ * @brief Ⱦִ߳едȾá
+ */
static void replayQueue();
// ================== OpenGL ״̬װ ==================
+ /**
+ * @brief һ OpenGL ܣ GL_BLEND
+ * @param capability Ҫõ OpenGL ö١
+ */
static void enable(GLenum capability);
+
+ /**
+ * @brief һ OpenGL ܡ
+ * @param capability Ҫõ OpenGL ö١
+ */
static void disable(GLenum capability);
+
+ /**
+ * @brief ǰȾ״̬ɫϡӿڵȣ״̬ջ
+ */
static void pushState();
+
+ /**
+ * @brief ״̬ջеָһȾ״̬
+ */
static void popState();
+
+ /**
+ * @brief ȡǰ״̬ջĴС
+ * @return ջе״̬
+ */
static size_t getStateStackSize();
+
+ /**
+ * @brief ɫ
+ */
static void clearColor(float r, float g, float b, float a);
+
+ /**
+ * @brief ָĻ GL_COLOR_BUFFER_BIT
+ * @param mask ҪĻλ롣
+ */
static void clear(GLbitfield mask);
+
+ /**
+ * @brief OpenGL ӿڡ
+ */
static void viewport(int x, int y, int width, int height);
// ================== VAO / VBO / EBO ==================
+ /**
+ * @brief һ (VAO)
+ * @return ´ VAO ľ
+ */
static GLuint GenVertexArrays();
+
+ /**
+ * @brief ɾһ VAO
+ * @param vao Ҫɾ VAO ľ
+ */
static void DeleteVertexArrays(GLuint vao);
+
+ /**
+ * @brief һ VAO
+ * @param vao Ҫ VAO ľ
+ */
static void BindVertexArray(GLuint vao);
+
+ /**
+ * @brief һ (VBO/EBO)
+ * @return ´Ļľ
+ */
static GLuint GenBuffers();
+
+ /**
+ * @brief ɾһ
+ * @param buffer ҪɾĻľ
+ */
static void DeleteBuffers(GLuint buffer);
+
+ /**
+ * @brief һ
+ * @param target Ŀ ( GL_ARRAY_BUFFER)
+ * @param buffer ҪĻľ
+ */
static void BindBuffer(GLenum target, GLuint buffer);
+
+ /**
+ * @brief ϴǰĻ
+ * @param target Ŀꡣ
+ * @param size ݵĴСֽΪλ
+ * @param data ָݵָ롣
+ * @param usage ݵԤ; ( GL_STATIC_DRAW)
+ */
static void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
// ================== Uniform ==================
@@ -83,39 +215,147 @@ public:
static void uniform4f(GLint location, const glm::vec4& vec);
static void uniformMatrix3(GLint location, const glm::mat3& matrix, bool transpose = false);
static void uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose = false);
+
+ /**
+ * @brief ȡɫ uniform λá
+ * @param program ɫľ
+ * @param name uniform ơ
+ * @return uniform λá
+ */
static GLint getUniformLocation(GLuint program, const std::string& name);
// ================== ==================
+ /**
+ * @brief ߿
+ */
static void lineWidth(float width);
+
+ /**
+ * @brief ʹлơ
+ */
static void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
+
+ /**
+ * @brief ֱʹöлơ
+ */
static void drawArrays(GLenum mode, GLint first, GLsizei count);
// ================== ģʽ ==================
+ /**
+ * @brief ûϡ
+ */
static void enableBlend();
+
+ /**
+ * @brief ûϡ
+ */
static void disableBlend();
+
+ /**
+ * @brief ûϺ
+ */
static void blendFunc(GLenum sfactor, GLenum dfactor);
+
+ /**
+ * @brief Ĭϵ Alpha Ϻ (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+ */
static void defaultBlendFunc();
// ================== ɫ ==================
+ /**
+ * @brief һյɫ
+ * @return ³ľ
+ */
static GLuint createProgram();
+
+ /**
+ * @brief ȡǰɫ
+ * @return ǰľ
+ */
static GLint getCurrentProgram();
+
+ /**
+ * @brief һɫӵɫ
+ */
static void attachShader(GLuint program, GLuint shader);
+
+ /**
+ * @brief һɫ
+ */
static void linkProgram(GLuint program);
+
+ /**
+ * @brief ȡɫIJ
+ */
static GLint getProgrami(GLuint program, GLenum pname);
+
+ /**
+ * @brief ȡɫ־Ϣ
+ */
static std::string getProgramInfoLog(GLuint program);
+
+ /**
+ * @brief ӳзһɫ
+ */
static void detachShader(GLuint program, GLuint shader);
+
+ /**
+ * @brief ɾһɫ
+ */
static void deleteProgram(GLuint program);
+
+ /**
+ * @brief ӶƬɫԴһij
+ */
static GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);
+
+ /**
+ * @brief Ӷ㡢κƬɫԴһij
+ */
static GLuint linkProgram(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader);
+
+ /**
+ * @brief һɫ
+ */
static void useProgram(GLuint program);
// ================== ɫ ==================
+ /**
+ * @brief һָ͵ɫ
+ * @param type ɫ ( GL_VERTEX_SHADER)
+ * @return ɫľ
+ */
static GLuint createShader(GLenum type);
+
+ /**
+ * @brief ΪɫԴ롣
+ */
static void shaderSource(GLuint shader, const std::string& source);
+
+ /**
+ * @brief һɫ
+ */
static void compileShader(GLuint shader);
+
+ /**
+ * @brief ȡɫIJ
+ */
static GLint getShaderi(GLuint shader, GLenum pname);
+
+ /**
+ * @brief ȡɫ־Ϣ
+ */
static std::string getShaderInfoLog(GLuint shader);
+
+ /**
+ * @brief ɾһɫ
+ */
static void deleteShader(GLuint shader);
+
+ /**
+ * @brief Դһָ͵ɫ
+ * @return ɫ
+ */
static GLuint compileShader(GLenum type, const std::string& source);
// ================== Ȳ ==================
@@ -126,10 +366,36 @@ public:
static void disableDepthTest();
// ================== ==================
+ /**
+ * @brief һ 2D ǰԪ
+ * @param texture Ҫľ
+ */
static void bindTexture(GLuint texture);
+
+ /**
+ * @brief һ Texture ָԪ
+ * @details һԪͰϲΪһ
+ * ȫύȾ̡߳
+ * @param texture Ҫ Texture ijá
+ * @param textureUnit ҪԪ (0, 1, 2, ...)
+ */
+ static void bindTexture(const Vivid2D::Render::Texture::Texture& texture, int textureUnit = 0);
static void getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
+ /**
+ * @brief һԪ
+ * @param texture ҪԪ ( GL_TEXTURE0)
+ */
static void activeTexture(GLenum texture);
+ /**
+ * @brief һ
+ * @return ľ
+ */
static GLuint genTextures();
+
+ /**
+ * @brief ɾһ
+ * @param texture Ҫɾľ
+ */
static void deleteTextures(GLuint texture);
static void texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
static void texParameteri(GLenum target, GLenum pname, GLint param);
@@ -137,6 +403,11 @@ public:
static void setTextureMagFilter(GLenum filter);
static void setTextureWrapS(GLenum wrap);
static void setTextureWrapT(GLenum wrap);
+
+ /**
+ * @brief һĬϵ 1x1 ɫ
+ * @return Ĭľ
+ */
static GLuint createDefaultTexture();
// ================== ==================
@@ -146,20 +417,41 @@ public:
// ================== ߷ ==================
static void readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
+ /**
+ * @brief Ƿ֧ij OpenGL չ
+ */
static bool isExtensionSupported(const std::string& extension);
static void pixelStore(GLenum pname, GLint param);
static std::string getVendor();
static std::string getRenderer();
static std::string getOpenGLVersion();
static std::string getGLSLVersion();
+
+ /**
+ * @brief ¼ϸ OpenGL Ϣ
+ */
static void logDetailedGLInfo();
+
+ /**
+ * @brief һĬϵ OpenGL ״̬ûϣɫ
+ */
static void setupDefaultState();
+
+ /**
+ * @brief 鲢¼κη OpenGL
+ * @param operation ¼IJơ
+ */
static void checkGLError(const std::string& operation);
// ================== ȡ״̬ ==================
static int getViewportWidth();
static int getViewportHeight();
static glm::vec4 getClearColor();
+
+ /**
+ * @brief ȡǰȾе
+ * @return дС
+ */
static size_t getQueueSize();
private: