Update texture packer to Godot Engine 4.0.

This commit is contained in:
K. S. Ernest (iFire) Lee 2023-05-27 13:08:19 -07:00
parent 2e8f8b970f
commit 52bc23c438
22 changed files with 258 additions and 345 deletions

View File

@ -8,38 +8,9 @@ It uses the legacy version of [rectpack2D](https://github.com/TeamHypersomnia/re
It should work on all platforms.
## Godot Version Support
This branch tries to follow godot's master branch (as much as I have time).
For different godot versions look at the other branches.
Status for this branch: Update for 4.0 is work in progress.
# Building
1. Get the source code for the engine.
If you want Godot 3.2:
```git clone -b 3.2 https://github.com/godotengine/godot.git godot```
If you want Godot 4.0:
```git clone https://github.com/godotengine/godot.git godot```
2. Go into Godot's modules directory.
```
cd ./godot/modules/
```
3. Clone this repository
```
git clone https://github.com/Relintai/texture_packer texture_packer
```
4. Build Godot. [Tutorial](https://docs.godotengine.org/en/latest/development/compiling/index.html)
Build Godot. [Tutorial](https://docs.godotengine.org/en/latest/development/compiling/index.html)
# Features and Usage
@ -53,14 +24,14 @@ Supports filters, custom background color, margins.
### The keep_original_atlases option:
If you set this to true, and then add AtlasTextures, TexturePacker will change these ones (the ones you actually added)
If you set this to true, and then add AtlasTextures, TexturePacker will change these ones (the ones you actually added)
after the bake.
You can use this to bake gui textures together, without changing the resources everywhere at runtime.
Think of rpgs, when you have a huge number of potential icons that the player can put on his or her actionbars.
You can take look at Tales of Maj'Eyal or pretty much every actually complex MMORPGs as an example.
Note: Doing something like this in only recommended, if you can't pre-make the atlases (or it's really unfeasible), you are better off
Note: Doing something like this in only recommended, if you can't pre-make the atlases (or it's really unfeasible), you are better off
making the atlases yourself during development.
## TextureMerger
@ -92,7 +63,7 @@ change to the first added texture's size.
add_texture looks like this:
```
```
void add_texture(Ref<Texture> p_texture, Color p_color = Color(1, 1, 1, 1), Vector2 p_position = Vector2(), Rect2 p_rect = Rect2());
```
@ -101,5 +72,5 @@ With the position parameter you can offset your texture (in the resulted texture
There are setters to manipulate the added data later.
After the merge, you can either use `get_result_as_texture()` (it creates an ImageTexture on the fly), or the `data` property to
After the merge, you can either use `get_result_as_texture()` (it creates an ImageTexture on the fly), or the `data` property to
grab the resulting Image.

24
SCsub
View File

@ -1,35 +1,19 @@
import os
Import('env')
Import("env")
module_env = env.Clone()
sources = [
"register_types.cpp",
"texture_packer.cpp",
"rectpack2D/pack.cpp",
"texture_merger.cpp",
"texture_resource/packer_image_resource.cpp",
"texture_resource/editor_plugin_packer_image_resource.cpp",
"texture_resource/packer_image_resource_importer.cpp",
"layers/texture_layer_merger.cpp",
]
module_env.add_source_files(env.modules_sources, sources)
if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes':
# Shared lib compilation
module_env.Append(CCFLAGS=['-fPIC'])
module_env['LIBS'] = []
shared_lib = module_env.SharedLibrary(target='#bin/texture_packer', source=sources)
shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
env.Append(LIBS=[shared_lib_shim])
env.Append(LIBPATH=['#bin'])
else:
# Static compilation
module_env.add_source_files(env.modules_sources, sources)
if env.editor_build:
module_env.add_source_files(env.modules_sources, "editor/*.cpp")

View File

@ -1,9 +1,11 @@
def can_build(env, platform):
return True
def configure(env):
pass
def get_doc_classes():
return [
"TextureMerger",
@ -12,5 +14,6 @@ def get_doc_classes():
"PackerImageResource",
]
def get_doc_path():
return "doc_classes"

View File

@ -1,18 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PackerImageResource" inherits="Texture" version="3.5">
<class name="PackerImageResource" inherits="Texture" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A simple [Texture] class containing an imported [Image] without drawing logic.
</brief_description>
<description>
PackerImageResource is a Texture class designed for baking textures. It contains an imported [Image] and does not register its data in the [RenderingServer]. This makes it useful for textures that are only needed for baking.
</description>
<tutorials>
</tutorials>
<methods>
<method name="set_data">
<return type="void" />
<param index="0" name="image" type="Image" />
<description>
Sets the image data for the [PackerImageResource].
</description>
</method>
</methods>
<members>
<member name="data" type="Image" setter="set_data" getter="get_data">
</member>
<member name="flags" type="int" setter="set_flags" getter="get_flags" overrides="Texture" default="0" />
</members>
<constants>
</constants>
</class>

View File

@ -1,113 +1,131 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextureLayerMerger" inherits="Reference" version="3.5">
<class name="TextureLayerMerger" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A class, that can merge textures as layers together.
A utility class that can merge textures as layers together.
</brief_description>
<description>
TextureLayerMerger is a utility class that allows you to combine multiple [Texture2D] objects into a single [ImageTexture]. It provides methods for adding, modifying, and removing textures, as well as controlling their position, color, and cropping. Once all textures are set up, the `merge` method can be called to create the final combined texture.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_texture">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<argument index="1" name="color" type="Color" default="Color( 1, 1, 1, 1 )" />
<argument index="2" name="position" type="Vector2" default="Vector2( 0, 0 )" />
<argument index="3" name="rect" type="Rect2" default="Rect2( 0, 0, 0, 0 )" />
<param index="0" name="texture" type="Texture2D" />
<param index="1" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="2" name="position" type="Vector2" default="Vector2(0, 0)" />
<param index="3" name="rect" type="Rect2" default="Rect2(0, 0, 0, 0)" />
<description>
Adds a new texture layer with the specified texture, color, position, and optional cropping rectangle.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
Removes all texture layers from the merger.
</description>
</method>
<method name="get_color">
<return type="Color" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the color of the texture layer at the specified index.
</description>
</method>
<method name="get_position">
<return type="Vector2" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the position of the texture layer at the specified index.
</description>
</method>
<method name="get_rect">
<return type="Rect2" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the cropping rectangle of the texture layer at the specified index.
</description>
</method>
<method name="get_result_as_texture" qualifiers="const">
<return type="ImageTexture" />
<description>
Returns the merged result as an [ImageTexture]. Call `merge` before using this method to get the updated result.
</description>
</method>
<method name="get_texture">
<return type="Texture" />
<argument index="0" name="index" type="int" />
<return type="Texture2D" />
<param index="0" name="index" type="int" />
<description>
Returns the [Texture2D] object of the texture layer at the specified index.
</description>
</method>
<method name="get_texture_count">
<return type="int" />
<description>
Returns the total number of texture layers in the merger.
</description>
</method>
<method name="merge">
<return type="void" />
<description>
Merges all texture layers into a single [ImageTexture]. Call `get_result_as_texture` after this method to get the merged result.
</description>
</method>
<method name="remove_texture">
<return type="void" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Removes the texture layer at the specified index.
</description>
</method>
<method name="set_color">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="color" type="Color" />
<param index="0" name="index" type="int" />
<param index="1" name="color" type="Color" />
<description>
Sets the color of the texture layer at the specified index.
</description>
</method>
<method name="set_position">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="position" type="Vector2" />
<param index="0" name="index" type="int" />
<param index="1" name="position" type="Vector2" />
<description>
Sets the position of the texture layer at the specified index.
</description>
</method>
<method name="set_rect">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="rect" type="Rect2" />
<param index="0" name="index" type="int" />
<param index="1" name="rect" type="Rect2" />
<description>
Sets the cropping rectangle of the texture layer at the specified index.
</description>
</method>
<method name="set_texture">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="texture" type="Texture" />
<param index="0" name="index" type="int" />
<param index="1" name="texture" type="Texture2D" />
<description>
Sets the [Texture2D] object of the texture layer at the specified index.
</description>
</method>
</methods>
<members>
<member name="base_color" type="Color" setter="set_base_color" getter="get_base_color" default="Color( 0, 0, 0, 1 )">
<member name="base_color" type="Color" setter="set_base_color" getter="get_base_color" default="Color(0, 0, 0, 1)">
The base color used as the background for the merged texture.
</member>
<member name="data" type="Image" setter="set_data" getter="get_data">
The [Image] data of the merged texture.
</member>
<member name="height" type="int" setter="set_height" getter="get_height" default="0">
The height of the merged texture.
</member>
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="0">
[Texture] flags applied to the merged texture.
</member>
<member name="width" type="int" setter="set_width" getter="get_width" default="0">
The width of the merged texture.
</member>
</members>
<constants>
</constants>
</class>

View File

@ -1,157 +1,186 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextureMerger" inherits="Node" version="3.5">
<class name="TextureMerger" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A node, that can merge textures.
A node that can merge textures.
</brief_description>
<description>
TextureMerger is a utility node that allows you to combine multiple [Texture] objects into a single [AtlasTexture]. It provides methods for adding, modifying, and removing textures, as well as controlling their position and cropping. Once all textures are set up, the `merge` method can be called to create the final combined texture.
</description>
<tutorials>
</tutorials>
<methods>
<method name="_texture_added" qualifiers="virtual">
<return type="void" />
<argument index="0" name="texture" type="AtlasTexture" />
<param index="0" name="texture" type="AtlasTexture" />
<description>
Called when a new texture is added to the merger. Can be overridden in extended classes to implement custom behavior.
</description>
</method>
<method name="_texture_merged" qualifiers="virtual">
<return type="void" />
<description>
Called when the textures are merged. Can be overridden in extended classes to implement custom behavior.
</description>
</method>
<method name="_texture_removed" qualifiers="virtual">
<return type="void" />
<description>
Called when a texture is removed from the merger. Can be overridden in derived classes to implement custom behavior.
</description>
</method>
<method name="add_texture">
<return type="AtlasTexture" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture" />
<description>
Adds a new texture to the merger and returns the corresponding [AtlasTexture].
</description>
</method>
<method name="clear">
<return type="void" />
<description>
Removes all textures from the merger.
</description>
</method>
<method name="get_dirty" qualifiers="const">
<return type="bool" />
<description>
Returns whether the merger is marked as dirty, indicating that the merged texture needs to be updated.
</description>
</method>
<method name="get_generated_texture">
<return type="ImageTexture" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the generated [ImageTexture] at the specified index after merging.
</description>
</method>
<method name="get_generated_texture_count">
<return type="int" />
<description>
Returns the total number of generated textures in the merger.
</description>
</method>
<method name="get_original_texture">
<return type="Texture" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the original [Texture] object at the specified index.
</description>
</method>
<method name="get_packer" qualifiers="const">
<return type="TexturePacker" />
<description>
Returns the [TexturePacker] instance used by the merger.
</description>
</method>
<method name="get_texture">
<return type="AtlasTexture" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture" />
<description>
Returns the [AtlasTexture] corresponding to the given [Texture] object.
</description>
</method>
<method name="get_texture_count">
<return type="int" />
<description>
Returns the total number of textures in the merger.
</description>
</method>
<method name="get_texture_index">
<return type="AtlasTexture" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the [AtlasTexture] at the specified index.
</description>
</method>
<method name="merge">
<return type="void" />
<description>
Merges all textures into a single [AtlasTexture]. Call `get_generated_texture` after this method to get the merged result.
</description>
</method>
<method name="remove_texture">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture" />
<description>
Removes the specified texture from the merger.
</description>
</method>
<method name="remove_texture_index">
<return type="void" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Removes the texture at the specified index from the merger.
</description>
</method>
<method name="set_dirty">
<return type="void" />
<argument index="0" name="value" type="bool" />
<param index="0" name="value" type="bool" />
<description>
Sets the dirty flag for the merger, indicating that the merged texture needs to be updated.
</description>
</method>
<method name="set_packer">
<return type="void" />
<argument index="0" name="packer" type="TexturePacker" />
<param index="0" name="packer" type="TexturePacker" />
<description>
Sets the [TexturePacker] instance to be used by the merger.
</description>
</method>
<method name="unref_texture">
<return type="bool" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture" />
<description>
Decreases the reference count of the specified texture and removes it from the merger if the reference count reaches zero. Returns true if the texture was removed.
</description>
</method>
<method name="unref_texture_index">
<return type="bool" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Decreases the reference count of the texture at the specified index and removes it from the merger if the reference count reaches zero. Returns true if the texture was removed.
</description>
</method>
</methods>
<members>
<member name="automatic_merge" type="bool" setter="set_automatic_merge" getter="get_automatic_merge" default="false">
If true, textures will be automatically merged when added or removed.
</member>
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color( 0, 0, 0, 1 )">
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color(0, 0, 0, 1)">
The background color of the generated [AtlasTexture].
</member>
<member name="keep_original_atlases" type="bool" setter="set_keep_original_atlases" getter="get_keep_original_atlases" default="false">
If true, original atlases will be kept in memory after merging.
</member>
<member name="margin" type="int" setter="set_margin" getter="get_margin" default="0">
The margin between textures in the generated [AtlasTexture].
</member>
<member name="max_atlas_size" type="int" setter="set_max_atlas_size" getter="get_max_atlas_size" default="1024">
The maximum size of the generated [AtlasTexture].
</member>
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="5">
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="0">
[Texture] flags to apply to the generated [AtlasTexture].
</member>
<member name="textures" type="Array" setter="set_textures" getter="get_textures" default="[ ]">
<member name="textures" type="Array" setter="set_textures" getter="get_textures" default="[]">
Array of textures to be merged.
</member>
</members>
<signals>
<signal name="texture_added">
<argument index="0" name="texture" type="AtlasTexture" />
<param index="0" name="texture" type="AtlasTexture" />
<description>
Emitted when a new texture is added to the merger.
</description>
</signal>
<signal name="texture_merged">
<description>
Emitted when the textures are merged.
</description>
</signal>
<signal name="texture_removed">
<description>
Emitted when a texture is removed from the merger.
</description>
</signal>
</signals>
<constants>
</constants>
</class>

View File

@ -1,100 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TexturePacker" inherits="Reference" version="3.5">
<class name="TexturePacker" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A class, that can merge textures.
A packer utility that can merge textures.
</brief_description>
<description>
TexturePacker is a utility class that allows you to merge multiple textures into a single texture atlas.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_texture">
<return type="AtlasTexture" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture2D" />
<description>
Adds a texture to the packer and returns an [AtlasTexture] representing the added texture.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
Clears all textures from the packer.
</description>
</method>
<method name="get_generated_texture">
<return type="ImageTexture" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns the generated ImageTexture at the given index.
</description>
</method>
<method name="get_generated_texture_count">
<return type="int" />
<description>
Returns the number of generated textures in the packer.
</description>
</method>
<method name="get_original_texture">
<return type="Texture" />
<argument index="0" name="index" type="int" />
<return type="Texture2D" />
<param index="0" name="index" type="int" />
<description>
Returns the original [Texture2D] at the given index.
</description>
</method>
<method name="get_texture">
<return type="AtlasTexture" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture2D" />
<description>
Returns an [AtlasTexture] representing the given Texture2D.
</description>
</method>
<method name="get_texture_count">
<return type="int" />
<description>
Returns the number of textures added to the packer.
</description>
</method>
<method name="get_texture_index">
<return type="AtlasTexture" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Returns an [AtlasTexture] representing the texture at the given index.
</description>
</method>
<method name="merge">
<return type="void" />
<description>
Merges all added textures into a single texture atlas.
</description>
</method>
<method name="remove_texture">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture2D" />
<description>
Removes the specified texture from the packer.
</description>
</method>
<method name="remove_texture_index">
<return type="void" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Removes the texture at the specified index from the packer.
</description>
</method>
<method name="unref_texture">
<return type="bool" />
<argument index="0" name="texture" type="Texture" />
<param index="0" name="texture" type="Texture2D" />
<description>
Unreferences the specified texture and returns true if successful, false otherwise.
</description>
</method>
<method name="unref_texture_index">
<return type="bool" />
<argument index="0" name="index" type="int" />
<param index="0" name="index" type="int" />
<description>
Unreferences the texture at the specified index and returns true if successful, false otherwise.
</description>
</method>
</methods>
<members>
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color( 0, 0, 0, 1 )">
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color(0, 0, 0, 1)">
The background color of the texture atlas.
</member>
<member name="keep_original_atlases" type="bool" setter="set_keep_original_atlases" getter="get_keep_original_atlases" default="false">
If true, the original atlases will be kept in memory after merging.
</member>
<member name="margin" type="int" setter="set_margin" getter="get_margin" default="0">
The margin between textures in the atlas.
</member>
<member name="max_atlas_size" type="int" setter="set_max_atlas_size" getter="get_max_atlas_size" default="1024">
The maximum size of the texture atlas.
</member>
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="5">
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="0">
Texture flags applied to the generated atlas.
</member>
</members>
<constants>
</constants>
</class>

View File

@ -27,11 +27,7 @@ SOFTWARE.
void EditorPluginPackerImageResource::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
#if VERSION_MAJOR < 4
_importer.instantiate();
#else
_importer.instantiate();
#endif
add_import_plugin(_importer);
break;
@ -44,6 +40,5 @@ void EditorPluginPackerImageResource::_notification(int p_what) {
}
}
EditorPluginPackerImageResource::EditorPluginPackerImageResource(EditorNode *node) {
_node = node;
EditorPluginPackerImageResource::EditorPluginPackerImageResource() {
}

View File

@ -23,31 +23,23 @@ SOFTWARE.
#ifndef EDITOR_PLUGIN_PACKER_IMAGE_RESOURCE_H
#define EDITOR_PLUGIN_PACKER_IMAGE_RESOURCE_H
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/string/ustring.h"
#else
#include "core/ustring.h"
#endif
#include "core/version.h"
#include "editor/editor_plugin.h"
#include "packer_image_resource_importer.h"
class EditorPluginPackerImageResource : public EditorPlugin {
GDCLASS(EditorPluginPackerImageResource, EditorPlugin);
public:
EditorPluginPackerImageResource(EditorNode *node);
EditorPluginPackerImageResource();
protected:
void _notification(int p_what);
private:
EditorNode *_node;
Ref<PackerImageResourceImporter> _importer;
};
#endif
#endif // EDITOR_PLUGIN_PACKER_IMAGE_RESOURCE_H

View File

@ -24,10 +24,6 @@ SOFTWARE.
#include "core/version.h"
#if VERSION_MAJOR >= 4
#define REAL FLOAT
#endif
String PackerImageResourceImporter::get_importer_name() const {
return "packer_image_resource";
}
@ -62,7 +58,7 @@ String PackerImageResourceImporter::get_preset_name(int p_idx) const {
void PackerImageResourceImporter::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "hdr_as_srgb"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "scale"), 1.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "scale"), 1.0));
}
bool PackerImageResourceImporter::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
@ -72,31 +68,16 @@ bool PackerImageResourceImporter::get_option_visibility(const String &p_path, co
Error PackerImageResourceImporter::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
bool hdr_as_srgb = p_options["hdr_as_srgb"];
float scale = p_options["scale"];
Ref<Image> image;
#if VERSION_MAJOR < 4
image.instantiate();
#else
image.instantiate();
#endif
Error err = ImageLoader::load_image(p_source_file, image, NULL, hdr_as_srgb, scale);
Error err = ImageLoader::load_image(p_source_file, image, nullptr, hdr_as_srgb, scale);
if (err != OK) {
return err;
}
Ref<PackerImageResource> res;
#if VERSION_MAJOR < 4
res.instantiate();
#else
res.instantiate();
#endif
res->set_data(image);
return ResourceSaver::save(res, p_save_path + "." + get_save_extension());
return Error::ERR_PARSE_ERROR;
}
PackerImageResourceImporter::PackerImageResourceImporter() {

View File

@ -23,41 +23,34 @@ SOFTWARE.
#ifndef PACKER_IMAGE_RESOURCE_H
#define PACKER_IMAGE_RESOURCE_H
#include "core/io/image.h"
#include "core/io/image_loader.h"
#include "core/io/resource_saver.h"
#include "core/string/ustring.h"
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/image.h"
#include "core/string/ustring.h"
#else
#include "core/image.h"
#include "core/ustring.h"
#endif
#include "core/io/resource_saver.h"
#include "editor/import/editor_import_plugin.h"
#include "core/io/image_loader.h"
#include "packer_image_resource.h"
#include "../texture_resource/packer_image_resource.h"
class PackerImageResourceImporter : public EditorImportPlugin {
GDCLASS(PackerImageResourceImporter, EditorImportPlugin);
public:
virtual String get_importer_name() const;
virtual String get_visible_name() const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual String get_save_extension() const;
virtual String get_resource_type() const;
virtual float get_priority() const;
virtual String get_importer_name() const override;
virtual String get_visible_name() const override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
virtual String get_save_extension() const override;
virtual String get_resource_type() const override;
virtual float get_priority() const override;
virtual int get_preset_count() const;
virtual String get_preset_name(int p_idx) const;
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const override;
virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) override;
PackerImageResourceImporter();
~PackerImageResourceImporter();

View File

@ -78,7 +78,7 @@ Ref<ImageTexture> TextureLayerMerger::get_result_as_texture() const {
return tex;
}
void TextureLayerMerger::add_texture(const Ref<Texture> &p_texture, const Color &p_color, const Vector2 &p_position, Rect2 p_rect) {
void TextureLayerMerger::add_texture(const Ref<Texture2D> &p_texture, const Color &p_color, const Vector2 &p_position, Rect2 p_rect) {
ERR_FAIL_COND(!p_texture.is_valid());
LayerMergerEntry entry;
@ -119,12 +119,12 @@ void TextureLayerMerger::add_texture(const Ref<Texture> &p_texture, const Color
_entries.push_back(entry);
}
Ref<Texture> TextureLayerMerger::get_texture(const int p_index) {
ERR_FAIL_INDEX_V(p_index, _entries.size(), Ref<Texture>());
Ref<Texture2D> TextureLayerMerger::get_texture(const int p_index) {
ERR_FAIL_INDEX_V(p_index, _entries.size(), Ref<Texture2D>());
return _entries.get(p_index).texture;
}
void TextureLayerMerger::set_texture(const int p_index, const Ref<Texture> &p_texture) {
void TextureLayerMerger::set_texture(const int p_index, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_index, _entries.size());
_entries.get(p_index).texture = p_texture;
@ -192,7 +192,7 @@ void TextureLayerMerger::merge() {
#endif
}
PoolVector<uint8_t> data;
Vector<uint8_t> data;
data.resize(_width * _height * 4);
write_base_color_to_array(data);
@ -220,7 +220,7 @@ void TextureLayerMerger::merge() {
Ref<Image> input_image;
if (altas_texture.is_valid()) {
Ref<Texture> atlas = altas_texture->get_atlas();
Ref<Texture2D> atlas = altas_texture->get_atlas();
ERR_CONTINUE(!atlas.is_valid());
@ -255,7 +255,7 @@ void TextureLayerMerger::merge() {
int iiw = input_image->get_width();
int iih = input_image->get_height();
PoolVector<uint8_t> input_image_data = input_image->get_data();
Vector<uint8_t> input_image_data = input_image->get_data();
const Color &blendcolor = e.color;
@ -333,15 +333,10 @@ void TextureLayerMerger::merge() {
}
}
}
#if VERSION_MAJOR < 4
_image->create(_width, _height, (_texture_flags & Texture::FLAG_MIPMAPS) != 0, Image::FORMAT_RGBA8, data);
#else
_image->create(_width, _height, true, Image::FORMAT_RGBA8, data);
#endif
_image = Image::create_from_data(_width, _height, true, Image::FORMAT_RGBA8, data);
}
void TextureLayerMerger::write_base_color_to_array(PoolVector<uint8_t> &data) {
void TextureLayerMerger::write_base_color_to_array(Vector<uint8_t> &data) {
int cr = _base_color.r * 255;
int cg = _base_color.g * 255;
int cb = _base_color.b * 255;

View File

@ -25,32 +25,17 @@ SOFTWARE.
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/object/ref_counted.h"
#ifndef Reference
#define Reference RefCounted
#endif
#include "core/templates/vector.h"
#include "core/io/image.h"
#else
#include "core/reference.h"
#include "core/vector.h"
#include "core/image.h"
#endif
#include "core/math/rect2.h"
#include "scene/resources/texture.h"
#include "core/version.h"
#if VERSION_MAJOR >= 4
#define PoolVector Vector
#define Texture Texture2D
#endif
class TextureLayerMerger : public RefCounted {
class TextureLayerMerger : public Reference {
GDCLASS(TextureLayerMerger, Reference);
GDCLASS(TextureLayerMerger, RefCounted);
public:
int get_width() const;
@ -70,10 +55,10 @@ public:
Ref<ImageTexture> get_result_as_texture() const;
void add_texture(const Ref<Texture> &p_texture, const Color &p_color = Color(1, 1, 1, 1), const Vector2 &p_position = Vector2(), Rect2 p_rect = Rect2());
void add_texture(const Ref<Texture2D> &p_texture, const Color &p_color = Color(1, 1, 1, 1), const Vector2 &p_position = Vector2(), Rect2 p_rect = Rect2());
Ref<Texture> get_texture(const int p_index);
void set_texture(const int p_index, const Ref<Texture> &p_texture);
Ref<Texture2D> get_texture(const int p_index);
void set_texture(const int p_index, const Ref<Texture2D> &p_texture);
Color get_color(const int p_index);
void set_color(const int p_index, const Color &p_color);
@ -94,12 +79,12 @@ public:
~TextureLayerMerger();
protected:
void write_base_color_to_array(PoolVector<uint8_t> &data);
void write_base_color_to_array(Vector<uint8_t> &data);
static void _bind_methods();
struct LayerMergerEntry {
Ref<Texture> texture;
Ref<Texture2D> texture;
Color color;
Rect2 rect;
Vector2 position;
@ -118,4 +103,4 @@ private:
Vector<LayerMergerEntry> _entries;
};
#endif
#endif // TEXTURE_LAYER_MERGER_H

View File

@ -10,14 +10,14 @@ No crashes so far and works quite fast.
Copied from: http://gamedev.stackexchange.com/a/34193/16982
[This algorithm][1] should meet every gamedeving needs.
It's very, very efficient, lightweight, and I've myself improved it with searching the best possible sorting function
(whether it's by area, perimeter, width, height, max(width, height))
[This algorithm][1] should meet every gamedeving needs.
It's very, very efficient, lightweight, and I've myself improved it with searching the best possible sorting function
(whether it's by area, perimeter, width, height, max(width, height))
and the best possible bin size so **you don't have to hardcode the width/height yourself anymore**.
It's also easy to design it so it automatically portions out your rectangles into more bins
if one with fixed maximum size is not sufficient, so you probably want to pass all your textures to it
and pass a maximum texture size as the value for maximum bins' dimension, and BAM !
and pass a maximum texture size as the value for maximum bins' dimension, and BAM !
You have your texture atlases ready to be uploaded to GPU. Same goes for font packing.
400 random rectangles, automatically divided into 3 bins of maximum 400x400 size:

View File

@ -46,7 +46,7 @@ int discard_step = 128;
For every sorting function, algorithm will perform packing attempts beginning with a bin with width and height equal to max_side,
and decreasing its dimensions if it finds out that rectangles did actually fit, increasing otherwise.
Although, it's doing that in sort of binary search manner, so for every comparing function it will perform at most log2(max_side) packing attempts looking for the smallest possible bin size.
discard_step = 128 means that the algorithm will break of the searching loop if the rectangles fit but "it may be possible to fit them in a bin smaller by 128"
discard_step = 128 means that the algorithm will break of the searching loop if the rectangles fit but "it may be possible to fit them in a bin smaller by 128"
the bigger the value, the sooner the algorithm will finish but the rectangles will be packed less tightly.
use discard_step = 1 for maximum tightness.
@ -76,8 +76,8 @@ struct node {
pnode c[2];
rect_ltrb rc;
bool id = false;
node(rect_ltrb rc = rect_ltrb()) :
rc(rc) {}
node(rect_ltrb rect_rc = rect_ltrb()) :
rc(rect_rc) {}
void reset(const rect_wh &r) {
id = false;
@ -272,15 +272,15 @@ rect_wh::rect_wh(const rect_ltrb &rr) :
rect_wh::rect_wh(const rect_xywh &rr) :
w(rr.w),
h(rr.h) {}
rect_wh::rect_wh(int w, int h) :
w(w),
h(h) {}
rect_wh::rect_wh(int p_w, int p_h) :
w(p_w),
h(p_h) {}
int rect_wh::fits(const rect_wh &r, bool allowFlip) const {
if (w == r.w && h == r.h) return 3;
if (allowFlip && h == r.w && w == r.h) return 4;
if (w <= r.w && h <= r.h) return 1;
if (allowFlip && h <= r.w && w <= r.h) return 2;
int rect_wh::fits(const rect_wh &p_r, bool p_allow_flip) const {
if (w == p_r.w && h == p_r.h) return 3;
if (p_allow_flip && h == p_r.w && w == p_r.h) return 4;
if (w <= p_r.w && h <= p_r.h) return 1;
if (p_allow_flip && h <= p_r.w && w <= p_r.h) return 2;
return 0;
}
@ -289,11 +289,11 @@ rect_ltrb::rect_ltrb() :
t(0),
r(0),
b(0) {}
rect_ltrb::rect_ltrb(int l, int t, int r, int b) :
l(l),
t(t),
r(r),
b(b) {}
rect_ltrb::rect_ltrb(int p_l, int p_t, int p_r, int p_b) :
l(p_l),
t(p_t),
r(p_r),
b(p_b) {}
int rect_ltrb::w() const {
return r - l;
@ -322,16 +322,16 @@ void rect_ltrb::h(int hh) {
rect_xywh::rect_xywh() :
x(0),
y(0) {}
rect_xywh::rect_xywh(const rect_ltrb &rc) :
x(rc.l),
y(rc.t) {
b(rc.b);
r(rc.r);
rect_xywh::rect_xywh(const rect_ltrb &p_rc) :
x(p_rc.l),
y(p_rc.t) {
b(p_rc.b);
r(p_rc.r);
}
rect_xywh::rect_xywh(int x, int y, int w, int h) :
rect_wh(w, h),
x(x),
y(y) {}
rect_xywh::rect_xywh(int p_x, int p_y, int p_w, int p_h) :
rect_wh(p_w, p_h),
x(p_x),
y(p_y) {}
rect_xywh::operator rect_ltrb() {
rect_ltrb rr(x, y, 0, 0);
@ -348,12 +348,12 @@ int rect_xywh::b() const {
return y + h;
}
void rect_xywh::r(int right) {
w = right - x;
void rect_xywh::r(int p_right) {
w = p_right - x;
}
void rect_xywh::b(int bottom) {
h = bottom - y;
void rect_xywh::b(int p_bottom) {
h = p_bottom - y;
}
int rect_wh::area() {
@ -364,11 +364,11 @@ int rect_wh::perimeter() {
return 2 * w + 2 * h;
}
rect_xywhf::rect_xywhf(const rect_ltrb &rr) :
rect_xywh(rr),
rect_xywhf::rect_xywhf(const rect_ltrb &p_rr) :
rect_xywh(p_rr),
flipped(false) {}
rect_xywhf::rect_xywhf(int x, int y, int width, int height) :
rect_xywh(x, y, width, height),
rect_xywhf::rect_xywhf(int p_x, int p_y, int p_width, int p_height) :
rect_xywh(p_x, p_y, p_width, p_height),
flipped(false) {}
rect_xywhf::rect_xywhf() :
flipped(false) {}

View File

@ -21,23 +21,18 @@ SOFTWARE.
*/
#include "register_types.h"
#include "core/object/class_db.h"
#include "layers/texture_layer_merger.h"
#include "texture_merger.h"
#include "texture_packer.h"
#include "texture_resource/packer_image_resource.h"
#include "layers/texture_layer_merger.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_plugin.h"
#include "texture_resource/editor_plugin_packer_image_resource.h"
#include "editor/editor_plugin_packer_image_resource.h"
#endif
void register_texture_packer_types(ModuleInitializationLevel p_level) {
void initialize_texture_packer_module(ModuleInitializationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
GDREGISTER_CLASS(TexturePacker);
GDREGISTER_CLASS(TextureMerger);
@ -54,5 +49,5 @@ void register_texture_packer_types(ModuleInitializationLevel p_level) {
#endif
}
void unregister_texture_packer_types(ModuleInitializationLevel p_level) {
void uninitialize_texture_packer_module(ModuleInitializationLevel p_level) {
}

View File

@ -28,4 +28,4 @@ SOFTWARE.
void initialize_texture_packer_module(ModuleInitializationLevel p_level);
void uninitialize_texture_packer_module(ModuleInitializationLevel p_level);
#endif
#endif // TEXTURE_PACKER_REGISTER_TYPES_H

View File

@ -25,13 +25,8 @@ SOFTWARE.
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/templates/vector.h"
#include "core/config/engine.h"
#else
#include "core/vector.h"
#include "core/engine.h"
#endif
#include "scene/main/node.h"

View File

@ -57,7 +57,7 @@ void TexturePacker::set_margin(const int margin) {
_margin = margin;
}
Ref<AtlasTexture> TexturePacker::add_texture(const Ref<Texture> &texture) {
Ref<AtlasTexture> TexturePacker::add_texture(const Ref<Texture2D> &texture) {
ERR_FAIL_COND_V(!texture.is_valid(), Ref<AtlasTexture>());
Ref<AtlasTexture> atlas_text = texture;
@ -67,7 +67,7 @@ Ref<AtlasTexture> TexturePacker::add_texture(const Ref<Texture> &texture) {
for (int i = 0; i < _rects.size(); ++i) {
rect_xywhf *r = _rects.get(i);
Ref<Texture> t;
Ref<Texture2D> t;
Ref<AtlasTexture> at = texture;
if (_keep_original_atlases && at.is_valid())
@ -148,11 +148,11 @@ Ref<AtlasTexture> TexturePacker::add_texture(const Ref<Texture> &texture) {
return tex;
}
Ref<AtlasTexture> TexturePacker::get_texture(const Ref<Texture> &texture) {
Ref<AtlasTexture> TexturePacker::get_texture(const Ref<Texture2D> &texture) {
for (int i = 0; i < _rects.size(); ++i) {
rect_xywhf *r = _rects.get(i);
Ref<Texture> t;
Ref<Texture2D> t;
Ref<AtlasTexture> at = texture;
if (_keep_original_atlases && at.is_valid())
@ -165,7 +165,7 @@ Ref<AtlasTexture> TexturePacker::get_texture(const Ref<Texture> &texture) {
}
}
return Ref<Texture>();
return Ref<Texture2D>();
}
Ref<AtlasTexture> TexturePacker::get_texture_index(const int index) {
@ -174,17 +174,17 @@ Ref<AtlasTexture> TexturePacker::get_texture_index(const int index) {
return _rects.get(index)->atlas_texture;
}
Ref<Texture> TexturePacker::get_original_texture(const int index) {
ERR_FAIL_INDEX_V(index, _rects.size(), Ref<Texture>());
Ref<Texture2D> TexturePacker::get_original_texture(const int index) {
ERR_FAIL_INDEX_V(index, _rects.size(), Ref<Texture2D>());
return _rects.get(index)->original_texture;
}
bool TexturePacker::contains_texture(const Ref<Texture> &texture) {
bool TexturePacker::contains_texture(const Ref<Texture2D> &texture) {
for (int i = 0; i < _rects.size(); ++i) {
rect_xywhf *r = _rects.get(i);
Ref<Texture> t;
Ref<Texture2D> t;
Ref<AtlasTexture> at = texture;
if (_keep_original_atlases && at.is_valid())
@ -225,11 +225,11 @@ bool TexturePacker::unref_texture_index(const int index) {
return false;
}
bool TexturePacker::unref_texture(const Ref<Texture> &texture) {
bool TexturePacker::unref_texture(const Ref<Texture2D> &texture) {
for (int i = 0; i < _rects.size(); ++i) {
rect_xywhf *r = _rects.get(i);
Ref<Texture> t;
Ref<Texture2D> t;
Ref<AtlasTexture> at = texture;
if (_keep_original_atlases && at.is_valid())
@ -273,11 +273,11 @@ void TexturePacker::remove_texture_index(const int index) {
memdelete(r);
}
void TexturePacker::remove_texture(const Ref<Texture> &texture) {
void TexturePacker::remove_texture(const Ref<Texture2D> &texture) {
for (int i = 0; i < _rects.size(); ++i) {
rect_xywhf *r = _rects.get(i);
Ref<Texture> t;
Ref<Texture2D> t;
Ref<AtlasTexture> at = texture;
if (_keep_original_atlases && at.is_valid())
@ -345,7 +345,7 @@ void TexturePacker::merge() {
for (uint32_t i = 0; i < bins.size(); ++i) {
bin b = bins[i];
PoolByteArray data;
PackedByteArray data;
data.resize(b.size.w * b.size.h * 4);
//Setup background color
@ -365,7 +365,7 @@ void TexturePacker::merge() {
for (uint32_t j = 0; j < b.rects.size(); ++j) {
rect_xywhf *r = b.rects[j];
Ref<Texture> otext = r->original_texture;
Ref<Texture2D> otext = r->original_texture;
Ref<AtlasTexture> aotext = otext;
int rect_pos_x = 0;
@ -392,7 +392,7 @@ void TexturePacker::merge() {
int img_width = img->get_width();
PoolByteArray image_data = img->get_data();
PackedByteArray image_data = img->get_data();
int input_format_offset = get_offset_for_format(img->get_format());
@ -412,26 +412,9 @@ void TexturePacker::merge() {
}
}
Ref<Image> image;
#if VERSION_MAJOR < 4
image.instantiate();
#else
image.instantiate();
#endif
image->create(b.size.w, b.size.h, false, Image::FORMAT_RGBA8, data);
Ref<Image> image = Image::create_from_data(b.size.w, b.size.h, false, Image::FORMAT_RGBA8, data);
Ref<ImageTexture> texture;
#if VERSION_MAJOR < 4
texture.instantiate();
#else
texture.instantiate();
#endif
#if VERSION_MAJOR < 4
texture->create_from_image(image, _texture_flags);
#else
texture->create_from_image(image);
#endif
Ref<ImageTexture> texture = ImageTexture::create_from_image(image);
_generated_textures.set(i, texture);
@ -476,12 +459,6 @@ int TexturePacker::get_offset_for_format(const Image::Format format) {
case Image::FORMAT_BPTC_RGBA:
case Image::FORMAT_BPTC_RGBF:
case Image::FORMAT_BPTC_RGBFU:
#if VERSION_MAJOR <= 3
case Image::FORMAT_PVRTC2:
case Image::FORMAT_PVRTC2A:
case Image::FORMAT_PVRTC4:
case Image::FORMAT_PVRTC4A:
#endif
case Image::FORMAT_ETC:
case Image::FORMAT_ETC2_R11:
case Image::FORMAT_ETC2_R11S:
@ -490,13 +467,13 @@ int TexturePacker::get_offset_for_format(const Image::Format format) {
case Image::FORMAT_ETC2_RGB8:
case Image::FORMAT_ETC2_RGBA8:
case Image::FORMAT_ETC2_RGB8A1:
#if VERSION_MAJOR >= 4
case Image::FORMAT_ASTC_4x4:
case Image::FORMAT_ASTC_4x4_HDR:
case Image::FORMAT_ASTC_8x8:
case Image::FORMAT_ASTC_8x8_HDR:
case Image::FORMAT_RGB565:
case Image::FORMAT_ETC2_RA_AS_RG:
case Image::FORMAT_DXT5_RA_AS_RG:
#else
case Image::FORMAT_RGBA5551:
#endif
case Image::FORMAT_MAX:
return 0;
}
@ -506,7 +483,7 @@ int TexturePacker::get_offset_for_format(const Image::Format format) {
TexturePacker::TexturePacker() {
#if VERSION_MAJOR < 4
_texture_flags = Texture::FLAG_MIPMAPS | Texture::FLAG_FILTER;
_texture_flags = Texture2D::FLAG_MIPMAPS | Texture2D::FLAG_FILTER;
#else
_texture_flags = 0;
#endif

View File

@ -25,38 +25,19 @@ SOFTWARE.
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/image.h"
#include "core/object/ref_counted.h"
#ifndef Reference
#define Reference RefCounted
#endif
#include "core/templates/vector.h"
#include "core/string/ustring.h"
#include "core/math/color.h"
#else
#include "core/image.h"
#include "core/reference.h"
#include "core/vector.h"
#include "core/ustring.h"
#include "core/color.h"
#endif
#include "scene/resources/texture.h"
#include <vector>
#include "rectpack2D/pack.h"
#if VERSION_MAJOR >= 4
#define PoolVector Vector
#define Texture Texture2D
#define PoolByteArray PackedByteArray
#define REAL FLOAT
#endif
class TexturePacker : public Reference {
GDCLASS(TexturePacker, Reference);
class TexturePacker : public RefCounted {
GDCLASS(TexturePacker, RefCounted);
public:
int get_texture_flags() const;
@ -74,19 +55,19 @@ public:
int get_margin() const;
void set_margin(const int margin);
Ref<AtlasTexture> add_texture(const Ref<Texture> &texture);
Ref<AtlasTexture> add_texture(const Ref<Texture2D> &texture);
Ref<AtlasTexture> get_texture(const Ref<Texture> &texture);
Ref<AtlasTexture> get_texture(const Ref<Texture2D> &texture);
Ref<AtlasTexture> get_texture_index(const int index);
Ref<Texture> get_original_texture(const int index);
Ref<Texture2D> get_original_texture(const int index);
bool contains_texture(const Ref<Texture> &texture);
bool contains_texture(const Ref<Texture2D> &texture);
bool unref_texture_index(const int index);
bool unref_texture(const Ref<Texture> &texture);
bool unref_texture(const Ref<Texture2D> &texture);
void remove_texture_index(const int index);
void remove_texture(const Ref<Texture> &texture);
void remove_texture(const Ref<Texture2D> &texture);
int get_texture_count();
void clear();
@ -115,4 +96,4 @@ private:
Vector<Ref<ImageTexture> > _generated_textures;
};
#endif
#endif // TEXTURE_PACKER_H

View File

@ -20,7 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "packer_image_resource.h"
#include "../texture_resource/packer_image_resource.h"
#include "core/version.h"

View File

@ -42,7 +42,7 @@ public:
int get_width() const;
int get_height() const;
RID get_rid() const;
RID get_rid() const override;
bool has_alpha() const;
void set_flags(uint32_t p_flags);