#pragma once class render_target; class texture; class slang_handle; class shader { public: virtual ~shader() = default; explicit shader(const std::shared_ptr<slang_handle>& handle) : handle_(handle) {} virtual bool init() { return false; } [[nodiscard]] virtual bool is_initialized() const = 0; [[nodiscard]] virtual bool is_valid() const { return handle_ != nullptr && is_initialized(); } virtual void bind() = 0; virtual void unbind() = 0; virtual void compute(int x, int y, int z) {} virtual void draw(int width, int height, std::shared_ptr<shader> in_vertex_shader = nullptr) {} // param setters virtual void set_constant_buffer(const char* name, void* buffer, int size) = 0; virtual void set_uav_buffer(const char* name, void* buffer, int size, int element_size) {} virtual void set_texture(const char* name, std::shared_ptr<texture> in_texture) = 0; virtual void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) = 0; template<typename T> void set_constant_buffer(const char* name, const T& buffer) { set_constant_buffer(name, (void*)&buffer, sizeof(T)); } template<typename T> void set_constant_buffer(const char* name, const std::vector<T>& buffer) { set_constant_buffer(name, (void*)buffer.data(), sizeof(T) * buffer.size()); } template<typename T> void set_uav_buffer(const char* name, const T& buffer) { set_uav_buffer(name, (void*)&buffer, sizeof(T)); } template<typename T> void set_uav_buffer(const char* name, const std::vector<T>& buffer) { set_uav_buffer(name, (void*)buffer.data(), sizeof(T) * buffer.size()); } protected: std::shared_ptr<slang_handle> handle_; };