CollageDrawer - coldrockgames/gml-raptor GitHub Wiki

Similar to the CanvasDrawer, this object draws surfaces, but it does it in a smart way.

You can see a full example of the builder chain for the collage subsystem at Collage Builder Example.

What is a Collage?

The base for this object is the MIT licensed Collage Library by tabularElf.
He created a library with a great idea: Build entire texture pages at runtime. It is a good concept, and while we had to change lots of code in the library and fix many bugs, the core idea and the GPU- and render-mechanics of the library are great. At the time of writing this, we used a code base with version number 0.5, more or less a prototype, but it was all that was available, so we adapted it and integrated it into raptor.

In GameMaker, using sprite_add always creates a new texture page for the sprite. So, in a dynamic game, where you maybe load hundred sprites or more, you will have a hundred texture swaps per frame. This is going to kill your performance sooner or later and Collage targets exactly this problem: Put all those together on one texture page, thus removing dozens of texture swaps.

You create a compilation, a series of images, sprites, files, file strips, surfaces, even whole sprite-sheets with several rows and columns and multiple sprites on one sheet and images from the internet and the library will pack them together onto one single texture page (to be more exact: to as many texture pages as you tell it to).

What is the CollageDrawer?

This is the game object that brings your collages to life. It renders any sprite contained in any collage with only three variable definitions:

image
Variable Description
collage_name The name of the collage to use
sprite_name The name of the sprite in the named collage to render

It's as easy as that!

In contrast to the original source code of collage, we removed many double definitions in the library. You work normally with the "green" variables, like image_speed, image_index, fps, image_angle and all those. Also the scaling is simply taken from the green variables, so you can place your drawer either directly in the room and apply the settings or you create it in code, or you just skin it. Yes! As the drawer is a raptor object, it is fully skinnable, respects themes and can even be initialized through the Raptor RichJson Format in a data file. This means, it can be hot-patched through a download from your game server without any restrictions and assumptions (like squared sprites in a file strip).

Raptor's Collage Interface

We removed the public interface from collage and created a builder pattern syntax to interact with the library. This gives you a consistent way to create the content and completely removes the need to care about async events in HTML mode or image downloads from your server. It is all handled internally by raptor, even the async callbacks. You just don't need to care.

You start interacting with collage through the COLLAGE macro, which resolves to a (singleton) CollageManager instance. This is the interface class we created to interact with the library.

It offers these methods:

Collage Management Methods

for_collage

Set the "focus" of the CollageManager to the name of the collage you specify with this function. This does not create the collage for you, as creating requires more information. See the create method below.

You don't need to care about batching anymore. The CollageManager keeps track of all batches and finishes or creates batches for you.

The collage, you activate with this function is now referred to as the selected collage for the following function definitions.

/// @func	for_collage(_name)
/// @desc 	Begin a chain for the collage identified by _name
static for_collage = function(_name) {

create

Creates a new collage instance. This method is "safe" to call. If the selected collage already exists, this function does not destroy or overwrite it, it just returns in this case. So you may run through your builder tree multiple times without creating zombie instances.

/// @func	create(
///			_width = 4096, _height = 4096, 
///			_crop = __COLLAGE_DEFAULT_CROP, 
///			_margin = 0, 
///			_optimize = __COLLAGE_DEFAULT_OPTIMIZE)
/// @desc	Create a new collage with the specified data,
///		ONLY IF IT DOES NOT ALREADY EXIST!
///		To recreate a collage, use .destroy().create()
///		NOTE: This function also starts batching mode.
static create = function(
	_width = 4096, _height = 4096, 
	_crop = __COLLAGE_DEFAULT_CROP, 
	_margin = 0, 
	_optimize = __COLLAGE_DEFAULT_OPTIMIZE) {

destroy
clear

/// @func	destroy()
/// @desc	Destroys the currently selected collage
static destroy = function() {
/// @func	clear()
/// @desc	Remove all images and reset the selected collage
static clear = function() {

get

/// @func	get(_collage_name)
/// @desc	Retrieve the collage instance stored as _collage_name
///		NOTE: This retrieves the collage instance from the original library
static get = function(_collage_name) {

exists

/// @func	exists(_collage_name)
/// @desc	Checks whether a collage with the specified name exists
static exists = function(_collage_name) {

sprite_exists
sprite_sheet_exists

/// @func	sprite_exists(_name)
/// @desc	Check whether a sprite with the given name exists in the collage
static sprite_exists = function(_name) {
/// @func	sprite_sheet_exists(_name) 
/// @desc	Check whether a sprite sheet with the given name exists in the collage
static sprite_sheet_exists = function(_name) {

push_to_vram
remove_from_vram

Pushes to or removes a collage from graphics card's memory.

/// @func	push_to_vram()
/// @desc	Preload all texture pages of the current collage into graphics card memory
static push_to_vram = function() {
/// @func	remove_from_vram()
/// @desc	Free memory on the graphics card by unloading all pages of this collage
static remove_from_vram = function() {

is_waiting_for_async_images

/// @func	is_waiting_for_async_images()
/// @desc	Returns whether any async manager still waiting for images to be loaded
static is_waiting_for_async_images = function() {

Building The Collage

As every builder pattern, you close your command chain by invoking the .build() method.

Note

As the Manager is capable of downloading images from the internet and also works on HTML5, where every image access is asynchronous by definition, the build() method may block until all images arrived from their content source.

build

/// @func	build()
/// @desc	build all the data into texture pages
static build = function() {

Batch Methods

While we expose access to collage's batch methods, we recommend, that you let the CollageManager do the hard work and manage batching for you. The raptor version of the library is designed to provide you a transparent way to "just add your images to the collage" without having to think too deep about the details. Batch mode is activated and deactivated for you, but you are allowed to override the behavior if needed.

start_batch
clear_batch
finish_batch

/// @func	start_batch()
/// @desc	Begin a batch on the selected collage
static start_batch = function() {
/// @func	clear_batch()
/// @desc	Clear the current batch on the selected collage
static clear_batch = function() {
/// @func	finish_batch(_crop = true)
/// @desc	Finish the current batch for the selected collage,
///		optionally crop any unused space around the textures (default: true)
static finish_batch = function(_crop = true) {

is_in_batch_mode

/// @func	is_in_batch_mode() 
static is_in_batch_mode = function() {

Content Management Methods

add_spritesheet

Calling this function creates a new builder pattern to set up your sprite sheet. The pattern ends by adding .build() to the chain.
For details about sprite sheets see CollageSpriteSheet.

/// @func	add_spritesheet(_name, _filename)
/// @desc	Add a new SpriteSheet to the collage
static add_spritesheet = function(_name, _filename) {

add_sprite

/// @func	add_sprite(_name, _index, _separate_texture = false)
/// @desc	Add an existing sprite to the collage
///		The _index parameter must be a valid sprite_index known to the game, not a filename!
static add_sprite = function(_name, _index, _separate_texture = false) {

add_file

/// @func	add_file(
///			_name, _filename, 
///			_xorigin = 0, _yorigin = 0, 
///			_remove_back = false, 
///			_smooth = false, _separate_texture = false)
/// @desc	Add a new single frame sprite from an external image file to the collage 
static add_file = function(

add_file_strip

/// @func	add_file_strip(
///			_name, _filename, 
///			_frame_count = 1, _fps = 0, 
///			_xorigin = 0, _yorigin = 0, 
///			_remove_back = false, 
///			_smooth = false, _separate_texture = false)
/// @desc	Add a new sprite to the collage from a filestrip image file
static add_file_strip = function(_name, _filename, _frame_count = 1, _fps = 0,

add_surface

/// @func	add_surface(
///			_name, _filename, 
///			_xorigin = 0, _yorigin = 0, 
///			_remove_back = false, 
///			_smooth = false, _separate_texture = false)
/// @desc	Add a new single frame sprite to the collage from a surface
static add_surface = function(

add_surface_part

/// @func	add_surface_part(
///			_name, _surface, 
///			_x, _y, _w, _h, 
///			_xorigin = 0, _yorigin = 0, 
///			_remove_back = false, 
///			_smooth = false, _separate_texture = false)
/// @desc	Add a new single frame sprite to the collage from a part of a surface
static add_surface_part = function(

add_surface_strip

/// @func	add_surface_strip(
///			_name, _surface, 
///			_frame_count = 1, _fps = 0, 
///			_xorigin = 0, _yorigin = 0, 
///			_remove_back = false, 
///			_smooth = false, _separate_texture = false)
/// @desc	Add a new single frame sprite to the collage from a surface
static add_surface_strip = function(

Texture Information Methods

get_texture_page

/// @func	get_texture_page(_index)
/// @desc	Return the texture page at the given index from the current collage
static get_texture_page = function(_index) {

get_texture

/// @func	get_texture(_index)
/// @desc	Return the texture (surface) of the page at the given index
static get_texture = function(_index) {

get_page_count

/// @func	get_page_count()
/// @desc	Return the number of texture pages in the current collage
static get_page_count = function() {

get_image_array

/// @func	get_image_array(_sorted = false)
/// @desc	Return an array of all image objects in the collage; optionally sorted
static get_image_array = function(_sorted = false) {

get_sprite_names

/// @func	get_sprite_names()
/// @desc	Return an array of all sprite names in the collage
static get_sprite_names = function() {

get_sprite_sheet_names

/// @func	get_sprite_sheet_names()
/// @desc	Return the names of all sprite sheets known to the manager
static get_sprite_sheet_names = function() {

get_sprite

/// @func	get_sprite(_sprite_name)
/// @desc	Retrieve the sprite with the specified name
///		or undefined, if not found
static get_sprite = function(_sprite_name) {
	return vsget(__sprites, _sprite_name);
}

get_sprite_sheet

/// @func	get_sprite_sheet(_spritesheet_name)
/// @desc	Retrieve the sprite with the specified name
///		or undefined, if not found
static get_sprite_sheet = function(_spritesheet_name) {
	return vsget(__spritesheets, _spritesheet_name);
}
⚠️ **GitHub.com Fallback** ⚠️