Icon Processor

by Forum_account
An easy way to generate and process icons. [More]
To download this library for your Linux/Mac installation, enter this on your command line:

DreamDownload byond://Forum_account.IconProcessor##version=3

Emulator users, in the BYOND pager go to File | Open Location and enter this URL:

byond://Forum_account.IconProcessor##version=3

5744 downloads
Version 3
Date added: Mar 14 2012
Last updated: Mar 17 2012
9 fans
This library handles the overhead for processing icons. If you want to run a custom operation of every pixel of every icon state in an icon, there are lots of loops and other things you need to write. This library handles all of that.

The library works by providing the IconProcessor datum which contains procs for manipulating icons. It has procs that are automatically called for every icon state and for each pixel - all you have to do is override these procs to define the operation you want to perform. The IconProcessor object also has procs to perform useful operations (interpolation, sampling, etc.).

To change the opacity of an entire icon, here's all you have to do:

Fade
parent_type = /IconProcessor

var
opacity = 0

New(o)
opacity = o

// to apply the fade effect we process each state
// pixel by pixel.
state()
per_pixel()

// output the icon, state name, direction, and frame number
show_progress()

pixel()

// get the color at the current x/y
var/Color/c = get(x, y)

// if the pixel isn't already more than transparent
// than desired, set its alpha value.
if(c.a > opacity)
c.a = opacity

return c

And to run it:

// create an instance of the fade processor that makes the
// icons 20% opaque
var/Fade/fade = new(0.2)

// process the sample icon
var/icon/result = fade.process('icon-processor-demo-icons.dmi')

// save the result as "fade.dmi"
src << ftp(result, "fade.dmi")

Comments

Asielen: (Jul 27 2012, 1:05 pm)
Thanks for the rundown and the link. Perlin noise seems like it can be very useful in creating games.
Forum_account: (Jul 27 2012, 6:19 am)
Perlin noise uses a matrix of random vectors and interpolates between those vectors to generate the noise values. The SIZE var tells it how large that matrix of vectors will be. You shouldn't need to worry about that too much but if you are making a 100x100 map you'd want the SIZE and scale to be set such that the noise values don't repeat.

The interpolation var determines what method is used to interpolate between vectors when generating noise values. It can be set to LINEAR or COSINE.

The scale var is a multiplier applied to all coordinates. If you're making a 32x32 icon and the size of the matrix you're using is 5x5x5. If you use each pixel's coordinates to get noise values the function will repeat (noise(1, 1, 1) is the same as noise(6, 1, 1) because the size is 5). You can set the scale to 0.1 so that calling noise(32, 32, 1) will actually sample the noise function at the coordinates 3.2, 3.2, 0.1.

The levels var determines how many times the noise function is sampled.

This web page has some good pictures to show how it works and what these variables are used for: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
Asielen: (Jul 26 2012, 6:39 pm)
I am interested in your Perlin noise generator. I have it working for map generation, I am just wondering if you could explain the PerlinNoise datum a little more. Specifically what each of the variables and constants modify.

The ones I am curious about are:
var
const
SIZE
LINEAR
COSINE
interpolation
levels
scale
Zaoshi: (Mar 29 2012, 10:17 am)
Forum_account wrote:
You'd have to process everything twice.

You'd have to tell difference between that particular object and other part of the scene to process it second time, therefore this method isn't used at all (I hope). There's simply color value sent to shader that gets added to every pixel when the object is drawn for the first time:
float4 PixelShader(/* ... */) {
float4 FinalColor(0, 0, 0, 0);
// other calculations such as lighting
return FinalColor + FadeColor; // not an actual code
}

That results only in one extra operation per pixel.

To the GPU it's probably less costly to make this an additional operation applied to every pixel than to handle this as a single translucent blue polygon placed over the whole screen
Partially true. Drawing blue transparent polygon would require more operations per pixel, but difference is extremely low, calling Draw() proc alone costs more than those operations, therefore this way would be fine.
Forum_account: (Mar 17 2012, 8:11 am)
I guess that wasn't the best example. It doesn't have to be a full screen tint, it could just be applied to a single object.

To the GPU it's probably less costly to make this an additional operation applied to every pixel than to handle this as a single translucent blue polygon placed over the whole screen. To process that, you'd have to render all geometry then process the translucent overlay. You'd have to process everything twice. GPUs are fast because they do a lot of work in parallel. If this is just an extra operation applied to each pixel, you still get the full benefit of parallelization.