summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct7
-rw-r--r--core/image.cpp16
-rw-r--r--core/image.h2
-rw-r--r--doc/base/classes.xml2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp17
-rw-r--r--drivers/gles3/shader_gles3.cpp3
-rw-r--r--drivers/gles3/shaders/scene.glsl42
-rw-r--r--editor/SCsub149
-rw-r--r--editor/editor_node.cpp103
-rw-r--r--editor/editor_node.h5
-rw-r--r--editor/import/resource_importer_wav.cpp11
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp6
-rw-r--r--editor/plugins/editor_preview_plugins.cpp6
-rw-r--r--editor/plugins/shader_graph_editor_plugin.cpp2
-rw-r--r--editor/script_create_dialog.cpp34
-rw-r--r--editor/script_create_dialog.h2
-rw-r--r--platform/iphone/export/export.cpp347
-rw-r--r--platform/iphone/export/export.h30
-rw-r--r--platform/osx/export/export.cpp4
-rw-r--r--platform/x11/os_x11.cpp26
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--scene/resources/material.cpp248
-rw-r--r--scene/resources/material.h61
-rw-r--r--servers/visual/shader_language.cpp3
-rw-r--r--servers/visual/shader_types.cpp5
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp2368
27 files changed, 2296 insertions, 1208 deletions
diff --git a/SConstruct b/SConstruct
index e745d7bb15..a403117065 100644
--- a/SConstruct
+++ b/SConstruct
@@ -87,6 +87,13 @@ env_base.disabled_modules = []
env_base.use_ptrcall = False
env_base.split_drivers = False
+# To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
+# http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
+env_base.Decider('MD5-timestamp')
+# Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
+# http://scons.org/doc/production/HTML/scons-user/ch06s04.html
+env_base.SetOption('implicit_cache', 1)
+
env_base.__class__.android_add_maven_repository = methods.android_add_maven_repository
env_base.__class__.android_add_dependency = methods.android_add_dependency
diff --git a/core/image.cpp b/core/image.cpp
index 023a058667..76f21a25de 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -423,7 +423,7 @@ void Image::convert(Format p_new_format) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
- new_img.put_pixel(i, j, get_pixel(i, j));
+ new_img.set_pixel(i, j, get_pixel(i, j));
}
}
@@ -1737,7 +1737,7 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g);
dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b);
dc.a = (double)(sc.a + dc.a * (1.0 - sc.a));
- put_pixel(dst_x, dst_y, dc);
+ set_pixel(dst_x, dst_y, dc);
}
}
@@ -1792,7 +1792,7 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g);
dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b);
dc.a = (double)(sc.a + dc.a * (1.0 - sc.a));
- put_pixel(dst_x, dst_y, dc);
+ set_pixel(dst_x, dst_y, dc);
}
}
}
@@ -1812,7 +1812,7 @@ void Image::fill(const Color &c) {
int pixel_size = get_format_pixel_size(format);
// put first pixel with the format-aware API
- put_pixel(0, 0, c);
+ set_pixel(0, 0, c);
for (int y = 0; y < height; y++) {
@@ -2041,12 +2041,12 @@ Color Image::get_pixel(int p_x, int p_y) const {
return Color();
}
-void Image::put_pixel(int p_x, int p_y, const Color &p_color) {
+void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
uint8_t *ptr = write_lock.ptr();
#ifdef DEBUG_ENABLED
if (!ptr) {
- ERR_EXPLAIN("Image must be locked with 'lock()' before using put_pixel()");
+ ERR_EXPLAIN("Image must be locked with 'lock()' before using set_pixel()");
ERR_FAIL_COND(!ptr);
}
@@ -2160,7 +2160,7 @@ void Image::put_pixel(int p_x, int p_y, const Color &p_color) {
} break;
default: {
- ERR_EXPLAIN("Can't put_pixel() on compressed image, sorry.");
+ ERR_EXPLAIN("Can't set_pixel() on compressed image, sorry.");
ERR_FAIL();
}
}
@@ -2270,7 +2270,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("lock"), &Image::lock);
ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock);
- ClassDB::bind_method(D_METHOD("put_pixel", "x", "y", "color"), &Image::put_pixel);
+ ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel);
ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel);
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
diff --git a/core/image.h b/core/image.h
index e523f703fa..7acc4744e9 100644
--- a/core/image.h
+++ b/core/image.h
@@ -315,7 +315,7 @@ public:
DetectChannels get_detected_channels();
Color get_pixel(int p_x, int p_y) const;
- void put_pixel(int p_x, int p_y, const Color &p_color);
+ void set_pixel(int p_x, int p_y, const Color &p_color);
void copy_internals_from(const Ref<Image> &p_image) {
ERR_FAIL_COND(p_image.is_null());
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 39f5c94a94..6ff3e0fa29 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -19218,7 +19218,7 @@
<description>
</description>
</method>
- <method name="put_pixel">
+ <method name="set_pixel">
<argument index="0" name="x" type="int">
</argument>
<argument index="1" name="y" type="int">
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 6c568714f8..0bcfaf1839 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -304,6 +304,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
uniform_sizes.resize(max_uniforms);
uniform_alignments.resize(max_uniforms);
uniform_defines.resize(max_uniforms);
+ bool uses_uniforms = false;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
@@ -323,9 +324,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key());
r_gen_code.texture_hints[E->get().texture_order] = E->get().hint;
} else {
- if (r_gen_code.uniforms.empty()) {
+ if (!uses_uniforms) {
r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
+ uses_uniforms = true;
}
uniform_defines[E->get().order] = ucode;
uniform_sizes[E->get().order] = _get_datatype_size(E->get().type);
@@ -651,6 +653,14 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
_dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode]);
+ if (r_gen_code.uniform_total_size) { //uniforms used?
+ int md = sizeof(float) * 4;
+ if (r_gen_code.uniform_total_size % md) {
+ r_gen_code.uniform_total_size += md - (r_gen_code.uniform_total_size % md);
+ }
+ r_gen_code.uniform_total_size += md; //pad just in case
+ }
+
return OK;
}
@@ -700,7 +710,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n";
- actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
@@ -775,7 +785,8 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
- actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index c821acadf5..33a7c9a22f 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -416,7 +416,8 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
strings.push_back(fragment_code4.get_data());
#ifdef DEBUG_SHADER
- DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
+ DEBUG_PRINT("\nFragment Globals:\n\n" + String(code_globals.get_data()));
+ DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string2.get_data()));
for (int i = 0; i < strings.size(); i++) {
//print_line("frag strings "+itos(i)+":"+String(strings[i]));
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 29623a6296..cea963503f 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -275,6 +275,19 @@ void main() {
highp mat4 modelview = camera_inverse_matrix * world_matrix;
highp mat4 local_projection = projection_matrix;
+//using world coordinates
+#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
+
+ vertex = world_matrix * vertex;
+ normal = normalize((world_matrix * vec4(normal,0.0)).xyz);
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
+
+ tangent = normalize((world_matrix * vec4(tangent,0.0)).xyz);
+ binormal = normalize((world_matrix * vec4(binormal,0.0)).xyz);
+#endif
+#endif
+
//defines that make writing custom shaders easier
#define projection_matrix local_projection
#define world_transform world_matrix
@@ -286,29 +299,42 @@ VERTEX_SHADER_CODE
-
-#if !defined(SKIP_TRANSFORM_USED)
+//using local coordinates (default)
+#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED)
vertex = modelview * vertex;
normal = normalize((modelview * vec4(normal,0.0)).xyz);
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
+
+ tangent = normalize((modelview * vec4(tangent,0.0)).xyz);
+ binormal = normalize((modelview * vec4(binormal,0.0)).xyz);
+#endif
#endif
+//using world coordinates
+#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
- vertex_interp = vertex.xyz;
- normal_interp = normal;
+ vertex = camera_inverse_matrix * vertex;
+ normal = normalize((camera_inverse_matrix * vec4(normal,0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
-#if !defined(SKIP_TRANSFORM_USED)
+ tangent = normalize((camera_inverse_matrix * vec4(tangent,0.0)).xyz);
+ binormal = normalize((camera_inverse_matrix * vec4(binormal,0.0)).xyz);
+#endif
+#endif
- tangent = normalize((modelview * vec4(tangent,0.0)).xyz);
- binormal = normalize((modelview * vec4(binormal,0.0)).xyz);
+ vertex_interp = vertex.xyz;
+ normal_interp = normal;
-#endif
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
tangent_interp = tangent;
binormal_interp = binormal;
#endif
+
#ifdef RENDER_DEPTH
diff --git a/editor/SCsub b/editor/SCsub
index 47bdec2e0d..f0d378c097 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -187,9 +187,11 @@ def make_authors_header(target, source, env):
def make_license_header(target, source, env):
- src = source[0].srcnode().abspath
+ src_copyright = source[0].srcnode().abspath
+ src_license = source[1].srcnode().abspath
dst = target[0].srcnode().abspath
- f = open(src, "rb")
+ f = open(src_license, "rb")
+ fc = open(src_copyright, "rb")
g = open(dst, "wb")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
@@ -201,6 +203,145 @@ def make_license_header(target, source, env):
g.write("\n\t\"" + line.strip().replace("\"", "\\\"") + "\\n\"")
g.write(";\n")
+
+ tp_current = 0
+ tp_file = ""
+ tp_comment = ""
+ tp_copyright = ""
+ tp_license = ""
+
+ tp_licensename = ""
+ tp_licensebody = ""
+
+ tp = []
+ tp_licensetext = []
+ for line in fc:
+ if line.startswith("#"):
+ continue
+
+ if line.startswith("Files:"):
+ tp_file = line[6:].strip()
+ tp_current = 1
+ elif line.startswith("Comment:"):
+ tp_comment = line[8:].strip()
+ tp_current = 2
+ elif line.startswith("Copyright:"):
+ tp_copyright = line[10:].strip()
+ tp_current = 3
+ elif line.startswith("License:"):
+ if tp_current != 0:
+ tp_license = line[8:].strip()
+ tp_current = 4
+ else:
+ tp_licensename = line[8:].strip()
+ tp_current = 5
+ elif line.startswith(" "):
+ if tp_current == 1:
+ tp_file += "\n" + line.strip()
+ elif tp_current == 3:
+ tp_copyright += "\n" + line.strip()
+ elif tp_current == 5:
+ if line.strip() == ".":
+ tp_licensebody += "\n"
+ else:
+ tp_licensebody += line[1:]
+ else:
+ if tp_current != 0:
+ if tp_current == 5:
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
+ tp_licensename = ""
+ tp_licensebody = ""
+ else:
+ added = False
+ for i in tp:
+ if i[0] == tp_comment:
+ i[1].append([tp_file, tp_copyright, tp_license])
+ added = True
+ break
+ if not added:
+ tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]])
+
+ tp_file = []
+ tp_comment = ""
+ tp_copyright = []
+ tp_license = ""
+ tp_current = 0
+
+ about_thirdparty = ""
+ about_tp_copyright_count = ""
+ about_tp_license = ""
+ about_tp_copyright = ""
+ about_tp_file = ""
+
+ for i in tp:
+ about_thirdparty += "\t\"" + i[0] + "\",\n"
+ about_tp_copyright_count += str(len(i[1])) + ", "
+ for j in i[1]:
+ file_body = ""
+ copyright_body = ""
+ for k in j[0].split("\n"):
+ if file_body != "":
+ file_body += "\\n\"\n"
+ file_body += "\t\"" + k.strip().replace("\"", "\\\"")
+ for k in j[1].split("\n"):
+ if copyright_body != "":
+ copyright_body += "\\n\"\n"
+ copyright_body += "\t\"" + k.strip().replace("\"", "\\\"")
+
+ about_tp_file += "\t" + file_body + "\",\n"
+ about_tp_copyright += "\t" + copyright_body + "\",\n"
+ about_tp_license += "\t\"" + j[2] + "\",\n"
+
+ about_license_name = ""
+ about_license_body = ""
+
+ for i in tp_licensetext:
+ body = ""
+ for j in i[1].split("\n"):
+ if body != "":
+ body += "\\n\"\n"
+ body += "\t\"" + j.strip().replace("\"", "\\\"")
+
+ about_license_name += "\t\"" + i[0] + "\",\n"
+ about_license_body += "\t" + body + "\",\n"
+
+ g.write("static const char *about_thirdparty[] = {\n")
+ g.write(about_thirdparty)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n")
+
+ g.write("static const int about_tp_copyright_count[] = {\n\t")
+ g.write(about_tp_copyright_count)
+ g.write("0\n};\n")
+
+ g.write("static const char *about_tp_file[] = {\n")
+ g.write(about_tp_file)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_copyright[] = {\n")
+ g.write(about_tp_copyright)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_license[] = {\n")
+ g.write(about_tp_license)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_license_name[] = {\n")
+ g.write(about_license_name)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n")
+
+ g.write("static const char *about_license_body[] = {\n")
+ g.write(about_license_body)
+ g.write("\t0\n")
+ g.write("};\n")
+
g.write("#endif\n")
if (env["tools"] == "yes"):
@@ -254,8 +395,8 @@ if (env["tools"] == "yes"):
env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header)
# License
- env.Depends('#editor/license.gen.h', "../LICENSE.txt")
- env.Command('#editor/license.gen.h', "../LICENSE.txt", make_license_header)
+ env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
+ env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header)
env.add_source_files(env.editor_sources, "*.cpp")
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index c52a133e78..b61f82ffaf 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4948,6 +4948,13 @@ void EditorNode::_check_gui_base_size() {
}
}
+void EditorNode::_license_tree_selected() {
+
+ TreeItem *selected = _tpl_tree->get_selected();
+ _tpl_text->select(0, 0, 0, 0);
+ _tpl_text->set_text(selected->get_metadata(0));
+}
+
void EditorNode::open_export_template_manager() {
export_template_manager->popup_manager();
@@ -5037,6 +5044,8 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout);
ClassDB::bind_method(D_METHOD("_check_gui_base_size"), &EditorNode::_check_gui_base_size);
+ ClassDB::bind_method(D_METHOD("_license_tree_selected"), &EditorNode::_license_tree_selected);
+
ADD_SIGNAL(MethodInfo("play_pressed"));
ADD_SIGNAL(MethodInfo("pause_pressed"));
ADD_SIGNAL(MethodInfo("stop_pressed"));
@@ -6096,6 +6105,7 @@ EditorNode::EditorNode() {
hbc->add_child(logo);
Label *about_text = memnew(Label);
+ about_text->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
about_text->set_text(VERSION_FULL_NAME + String::utf8("\n\u00A9 2007-2017 Juan Linietsky, Ariel Manzur.\n\u00A9 2014-2017 ") +
TTR("Godot Engine contributors") + "\n");
hbc->add_child(about_text);
@@ -6110,15 +6120,6 @@ EditorNode::EditorNode() {
dev_base->set_v_size_flags(Control::SIZE_EXPAND);
tc->add_child(dev_base);
- TextEdit *license = memnew(TextEdit);
- license->set_name(TTR("License"));
- license->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- license->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- license->set_wrap(true);
- license->set_readonly(true);
- license->set_text(String::utf8(about_license));
- tc->add_child(license);
-
VBoxContainer *dev_vbc = memnew(VBoxContainer);
dev_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
dev_base->add_child(dev_vbc);
@@ -6151,6 +6152,90 @@ EditorNode::EditorNode() {
hs->set_modulate(Color(0, 0, 0, 0));
dev_vbc->add_child(hs);
}
+
+ TextEdit *license = memnew(TextEdit);
+ license->set_name(TTR("License"));
+ license->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ license->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ license->set_wrap(true);
+ license->set_readonly(true);
+ license->set_text(String::utf8(about_license));
+ tc->add_child(license);
+
+ VBoxContainer *license_thirdparty = memnew(VBoxContainer);
+ license_thirdparty->set_name(TTR("Thirdparty License"));
+ license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ tc->add_child(license_thirdparty);
+
+ Label *tpl_label = memnew(Label);
+ tpl_label->set_custom_minimum_size(Size2(0, 64 * EDSCALE));
+ tpl_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ tpl_label->set_autowrap(true);
+ tpl_label->set_text(TTR("Godot Engine relies on a number of thirdparty free and open source libraries, all compatible with the terms of its MIT license. The following is an exhaustive list of all such thirdparty components with their respective copyright statements and license terms."));
+ license_thirdparty->add_child(tpl_label);
+
+ HSplitContainer *tpl_hbc = memnew(HSplitContainer);
+ tpl_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ tpl_hbc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ tpl_hbc->set_split_offset(240 * EDSCALE);
+ license_thirdparty->add_child(tpl_hbc);
+
+ _tpl_tree = memnew(Tree);
+ _tpl_tree->set_hide_root(true);
+ TreeItem *root = _tpl_tree->create_item();
+ TreeItem *tpl_ti_all = _tpl_tree->create_item(root);
+ tpl_ti_all->set_text(0, TTR("All Components"));
+ TreeItem *tpl_ti_tp = _tpl_tree->create_item(root);
+ tpl_ti_tp->set_text(0, TTR("Components"));
+ tpl_ti_tp->set_selectable(0, false);
+ TreeItem *tpl_ti_lc = _tpl_tree->create_item(root);
+ tpl_ti_lc->set_text(0, TTR("Licenses"));
+ tpl_ti_lc->set_selectable(0, false);
+ int read_idx = 0;
+ String long_text = "";
+ for (int i = 0; i < THIRDPARTY_COUNT; i++) {
+
+ TreeItem *ti = _tpl_tree->create_item(tpl_ti_tp);
+ String thirdparty = String(about_thirdparty[i]);
+ ti->set_text(0, thirdparty);
+ String text = thirdparty + "\n";
+ long_text += "- " + thirdparty + "\n\n";
+ for (int j = 0; j < about_tp_copyright_count[i]; j++) {
+
+ text += "\n Files:\n " + String(about_tp_file[read_idx]).replace("\n", "\n ") + "\n";
+ String copyright = String::utf8(" \u00A9 ") + String::utf8(about_tp_copyright[read_idx]).replace("\n", String::utf8("\n \u00A9 "));
+ text += copyright;
+ long_text += copyright;
+ String license = "\n License: " + String(about_tp_license[read_idx]) + "\n";
+ text += license;
+ long_text += license + "\n";
+ read_idx++;
+ }
+ ti->set_metadata(0, text);
+ }
+ for (int i = 0; i < LICENSE_COUNT; i++) {
+
+ TreeItem *ti = _tpl_tree->create_item(tpl_ti_lc);
+ String licensename = String(about_license_name[i]);
+ ti->set_text(0, licensename);
+ long_text += "- " + licensename + "\n\n";
+ String licensebody = String(about_license_body[i]);
+ ti->set_metadata(0, licensebody);
+ long_text += " " + licensebody.replace("\n", "\n ") + "\n\n";
+ }
+ tpl_ti_all->set_metadata(0, long_text);
+ tpl_hbc->add_child(_tpl_tree);
+
+ _tpl_text = memnew(TextEdit);
+ _tpl_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ _tpl_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ _tpl_text->set_wrap(true);
+ _tpl_text->set_readonly(true);
+ tpl_hbc->add_child(_tpl_text);
+
+ _tpl_tree->connect("item_selected", this, "_license_tree_selected");
+ tpl_ti_all->select(0);
+ _tpl_text->set_text(tpl_ti_all->get_metadata(0));
}
warning = memnew(AcceptDialog);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 24acedbf26..49ac04243c 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -431,6 +431,9 @@ private:
List<String> previous_scenes;
bool opening_prev;
+ Tree *_tpl_tree;
+ TextEdit *_tpl_text;
+
void _dialog_action(String p_file);
void _edit_current();
@@ -636,6 +639,8 @@ private:
void _dim_timeout();
void _check_gui_base_size();
+ void _license_tree_selected();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 7841baa02e..18c4bed5dd 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -153,6 +153,8 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
uint16_t compression_code = file->get_16();
+ //Issue: #7755 : Not a bug - usage of other formats (format codes) are unsupported in current importer version.
+ //Consider revision for engine version 3.0
if (compression_code != 1) {
ERR_PRINT("Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead.");
break;
@@ -249,6 +251,15 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
if (chunkID[0] == 's' && chunkID[1] == 'm' && chunkID[2] == 'p' && chunkID[3] == 'l') {
//loop point info!
+ /**
+ * Consider exploring next document:
+ * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/RIFFNEW.pdf
+ * Especially on page:
+ * 16 - 17
+ * Timestamp:
+ * 22:38 06.07.2017 GMT
+ **/
+
for (int i = 0; i < 10; i++)
file->get_32(); // i wish to know why should i do this... no doc!
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index e51254f84b..7ce884a455 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1170,7 +1170,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
canvas_item->edit_set_state(se->undo_state);
if (canvas_item->cast_to<Node2D>())
canvas_item->cast_to<Node2D>()->edit_set_pivot(se->undo_pivot);
- if (canvas_item->cast_to<Node2D>())
+ if (canvas_item->cast_to<Control>())
canvas_item->cast_to<Control>()->set_pivot_offset(se->undo_pivot);
}
}
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index c74eaf21a1..2d05c8eba1 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -874,7 +874,7 @@ Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) {
Color bg_color(0.1, 0.1, 0.1, 1.0);
for (int i = 0; i < thumbnail_size; i++) {
for (int j = 0; j < thumbnail_size; j++) {
- im.put_pixel(i, j, bg_color);
+ im.set_pixel(i, j, bg_color);
}
}
@@ -890,7 +890,7 @@ Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) {
// Plot point
if (y >= 0 && y < im.get_height()) {
- im.put_pixel(x, y, line_color);
+ im.set_pixel(x, y, line_color);
}
// Plot vertical line to fix discontinuity (not 100% correct but enough for a preview)
@@ -904,7 +904,7 @@ Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) {
y1 = y;
}
for (int ly = y0; ly < y1; ++ly) {
- im.put_pixel(x, ly, line_color);
+ im.set_pixel(x, ly, line_color);
}
}
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 11d804422a..7f8581535c 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -431,7 +431,7 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {
for (int i = 0; i < thumbnail_size; i++) {
for (int j = 0; j < thumbnail_size; j++) {
- img->put_pixel(i, j, bg_color);
+ img->set_pixel(i, j, bg_color);
}
}
@@ -469,8 +469,8 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {
Color ul = color;
ul.a *= 0.5;
- img->put_pixel(col, line * 2, bg_color.blend(ul));
- img->put_pixel(col, line * 2 + 1, color);
+ img->set_pixel(col, line * 2, bg_color.blend(ul));
+ img->set_pixel(col, line * 2 + 1, color);
prev_is_text = _is_text_char(c);
}
diff --git a/editor/plugins/shader_graph_editor_plugin.cpp b/editor/plugins/shader_graph_editor_plugin.cpp
index 9c65ef667a..5506c035ec 100644
--- a/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/editor/plugins/shader_graph_editor_plugin.cpp
@@ -1382,7 +1382,7 @@ ToolButton *ShaderGraphView::make_editor(String text,GraphNode* gn,int p_id,int
Color c = graph->default_get_value(type,p_id,param);
for (int x=1;x<14;x++)
for (int y=1;y<14;y++)
- icon_color.put_pixel(x,y,c);
+ icon_color.set_pixel(x,y,c);
Ref<ImageTexture> t;
t.instance();
t->create_from_image(icon_color);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 00fdcb676b..47675bcffe 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -58,6 +58,7 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
file_path->set_text("");
}
_lang_changed(current_language);
+ _template_changed(template_menu->get_selected());
_parent_name_changed(parent_name->get_text());
_class_name_changed("");
_path_changed(file_path->get_text());
@@ -118,13 +119,15 @@ void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
void ScriptCreateDialog::_template_changed(int p_template) {
+ String selected_template = p_template == 0 ? "" : template_menu->get_item_text(template_menu->get_selected());
+ EditorSettings::get_singleton()->set_project_metadata("script_setup", "last_selected_template", selected_template);
if (p_template == 0) {
//default
script_template = "";
return;
}
String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension();
- String name = template_menu->get_item_text(p_template) + "." + ext;
+ String name = template_list[p_template - 1] + "." + ext;
script_template = EditorSettings::get_singleton()->get_settings_path() + "/script_templates/" + name;
}
@@ -148,15 +151,19 @@ void ScriptCreateDialog::_create_new() {
Ref<Script> scr;
if (script_template != "") {
- scr = ResourceLoader::load(script_template)->duplicate();
+ scr = ResourceLoader::load(script_template);
+ if (scr.is_null()) {
+ alert->get_ok()->set_text(TTR("OK"));
+ alert->set_text(vformat(TTR("Error loading template '%s'"), script_template));
+ alert->popup_centered();
+ return;
+ }
+ scr = scr->duplicate();
ScriptServer::get_language(language_menu->get_selected())->make_template(cname, parent_name->get_text(), scr);
} else {
scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
}
- String selected_language = language_menu->get_item_text(language_menu->get_selected());
- editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
-
if (cname != "")
scr->set_name(cname);
@@ -240,13 +247,22 @@ void ScriptCreateDialog::_lang_changed(int l) {
bool use_templates = language->is_using_templates();
template_menu->set_disabled(!use_templates);
if (use_templates) {
- Vector<String> template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+ template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+
+ String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
+ String last_template = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_template", "");
template_menu->clear();
template_menu->add_item(TTR("Default"));
for (int i = 0; i < template_list.size(); i++) {
- template_menu->add_item(template_list[i].capitalize());
+ String s = template_list[i].capitalize();
+ template_menu->add_item(s);
+ if (language_menu->get_item_text(l) == last_lang && last_template == s) {
+ template_menu->select(i + 1);
+ }
}
+ _template_changed(template_menu->get_selected());
+ EditorSettings::get_singleton()->set_project_metadata("script_setup", "last_selected_language", language_menu->get_item_text(l));
}
_update_dialog();
@@ -506,8 +522,6 @@ void ScriptCreateDialog::_bind_methods() {
ScriptCreateDialog::ScriptCreateDialog() {
- editor_settings = EditorSettings::get_singleton();
-
GridContainer *gc = memnew(GridContainer);
VBoxContainer *vb = memnew(VBoxContainer);
HBoxContainer *hb = memnew(HBoxContainer);
@@ -613,7 +627,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
}
}
- String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
+ String last_selected_language = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
if (last_selected_language != "") {
for (int i = 0; i < language_menu->get_item_count(); i++) {
if (language_menu->get_item_text(i) == last_selected_language) {
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 1adbfe3f7d..f503b878f5 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -59,7 +59,6 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool create_new;
bool is_browsing_parent;
String initial_bp;
- EditorSettings *editor_settings;
bool is_new_script_created;
bool is_path_valid;
bool has_named_classes;
@@ -70,6 +69,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
int current_language;
bool re_check_path;
String script_template;
+ Vector<String> template_list;
void _path_changed(const String &p_path = String());
void _lang_changed(int l = 0);
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
new file mode 100644
index 0000000000..0960ec8791
--- /dev/null
+++ b/platform/iphone/export/export.cpp
@@ -0,0 +1,347 @@
+/*************************************************************************/
+/* export.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "export.h"
+#include "editor/editor_export.h"
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
+#include "global_config.h"
+#include "io/marshalls.h"
+#include "io/resource_saver.h"
+#include "io/zip_io.h"
+#include "os/file_access.h"
+#include "os/os.h"
+#include "platform/osx/logo.gen.h"
+#include "string.h"
+#include "version.h"
+
+#include <sys/stat.h>
+
+class EditorExportPlatformIOS : public EditorExportPlatform {
+
+ GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
+
+ int version_code;
+
+ Ref<ImageTexture> logo;
+
+ void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary);
+
+protected:
+ virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
+ virtual void get_export_options(List<ExportOption> *r_options);
+
+public:
+ virtual String get_name() const { return "iOS"; }
+ virtual Ref<Texture> get_logo() const { return logo; }
+
+ virtual String get_binary_extension() const { return "xcodeproj"; }
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
+
+ virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
+
+ EditorExportPlatformIOS();
+ ~EditorExportPlatformIOS();
+};
+
+void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
+
+ // what does this need to do?
+}
+
+void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
+ // r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier"), "org.godotengine.iosgame"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "godotiosgame"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/bits_mode", PROPERTY_HINT_ENUM, "Fat (32 & 64 bits),64 bits,32 bits"), 1));
+
+ /* probably need some more info */
+}
+
+void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary) {
+
+ String str;
+ String strnew;
+ str.parse_utf8((const char *)pfile.ptr(), pfile.size());
+ Vector<String> lines = str.split("\n");
+ for (int i = 0; i < lines.size(); i++) {
+ if (lines[i].find("$binary") != -1) {
+ strnew += lines[i].replace("$binary", p_binary) + "\n";
+ } else if (lines[i].find("$name") != -1) {
+ strnew += lines[i].replace("$name", p_name) + "\n";
+ } else if (lines[i].find("$info") != -1) {
+ strnew += lines[i].replace("$info", p_preset->get("application/info")) + "\n";
+ } else if (lines[i].find("$identifier") != -1) {
+ strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n";
+ } else if (lines[i].find("$short_version") != -1) {
+ strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n";
+ } else if (lines[i].find("$version") != -1) {
+ strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n";
+ } else if (lines[i].find("$signature") != -1) {
+ strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n";
+ } else if (lines[i].find("$copyright") != -1) {
+ strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n";
+ } else {
+ strnew += lines[i] + "\n";
+ }
+ }
+
+ // !BAS! I'm assuming the 9 in the original code was a typo. I've added -1 or else it seems to also be adding our terminating zero...
+ // should apply the same fix in our OSX export.
+ CharString cs = strnew.utf8();
+ pfile.resize(cs.size() - 1);
+ for (int i = 0; i < cs.size() - 1; i++) {
+ pfile[i] = cs[i];
+ }
+}
+
+Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ String src_pkg_name;
+ String dest_dir = p_path.get_base_dir() + "/";
+ String binary_name = p_path.get_file().get_basename();
+
+ EditorProgress ep("export", "Exporting for iOS", 3);
+
+ if (p_debug)
+ src_pkg_name = p_preset->get("custom_package/debug");
+ else
+ src_pkg_name = p_preset->get("custom_package/release");
+
+ if (src_pkg_name == "") {
+ String err;
+ src_pkg_name = find_export_template("iphone.zip", &err);
+ if (src_pkg_name == "") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ ep.step("Creating app", 0);
+
+ unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
+ if (!src_pkg_zip) {
+
+ EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(src_pkg_zip);
+
+ String binary_to_use = "godot.iphone." + String(p_debug ? "debug" : "release") + ".";
+ int bits_mode = p_preset->get("application/bits_mode");
+ binary_to_use += String(bits_mode == 0 ? "fat" : bits_mode == 1 ? "arm64" : "armv7");
+
+ print_line("binary: " + binary_to_use);
+ String pkg_name;
+ if (p_preset->get("application/name") != "")
+ pkg_name = p_preset->get("application/name"); // app_name
+ else if (String(GlobalConfig::get_singleton()->get("application/name")) != "")
+ pkg_name = String(GlobalConfig::get_singleton()->get("application/name"));
+ else
+ pkg_name = "Unnamed";
+
+ DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir);
+ ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE)
+
+ /* Now process our template */
+ bool found_binary = false;
+ int total_size = 0;
+
+ while (ret == UNZ_OK) {
+ bool is_execute = false;
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, NULL, 0, NULL, 0);
+
+ String file = fname;
+
+ print_line("READ: " + file);
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(src_pkg_zip);
+ unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzCloseCurrentFile(src_pkg_zip);
+
+ //write
+
+ file = file.replace_first("iphone/", "");
+
+ if (file == "godot_ios.xcodeproj/project.pbxproj") {
+ print_line("parse pbxproj");
+ _fix_config_file(p_preset, data, pkg_name, binary_name);
+ } else if (file == "godot_ios/godot_ios-Info.plist") {
+ print_line("parse plist");
+ _fix_config_file(p_preset, data, pkg_name, binary_name);
+ } else if (file.begins_with("godot.iphone")) {
+ if (file != binary_to_use) {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; //ignore!
+ }
+ found_binary = true;
+ is_execute = true;
+ file = "godot_ios.iphone";
+ }
+
+ ///@TODO need to parse logo files
+
+ if (data.size() > 0) {
+ file = file.replace("godot_ios", binary_name);
+
+ print_line("ADDING: " + file + " size: " + itos(data.size()));
+ total_size += data.size();
+
+ /* write it into our folder structure */
+ file = dest_dir + file;
+
+ /* make sure this folder exists */
+ String dir_name = file.get_base_dir();
+ if (!tmp_app_path->dir_exists(dir_name)) {
+ print_line("Creating " + dir_name);
+ Error dir_err = tmp_app_path->make_dir_recursive(dir_name);
+ if (dir_err) {
+ ERR_PRINTS("Can't create '" + dir_name + "'.");
+ unzClose(src_pkg_zip);
+ return ERR_CANT_CREATE;
+ }
+ }
+
+ /* write the file */
+ FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
+ if (!f) {
+ ERR_PRINTS("Can't write '" + file + "'.");
+ unzClose(src_pkg_zip);
+ return ERR_CANT_CREATE;
+ };
+ f->store_buffer(data.ptr(), data.size());
+ f->close();
+ memdelete(f);
+
+#ifdef OSX_ENABLED
+ if (is_execute) {
+ // we need execute rights on this file
+ chmod(file.utf8().get_data(), 0755);
+ }
+#endif
+ }
+
+ ret = unzGoToNextFile(src_pkg_zip);
+ }
+
+ /* we're done with our source zip */
+ unzClose(src_pkg_zip);
+
+ if (!found_binary) {
+ ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive.");
+ unzClose(src_pkg_zip);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ep.step("Making PKG", 1);
+
+ String pack_path = dest_dir + binary_name + ".pck";
+ Error err = save_pack(p_preset, pack_path);
+
+ if (err) {
+ return err;
+ }
+
+#ifdef OSX_ENABLED
+ /* and open up xcode with our new project.... */
+ List<String> args;
+ args.push_back(p_path);
+ err = OS::get_singleton()->execute("/usr/bin/open", args, false);
+ ERR_FAIL_COND_V(err, err);
+
+#endif
+
+ return OK;
+}
+
+bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+
+ bool valid = true;
+ String err;
+
+ if (!exists_export_template("iphone.zip", &err)) {
+ valid = false;
+ }
+
+ if (p_preset->get("custom_package/debug") != "" && !FileAccess::exists(p_preset->get("custom_package/debug"))) {
+ valid = false;
+ err += "Custom debug package not found.\n";
+ }
+
+ if (p_preset->get("custom_package/release") != "" && !FileAccess::exists(p_preset->get("custom_package/release"))) {
+ valid = false;
+ err += "Custom release package not found.\n";
+ }
+
+ if (!err.empty())
+ r_error = err;
+
+ return valid;
+}
+
+EditorExportPlatformIOS::EditorExportPlatformIOS() {
+
+ ///@TODO need to create the correct logo
+ // Ref<Image> img = memnew(Image(_iphone_logo));
+ Ref<Image> img = memnew(Image(_osx_logo));
+ logo.instance();
+ logo->create_from_image(img);
+}
+
+EditorExportPlatformIOS::~EditorExportPlatformIOS() {
+}
+
+void register_iphone_exporter() {
+
+ Ref<EditorExportPlatformIOS> platform;
+ platform.instance();
+
+ EditorExport::get_singleton()->add_export_platform(platform);
+}
diff --git a/platform/iphone/export/export.h b/platform/iphone/export/export.h
new file mode 100644
index 0000000000..6e9324aed7
--- /dev/null
+++ b/platform/iphone/export/export.h
@@ -0,0 +1,30 @@
+/*************************************************************************/
+/* export.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+void register_iphone_exporter();
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 9d3493cb49..c81fb00b36 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -185,8 +185,8 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset
}
CharString cs = strnew.utf8();
- plist.resize(cs.size());
- for (int i = 9; i < cs.size(); i++) {
+ plist.resize(cs.size() - 1);
+ for (int i = 0; i < cs.size() - 1; i++) {
plist[i] = cs[i];
}
}
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 383abffe46..f2754cc180 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -278,6 +278,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+ } else if (current_videomode.borderless_window) {
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = 0;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
}
// disable resizable window
@@ -1018,6 +1025,25 @@ bool OS_X11::is_window_maximized() const {
return false;
}
+void OS_X11::set_borderless_window(int p_borderless) {
+
+ if (current_videomode.borderless_window == p_borderless)
+ return;
+
+ current_videomode.borderless_window = p_borderless;
+
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = current_videomode.borderless_window ? 0 : 1;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+}
+
+bool OS_X11::get_borderless_window() {
+ return current_videomode.borderless_window;
+}
+
void OS_X11::request_attention() {
// Using EWMH -- Extended Window Manager Hints
//
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index b253934a05..39c512b6bd 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -251,6 +251,9 @@ public:
virtual bool is_window_maximized() const;
virtual void request_attention();
+ virtual void set_borderless_window(int p_borderless);
+ virtual bool get_borderless_window();
+
virtual void move_window_to_foreground();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 6209f99d9d..d9bd9eca6d 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -198,6 +198,8 @@ void SpatialMaterial::init_shaders() {
shader_names->uv1_offset = "uv1_offset";
shader_names->uv2_scale = "uv2_scale";
shader_names->uv2_offset = "uv2_offset";
+ shader_names->uv1_blend_sharpness = "uv1_blend_sharpness";
+ shader_names->uv2_blend_sharpness = "uv2_blend_sharpness";
shader_names->particle_h_frames = "particle_h_frames";
shader_names->particle_v_frames = "particle_v_frames";
@@ -298,6 +300,9 @@ void SpatialMaterial::_update_shader() {
code += ",ontop";
}
+ if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += ",world_vertex_coords";
+ }
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
@@ -309,10 +314,6 @@ void SpatialMaterial::_update_shader() {
code += "uniform float point_size : hint_range(0,128);\n";
code += "uniform sampler2D texture_metallic : hint_white;\n";
code += "uniform sampler2D texture_roughness : hint_white;\n";
- code += "uniform vec2 uv1_scale;\n";
- code += "uniform vec2 uv1_offset;\n";
- code += "uniform vec2 uv2_scale;\n";
- code += "uniform vec2 uv2_offset;\n";
if (billboard_mode == BILLBOARD_PARTICLES) {
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
@@ -371,6 +372,26 @@ void SpatialMaterial::_update_shader() {
code += "uniform int depth_min_layers;\n";
code += "uniform int depth_max_layers;\n";
}
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "varying vec3 uv1_world_pos;\n";
+ }
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "varying vec3 uv2_world_pos;\n";
+ }
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "uniform float uv1_blend_sharpness;\n";
+ code += "varying vec3 uv1_power_normal;\n";
+ }
+
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "uniform float uv2_blend_sharpness;\n";
+ code += "varying vec3 uv2_power_normal;\n";
+ }
+
+ code += "uniform vec3 uv1_scale;\n";
+ code += "uniform vec3 uv1_offset;\n";
+ code += "uniform vec3 uv2_scale;\n";
+ code += "uniform vec3 uv2_offset;\n";
code += "\n\n";
@@ -384,7 +405,10 @@ void SpatialMaterial::_update_shader() {
code += "\tPOINT_SIZE=point_size;\n";
}
- code += "\tUV=UV*uv1_scale+uv1_offset;\n";
+
+ if (!flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tUV=UV*uv1_scale.xy+uv1_offset.xy;\n";
+ }
switch (billboard_mode) {
case BILLBOARD_DISABLED: {
@@ -414,7 +438,6 @@ void SpatialMaterial::_update_shader() {
//code += "\tUV+= UV * vec2(float(particle_frame % particles_anim_h_frames),float(particle_frame / particles_anim_v_frames));\n";
//handle rotation
// code += "\tmat4 rotation = mat4("
-
} break;
}
@@ -437,20 +460,61 @@ void SpatialMaterial::_update_shader() {
code += "\t}\n";
}
- if (detail_uv == DETAIL_UV_2) {
+ if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "\tUV2=UV2*uv2_scale+uv2_offset;\n";
}
+ if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
+ //generate tangent and binormal in world space
+ code += "\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n";
+ code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n";
+ code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n";
+ code += "\tTANGENT = normalize(TANGENT);\n";
+
+ code += "\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n";
+ code += "\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n";
+ code += "\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n";
+ code += "\tBINORMAL = normalize(BINORMAL);\n";
+ }
+
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+
+ code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
+ code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
+ code += "\tuv1_world_pos = VERTEX * uv1_scale + uv1_offset;\n";
+ code += "\tuv1_world_pos *= vec3(1.0,-1.0, 1.0);\n";
+ }
+
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+
+ code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
+ code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
+ code += "\tuv2_world_pos = VERTEX * uv2_scale + uv2_offset;\n";
+ code += "\tuv2_world_pos *= vec3(1.0,-1.0, 1.0);\n";
+ }
code += "}\n";
code += "\n\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_world_pos) {\n";
+ code += "\tvec4 samp=vec4(0.0);\n";
+ code += "\tsamp+= texture(p_sampler,p_world_pos.xy) * p_weights.z;\n";
+ code += "\tsamp+= texture(p_sampler,p_world_pos.xz) * p_weights.y;\n";
+ code += "\tsamp+= texture(p_sampler,p_world_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n";
+ code += "\treturn samp;\n";
+ code += "}\n";
+ }
+ code += "\n\n";
code += "void fragment() {\n";
- code += "\tvec2 base_uv = UV;\n";
- if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
+ if (!flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec2 base_uv = UV;\n";
+ }
+
+ if ((features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) || (features[FEATURE_AMBIENT_OCCLUSION] && flags[FLAG_AO_ON_UV2])) {
code += "\tvec2 base_uv2 = UV2;\n";
}
- if (features[FEATURE_DEPTH_MAPPING]) {
+ if (features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar
code += "\t{\n";
code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT,-BINORMAL,NORMAL));\n"; //binormal is negative due to mikktpsace
@@ -490,7 +554,11 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_USE_POINT_SIZE]) {
code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
} else {
- code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_world_pos);\n";
+ } else {
+ code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
+ }
}
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
@@ -498,22 +566,39 @@ void SpatialMaterial::_update_shader() {
}
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
- code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tfloat metallic_tex = triplanar_texture(texture_metallic,uv1_power_normal,uv1_world_pos).r;\n";
+ } else {
+ code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n";
+ }
code += "\tMETALLIC = metallic_tex * metallic;\n";
- code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tfloat roughness_tex = triplanar_texture(texture_roughness,uv1_power_normal,uv1_world_pos).r;\n";
+ } else {
+ code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n";
+ }
code += "\tROUGHNESS = roughness_tex * roughness;\n";
code += "\tSPECULAR = specular;\n";
if (features[FEATURE_NORMAL_MAPPING]) {
- code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tNORMALMAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_world_pos).rgb;\n";
+ } else {
+ code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
+ }
code += "\tNORMALMAP_DEPTH = normal_scale;\n";
}
if (features[FEATURE_EMISSION]) {
- code += "\tEMISSION = (emission.rgb+texture(texture_emission,base_uv).rgb)*emission_energy;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_world_pos).rgb;\n";
+ } else {
+ code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n";
+ }
+ code += "\tEMISSION = (emission.rgb+emission_tex)*emission_energy;\n";
}
- if (features[FEATURE_REFRACTION]) {
+ if (features[FEATURE_REFRACTION] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //refraction not supported with triplanar
if (features[FEATURE_NORMAL_MAPPING]) {
code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) ) * SIDE;\n";
@@ -532,38 +617,82 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_RIM]) {
- code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xw;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_world_pos).xy;\n";
+ } else {
+ code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xy;\n";
+ }
code += "\tRIM = rim*rim_tex.x;";
code += "\tRIM_TINT = rim_tint*rim_tex.y;\n";
}
if (features[FEATURE_CLEARCOAT]) {
- code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xw;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_world_pos).xy;\n";
+ } else {
+ code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n";
+ }
code += "\tCLEARCOAT = clearcoat*clearcoat_tex.x;";
code += "\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n";
}
if (features[FEATURE_ANISOTROPY]) {
- code += "\tvec4 anisotropy_tex = texture(texture_flowmap,base_uv);\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_world_pos).rga;\n";
+ } else {
+ code += "\tvec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n";
+ }
code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n";
code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
- code += "\tAO = texture(texture_ambient_occlusion,base_uv).r;\n";
+ if (flags[FLAG_AO_ON_UV2]) {
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "\tAO = triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_world_pos).r;\n";
+ } else {
+ code += "\tAO = texture(texture_ambient_occlusion,base_uv2).r;\n";
+ }
+ } else {
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tAO = triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_world_pos).r;\n";
+ } else {
+ code += "\tAO = texture(texture_ambient_occlusion,base_uv).r;\n";
+ }
+ }
}
if (features[FEATURE_SUBSURACE_SCATTERING]) {
- code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_world_pos).r;\n";
+ } else {
+ code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
+ }
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
if (features[FEATURE_DETAIL]) {
- String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
- code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
- code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
- code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
+
+ bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2);
+
+ if (triplanar) {
+ String tp_uv = detail_uv == DETAIL_UV_1 ? "uv1" : "uv2";
+ code += "\tvec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_world_pos);\n";
+ code += "\tvec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_world_pos);\n";
+
+ } else {
+ String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
+ code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
+ code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
+ }
+
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+
+ code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal);\n";
+ } else {
+ code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
+ }
switch (detail_blend_mode) {
case BLEND_MODE_MIX: {
@@ -581,7 +710,6 @@ void SpatialMaterial::_update_shader() {
}
code += "\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n";
-
code += "\tNORMALMAP = mix(NORMALMAP,detail_norm,detail_mask_tex.r);\n";
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
@@ -971,49 +1099,71 @@ float SpatialMaterial::get_point_size() const {
return point_size;
}
-void SpatialMaterial::set_uv1_scale(const Vector2 &p_scale) {
+void SpatialMaterial::set_uv1_scale(const Vector3 &p_scale) {
uv1_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
-Vector2 SpatialMaterial::get_uv1_scale() const {
+Vector3 SpatialMaterial::get_uv1_scale() const {
return uv1_scale;
}
-void SpatialMaterial::set_uv1_offset(const Vector2 &p_offset) {
+void SpatialMaterial::set_uv1_offset(const Vector3 &p_offset) {
uv1_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector2 SpatialMaterial::get_uv1_offset() const {
+Vector3 SpatialMaterial::get_uv1_offset() const {
return uv1_offset;
}
-void SpatialMaterial::set_uv2_scale(const Vector2 &p_scale) {
+void SpatialMaterial::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
+
+ uv1_triplanar_sharpness = p_sharpness;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
+}
+
+float SpatialMaterial::get_uv1_triplanar_blend_sharpness() const {
+
+ return uv1_triplanar_sharpness;
+}
+
+void SpatialMaterial::set_uv2_scale(const Vector3 &p_scale) {
uv2_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
-Vector2 SpatialMaterial::get_uv2_scale() const {
+Vector3 SpatialMaterial::get_uv2_scale() const {
return uv2_scale;
}
-void SpatialMaterial::set_uv2_offset(const Vector2 &p_offset) {
+void SpatialMaterial::set_uv2_offset(const Vector3 &p_offset) {
uv2_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
-Vector2 SpatialMaterial::get_uv2_offset() const {
+Vector3 SpatialMaterial::get_uv2_offset() const {
return uv2_offset;
}
+void SpatialMaterial::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
+
+ uv2_triplanar_sharpness = p_sharpness;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
+}
+
+float SpatialMaterial::get_uv2_triplanar_blend_sharpness() const {
+
+ return uv2_triplanar_sharpness;
+}
+
void SpatialMaterial::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
@@ -1063,7 +1213,6 @@ void SpatialMaterial::set_depth_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
_queue_shader_change();
_change_notify();
- ;
}
bool SpatialMaterial::is_depth_deep_parallax_enabled() const {
@@ -1177,12 +1326,18 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &SpatialMaterial::set_uv1_offset);
ClassDB::bind_method(D_METHOD("get_uv1_offset"), &SpatialMaterial::get_uv1_offset);
+ ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv1_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &SpatialMaterial::get_uv1_triplanar_blend_sharpness);
+
ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &SpatialMaterial::set_uv2_scale);
ClassDB::bind_method(D_METHOD("get_uv2_scale"), &SpatialMaterial::get_uv2_scale);
ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &SpatialMaterial::set_uv2_offset);
ClassDB::bind_method(D_METHOD("get_uv2_offset"), &SpatialMaterial::get_uv2_offset);
+ ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv2_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &SpatialMaterial::get_uv2_triplanar_blend_sharpness);
+
ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpatialMaterial::set_billboard_mode);
ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpatialMaterial::get_billboard_mode);
@@ -1271,6 +1426,7 @@ void SpatialMaterial::_bind_methods() {
ADD_GROUP("Ambient Occlusion", "ao_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2"), "set_flag", "get_flag", FLAG_AO_ON_UV2);
ADD_GROUP("Depth", "depth_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
@@ -1299,12 +1455,16 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL);
ADD_GROUP("UV1", "uv1_");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv1_scale"), "set_uv1_scale", "get_uv1_scale");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv1_offset"), "set_uv1_offset", "get_uv1_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale"), "set_uv1_scale", "get_uv1_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset"), "set_uv1_offset", "get_uv1_offset");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_TRIPLANAR);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness"), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness");
ADD_GROUP("UV2", "uv2_");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv2_scale"), "set_uv2_scale", "get_uv2_scale");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale"), "set_uv2_scale", "get_uv2_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness"), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness");
BIND_CONSTANT(TEXTURE_ALBEDO);
BIND_CONSTANT(TEXTURE_METALLIC);
@@ -1393,10 +1553,12 @@ SpatialMaterial::SpatialMaterial()
set_refraction(0.05);
set_line_width(1);
set_point_size(1);
- set_uv1_offset(Vector2(0, 0));
- set_uv1_scale(Vector2(1, 1));
- set_uv2_offset(Vector2(0, 0));
- set_uv2_scale(Vector2(1, 1));
+ set_uv1_offset(Vector3(0, 0, 0));
+ set_uv1_scale(Vector3(1, 1, 1));
+ set_uv1_triplanar_blend_sharpness(1);
+ set_uv2_offset(Vector3(0, 0, 0));
+ set_uv2_scale(Vector3(1, 1, 1));
+ set_uv2_triplanar_blend_sharpness(1);
set_billboard_mode(BILLBOARD_DISABLED);
set_particles_anim_h_frames(1);
set_particles_anim_v_frames(1);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index fb6c5b81d9..80732be8de 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -155,6 +155,9 @@ public:
FLAG_SRGB_VERTEX_COLOR,
FLAG_USE_POINT_SIZE,
FLAG_FIXED_SIZE,
+ FLAG_UV1_USE_TRIPLANAR,
+ FLAG_UV2_USE_TRIPLANAR,
+ FLAG_AO_ON_UV2,
FLAG_MAX
};
@@ -176,20 +179,20 @@ private:
union MaterialKey {
struct {
- uint32_t feature_mask : 11;
- uint32_t detail_uv : 1;
- uint32_t blend_mode : 2;
- uint32_t depth_draw_mode : 2;
- uint32_t cull_mode : 2;
- uint32_t flags : 6;
- uint32_t detail_blend_mode : 2;
- uint32_t diffuse_mode : 2;
- uint32_t invalid_key : 1;
- uint32_t deep_parallax : 1;
- uint32_t billboard_mode : 2;
+ uint64_t feature_mask : 11;
+ uint64_t detail_uv : 1;
+ uint64_t blend_mode : 2;
+ uint64_t depth_draw_mode : 2;
+ uint64_t cull_mode : 2;
+ uint64_t flags : 9;
+ uint64_t detail_blend_mode : 2;
+ uint64_t diffuse_mode : 2;
+ uint64_t invalid_key : 1;
+ uint64_t deep_parallax : 1;
+ uint64_t billboard_mode : 2;
};
- uint32_t key;
+ uint64_t key;
bool operator<(const MaterialKey &p_key) const {
return key < p_key.key;
@@ -258,6 +261,8 @@ private:
StringName particles_anim_loop;
StringName depth_min_layers;
StringName depth_max_layers;
+ StringName uv1_blend_sharpness;
+ StringName uv2_blend_sharpness;
StringName texture_names[TEXTURE_MAX];
};
@@ -293,11 +298,13 @@ private:
int particles_anim_v_frames;
bool particles_anim_loop;
- Vector2 uv1_scale;
- Vector2 uv1_offset;
+ Vector3 uv1_scale;
+ Vector3 uv1_offset;
+ float uv1_triplanar_sharpness;
- Vector2 uv2_scale;
- Vector2 uv2_offset;
+ Vector3 uv2_scale;
+ Vector3 uv2_offset;
+ float uv2_triplanar_sharpness;
DetailUV detail_uv;
@@ -411,17 +418,23 @@ public:
void set_feature(Feature p_feature, bool p_enabled);
bool get_feature(Feature p_feature) const;
- void set_uv1_scale(const Vector2 &p_scale);
- Vector2 get_uv1_scale() const;
+ void set_uv1_scale(const Vector3 &p_scale);
+ Vector3 get_uv1_scale() const;
- void set_uv1_offset(const Vector2 &p_offset);
- Vector2 get_uv1_offset() const;
+ void set_uv1_offset(const Vector3 &p_offset);
+ Vector3 get_uv1_offset() const;
- void set_uv2_scale(const Vector2 &p_scale);
- Vector2 get_uv2_scale() const;
+ void set_uv1_triplanar_blend_sharpness(float p_sharpness);
+ float get_uv1_triplanar_blend_sharpness() const;
- void set_uv2_offset(const Vector2 &p_offset);
- Vector2 get_uv2_offset() const;
+ void set_uv2_scale(const Vector3 &p_scale);
+ Vector3 get_uv2_scale() const;
+
+ void set_uv2_offset(const Vector3 &p_offset);
+ Vector3 get_uv2_offset() const;
+
+ void set_uv2_triplanar_blend_sharpness(float p_sharpness);
+ float get_uv2_triplanar_blend_sharpness() const;
void set_billboard_mode(BillboardMode p_mode);
BillboardMode get_billboard_mode() const;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 96d56dfc56..49f9e161fa 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -1357,11 +1357,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
//builtins - exponential
{ "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
- { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
- { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
- { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
{ "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
{ "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index b04c8716fb..c7ffcb5095 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -137,7 +137,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_default_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_vertex_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("world_vertex_coords");
/************ CANVAS ITEM **************************/
@@ -188,7 +189,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_transform");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_vertex_transform");
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mix");
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_add");
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp
index 920a1e143f..5656556db9 100644
--- a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp
@@ -24,208 +24,227 @@ Block4x4Encoding_ETC1 encodes the ETC1 subset of RGB8.
*/
-#include "EtcBlock4x4Encoding_RGB8.h"
#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_RGB8.h"
-#include "EtcBlock4x4.h"
#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
#include "EtcMath.h"
-#include <assert.h>
-#include <float.h>
#include <stdio.h>
#include <string.h>
+#include <assert.h>
+#include <float.h>
#include <limits>
-namespace Etc {
-float Block4x4Encoding_RGB8::s_afTHDistanceTable[TH_DISTANCES] =
+namespace Etc
+{
+ float Block4x4Encoding_RGB8::s_afTHDistanceTable[TH_DISTANCES] =
+ {
+ 3.0f / 255.0f,
+ 6.0f / 255.0f,
+ 11.0f / 255.0f,
+ 16.0f / 255.0f,
+ 23.0f / 255.0f,
+ 32.0f / 255.0f,
+ 41.0f / 255.0f,
+ 64.0f / 255.0f
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_RGB8::Block4x4Encoding_RGB8(void)
+ {
+
+ m_pencodingbitsRGB8 = nullptr;
+
+ }
+
+ Block4x4Encoding_RGB8::~Block4x4Encoding_RGB8(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ // handle ETC1 modes
+ Block4x4Encoding_ETC1::InitFromEncodingBits(a_pblockParent,
+ a_paucEncodingBits, a_pafrgbaSource,a_errormetric);
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
+
+ // detect if there is a T, H or Planar mode present
+ if (m_pencodingbitsRGB8->differential.diff)
{
- 3.0f / 255.0f,
- 6.0f / 255.0f,
- 11.0f / 255.0f,
- 16.0f / 255.0f,
- 23.0f / 255.0f,
- 32.0f / 255.0f,
- 41.0f / 255.0f,
- 64.0f / 255.0f
- };
+ int iRed1 = (int)m_pencodingbitsRGB8->differential.red1;
+ int iDRed2 = m_pencodingbitsRGB8->differential.dred2;
+ int iRed2 = iRed1 + iDRed2;
-// ----------------------------------------------------------------------------------------------------
-//
-Block4x4Encoding_RGB8::Block4x4Encoding_RGB8(void) {
+ int iGreen1 = (int)m_pencodingbitsRGB8->differential.green1;
+ int iDGreen2 = m_pencodingbitsRGB8->differential.dgreen2;
+ int iGreen2 = iGreen1 + iDGreen2;
- m_pencodingbitsRGB8 = nullptr;
-}
+ int iBlue1 = (int)m_pencodingbitsRGB8->differential.blue1;
+ int iDBlue2 = m_pencodingbitsRGB8->differential.dblue2;
+ int iBlue2 = iBlue1 + iDBlue2;
-Block4x4Encoding_RGB8::~Block4x4Encoding_RGB8(void) {}
-// ----------------------------------------------------------------------------------------------------
-// initialization from the encoding bits of a previous encoding
-// a_pblockParent points to the block associated with this encoding
-// a_errormetric is used to choose the best encoding
-// a_pafrgbaSource points to a 4x4 block subset of the source image
-// a_paucEncodingBits points to the final encoding bits of a previous encoding
-//
-void Block4x4Encoding_RGB8::InitFromEncodingBits(Block4x4 *a_pblockParent,
- unsigned char *a_paucEncodingBits,
- ColorFloatRGBA *a_pafrgbaSource,
- ErrorMetric a_errormetric) {
-
- // handle ETC1 modes
- Block4x4Encoding_ETC1::InitFromEncodingBits(a_pblockParent,
- a_paucEncodingBits, a_pafrgbaSource, a_errormetric);
-
- m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
-
- // detect if there is a T, H or Planar mode present
- if (m_pencodingbitsRGB8->differential.diff) {
- int iRed1 = (int)m_pencodingbitsRGB8->differential.red1;
- int iDRed2 = m_pencodingbitsRGB8->differential.dred2;
- int iRed2 = iRed1 + iDRed2;
-
- int iGreen1 = (int)m_pencodingbitsRGB8->differential.green1;
- int iDGreen2 = m_pencodingbitsRGB8->differential.dgreen2;
- int iGreen2 = iGreen1 + iDGreen2;
-
- int iBlue1 = (int)m_pencodingbitsRGB8->differential.blue1;
- int iDBlue2 = m_pencodingbitsRGB8->differential.dblue2;
- int iBlue2 = iBlue1 + iDBlue2;
-
- if (iRed2 < 0 || iRed2 > 31) {
- InitFromEncodingBits_T();
- } else if (iGreen2 < 0 || iGreen2 > 31) {
- InitFromEncodingBits_H();
- } else if (iBlue2 < 0 || iBlue2 > 31) {
- InitFromEncodingBits_Planar();
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ InitFromEncodingBits_T();
+ }
+ else if (iGreen2 < 0 || iGreen2 > 31)
+ {
+ InitFromEncodingBits_H();
+ }
+ else if (iBlue2 < 0 || iBlue2 > 31)
+ {
+ InitFromEncodingBits_Planar();
+ }
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// initialization from the encoding bits of a previous encoding if T mode is detected
-//
-void Block4x4Encoding_RGB8::InitFromEncodingBits_T(void) {
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if T mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_T(void)
+ {
- m_mode = MODE_T;
+ m_mode = MODE_T;
- unsigned char ucRed1 = (unsigned char)((m_pencodingbitsRGB8->t.red1a << 2) +
- m_pencodingbitsRGB8->t.red1b);
- unsigned char ucGreen1 = m_pencodingbitsRGB8->t.green1;
- unsigned char ucBlue1 = m_pencodingbitsRGB8->t.blue1;
+ unsigned char ucRed1 = (unsigned char)((m_pencodingbitsRGB8->t.red1a << 2) +
+ m_pencodingbitsRGB8->t.red1b);
+ unsigned char ucGreen1 = m_pencodingbitsRGB8->t.green1;
+ unsigned char ucBlue1 = m_pencodingbitsRGB8->t.blue1;
- unsigned char ucRed2 = m_pencodingbitsRGB8->t.red2;
- unsigned char ucGreen2 = m_pencodingbitsRGB8->t.green2;
- unsigned char ucBlue2 = m_pencodingbitsRGB8->t.blue2;
+ unsigned char ucRed2 = m_pencodingbitsRGB8->t.red2;
+ unsigned char ucGreen2 = m_pencodingbitsRGB8->t.green2;
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->t.blue2;
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
- m_uiCW1 = (m_pencodingbitsRGB8->t.da << 1) + m_pencodingbitsRGB8->t.db;
+ m_uiCW1 = (m_pencodingbitsRGB8->t.da << 1) + m_pencodingbitsRGB8->t.db;
- Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
- DecodePixels_T();
+ DecodePixels_T();
- CalcBlockError();
-}
+ CalcBlockError();
-// ----------------------------------------------------------------------------------------------------
-// initialization from the encoding bits of a previous encoding if H mode is detected
-//
-void Block4x4Encoding_RGB8::InitFromEncodingBits_H(void) {
+ }
- m_mode = MODE_H;
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if H mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_H(void)
+ {
- unsigned char ucRed1 = m_pencodingbitsRGB8->h.red1;
- unsigned char ucGreen1 = (unsigned char)((m_pencodingbitsRGB8->h.green1a << 1) +
- m_pencodingbitsRGB8->h.green1b);
- unsigned char ucBlue1 = (unsigned char)((m_pencodingbitsRGB8->h.blue1a << 3) +
- (m_pencodingbitsRGB8->h.blue1b << 1) +
- m_pencodingbitsRGB8->h.blue1c);
+ m_mode = MODE_H;
+
+ unsigned char ucRed1 = m_pencodingbitsRGB8->h.red1;
+ unsigned char ucGreen1 = (unsigned char)((m_pencodingbitsRGB8->h.green1a << 1) +
+ m_pencodingbitsRGB8->h.green1b);
+ unsigned char ucBlue1 = (unsigned char)((m_pencodingbitsRGB8->h.blue1a << 3) +
+ (m_pencodingbitsRGB8->h.blue1b << 1) +
+ m_pencodingbitsRGB8->h.blue1c);
+
+ unsigned char ucRed2 = m_pencodingbitsRGB8->h.red2;
+ unsigned char ucGreen2 = (unsigned char)((m_pencodingbitsRGB8->h.green2a << 1) +
+ m_pencodingbitsRGB8->h.green2b);
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->h.blue2;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+
+ // used to determine the LSB of the CW
+ unsigned int uiRGB1 = (unsigned int)(((int)ucRed1 << 16) + ((int)ucGreen1 << 8) + (int)ucBlue1);
+ unsigned int uiRGB2 = (unsigned int)(((int)ucRed2 << 16) + ((int)ucGreen2 << 8) + (int)ucBlue2);
+
+ m_uiCW1 = (m_pencodingbitsRGB8->h.da << 2) + (m_pencodingbitsRGB8->h.db << 1);
+ if (uiRGB1 >= uiRGB2)
+ {
+ m_uiCW1++;
+ }
- unsigned char ucRed2 = m_pencodingbitsRGB8->h.red2;
- unsigned char ucGreen2 = (unsigned char)((m_pencodingbitsRGB8->h.green2a << 1) +
- m_pencodingbitsRGB8->h.green2b);
- unsigned char ucBlue2 = m_pencodingbitsRGB8->h.blue2;
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+ DecodePixels_H();
- // used to determine the LSB of the CW
- unsigned int uiRGB1 = (unsigned int)(((int)ucRed1 << 16) + ((int)ucGreen1 << 8) + (int)ucBlue1);
- unsigned int uiRGB2 = (unsigned int)(((int)ucRed2 << 16) + ((int)ucGreen2 << 8) + (int)ucBlue2);
+ CalcBlockError();
- m_uiCW1 = (m_pencodingbitsRGB8->h.da << 2) + (m_pencodingbitsRGB8->h.db << 1);
- if (uiRGB1 >= uiRGB2) {
- m_uiCW1++;
}
- Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
-
- DecodePixels_H();
-
- CalcBlockError();
-}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if Planar mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_Planar(void)
+ {
-// ----------------------------------------------------------------------------------------------------
-// initialization from the encoding bits of a previous encoding if Planar mode is detected
-//
-void Block4x4Encoding_RGB8::InitFromEncodingBits_Planar(void) {
+ m_mode = MODE_PLANAR;
- m_mode = MODE_PLANAR;
+ unsigned char ucOriginRed = m_pencodingbitsRGB8->planar.originRed;
+ unsigned char ucOriginGreen = (unsigned char)((m_pencodingbitsRGB8->planar.originGreen1 << 6) +
+ m_pencodingbitsRGB8->planar.originGreen2);
+ unsigned char ucOriginBlue = (unsigned char)((m_pencodingbitsRGB8->planar.originBlue1 << 5) +
+ (m_pencodingbitsRGB8->planar.originBlue2 << 3) +
+ (m_pencodingbitsRGB8->planar.originBlue3 << 1) +
+ m_pencodingbitsRGB8->planar.originBlue4);
- unsigned char ucOriginRed = m_pencodingbitsRGB8->planar.originRed;
- unsigned char ucOriginGreen = (unsigned char)((m_pencodingbitsRGB8->planar.originGreen1 << 6) +
- m_pencodingbitsRGB8->planar.originGreen2);
- unsigned char ucOriginBlue = (unsigned char)((m_pencodingbitsRGB8->planar.originBlue1 << 5) +
- (m_pencodingbitsRGB8->planar.originBlue2 << 3) +
- (m_pencodingbitsRGB8->planar.originBlue3 << 1) +
- m_pencodingbitsRGB8->planar.originBlue4);
+ unsigned char ucHorizRed = (unsigned char)((m_pencodingbitsRGB8->planar.horizRed1 << 1) +
+ m_pencodingbitsRGB8->planar.horizRed2);
+ unsigned char ucHorizGreen = m_pencodingbitsRGB8->planar.horizGreen;
+ unsigned char ucHorizBlue = (unsigned char)((m_pencodingbitsRGB8->planar.horizBlue1 << 5) +
+ m_pencodingbitsRGB8->planar.horizBlue2);
- unsigned char ucHorizRed = (unsigned char)((m_pencodingbitsRGB8->planar.horizRed1 << 1) +
- m_pencodingbitsRGB8->planar.horizRed2);
- unsigned char ucHorizGreen = m_pencodingbitsRGB8->planar.horizGreen;
- unsigned char ucHorizBlue = (unsigned char)((m_pencodingbitsRGB8->planar.horizBlue1 << 5) +
- m_pencodingbitsRGB8->planar.horizBlue2);
+ unsigned char ucVertRed = (unsigned char)((m_pencodingbitsRGB8->planar.vertRed1 << 3) +
+ m_pencodingbitsRGB8->planar.vertRed2);
+ unsigned char ucVertGreen = (unsigned char)((m_pencodingbitsRGB8->planar.vertGreen1 << 2) +
+ m_pencodingbitsRGB8->planar.vertGreen2);
+ unsigned char ucVertBlue = m_pencodingbitsRGB8->planar.vertBlue;
- unsigned char ucVertRed = (unsigned char)((m_pencodingbitsRGB8->planar.vertRed1 << 3) +
- m_pencodingbitsRGB8->planar.vertRed2);
- unsigned char ucVertGreen = (unsigned char)((m_pencodingbitsRGB8->planar.vertGreen1 << 2) +
- m_pencodingbitsRGB8->planar.vertGreen2);
- unsigned char ucVertBlue = m_pencodingbitsRGB8->planar.vertBlue;
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromR6G7B6(ucOriginRed, ucOriginGreen, ucOriginBlue);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromR6G7B6(ucHorizRed, ucHorizGreen, ucHorizBlue);
+ m_frgbaColor3 = ColorFloatRGBA::ConvertFromR6G7B6(ucVertRed, ucVertGreen, ucVertBlue);
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromR6G7B6(ucOriginRed, ucOriginGreen, ucOriginBlue);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromR6G7B6(ucHorizRed, ucHorizGreen, ucHorizBlue);
- m_frgbaColor3 = ColorFloatRGBA::ConvertFromR6G7B6(ucVertRed, ucVertGreen, ucVertBlue);
+ DecodePixels_Planar();
- DecodePixels_Planar();
+ CalcBlockError();
- CalcBlockError();
-}
+ }
-// ----------------------------------------------------------------------------------------------------
-// perform a single encoding iteration
-// replace the encoding if a better encoding was found
-// subsequent iterations generally take longer for each iteration
-// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
-//
-void Block4x4Encoding_RGB8::PerformIteration(float a_fEffort) {
- assert(!m_boolDone);
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGB8::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
- switch (m_uiEncodingIterations) {
+ switch (m_uiEncodingIterations)
+ {
case 0:
Block4x4Encoding_ETC1::PerformFirstIteration();
-
- //@TODO@ Restrict here compression to ETC1 to speed up compression in low quality
- if (m_boolDone) {
+ if (m_boolDone)
+ {
break;
}
TryPlanar(0);
SetDoneIfPerfect();
- if (m_boolDone) {
+ if (m_boolDone)
+ {
break;
}
TryTAndH(0);
-
break;
case 1:
@@ -246,35 +265,40 @@ void Block4x4Encoding_RGB8::PerformIteration(float a_fEffort) {
case 5:
TryPlanar(1);
- if (a_fEffort <= 49.5f) {
+ if (a_fEffort <= 49.5f)
+ {
m_boolDone = true;
}
break;
case 6:
TryTAndH(1);
- if (a_fEffort <= 59.5f) {
+ if (a_fEffort <= 59.5f)
+ {
m_boolDone = true;
}
break;
case 7:
Block4x4Encoding_ETC1::TryDegenerates1();
- if (a_fEffort <= 69.5f) {
+ if (a_fEffort <= 69.5f)
+ {
m_boolDone = true;
}
break;
case 8:
Block4x4Encoding_ETC1::TryDegenerates2();
- if (a_fEffort <= 79.5f) {
+ if (a_fEffort <= 79.5f)
+ {
m_boolDone = true;
}
break;
case 9:
Block4x4Encoding_ETC1::TryDegenerates3();
- if (a_fEffort <= 89.5f) {
+ if (a_fEffort <= 89.5f)
+ {
m_boolDone = true;
}
break;
@@ -287,870 +311,1010 @@ void Block4x4Encoding_RGB8::PerformIteration(float a_fEffort) {
default:
assert(0);
break;
- }
-
- m_uiEncodingIterations++;
+ }
- SetDoneIfPerfect();
-}
+ m_uiEncodingIterations++;
-// ----------------------------------------------------------------------------------------------------
-// try encoding in Planar mode
-// save this encoding if it improves the error
-//
-void Block4x4Encoding_RGB8::TryPlanar(unsigned int a_uiRadius) {
- Block4x4Encoding_RGB8 encodingTry = *this;
+ SetDoneIfPerfect();
+ }
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in Planar mode
+ // save this encoding if it improves the error
+ //
+ void Block4x4Encoding_RGB8::TryPlanar(unsigned int a_uiRadius)
{
- encodingTry.m_mode = MODE_PLANAR;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- }
+ Block4x4Encoding_RGB8 encodingTry = *this;
- encodingTry.CalculatePlanarCornerColors();
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ }
- encodingTry.DecodePixels_Planar();
+ encodingTry.CalculatePlanarCornerColors();
- encodingTry.CalcBlockError();
+ encodingTry.DecodePixels_Planar();
- if (a_uiRadius > 0) {
- encodingTry.TwiddlePlanar();
- }
+ encodingTry.CalcBlockError();
- if (encodingTry.m_fError < m_fError) {
- m_mode = MODE_PLANAR;
- m_boolDiff = true;
- m_boolFlip = false;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_frgbaColor3 = encodingTry.m_frgbaColor3;
+ if (a_uiRadius > 0)
+ {
+ encodingTry.TwiddlePlanar();
+ }
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ m_fError = encodingTry.m_fError;
}
- m_fError = encodingTry.m_fError;
}
-}
-// ----------------------------------------------------------------------------------------------------
-// try encoding in T mode or H mode
-// save this encoding if it improves the error
-//
-void Block4x4Encoding_RGB8::TryTAndH(unsigned int a_uiRadius) {
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode or H mode
+ // save this encoding if it improves the error
+ //
+ void Block4x4Encoding_RGB8::TryTAndH(unsigned int a_uiRadius)
+ {
- CalculateBaseColorsForTAndH();
+ CalculateBaseColorsForTAndH();
- TryT(a_uiRadius);
+ TryT(a_uiRadius);
- TryH(a_uiRadius);
-}
+ TryH(a_uiRadius);
-// ----------------------------------------------------------------------------------------------------
-// calculate original values for base colors
-// store them in m_frgbaOriginalColor1 and m_frgbaOriginalColor2
-//
-void Block4x4Encoding_RGB8::CalculateBaseColorsForTAndH(void) {
-
- bool boolRGBX = m_pblockParent->GetImageSource()->GetErrorMetric() == ErrorMetric::RGBX;
-
- ColorFloatRGBA frgbaBlockAverage = (m_frgbaSourceAverageLeft + m_frgbaSourceAverageRight) * 0.5f;
-
- // find pixel farthest from average gray line
- unsigned int uiFarthestPixel = 0;
- float fFarthestGrayDistance2 = 0.0f;
- unsigned int uiTransparentPixels = 0;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- // don't count transparent
- if (m_pafrgbaSource[uiPixel].fA == 0.0f && !boolRGBX) {
- uiTransparentPixels++;
- } else {
- float fGrayDistance2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], frgbaBlockAverage);
-
- if (fGrayDistance2 > fFarthestGrayDistance2) {
- uiFarthestPixel = uiPixel;
- fFarthestGrayDistance2 = fGrayDistance2;
- }
- }
}
- // a transparent block should not reach this method
- assert(uiTransparentPixels < PIXELS);
-
- // set the original base colors to:
- // half way to the farthest pixel and
- // the mirror color on the other side of the average
- ColorFloatRGBA frgbaOffset = (m_pafrgbaSource[uiFarthestPixel] - frgbaBlockAverage) * 0.5f;
- m_frgbaOriginalColor1_TAndH = (frgbaBlockAverage + frgbaOffset).QuantizeR4G4B4();
- m_frgbaOriginalColor2_TAndH = (frgbaBlockAverage - frgbaOffset).ClampRGB().QuantizeR4G4B4(); // the "other side" might be out of range
-
- // move base colors to find best fit
- for (unsigned int uiIteration = 0; uiIteration < 10; uiIteration++) {
- // find the center of pixels closest to each color
- float fPixelsCloserToColor1 = 0.0f;
- ColorFloatRGBA frgbSumPixelsCloserToColor1;
- float fPixelsCloserToColor2 = 0.0f;
- ColorFloatRGBA frgbSumPixelsCloserToColor2;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- // don't count transparent pixels
- if (m_pafrgbaSource[uiPixel].fA == 0.0f) {
- continue;
- }
- float fGrayDistance2ToColor1 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor1_TAndH);
- float fGrayDistance2ToColor2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor2_TAndH);
+ // ----------------------------------------------------------------------------------------------------
+ // calculate original values for base colors
+ // store them in m_frgbaOriginalColor1 and m_frgbaOriginalColor2
+ //
+ void Block4x4Encoding_RGB8::CalculateBaseColorsForTAndH(void)
+ {
+
+ bool boolRGBX = m_pblockParent->GetImageSource()->GetErrorMetric() == ErrorMetric::RGBX;
- ColorFloatRGBA frgbaAlphaWeightedSource = m_pafrgbaSource[uiPixel] * m_pafrgbaSource[uiPixel].fA;
+ ColorFloatRGBA frgbaBlockAverage = (m_frgbaSourceAverageLeft + m_frgbaSourceAverageRight) * 0.5f;
- if (fGrayDistance2ToColor1 <= fGrayDistance2ToColor2) {
- fPixelsCloserToColor1 += m_pafrgbaSource[uiPixel].fA;
- frgbSumPixelsCloserToColor1 = frgbSumPixelsCloserToColor1 + frgbaAlphaWeightedSource;
- } else {
- fPixelsCloserToColor2 += m_pafrgbaSource[uiPixel].fA;
- frgbSumPixelsCloserToColor2 = frgbSumPixelsCloserToColor2 + frgbaAlphaWeightedSource;
+ // find pixel farthest from average gray line
+ unsigned int uiFarthestPixel = 0;
+ float fFarthestGrayDistance2 = 0.0f;
+ unsigned int uiTransparentPixels = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // don't count transparent
+ if (m_pafrgbaSource[uiPixel].fA == 0.0f && !boolRGBX)
+ {
+ uiTransparentPixels++;
+ }
+ else
+ {
+ float fGrayDistance2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], frgbaBlockAverage);
+
+ if (fGrayDistance2 > fFarthestGrayDistance2)
+ {
+ uiFarthestPixel = uiPixel;
+ fFarthestGrayDistance2 = fGrayDistance2;
+ }
}
}
- if (fPixelsCloserToColor1 == 0.0f || fPixelsCloserToColor2 == 0.0f) {
- break;
- }
+ // a transparent block should not reach this method
+ assert(uiTransparentPixels < PIXELS);
+
+ // set the original base colors to:
+ // half way to the farthest pixel and
+ // the mirror color on the other side of the average
+ ColorFloatRGBA frgbaOffset = (m_pafrgbaSource[uiFarthestPixel] - frgbaBlockAverage) * 0.5f;
+ m_frgbaOriginalColor1_TAndH = (frgbaBlockAverage + frgbaOffset).QuantizeR4G4B4();
+ m_frgbaOriginalColor2_TAndH = (frgbaBlockAverage - frgbaOffset).ClampRGB().QuantizeR4G4B4(); // the "other side" might be out of range
+
+ // move base colors to find best fit
+ for (unsigned int uiIteration = 0; uiIteration < 10; uiIteration++)
+ {
+ // find the center of pixels closest to each color
+ float fPixelsCloserToColor1 = 0.0f;
+ ColorFloatRGBA frgbSumPixelsCloserToColor1;
+ float fPixelsCloserToColor2 = 0.0f;
+ ColorFloatRGBA frgbSumPixelsCloserToColor2;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // don't count transparent pixels
+ if (m_pafrgbaSource[uiPixel].fA == 0.0f)
+ {
+ continue;
+ }
- ColorFloatRGBA frgbAvgColor1Pixels = (frgbSumPixelsCloserToColor1 * (1.0f / fPixelsCloserToColor1)).QuantizeR4G4B4();
- ColorFloatRGBA frgbAvgColor2Pixels = (frgbSumPixelsCloserToColor2 * (1.0f / fPixelsCloserToColor2)).QuantizeR4G4B4();
+ float fGrayDistance2ToColor1 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor1_TAndH);
+ float fGrayDistance2ToColor2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor2_TAndH);
- if (frgbAvgColor1Pixels.fR == m_frgbaOriginalColor1_TAndH.fR &&
+ ColorFloatRGBA frgbaAlphaWeightedSource = m_pafrgbaSource[uiPixel] * m_pafrgbaSource[uiPixel].fA;
+
+ if (fGrayDistance2ToColor1 <= fGrayDistance2ToColor2)
+ {
+ fPixelsCloserToColor1 += m_pafrgbaSource[uiPixel].fA;
+ frgbSumPixelsCloserToColor1 = frgbSumPixelsCloserToColor1 + frgbaAlphaWeightedSource;
+ }
+ else
+ {
+ fPixelsCloserToColor2 += m_pafrgbaSource[uiPixel].fA;
+ frgbSumPixelsCloserToColor2 = frgbSumPixelsCloserToColor2 + frgbaAlphaWeightedSource;
+ }
+ }
+ if (fPixelsCloserToColor1 == 0.0f || fPixelsCloserToColor2 == 0.0f)
+ {
+ break;
+ }
+
+ ColorFloatRGBA frgbAvgColor1Pixels = (frgbSumPixelsCloserToColor1 * (1.0f / fPixelsCloserToColor1)).QuantizeR4G4B4();
+ ColorFloatRGBA frgbAvgColor2Pixels = (frgbSumPixelsCloserToColor2 * (1.0f / fPixelsCloserToColor2)).QuantizeR4G4B4();
+
+ if (frgbAvgColor1Pixels.fR == m_frgbaOriginalColor1_TAndH.fR &&
frgbAvgColor1Pixels.fG == m_frgbaOriginalColor1_TAndH.fG &&
frgbAvgColor1Pixels.fB == m_frgbaOriginalColor1_TAndH.fB &&
frgbAvgColor2Pixels.fR == m_frgbaOriginalColor2_TAndH.fR &&
frgbAvgColor2Pixels.fG == m_frgbaOriginalColor2_TAndH.fG &&
- frgbAvgColor2Pixels.fB == m_frgbaOriginalColor2_TAndH.fB) {
- break;
+ frgbAvgColor2Pixels.fB == m_frgbaOriginalColor2_TAndH.fB)
+ {
+ break;
+ }
+
+ m_frgbaOriginalColor1_TAndH = frgbAvgColor1Pixels;
+ m_frgbaOriginalColor2_TAndH = frgbAvgColor2Pixels;
}
- m_frgbaOriginalColor1_TAndH = frgbAvgColor1Pixels;
- m_frgbaOriginalColor2_TAndH = frgbAvgColor2Pixels;
}
-}
-// ----------------------------------------------------------------------------------------------------
-// try encoding in T mode
-// save this encoding if it improves the error
-//
-// since pixels that use base color1 don't use the distance table, color1 and color2 can be twiddled independently
-// better encoding can be found if TWIDDLE_RADIUS is set to 2, but it will be much slower
-//
-void Block4x4Encoding_RGB8::TryT(unsigned int a_uiRadius) {
- Block4x4Encoding_RGB8 encodingTry = *this;
-
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode
+ // save this encoding if it improves the error
+ //
+ // since pixels that use base color1 don't use the distance table, color1 and color2 can be twiddled independently
+ // better encoding can be found if TWIDDLE_RADIUS is set to 2, but it will be much slower
+ //
+ void Block4x4Encoding_RGB8::TryT(unsigned int a_uiRadius)
{
- encodingTry.m_mode = MODE_T;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- encodingTry.m_fError = FLT_MAX;
- }
+ Block4x4Encoding_RGB8 encodingTry = *this;
- int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
- int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
- int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_T;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
- int iMinRed1 = iColor1Red - (int)a_uiRadius;
- if (iMinRed1 < 0) {
- iMinRed1 = 0;
- }
- int iMaxRed1 = iColor1Red + (int)a_uiRadius;
- if (iMaxRed1 > 15) {
- iMinRed1 = 15;
- }
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
- int iMinGreen1 = iColor1Green - (int)a_uiRadius;
- if (iMinGreen1 < 0) {
- iMinGreen1 = 0;
- }
- int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
- if (iMaxGreen1 > 15) {
- iMinGreen1 = 15;
- }
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
- int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
- if (iMinBlue1 < 0) {
- iMinBlue1 = 0;
- }
- int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
- if (iMaxBlue1 > 15) {
- iMinBlue1 = 15;
- }
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
- int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
- int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
- int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
- int iMinRed2 = iColor2Red - (int)a_uiRadius;
- if (iMinRed2 < 0) {
- iMinRed2 = 0;
- }
- int iMaxRed2 = iColor2Red + (int)a_uiRadius;
- if (iMaxRed2 > 15) {
- iMinRed2 = 15;
- }
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
- int iMinGreen2 = iColor2Green - (int)a_uiRadius;
- if (iMinGreen2 < 0) {
- iMinGreen2 = 0;
- }
- int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
- if (iMaxGreen2 > 15) {
- iMinGreen2 = 15;
- }
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
- int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
- if (iMinBlue2 < 0) {
- iMinBlue2 = 0;
- }
- int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
- if (iMaxBlue2 > 15) {
- iMinBlue2 = 15;
- }
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
- for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++) {
- encodingTry.m_uiCW1 = uiDistance;
-
- // twiddle m_frgbaOriginalColor2_TAndH
- // twiddle color2 first, since it affects 3 selectors, while color1 only affects one selector
- //
- for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++) {
- for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++) {
- for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++) {
- for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++) {
- if (uiBaseColorSwaps == 0) {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
- } else {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor1_TAndH;
- }
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
- encodingTry.TryT_BestSelectorCombination();
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor2_TAndH
+ // twiddle color2 first, since it affects 3 selectors, while color1 only affects one selector
+ //
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor1_TAndH;
+ }
- if (encodingTry.m_fError < m_fError) {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
+ encodingTry.TryT_BestSelectorCombination();
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
- m_fError = encodingTry.m_fError;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
}
}
}
}
- }
- // twiddle m_frgbaOriginalColor1_TAndH
- for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++) {
- for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++) {
- for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++) {
- for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++) {
- if (uiBaseColorSwaps == 0) {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
- } else {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor2_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- }
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor2_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ }
- encodingTry.TryT_BestSelectorCombination();
+ encodingTry.TryT_BestSelectorCombination();
- if (encodingTry.m_fError < m_fError) {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
- m_fError = encodingTry.m_fError;
+ m_fError = encodingTry.m_fError;
+ }
}
}
}
}
+
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// find best selector combination for TryT
-// called on an encodingTry
-//
-void Block4x4Encoding_RGB8::TryT_BestSelectorCombination(void) {
-
- float fDistance = s_afTHDistanceTable[m_uiCW1];
-
- unsigned int auiBestPixelSelectors[PIXELS];
- float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
- FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
- ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
- ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
-
- assert(SELECTORS == 4);
- afrgbaDecodedPixel[0] = m_frgbaColor1;
- afrgbaDecodedPixel[1] = (m_frgbaColor2 + fDistance).ClampRGB();
- afrgbaDecodedPixel[2] = m_frgbaColor2;
- afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
-
- // try each selector
- for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++) {
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
-
- float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
- m_pafrgbaSource[uiPixel]);
-
- if (fPixelError < afBestPixelErrors[uiPixel]) {
- afBestPixelErrors[uiPixel] = fPixelError;
- auiBestPixelSelectors[uiPixel] = uiSelector;
- afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryT
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8::TryT_BestSelectorCombination(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = m_frgbaColor1;
+ afrgbaDecodedPixel[1] = (m_frgbaColor2 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = m_frgbaColor2;
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+ // try each selector
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
}
}
- }
+
- // add up all of the pixel errors
- float fBlockError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- fBlockError += afBestPixelErrors[uiPixel];
- }
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
- if (fBlockError < m_fError) {
- m_fError = fBlockError;
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// try encoding in T mode
-// save this encoding if it improves the error
-//
-// since all pixels use the distance table, color1 and color2 can NOT be twiddled independently
-// TWIDDLE_RADIUS of 2 is WAY too slow
-//
-void Block4x4Encoding_RGB8::TryH(unsigned int a_uiRadius) {
- Block4x4Encoding_RGB8 encodingTry = *this;
-
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode
+ // save this encoding if it improves the error
+ //
+ // since all pixels use the distance table, color1 and color2 can NOT be twiddled independently
+ // TWIDDLE_RADIUS of 2 is WAY too slow
+ //
+ void Block4x4Encoding_RGB8::TryH(unsigned int a_uiRadius)
{
- encodingTry.m_mode = MODE_H;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- encodingTry.m_fError = FLT_MAX;
- }
+ Block4x4Encoding_RGB8 encodingTry = *this;
- int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
- int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
- int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_H;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
- int iMinRed1 = iColor1Red - (int)a_uiRadius;
- if (iMinRed1 < 0) {
- iMinRed1 = 0;
- }
- int iMaxRed1 = iColor1Red + (int)a_uiRadius;
- if (iMaxRed1 > 15) {
- iMinRed1 = 15;
- }
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
- int iMinGreen1 = iColor1Green - (int)a_uiRadius;
- if (iMinGreen1 < 0) {
- iMinGreen1 = 0;
- }
- int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
- if (iMaxGreen1 > 15) {
- iMinGreen1 = 15;
- }
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
- int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
- if (iMinBlue1 < 0) {
- iMinBlue1 = 0;
- }
- int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
- if (iMaxBlue1 > 15) {
- iMinBlue1 = 15;
- }
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
- int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
- int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
- int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
- int iMinRed2 = iColor2Red - (int)a_uiRadius;
- if (iMinRed2 < 0) {
- iMinRed2 = 0;
- }
- int iMaxRed2 = iColor2Red + (int)a_uiRadius;
- if (iMaxRed2 > 15) {
- iMinRed2 = 15;
- }
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
- int iMinGreen2 = iColor2Green - (int)a_uiRadius;
- if (iMinGreen2 < 0) {
- iMinGreen2 = 0;
- }
- int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
- if (iMaxGreen2 > 15) {
- iMinGreen2 = 15;
- }
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
- int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
- if (iMinBlue2 < 0) {
- iMinBlue2 = 0;
- }
- int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
- if (iMaxBlue2 > 15) {
- iMinBlue2 = 15;
- }
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
- for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++) {
- encodingTry.m_uiCW1 = uiDistance;
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
- // twiddle m_frgbaOriginalColor1_TAndH
- for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++) {
- for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++) {
- for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++) {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed1 == iColor2Red && iGreen1 == iColor2Green && iBlue1 == iColor2Blue)
+ {
+ continue;
+ }
- // if color1 == color2, H encoding issues can pop up, so abort
- if (iRed1 == iColor2Red && iGreen1 == iColor2Green && iBlue1 == iColor2Blue) {
- continue;
- }
+ encodingTry.TryH_BestSelectorCombination();
- encodingTry.TryH_BestSelectorCombination();
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
- if (encodingTry.m_fError < m_fError) {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ m_fError = encodingTry.m_fError;
}
-
- m_fError = encodingTry.m_fError;
}
}
}
- }
- // twiddle m_frgbaOriginalColor2_TAndH
- for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++) {
- for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++) {
- for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++) {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ // twiddle m_frgbaOriginalColor2_TAndH
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed2 == iColor1Red && iGreen2 == iColor1Green && iBlue2 == iColor1Blue)
+ {
+ continue;
+ }
- // if color1 == color2, H encoding issues can pop up, so abort
- if (iRed2 == iColor1Red && iGreen2 == iColor1Green && iBlue2 == iColor1Blue) {
- continue;
- }
+ encodingTry.TryH_BestSelectorCombination();
- encodingTry.TryH_BestSelectorCombination();
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
- if (encodingTry.m_fError < m_fError) {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ m_fError = encodingTry.m_fError;
}
-
- m_fError = encodingTry.m_fError;
}
}
}
+
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// find best selector combination for TryH
-// called on an encodingTry
-//
-void Block4x4Encoding_RGB8::TryH_BestSelectorCombination(void) {
-
- float fDistance = s_afTHDistanceTable[m_uiCW1];
-
- unsigned int auiBestPixelSelectors[PIXELS];
- float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
- FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
- ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
- ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
-
- assert(SELECTORS == 4);
- afrgbaDecodedPixel[0] = (m_frgbaColor1 + fDistance).ClampRGB();
- afrgbaDecodedPixel[1] = (m_frgbaColor1 - fDistance).ClampRGB();
- afrgbaDecodedPixel[2] = (m_frgbaColor2 + fDistance).ClampRGB();
- afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
-
- // try each selector
- for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++) {
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
-
- float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
- m_pafrgbaSource[uiPixel]);
-
- if (fPixelError < afBestPixelErrors[uiPixel]) {
- afBestPixelErrors[uiPixel] = fPixelError;
- auiBestPixelSelectors[uiPixel] = uiSelector;
- afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryH
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8::TryH_BestSelectorCombination(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = (m_frgbaColor1 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[1] = (m_frgbaColor1 - fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = (m_frgbaColor2 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+ // try each selector
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
}
}
- }
+
- // add up all of the pixel errors
- float fBlockError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- fBlockError += afBestPixelErrors[uiPixel];
- }
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
- if (fBlockError < m_fError) {
- m_fError = fBlockError;
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
}
- }
-}
-// ----------------------------------------------------------------------------------------------------
-// use linear regression to find the best fit for colors along the edges of the 4x4 block
-//
-void Block4x4Encoding_RGB8::CalculatePlanarCornerColors(void) {
- ColorFloatRGBA afrgbaRegression[MAX_PLANAR_REGRESSION_SIZE];
- ColorFloatRGBA frgbaSlope;
- ColorFloatRGBA frgbaOffset;
-
- // top edge
- afrgbaRegression[0] = m_pafrgbaSource[0];
- afrgbaRegression[1] = m_pafrgbaSource[4];
- afrgbaRegression[2] = m_pafrgbaSource[8];
- afrgbaRegression[3] = m_pafrgbaSource[12];
- ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
- m_frgbaColor1 = frgbaOffset;
- m_frgbaColor2 = (frgbaSlope * 4.0f) + frgbaOffset;
-
- // left edge
- afrgbaRegression[0] = m_pafrgbaSource[0];
- afrgbaRegression[1] = m_pafrgbaSource[1];
- afrgbaRegression[2] = m_pafrgbaSource[2];
- afrgbaRegression[3] = m_pafrgbaSource[3];
- ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
- m_frgbaColor1 = (m_frgbaColor1 + frgbaOffset) * 0.5f; // average with top edge
- m_frgbaColor3 = (frgbaSlope * 4.0f) + frgbaOffset;
-
- // right edge
- afrgbaRegression[0] = m_pafrgbaSource[12];
- afrgbaRegression[1] = m_pafrgbaSource[13];
- afrgbaRegression[2] = m_pafrgbaSource[14];
- afrgbaRegression[3] = m_pafrgbaSource[15];
- ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
- m_frgbaColor2 = (m_frgbaColor2 + frgbaOffset) * 0.5f; // average with top edge
-
- // bottom edge
- afrgbaRegression[0] = m_pafrgbaSource[3];
- afrgbaRegression[1] = m_pafrgbaSource[7];
- afrgbaRegression[2] = m_pafrgbaSource[11];
- afrgbaRegression[3] = m_pafrgbaSource[15];
- ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
- m_frgbaColor3 = (m_frgbaColor3 + frgbaOffset) * 0.5f; // average with left edge
-
- // quantize corner colors to 6/7/6
- m_frgbaColor1 = m_frgbaColor1.QuantizeR6G7B6();
- m_frgbaColor2 = m_frgbaColor2.QuantizeR6G7B6();
- m_frgbaColor3 = m_frgbaColor3.QuantizeR6G7B6();
-}
-
-// ----------------------------------------------------------------------------------------------------
-// try different corner colors by slightly changing R, G and B independently
-//
-// R, G and B decoding and errors are independent, so R, G and B twiddles can be independent
-//
-// return true if improvement
-//
-bool Block4x4Encoding_RGB8::TwiddlePlanar(void) {
- bool boolImprovement = false;
-
- while (TwiddlePlanarR()) {
- boolImprovement = true;
}
- while (TwiddlePlanarG()) {
- boolImprovement = true;
- }
+ // ----------------------------------------------------------------------------------------------------
+ // use linear regression to find the best fit for colors along the edges of the 4x4 block
+ //
+ void Block4x4Encoding_RGB8::CalculatePlanarCornerColors(void)
+ {
+ ColorFloatRGBA afrgbaRegression[MAX_PLANAR_REGRESSION_SIZE];
+ ColorFloatRGBA frgbaSlope;
+ ColorFloatRGBA frgbaOffset;
+
+ // top edge
+ afrgbaRegression[0] = m_pafrgbaSource[0];
+ afrgbaRegression[1] = m_pafrgbaSource[4];
+ afrgbaRegression[2] = m_pafrgbaSource[8];
+ afrgbaRegression[3] = m_pafrgbaSource[12];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor1 = frgbaOffset;
+ m_frgbaColor2 = (frgbaSlope * 4.0f) + frgbaOffset;
+
+ // left edge
+ afrgbaRegression[0] = m_pafrgbaSource[0];
+ afrgbaRegression[1] = m_pafrgbaSource[1];
+ afrgbaRegression[2] = m_pafrgbaSource[2];
+ afrgbaRegression[3] = m_pafrgbaSource[3];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor1 = (m_frgbaColor1 + frgbaOffset) * 0.5f; // average with top edge
+ m_frgbaColor3 = (frgbaSlope * 4.0f) + frgbaOffset;
+
+ // right edge
+ afrgbaRegression[0] = m_pafrgbaSource[12];
+ afrgbaRegression[1] = m_pafrgbaSource[13];
+ afrgbaRegression[2] = m_pafrgbaSource[14];
+ afrgbaRegression[3] = m_pafrgbaSource[15];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor2 = (m_frgbaColor2 + frgbaOffset) * 0.5f; // average with top edge
+
+ // bottom edge
+ afrgbaRegression[0] = m_pafrgbaSource[3];
+ afrgbaRegression[1] = m_pafrgbaSource[7];
+ afrgbaRegression[2] = m_pafrgbaSource[11];
+ afrgbaRegression[3] = m_pafrgbaSource[15];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor3 = (m_frgbaColor3 + frgbaOffset) * 0.5f; // average with left edge
+
+ // quantize corner colors to 6/7/6
+ m_frgbaColor1 = m_frgbaColor1.QuantizeR6G7B6();
+ m_frgbaColor2 = m_frgbaColor2.QuantizeR6G7B6();
+ m_frgbaColor3 = m_frgbaColor3.QuantizeR6G7B6();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing R, G and B independently
+ //
+ // R, G and B decoding and errors are independent, so R, G and B twiddles can be independent
+ //
+ // return true if improvement
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanar(void)
+ {
+ bool boolImprovement = false;
- while (TwiddlePlanarB()) {
- boolImprovement = true;
- }
+ while (TwiddlePlanarR())
+ {
+ boolImprovement = true;
+ }
- return boolImprovement;
-}
+ while (TwiddlePlanarG())
+ {
+ boolImprovement = true;
+ }
-// ----------------------------------------------------------------------------------------------------
-// try different corner colors by slightly changing R
-//
-bool Block4x4Encoding_RGB8::TwiddlePlanarR() {
- bool boolImprovement = false;
+ while (TwiddlePlanarB())
+ {
+ boolImprovement = true;
+ }
- Block4x4Encoding_RGB8 encodingTry = *this;
+ return boolImprovement;
+ }
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing R
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarR()
{
- encodingTry.m_mode = MODE_PLANAR;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- }
+ bool boolImprovement = false;
- int iOriginRed = encodingTry.m_frgbaColor1.IntRed(63.0f);
- int iHorizRed = encodingTry.m_frgbaColor2.IntRed(63.0f);
- int iVertRed = encodingTry.m_frgbaColor3.IntRed(63.0f);
+ Block4x4Encoding_RGB8 encodingTry = *this;
- for (int iTryOriginRed = iOriginRed - 1; iTryOriginRed <= iOriginRed + 1; iTryOriginRed++) {
- // check for out of range
- if (iTryOriginRed < 0 || iTryOriginRed > 63) {
- continue;
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
}
- encodingTry.m_frgbaColor1.fR = ((iTryOriginRed << 2) + (iTryOriginRed >> 4)) / 255.0f;
+ int iOriginRed = encodingTry.m_frgbaColor1.IntRed(63.0f);
+ int iHorizRed = encodingTry.m_frgbaColor2.IntRed(63.0f);
+ int iVertRed = encodingTry.m_frgbaColor3.IntRed(63.0f);
- for (int iTryHorizRed = iHorizRed - 1; iTryHorizRed <= iHorizRed + 1; iTryHorizRed++) {
+ for (int iTryOriginRed = iOriginRed - 1; iTryOriginRed <= iOriginRed + 1; iTryOriginRed++)
+ {
// check for out of range
- if (iTryHorizRed < 0 || iTryHorizRed > 63) {
+ if (iTryOriginRed < 0 || iTryOriginRed > 63)
+ {
continue;
}
- encodingTry.m_frgbaColor2.fR = ((iTryHorizRed << 2) + (iTryHorizRed >> 4)) / 255.0f;
+ encodingTry.m_frgbaColor1.fR = ((iTryOriginRed << 2) + (iTryOriginRed >> 4)) / 255.0f;
- for (int iTryVertRed = iVertRed - 1; iTryVertRed <= iVertRed + 1; iTryVertRed++) {
+ for (int iTryHorizRed = iHorizRed - 1; iTryHorizRed <= iHorizRed + 1; iTryHorizRed++)
+ {
// check for out of range
- if (iTryVertRed < 0 || iTryVertRed > 63) {
+ if (iTryHorizRed < 0 || iTryHorizRed > 63)
+ {
continue;
}
- // don't bother with null twiddle
- if (iTryOriginRed == iOriginRed && iTryHorizRed == iHorizRed && iTryVertRed == iVertRed) {
- continue;
- }
+ encodingTry.m_frgbaColor2.fR = ((iTryHorizRed << 2) + (iTryHorizRed >> 4)) / 255.0f;
- encodingTry.m_frgbaColor3.fR = ((iTryVertRed << 2) + (iTryVertRed >> 4)) / 255.0f;
+ for (int iTryVertRed = iVertRed - 1; iTryVertRed <= iVertRed + 1; iTryVertRed++)
+ {
+ // check for out of range
+ if (iTryVertRed < 0 || iTryVertRed > 63)
+ {
+ continue;
+ }
- encodingTry.DecodePixels_Planar();
+ // don't bother with null twiddle
+ if (iTryOriginRed == iOriginRed && iTryHorizRed == iHorizRed && iTryVertRed == iVertRed)
+ {
+ continue;
+ }
- encodingTry.CalcBlockError();
+ encodingTry.m_frgbaColor3.fR = ((iTryVertRed << 2) + (iTryVertRed >> 4)) / 255.0f;
- if (encodingTry.m_fError < m_fError) {
- m_mode = MODE_PLANAR;
- m_boolDiff = true;
- m_boolFlip = false;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_frgbaColor3 = encodingTry.m_frgbaColor3;
+ encodingTry.DecodePixels_Planar();
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
+ encodingTry.CalcBlockError();
- m_fError = encodingTry.m_fError;
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
- boolImprovement = true;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+
+ boolImprovement = true;
+ }
}
}
}
- }
- return boolImprovement;
-}
-
-// ----------------------------------------------------------------------------------------------------
-// try different corner colors by slightly changing G
-//
-bool Block4x4Encoding_RGB8::TwiddlePlanarG() {
- bool boolImprovement = false;
-
- Block4x4Encoding_RGB8 encodingTry = *this;
+ return boolImprovement;
+ }
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing G
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarG()
{
- encodingTry.m_mode = MODE_PLANAR;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- }
+ bool boolImprovement = false;
- int iOriginGreen = encodingTry.m_frgbaColor1.IntGreen(127.0f);
- int iHorizGreen = encodingTry.m_frgbaColor2.IntGreen(127.0f);
- int iVertGreen = encodingTry.m_frgbaColor3.IntGreen(127.0f);
+ Block4x4Encoding_RGB8 encodingTry = *this;
- for (int iTryOriginGreen = iOriginGreen - 1; iTryOriginGreen <= iOriginGreen + 1; iTryOriginGreen++) {
- // check for out of range
- if (iTryOriginGreen < 0 || iTryOriginGreen > 127) {
- continue;
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
}
- encodingTry.m_frgbaColor1.fG = ((iTryOriginGreen << 1) + (iTryOriginGreen >> 6)) / 255.0f;
+ int iOriginGreen = encodingTry.m_frgbaColor1.IntGreen(127.0f);
+ int iHorizGreen = encodingTry.m_frgbaColor2.IntGreen(127.0f);
+ int iVertGreen = encodingTry.m_frgbaColor3.IntGreen(127.0f);
- for (int iTryHorizGreen = iHorizGreen - 1; iTryHorizGreen <= iHorizGreen + 1; iTryHorizGreen++) {
+ for (int iTryOriginGreen = iOriginGreen - 1; iTryOriginGreen <= iOriginGreen + 1; iTryOriginGreen++)
+ {
// check for out of range
- if (iTryHorizGreen < 0 || iTryHorizGreen > 127) {
+ if (iTryOriginGreen < 0 || iTryOriginGreen > 127)
+ {
continue;
}
- encodingTry.m_frgbaColor2.fG = ((iTryHorizGreen << 1) + (iTryHorizGreen >> 6)) / 255.0f;
+ encodingTry.m_frgbaColor1.fG = ((iTryOriginGreen << 1) + (iTryOriginGreen >> 6)) / 255.0f;
- for (int iTryVertGreen = iVertGreen - 1; iTryVertGreen <= iVertGreen + 1; iTryVertGreen++) {
+ for (int iTryHorizGreen = iHorizGreen - 1; iTryHorizGreen <= iHorizGreen + 1; iTryHorizGreen++)
+ {
// check for out of range
- if (iTryVertGreen < 0 || iTryVertGreen > 127) {
+ if (iTryHorizGreen < 0 || iTryHorizGreen > 127)
+ {
continue;
}
- // don't bother with null twiddle
- if (iTryOriginGreen == iOriginGreen &&
- iTryHorizGreen == iHorizGreen &&
- iTryVertGreen == iVertGreen) {
- continue;
- }
+ encodingTry.m_frgbaColor2.fG = ((iTryHorizGreen << 1) + (iTryHorizGreen >> 6)) / 255.0f;
- encodingTry.m_frgbaColor3.fG = ((iTryVertGreen << 1) + (iTryVertGreen >> 6)) / 255.0f;
+ for (int iTryVertGreen = iVertGreen - 1; iTryVertGreen <= iVertGreen + 1; iTryVertGreen++)
+ {
+ // check for out of range
+ if (iTryVertGreen < 0 || iTryVertGreen > 127)
+ {
+ continue;
+ }
- encodingTry.DecodePixels_Planar();
+ // don't bother with null twiddle
+ if (iTryOriginGreen == iOriginGreen &&
+ iTryHorizGreen == iHorizGreen &&
+ iTryVertGreen == iVertGreen)
+ {
+ continue;
+ }
- encodingTry.CalcBlockError();
+ encodingTry.m_frgbaColor3.fG = ((iTryVertGreen << 1) + (iTryVertGreen >> 6)) / 255.0f;
- if (encodingTry.m_fError < m_fError) {
- m_mode = MODE_PLANAR;
- m_boolDiff = true;
- m_boolFlip = false;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_frgbaColor3 = encodingTry.m_frgbaColor3;
+ encodingTry.DecodePixels_Planar();
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
+ encodingTry.CalcBlockError();
- m_fError = encodingTry.m_fError;
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
- boolImprovement = true;
+ boolImprovement = true;
+ }
}
}
}
- }
-
- return boolImprovement;
-}
-
-// ----------------------------------------------------------------------------------------------------
-// try different corner colors by slightly changing B
-//
-bool Block4x4Encoding_RGB8::TwiddlePlanarB() {
- bool boolImprovement = false;
- Block4x4Encoding_RGB8 encodingTry = *this;
+ return boolImprovement;
+ }
- // init "try"
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing B
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarB()
{
- encodingTry.m_mode = MODE_PLANAR;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- }
+ bool boolImprovement = false;
- int iOriginBlue = encodingTry.m_frgbaColor1.IntBlue(63.0f);
- int iHorizBlue = encodingTry.m_frgbaColor2.IntBlue(63.0f);
- int iVertBlue = encodingTry.m_frgbaColor3.IntBlue(63.0f);
+ Block4x4Encoding_RGB8 encodingTry = *this;
- for (int iTryOriginBlue = iOriginBlue - 1; iTryOriginBlue <= iOriginBlue + 1; iTryOriginBlue++) {
- // check for out of range
- if (iTryOriginBlue < 0 || iTryOriginBlue > 63) {
- continue;
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
}
- encodingTry.m_frgbaColor1.fB = ((iTryOriginBlue << 2) + (iTryOriginBlue >> 4)) / 255.0f;
+ int iOriginBlue = encodingTry.m_frgbaColor1.IntBlue(63.0f);
+ int iHorizBlue = encodingTry.m_frgbaColor2.IntBlue(63.0f);
+ int iVertBlue = encodingTry.m_frgbaColor3.IntBlue(63.0f);
- for (int iTryHorizBlue = iHorizBlue - 1; iTryHorizBlue <= iHorizBlue + 1; iTryHorizBlue++) {
+ for (int iTryOriginBlue = iOriginBlue - 1; iTryOriginBlue <= iOriginBlue + 1; iTryOriginBlue++)
+ {
// check for out of range
- if (iTryHorizBlue < 0 || iTryHorizBlue > 63) {
+ if (iTryOriginBlue < 0 || iTryOriginBlue > 63)
+ {
continue;
}
- encodingTry.m_frgbaColor2.fB = ((iTryHorizBlue << 2) + (iTryHorizBlue >> 4)) / 255.0f;
+ encodingTry.m_frgbaColor1.fB = ((iTryOriginBlue << 2) + (iTryOriginBlue >> 4)) / 255.0f;
- for (int iTryVertBlue = iVertBlue - 1; iTryVertBlue <= iVertBlue + 1; iTryVertBlue++) {
+ for (int iTryHorizBlue = iHorizBlue - 1; iTryHorizBlue <= iHorizBlue + 1; iTryHorizBlue++)
+ {
// check for out of range
- if (iTryVertBlue < 0 || iTryVertBlue > 63) {
+ if (iTryHorizBlue < 0 || iTryHorizBlue > 63)
+ {
continue;
}
- // don't bother with null twiddle
- if (iTryOriginBlue == iOriginBlue && iTryHorizBlue == iHorizBlue && iTryVertBlue == iVertBlue) {
- continue;
- }
+ encodingTry.m_frgbaColor2.fB = ((iTryHorizBlue << 2) + (iTryHorizBlue >> 4)) / 255.0f;
- encodingTry.m_frgbaColor3.fB = ((iTryVertBlue << 2) + (iTryVertBlue >> 4)) / 255.0f;
+ for (int iTryVertBlue = iVertBlue - 1; iTryVertBlue <= iVertBlue + 1; iTryVertBlue++)
+ {
+ // check for out of range
+ if (iTryVertBlue < 0 || iTryVertBlue > 63)
+ {
+ continue;
+ }
- encodingTry.DecodePixels_Planar();
+ // don't bother with null twiddle
+ if (iTryOriginBlue == iOriginBlue && iTryHorizBlue == iHorizBlue && iTryVertBlue == iVertBlue)
+ {
+ continue;
+ }
- encodingTry.CalcBlockError();
+ encodingTry.m_frgbaColor3.fB = ((iTryVertBlue << 2) + (iTryVertBlue >> 4)) / 255.0f;
- if (encodingTry.m_fError < m_fError) {
- m_mode = MODE_PLANAR;
- m_boolDiff = true;
- m_boolFlip = false;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_frgbaColor3 = encodingTry.m_frgbaColor3;
+ encodingTry.DecodePixels_Planar();
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
+ encodingTry.CalcBlockError();
- m_fError = encodingTry.m_fError;
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
- boolImprovement = true;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+
+ boolImprovement = true;
+ }
}
}
}
- }
- return boolImprovement;
-}
+ return boolImprovement;
+ }
-// ----------------------------------------------------------------------------------------------------
-// set the encoding bits based on encoding state
-//
-void Block4x4Encoding_RGB8::SetEncodingBits(void) {
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits(void)
+ {
- switch (m_mode) {
+ switch (m_mode)
+ {
case MODE_ETC1:
Block4x4Encoding_ETC1::SetEncodingBits();
break;
@@ -1169,241 +1333,270 @@ void Block4x4Encoding_RGB8::SetEncodingBits(void) {
default:
assert(false);
+ }
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// set the encoding bits based on encoding state for T mode
-//
-void Block4x4Encoding_RGB8::SetEncodingBits_T(void) {
- static const bool SANITY_CHECK = true;
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for T mode
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_T(void)
+ {
+ static const bool SANITY_CHECK = true;
- assert(m_mode == MODE_T);
- assert(m_boolDiff == true);
+ assert(m_mode == MODE_T);
+ assert(m_boolDiff == true);
- unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
- unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
- unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
- unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
- unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
- unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
- m_pencodingbitsRGB8->t.red1a = uiRed1 >> 2;
- m_pencodingbitsRGB8->t.red1b = uiRed1;
- m_pencodingbitsRGB8->t.green1 = uiGreen1;
- m_pencodingbitsRGB8->t.blue1 = uiBlue1;
+ m_pencodingbitsRGB8->t.red1a = uiRed1 >> 2;
+ m_pencodingbitsRGB8->t.red1b = uiRed1;
+ m_pencodingbitsRGB8->t.green1 = uiGreen1;
+ m_pencodingbitsRGB8->t.blue1 = uiBlue1;
- m_pencodingbitsRGB8->t.red2 = uiRed2;
- m_pencodingbitsRGB8->t.green2 = uiGreen2;
- m_pencodingbitsRGB8->t.blue2 = uiBlue2;
+ m_pencodingbitsRGB8->t.red2 = uiRed2;
+ m_pencodingbitsRGB8->t.green2 = uiGreen2;
+ m_pencodingbitsRGB8->t.blue2 = uiBlue2;
- m_pencodingbitsRGB8->t.da = m_uiCW1 >> 1;
- m_pencodingbitsRGB8->t.db = m_uiCW1;
+ m_pencodingbitsRGB8->t.da = m_uiCW1 >> 1;
+ m_pencodingbitsRGB8->t.db = m_uiCW1;
- m_pencodingbitsRGB8->t.diff = 1;
+ m_pencodingbitsRGB8->t.diff = 1;
- Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
- // create an invalid R differential to trigger T mode
- m_pencodingbitsRGB8->t.detect1 = 0;
- m_pencodingbitsRGB8->t.detect2 = 0;
- int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- if (iRed2 >= 4) {
- m_pencodingbitsRGB8->t.detect1 = 7;
- m_pencodingbitsRGB8->t.detect2 = 0;
- } else {
+ // create an invalid R differential to trigger T mode
m_pencodingbitsRGB8->t.detect1 = 0;
- m_pencodingbitsRGB8->t.detect2 = 1;
- }
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ if (iRed2 >= 4)
+ {
+ m_pencodingbitsRGB8->t.detect1 = 7;
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->t.detect1 = 0;
+ m_pencodingbitsRGB8->t.detect2 = 1;
+ }
- if (SANITY_CHECK) {
- iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- // make sure red overflows
- assert(iRed2 < 0 || iRed2 > 31);
- }
-}
+ // make sure red overflows
+ assert(iRed2 < 0 || iRed2 > 31);
+ }
-// ----------------------------------------------------------------------------------------------------
-// set the encoding bits based on encoding state for H mode
-//
-// colors and selectors may need to swap in order to generate lsb of distance index
-//
-void Block4x4Encoding_RGB8::SetEncodingBits_H(void) {
- static const bool SANITY_CHECK = true;
-
- assert(m_mode == MODE_H);
- assert(m_boolDiff == true);
-
- unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
- unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
- unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
-
- unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
- unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
- unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
-
- unsigned int uiColor1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
- unsigned int uiColor2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
-
- bool boolOddDistance = m_uiCW1 & 1;
- bool boolSwapColors = (uiColor1 < uiColor2) ^ !boolOddDistance;
-
- if (boolSwapColors) {
- m_pencodingbitsRGB8->h.red1 = uiRed2;
- m_pencodingbitsRGB8->h.green1a = uiGreen2 >> 1;
- m_pencodingbitsRGB8->h.green1b = uiGreen2;
- m_pencodingbitsRGB8->h.blue1a = uiBlue2 >> 3;
- m_pencodingbitsRGB8->h.blue1b = uiBlue2 >> 1;
- m_pencodingbitsRGB8->h.blue1c = uiBlue2;
-
- m_pencodingbitsRGB8->h.red2 = uiRed1;
- m_pencodingbitsRGB8->h.green2a = uiGreen1 >> 1;
- m_pencodingbitsRGB8->h.green2b = uiGreen1;
- m_pencodingbitsRGB8->h.blue2 = uiBlue1;
-
- m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
- m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
- } else {
- m_pencodingbitsRGB8->h.red1 = uiRed1;
- m_pencodingbitsRGB8->h.green1a = uiGreen1 >> 1;
- m_pencodingbitsRGB8->h.green1b = uiGreen1;
- m_pencodingbitsRGB8->h.blue1a = uiBlue1 >> 3;
- m_pencodingbitsRGB8->h.blue1b = uiBlue1 >> 1;
- m_pencodingbitsRGB8->h.blue1c = uiBlue1;
-
- m_pencodingbitsRGB8->h.red2 = uiRed2;
- m_pencodingbitsRGB8->h.green2a = uiGreen2 >> 1;
- m_pencodingbitsRGB8->h.green2b = uiGreen2;
- m_pencodingbitsRGB8->h.blue2 = uiBlue2;
-
- m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
- m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
}
- m_pencodingbitsRGB8->h.diff = 1;
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for H mode
+ //
+ // colors and selectors may need to swap in order to generate lsb of distance index
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_H(void)
+ {
+ static const bool SANITY_CHECK = true;
- Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+ assert(m_mode == MODE_H);
+ assert(m_boolDiff == true);
- if (boolSwapColors) {
- m_pencodingbitsRGB8->h.selectors ^= 0x0000FFFF;
- }
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
- // create an invalid R differential to trigger T mode
- m_pencodingbitsRGB8->h.detect1 = 0;
- m_pencodingbitsRGB8->h.detect2 = 0;
- m_pencodingbitsRGB8->h.detect3 = 0;
- int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- if (iRed2 < 0 || iRed2 > 31) {
- m_pencodingbitsRGB8->h.detect1 = 1;
- }
- if (iGreen2 >= 4) {
- m_pencodingbitsRGB8->h.detect2 = 7;
- m_pencodingbitsRGB8->h.detect3 = 0;
- } else {
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+
+ unsigned int uiColor1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
+ unsigned int uiColor2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
+
+ bool boolOddDistance = m_uiCW1 & 1;
+ bool boolSwapColors = (uiColor1 < uiColor2) ^ !boolOddDistance;
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed2;
+ m_pencodingbitsRGB8->h.green1a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue2 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue2 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue2;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed1;
+ m_pencodingbitsRGB8->h.green2a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue1;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed1;
+ m_pencodingbitsRGB8->h.green1a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue1 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue1 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue1;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed2;
+ m_pencodingbitsRGB8->h.green2a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue2;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+
+ m_pencodingbitsRGB8->h.diff = 1;
+
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.selectors ^= 0x0000FFFF;
+ }
+
+ // create an invalid R differential to trigger T mode
+ m_pencodingbitsRGB8->h.detect1 = 0;
m_pencodingbitsRGB8->h.detect2 = 0;
- m_pencodingbitsRGB8->h.detect3 = 1;
- }
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ m_pencodingbitsRGB8->h.detect1 = 1;
+ }
+ if (iGreen2 >= 4)
+ {
+ m_pencodingbitsRGB8->h.detect2 = 7;
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.detect2 = 0;
+ m_pencodingbitsRGB8->h.detect3 = 1;
+ }
- if (SANITY_CHECK) {
- iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- // make sure red doesn't overflow and green does
- assert(iRed2 >= 0 && iRed2 <= 31);
- assert(iGreen2 < 0 || iGreen2 > 31);
- }
-}
+ // make sure red doesn't overflow and green does
+ assert(iRed2 >= 0 && iRed2 <= 31);
+ assert(iGreen2 < 0 || iGreen2 > 31);
+ }
-// ----------------------------------------------------------------------------------------------------
-// set the encoding bits based on encoding state for Planar mode
-//
-void Block4x4Encoding_RGB8::SetEncodingBits_Planar(void) {
- static const bool SANITY_CHECK = true;
-
- assert(m_mode == MODE_PLANAR);
- assert(m_boolDiff == true);
-
- unsigned int uiOriginRed = (unsigned int)m_frgbaColor1.IntRed(63.0f);
- unsigned int uiOriginGreen = (unsigned int)m_frgbaColor1.IntGreen(127.0f);
- unsigned int uiOriginBlue = (unsigned int)m_frgbaColor1.IntBlue(63.0f);
-
- unsigned int uiHorizRed = (unsigned int)m_frgbaColor2.IntRed(63.0f);
- unsigned int uiHorizGreen = (unsigned int)m_frgbaColor2.IntGreen(127.0f);
- unsigned int uiHorizBlue = (unsigned int)m_frgbaColor2.IntBlue(63.0f);
-
- unsigned int uiVertRed = (unsigned int)m_frgbaColor3.IntRed(63.0f);
- unsigned int uiVertGreen = (unsigned int)m_frgbaColor3.IntGreen(127.0f);
- unsigned int uiVertBlue = (unsigned int)m_frgbaColor3.IntBlue(63.0f);
-
- m_pencodingbitsRGB8->planar.originRed = uiOriginRed;
- m_pencodingbitsRGB8->planar.originGreen1 = uiOriginGreen >> 6;
- m_pencodingbitsRGB8->planar.originGreen2 = uiOriginGreen;
- m_pencodingbitsRGB8->planar.originBlue1 = uiOriginBlue >> 5;
- m_pencodingbitsRGB8->planar.originBlue2 = uiOriginBlue >> 3;
- m_pencodingbitsRGB8->planar.originBlue3 = uiOriginBlue >> 1;
- m_pencodingbitsRGB8->planar.originBlue4 = uiOriginBlue;
-
- m_pencodingbitsRGB8->planar.horizRed1 = uiHorizRed >> 1;
- m_pencodingbitsRGB8->planar.horizRed2 = uiHorizRed;
- m_pencodingbitsRGB8->planar.horizGreen = uiHorizGreen;
- m_pencodingbitsRGB8->planar.horizBlue1 = uiHorizBlue >> 5;
- m_pencodingbitsRGB8->planar.horizBlue2 = uiHorizBlue;
-
- m_pencodingbitsRGB8->planar.vertRed1 = uiVertRed >> 3;
- m_pencodingbitsRGB8->planar.vertRed2 = uiVertRed;
- m_pencodingbitsRGB8->planar.vertGreen1 = uiVertGreen >> 2;
- m_pencodingbitsRGB8->planar.vertGreen2 = uiVertGreen;
- m_pencodingbitsRGB8->planar.vertBlue = uiVertBlue;
-
- m_pencodingbitsRGB8->planar.diff = 1;
-
- // create valid RG differentials and an invalid B differential to trigger planar mode
- m_pencodingbitsRGB8->planar.detect1 = 0;
- m_pencodingbitsRGB8->planar.detect2 = 0;
- m_pencodingbitsRGB8->planar.detect3 = 0;
- m_pencodingbitsRGB8->planar.detect4 = 0;
- int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- int iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
- if (iRed2 < 0 || iRed2 > 31) {
- m_pencodingbitsRGB8->planar.detect1 = 1;
- }
- if (iGreen2 < 0 || iGreen2 > 31) {
- m_pencodingbitsRGB8->planar.detect2 = 1;
}
- if (iBlue2 >= 4) {
- m_pencodingbitsRGB8->planar.detect3 = 7;
- m_pencodingbitsRGB8->planar.detect4 = 0;
- } else {
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for Planar mode
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_Planar(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_PLANAR);
+ assert(m_boolDiff == true);
+
+ unsigned int uiOriginRed = (unsigned int)m_frgbaColor1.IntRed(63.0f);
+ unsigned int uiOriginGreen = (unsigned int)m_frgbaColor1.IntGreen(127.0f);
+ unsigned int uiOriginBlue = (unsigned int)m_frgbaColor1.IntBlue(63.0f);
+
+ unsigned int uiHorizRed = (unsigned int)m_frgbaColor2.IntRed(63.0f);
+ unsigned int uiHorizGreen = (unsigned int)m_frgbaColor2.IntGreen(127.0f);
+ unsigned int uiHorizBlue = (unsigned int)m_frgbaColor2.IntBlue(63.0f);
+
+ unsigned int uiVertRed = (unsigned int)m_frgbaColor3.IntRed(63.0f);
+ unsigned int uiVertGreen = (unsigned int)m_frgbaColor3.IntGreen(127.0f);
+ unsigned int uiVertBlue = (unsigned int)m_frgbaColor3.IntBlue(63.0f);
+
+ m_pencodingbitsRGB8->planar.originRed = uiOriginRed;
+ m_pencodingbitsRGB8->planar.originGreen1 = uiOriginGreen >> 6;
+ m_pencodingbitsRGB8->planar.originGreen2 = uiOriginGreen;
+ m_pencodingbitsRGB8->planar.originBlue1 = uiOriginBlue >> 5;
+ m_pencodingbitsRGB8->planar.originBlue2 = uiOriginBlue >> 3;
+ m_pencodingbitsRGB8->planar.originBlue3 = uiOriginBlue >> 1;
+ m_pencodingbitsRGB8->planar.originBlue4 = uiOriginBlue;
+
+ m_pencodingbitsRGB8->planar.horizRed1 = uiHorizRed >> 1;
+ m_pencodingbitsRGB8->planar.horizRed2 = uiHorizRed;
+ m_pencodingbitsRGB8->planar.horizGreen = uiHorizGreen;
+ m_pencodingbitsRGB8->planar.horizBlue1 = uiHorizBlue >> 5;
+ m_pencodingbitsRGB8->planar.horizBlue2 = uiHorizBlue;
+
+ m_pencodingbitsRGB8->planar.vertRed1 = uiVertRed >> 3;
+ m_pencodingbitsRGB8->planar.vertRed2 = uiVertRed;
+ m_pencodingbitsRGB8->planar.vertGreen1 = uiVertGreen >> 2;
+ m_pencodingbitsRGB8->planar.vertGreen2 = uiVertGreen;
+ m_pencodingbitsRGB8->planar.vertBlue = uiVertBlue;
+
+ m_pencodingbitsRGB8->planar.diff = 1;
+
+ // create valid RG differentials and an invalid B differential to trigger planar mode
+ m_pencodingbitsRGB8->planar.detect1 = 0;
+ m_pencodingbitsRGB8->planar.detect2 = 0;
m_pencodingbitsRGB8->planar.detect3 = 0;
- m_pencodingbitsRGB8->planar.detect4 = 1;
- }
+ m_pencodingbitsRGB8->planar.detect4 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ int iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ m_pencodingbitsRGB8->planar.detect1 = 1;
+ }
+ if (iGreen2 < 0 || iGreen2 > 31)
+ {
+ m_pencodingbitsRGB8->planar.detect2 = 1;
+ }
+ if (iBlue2 >= 4)
+ {
+ m_pencodingbitsRGB8->planar.detect3 = 7;
+ m_pencodingbitsRGB8->planar.detect4 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->planar.detect3 = 0;
+ m_pencodingbitsRGB8->planar.detect4 = 1;
+ }
- if (SANITY_CHECK) {
- iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
+
+ // make sure red and green don't overflow and blue does
+ assert(iRed2 >= 0 && iRed2 <= 31);
+ assert(iGreen2 >= 0 && iGreen2 <= 31);
+ assert(iBlue2 < 0 || iBlue2 > 31);
+ }
- // make sure red and green don't overflow and blue does
- assert(iRed2 >= 0 && iRed2 <= 31);
- assert(iGreen2 >= 0 && iGreen2 <= 31);
- assert(iBlue2 < 0 || iBlue2 > 31);
}
-}
-// ----------------------------------------------------------------------------------------------------
-// set the decoded colors and decoded alpha based on the encoding state for T mode
-//
-void Block4x4Encoding_RGB8::DecodePixels_T(void) {
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for T mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_T(void)
+ {
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- switch (m_auiSelectors[uiPixel]) {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
case 0:
m_afrgbaDecodedColors[uiPixel] = m_frgbaColor1;
break;
@@ -1419,20 +1612,25 @@ void Block4x4Encoding_RGB8::DecodePixels_T(void) {
case 3:
m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
break;
+ }
+
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// set the decoded colors and decoded alpha based on the encoding state for H mode
-//
-void Block4x4Encoding_RGB8::DecodePixels_H(void) {
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for H mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_H(void)
+ {
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- switch (m_auiSelectors[uiPixel]) {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
case 0:
m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 + frgbaDistance).ClampRGB();
break;
@@ -1448,75 +1646,85 @@ void Block4x4Encoding_RGB8::DecodePixels_H(void) {
case 3:
m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
break;
+ }
+
}
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-// set the decoded colors and decoded alpha based on the encoding state for Planar mode
-//
-void Block4x4Encoding_RGB8::DecodePixels_Planar(void) {
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for Planar mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_Planar(void)
+ {
- int iRO = (int)roundf(m_frgbaColor1.fR * 255.0f);
- int iGO = (int)roundf(m_frgbaColor1.fG * 255.0f);
- int iBO = (int)roundf(m_frgbaColor1.fB * 255.0f);
+ int iRO = (int)roundf(m_frgbaColor1.fR * 255.0f);
+ int iGO = (int)roundf(m_frgbaColor1.fG * 255.0f);
+ int iBO = (int)roundf(m_frgbaColor1.fB * 255.0f);
- int iRH = (int)roundf(m_frgbaColor2.fR * 255.0f);
- int iGH = (int)roundf(m_frgbaColor2.fG * 255.0f);
- int iBH = (int)roundf(m_frgbaColor2.fB * 255.0f);
+ int iRH = (int)roundf(m_frgbaColor2.fR * 255.0f);
+ int iGH = (int)roundf(m_frgbaColor2.fG * 255.0f);
+ int iBH = (int)roundf(m_frgbaColor2.fB * 255.0f);
- int iRV = (int)roundf(m_frgbaColor3.fR * 255.0f);
- int iGV = (int)roundf(m_frgbaColor3.fG * 255.0f);
- int iBV = (int)roundf(m_frgbaColor3.fB * 255.0f);
+ int iRV = (int)roundf(m_frgbaColor3.fR * 255.0f);
+ int iGV = (int)roundf(m_frgbaColor3.fG * 255.0f);
+ int iBV = (int)roundf(m_frgbaColor3.fB * 255.0f);
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++) {
- int iX = (int)(uiPixel >> 2);
- int iY = (int)(uiPixel & 3);
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ int iX = (int)(uiPixel >> 2);
+ int iY = (int)(uiPixel & 3);
- int iR = (iX * (iRH - iRO) + iY * (iRV - iRO) + 4 * iRO + 2) >> 2;
- int iG = (iX * (iGH - iGO) + iY * (iGV - iGO) + 4 * iGO + 2) >> 2;
- int iB = (iX * (iBH - iBO) + iY * (iBV - iBO) + 4 * iBO + 2) >> 2;
+ int iR = (iX*(iRH - iRO) + iY*(iRV - iRO) + 4*iRO + 2) >> 2;
+ int iG = (iX*(iGH - iGO) + iY*(iGV - iGO) + 4*iGO + 2) >> 2;
+ int iB = (iX*(iBH - iBO) + iY*(iBV - iBO) + 4*iBO + 2) >> 2;
- ColorFloatRGBA frgba;
- frgba.fR = (float)iR / 255.0f;
- frgba.fG = (float)iG / 255.0f;
- frgba.fB = (float)iB / 255.0f;
- frgba.fA = 1.0f;
+ ColorFloatRGBA frgba;
+ frgba.fR = (float)iR / 255.0f;
+ frgba.fG = (float)iG / 255.0f;
+ frgba.fB = (float)iB / 255.0f;
+ frgba.fA = 1.0f;
+
+ m_afrgbaDecodedColors[uiPixel] = frgba.ClampRGB();
+ }
- m_afrgbaDecodedColors[uiPixel] = frgba.ClampRGB();
}
-}
-// ----------------------------------------------------------------------------------------------------
-// perform a linear regression for the a_uiPixels in a_pafrgbaPixels[]
-//
-// output the closest color line using a_pfrgbaSlope and a_pfrgbaOffset
-//
-void Block4x4Encoding_RGB8::ColorRegression(ColorFloatRGBA *a_pafrgbaPixels, unsigned int a_uiPixels,
- ColorFloatRGBA *a_pfrgbaSlope, ColorFloatRGBA *a_pfrgbaOffset) {
- typedef struct
+ // ----------------------------------------------------------------------------------------------------
+ // perform a linear regression for the a_uiPixels in a_pafrgbaPixels[]
+ //
+ // output the closest color line using a_pfrgbaSlope and a_pfrgbaOffset
+ //
+ void Block4x4Encoding_RGB8::ColorRegression(ColorFloatRGBA *a_pafrgbaPixels, unsigned int a_uiPixels,
+ ColorFloatRGBA *a_pfrgbaSlope, ColorFloatRGBA *a_pfrgbaOffset)
{
- float f[4];
- } Float4;
+ typedef struct
+ {
+ float f[4];
+ } Float4;
- Float4 *paf4Pixels = (Float4 *)(a_pafrgbaPixels);
- Float4 *pf4Slope = (Float4 *)(a_pfrgbaSlope);
- Float4 *pf4Offset = (Float4 *)(a_pfrgbaOffset);
+ Float4 *paf4Pixels = (Float4 *)(a_pafrgbaPixels);
+ Float4 *pf4Slope = (Float4 *)(a_pfrgbaSlope);
+ Float4 *pf4Offset = (Float4 *)(a_pfrgbaOffset);
- float afX[MAX_PLANAR_REGRESSION_SIZE];
- float afY[MAX_PLANAR_REGRESSION_SIZE];
+ float afX[MAX_PLANAR_REGRESSION_SIZE];
+ float afY[MAX_PLANAR_REGRESSION_SIZE];
- // handle r, g and b separately. don't bother with a
- for (unsigned int uiComponent = 0; uiComponent < 3; uiComponent++) {
- for (unsigned int uiPixel = 0; uiPixel < a_uiPixels; uiPixel++) {
- afX[uiPixel] = (float)uiPixel;
- afY[uiPixel] = paf4Pixels[uiPixel].f[uiComponent];
- }
- Etc::Regression(afX, afY, a_uiPixels,
+ // handle r, g and b separately. don't bother with a
+ for (unsigned int uiComponent = 0; uiComponent < 3; uiComponent++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < a_uiPixels; uiPixel++)
+ {
+ afX[uiPixel] = (float)uiPixel;
+ afY[uiPixel] = paf4Pixels[uiPixel].f[uiComponent];
+
+ }
+ Etc::Regression(afX, afY, a_uiPixels,
&(pf4Slope->f[uiComponent]), &(pf4Offset->f[uiComponent]));
+ }
+
}
-}
-// ----------------------------------------------------------------------------------------------------
-//
+ // ----------------------------------------------------------------------------------------------------
+ //
}