Legacy GM Is GML fast enough to index a image?

S

Shadowblitz16

Guest
Is GML fast enough to index a image into a array of tiled pixels and then swap the colors out during run time?

I would like to learn how to do this in GMS and make an extension out of it

I was thinking of making a gb style tile based engine extension possibly make money off of it while making a zelda engine
 

obscene

Member
Nope, that's something for a shader. With GML you would have to use draw_get_pixel to read the values, which is terribly slow. If you were trying to do this as a screen effect you'd be talking -900 FPS :p
 
S

Shadowblitz16

Guest
thats dumb.
is there any tutorials on shaders and how they work in gms?
 

TheouAegis

Member
Did the GB have palette swapping? I thought with only 4 colors that everything was defined as-is.

If you can manage the increase in texture swaps, you could render to a surface, save the surface to a buffer, change the color values, convert the buffer back to a surface, then save the surface to a sprite. :p

Or you can GIF palette swap, but every time I try to do that in GMS I come across one issue or another (could just be me, though).


There should be some palette swap shaders with instructions. GMS does have shader tutorials in the Tutorials tab.
 
S

Shadowblitz16

Guest
@TheouAegis
the GB color did

ya I guess I could draw them to a surface however I didn't know you could save surfaces to buffers I always thought that gms deleted them and there was nothing you can do about it.

The GIF thing I have no idea how to do but i guess I don't really know how to use shaders either

I kinda wanted a shader that used a list or array to read from rgb values and indexed the image to a certain number of colors

another thing is that the palette shader isn't the only one I need
here is a small list of what I can think of right now
-color index shader
-color swap shader
-gb zelda wave effect shader (the effect when link warps)
-gb zelda wipe effect shader (the effect when link enters doors)
-gb zelda pixel fade shader (basically makes the images pixel disappear to a point of being completely invisible )

so I guess I could look at the tutorial page on gms's launcher
 

TheouAegis

Member
isn't the pixel fade just when your battery dies? :bash:

I think the fade was done the same way as the NES fades (assuming everyone really did do palette swaps back then). Each color is advanced one step to the fade color. Basically, take your palette you'd set the shader to, then adjust each color manually.
 

dphsw

Member
Is GML fast enough to index a image into a array of tiled pixels and then swap the colors out during run time?
Nope, that's something for a shader. With GML you would have to use draw_get_pixel to read the values, which is terribly slow. If you were trying to do this as a screen effect you'd be talking -900 FPS :p
I don't think you could get an array of pixels using a shader. I think it is possible in HLSL11 for shaders to return data, but I doubt GML supports that ability. If you wanted to work with palettes in a shader, I think I'd send the shader a greyscale sprite, with the amount of lightness indicating what colour to use, and then tell it to look along a second image that contained all the colours - then you could palette-swap by swapping the second image for a different image. But it would still be fiddly and unpleasant to use.

There is another way to get the values for the image. (Unfortunately, it only works in Windows and PS4, according to the manual.) I haven't tried it, but it will always depend on size - if you're just doing a color-swap for a small sprite, I expect this will be fast enough for real time. Draw image to a surface (as small as possible, since the size of the surface will affect the speed of the operation), then use buffer_get_surface to write the data from the surface to the buffer. The size of the buffer should be the surface's width*height*4, and every 4 bytes in the buffer should contain red,blue,green and alpha bytes for the pixel. By reading 4 bytes at a time as a uint32 (the buffer functions are the only GML functions that let you create uint32 values, I think, all GML values are floats by default, so you may need to use a temporary buffer to create any uint32 variables you want to use) you can get the colour of any pixel, and swap it for a different value if you wish. Having done any operations you want to on the color data in the buffer, you can write it back to the surface with buffer_set_surface.

As for your wave effect, wipe effect and pixel fade, those all could be done with shaders, though I expect just using draw_surface_part or set_color would be fast enough. For the wave effect, for example, just draw each 1-pixel high line of the screen separately, moving them back and forth in a wave. It won't be as efficient as a shader, but simpler, and that'll be the way the gameboy did it - and if a gameboy did it without any graphics acceleration then surely a modern PC can too. (Indeed, I did similar effects back on my old 16Mb Pentium-120 back when we had no graphics cards or shaders.)
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
There's a whole bunch of "palette swap" shaders already made, like this one or this one. If you search "gamemaker palette swap shader", there are multiple tutorials, assets, and questions on forums.
 
S

Shadowblitz16

Guest
@TheouAegis no the pixel fade is in this video at 1:50 and yes its used in ooa/oos as well

@dphsw I kinda didn't want to use just grey scale I need it to be limited to 16 color as well.

@YellowAfterlife I kinda wanted to use a array of colors instead of images for my palettes
 
S

Shadowblitz16

Guest
@Tsa05 I think one of these works however I need a way to index my images color first
for example if I had a image with 16 colors in it and had a palette of 3 colors,
when the index shader was applied and the image was drawn it would take the 16 colors and find the ones closest to the 3 colors and set them to it
this would make an image of whatever number of color only be able to be drawn with the colors specified

really having the palette shader and the index shader be combined so that I don't have to draw to a surface and save it since there is no sprite_replace_from_ surface(0 function

@TheouAegis I Just took a look at the tutorial page and there is no shader tutorial
however there is a shader demo.
 
Last edited by a moderator:
Here's a link to the source for the tool I distribute with my retro palette swapper to allow users to edit their own palettes. It will take an image and find all the unique colors present and put it in a data structure, which sounds what you want.

The magic happens in the script: button_add_sprite
 
S

Shadowblitz16

Guest
@Pixelated_Pope
It look like all I need is the button_add_sprite script and the rebuild_palette_sprite correct?
also what is the dirty project flag for?
 
@Shadowblitz16 Unimportant for what you are doing with this code. This is a palette builder application. You can actually build palette sprites for use with my palette swapper using this tool. So if you spend like... an hour building 15 palettes for one sprite, you can save that "project" and reload it later when you want to add a 16th palette. The project dirty flag is set if there are any changes to the project that need to be saved.

I'm not sure what you need with rebuild_palette_sprite, but if you say you need it... you would know better than me.
 
S

Shadowblitz16

Guest
@Pixelated_Pope well I wanted to let users import custom tilesets and have the program auto index it fro them so errors can't occur if people import a tileset with wrong colors
 
S

Shadowblitz16

Guest
@Pixelated_Pope can you explain how to get this working with GMS2? I don't see where Pal_Col and the other variables are defined
when I right click on them it bring up random help pages in GMS1

this is the area of code I'm trying to fix
Code:
                var _grid=ds_list_find_value(Palettes,ii);
                var _row=ds_grid_add_row(_grid);
                _grid[# Pal_Cols.Color,_row]          = _col;
                _grid[# Pal_Cols.Hue,_row]            = color_get_hue(_col);
                _grid[# Pal_Cols.Saturation,_row]     = color_get_saturation(_col);
                _grid[# Pal_Cols.Value,_row]          = color_get_value(_col);
                _grid[# Pal_Cols.New_Color,_row]      = _grid[# Pal_Cols.Color,_row];
                _grid[# Pal_Cols.New_Hue,_row]        = _grid[# Pal_Cols.Hue,_row];
                _grid[# Pal_Cols.New_Saturation,_row] = _grid[# Pal_Cols.Saturation,_row];
                _grid[# Pal_Cols.New_Value,_row]      = _grid[# Pal_Cols.Value,_row];
I looked at the macros in your project and they are not in there.
 
Last edited by a moderator:
Top