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/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
**/vcpkg_installed/
|
||||
|
||||
15
README.md
15
README.md
@@ -19,21 +19,30 @@
|
||||
## 二、配置 vcpkg
|
||||
|
||||
`vcpkg` 用于下载和安装项目所需的第三方库。
|
||||
下列方法二选一:
|
||||
|
||||
1. **下载并引导 vcpkg:**
|
||||
1. 手动安装vcpkg
|
||||
|
||||
- 1. **下载并引导 vcpkg:**
|
||||
|
||||
- 克隆 vcpkg 仓库或下载压缩包。
|
||||
- 运行引导脚本(Windows 上通常是 `.\bootstrap-vcpkg.bat`)。
|
||||
|
||||
2. **安装项目依赖库:**
|
||||
- 2. **安装项目依赖库:**
|
||||
打开命令行或 PowerShell,进入 vcpkg 目录,然后运行以下命令来安装项目所需的库:
|
||||
|
||||
```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** (数学库)。
|
||||
|
||||
2. 使用Visual Studio Installer安装的vcpkg
|
||||
- 使用Visual Studio打开项目,点击 工具-命令行-开发者命令提示/开发者 PowerShell,执行下列命令:
|
||||
- vcpkg integrate install
|
||||
- (可选)执行下列命令,编译会自动执行
|
||||
- vcpkg install
|
||||
|
||||
## 三、使用 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;
|
||||
}
|
||||
|
||||
// <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 {
|
||||
class logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* <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>
|
||||
* <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>
|
||||
* <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()
|
||||
* <EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* 这是一个完全静态的类,旨在将来自任何线程的渲染调用排队,并在一个专用的渲染线程上执行它们。
|
||||
* 这样做可以确保所有 OpenGL 操作的线程安全性。它还提供了对 OpenGL 状态、着色器、缓冲区和纹理的
|
||||
* 高级管理功能,以及一个用于调试的错误检查机制。
|
||||
* 使用方法:在主线程或其他逻辑线程中调用公开的静态方法(如 RenderSystem::drawElements),
|
||||
* 这些方法会将渲染命令记录到队列中。在渲染线程的循环中,调用 RenderSystem::replayQueue()
|
||||
* 来执行所有排队的命令。
|
||||
*/
|
||||
class VIVID_2D_MYDLL_API RenderSystem {
|
||||
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(const RenderSystem&) = delete;
|
||||
RenderSystem& operator=(const RenderSystem&) = delete;
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
// ================== <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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鵱ǰ<EFBFBD>߳<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̡߳<EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>̣߳<EFBFBD><EFBFBD><EFBFBD> true<EFBFBD><EFBFBD>
|
||||
* @brief 检查当前线程是否是渲染线程。
|
||||
* @return 如果是渲染线程,则返回 true。
|
||||
*/
|
||||
static bool isOnRenderThread();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鵱ǰ<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Ρ<EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD> true<EFBFBD><EFBFBD>
|
||||
* @brief 检查当前是否处于初始化阶段。
|
||||
* @return 如果是初始化阶段,则返回 true。
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief ʹ<EFBFBD><EFBFBD> GLAD <EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>롣
|
||||
* @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>
|
||||
* @brief 使用 GLAD 加载 OpenGL 函数指针。
|
||||
* @param loader 一个函数指针,用于获取 OpenGL 函数的地址(例如 glfwGetProcAddress)。
|
||||
*/
|
||||
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>
|
||||
* @param renderCall Ҫִ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 将一个渲染调用(作为 lambda 函数)记录到命令队列中,以便稍后在渲染线程上执行。
|
||||
* @param 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();
|
||||
|
||||
// ================== 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>
|
||||
* @param capability Ҫ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>١<EFBFBD>
|
||||
* @brief 启用一个 OpenGL 功能(例如 GL_BLEND)。
|
||||
* @param capability 要启用的 OpenGL 功能枚举。
|
||||
*/
|
||||
static void enable(GLenum capability);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD>ܡ<EFBFBD>
|
||||
* @param capability Ҫ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>١<EFBFBD>
|
||||
* @brief 禁用一个 OpenGL 功能。
|
||||
* @param capability 要禁用的 OpenGL 功能枚举。
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ״̬<EFBFBD><EFBFBD>ջ<EFBFBD>Ĵ<EFBFBD>С<EFBFBD><EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD>ջ<EFBFBD>е<EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 获取当前状态堆栈的大小。
|
||||
* @return 堆栈中的状态数量。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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>
|
||||
* @param mask Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>롣
|
||||
* @brief 清除指定的缓冲区(例如 GL_COLOR_BUFFER_BIT)。
|
||||
* @param 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);
|
||||
|
||||
// ================== 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>
|
||||
* @return <EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 生成一个顶点数组对象 (VAO)。
|
||||
* @return 新创建的 VAO 的句柄。
|
||||
*/
|
||||
static GLuint GenVertexArrays();
|
||||
|
||||
/**
|
||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> VAO<EFBFBD><EFBFBD>
|
||||
* @param vao Ҫɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 删除一个 VAO。
|
||||
* @param vao 要删除的 VAO 的句柄。
|
||||
*/
|
||||
static void DeleteVertexArrays(GLuint vao);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> VAO<EFBFBD><EFBFBD>
|
||||
* @param vao Ҫ<EFBFBD><EFBFBD> VAO <EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 绑定一个 VAO。
|
||||
* @param vao 要绑定的 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>
|
||||
* @return <EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 生成一个缓冲区对象 (VBO/EBO)。
|
||||
* @return 新创建的缓冲区的句柄。
|
||||
*/
|
||||
static GLuint GenBuffers();
|
||||
|
||||
/**
|
||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param buffer Ҫɾ<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 删除一个缓冲区对象。
|
||||
* @param 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>
|
||||
* @param target <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> GL_ARRAY_BUFFER)<EFBFBD><EFBFBD>
|
||||
* @param buffer Ҫ<EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 绑定一个缓冲区对象。
|
||||
* @param target 缓冲区的目标 (例如 GL_ARRAY_BUFFER)。
|
||||
* @param 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>
|
||||
* @param target <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ꡣ
|
||||
* @param size <EFBFBD><EFBFBD><EFBFBD>ݵĴ<EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param data ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD>롣
|
||||
* @param usage <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>; (<28><><EFBFBD><EFBFBD> GL_STATIC_DRAW)<EFBFBD><EFBFBD>
|
||||
* @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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
// ================== Uniform 设置 ==================
|
||||
static void uniform1i(GLint location, int value);
|
||||
static void uniform1f(GLint location, float value);
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> uniform <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>á<EFBFBD>
|
||||
* @param program <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param name uniform <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
* @return uniform <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>á<EFBFBD>
|
||||
* @brief 获取着色器程序中 uniform 变量的位置。
|
||||
* @param program 着色器程序的句柄。
|
||||
* @param name uniform 变量的名称。
|
||||
* @return uniform 变量的位置。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ ==================
|
||||
// ================== 混合模式 ==================
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ϡ<EFBFBD>
|
||||
* @brief 启用混合。
|
||||
*/
|
||||
static void enableBlend();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ϡ<EFBFBD>
|
||||
* @brief 禁用混合。
|
||||
*/
|
||||
static void disableBlend();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>Ϻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 设置混合函数。
|
||||
*/
|
||||
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();
|
||||
|
||||
// ================== <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>
|
||||
* @return <EFBFBD>³<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 创建一个空的着色器程序。
|
||||
* @return 新程序的句柄。
|
||||
*/
|
||||
static GLuint createProgram();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 获取当前绑定的着色器程序。
|
||||
* @return 当前程序的句柄。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 链接一个着色器程序。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 删除一个着色器程序。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 激活一个着色器程序。
|
||||
*/
|
||||
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>
|
||||
* @param type <EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> GL_VERTEX_SHADER)<EFBFBD><EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 创建一个指定类型的着色器对象。
|
||||
* @param type 着色器类型 (例如 GL_VERTEX_SHADER)。
|
||||
* @return 新着色器对象的句柄。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 编译一个着色器。
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>
|
||||
* @brief 获取着色器的日志信息。
|
||||
*/
|
||||
static std::string getShaderInfoLog(GLuint shader);
|
||||
|
||||
/**
|
||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 删除一个着色器。
|
||||
*/
|
||||
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>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 从源代码编译一个指定类型的着色器。
|
||||
* @return 编译后的着色器句柄。
|
||||
*/
|
||||
static GLuint compileShader(GLenum type, const std::string& source);
|
||||
|
||||
// ================== <EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
// ================== 深度测试 ==================
|
||||
static void depthFunc(GLenum func);
|
||||
static void depthMask(bool flag);
|
||||
static void clearDepth(double depth);
|
||||
static void enableDepthTest();
|
||||
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>
|
||||
* @param texture Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 绑定一个 2D 纹理到当前活动的纹理单元。
|
||||
* @param 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>
|
||||
* @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>
|
||||
* @param texture Ҫ<EFBFBD><EFBFBD> Texture <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
||||
* @param textureUnit Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> (0, 1, 2, ...)<EFBFBD><EFBFBD>
|
||||
* @brief 绑定一个 Texture 对象到指定的纹理单元。
|
||||
* @details 这是一个便利方法,它将激活纹理单元和绑定纹理两个操作合并为一个命令,
|
||||
* 并安全地提交到渲染线程。
|
||||
* @param texture 要绑定的 Texture 对象的常量引用。
|
||||
* @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 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
|
||||
* @param texture Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ (<28><><EFBFBD><EFBFBD> GL_TEXTURE0)<EFBFBD><EFBFBD>
|
||||
* @brief 激活一个纹理单元。
|
||||
* @param texture 要激活的纹理单元 (例如 GL_TEXTURE0)。
|
||||
*/
|
||||
static void activeTexture(GLenum texture);
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 生成一个纹理对象。
|
||||
* @return 新纹理的句柄。
|
||||
*/
|
||||
static GLuint genTextures();
|
||||
|
||||
/**
|
||||
* @brief ɾ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param texture Ҫɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @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);
|
||||
@@ -405,20 +405,20 @@ public:
|
||||
static void setTextureWrapT(GLenum wrap);
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD> 1x1 <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return Ĭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @brief 创建一个默认的 1x1 白色纹理。
|
||||
* @return 默认纹理的句柄。
|
||||
*/
|
||||
static GLuint createDefaultTexture();
|
||||
|
||||
// ================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
// ================== 顶点属性 ==================
|
||||
static void enableVertexAttribArray(GLuint index);
|
||||
static void disableVertexAttribArray(GLuint index);
|
||||
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);
|
||||
/**
|
||||
* @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 void pixelStore(GLenum pname, GLint param);
|
||||
@@ -428,35 +428,35 @@ public:
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD>鲢<EFBFBD><EFBFBD>¼<EFBFBD>κη<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OpenGL <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @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>
|
||||
* @brief 检查并记录任何发生的 OpenGL 错误。
|
||||
* @param operation 导致检查的操作的描述性名称。
|
||||
*/
|
||||
static void checkGLError(const std::string& operation);
|
||||
|
||||
// ================== <EFBFBD><EFBFBD>ȡ״̬ ==================
|
||||
// ================== 获取状态 ==================
|
||||
static int getViewportWidth();
|
||||
static int getViewportHeight();
|
||||
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>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>С<EFBFBD><EFBFBD>
|
||||
* @brief 获取当前渲染命令队列中的命令数量。
|
||||
* @return 队列大小。
|
||||
*/
|
||||
static size_t getQueueSize();
|
||||
|
||||
private:
|
||||
struct RenderState;
|
||||
// ˽<EFBFBD>еġ<EFBFBD>ֱ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>GL<EFBFBD><EFBFBD><EFBFBD>õİ汾
|
||||
// 私有的、直接执行GL调用的版本
|
||||
static void _enable(GLenum capability);
|
||||
static void _disable(GLenum capability);
|
||||
static void _pushState();
|
||||
@@ -511,15 +511,15 @@ private:
|
||||
|
||||
static std::string getGLErrorString(GLenum error);
|
||||
|
||||
// <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 静态成员变量
|
||||
static std::thread::id s_RenderThreadId;
|
||||
static std::atomic<bool> s_IsInInit;
|
||||
static std::queue<std::function<void()>> s_RenderQueue;
|
||||
static std::mutex s_RenderQueueMutex;
|
||||
static std::atomic<bool> s_IsReplayingQueue;
|
||||
|
||||
// ================== RenderState <EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD> ==================
|
||||
struct RenderSystem::RenderState {
|
||||
// ================== RenderState 结构体和实现 ==================
|
||||
struct RenderState {
|
||||
GLint currentProgram = 0;
|
||||
GLboolean blendEnabled = 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",
|
||||
"version-string": "0.1.0",
|
||||
"dependencies": [
|
||||
"stb"
|
||||
]
|
||||
"stb",
|
||||
"glfw3",
|
||||
"glew",
|
||||
"glad",
|
||||
"spdlog",
|
||||
"glm",
|
||||
"stduuid"
|
||||
],
|
||||
"builtin-baseline": "d1ff36c6520ee43f1a656c03cd6425c2974a449e"
|
||||
}
|
||||
Reference in New Issue
Block a user