载入中...
搜索中...
未找到
SpriteStack.h
浏览该文件的文档.
1#pragma once
2
3#include "common/Module.h"
4
5#include <cstdint>
6#include <functional>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11#include <glm/glm.hpp>
12
13namespace eve::graphics {
14class Camera3D;
15class Graphics;
16class Mesh;
17class Shader;
18class Texture;
19} // namespace eve::graphics
20
21namespace eve::image {
22class ImageData;
23} // namespace eve::image
24
25namespace eve::model3d {
26class ModelData;
27} // namespace eve::model3d
28
29namespace eve::spritestack {
30
38struct SliceInput {
39 const float *posXYZ = nullptr;
40 const float *nrmXYZ = nullptr;
41 const float *rgb = nullptr;
42 int vertexCount = 0;
43 const uint32_t *indices = nullptr;
44 int indexCount = 0;
45};
46
53 int layerCount = 16;
54 int imageW = 128;
55 int imageH = 128;
56 std::string axis = "z"; // "x" | "y" | "z"
57 float thickness = 0.f; // world units per layer; 0 = auto from AABB
58 float padding = 0.04f; // margin around the model in the image plane
59 bool shade = true; // N*view shading per triangle
60 float tintR = 1.f;
61 float tintG = 1.f;
62 float tintB = 1.f;
63};
64
70std::vector<image::ImageData *> sliceMeshToLayers(const SliceInput &input,
71 const SliceOptions &options);
72
74std::vector<image::ImageData *> sliceModelToLayers(model3d::ModelData *model,
75 const SliceOptions &options);
76
81std::vector<image::ImageData *> slicePrimitiveToLayers(const std::string &kind,
82 const SliceOptions &options);
83
99public:
100 SpriteStack3D() = default;
102
103 SpriteStack3D(const SpriteStack3D &) = delete;
105
107 struct SliceDraw {
108 glm::mat4 model{1.f};
109 glm::vec4 uv{0.f, 0.f, 1.f, 1.f};
110 float distSq = 0.f;
112 };
113
114 void setLayerCount(int count);
115 int getLayerCount() const;
116
118 void setLayerTexture(graphics::Texture *texture, int index);
119 graphics::Texture *getLayerTexture(int index) const;
120
122 void setLayerImage(graphics::Graphics *gfx, image::ImageData *img, int index);
124 void setLayerFile(graphics::Graphics *gfx, const std::string &path, int index);
131 int layerCount);
132
134 void setThickness(float thickness);
135 float getThickness() const;
136
138 void setSize(float width, float height);
139 float getWidth() const;
140 float getHeight() const;
141
142 void setPosition(float x, float y, float z);
143 void setYaw(float radians);
144 void setTint(float r, float g, float b, float a = 1.f);
145 void setAlphaCutoff(float cutoff);
146 void setVisible(bool visible);
147 bool getVisible() const;
148 void setMode(const std::string &mode); // "vertical" | "horizontal"
149 std::string getMode() const;
150
152 void setShadowEnabled(bool enabled);
153 bool getShadowEnabled() const;
154 void setShadowOpacity(float opacity);
155 void setShadowLight(float dx, float dy, float dz);
156 void setShadowPlaneY(float y);
157
159 void setOutline(float width, float r = 0.f, float g = 0.f, float b = 0.f);
160 float getOutlineWidth() const;
161 void setOutlineColor(float r, float g, float b);
162
168 void setGbufferEnabled(bool enabled);
169 bool getGbufferEnabled() const;
170
177 void setCastShadow(bool cast);
178 bool getCastShadow() const;
179
181 uint64_t getVersion() const { return version_; }
182
188 void render(graphics::Graphics *gfx, graphics::Camera3D *camera = nullptr) const;
189
190private:
191 void ensureResources(graphics::Graphics *gfx) const;
192
193 void bumpVersion() { ++version_; }
194
195 friend class SpriteStackBatch;
196
197 static void collectSlices(const SpriteStack3D &stack, const glm::vec3 &eye,
198 std::vector<SliceDraw> &out);
199 static SliceDraw makeShadowDraw(const SpriteStack3D &stack, const SliceDraw &s,
200 const glm::vec3 &eye);
201 static SliceDraw makeOutlineDraw(const SpriteStack3D &stack, const SliceDraw &s,
202 const glm::vec3 &eye);
203 static void drawGbufferStacks(graphics::Graphics &gfx, const glm::mat4 &viewProj,
204 float eyeX, float eyeY, float eyeZ, float nearZ, float farZ);
205 static void registerGbufferDrawer();
206 static std::vector<SpriteStack3D *> &gbufferStacks();
207 static void drawShadowCasterStacks(graphics::Graphics &gfx, const glm::mat4 &lightVP,
208 float eyeX, float eyeY, float eyeZ);
209 static void registerShadowDrawer();
210 static std::vector<SpriteStack3D *> &shadowCasterStacks();
211
212 struct Layer {
213 graphics::Texture *texture = nullptr;
214 glm::vec4 uv{0.f, 0.f, 1.f, 1.f}; // u0, v0, u1, v1
215 };
216 std::vector<Layer> layers_;
217 int layerCount_ = 0;
218 float thickness_ = 0.1f;
219 float width_ = 1.f;
220 float height_ = 1.f;
221 float x_ = 0.f, y_ = 0.f, z_ = 0.f;
222 float yaw_ = 0.f;
223 float tintR_ = 1.f, tintG_ = 1.f, tintB_ = 1.f, tintA_ = 1.f;
224 float alphaCutoff_ = 0.05f;
225 bool visible_ = true;
226 std::string mode_ = "vertical";
227 bool shadowEnabled_ = false;
228 float shadowOpacity_ = 0.32f;
229 float shadowLightX_ = 0.35f, shadowLightY_ = -1.f, shadowLightZ_ = 0.25f;
230 float shadowPlaneY_ = 0.f;
231 float outlineWidth_ = 0.f;
232 float outlineR_ = 0.f, outlineG_ = 0.f, outlineB_ = 0.f;
233 bool gbufferEnabled_ = false;
234 bool castShadow_ = false;
235 uint64_t version_ = 1;
236
237 // Lazy GPU resources (owned by Graphics).
238 mutable graphics::Shader *shader_ = nullptr;
239 mutable graphics::Mesh *quad_ = nullptr;
240};
241
252public:
253 SpriteStackBatch() = default;
254 ~SpriteStackBatch() = default;
255
258
259 void add(SpriteStack3D *stack);
260 void remove(SpriteStack3D *stack);
261 void clear();
262 int getStackCount() const;
263
264 void render(graphics::Graphics *gfx, graphics::Camera3D *camera = nullptr);
265
266private:
267 struct GroupKey {
268 graphics::Texture *texture = nullptr;
269 uint32_t tint = 0; // packed RGBA
270 bool operator==(const GroupKey &o) const {
271 return texture == o.texture && tint == o.tint;
272 }
273 };
274 struct GroupKeyHash {
275 size_t operator()(const GroupKey &k) const {
276 return std::hash<void *>()(k.texture) ^ (size_t(k.tint) * 0x9e3779b9u);
277 }
278 };
279
280 struct Group {
281 graphics::Mesh *mesh = nullptr;
282 uint64_t stamp = 0;
283 int vertexCapacity = 0;
284 int indexCapacity = 0;
285 };
286
287 void ensureShader(graphics::Graphics *gfx);
288
289 std::vector<SpriteStack3D *> stacks_;
290 std::unordered_map<GroupKey, Group, GroupKeyHash> groups_;
291 bool forceRebuild_ = true; // add/remove/clear invalidate cached group meshes
292 mutable graphics::Shader *shader_ = nullptr;
293};
294
300class SpriteStack : public Module {
301public:
303 SpriteStack() = default;
304 ~SpriteStack() override = default;
305
310
311 std::vector<image::ImageData *> slicePrimitive(const std::string &kind, int layerCount,
312 int imageW, int imageH,
313 const std::string &axis, float thickness);
314 std::vector<image::ImageData *> sliceModel(model3d::ModelData *model, int layerCount,
315 int imageW, int imageH, const std::string &axis,
316 float thickness);
317};
318
319} // namespace eve::spritestack
Tok kind
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
float height
Definition Grass.cpp:235
int x
Definition Grass.cpp:135
float thickness
uint32_t a
uint32_t b
int width
glm::vec3 eye
Mesh * mesh
glm::mat4 viewProj
glm::mat4 model
bool enabled
uint32_t s
Definition Weather.cpp:28
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:18
Custom GPU program.
Definition Shader.h:30
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
Represents raw pixel data.
Definition ImageData.h:26
CPU-side decoded 3D model (Assimp scene owned via medialoader::ModelScene). Does not upload to GPU — ...
Definition ModelData.h:23
A renderable pseudo-3D sprite stack: a column of layer textures drawn as alpha-blended slices inside ...
Definition SpriteStack.h:98
SpriteStack3D & operator=(const SpriteStack3D &)=delete
void setOutlineColor(float r, float g, float b)
void setShadowLight(float dx, float dy, float dz)
void setLayerImage(graphics::Graphics *gfx, image::ImageData *img, int index)
Upload RGBA8 ImageData layers (convenience around setLayerTexture).
void setTint(float r, float g, float b, float a=1.f)
void render(graphics::Graphics *gfx, graphics::Camera3D *camera=nullptr) const
Draw all slices into the currently open 3D scene pass (Vulkan). Uses the active Camera3D when camera ...
void setSize(float width, float height)
Quad size for every slice (world units). Default 1 x 1.
void setLayerTexture(graphics::Texture *texture, int index)
Null texture clears the slot (that layer is skipped).
void setPosition(float x, float y, float z)
graphics::Texture * getLayerTexture(int index) const
uint64_t getVersion() const
Monotonic revision counter; SpriteStackBatch uses it to detect changes.
void setMode(const std::string &mode)
void setLayerFile(graphics::Graphics *gfx, const std::string &path, int index)
Upload each path via Graphics::newTextureFromFile (reloads in place).
void setAlphaCutoff(float cutoff)
void setOutline(float width, float r=0.f, float g=0.f, float b=0.f)
Stylized rim outline: an expanded dark silhouette behind every slice.
void setGbufferEnabled(bool enabled)
Contribute this stack to the G-buffer (via RenderSystem3D's extra-drawer hook) so post-processing tha...
void setCastShadow(bool cast)
Cast real CSM shadows: the stack's slices are drawn into the cascaded shadow map through the alpha-cu...
void setShadowEnabled(bool enabled)
Pseudo-3D projected contact shadow (soft dark silhouette on the ground).
void setShadowOpacity(float opacity)
SpriteStack3D(const SpriteStack3D &)=delete
void setLayersFromAtlas(graphics::Graphics *gfx, graphics::Texture *atlas, int layerCount)
Split one horizontal atlas strip into layerCount layers (layer i = columns [i/count....
void setThickness(float thickness)
World-space spacing between consecutive slices.
Multi-stack batching: draws every visible slice of the registered stacks as ONE draw call per (textur...
void remove(SpriteStack3D *stack)
void render(graphics::Graphics *gfx, graphics::Camera3D *camera=nullptr)
void add(SpriteStack3D *stack)
SpriteStackBatch(const SpriteStackBatch &)=delete
SpriteStackBatch & operator=(const SpriteStackBatch &)=delete
SpriteStack module: CPU slicing + SpriteStack3D factory.
SpriteStack3D * newStack(graphics::Graphics *gfx)
New empty stack (caller/VM owns; set layers before rendering).
SpriteStackBatch * newBatch(graphics::Graphics *gfx)
New empty batch (caller/VM owns).
std::vector< image::ImageData * > slicePrimitive(const std::string &kind, int layerCount, int imageW, int imageH, const std::string &axis, float thickness)
std::vector< image::ImageData * > sliceModel(model3d::ModelData *model, int layerCount, int imageW, int imageH, const std::string &axis, float thickness)
~SpriteStack() override=default
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6
std::vector< image::ImageData * > sliceMeshToLayers(const SliceInput &input, const SliceOptions &opt)
Slice a triangle mesh into layerCount RGBA8 layer images (caller owns the returned ImageData)....
std::vector< image::ImageData * > slicePrimitiveToLayers(const std::string &kind, const SliceOptions &opt)
Build a procedural CPU mesh ("box" | "cylinder" | "sphere" | "cone") and slice it — a self-contained ...
std::vector< image::ImageData * > sliceModelToLayers(model3d::ModelData *model, const SliceOptions &opt)
Slice every mesh of a decoded model (assimp scene) with the same options.
CPU inputs for slicing a triangle mesh into sprite-stack layers.
Definition SpriteStack.h:38
Slicer options. The mesh is cut into layerCount thin slabs along axis ("x" | "y" | "z"); each slab is...
Definition SpriteStack.h:52
One slice instance with its baked world transform and layer UV rect.