*Exactly* changing the color of a spirte
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
*Exactly* changing the color of a spirte
I have symbols in pure white (255,255,255) I want to display in various colors. I used modulate color mode but that doesn't do what I want. The symbols end up having a color *near* the color I actually set e.g. I set the color (33,40,33) but the symbol is drawn in (36,41,36). And yes I pretty clearly noticed the difference (I am picky about color). Is there a way to do exact color changes in LÖVE?
Re: *Exactly* changing the color of a spirte
You can just use the default color mode to do that, I think
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
- slime
- Solid Snayke
- Posts: 3131
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: *Exactly* changing the color of a spirte
setColor with the modulate (default) color mode should do what you want. If not, it's a bug. How are you determining what the rgb value of the final output color is? Can you upload a .love file and screenshot demonstrating the problem?
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: *Exactly* changing the color of a spirte
I looked up the color modes in the wiki after my problems and the description of "modulate" certainly doesn't sound like straight color replacement.slime wrote:setColor with the modulate (default) color mode should do what you want.
Also now that I thought about it some more, that wouldn't even work in my case. I mean in straight SDL I just write "replace white with set color". I mean the symbols are loaded from a bitmap, pure white (0xffffff) symbols on a pure black background (0x000000). If modulate changed all colors of the image to the set color I would only get solid blocks of said color. I actually only want to change everything that's white in my source image to the set color..Images (etc) will be affected by the current color.
'modulate' works like a filter that absorbs colors that differ from the current color (possibly to a point where a color channel is entirely absorbed
Yes, I took a screenshot to confirm my perception of difference and then compared the set color to the color that was actually displayed. The RGB values did not match. As I said, set color was (33,40,33), output color was (36,41,36)How are you determining what the rgb value of the final output color is?
Yes, but I would need to isolate the relevant code from the rest of the program and that would take a while. And as I said I think I actually did the wrong thing to begin with. I guess my brain somehow considered black "not a color" at that momentCan you upload a .love file and screenshot demonstrating the problem?
So before I upload an example I ask, what is the correct way to change a specific color in an image? If that is even possible.
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: *Exactly* changing the color of a spirte
Here is code which demonstrates that "modulate" does indeed not replace colors with the set color but somehow mixes whatever colors are in the image with the set color.
As I said I want to change one color to another. Not mix colors.
Code: Select all
function love.load()
-- Input.png is nothing but a square of (0xcc, 0x00, 0x1f)
Input = love.graphics.newImage("Input.png")
ExpectedOutput = love.graphics.newImage("ExpectedOutput.png")
end
function love.draw()
-- Displays a square with the color (0x29, 0x00, 0x06)
-- NOT (0x33, 0x40, 0x33)
love.graphics.setColorMode("modulate")
love.graphics.setColor({0x33, 0x40, 0x33})
love.graphics.draw(Input, 10, 10)
-- Expection was a square of (0x33, 0x40, 0x33)
love.graphics.setColorMode("replace")
love.graphics.draw(ExpectedOutput, 300, 300)
end
- Attachments
-
- Issue.love
- Demo code
- (1.17 KiB) Downloaded 92 times
- slime
- Solid Snayke
- Posts: 3131
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: *Exactly* changing the color of a spirte
The modulate color mode is not straight color replacement - except when the color of a pixel in an image is 255,255,255. In that case, it goes something like this:
There is no straight color replacement ColorMode in LÖVE, and there probably never will be. I don't think fixed-function OpenGL can even do that without some enormous kludge. There aren't many reasons to do it in the first place if you have access to the original image.
You can use a shader (PixelEffect) to do image color replacement, if you really want. It might look something like this:
Or you could load the image as ImageData and change it in Lua:
Code: Select all
(33, 40, 33) * (255, 255, 255) = ((33*255)/255, (40*255)/255, (33*255)/255) == (33*1, 40*1, 33*1) == (33, 40, 33).
You can use a shader (PixelEffect) to do image color replacement, if you really want. It might look something like this:
Code: Select all
effect = love.graphics.newPixelEffect[[
const vec3 replaceinput = vec3(1.0, 1.0, 1.0);
const vec3 replaceoutput = vec3(33.0/255.0, 40.0/255.0, 33.0/255.0);
vec4 effect(vec4 color, Image texture, vec2 texcoord, vec2 pixcoord)
{
vec4 texcolor = Texel(texture, texcoord);
if (all(equal(texcolor.rgb, replaceinput)))
texcolor.rgb = replaceoutput;
// or less clear but maybe more performant
// texcolor.rgb = mix(texcolor.rgb, replaceoutput, float(all(equal(texcolor.rgb, replaceinput))))
return texcolor;
}
]]
Code: Select all
local replaceinput = {255, 255, 255}
local replaceoutput = {33, 40, 33}
local imagedata = love.image.newImageData(myfile)
local function map(x,y,r,g,b,a)
if r == replaceinput[1] and g == replaceinput[2] and b == replaceinput[3] then
r, g, b = unpack(replaceoutput)
end
return r, g, b, a
end
imagedata:mapPixel(map)
image = love.graphics.newImage(imagedata)
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: *Exactly* changing the color of a spirte
Strange. I changed the color of the Input.png square to 255,255,255 and it did indeed work. However, my symbol bitmap is also 255,255,255 and the output is all wrong. I cannot reproduce this problem in an isolated example. I guess there must be an issue somewhere else..slime wrote:The modulate color mode is not straight color replacement - except when the color of a pixel in an image is 255,255,255.
Okay, thanks for the explanation!There is no straight color replacement ColorMode in LÖVE, and there probably never will be. I don't think fixed-function OpenGL can even do that without some enormous kludge.
I see, thanks again.You can use a shader (PixelEffect) to do image color replacement, if you really want. It might look something like this:Code: Select all
effect = love.graphics.newPixelEffect[[ const vec3 replaceinput = vec3(1.0, 1.0, 1.0); const vec3 replaceoutput = vec3(33.0/255.0, 40.0/255.0, 33.0/255.0); vec4 effect(vec4 color, Image texture, vec2 texcoord, vec2 pixcoord) { vec4 texcolor = Texel(texture, texcoord); if (all(equal(texcolor.rgb, replaceinput))) texcolor.rgb = replaceoutput; // or less clear but maybe more performant // texcolor.rgb = mix(texcolor.rgb, replaceoutput, float(all(equal(texcolor.rgb, replaceinput)))) return texcolor; } ]]
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: *Exactly* changing the color of a spirte
Found it. Had nothing to do with LÖVE. One of the numbers in my code was off by 1, that caused all the problems.Hexenhammer wrote: Strange. I changed the color of the Input.png square to 255,255,255 and it did indeed work. However, my symbol bitmap is also 255,255,255 and the output is all wrong. I cannot reproduce this problem in an isolated example. I guess there must be an issue somewhere else..
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: *Exactly* changing the color of a spirte
In my humble opinion, you should give your image font an appropriate alpha layer (ie., alpha -> from brightness), fill the image with white (unless you want outlines or something), and use normal alpha blending mode. Using modulate blend mode just to get rid of a black background is not how to do it. To use alpha, you'll need to make your image a .png.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: *Exactly* changing the color of a spirte
You misunderstood what I want to do here. I don't want to get rid of the black background, the symbols are drawn on black, I just want to draw them in various colors. And my original method actually worked fine, as I said just one of the numbers was off by 1 which caused the selection of the wrong color.Taehl wrote:In my humble opinion, you should give your image font an appropriate alpha layer (ie., alpha -> from brightness), fill the image with white (unless you want outlines or something), and use normal alpha blending mode. Using modulate blend mode just to get rid of a black background is not how to do it. To use alpha, you'll need to make your image a .png.
What I am doing here is emulating a glorified textmode for a roguelike which allows me to use custom colors and symbols. The end result looks like this:
I do this by first creating a "symbol atlas" containing all symbols in all colors and then I quad from there into a sprite batch which eventually gets draw. This is nicely efficient. I get about 1000 FPS drawing >8000 differently colored symbols.
Who is online
Users browsing this forum: Bing [Bot] and 2 guests