gnysek
Member
GM Version: GMS 2.x
Target Platform: Windows and others
Download: http://gmclan.org/uploader/23/particle_texture.yyz
Links: na
Summary:
Draw particle images from texture page as sprites
Tutorial:
Hi. I've noticed recently, that particle shapes are exported together with texture page, on same texture (in GMS 1.4 it was a different one).
So, with little of guessing, I found a way to get texture ids of those particle images There's 14 images in total, and pointer of every is 0x16 (hex, 22 as decimal) further in memory after last one.
However, since this address can be different each time (Windows and GFX drivers allocation), we first need to find address of first sprite, then we need to count number of all sprites to get particle address.
Particles are next image after last one from what I found, and there is total of 14 possible images. They are saved on texture in little different order that pointed in manual, but that's not a big problem - an array with proper position, where index == pt_shape_xxx is enough to solve this problem.
We gonna buffer pointers of all those sprites, so we don't need to calculate them each time.
So first, a script to get texture id of particle (you can pass any part shape variable from pt_shape_pixel ... to ... pt_shape_snow)
particle_get_texture(pt_shape);
Then, we need one helper function, to convert string containing our pointer to real, and vice-versa. I've used script from GMLscripts.com called:
base_convert:
at last, as we cannot use draw_sprite in this case, we need to mimic it a little. I've created script called
draw_texture(x,y,width,height,textureid (will work for sprite_get_texture() too).
So now, we just need to create an object, then write:
and we should get:
All particles looks like this:
---
I've tested this example with 3 sprites in game, one of them with two frames - so it may be, that if there's more than one texture page, it won't work.
Also notice, that pt_shape_pixel and pt_shape_line are wider than the others, so they are drawn stretched to square above.
It's a hacky way, so may not always work. If game crashes, try cleaning cache.
I've already reported suggestion to give a proper way to access particle sprites, and use them in draw_sprite() functions too: https://forum.yoyogames.com/index.php?threads/using-particle-sprite.34688/
Target Platform: Windows and others
Download: http://gmclan.org/uploader/23/particle_texture.yyz
Links: na
Summary:
Draw particle images from texture page as sprites
Tutorial:
Hi. I've noticed recently, that particle shapes are exported together with texture page, on same texture (in GMS 1.4 it was a different one).
So, with little of guessing, I found a way to get texture ids of those particle images There's 14 images in total, and pointer of every is 0x16 (hex, 22 as decimal) further in memory after last one.
However, since this address can be different each time (Windows and GFX drivers allocation), we first need to find address of first sprite, then we need to count number of all sprites to get particle address.
Particles are next image after last one from what I found, and there is total of 14 possible images. They are saved on texture in little different order that pointed in manual, but that's not a big problem - an array with proper position, where index == pt_shape_xxx is enough to solve this problem.
We gonna buffer pointers of all those sprites, so we don't need to calculate them each time.
So first, a script to get texture id of particle (you can pass any part shape variable from pt_shape_pixel ... to ... pt_shape_snow)
particle_get_texture(pt_shape);
Code:
/// @desc returns pointer to particle textures, so they can be used with draw vertex functions
//
/// @param pt_shape_type a particle shape from pt_shape_pixel to pt_shape_snow - see GMS manual for more info
//
/// (c) 2017 Piotr 'gnysek' Gnys
if (!variable_global_exists("__particle_tex_buffer")) {
// ensure particles are on texture pages
var _pt = part_type_create();
part_type_destroy(_pt); // free it asap :)
// first get number of existing sprites
var _frames = 0;
while(sprite_exists(_frames)) {
_frames++;
}
global.__particle_tex_buffer = []; // create array in which we gonna buffer tex pointers
var _pointer_to_first_sprite = real(base_convert(sprite_get_texture(0, 0), 16, 10)); // convert pointer of first sprite to integer number
var _shape_to_tex = [6, 2, 12, 5, 13, 0, 7, 11, 4, 10, 8, 1, 3, 9]; // a helper array with order of particle sprites
for(var i = 0; i < 14; i++) {
global.__particle_tex_buffer[i] = ptr(base_convert(_pointer_to_first_sprite + $16 * (_shape_to_tex[i] + _frames), 10, 16)); // convert pointer to first sprite + 0x16 * number of sprites to pointer again
}
}
return global.__particle_tex_buffer[clamp(argument0, pt_shape_pixel, pt_shape_snow)]; // return bufferred address
Then, we need one helper function, to convert string containing our pointer to real, and vice-versa. I've used script from GMLscripts.com called:
base_convert:
Code:
/// @desc base_convert(number,oldbase,newbase)
//
// Returns a string of digits representing the
// given number converted form one base to another.
// Base36 is the largest base supported.
//
/// @param number integer value to be converted, string
/// @param oldbase base of the given number, integer
/// @param newbase base of the returned value, integer
//
/// GMLscripts.com/license
{
var number, oldbase, newbase, out;
number = string_upper(string(argument0));
oldbase = argument1;
newbase = argument2;
out = "";
var len, tab;
len = string_length(number);
tab = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var i, num;
for (i=0; i<len; i+=1) {
num[i] = string_pos(string_char_at(number, i+1), tab) - 1;
}
do {
var divide, newlen;
divide = 0;
newlen = 0;
for (i=0; i<len; i+=1) {
divide = divide * oldbase + num[i];
if (divide >= newbase) {
num[newlen] = divide div newbase;
newlen += 1;
divide = divide mod newbase;
} else if (newlen > 0) {
num[newlen] = 0;
newlen += 1;
}
}
len = newlen;
out = string_char_at(tab, divide+1) + out;
} until (len == 0);
return out;
}
at last, as we cannot use draw_sprite in this case, we need to mimic it a little. I've created script called
draw_texture(x,y,width,height,textureid (will work for sprite_get_texture() too).
Code:
/// @desc draws texture using two vertexes
//
/// @param x1
/// @param x2
/// @param width
/// @param height
/// @param textureid
//
/// (c) 2017 Piotr 'gnysek' Gnys
var x1 = argument0;
var y1 = argument1;
var x2 = argument0 + argument2;
var y2 = argument1 + argument3;
draw_primitive_begin_texture(pr_trianglelist, argument4);
draw_vertex_texture(x1,y1, 0, 0);
draw_vertex_texture(x2,y1, 1, 0);
draw_vertex_texture(x1,y2, 0, 1);
draw_vertex_texture(x1,y2, 0, 1);
draw_vertex_texture(x2,y2, 1, 1);
draw_vertex_texture(x2,y1, 1, 0);
draw_primitive_end();
So now, we just need to create an object, then write:
Code:
draw_texture(0, 0, 100, 100, particle_get_texture(pt_star));
All particles looks like this:
---
I've tested this example with 3 sprites in game, one of them with two frames - so it may be, that if there's more than one texture page, it won't work.
Also notice, that pt_shape_pixel and pt_shape_line are wider than the others, so they are drawn stretched to square above.
It's a hacky way, so may not always work. If game crashes, try cleaning cache.
I've already reported suggestion to give a proper way to access particle sprites, and use them in draw_sprite() functions too: https://forum.yoyogames.com/index.php?threads/using-particle-sprite.34688/
Last edited: