载入中...
搜索中...
未找到
LifeFieldMaterialBinding.cpp
浏览该文件的文档.
2
3#include "common/Diagnostic.h"
4#include "graphics/Graphics.h"
5
6#include <algorithm>
7#include <cmath>
8
9namespace eve::gpuagents {
10namespace {
11
12std::uint8_t encode01(float v) { return static_cast<std::uint8_t>(std::clamp(v, 0.f, 1.f) * 255.f + 0.5f); }
13
14float height01(float h, float minH, float maxH) {
15 if (maxH - minH < 1e-5f) return 0.5f;
16 return (h - minH) / (maxH - minH);
17}
18
19} // namespace
20
22 if (field.resolution < 2 || field.lifeField.size() != static_cast<size_t>(field.resolution) * field.resolution) {
24 "surface field is not initialized for life binding", "field", {},
25 "gpuagents"));
26 }
27 const int res = field.resolution;
28 uniforms_.origin = field.origin;
29 uniforms_.worldSize = field.worldSize;
30 uniforms_.resolution = res;
31
32 lifePixels_.assign(static_cast<size_t>(res) * res * 4u, 0);
33 surfacePixels_.assign(static_cast<size_t>(res) * res * 4u, 0);
34
35 float minH = field.height.empty() ? 0.f : field.height[0];
36 float maxH = minH;
37 for (float h : field.height) {
38 minH = std::min(minH, h);
39 maxH = std::max(maxH, h);
40 }
41
42 for (int z = 0; z < res; ++z) {
43 for (int x = 0; x < res; ++x) {
44 const size_t i = static_cast<size_t>(x + res * z);
45 const auto& life = field.lifeField[i];
46 const size_t p = i * 4u;
47 lifePixels_[p + 0] = encode01(life.r);
48 lifePixels_[p + 1] = encode01(life.g);
49 lifePixels_[p + 2] = encode01(life.b);
50 lifePixels_[p + 3] = encode01(life.a);
51
52 const float h = field.height.empty() ? 0.f : field.height[i];
53 const glm::vec3 n = field.normals.empty() ? glm::vec3(0.f, 1.f, 0.f) : field.normals[i];
54 surfacePixels_[p + 0] = encode01(height01(h, minH, maxH));
55 surfacePixels_[p + 1] = encode01(n.x * 0.5f + 0.5f);
56 surfacePixels_[p + 2] = encode01(n.y * 0.5f + 0.5f);
57 surfacePixels_[p + 3] = encode01(n.z * 0.5f + 0.5f);
58 }
59 }
60 return Result<void>::success();
61}
62
64 if (!gfx) {
66 Diagnostic::error(DiagnosticCode::InvalidArgument, "graphics is null", "gfx", {}, "gpuagents"));
67 }
68 if (lifePixels_.empty()) {
70 "life-field pixels empty; call syncFrom first",
71 "syncFrom", {}, "gpuagents"));
72 }
73 auto* tex = gfx->newTexture(uniforms_.resolution, uniforms_.resolution, lifePixels_.data(), false, false);
74 if (!tex) {
76 DiagnosticCode::Failed, "failed to create life-field texture", "texture", {}, "gpuagents"));
77 }
79}
80
82 if (!gfx) {
84 Diagnostic::error(DiagnosticCode::InvalidArgument, "graphics is null", "gfx", {}, "gpuagents"));
85 }
86 if (surfacePixels_.empty()) {
88 "surface-data pixels empty; call syncFrom first",
89 "syncFrom", {}, "gpuagents"));
90 }
91 auto* tex = gfx->newTexture(uniforms_.resolution, uniforms_.resolution, surfacePixels_.data(), false, false);
92 if (!tex) {
94 DiagnosticCode::Failed, "failed to create surface-data texture", "texture", {}, "gpuagents"));
95 }
97}
98
100 bool lifeField) const {
101 if (!gfx || !texture) {
102 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "graphics or texture is null",
103 "texture", {}, "gpuagents"));
104 }
105 const auto& pixels = lifeField ? lifePixels_ : surfacePixels_;
106 if (pixels.empty()) {
108 "pixel buffer empty; call syncFrom first", "syncFrom", {},
109 "gpuagents"));
110 }
111 if (!gfx->updateTexture(texture, uniforms_.resolution, uniforms_.resolution, pixels.data())) {
113 Diagnostic::error(DiagnosticCode::Failed, "updateTexture failed", "texture", {}, "gpuagents"));
114 }
115 return Result<void>::success();
116}
117
118} // namespace eve::gpuagents
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
glm::vec4 p[6]
Stable, structured diagnostics shared by engine modules.
glm::vec3 n
Definition Grass.cpp:63
float v
int h
uint8_t * pixels
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Result< void > syncFrom(const SurfaceField &field)
Rebuild CPU pixel buffers from a surface field.
Result< void > updateTexture(graphics::Graphics *gfx, graphics::Texture *texture, bool lifeField) const
Update an existing texture in place.
Result< graphics::Texture * > uploadSurfaceData(graphics::Graphics *gfx)
Upload surface-data texture.
Result< graphics::Texture * > uploadLifeField(graphics::Graphics *gfx)
Upload or refresh Graphics textures from the packed buffers.
2.5D surface + life-field textures for Life Network.
virtual bool updateTexture(Texture *texture, int width, int height, const uint8_t *rgba)=0
Replace an existing texture's pixels in place (pointer stays stable).
virtual Texture * newTexture(int width, int height, const uint8_t *rgba, bool repeatU=false, bool repeatV=false)=0
Creates a texture. @ownership Caller deletes unless documented otherwise.
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18