Files
godot/scene/resources/blit_material.cpp
Colin O'Rourke 63f6e3691c DrawableTextures
Implementing DrawableTextures based on: https://github.com/godotengine/godot-proposals/issues/7379
2026-01-29 01:16:06 -08:00

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() {
}