2026-02-11 19:40:26 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2026-02-25 06:23:53 +08:00
|
|
|
|
#include <graphics/alpha_mask.h>
|
2026-02-26 00:55:13 +08:00
|
|
|
|
#include <graphics/texture.h>
|
|
|
|
|
|
|
2026-02-11 19:40:26 +08:00
|
|
|
|
#include <glad/glad.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
|
|
namespace extra2d {
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// OpenGL 纹理实现
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
class GLTexture : public Texture {
|
|
|
|
|
|
public:
|
2026-02-26 00:55:13 +08:00
|
|
|
|
GLTexture(int width, int height, const uint8_t *pixels, int channels);
|
|
|
|
|
|
GLTexture(const std::string &filepath);
|
|
|
|
|
|
~GLTexture();
|
|
|
|
|
|
|
|
|
|
|
|
// Texture 接口实现
|
2026-02-26 00:59:16 +08:00
|
|
|
|
int width() const override { return width_; }
|
|
|
|
|
|
int height() const override { return height_; }
|
2026-02-26 00:55:13 +08:00
|
|
|
|
Size size() const override {
|
|
|
|
|
|
return Size(static_cast<float>(width_), static_cast<float>(height_));
|
|
|
|
|
|
}
|
|
|
|
|
|
int getChannels() const override { return channels_; }
|
|
|
|
|
|
PixelFormat getFormat() const override;
|
|
|
|
|
|
void *getNativeHandle() const override {
|
|
|
|
|
|
return reinterpret_cast<void *>(static_cast<uintptr_t>(textureID_));
|
|
|
|
|
|
}
|
|
|
|
|
|
bool isValid() const override { return textureID_ != 0; }
|
|
|
|
|
|
void setFilter(bool linear) override;
|
|
|
|
|
|
void setWrap(bool repeat) override;
|
|
|
|
|
|
|
|
|
|
|
|
// 从参数创建纹理的工厂方法
|
|
|
|
|
|
static Ptr<Texture> create(int width, int height, PixelFormat format);
|
|
|
|
|
|
|
|
|
|
|
|
// 加载压缩纹理(KTX/DDS 格式)
|
|
|
|
|
|
bool loadCompressed(const std::string &filepath);
|
|
|
|
|
|
|
|
|
|
|
|
// OpenGL 特定
|
|
|
|
|
|
GLuint getTextureID() const { return textureID_; }
|
|
|
|
|
|
void bind(unsigned int slot = 0) const;
|
|
|
|
|
|
void unbind() const;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取纹理数据大小(字节),用于 VRAM 跟踪
|
|
|
|
|
|
size_t getDataSize() const { return dataSize_; }
|
|
|
|
|
|
|
|
|
|
|
|
// Alpha 遮罩
|
|
|
|
|
|
bool hasAlphaMask() const {
|
|
|
|
|
|
return alphaMask_ != nullptr && alphaMask_->isValid();
|
|
|
|
|
|
}
|
|
|
|
|
|
const AlphaMask *getAlphaMask() const { return alphaMask_.get(); }
|
|
|
|
|
|
void generateAlphaMask(); // 从当前纹理数据生成遮罩
|
2026-02-11 19:40:26 +08:00
|
|
|
|
|
|
|
|
|
|
private:
|
2026-02-26 00:55:13 +08:00
|
|
|
|
GLuint textureID_;
|
|
|
|
|
|
int width_;
|
|
|
|
|
|
int height_;
|
|
|
|
|
|
int channels_;
|
|
|
|
|
|
PixelFormat format_;
|
|
|
|
|
|
size_t dataSize_;
|
|
|
|
|
|
|
|
|
|
|
|
// 原始像素数据(用于生成遮罩)
|
|
|
|
|
|
std::vector<uint8_t> pixelData_;
|
|
|
|
|
|
std::unique_ptr<AlphaMask> alphaMask_;
|
|
|
|
|
|
|
|
|
|
|
|
void createTexture(const uint8_t *pixels);
|
|
|
|
|
|
|
|
|
|
|
|
// KTX 文件加载
|
|
|
|
|
|
bool loadKTX(const std::string &filepath);
|
|
|
|
|
|
// DDS 文件加载
|
|
|
|
|
|
bool loadDDS(const std::string &filepath);
|
2026-02-11 19:40:26 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace extra2d
|