mirror of
https://github.com/godotengine/godot.git
synced 2026-02-07 19:32:36 +00:00
Implementing DrawableTextures based on: https://github.com/godotengine/godot-proposals/issues/7379
141 lines
5.4 KiB
C++
141 lines
5.4 KiB
C++
/**************************************************************************/
|
|
/* blit_material.cpp */
|
|
/**************************************************************************/
|
|
/* This file is part of: */
|
|
/* GODOT ENGINE */
|
|
/* https://godotengine.org */
|
|
/**************************************************************************/
|
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/**************************************************************************/
|
|
|
|
#include "blit_material.h"
|
|
|
|
#include "core/version.h"
|
|
|
|
void BlitMaterial::_update_shader(BlendMode p_blend) {
|
|
MutexLock shader_lock(shader_mutex);
|
|
int index = int(p_blend);
|
|
if (shader_cache[p_blend].is_null()) {
|
|
shader_cache[p_blend] = RS::get_singleton()->shader_create();
|
|
String code = "// NOTE: Shader automatically converted from " GODOT_VERSION_NAME " " GODOT_VERSION_FULL_CONFIG "'s BlitMaterial.\n\n";
|
|
|
|
code += "shader_type texture_blit;\nrender_mode ";
|
|
switch (p_blend) {
|
|
case BLEND_MODE_MIX:
|
|
code += "blend_mix";
|
|
break;
|
|
case BLEND_MODE_ADD:
|
|
code += "blend_add";
|
|
break;
|
|
case BLEND_MODE_SUB:
|
|
code += "blend_sub";
|
|
break;
|
|
case BLEND_MODE_MUL:
|
|
code += "blend_mul";
|
|
break;
|
|
case BLEND_MODE_DISABLED:
|
|
code += "blend_disabled";
|
|
break;
|
|
default:
|
|
code += "blend_mix";
|
|
break;
|
|
}
|
|
code += ";\n\n";
|
|
|
|
code += "uniform sampler2D source_texture0 : hint_blit_source0;\n";
|
|
code += "uniform sampler2D source_texture1 : hint_blit_source1;\n";
|
|
code += "uniform sampler2D source_texture2 : hint_blit_source2;\n";
|
|
code += "uniform sampler2D source_texture3 : hint_blit_source3;\n\n";
|
|
|
|
code += "void blit() {\n";
|
|
code += " // Copies from each whole source texture to a rect on each output texture.\n";
|
|
code += " COLOR0 = texture(source_texture0, UV) * MODULATE;\n";
|
|
code += " COLOR1 = texture(source_texture1, UV) * MODULATE;\n";
|
|
code += " COLOR2 = texture(source_texture2, UV) * MODULATE;\n";
|
|
code += " COLOR3 = texture(source_texture3, UV) * MODULATE;\n}";
|
|
RS::get_singleton()->shader_set_code(shader_cache[index], code);
|
|
}
|
|
}
|
|
|
|
void BlitMaterial::set_blend_mode(BlendMode p_blend_mode) {
|
|
blend_mode = p_blend_mode;
|
|
_update_shader(blend_mode);
|
|
if (shader_set) {
|
|
RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(blend_mode)]);
|
|
}
|
|
}
|
|
|
|
BlitMaterial::BlendMode BlitMaterial::get_blend_mode() const {
|
|
return blend_mode;
|
|
}
|
|
|
|
RID BlitMaterial::get_shader_rid() const {
|
|
_update_shader(blend_mode);
|
|
return shader_cache[int(blend_mode)];
|
|
}
|
|
|
|
Shader::Mode BlitMaterial::get_shader_mode() const {
|
|
return Shader::MODE_TEXTURE_BLIT;
|
|
}
|
|
|
|
RID BlitMaterial::get_rid() const {
|
|
_update_shader(blend_mode);
|
|
if (!shader_set) {
|
|
RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(blend_mode)]);
|
|
shader_set = true;
|
|
}
|
|
return _get_material();
|
|
}
|
|
|
|
Mutex BlitMaterial::shader_mutex;
|
|
RID BlitMaterial::shader_cache[5];
|
|
|
|
void BlitMaterial::cleanup_shader() {
|
|
for (int i = 0; i < 5; i++) {
|
|
if (shader_cache[i].is_valid()) {
|
|
RS::get_singleton()->free_rid(shader_cache[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlitMaterial::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &BlitMaterial::set_blend_mode);
|
|
ClassDB::bind_method(D_METHOD("get_blend_mode"), &BlitMaterial::get_blend_mode);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply,Disabled"), "set_blend_mode", "get_blend_mode");
|
|
|
|
BIND_ENUM_CONSTANT(BLEND_MODE_MIX);
|
|
BIND_ENUM_CONSTANT(BLEND_MODE_ADD);
|
|
BIND_ENUM_CONSTANT(BLEND_MODE_SUB);
|
|
BIND_ENUM_CONSTANT(BLEND_MODE_MUL);
|
|
BIND_ENUM_CONSTANT(BLEND_MODE_DISABLED);
|
|
}
|
|
|
|
BlitMaterial::BlitMaterial() {
|
|
_set_material(RS::get_singleton()->material_create());
|
|
set_blend_mode(BLEND_MODE_MIX);
|
|
}
|
|
|
|
BlitMaterial::~BlitMaterial() {
|
|
}
|