Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / Color & Tone
- By Wurstinator Date 2010-05-14 13:11
Hi :3
I'd like to request another thing ( :D )
Ruby Game Scripting System has a nice feature of so called "colors" and "tones".
Color = Red, Green, Blue, Alpha
Tone = Red, Green, Blue, Gray
They are applied when the image (Sprite) is drawn
I made some examples:
Image without any effects:
http://img140.imageshack.us/img140/2891/nonep.png
Tone (255, 0, 0, 0):
http://img248.imageshack.us/img248/3278/tonem.png
Color (0, 100, 255, 130):
http://img97.imageshack.us/img97/4575/colormd.png
Tone (255, 0, 0, 0) and Color (0, 100, 255, 130):
http://img413.imageshack.us/img413/6145/both.png
Tone (200, 0, 0, 200):
http://img375.imageshack.us/img375/9825/tone.png
Color (0, 50, 0, 255) (with or without Tone, is the same here):
http://img32.imageshack.us/img32/5354/colorou.png

The algorithm is pretty easy. For each pixel the following is done:
R, G and B of the tone are added to R, G and B of the pixel.
The saturation (HSV) is reduced by the tone's gray value.
The color is "overlayed" ((color.alpha / 255.0) * color.red + (1 - (color.alpha / 255.0)) * pixel.red)

Yes... and that's what I'd like to rebuild in gosu :)
- By mathias Date 2010-05-14 14:28
Find a way on how to do it with pure opengl commands (any maybe even supply a working patch for it) and I will guarantee you julian will implement it. If there is no way with pure opengl, I don't think you have a chance of it getting implemented in gosu (Maybe you can do it with texplay?)
- By erisdiscord Date 2010-05-15 02:52
I like this idea. Does anyone know whether shaders can be applied per-texture? I'm not too well versed in OpenGL beyond the basic drawing primitives. It would be cool to see an API in place for per-draw and fullscreen shaders instead of having a ton of different parameters or calls for operations that could be done using that one shader call.

Of course, I'm also not sure how backwards-compatible Julian wants to be nor how widely available shaders are.
- By jlnr (dev) Date 2010-05-15 03:59
I think you could enable a shader, then do your image.draw, then call "gl{}" which will flush the one rendering operation to the screen (with the shader applied), then disable the shader again. But that effectively disables Z ordering. :(

Putting custom things in the Z queue is on my list of things that would be awesome though.
- By BlueScope Date 2010-05-15 12:18
First of all, the hue feature isn't a RGSS, but a RPG Maker feature. As shown in the pictures provided, it doesn't really create quality results, and while working for simple sprites like the tutorials star sprite, I wouldn't use it for monster sprites like the one you provided. I'm not saying it's a useless feature, however, it's a tool that encourages game makers to create non-quality results (as the feature in RPG Maker proves).

I tried to fight that difficulty a while ago myself though, creating a script that works on a pixel-by-pixel basis, being my Bitmap Remapping script posted on .org - it creates quality results by ensuring control over ever pixel remapped with a specific color, and also encourages the use of palettes throughout the game (which, my fellow game designers, is a very appealing detail to games). In my opinion, it renders a Tone feature obsolete within reason, and it should be fairly easy translateable to to Gosu/Ruby without the need for a source implementation (however, speeding it up would be something useful).

For clarification: I don't say a Tone feature wouldn't be worth implementing.
- By AmIMeYet Date 2010-05-15 14:13
Well, I think that Color and Tone are definitely features of RGSS, seeing as how there are classes for them, and the RPG Maker events actually only have a set of properties, where the interpreter creates Tones and Colors for. At least, that's what I think it was. It's been a while since I worked with RPG Maker, and my EventScripter project specifically (which could be used to create new events at runtime), so my memory is a bit rusty.. My own documentation isn't really helpful either, to be honest, so now I'm not even sure if I'm correct at all. I don't have RMVX installed anymore, so I'm unable to access my EventScripter script, it's notes, and the default scripts. Unfortunate.

The thing about the provided pictures is that they don't quite do justice to the Tones and Colors. They are best used within whole maps, as a way of creating atmosphere. Best of all, it's completely dynamic, so you can smoothly flow from one tone to another.

Your Bitmap Remapping is also a valuable idea, although there of course isn't such a feature like set_pixel in Gosu. Should work great with Texplay though!
- By Wurstinator Date 2010-05-15 16:30
@jlnr: Disabling z is not good :(

@BlueScope: Tone != Hue
And of course, tone, color and hue are all features of RGSS. The RMXP without RGSS would have nothing to do with Ruby.

@ AmIMeYet: I already thought about texplay but as you said it should be smoothly used with maps. A map contains maybe 25 sprites. With 60 FPS and normal RMXP-32x48 images that means 25 * 60 * 32 * 48 = 2304000 pixels each second have to be rendered.
- By BlueScope Date 2010-05-15 23:53
If Tone is an RGSS feature, everything is an RGSS feature... most of the features are controlled via a GUI interface, but have an RGSS background, such as Tone. To me, stuff like the modules (Input, Cache, ...) are RGSS features, as they're mainly accessed with/through RGSS, while stuff like Tone is a non-RGSS-feature, as the scripted side (that naturally has to be there) is merely the background of the feature meant to be used from the event commands or submenus.
As not of that really is of any importance, I suggest to drop the topic, though ^^"

@AmIMeYet: If you're talking about changing the tone/hue for the whole screen, then yes, that makes sense. I was focussed on setting stuff for single sprites because of the provided pictures though ^^" in which case, imo, it doesn't.

@Wurstinator: My script clearly isn't meant to be executed each frame, but stored in a cached image, so no matter if you change a sprite in appearance or not, the performance will be the same after a single process.
- By Wurstinator Date 2010-05-17 16:03
Anyway, even with cache, it would be way to slow the first time.
And also, it would fastly use up all available RAM.
- By BlueScope Date 2010-05-17 17:00
Well, I guess that depends on the sprite dimensions and actual pixels to be remapped... My tests with basic RPG Maker sprites (24x32 or 32x48, if I'm not mistaken) and an average of 100 pixels remapped per update, I had no problems with doing for up to 6 sprites at a time... and I have to mention that wasn't for cached sprites. Therefore, I can clearly imagine getting an insane amount of sprites remapped that way without serious loss of time or processing power (which isn't unusual during loading times anyway) if actually executed while caching and ran from the Gosu source, as in written in C rather than in actual Ruby. However, I'm aware it's a very exhaustive method, so yeah... it was just a side note anyway, not a replacement ^^
- By Wurstinator Date 2010-05-24 17:09
For some sprites it may fit but a full map has about
20 characters (128 * 192) +
400 tiles (32 * 32)
= over 900000 pixels each frame.

So, I need a method written in C.
- By banister Date 2010-05-27 00:19 Edited 2010-05-27 03:59
If you can explain precisely what you mean by this:

"The saturation (HSV) is reduced by the tone's gray value."

and this:

"The color is "overlayed" ((color.alpha / 255.0) * color.red + (1 - (color.alpha / 255.0)) * pixel.red)"

I can implement 'tones' in TP.

Bear in mind I don't know anything about HSV and HSV is not currently supported by TP.

If you could also give API suggestions that would be appreciated :)
- By RunnerPack Date 2010-05-27 06:41
banister wrote:

> If you can explain precisely what you mean by this:
>
> "The saturation (HSV) is reduced by the tone's gray
> value."


Here's what I think is happening (for each pixel):

1. Convert the source pixel's and the tone's RGB colors into HSL (HSV?)
2. Replace the source pixel's hue with the tone's hue.
3. Alpha-blend the tone's saturation onto the source's (using the tone's fourth element as alpha).
4. Convert the HSL back to RGB.

I could be totally wrong, though :P

> and this:
>
> "The color is "overlayed" ((color.alpha / 255.0) *
> color.red + (1 - (color.alpha / 255.0)) *
> pixel.red)"


It's just a standard alpha blending, right? This could be done by making a solid-color image the size of the "source" and blending it on top... it would just use more memory :P

> I can implement 'tones' in TP.
>
> Bear in mind I don't know anything about HSV and
> HSV is not currently supported by TP.


http://en.wikipedia.org/wiki/HSL_and_HSV

> If you could also give API suggestions that would
> be appreciated :)


Doesn't SDL have some HSV/HSL stuff? It's been a while since I've used it... Otherwise, there are nice, fairly efficient color space conversion algorithms all over the place. Probably even some OpenGL (or at least GPU-accelerated) ones, too.

I'm not begging for this one, but it might be interesting (and I /know/ you could implement it ;)
- By jlnr (dev) Date 2010-05-27 07:25

> Doesn't SDL have some HSV/HSL stuff?


I have no experience with the SDL, but Gosu does ;) Color.from_hsv, Color.hue, Color.saturation, Color.value (or .h .s .v? I forgot), even with individual setters. Since the internal representation is still A8R8G8B8, you can get rounding errors if you set and get the hue though.
- By Wurstinator Date 2010-05-29 12:28

> "The saturation (HSV) is reduced by the tone's gray value."


As RunnerPack said it is converted to HSV, saturation is reduced and then back to RGB.
Anyway, this can be done also without conversion:
class Color
  def grayscale(percent = 1.0)
    average = (self.red + self.green + self.blue) / 3
    r = (average - self.red) * percent
    g = (average - self.green) * percent
    b = (average - self.blue) * percent
    return Color.new(self.red + r, self.green + g, self.blue + b, self.alpha)
  end
end

A small code I have written for RGSS. It should be clear how it works :)

> "The color is "overlayed" ((color.alpha / 255.0) * color.red + (1 - (color.alpha / 255.0)) * pixel.red)"


Standard alpha blending :)

> I can implement 'tones' in TP.


That would be nice but as TP changes the Images themselves and does not only modify the draw method of Gosu it might also come to a problem of performance :|
Up Topic Gosu / Gosu Exchange / Color & Tone

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill