1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// This file is part of the 64k demo project.
// It defines the TextureManager for procedural assets.
// Handles generation and GPU upload of procedural textures.
#pragma once
#include "gpu/gpu.h"
#include <map>
#include <string>
#include <vector>
struct ProceduralTextureDef {
int width;
int height;
bool (*gen_func)(uint8_t*, int, int, const float*, int);
std::vector<float> params;
};
struct GpuTexture {
WGPUTexture texture;
WGPUTextureView view;
int width;
int height;
};
struct GpuProceduralParams {
int width;
int height;
const float* params;
int num_params;
};
class TextureManager {
public:
void init(WGPUDevice device, WGPUQueue queue);
void shutdown();
// Registers and generates a texture immediately
void create_procedural_texture(const std::string& name,
const ProceduralTextureDef& def);
// Creates a texture from existing data (RGBA8)
void create_texture(const std::string& name, int width, int height,
const uint8_t* data);
// GPU procedural generation
void create_gpu_noise_texture(const std::string& name,
const GpuProceduralParams& params);
void create_gpu_perlin_texture(const std::string& name,
const GpuProceduralParams& params);
void create_gpu_grid_texture(const std::string& name,
const GpuProceduralParams& params);
#if !defined(STRIP_GPU_COMPOSITE)
// GPU composite generation (multi-input textures)
void create_gpu_composite_texture(const std::string& name,
const std::string& shader_func,
const char* shader_code,
const void* uniform_data,
size_t uniform_size,
int width, int height,
const std::vector<std::string>& input_names);
#endif
#if !defined(STRIP_ALL)
// On-demand lazy generation (stripped in final builds)
WGPUTextureView get_or_generate_gpu_texture(const std::string& name,
const GpuProceduralParams& params);
#endif
// Retrieves a texture view by name (returns nullptr if not found)
WGPUTextureView get_texture_view(const std::string& name);
private:
struct ComputePipelineInfo {
WGPUComputePipeline pipeline;
const char* shader_code;
size_t uniform_size;
int num_input_textures;
};
WGPUComputePipeline get_or_create_compute_pipeline(const std::string& func_name,
const char* shader_code,
size_t uniform_size,
int num_input_textures = 0);
void dispatch_compute(const std::string& func_name, WGPUTexture target,
const GpuProceduralParams& params, const void* uniform_data,
size_t uniform_size);
#if !defined(STRIP_GPU_COMPOSITE)
void dispatch_composite(const std::string& func_name, WGPUTexture target,
const GpuProceduralParams& params,
const void* uniform_data, size_t uniform_size,
const std::vector<WGPUTextureView>& input_views);
#endif
WGPUDevice device_;
WGPUQueue queue_;
std::map<std::string, GpuTexture> textures_;
std::map<std::string, ComputePipelineInfo> compute_pipelines_;
#if !defined(STRIP_GPU_COMPOSITE)
WGPUSampler linear_sampler_;
#endif
};
|