Pixmap saturating/hue

BlitzMax Forums/BlitzMax Programming/Pixmap saturating/hue

plash(Posted 2008) [#1]
Is there a way to recolor or saturate a specific color/color-range (and possibly the whole pixmap) in a pixmap, without having to parse all the pixels?
Can we do it using standard max2d calls (or more specifically, OpenGL)?

I can think of one way to do it, make a pixmap with the areas you want to saturate/hue in the mask color and draw a pre-colorized mask image under the pixmap, so that the color of the mask image shows through to the other side.


plash(Posted 2008) [#2]
Also, I cannot find a code example using the accumulation buffer, anyone care to share?


ImaginaryHuman(Posted 2008) [#3]
Accumulation buffer should be easy to use, you just ask for it when you call GLGraphics or set it in the driver default, and then call glAccum() to accumulate and some other command to copy it back to the backbuffer. There might be some other command to set up the scale factor and operation.

The saturation thing, you can't really do saturation or hue changes using RGB data, you have to convert the color space. You can use SetColor to add a tint, and use a blend mode, but real saturation/hue is going to need you to either modify the colorspace back and forth in the pixmap or write a shader.


plash(Posted 2008) [#4]
and some other command to copy it back to the backbuffer
Sounds like a useful command.

The saturation thing, you can't really do saturation or hue changes using RGB data, you have to convert the color space.
Can we draw a texture and tell gl to replace a certain color? Is that something a shader could do?

Shaders are a newer thing right? Will they work in the current max wrapper for OpenGL? (v1.1?)
Do shaders require a newer graphics card?


P.S. To anyone about to post "go Google it," I have been, and even if I can find something it's specifically for 3D or has a bunch of other stuff going on, making it very hard to find what I'm looking for (referring to code.) I find it better to ask here.. just hardly any responses :(


ImaginaryHuman(Posted 2008) [#5]
Yes shaders can do more or less anything. You need GL extensions to use them, and it must be supported by the gfx card.

It isn't easy to replace a color without something like that.


plash(Posted 2008) [#6]
What about grayscaling a whole scene (whole window)?

I already know one answer will be "shaders," but is it something that could be quickly done with the accumulation buffer?


ImaginaryHuman(Posted 2008) [#7]
I recommend looking at and reading at least some of the OpenGL Red Book, which is available for free online as html pages in various places. It will help you to understand how OpenGL is working and what it is able to do, or at least the basics of it.

The accumulation buffer is only really intended for one purpose - to `accumulate` the contents of the backbuffer over several frames. All you can really do with it is either copy the backbuffer to the accumulation buffer, or add the backbuffer to the accumulation buffer with a scale factor. So if you wanted to add up the values of 10 backbuffers you'd add their contents to the accumulation buffer by multiplying their values by 0.1 - then once it's all added together you can copy it back to the backbuffer and you'll see motion blur, for example. You can do some other things like depth of field, jittered antialiasing etc, but you can't really do any of the kind of processing operations that you're talking about. All you can do is add values by the same amount across the board.

There are a few ways to do grayscale - you can get your data into a pixmap and convert the R G and B components to a percentage of 0.333 and then add them together, or add different weighting to each component. You can also use glReadPixels to read the backbuffer into a pixmap - you can read just one of the components if you like, such as the red channel, and then pretend that it's grayscale. Also you can try working with GL_INTENSITY format pixmaps. And maybe use a shader. ;-)

Similarly if you wanna change individual pixel values on a pixel-by-pixel basis you really have to use something that does per-pixel changes, which would be the alpha channel, stencils, blending, texturing, or shaders. Or work with pixmaps and write a software-based image processing function.


xlsior(Posted 2008) [#8]
What about grayscaling a whole scene (whole window)?


Here's one I did, but it does parse all the pixels:
http://www.blitzbasic.com/codearcs/codearcs.php?code=2089

At some point in the past Indiepath posted some code that was supposed to do this in one go (OpenGL?) but while it worked OK on some cards, it never did on others. (His sample code turned the images into shades of green instead of B/W on my video card, among others)


ImaginaryHuman(Posted 2008) [#9]
GL does have an image processing subset which you can activate through higher versions using extensions, I think it can do things like grayscale.