feat(Logger): Add a universal logger
- Add a Logger framework - Add a spdlog logger adapter - Update README and vcpkg.json - fix some language error
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -360,4 +360,6 @@ MigrationBackup/
|
|||||||
.ionide/
|
.ionide/
|
||||||
|
|
||||||
# Fody - auto-generated XML schema
|
# Fody - auto-generated XML schema
|
||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
**/vcpkg_installed/
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -19,21 +19,30 @@
|
|||||||
## 二、配置 vcpkg
|
## 二、配置 vcpkg
|
||||||
|
|
||||||
`vcpkg` 用于下载和安装项目所需的第三方库。
|
`vcpkg` 用于下载和安装项目所需的第三方库。
|
||||||
|
下列方法二选一:
|
||||||
|
|
||||||
1. **下载并引导 vcpkg:**
|
1. 手动安装vcpkg
|
||||||
|
|
||||||
|
- 1. **下载并引导 vcpkg:**
|
||||||
|
|
||||||
- 克隆 vcpkg 仓库或下载压缩包。
|
- 克隆 vcpkg 仓库或下载压缩包。
|
||||||
- 运行引导脚本(Windows 上通常是 `.\bootstrap-vcpkg.bat`)。
|
- 运行引导脚本(Windows 上通常是 `.\bootstrap-vcpkg.bat`)。
|
||||||
|
|
||||||
2. **安装项目依赖库:**
|
- 2. **安装项目依赖库:**
|
||||||
打开命令行或 PowerShell,进入 vcpkg 目录,然后运行以下命令来安装项目所需的库:
|
打开命令行或 PowerShell,进入 vcpkg 目录,然后运行以下命令来安装项目所需的库:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.\vcpkg install glfw3 glew stb glad spdlog glm
|
.\vcpkg install glfw3 glew stb glad spdlog glm stduuid
|
||||||
```
|
```
|
||||||
|
|
||||||
- 此命令将下载并安装 **glfw3** (窗口和上下文管理)、**glew/glad** (OpenGL 扩展加载)、**stb** (图像处理/加载等)、**spdlog** (日志记录) 和 **glm** (数学库)。
|
- 此命令将下载并安装 **glfw3** (窗口和上下文管理)、**glew/glad** (OpenGL 扩展加载)、**stb** (图像处理/加载等)、**spdlog** (日志记录) 和 **glm** (数学库)。
|
||||||
|
|
||||||
|
2. 使用Visual Studio Installer安装的vcpkg
|
||||||
|
- 使用Visual Studio打开项目,点击 工具-命令行-开发者命令提示/开发者 PowerShell,执行下列命令:
|
||||||
|
- vcpkg integrate install
|
||||||
|
- (可选)执行下列命令,编译会自动执行
|
||||||
|
- vcpkg install
|
||||||
|
|
||||||
## 三、使用 Visual Studio 构建项目
|
## 三、使用 Visual Studio 构建项目
|
||||||
|
|
||||||
一旦依赖库安装完毕,你可以直接在 Visual Studio 中打开并构建项目。
|
一旦依赖库安装完毕,你可以直接在 Visual Studio 中打开并构建项目。
|
||||||
|
|||||||
7
Vivid2DRenderer/libs/logger/build spdlog.cmd
Normal file
7
Vivid2DRenderer/libs/logger/build spdlog.cmd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
rem Build debug version
|
||||||
|
cl /c /Od /MDd /Zi /D_DEBUG /DUSE_SPDLOG /EHsc /std:c++17 /I include /I..\..\vcpkg_installed\x64-windows\include src\Logger.cpp /Fo:build\Debugx64\Logger_d.obj /utf-8 /Fd:build\Debugx64\Logger_d.pdb
|
||||||
|
lib /NOLOGO /OUT:build\Debugx64\Logger_d.lib build\Debugx64\Logger_d.obj
|
||||||
|
|
||||||
|
rem Build release version
|
||||||
|
cl /c /O2 /MD /DNDEBUG /DUSE_SPDLOG /EHsc /std:c++17 /I include /I..\..\vcpkg_installed\x64-windows\include src\Logger.cpp /Fo:build\Releasex64\Logger.obj /utf-8 /Fd:build\Releasex64\Logger.pdb
|
||||||
|
lib /NOLOGO /OUT:build\Releasex64\Logger.lib build\Releasex64\Logger.obj
|
||||||
BIN
Vivid2DRenderer/libs/logger/build/Debugx64/Logger_d.lib
Normal file
BIN
Vivid2DRenderer/libs/logger/build/Debugx64/Logger_d.lib
Normal file
Binary file not shown.
BIN
Vivid2DRenderer/libs/logger/build/Releasex64/Logger.lib
Normal file
BIN
Vivid2DRenderer/libs/logger/build/Releasex64/Logger.lib
Normal file
Binary file not shown.
295
Vivid2DRenderer/libs/logger/include/Logger.h
Normal file
295
Vivid2DRenderer/libs/logger/include/Logger.h
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
// C++ 标准库版本判断
|
||||||
|
#if __cplusplus >= 202002L && defined(USE_STD_FORMAT)
|
||||||
|
// C++20 或更高版本
|
||||||
|
#include <format>
|
||||||
|
namespace LoggerFormatNS = std;
|
||||||
|
#else
|
||||||
|
#include <fmt/core.h> // 仅基础格式化
|
||||||
|
#include <fmt/format.h> // 完整功能
|
||||||
|
namespace LoggerFormatNS = fmt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
// 用于支持 << 流式传递打印日志
|
||||||
|
// LoggerStream.h
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
|
// 日志打印等级
|
||||||
|
enum class LogLevel : int
|
||||||
|
{
|
||||||
|
trace,
|
||||||
|
debug,
|
||||||
|
info,
|
||||||
|
warning,
|
||||||
|
error,
|
||||||
|
critical,
|
||||||
|
off
|
||||||
|
};
|
||||||
|
// 日志打印的颜色模式(如黑白或彩色)
|
||||||
|
enum class LogColorMode : int
|
||||||
|
{
|
||||||
|
automatic,
|
||||||
|
always,
|
||||||
|
never
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoggerInterface; // 前置声明
|
||||||
|
class Logger;
|
||||||
|
// 辅助类:流式日志打印
|
||||||
|
class LoggerStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoggerStream(LoggerInterface *logger, std::function<void(const std::string &)> log_func)
|
||||||
|
: logger(logger), logFunc(log_func) {}
|
||||||
|
|
||||||
|
// 允许移动
|
||||||
|
LoggerStream(LoggerStream &&) noexcept = default;
|
||||||
|
LoggerStream &operator=(LoggerStream &&) noexcept = default;
|
||||||
|
|
||||||
|
// 禁止拷贝
|
||||||
|
LoggerStream(const LoggerStream &) = delete;
|
||||||
|
LoggerStream &operator=(const LoggerStream &) = delete;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
LoggerStream &operator<<(const T &value)
|
||||||
|
{
|
||||||
|
ss << value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LoggerStream()
|
||||||
|
{
|
||||||
|
logFunc(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LoggerInterface *logger;
|
||||||
|
std::function<void(const std::string &)> logFunc;
|
||||||
|
std::stringstream ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
//class FormatterInterface
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// virtual ~FormatterInterface() = default;
|
||||||
|
// virtual std::string format(const std::string& fmt, ...) = 0;
|
||||||
|
//};
|
||||||
|
//class DefaultFormatter : public FormatterInterface
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// std::string format(const std::string& fmt, ...) override {
|
||||||
|
// va_list args;
|
||||||
|
// va_start(args, fmt);
|
||||||
|
// std::string formatted = LoggerFormatNS::vformat(fmt, fmt::make_format_args(args));
|
||||||
|
// va_end(args);
|
||||||
|
// return formatted;
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
class LoggerSinkInterface {
|
||||||
|
protected:
|
||||||
|
std::string m_pattern;
|
||||||
|
LogLevel m_level;
|
||||||
|
friend class Logger;
|
||||||
|
virtual std::any getBaseSink() = 0;
|
||||||
|
public:
|
||||||
|
virtual ~LoggerSinkInterface() = default;
|
||||||
|
virtual void flush() noexcept(false) = 0;
|
||||||
|
virtual void setPattern(const std::string& pattern) = 0;
|
||||||
|
virtual std::string pattern() const = 0;
|
||||||
|
virtual void setLevel(LogLevel level) = 0;
|
||||||
|
virtual LogLevel level() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 预留了两种打印方法的 Sink 实现,要求每个日志系统都要实现这两种 Sink
|
||||||
|
// 也可以自定义更多 Sink 实现类
|
||||||
|
class ConsoleLoggerSink : public LoggerSinkInterface {
|
||||||
|
protected:
|
||||||
|
virtual std::any getBaseSink();
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> pImpl;
|
||||||
|
LogColorMode m_colorMode;
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef std::uint16_t LogColor;
|
||||||
|
#else
|
||||||
|
typedef std::string_view LogColor;
|
||||||
|
#endif
|
||||||
|
LogColor m_color;
|
||||||
|
public:
|
||||||
|
virtual void flush() noexcept(false);
|
||||||
|
virtual void setPattern(const std::string& pattern);
|
||||||
|
virtual std::string pattern() const;
|
||||||
|
virtual void setLevel(LogLevel level);
|
||||||
|
virtual LogLevel level() const;
|
||||||
|
explicit ConsoleLoggerSink(const std::string& name, LogColorMode colorMode = LogColorMode::automatic);
|
||||||
|
void setColorMode(LogColorMode colorMode);
|
||||||
|
void setColor(LogLevel level, LogColor colorCode);
|
||||||
|
//LogColorMode getColorMode() const;
|
||||||
|
//std::string_view getColor(LogLevel level) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileLoggerSink : public LoggerSinkInterface {
|
||||||
|
protected:
|
||||||
|
virtual std::any getBaseSink();
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> pImpl;
|
||||||
|
public:
|
||||||
|
struct FileEventHandler {
|
||||||
|
std::function<void(const std::string& filename)> beforeOpen = nullptr;
|
||||||
|
std::function<void(const std::string& filename, std::FILE* fileStream)> afterOpen = nullptr;
|
||||||
|
std::function<void(const std::string& filename, std::FILE* fileStream)> beforeClose = nullptr;
|
||||||
|
std::function<void(const std::string& filename)> afterClose = nullptr;
|
||||||
|
};
|
||||||
|
explicit FileLoggerSink(const std::string& name, bool truncate = false, FileEventHandler eventHandler = FileEventHandler());
|
||||||
|
virtual void flush() noexcept(false) = 0;
|
||||||
|
virtual void setPattern(const std::string& pattern);
|
||||||
|
virtual std::string pattern() const;
|
||||||
|
virtual void setLevel(LogLevel level);
|
||||||
|
virtual LogLevel level() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 日志打印器接口
|
||||||
|
class LoggerInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~LoggerInterface() = default;
|
||||||
|
virtual void setLevel(LogLevel level) noexcept(false) = 0;
|
||||||
|
virtual void setGlobalLevel(LogLevel level) noexcept(false) = 0;
|
||||||
|
virtual void level() const noexcept = 0;
|
||||||
|
virtual LoggerStream trace() noexcept = 0;
|
||||||
|
virtual LoggerStream debug() noexcept = 0;
|
||||||
|
virtual LoggerStream info() noexcept = 0;
|
||||||
|
virtual LoggerStream warning() noexcept = 0;
|
||||||
|
virtual LoggerStream error() noexcept = 0;
|
||||||
|
virtual LoggerStream critical() noexcept = 0;
|
||||||
|
virtual void trace(const std::string &msg) noexcept = 0;
|
||||||
|
virtual void debug(const std::string &msg) noexcept = 0;
|
||||||
|
virtual void info(const std::string &msg) noexcept = 0;
|
||||||
|
virtual void warning(const std::string &msg) noexcept = 0;
|
||||||
|
virtual void error(const std::string &msg) noexcept = 0;
|
||||||
|
virtual void critical(const std::string &msg) noexcept = 0;
|
||||||
|
// fmt + args
|
||||||
|
template <typename... Args>
|
||||||
|
void trace(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::trace, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void debug(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::debug, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void info(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::info, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void warning(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::warning, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void error(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::error, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void critical(const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
_loggerHelper(&LoggerInterface::critical, fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename... Args>
|
||||||
|
void _loggerHelper(void (LoggerInterface::*func)(const std::string &), const std::string &fmt, Args &&...args) noexcept {
|
||||||
|
std::string formattedMsg = LoggerFormatNS::format(fmt, std::forward<Args>(args)...);
|
||||||
|
// 处理后交给具体的日志实现
|
||||||
|
(this->*func)(formattedMsg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 错误码
|
||||||
|
typedef int LoggerErrorCodeType;
|
||||||
|
enum class LoggerErrorCode : LoggerErrorCodeType
|
||||||
|
{
|
||||||
|
OK = 0,
|
||||||
|
Unknown = 1,
|
||||||
|
SinkNotInitialized = 2,
|
||||||
|
PatternSetFailed = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义日志抛出的错误
|
||||||
|
class LoggerException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string msg;
|
||||||
|
LoggerErrorCode eCode;
|
||||||
|
public:
|
||||||
|
explicit LoggerException(LoggerErrorCode code, const std::string& message) : std::exception(message.c_str()), msg(message), eCode(code) {}
|
||||||
|
char const* what() const override {
|
||||||
|
return this->msg.c_str();
|
||||||
|
}
|
||||||
|
LoggerErrorCode code() const {
|
||||||
|
return this->eCode;
|
||||||
|
}
|
||||||
|
std::string toString() const {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
LoggerErrorCodeType toLoggerErrorCodeType() const {
|
||||||
|
return static_cast<LoggerErrorCodeType>(eCode);
|
||||||
|
}
|
||||||
|
operator std::string() const {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
operator LoggerErrorCode() const {
|
||||||
|
return eCode;
|
||||||
|
}
|
||||||
|
operator LoggerErrorCodeType() const {
|
||||||
|
return static_cast<LoggerErrorCodeType>(eCode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 日志打印器
|
||||||
|
class Logger : public LoggerInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class LoggerImpl;
|
||||||
|
std::unique_ptr<LoggerImpl> pImpl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 默认构造:仅使用ConsoleLoggerSink
|
||||||
|
explicit Logger(const std::string &name);
|
||||||
|
// 带有自定义 Sink 列表的构造函数
|
||||||
|
template <typename SinksIterator>
|
||||||
|
explicit Logger(const std::string &name, SinksIterator&& sinksBegin, SinksIterator&& sinksEnd);
|
||||||
|
explicit Logger(const std::string &name, std::vector<std::shared_ptr<LoggerSinkInterface>> sinks)
|
||||||
|
: Logger(name, sinks.begin(), sinks.end()) {}
|
||||||
|
~Logger();
|
||||||
|
void setGlobalLevel(LogLevel level) noexcept(false) override;
|
||||||
|
void setLevel(LogLevel level) noexcept(false) override;
|
||||||
|
// 流式日志打印
|
||||||
|
LoggerStream trace() noexcept override;
|
||||||
|
LoggerStream debug() noexcept override;
|
||||||
|
LoggerStream info() noexcept override;
|
||||||
|
LoggerStream warning() noexcept override;
|
||||||
|
LoggerStream error() noexcept override;
|
||||||
|
LoggerStream critical() noexcept override;
|
||||||
|
void trace(const std::string &msg) noexcept override;
|
||||||
|
void debug(const std::string &msg) noexcept override;
|
||||||
|
void info(const std::string &msg) noexcept override;
|
||||||
|
void warning(const std::string &msg) noexcept override;
|
||||||
|
void error(const std::string &msg) noexcept override;
|
||||||
|
void critical(const std::string &msg) noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !LOGGER_H
|
||||||
|
|
||||||
36
Vivid2DRenderer/libs/logger/src/Logger.cpp
Normal file
36
Vivid2DRenderer/libs/logger/src/Logger.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include <Logger.h>
|
||||||
|
// 流传递无参日志打印
|
||||||
|
LoggerStream Logger::trace() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->trace(msg); });
|
||||||
|
}
|
||||||
|
LoggerStream Logger::debug() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->debug(msg); });
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerStream Logger::info() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->info(msg); });
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerStream Logger::warning() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->warning(msg); });
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerStream Logger::error() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->error(msg); });
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerStream Logger::critical() noexcept
|
||||||
|
{
|
||||||
|
return LoggerStream(this, [this](const std::string& msg) { this->critical(msg); });
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SPDLOG
|
||||||
|
|
||||||
|
#include "LoggerSpdLog.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
320
Vivid2DRenderer/libs/logger/src/LoggerSpdLog.h
Normal file
320
Vivid2DRenderer/libs/logger/src/LoggerSpdLog.h
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Logger.h>
|
||||||
|
//#include "../include/Logger.h"
|
||||||
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/spdlog.h"
|
||||||
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/sinks/sink.h"
|
||||||
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/sinks/stdout_color_sinks.h"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
#include <spdlog/sinks/basic_file_sink.h>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
class SpdLogUtils {
|
||||||
|
public:
|
||||||
|
enum class SpdLogLevel : int
|
||||||
|
{
|
||||||
|
trace = SPDLOG_LEVEL_TRACE,
|
||||||
|
debug = SPDLOG_LEVEL_DEBUG,
|
||||||
|
info = SPDLOG_LEVEL_INFO,
|
||||||
|
warning = SPDLOG_LEVEL_WARN,
|
||||||
|
error = SPDLOG_LEVEL_ERROR,
|
||||||
|
critical = SPDLOG_LEVEL_CRITICAL,
|
||||||
|
off = SPDLOG_LEVEL_OFF
|
||||||
|
};
|
||||||
|
static SpdLogLevel logLevelToSpdLogLevel(LogLevel level) {
|
||||||
|
SpdLogLevel spdLevel = SpdLogLevel::trace;
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case LogLevel::trace:
|
||||||
|
spdLevel = SpdLogLevel::trace;
|
||||||
|
break;
|
||||||
|
case LogLevel::debug:
|
||||||
|
spdLevel = SpdLogLevel::debug;
|
||||||
|
break;
|
||||||
|
case LogLevel::info:
|
||||||
|
spdLevel = SpdLogLevel::info;
|
||||||
|
break;
|
||||||
|
case LogLevel::warning:
|
||||||
|
spdLevel = SpdLogLevel::warning;
|
||||||
|
break;
|
||||||
|
case LogLevel::error:
|
||||||
|
spdLevel = SpdLogLevel::error;
|
||||||
|
break;
|
||||||
|
case LogLevel::critical:
|
||||||
|
spdLevel = SpdLogLevel::critical;
|
||||||
|
break;
|
||||||
|
case LogLevel::off:
|
||||||
|
spdLevel = SpdLogLevel::off;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
spdLevel = SpdLogLevel::trace;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return spdLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef spdlog::color_mode SpdLogColorMode;
|
||||||
|
static SpdLogColorMode logColorModeToSpdLogColorMode(LogColorMode colorMode) {
|
||||||
|
SpdLogColorMode cm = SpdLogColorMode::automatic;
|
||||||
|
switch (colorMode)
|
||||||
|
{
|
||||||
|
case LogColorMode::automatic:
|
||||||
|
cm = SpdLogColorMode::automatic;
|
||||||
|
break;
|
||||||
|
case LogColorMode::always:
|
||||||
|
cm = SpdLogColorMode::always;
|
||||||
|
break;
|
||||||
|
case LogColorMode::never:
|
||||||
|
cm = SpdLogColorMode::never;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cm;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConsoleLoggerSink::Impl {
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
// spdlog sink
|
||||||
|
std::shared_ptr<spdlog::sinks::stdout_color_sink_mt> m_sink;
|
||||||
|
Impl(LogColorMode colorMode = LogColorMode::automatic)
|
||||||
|
: m_sink(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()) {
|
||||||
|
SpdLogUtils::SpdLogColorMode cm = SpdLogUtils::logColorModeToSpdLogColorMode(colorMode);
|
||||||
|
m_sink->set_color_mode(cm);
|
||||||
|
}
|
||||||
|
operator spdlog::sinks::sink& () {
|
||||||
|
return *m_sink;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ConsoleLoggerSink::ConsoleLoggerSink(const std::string& name, LogColorMode colorMode)
|
||||||
|
: pImpl(std::make_unique<Impl>(colorMode)), m_colorMode(colorMode) {}
|
||||||
|
std::any ConsoleLoggerSink::getBaseSink()
|
||||||
|
{
|
||||||
|
return std::any(pImpl->m_sink);
|
||||||
|
}
|
||||||
|
void ConsoleLoggerSink::flush() noexcept(false) {
|
||||||
|
pImpl->m_sink->flush();
|
||||||
|
}
|
||||||
|
void ConsoleLoggerSink::setPattern(const std::string& pattern) {
|
||||||
|
|
||||||
|
if (pImpl->m_sink)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
pImpl->m_sink->set_pattern(pattern);
|
||||||
|
m_pattern = pattern;
|
||||||
|
}
|
||||||
|
catch (const spdlog::spdlog_ex& ex)
|
||||||
|
{
|
||||||
|
throw LoggerException(LoggerErrorCode::PatternSetFailed, "Failed to set log pattern: " + std::string(ex.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
||||||
|
}
|
||||||
|
std::string ConsoleLoggerSink::pattern() const {
|
||||||
|
return m_pattern;
|
||||||
|
}
|
||||||
|
void ConsoleLoggerSink::setLevel(LogLevel level) {
|
||||||
|
if (pImpl->m_sink)
|
||||||
|
{
|
||||||
|
pImpl->m_sink->set_level(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)));
|
||||||
|
m_level = level;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
||||||
|
}
|
||||||
|
LogLevel ConsoleLoggerSink::level() const {
|
||||||
|
return m_level;
|
||||||
|
}
|
||||||
|
void ConsoleLoggerSink::setColorMode(LogColorMode colorMode) {
|
||||||
|
m_colorMode = colorMode;
|
||||||
|
}
|
||||||
|
void ConsoleLoggerSink::setColor(LogLevel level, LogColor colorCode) {
|
||||||
|
// 设置不同日志级别的颜色代码
|
||||||
|
if (pImpl->m_sink)
|
||||||
|
{
|
||||||
|
pImpl->m_sink->set_color(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)), colorCode);
|
||||||
|
m_color = colorCode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FileLoggerSink::Impl {
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
// spdlog sink
|
||||||
|
std::shared_ptr<spdlog::sinks::basic_file_sink_mt> m_sink;
|
||||||
|
Impl(const std::string& filePath, bool truncate, FileEventHandler evh) {
|
||||||
|
spdlog::file_event_handlers feh;
|
||||||
|
feh.before_open = evh.beforeOpen;
|
||||||
|
feh.after_open = evh.afterOpen;
|
||||||
|
feh.before_close = evh.beforeClose;
|
||||||
|
feh.after_close = evh.afterClose;
|
||||||
|
m_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filePath, truncate, feh);
|
||||||
|
}
|
||||||
|
operator spdlog::sinks::sink&() {
|
||||||
|
return *m_sink;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FileLoggerSink::FileLoggerSink(const std::string& name, bool truncate, FileEventHandler eventHandler)
|
||||||
|
: pImpl(std::make_unique<Impl>(name, truncate, eventHandler)) {}
|
||||||
|
std::any FileLoggerSink::getBaseSink()
|
||||||
|
{
|
||||||
|
return std::any(pImpl->m_sink);
|
||||||
|
}
|
||||||
|
void FileLoggerSink::flush() noexcept(false) {
|
||||||
|
pImpl->m_sink->flush();
|
||||||
|
}
|
||||||
|
void FileLoggerSink::setPattern(const std::string& pattern) {
|
||||||
|
if (pImpl->m_sink)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
pImpl->m_sink->set_pattern(pattern);
|
||||||
|
m_pattern = pattern;
|
||||||
|
}
|
||||||
|
catch (const spdlog::spdlog_ex& ex)
|
||||||
|
{
|
||||||
|
throw LoggerException(LoggerErrorCode::PatternSetFailed, "Failed to set log pattern: " + std::string(ex.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
||||||
|
}
|
||||||
|
std::string FileLoggerSink::pattern() const {
|
||||||
|
return m_pattern;
|
||||||
|
}
|
||||||
|
void FileLoggerSink::setLevel(LogLevel level) {
|
||||||
|
if (pImpl->m_sink)
|
||||||
|
{
|
||||||
|
pImpl->m_sink->set_level(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)));
|
||||||
|
m_level = level;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
||||||
|
}
|
||||||
|
LogLevel FileLoggerSink::level() const {
|
||||||
|
return m_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Logger::LoggerImpl {
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
std::shared_ptr<spdlog::logger> logger;
|
||||||
|
LoggerImpl(const std::string& name) {
|
||||||
|
logger = spdlog::get(name);
|
||||||
|
if (!logger)
|
||||||
|
{
|
||||||
|
logger = spdlog::stdout_color_mt(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename SinksIterator>
|
||||||
|
LoggerImpl(const std::string& name, SinksIterator&& begin, SinksIterator&& end) {
|
||||||
|
std::vector< std::shared_ptr<spdlog::sinks::sink>> sinks;
|
||||||
|
for (auto it = begin; it != end; ++it) {
|
||||||
|
auto sinkSharedPtr = (*it)->getBaseSink();
|
||||||
|
sinks.push_back(std::any_cast<std::shared_ptr<spdlog::sinks::sink>> (sinkSharedPtr));
|
||||||
|
}
|
||||||
|
logger = std::make_shared<spdlog::logger>(name, sinks.begin(), sinks.end());
|
||||||
|
if (logger)
|
||||||
|
spdlog::register_logger(logger);
|
||||||
|
}
|
||||||
|
~LoggerImpl() {
|
||||||
|
try {
|
||||||
|
logger->flush();
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
spdlog::drop(logger->name());
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Logger::Logger(const std::string &name) : pImpl(std::make_unique<Logger::LoggerImpl>(name))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
template <typename SinksIterator>
|
||||||
|
Logger::Logger(const std::string& name, SinksIterator&& sinksBegin, SinksIterator&& sinksEnd)
|
||||||
|
: pImpl(std::make_unique<Logger::LoggerImpl>(name, std::forward<SinksIterator>(sinksBegin), std::forward<SinksIterator>(sinksEnd)))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::setGlobalLevel(LogLevel level) noexcept(false)
|
||||||
|
{
|
||||||
|
SpdLogUtils::SpdLogLevel l = SpdLogUtils::logLevelToSpdLogLevel(level);
|
||||||
|
spdlog::set_level(static_cast<spdlog::level::level_enum>(l));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::setLevel(LogLevel level) noexcept(false)
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
SpdLogUtils::SpdLogLevel l = SpdLogUtils::logLevelToSpdLogLevel(level);
|
||||||
|
pImpl->logger->set_level(static_cast<spdlog::level::level_enum>(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 带参数日志打印
|
||||||
|
void Logger::trace(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->trace(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::debug(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->debug(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::info(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->info(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::warning(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->warn(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::error(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::critical(const std::string &msg) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->logger)
|
||||||
|
{
|
||||||
|
pImpl->logger->critical(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
118
Vivid2DRenderer/libs/logger/src/StringProcess.cpp
Normal file
118
Vivid2DRenderer/libs/logger/src/StringProcess.cpp
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#include "StringProcess.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
std::string wstr2str_2UTF8(std::wstring text)
|
||||||
|
{
|
||||||
|
CHAR* str;
|
||||||
|
int Tsize = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
std::string str1 = str;
|
||||||
|
delete[]str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
std::string wstr2str_2ANSI(std::wstring text)
|
||||||
|
{
|
||||||
|
CHAR* str;
|
||||||
|
int Tsize = WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
std::string str1 = str;
|
||||||
|
delete[]str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring str2wstr_2UTF8(std::string text)
|
||||||
|
{
|
||||||
|
WCHAR* str;
|
||||||
|
int Tsize = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, 0, 0);
|
||||||
|
str = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, str, Tsize);
|
||||||
|
std::wstring str1 = str;
|
||||||
|
delete[]str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring str2wstr_2ANSI(std::string text)
|
||||||
|
{
|
||||||
|
WCHAR* str;
|
||||||
|
int Tsize = MultiByteToWideChar(CP_ACP, 0, text.c_str(), -1, 0, 0);
|
||||||
|
str = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, text.c_str(), -1, str, Tsize);
|
||||||
|
std::wstring str1 = str;
|
||||||
|
delete[]str;
|
||||||
|
return str1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UTF8ToANSI(std::string utf8Text)
|
||||||
|
{
|
||||||
|
WCHAR* wstr;//中间量
|
||||||
|
CHAR* str;//转换后的
|
||||||
|
int Tsize = MultiByteToWideChar(CP_UTF8, 0, utf8Text.c_str(), -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, utf8Text.c_str(), -1, wstr, Tsize);
|
||||||
|
Tsize = WideCharToMultiByte(CP_ACP, 0, wstr, -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, Tsize, 0, 0);
|
||||||
|
std::string wstr1 = str;
|
||||||
|
delete[]str;
|
||||||
|
delete[]wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
std::string ANSIToUTF8(std::string ansiText)
|
||||||
|
{
|
||||||
|
WCHAR* wstr;//中间量
|
||||||
|
CHAR* str;//转换后的
|
||||||
|
int Tsize = MultiByteToWideChar(CP_ACP, 0, ansiText.c_str(), -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, ansiText.c_str(), -1, wstr, Tsize);
|
||||||
|
Tsize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, Tsize, 0, 0);
|
||||||
|
std::string wstr1 = str;
|
||||||
|
delete[]str;
|
||||||
|
delete[]wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring ANSIToUTF8(std::wstring ansiText)
|
||||||
|
{
|
||||||
|
CHAR* str;//中间量
|
||||||
|
WCHAR* wstr;//转换后的
|
||||||
|
int Tsize = WideCharToMultiByte(CP_ACP, 0, ansiText.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, ansiText.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
Tsize = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, Tsize);
|
||||||
|
std::wstring wstr1 = wstr;
|
||||||
|
delete[]str;
|
||||||
|
delete[]wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
std::wstring UTF8ToANSI(std::wstring utf8Text)
|
||||||
|
{
|
||||||
|
CHAR* str;//中间量
|
||||||
|
WCHAR* wstr;//转换后的
|
||||||
|
int Tsize = WideCharToMultiByte(CP_UTF8, 0, utf8Text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, utf8Text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
Tsize = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, Tsize);
|
||||||
|
std::wstring wstr1 = wstr;
|
||||||
|
delete[]str;
|
||||||
|
delete[]wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring boolToWString(bool Bool)
|
||||||
|
{
|
||||||
|
return (Bool ? L"true" : L"false");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string boolToString(bool Bool)
|
||||||
|
{
|
||||||
|
return (Bool ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
131
Vivid2DRenderer/libs/logger/src/StringProcess.h
Normal file
131
Vivid2DRenderer/libs/logger/src/StringProcess.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
inline std::string wstr2str_2UTF8(std::wstring text);
|
||||||
|
inline std::string wstr2str_2ANSI(std::wstring text);
|
||||||
|
inline std::wstring str2wstr_2UTF8(std::string text);
|
||||||
|
inline std::wstring str2wstr_2ANSI(std::string text);
|
||||||
|
inline std::string UTF8ToANSI(std::string utf8Text);
|
||||||
|
inline std::string ANSIToUTF8(std::string ansiText);
|
||||||
|
inline std::wstring ANSIToUTF8(std::wstring ansiText);
|
||||||
|
inline std::wstring UTF8ToANSI(std::wstring utf8Text);
|
||||||
|
|
||||||
|
inline std::wstring boolToWString(bool Bool);
|
||||||
|
inline std::string boolToString(bool Bool);
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
inline std::string wstr2str_2UTF8(std::wstring text)
|
||||||
|
{
|
||||||
|
CHAR *str;
|
||||||
|
int Tsize = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
std::string str1 = str;
|
||||||
|
delete[] str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
inline std::string wstr2str_2ANSI(std::wstring text)
|
||||||
|
{
|
||||||
|
CHAR *str;
|
||||||
|
int Tsize = WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
std::string str1 = str;
|
||||||
|
delete[] str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring str2wstr_2UTF8(std::string text)
|
||||||
|
{
|
||||||
|
WCHAR *str;
|
||||||
|
int Tsize = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, 0, 0);
|
||||||
|
str = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, str, Tsize);
|
||||||
|
std::wstring str1 = str;
|
||||||
|
delete[] str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring str2wstr_2ANSI(std::string text)
|
||||||
|
{
|
||||||
|
WCHAR *str;
|
||||||
|
int Tsize = MultiByteToWideChar(CP_ACP, 0, text.c_str(), -1, 0, 0);
|
||||||
|
str = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, text.c_str(), -1, str, Tsize);
|
||||||
|
std::wstring str1 = str;
|
||||||
|
delete[] str;
|
||||||
|
return str1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string UTF8ToANSI(std::string utf8Text)
|
||||||
|
{
|
||||||
|
WCHAR *wstr; // 中间量
|
||||||
|
CHAR *str; // 转换后的
|
||||||
|
int Tsize = MultiByteToWideChar(CP_UTF8, 0, utf8Text.c_str(), -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, utf8Text.c_str(), -1, wstr, Tsize);
|
||||||
|
Tsize = WideCharToMultiByte(CP_ACP, 0, wstr, -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, Tsize, 0, 0);
|
||||||
|
std::string wstr1 = str;
|
||||||
|
delete[] str;
|
||||||
|
delete[] wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
inline std::string ANSIToUTF8(std::string ansiText)
|
||||||
|
{
|
||||||
|
WCHAR *wstr; // 中间量
|
||||||
|
CHAR *str; // 转换后的
|
||||||
|
int Tsize = MultiByteToWideChar(CP_ACP, 0, ansiText.c_str(), -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, ansiText.c_str(), -1, wstr, Tsize);
|
||||||
|
Tsize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, Tsize, 0, 0);
|
||||||
|
std::string wstr1 = str;
|
||||||
|
delete[] str;
|
||||||
|
delete[] wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring ANSIToUTF8(std::wstring ansiText)
|
||||||
|
{
|
||||||
|
CHAR *str; // 中间量
|
||||||
|
WCHAR *wstr; // 转换后的
|
||||||
|
int Tsize = WideCharToMultiByte(CP_ACP, 0, ansiText.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, ansiText.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
Tsize = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, Tsize);
|
||||||
|
std::wstring wstr1 = wstr;
|
||||||
|
delete[] str;
|
||||||
|
delete[] wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
inline std::wstring UTF8ToANSI(std::wstring utf8Text)
|
||||||
|
{
|
||||||
|
CHAR *str; // 中间量
|
||||||
|
WCHAR *wstr; // 转换后的
|
||||||
|
int Tsize = WideCharToMultiByte(CP_UTF8, 0, utf8Text.c_str(), -1, 0, 0, 0, 0);
|
||||||
|
str = new CHAR[Tsize];
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, utf8Text.c_str(), -1, str, Tsize, 0, 0);
|
||||||
|
Tsize = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
|
||||||
|
wstr = new WCHAR[Tsize];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, Tsize);
|
||||||
|
std::wstring wstr1 = wstr;
|
||||||
|
delete[] str;
|
||||||
|
delete[] wstr;
|
||||||
|
return wstr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring boolToWString(bool Bool)
|
||||||
|
{
|
||||||
|
return (Bool ? L"true" : L"false");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string boolToString(bool Bool)
|
||||||
|
{
|
||||||
|
return (Bool ? "true" : "false");
|
||||||
|
}
|
||||||
@@ -18,191 +18,191 @@ namespace Vivid2D::Render::Texture
|
|||||||
class Texture;
|
class Texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> spdlog::logger <EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD><EFBFBD>а<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 向前声明 spdlog::logger 以避免在头文件中包含其完整定义
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
class logger;
|
class logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class RenderSystem
|
* @class RenderSystem
|
||||||
* @brief <EFBFBD>ṩһ<EFBFBD><EFBFBD><EFBFBD>̰߳<EFBFBD>ȫ<EFBFBD>ġ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> OpenGL API <EFBFBD><EFBFBD>װ<EFBFBD>㡣
|
* @brief 提供一个线程安全的、基于命令队列的 OpenGL API 封装层。
|
||||||
* @details
|
* @details
|
||||||
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD>ּ࣬<EFBFBD>ڽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><EFBFBD>̵߳<EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ר<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǡ<EFBFBD>
|
* 这是一个完全静态的类,旨在将来自任何线程的渲染调用排队,并在一个专用的渲染线程上执行它们。
|
||||||
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̰߳<DFB3>ȫ<EFBFBD>ԡ<EFBFBD><D4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD>˶<EFBFBD> OpenGL ״̬<D7B4><CCAC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* 这样做可以确保所有 OpenGL 操作的线程安全性。它还提供了对 OpenGL 状态、着色器、缓冲区和纹理的
|
||||||
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD>Լ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD>ԵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
* 高级管理功能,以及一个用于调试的错误检查机制。
|
||||||
* ʹ<EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̻߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD>е<EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RenderSystem::drawElements<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* 使用方法:在主线程或其他逻辑线程中调用公开的静态方法(如 RenderSystem::drawElements),
|
||||||
* <EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ὣ<EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̵߳<EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RenderSystem::replayQueue()
|
* 这些方法会将渲染命令记录到队列中。在渲染线程的循环中,调用 RenderSystem::replayQueue()
|
||||||
* <EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* 来执行所有排队的命令。
|
||||||
*/
|
*/
|
||||||
class VIVID_2D_MYDLL_API RenderSystem {
|
class VIVID_2D_MYDLL_API RenderSystem {
|
||||||
public:
|
public:
|
||||||
// RenderSystem <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>࣬<EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD>ֹʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// RenderSystem 是一个静态工具类,因此禁止实例化。
|
||||||
RenderSystem() = delete;
|
RenderSystem() = delete;
|
||||||
~RenderSystem() = delete;
|
~RenderSystem() = delete;
|
||||||
RenderSystem(const RenderSystem&) = delete;
|
RenderSystem(const RenderSystem&) = delete;
|
||||||
RenderSystem& operator=(const RenderSystem&) = delete;
|
RenderSystem& operator=(const RenderSystem&) = delete;
|
||||||
using GLADloader = void* (*)(const char* name);
|
using GLADloader = void* (*)(const char* name);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>־ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 日志系统管理 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼʱ<EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
* @brief 初始化日志系统。必须在任何日志调用之前,在主函数开始时调用。
|
||||||
*/
|
*/
|
||||||
static void InitializeLogging();
|
static void InitializeLogging();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD>־ϵͳ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD>¡<EFBFBD>
|
* @brief 关闭日志系统。应在主函数结束时调用以确保所有日志都被刷新。
|
||||||
*/
|
*/
|
||||||
static void ShutdownLogging();
|
static void ShutdownLogging();
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̹߳<EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 初始化与线程管理 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ר<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̡߳<EFBFBD>
|
* @brief 初始化并启动专用的渲染线程。
|
||||||
*/
|
*/
|
||||||
static void initRenderThread();
|
static void initRenderThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>Ⱦϵͳ<EFBFBD>ij<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Ρ<EFBFBD><EFBFBD>ڴ˽Σ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>С<EFBFBD>
|
* @brief 开始渲染系统的初始化阶段。在此阶段,调用可以直接在调用线程上执行。
|
||||||
*/
|
*/
|
||||||
static void beginInitialization();
|
static void beginInitialization();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦϵͳ<EFBFBD>ij<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Ρ<EFBFBD><EFBFBD>˺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷӡ<EFBFBD>
|
* @brief 结束渲染系统的初始化阶段。此后,所有调用都将被排队。
|
||||||
*/
|
*/
|
||||||
static void finishInitialization();
|
static void finishInitialization();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鵱ǰ<EFBFBD>߳<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̡߳<EFBFBD>
|
* @brief 检查当前线程是否是渲染线程。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̣߳<EFBFBD><EFBFBD><EFBFBD> true<EFBFBD><EFBFBD>
|
* @return 如果是渲染线程,则返回 true。
|
||||||
*/
|
*/
|
||||||
static bool isOnRenderThread();
|
static bool isOnRenderThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鵱ǰ<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Ρ<EFBFBD>
|
* @brief 检查当前是否处于初始化阶段。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD> true<EFBFBD><EFBFBD>
|
* @return 如果是初始化阶段,则返回 true。
|
||||||
*/
|
*/
|
||||||
static bool isInInitPhase();
|
static bool isInInitPhase();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ǰ<EFBFBD>̱߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̣߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>
|
* @brief 断言当前线程必须是渲染线程,否则程序将中止。
|
||||||
*/
|
*/
|
||||||
static void assertOnRenderThread();
|
static void assertOnRenderThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ǰ<EFBFBD>̱߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̻߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Ρ<EFBFBD>
|
* @brief 断言当前线程必须是渲染线程或处于初始化阶段。
|
||||||
*/
|
*/
|
||||||
static void assertOnRenderThreadOrInit();
|
static void assertOnRenderThreadOrInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ʹ<EFBFBD><EFBFBD> GLAD <EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>롣
|
* @brief 使用 GLAD 加载 OpenGL 函数指针。
|
||||||
* @param loader һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>룬<EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD>ȡ OpenGL <20><><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> glfwGetProcAddress<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param loader 一个函数指针,用于获取 OpenGL 函数的地址(例如 glfwGetProcAddress)。
|
||||||
*/
|
*/
|
||||||
static void loadGLFunctions(GLADloader loader);
|
static void loadGLFunctions(GLADloader loader);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 渲染命令队列 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD>Ϊ lambda <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3>Ա<EFBFBD><D4B1>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD>ִ<EFBFBD>С<EFBFBD>
|
* @brief 将一个渲染调用(作为 lambda 函数)记录到命令队列中,以便稍后在渲染线程上执行。
|
||||||
* @param renderCall Ҫִ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param renderCall 要执行的渲染操作。
|
||||||
*/
|
*/
|
||||||
static void recordRenderCall(std::function<void()>&& renderCall);
|
static void recordRenderCall(std::function<void()>&& renderCall);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
* @brief 在渲染线程上执行命令队列中的所有待处理渲染调用。
|
||||||
*/
|
*/
|
||||||
static void replayQueue();
|
static void replayQueue();
|
||||||
|
|
||||||
// ================== OpenGL ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ ==================
|
// ================== OpenGL 状态管理封装 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GL_BLEND<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 启用一个 OpenGL 功能(例如 GL_BLEND)。
|
||||||
* @param capability Ҫ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>١<EFBFBD>
|
* @param capability 要启用的 OpenGL 功能枚举。
|
||||||
*/
|
*/
|
||||||
static void enable(GLenum capability);
|
static void enable(GLenum capability);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD>ܡ<EFBFBD>
|
* @brief 禁用一个 OpenGL 功能。
|
||||||
* @param capability Ҫ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>١<EFBFBD>
|
* @param capability 要禁用的 OpenGL 功能枚举。
|
||||||
*/
|
*/
|
||||||
static void disable(GLenum capability);
|
static void disable(GLenum capability);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD><EFBFBD>ӿڵȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>
|
* @brief 将当前的渲染状态(如着色器、混合、视口等)推入状态堆栈。
|
||||||
*/
|
*/
|
||||||
static void pushState();
|
static void pushState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD>ջ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ״̬<EFBFBD><EFBFBD>
|
* @brief 从状态堆栈中弹出并恢复上一个渲染状态。
|
||||||
*/
|
*/
|
||||||
static void popState();
|
static void popState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ״̬<EFBFBD><EFBFBD>ջ<EFBFBD>Ĵ<EFBFBD>С<EFBFBD><EFBFBD>
|
* @brief 获取当前状态堆栈的大小。
|
||||||
* @return <EFBFBD><EFBFBD>ջ<EFBFBD>е<EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 堆栈中的状态数量。
|
||||||
*/
|
*/
|
||||||
static size_t getStateStackSize();
|
static size_t getStateStackSize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>
|
* @brief 设置清屏颜色。
|
||||||
*/
|
*/
|
||||||
static void clearColor(float r, float g, float b, float a);
|
static void clearColor(float r, float g, float b, float a);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GL_COLOR_BUFFER_BIT<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 清除指定的缓冲区(例如 GL_COLOR_BUFFER_BIT)。
|
||||||
* @param mask Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>롣
|
* @param mask 要清除的缓冲区的位域掩码。
|
||||||
*/
|
*/
|
||||||
static void clear(GLbitfield mask);
|
static void clear(GLbitfield mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <EFBFBD>ӿڡ<EFBFBD>
|
* @brief 设置 OpenGL 视口。
|
||||||
*/
|
*/
|
||||||
static void viewport(int x, int y, int width, int height);
|
static void viewport(int x, int y, int width, int height);
|
||||||
|
|
||||||
// ================== VAO / VBO / EBO <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== VAO / VBO / EBO 操作 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (VAO)<EFBFBD><EFBFBD>
|
* @brief 生成一个顶点数组对象 (VAO)。
|
||||||
* @return <EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD>
|
* @return 新创建的 VAO 的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint GenVertexArrays();
|
static GLuint GenVertexArrays();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> VAO<EFBFBD><EFBFBD>
|
* @brief 删除一个 VAO。
|
||||||
* @param vao Ҫɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD>
|
* @param vao 要删除的 VAO 的句柄。
|
||||||
*/
|
*/
|
||||||
static void DeleteVertexArrays(GLuint vao);
|
static void DeleteVertexArrays(GLuint vao);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> VAO<EFBFBD><EFBFBD>
|
* @brief 绑定一个 VAO。
|
||||||
* @param vao Ҫ<EFBFBD><EFBFBD> VAO <EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param vao 要绑定的 VAO 的句柄。
|
||||||
*/
|
*/
|
||||||
static void BindVertexArray(GLuint vao);
|
static void BindVertexArray(GLuint vao);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (VBO/EBO)<EFBFBD><EFBFBD>
|
* @brief 生成一个缓冲区对象 (VBO/EBO)。
|
||||||
* @return <EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 新创建的缓冲区的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint GenBuffers();
|
static GLuint GenBuffers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 删除一个缓冲区对象。
|
||||||
* @param buffer Ҫɾ<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param buffer 要删除的缓冲区的句柄。
|
||||||
*/
|
*/
|
||||||
static void DeleteBuffers(GLuint buffer);
|
static void DeleteBuffers(GLuint buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 绑定一个缓冲区对象。
|
||||||
* @param target <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> GL_ARRAY_BUFFER)<EFBFBD><EFBFBD>
|
* @param target 缓冲区的目标 (例如 GL_ARRAY_BUFFER)。
|
||||||
* @param buffer Ҫ<EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param buffer 要绑定的缓冲区的句柄。
|
||||||
*/
|
*/
|
||||||
static void BindBuffer(GLenum target, GLuint buffer);
|
static void BindBuffer(GLenum target, GLuint buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 将数据上传到当前绑定的缓冲区。
|
||||||
* @param target <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ꡣ
|
* @param target 缓冲区目标。
|
||||||
* @param size <EFBFBD><EFBFBD><EFBFBD>ݵĴ<EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param size 数据的大小(以字节为单位)。
|
||||||
* @param data ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD>롣
|
* @param data 指向数据的指针。
|
||||||
* @param usage <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>; (<28><><EFBFBD><EFBFBD> GL_STATIC_DRAW)<EFBFBD><EFBFBD>
|
* @param usage 数据的预期用途 (例如 GL_STATIC_DRAW)。
|
||||||
*/
|
*/
|
||||||
static void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
static void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||||
|
|
||||||
// ================== Uniform <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== Uniform 设置 ==================
|
||||||
static void uniform1i(GLint location, int value);
|
static void uniform1i(GLint location, int value);
|
||||||
static void uniform1f(GLint location, float value);
|
static void uniform1f(GLint location, float value);
|
||||||
static void uniform2f(GLint location, float x, float y);
|
static void uniform2f(GLint location, float x, float y);
|
||||||
@@ -217,184 +217,184 @@ public:
|
|||||||
static void uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose = false);
|
static void uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> uniform <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>á<EFBFBD>
|
* @brief 获取着色器程序中 uniform 变量的位置。
|
||||||
* @param program <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param program 着色器程序的句柄。
|
||||||
* @param name uniform <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
* @param name uniform 变量的名称。
|
||||||
* @return uniform <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>á<EFBFBD>
|
* @return uniform 变量的位置。
|
||||||
*/
|
*/
|
||||||
static GLint getUniformLocation(GLuint program, const std::string& name);
|
static GLint getUniformLocation(GLuint program, const std::string& name);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 绘制命令 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><EFBFBD><EFBFBD>
|
* @brief 设置线宽。
|
||||||
*/
|
*/
|
||||||
static void lineWidth(float width);
|
static void lineWidth(float width);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD>ơ<EFBFBD>
|
* @brief 使用索引进行绘制。
|
||||||
*/
|
*/
|
||||||
static void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
static void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ֱ<EFBFBD><EFBFBD>ʹ<EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD>ơ<EFBFBD>
|
* @brief 直接使用顶点数组进行绘制。
|
||||||
*/
|
*/
|
||||||
static void drawArrays(GLenum mode, GLint first, GLsizei count);
|
static void drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ ==================
|
// ================== 混合模式 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ϡ<EFBFBD>
|
* @brief 启用混合。
|
||||||
*/
|
*/
|
||||||
static void enableBlend();
|
static void enableBlend();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ϡ<EFBFBD>
|
* @brief 禁用混合。
|
||||||
*/
|
*/
|
||||||
static void disableBlend();
|
static void disableBlend();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>Ϻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 设置混合函数。
|
||||||
*/
|
*/
|
||||||
static void blendFunc(GLenum sfactor, GLenum dfactor);
|
static void blendFunc(GLenum sfactor, GLenum dfactor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD> Alpha <20><><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD> (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)<EFBFBD><EFBFBD>
|
* @brief 设置默认的 Alpha 混合函数 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)。
|
||||||
*/
|
*/
|
||||||
static void defaultBlendFunc();
|
static void defaultBlendFunc();
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 着色器程序管理 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 创建一个空的着色器程序。
|
||||||
* @return <EFBFBD>³<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 新程序的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint createProgram();
|
static GLuint createProgram();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 获取当前绑定的着色器程序。
|
||||||
* @return <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 当前程序的句柄。
|
||||||
*/
|
*/
|
||||||
static GLint getCurrentProgram();
|
static GLint getCurrentProgram();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 将一个着色器附加到着色器程序。
|
||||||
*/
|
*/
|
||||||
static void attachShader(GLuint program, GLuint shader);
|
static void attachShader(GLuint program, GLuint shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 链接一个着色器程序。
|
||||||
*/
|
*/
|
||||||
static void linkProgram(GLuint program);
|
static void linkProgram(GLuint program);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 获取着色器程序的参数。
|
||||||
*/
|
*/
|
||||||
static GLint getProgrami(GLuint program, GLenum pname);
|
static GLint getProgrami(GLuint program, GLenum pname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>
|
* @brief 获取着色器程序的日志信息。
|
||||||
*/
|
*/
|
||||||
static std::string getProgramInfoLog(GLuint program);
|
static std::string getProgramInfoLog(GLuint program);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD>ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 从程序中分离一个着色器。
|
||||||
*/
|
*/
|
||||||
static void detachShader(GLuint program, GLuint shader);
|
static void detachShader(GLuint program, GLuint shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 删除一个着色器程序。
|
||||||
*/
|
*/
|
||||||
static void deleteProgram(GLuint program);
|
static void deleteProgram(GLuint program);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 链接顶点和片段着色器以创建一个完整的程序。
|
||||||
*/
|
*/
|
||||||
static GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);
|
static GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD>㡢<EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 链接顶点、几何和片段着色器以创建一个完整的程序。
|
||||||
*/
|
*/
|
||||||
static GLuint linkProgram(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader);
|
static GLuint linkProgram(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 激活一个着色器程序。
|
||||||
*/
|
*/
|
||||||
static void useProgram(GLuint program);
|
static void useProgram(GLuint program);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 着色器管理 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 创建一个指定类型的着色器对象。
|
||||||
* @param type <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> GL_VERTEX_SHADER)<EFBFBD><EFBFBD>
|
* @param type 着色器类型 (例如 GL_VERTEX_SHADER)。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 新着色器对象的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint createShader(GLenum type);
|
static GLuint createShader(GLenum type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ϊ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>롣
|
* @brief 为着色器设置源代码。
|
||||||
*/
|
*/
|
||||||
static void shaderSource(GLuint shader, const std::string& source);
|
static void shaderSource(GLuint shader, const std::string& source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 编译一个着色器。
|
||||||
*/
|
*/
|
||||||
static void compileShader(GLuint shader);
|
static void compileShader(GLuint shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 获取着色器的参数。
|
||||||
*/
|
*/
|
||||||
static GLint getShaderi(GLuint shader, GLenum pname);
|
static GLint getShaderi(GLuint shader, GLenum pname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>
|
* @brief 获取着色器的日志信息。
|
||||||
*/
|
*/
|
||||||
static std::string getShaderInfoLog(GLuint shader);
|
static std::string getShaderInfoLog(GLuint shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 删除一个着色器。
|
||||||
*/
|
*/
|
||||||
static void deleteShader(GLuint shader);
|
static void deleteShader(GLuint shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 从源代码编译一个指定类型的着色器。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 编译后的着色器句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint compileShader(GLenum type, const std::string& source);
|
static GLuint compileShader(GLenum type, const std::string& source);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 深度测试 ==================
|
||||||
static void depthFunc(GLenum func);
|
static void depthFunc(GLenum func);
|
||||||
static void depthMask(bool flag);
|
static void depthMask(bool flag);
|
||||||
static void clearDepth(double depth);
|
static void clearDepth(double depth);
|
||||||
static void enableDepthTest();
|
static void enableDepthTest();
|
||||||
static void disableDepthTest();
|
static void disableDepthTest();
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 纹理管理 ==================
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> 2D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EEB6AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
|
* @brief 绑定一个 2D 纹理到当前活动的纹理单元。
|
||||||
* @param texture Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param texture 要绑定的纹理的句柄。
|
||||||
*/
|
*/
|
||||||
static void bindTexture(GLuint texture);
|
static void bindTexture(GLuint texture);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> Texture <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
|
* @brief 绑定一个 Texture 对象到指定的纹理单元。
|
||||||
* @details <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>Ͱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD>Ϊһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @details 这是一个便利方法,它将激活纹理单元和绑定纹理两个操作合并为一个命令,
|
||||||
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD>ύ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̡߳<EFBFBD>
|
* 并安全地提交到渲染线程。
|
||||||
* @param texture Ҫ<EFBFBD><EFBFBD> Texture <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
* @param texture 要绑定的 Texture 对象的常量引用。
|
||||||
* @param textureUnit Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> (0, 1, 2, ...)<EFBFBD><EFBFBD>
|
* @param textureUnit 要绑定的纹理单元索引 (0, 1, 2, ...)。
|
||||||
*/
|
*/
|
||||||
static void bindTexture(const Vivid2D::Render::Texture::Texture& texture, int textureUnit = 0);
|
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);
|
static void getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
|
* @brief 激活一个纹理单元。
|
||||||
* @param texture Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ (<28><><EFBFBD><EFBFBD> GL_TEXTURE0)<EFBFBD><EFBFBD>
|
* @param texture 要激活的纹理单元 (例如 GL_TEXTURE0)。
|
||||||
*/
|
*/
|
||||||
static void activeTexture(GLenum texture);
|
static void activeTexture(GLenum texture);
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 生成一个纹理对象。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 新纹理的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint genTextures();
|
static GLuint genTextures();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 删除一个纹理对象。
|
||||||
* @param texture Ҫɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @param texture 要删除的纹理的句柄。
|
||||||
*/
|
*/
|
||||||
static void deleteTextures(GLuint 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 texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
|
||||||
@@ -405,20 +405,20 @@ public:
|
|||||||
static void setTextureWrapT(GLenum wrap);
|
static void setTextureWrapT(GLenum wrap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD> 1x1 <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 创建一个默认的 1x1 白色纹理。
|
||||||
* @return Ĭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @return 默认纹理的句柄。
|
||||||
*/
|
*/
|
||||||
static GLuint createDefaultTexture();
|
static GLuint createDefaultTexture();
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 顶点属性 ==================
|
||||||
static void enableVertexAttribArray(GLuint index);
|
static void enableVertexAttribArray(GLuint index);
|
||||||
static void disableVertexAttribArray(GLuint index);
|
static void disableVertexAttribArray(GLuint index);
|
||||||
static void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
|
static void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD><EFBFBD>߷<EFBFBD><EFBFBD><EFBFBD> ==================
|
// ================== 工具方法 ==================
|
||||||
static void readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
|
static void readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>֧<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD>
|
* @brief 检查是否支持某个 OpenGL 扩展。
|
||||||
*/
|
*/
|
||||||
static bool isExtensionSupported(const std::string& extension);
|
static bool isExtensionSupported(const std::string& extension);
|
||||||
static void pixelStore(GLenum pname, GLint param);
|
static void pixelStore(GLenum pname, GLint param);
|
||||||
@@ -428,35 +428,35 @@ public:
|
|||||||
static std::string getGLSLVersion();
|
static std::string getGLSLVersion();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD> OpenGL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
|
* @brief 记录详细的 OpenGL 和驱动信息。
|
||||||
*/
|
*/
|
||||||
static void logDetailedGLInfo();
|
static void logDetailedGLInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD> OpenGL ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
* @brief 设置一套默认的 OpenGL 状态(例如启用混合,设置清屏色)。
|
||||||
*/
|
*/
|
||||||
static void setupDefaultState();
|
static void setupDefaultState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鲢<EFBFBD><EFBFBD>¼<EFBFBD>κη<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 检查并记录任何发生的 OpenGL 错误。
|
||||||
* @param operation <EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
* @param operation 导致检查的操作的描述性名称。
|
||||||
*/
|
*/
|
||||||
static void checkGLError(const std::string& operation);
|
static void checkGLError(const std::string& operation);
|
||||||
|
|
||||||
// ================== <EFBFBD><EFBFBD>ȡ״̬ ==================
|
// ================== 获取状态 ==================
|
||||||
static int getViewportWidth();
|
static int getViewportWidth();
|
||||||
static int getViewportHeight();
|
static int getViewportHeight();
|
||||||
static glm::vec4 getClearColor();
|
static glm::vec4 getClearColor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
* @brief 获取当前渲染命令队列中的命令数量。
|
||||||
* @return <EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>С<EFBFBD><EFBFBD>
|
* @return 队列大小。
|
||||||
*/
|
*/
|
||||||
static size_t getQueueSize();
|
static size_t getQueueSize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct RenderState;
|
struct RenderState;
|
||||||
// ˽<EFBFBD>еġ<EFBFBD>ֱ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>GL<EFBFBD><EFBFBD><EFBFBD>õİ汾
|
// 私有的、直接执行GL调用的版本
|
||||||
static void _enable(GLenum capability);
|
static void _enable(GLenum capability);
|
||||||
static void _disable(GLenum capability);
|
static void _disable(GLenum capability);
|
||||||
static void _pushState();
|
static void _pushState();
|
||||||
@@ -511,15 +511,15 @@ private:
|
|||||||
|
|
||||||
static std::string getGLErrorString(GLenum error);
|
static std::string getGLErrorString(GLenum error);
|
||||||
|
|
||||||
// <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 静态成员变量
|
||||||
static std::thread::id s_RenderThreadId;
|
static std::thread::id s_RenderThreadId;
|
||||||
static std::atomic<bool> s_IsInInit;
|
static std::atomic<bool> s_IsInInit;
|
||||||
static std::queue<std::function<void()>> s_RenderQueue;
|
static std::queue<std::function<void()>> s_RenderQueue;
|
||||||
static std::mutex s_RenderQueueMutex;
|
static std::mutex s_RenderQueueMutex;
|
||||||
static std::atomic<bool> s_IsReplayingQueue;
|
static std::atomic<bool> s_IsReplayingQueue;
|
||||||
|
|
||||||
// ================== RenderState <EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD> ==================
|
// ================== RenderState 结构体和实现 ==================
|
||||||
struct RenderSystem::RenderState {
|
struct RenderState {
|
||||||
GLint currentProgram = 0;
|
GLint currentProgram = 0;
|
||||||
GLboolean blendEnabled = GL_FALSE;
|
GLboolean blendEnabled = GL_FALSE;
|
||||||
GLboolean depthTestEnabled = GL_FALSE;
|
GLboolean depthTestEnabled = GL_FALSE;
|
||||||
|
|||||||
17
Vivid2DRenderer/systems/defs.h
Normal file
17
Vivid2DRenderer/systems/defs.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef DEFS_H
|
||||||
|
#define DEFS_H
|
||||||
|
|
||||||
|
//// 检查 VIVID_2D_MYDLL_API 宏是否已经被定义
|
||||||
|
//#ifdef VIVID_2D_MYDLL_API
|
||||||
|
//// 如果已经定义,则先取消其定义(防止重复或冲突的定义)
|
||||||
|
//#undef VIVID_2D_MYDLL_API
|
||||||
|
//#endif
|
||||||
|
//
|
||||||
|
//// 强制将 VIVID_2D_MYDLL_API 宏定义为 __declspec(dllexport)
|
||||||
|
//// 作用:告诉编译器,使用此宏标记的类、函数或变量,必须从当前 DLL 中导出。
|
||||||
|
//// 这是在编译 DLL 自身源代码时,确保其接口能够被外部应用程序使用的关键步骤。
|
||||||
|
//#define VIVID_2D_MYDLL_API __declspec(dllexport)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
"name": "my-opengl-project",
|
"name": "my-opengl-project",
|
||||||
"version-string": "0.1.0",
|
"version-string": "0.1.0",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"stb"
|
"stb",
|
||||||
]
|
"glfw3",
|
||||||
|
"glew",
|
||||||
|
"glad",
|
||||||
|
"spdlog",
|
||||||
|
"glm",
|
||||||
|
"stduuid"
|
||||||
|
],
|
||||||
|
"builtin-baseline": "d1ff36c6520ee43f1a656c03cd6425c2974a449e"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user