violet
Simple, cross-platform graphics API
Loading...
Searching...
No Matches
render.h
1#ifndef __VIOLET_RENDE_H__
2#define __VIOLET_RENDE_H__
3
4#include <array>
5#include <functional>
6#include <optional>
7#include <vector>
8
9#include "error.h"
10#include "id.h"
11#include "result.h"
12
13namespace violet {
14
15enum class VertexAttributeType { Position, Normal, Color, Texcoord };
16enum class VertexAttributeSize { Float2, Float3, Float4 };
17
19 VertexAttributeSize size;
20 VertexAttributeType type;
21 size_t offset;
22};
23
25 public:
26 void add_attribute(
27 VertexAttributeSize size,
28 VertexAttributeType type,
29 size_t offset
30 ) {
31 attributes.emplace_back(VertexAttribute {size, type, offset});
32 }
33
34 size_t stride {0};
35 std::vector<VertexAttribute> attributes;
36};
37
39 float view_width {0.f};
40 float view_height {0.f};
41 void* native_handle {nullptr};
42};
43
45 enum class Type { Screen, Texture };
46 Type type;
47
48 static const RenderTarget SCREEN;
49};
50
52 enum class Type { Default, Texture };
53 Type type;
54
55 static const DepthTarget DEFAULT;
56};
57
58inline const RenderTarget RenderTarget::SCREEN =
59 RenderTarget {RenderTarget::Type::Screen};
60inline const DepthTarget DepthTarget::DEFAULT =
61 DepthTarget {DepthTarget::Type::Default};
62
63enum class LoadAction { Clear };
64enum class StoreAction { Store };
65
67
68struct ClearColor {
69 float r {0.1f};
70 float g {0.1f};
71 float b {0.1f};
72 float a {0.f};
73};
74
76 RenderTarget target;
77 ClearColor clear_color;
78 LoadAction load_action {LoadAction::Clear};
79 StoreAction store_action {StoreAction::Store};
80};
81
83 DepthTarget target;
84 LoadAction load_action {LoadAction::Clear};
85 StoreAction store_action {StoreAction::Store};
86 bool clear_depth {false};
87};
88
90 void add_color_attachment(
91 const RenderTarget& target,
92 const ClearColor& clear_color = {},
93 LoadAction load_action = LoadAction::Clear,
94 StoreAction store_action = StoreAction::Store
95 ) {
96 color_attachments.emplace_back(RenderPassColorAttachment {
97 target,
98 clear_color,
99 load_action,
100 store_action
101 });
102 }
103
104 void set_depth_attachment(
105 const DepthTarget& target,
106 bool clear_depth = true,
107 LoadAction load_action = LoadAction::Clear,
108 StoreAction store_action = StoreAction::Store
109 ) {
110 depth_attachment = RenderPassDepthAttachment {
111 target,
112 load_action,
113 store_action,
114 clear_depth
115 };
116 }
117
118 std::optional<RenderPassDepthAttachment> depth_attachment;
119 std::vector<RenderPassColorAttachment> color_attachments;
120};
121
122enum class IndexType { Uint16, Uint32 };
123
124struct Buffer {};
125template<typename Backend>
126class RendererImpl;
127
128struct Texture {};
129
130struct Sampler {};
131
132// struct RenderCommandEncoder {
133// RenderCommandEncoder() = default;
134// RenderCommandEncoder(const RenderCommandEncoder&) = delete;
135// RenderCommandEncoder(RenderCommandEncoder&&) noexcept = default;
136// RenderCommandEncoder& operator=(RenderCommandEncoder&&) noexcept = default;
137
138// struct IndexedDrawCall {
139// Handle<Buffer> buffer;
140// size_t count {0};
141// IndexType index_type;
142// };
143
144// struct InstancedDrawCall {
145// size_t start {0};
146// size_t end {0};
147// size_t count {0};
148// };
149
150// struct VertexDrawCall {
151// size_t start {0};
152// size_t end {0};
153// };
154
155// using DrawCall =
156// std::variant<IndexedDrawCall, InstancedDrawCall, VertexDrawCall>;
157
158// struct RenderState {
159// Handle<RenderPipeline> pipeline;
160// size_t current_vertex_slot {0};
161// std::vector<std::pair<Handle<Buffer>, size_t>> vertex_buffers;
162// std::vector<std::tuple<std::unique_ptr<uint8_t[]>, size_t, size_t>>
163// vertex_bytes;
164// std::vector<Handle<Texture>> textures;
165// std::vector<Handle<Sampler>> samplers;
166// std::vector<DrawCall> draws;
167// };
168
169// RenderPassDescriptor m_desc;
170
171// // static constexpr size_t MAX_PIPELINE_STATES = 16;
172// // std::array<RenderState, MAX_PIPELINE_STATES> pipeline_states;
173// std::vector<RenderState> pipeline_states;
174// size_t m_pipeline_count {0};
175
176// RenderState* current_state {nullptr};
177
178// void set_pipeline(const Handle<RenderPipeline>& pipeline) {
179// pipeline_states.push_back(RenderState {pipeline});
180// current_state = &pipeline_states.back();
181// current_state->pipeline = pipeline;
182// current_state->vertex_buffers.clear();
183// current_state->vertex_bytes.clear();
184// ++m_pipeline_count;
185// }
186
187// void set_vertex_buffer(const Handle<Buffer>& handle) {
188// if (!current_state) {
189// return;
190// }
191
192// current_state->vertex_buffers.emplace_back(
193// std::make_pair(handle, current_state->current_vertex_slot)
194// );
195
196// ++current_state->current_vertex_slot;
197// }
198
199// template<typename T>
200// void set_vertex_bytes(T* data, size_t size) {
201// if (!current_state) {
202// return;
203// }
204
205// auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
206// std::memcpy(buffer.get(), data, size);
207
208// current_state->vertex_bytes.emplace_back(std::make_tuple(
209// std::move(buffer),
210// size,
211// current_state->current_vertex_slot
212// ));
213// ++current_state->current_vertex_slot;
214// }
215
216// void set_texture(const Handle<Texture>& handle) {
217// current_state->textures.emplace_back(handle);
218// }
219
220// void set_sampler(const Handle<Sampler>& handle) {
221// current_state->samplers.emplace_back(handle);
222// }
223
224// void draw(size_t start, size_t end) {
225// current_state->draws.emplace_back(VertexDrawCall {start, end});
226// }
227
228// void draw_indexed(
229// const Handle<Buffer>& handle,
230// size_t count,
231// IndexType index_type = IndexType::Uint16
232// ) {
233// current_state->draws.emplace_back(
234// IndexedDrawCall {handle, count, index_type}
235// );
236// }
237
238// void draw_instanced(size_t start, size_t end, size_t count) {
239// current_state->draws.emplace_back(InstancedDrawCall {start, end, count}
240// );
241// }
242// };
243
244enum class TextureWrapMode { ClampToEdge, Repeat, Mirror };
245enum class TextureFilterMode { Linear, Nearest };
246
247enum class TextureFormat { RGBA8Unorm };
248enum class TextureDimension { D2, D3, D2Array };
249
251 int width {0};
252 int height {0};
253 int channels {0};
254 void* data {nullptr};
255 size_t array_layers {2};
256 TextureDimension dimension {TextureDimension::D2};
257 TextureFormat format {TextureFormat::RGBA8Unorm};
258 size_t len {0};
259};
260
262 TextureWrapMode wrap_mode {TextureWrapMode::ClampToEdge};
263 TextureFilterMode filter_mode {TextureFilterMode::Linear};
264};
265
266template<typename Encoder>
268 Encoder encoder;
269
270 inline void set_pipeline(const Handle<RenderPipeline>& pipeline);
271
272 inline void set_vertex_buffer(const Handle<Buffer>& handle);
273
274 template<typename T>
275 inline void set_vertex_bytes(const T* data, size_t size);
276
277 inline void set_texture(const Handle<Texture>& handle);
278
279 inline void set_sampler(const Handle<Sampler>& handle);
280
281 inline void draw(size_t start, size_t end);
282
283 inline void draw_indexed(
284 const Handle<Buffer>& handle,
285 size_t count,
286 IndexType index_type = IndexType::Uint16
287 );
288
289 inline void draw_instanced(size_t start, size_t end, size_t count);
290
291 inline void submit();
292};
293
294template<typename Backend>
296 public:
297 using EncoderType = typename Backend::EncoderType;
298
299 // template<typename RenderEncoder>
300 // struct RenderCommandEncoder {
301 // RenderCommandEncoder(const RenderPassDescriptor& desc) :
302
303 // descriptor(desc) {}
304
305 // RenderCommandEncoder(const RenderCommandEncoder&) = delete;
306 // RenderCommandEncoder(RenderCommandEncoder&&) noexcept = default;
307 // RenderCommandEncoder&
308 // operator=(RenderCommandEncoder&&) noexcept = default;
309
310 // Backend& m_backend;
311 // RenderPassDescriptor descriptor;
312
313 // struct IndexedDrawCall {
314 // Handle<Buffer> buffer;
315 // size_t count {0};
316 // IndexType index_type;
317 // };
318
319 // struct InstancedDrawCall {
320 // size_t start {0};
321 // size_t end {0};
322 // size_t count {0};
323 // };
324
325 // struct VertexDrawCall {
326 // size_t start {0};
327 // size_t end {0};
328 // };
329
330 // using DrawCall =
331 // std::variant<IndexedDrawCall, InstancedDrawCall, VertexDrawCall>;
332
333 // struct RenderPipelineState {
334 // Handle<RenderPipeline> pipeline_handle;
335 // std::vector<std::pair<size_t, Handle<Buffer>>> vertex_buffers;
336 // std::vector<std::tuple<size_t, const uint8_t*, size_t>>
337 // vertex_bytes;
338 // std::vector<std::pair<size_t, Handle<Texture>>> textures;
339 // std::vector<std::pair<size_t, Handle<Sampler>>> samplers;
340 // std::vector<DrawCall> draw_calls;
341 // // size_t current_vertex_buffer_slot {0};
342 // // size_t current_texture_slot {0};
343 // // size_t current_sampler_slot {0};
344 // };
345
346 // std::vector<RenderPipelineState> states;
347
348 // void set_pipeline(const Handle<RenderPipeline>& handle) {
349 // m_current_vertex_buffer_slot = 0;
350 // m_current_texture_slot = 0;
351 // m_current_sampler_slot = 0;
352 // states.push_back(RenderPipelineState {handle});
353 // }
354
355 // void set_vertex_buffer(const Handle<Buffer>& handle) {
356 // states.back().vertex_buffers.emplace_back(
357 // std::make_pair(m_current_vertex_buffer_slot, handle)
358 // );
359 // ++m_current_vertex_buffer_slot;
360 // }
361
362 // template<typename T>
363 // void set_vertex_bytes(const T* data, size_t size) {
364 // states.back().vertex_bytes.emplace_back(std::make_tuple(
365 // m_current_vertex_buffer_slot,
366 // reinterpret_cast<const uint8_t*>(data),
367 // size
368 // ));
369 // ++m_current_vertex_buffer_slot;
370 // }
371
372 // void set_texture(const Handle<Texture>& handle) {
373 // states.back().textures.emplace_back(
374 // std::make_pair(m_current_texture_slot, handle)
375 // );
376 // ++m_current_texture_slot;
377 // }
378
379 // void set_sampler(const Handle<Sampler>& handle) {
380 // states.back().samplers.emplace_back(
381 // std::make_pair(m_current_sampler_slot, handle)
382 // );
383 // ++m_current_sampler_slot;
384 // }
385
386 // void draw(size_t start, size_t end) {
387 // states.back().draw_calls.emplace_back(VertexDrawCall {start, end});
388 // }
389
390 // void draw_indexed(
391 // const Handle<Buffer>& handle,
392 // size_t count,
393 // IndexType index_type = IndexType::Uint16
394 // ) {
395 // states.back().draw_calls.emplace_back(
396 // IndexedDrawCall {handle, count, index_type}
397 // );
398 // }
399
400 // void draw_instanced(size_t start, size_t end, size_t count) {
401 // states.back().draw_calls.emplace_back(
402 // InstancedDrawCall {start, end, count}
403 // );
404 // }
405
406 // private:
407 // friend class RendererImpl<Backend>;
408 // size_t m_current_vertex_buffer_slot {0};
409 // size_t m_current_texture_slot {0};
410 // size_t m_current_sampler_slot {0};
411
412 // // void apply(EncoderType& encoder) {
413 // // for (const auto& command : m_commands) {
414 // // command(encoder);
415 // // }
416 // // }
417
418 // std::vector<std::function<void(EncoderType&)>> m_commands;
419 // };
420
422 Result<Handle<RenderPipeline>, Error> create_render_pipeline(
423 const std::string& label,
424 const std::string& shader_source,
425 const VertexLayoutDescriptor& desc
426 );
427
429 create_render_command_encoder(const RenderPassDescriptor& desc);
430 // return RenderCommandEncoder
431 // m_encoders.push_back(RenderCommandEncoder {m_backend, desc});
432 // return m_encoders.back();
433 // }
434
435 Result<Handle<Texture>, Error> create_texture(const CreateTextureDesc& desc
436 );
437 Result<Handle<Sampler>, Error> create_sampler(const CreateSamplerDesc& desc
438 );
439
440 template<typename T>
441 Result<Handle<Buffer>, Error> create_buffer(T data, size_t size);
442
443 template<typename T>
445 update_buffer(const Handle<Buffer>& handle, T data, size_t size);
446
447 template<typename T>
448 void
449 update_buffer_unchecked(const Handle<Buffer>& handle, T data, size_t size);
450
451 // void render();
452
453 private:
454 Backend m_backend;
455 float m_view_width {0.f};
456 float m_view_height {0.f};
457};
458
459} // namespace violet
460
461#endif
Definition error.h:10
Definition render.h:295
Definition result.h:16
Definition render.h:24
Definition render.h:124
Definition render.h:68
Definition render.h:261
Definition render.h:250
size_t array_layers
number of layers if dimension is D2Array
Definition render.h:255
Definition render.h:51
Definition id.h:9
Definition render.h:267
Definition render.h:75
Definition render.h:82
Definition render.h:89
Definition render.h:66
Definition render.h:44
Definition render.h:38
Definition render.h:130
Definition render.h:128
Definition render.h:18