Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
[2016.10] Sprite:setBlendMode(src, dst) - Gideros Forum

[2016.10] Sprite:setBlendMode(src, dst)

n1cken1cke Maintainer
edited November 2016 in Announcements
In Gideros 2016.10 `setBlendMode` has extended version with 2 parameters (blend functions): `src` and `dst`. They define how top sprite colors (`src`) will be blended with bottom sprite colors (`dst`). If you are familiar with image editors like Gimp or Photoshop you know they have many ready blend modes to mix layers in various ways for great effects. Those blend modes are just combinations of aforementioned blend functions so we have added direct support of those functions to Gideros.
There are 11 of them: Sprite.ZERO, Sprite.ONE, Sprite.SRC_COLOR, Sprite.ONE_MINUS_SRC_COLOR, Sprite.DST_COLOR, Sprite.ONE_MINUS_DST_COLOR, Sprite.SRC_ALPHA, Sprite.ONE_MINUS_SRC_ALPHA, Sprite.DST_ALPHA, Sprite.ONE_MINUS_DST_ALPHA, Sprite.SRC_ALPHA_SATURATE. This constants are represented in Lua as integers from 1 to 11. Therefore in Gideros we have 11 * 11 = 121 way to mix colors :)
To test extended `setBlendMode` you can use following snippet:
local topTex = Texture.new("top.png",true)
local btmTex = Texture.new("btm.png",true)
 
lh @ 10 -- label height
 
local w = (application:getDeviceWidth() - lh) / 11
local h = (application:getDeviceHeight() - lh) / 11
local s = math.min(w, h)
 
for x = 1, 11 do
	for y = 1, 11 do
		local top = Pixel.new(topTex, s, s)
		local btm = Pixel.new(btmTex, s, s)
		stage:addChild(btm)
		btm:addChild(top)
		btm:setBlendMode(x, y)
		btm:setPosition(lh + s * (x-1), lh + s * (y-1))
	end
end
 
local t = {}
for k,v in pairs(Sprite) do
	if tonumber(v) == v then t[v] = k end
end
 
for n = 1, 11 do
	local label = TextField.new(nil, t[n], "|")
	label:setX(lh + (n-1) * s + 2)
	label:setY(1)
	label:setClip(0, 0, s - 2, lh)
	stage:addChild(label)
	local line = Pixel.new(0x666666, 1, 1, lh + 11*s)
	line:setX(lh + n * s)
	stage:addChild(line)
end
 
for n = 1, 11 do
	local label = TextField.new(nil, t[n], "|")
	label:setY(lh + (n-0) * s - 2)
	label:setX(1)
	label:setRotation(-90)
	label:setClip(0, 0, s - 2, lh)
	stage:addChild(label)
	local line = Pixel.new(0x666666, 1, lh + 11*s, 1)
	line:setY(lh + n * s)
	stage:addChild(line)
end
Source images and screenshot are attached below but I suggest you to also experiment with other images to better understand how blend functions work.
blending.png
765 x 765 - 278K
btm.png
256 x 256 - 23K
top.png
256 x 256 - 2K
+1 -1 (+4 / -0 ) Share on Facebook

Comments

  • AWESOME!
    My Gideros games: www.totebo.com
  • Hi. I'm trying to understand your example. It uses a lot of the newer features of Giderosmobile so it's really cool, but at the same time, slightly confusing for me.

    I can grasp the @ macro, Pixel and setBlendMode. What I don't get is the little bit in the middle.

    for k,v in pairs(Sprite) do
    if tonumber(v) == v then t[v] = k end
    end

    I don't think I've ever seen someone iterate over Sprite before. What exactly are you doing (besides generating the 11-item table)? Can you iterate over other classes/objects? Why does it show the BlendModes when you do this?

    Thanks in advance.

    John
  • n1cken1cke Maintainer
    @Greywine: I am just building reverse table: a table where keys are swapped with values.
    Since I know Sprite contains numeric constants (1 to 11) only for blend functions I can iterate over Sprite class and when value is a number I am adding it to reverse table: that number becomes a key and that Sprite key becomes a value. In the end I have following table:
    t = {
    [1] = "ZERO",
    [2] = "ONE",
    [3] = "SRC_COLOR"
    .....
    }
    And I use that strings as labels on the top and on the left side of the example app.
    In Gideros each Sprite class and subclass is represented as a Lua table. Try to iterate over some class with `for k,v in pairs(some_class) do print(k,v) end` and you will see it's methods, constants, etc. That's why we can easily create new subclasses: we are using usual Lua tables and we can store anything we want in them.
  • Iterating over classes: good stuff!

    I just wasn't sure why the Sprite class returns the blend constants, but once you know, it's definitely an elegant way to display everything.

    Great example and thanks for the explanation.
  • XmanXman Member
    edited November 2016
    isn't the current setBlendMode function the combination of original setBlendMode and setBlendFunc?

    At the beginning, only setBlendFunc is available, setBlendMode is just a simplified function for setBlendFunc most use case.

    If we need more blend modes, it's better to just make the setBlendFunc available for advanced users, and keep the setBlendMode simple .

    atilim discussed the idea here
    http://giderosmobile.com/forum/discussion/406/setblendfunc-help-/p1


  • n1cken1cke Maintainer
    edited November 2016
    @Xman: `setBlendMode` is overloaded method: one argument to set blend modes as before, two arguments to set blend functions.
    Do you mean it's better to create`setBlendFunc` method for this and avoid overloading?
  • XmanXman Member
    edited November 2016
    Exactly!
    setBlendFunc was set to nil after setBlendMode is created.
    It can be made available easily.


  • n1cken1cke Maintainer
    @Xman: see this commit:
    https://github.com/gideros/gideros/commit/0bfc155d7f1cb30598f4c9c4a7c6e71bf9bc2c33
    As you can see I have refactored Gideros blending source to make it much more clean and simple, without the need of extra utils like `bin2c` and lua-files. Also in this particular case overloading makes sense because setBlendMode(src, dst) still means you set blend mode, only composed from 2 blend functions. Compare it for example with overloaded `Sprite:setScale` where you can use both simplified 1-arg and more complex 2-arg versions.
  • XmanXman Member
    edited November 2016
    sprite.lua is not only a "complicated way" for the blending function, we can easily extends the api for Sprite without polluting the C++ code. It should not be deleted.
    The creator of the engine atilim won't do such a lot of work to just add a setBlendMode function instead of make the binder code complicated like this.
  • n1cken1cke Maintainer
    C++ code was not polluted because Lua C API is natural way for Lua to interact with lower level languages like C/C++ :D It is easy to write, it is loaded faster and it doesnt need external convertors to load Lua scripts. And 99% of Gideros source uses Lua C API so it is bin2c-scripts are polluting C++ code, not Lua C API ;)
  • XmanXman Member
    edited November 2016
    You may ask @atilim why some Lua functions are implemented in this way.
    I think @atilim won't make this modification according to the this thread:
    http://giderosmobile.com/forum/discussion/406/setblendfunc-help-/p1
    setBlendMode accept two parameters for blendfunc really NOT make sense.

    I think you can make the setBlendFunc be available in any way as you like, but just leave anything else as it was.
  • n1cken1cke Maintainer
    image
    pic.jpg
    460 x 523 - 20K
    pic.jpg 20.1K
  • Apollo14Apollo14 Member
    edited August 20
    Hi guys!
    I'm trying to understand Blend Modes.
    How to choose blendmode{5,8}? (I've marked it on attached picture)
    I've tried
    local top = Bitmap.new(Texture.new("top.png",true))
    local btm = Bitmap.new(Texture.new("btm.png",true))
    stage:addChild(btm)
    stage:addChild(top)
     
    btm:setBlendMode(5,8)
    It doesn't give expected result.

    Btw, I've iterated through Sprite class, like in @n1cke 's first post:
    for k,v in pairs(Sprite) do
    	if tonumber(v) == v then print(k) end
    end
    I'm getting not 11, but 27 values (new values are STENCIL-related)
    Did these values break blendmode order of numbers?
    STENCIL_GEQUAL
    SRC_ALPHA_SATURATE
    DST_COLOR
    SRC_ALPHA
    STENCIL_EQUAL
    STENCIL_ZERO
    STENCIL_REPLACE
    STENCIL_NOTEQUAL
    STENCIL_LESS
    STENCIL_NEVER
    STENCIL_LEQUAL
    STENCIL_INVERT
    STENCIL_INCR_WRAP
    SRC_COLOR
    STENCIL_INCR
    ONE_MINUS_DST_ALPHA
    STENCIL_DECR_WRAP
    STENCIL_DECR
    ONE_MINUS_SRC_ALPHA
    ONE_MINUS_DST_COLOR
    ONE
    ZERO
    STENCIL_DISABLE
    DST_ALPHA
    ONE_MINUS_SRC_COLOR
    STENCIL_ALWAYS
    STENCIL_KEEP

    image
    what_blend_number.jpg
    765 x 765 - 430K
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
Sign In or Register to comment.