diff options
Diffstat (limited to 'source/blender/compositor/realtime_compositor/intern/conversion_operation.cc')
-rw-r--r-- | source/blender/compositor/realtime_compositor/intern/conversion_operation.cc | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc new file mode 100644 index 00000000000..d6bf74ffbee --- /dev/null +++ b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_math_vec_types.hh" + +#include "GPU_shader.h" + +#include "COM_context.hh" +#include "COM_conversion_operation.hh" +#include "COM_input_descriptor.hh" +#include "COM_result.hh" +#include "COM_utilities.hh" + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------- + * Conversion Operation. + */ + +void ConversionOperation::execute() +{ + Result &result = get_result(); + const Result &input = get_input(); + + if (input.is_single_value()) { + result.allocate_single_value(); + execute_single(input, result); + return; + } + + result.allocate_texture(input.domain()); + + GPUShader *shader = get_conversion_shader(); + GPU_shader_bind(shader); + + input.bind_as_texture(shader, "input_tx"); + result.bind_as_image(shader, "output_img"); + + compute_dispatch_threads_at_least(shader, input.domain().size); + + input.unbind_as_texture(); + result.unbind_as_image(); + GPU_shader_unbind(); +} + +SimpleOperation *ConversionOperation::construct_if_needed(Context &context, + const Result &input_result, + const InputDescriptor &input_descriptor) +{ + ResultType result_type = input_result.type(); + ResultType expected_type = input_descriptor.type; + + /* If the result type differs from the expected type, return an instance of an appropriate + * conversion operation. Otherwise, return a null pointer. */ + + if (result_type == ResultType::Float && expected_type == ResultType::Vector) { + return new ConvertFloatToVectorOperation(context); + } + + if (result_type == ResultType::Float && expected_type == ResultType::Color) { + return new ConvertFloatToColorOperation(context); + } + + if (result_type == ResultType::Color && expected_type == ResultType::Float) { + return new ConvertColorToFloatOperation(context); + } + + if (result_type == ResultType::Color && expected_type == ResultType::Vector) { + return new ConvertColorToVectorOperation(context); + } + + if (result_type == ResultType::Vector && expected_type == ResultType::Float) { + return new ConvertVectorToFloatOperation(context); + } + + if (result_type == ResultType::Vector && expected_type == ResultType::Color) { + return new ConvertVectorToColorOperation(context); + } + + return nullptr; +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Float To Vector Operation. + */ + +ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Float; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Vector, texture_pool())); +} + +void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &output) +{ + output.set_vector_value(float3(input.get_float_value())); +} + +GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_float_to_vector"); +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Float To Color Operation. + */ + +ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Float; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Color, texture_pool())); +} + +void ConvertFloatToColorOperation::execute_single(const Result &input, Result &output) +{ + float4 color = float4(input.get_float_value()); + color[3] = 1.0f; + output.set_color_value(color); +} + +GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_float_to_color"); +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Color To Float Operation. + */ + +ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Color; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Float, texture_pool())); +} + +void ConvertColorToFloatOperation::execute_single(const Result &input, Result &output) +{ + float4 color = input.get_color_value(); + output.set_float_value((color[0] + color[1] + color[2]) / 3.0f); +} + +GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_color_to_float"); +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Color To Vector Operation. + */ + +ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Color; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Vector, texture_pool())); +} + +void ConvertColorToVectorOperation::execute_single(const Result &input, Result &output) +{ + float4 color = input.get_color_value(); + output.set_vector_value(float3(color)); +} + +GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_color_to_vector"); +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Vector To Float Operation. + */ + +ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Vector; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Float, texture_pool())); +} + +void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &output) +{ + float3 vector = input.get_vector_value(); + output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f); +} + +GPUShader *ConvertVectorToFloatOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_vector_to_float"); +} + +/* ------------------------------------------------------------------------------------------------- + * Convert Vector To Color Operation. + */ + +ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context) + : ConversionOperation(context) +{ + InputDescriptor input_descriptor; + input_descriptor.type = ResultType::Vector; + declare_input_descriptor(input_descriptor); + populate_result(Result(ResultType::Color, texture_pool())); +} + +void ConvertVectorToColorOperation::execute_single(const Result &input, Result &output) +{ + output.set_color_value(float4(input.get_vector_value(), 1.0f)); +} + +GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const +{ + return shader_manager().get("compositor_convert_vector_to_color"); +} + +} // namespace blender::realtime_compositor |