32 return std::unexpected(
"invalid 2D GPU device or target format");
34 if (!shaders)
return std::unexpected(shaders.error().detail);
36 result->device_ = device;
37 result->shaders_ = std::move(*shaders);
41 const std::array<SDL_GPUVertexAttribute,3> attributes{{
47 color.blend_state.enable_blend =
true;
55 info.vertex_shader = result->shaders_.vertex();
56 info.fragment_shader = result->shaders_.fragment();
57 info.vertex_input_state = {&
buffer,1,attributes.data(),3};
62 info.target_info.color_target_descriptions = &color;
63 info.target_info.num_color_targets = 1;
65 if (!result->pipeline_)
return std::unexpected(std::string(
SDL_GetError()));
71 if (!result->sampler_)
return std::unexpected(std::string(
SDL_GetError()));
74 if (!result->linearSampler_)
return std::unexpected(std::string(
SDL_GetError()));
75 const std::array<MeshGPUVertex,6> vertices{{
76 {{0,0,0},{0,0,1},{0,0}}, {{1,0,0},{0,0,1},{1,0}}, {{0,1,0},{0,0,1},{0,1}},
77 {{0,1,0},{0,0,1},{0,1}}, {{1,0,0},{0,0,1},{1,0}}, {{1,1,0},{0,0,1},{1,1}}}};
80 if (!result->quad_)
return std::unexpected(std::string(
SDL_GetError()));
86 std::memcpy(
mapped,vertices.data(),
sizeof(vertices));
102 if (!submitted)
return std::unexpected(std::string(
SDL_GetError()));
158 width>std::numeric_limits<int>::max() ||
height>std::numeric_limits<int>::max())
159 return std::unexpected(
"invalid 2D command, target or dimensions");
163 const auto w=
static_cast<float>(
object.asset->image.width);
164 const auto h=
static_cast<float>(
object.asset->image.height);
165 return std::array<float,16>{
166 w*
m[0]/400.0F,-
w*
m[1]/300.0F,0,0,
167 h*
m[3]/400.0F,-
h*
m[4]/300.0F,0,0,
169 m[6]/400.0F-1.0F,1.0F-
m[7]/300.0F,0,1};
171 std::set<const data::BitmapRuntimeAsset*> used;
175 return standardPointerPresentation_ &&
181 for (
const auto node:
slot.order())
183 const auto*
object=
slot.find(node);
184 if (!
object)
return std::unexpected(
"missing 2D slot node");
186 auto texture=resolveTexture(object->asset);
189 if (!std::isfinite(
value))
return std::unexpected(
"2D projected matrix exceeds finite GPU range");
190 used.insert(object->asset.get());
193 for (
auto it=textures_.begin();
it!=textures_.end();)
195 if (!used.contains(
it->first))
199 if (
drawn==0)
return 0;
202 static_cast<float>(800.0*
fit.scale),
static_cast<float>(600.0*
fit.scale),0,1};
203 const SDL_Rect scissor{
static_cast<int>(std::ceil(
fit.offsetX)),
static_cast<int>(std::ceil(
fit.offsetY)),
204 static_cast<int>(std::floor(
fit.offsetX+800.0*
fit.scale)-std::ceil(
fit.offsetX)),
205 static_cast<int>(std::floor(
fit.offsetY+600.0*
fit.scale)-std::ceil(
fit.offsetY))};
221 for (
const auto node:
slot.order())
223 const auto&
object=*
slot.find(node);
230 object.asset->preferLinearFiltering ? linearSampler_ : sampler_};
std::expected< std::size_t, std::string > render(SDL_GPUCommandBuffer *command, SDL_GPUTexture *target, std::uint32_t width, std::uint32_t height, const SequenceWorld2DSlot &slot)