Transparency / Color problems with GeClipMap

On 30/07/2013 at 10:22, xxxxxxxx wrote:

Hi,

I have got some transparency problems with a GeClipMap. I am drawing some stuff into a 
GeClipMap, generally it is just a rect layered with a text and icon decorator. The GeClipMap is 
then drawn into the viewport by an ObjectData plugin. However if the underlying rect is not 
fully desaturated, the icon bitmap is hue shifted by  the bg hue. I have tried both relevant 
GeClipMap drawing modes GE_CM_DRAWMODE_BLEND and the STATIC_SOMETHING one.

correct on greyish bg:

shifted with red bg:

Pretty messy code chunk :

http://codepad.org/eDvC6mn5

def drawText(bd, colors, node, content, position, data, unit, offset) :
    """
    Draws a string to the given world space position. Returns the new offset.
    :param bd         : The BaseDraw to draw in.
    :param colors     : The fhVectorNullDrawColorStruct to draw with.
    :param txt        : The string to draw.
    :param position   : The anchor point in gloaal space.
    :param offset     : (opt) Offset the y drawing pos by offset
    :return           : int
    """
    font = data[c4d.PRIM_VECTORNULL_TEXT_FONT]
    alpha = min(230, 255 - int(data[c4d.PRIM_VECTORNULL_OPTIONS_TEXTTRANS] * 255))
    # get font bc
    if not isinstance(font, c4d.FontData) :
        fontbc = c4d.GetWorldContainer()[c4d.WPREF_FONT_STANDARD]
        fontsize = 12
    else:
        fontbc = font.GetFont()
        fontsize = fontbc[501]
    # get icon
    icon, icnw, icnh = None, 0, 0
    if data[c4d.PRIM_VECTORNULL_TEXT_ICON] != c4d.PRIM_VECTORNULL_TEXT_ICON_NONE:
        icon = bitmaps.InitResourceBitmap(node.GetType())
        icnw, icnh = icon.GetBw(), icon.GetBh()
        smode = data[c4d.PRIM_VECTORNULL_TEXT_ICON]
        if smode == c4d.PRIM_VECTORNULL_TEXT_ICON_SMALL:
            icnw, icnh = min(16, icnw), min(16, icnh)
        elif smode == c4d.PRIM_VECTORNULL_TEXT_ICON_MIDDLE:
            icnw, icnh = min(24, icnw), min(24, icnh)
        else:
            icnw, icnh = min(32, icnw), min(32, icnh)
        # scale icon
        if icnw != icon.GetBw() or icnh != icon.GetBh() :
            dest = bitmaps.BaseBitmap()
            dest.Init(icnw, icnh)
            icon.ScaleIt(dest, 256, True, True)
            icon = dest
    # build text struct
    txtdata = buildText(content, data, colors, unit)
    rawtext = ''
    for txt, color in txtdata:
        rawtext += txt
    # build bitmap
    geclip = bitmaps.GeClipMap()
    # calc font size
    geclip.Init(0, 0)
    geclip.BeginDraw()
    geclip.SetFont(fontbc, fontsize)
    if icon:
        gcw = geclip.TextWidth(rawtext) + icnw + 12
        gch = max ( icnh + 2, geclip.TextHeight() + 2)
    else:
        gcw = geclip.TextWidth(rawtext) + icnw + 4
        gch = geclip.TextHeight() + 2
    txth = geclip.TextHeight()
    geclip.EndDraw()
    # re-init
    geclip.Init(gcw, gch)
    geclip.BeginDraw()
    geclip.SetDrawMode(c4d.GE_CM_DRAWMODE_BLEND, 255)
    # draw bg
    geclip.SetFont(fontbc, fontsize)
    r = int(colors.GetBase().x * 255)
    g = int(colors.GetBase().y * 255)
    b = int(colors.GetBase().z * 255)
    geclip.SetColor(r, g, b, alpha)
    geclip.FillRect(0, 0, gcw, gch)
    geclip.SetColor(r, g, b, utils.Clamp(50, 255, int(alpha * 2)))
    geclip.Rect(0, 0, gcw - 1, gch - 1)
    # draw icon
    if icon is not None:
        for x in xrange(icnw) :
            for y in xrange(icnh) :
                col = icon.GetPixel(x, y)
                geclip.SetColor(col[0], col[1], col[2], 255)
                geclip.SetPixel(x+1, y+1)
        geclip.SetColor(0, 0, 0, 75)
        geclip.Rect(1, 1, icnw , icnh)
    # draw text
    if icon is not None:
        xoff = 7 + icnw
        yoff = 1 + int((gch - txth) * 0.5)
    else:
        xoff = 1
        yoff = 1
    for string, color in txtdata:
        r = int(color.x * 255)
        g = int(color.y * 255)
        b = int(color.z * 255)
        geclip.SetColor(r, g, b, 255)
        geclip.TextAt(xoff, yoff, string)
        xoff = xoff + geclip.TextWidth(string)
    geclip.EndDraw()
    # draw bitmap
    bmp = geclip.GetBitmap()
    p0 = bd.WS(position) - c4d.Vector(gcw * 0.5, 0, 0)
    offset += 4
    padr4 = [c4d.Vector(p0.x, p0.y + offset, 0),
             c4d.Vector(p0.x + gcw, p0.y + offset, 0),
             c4d.Vector(p0.x + gcw, p0.y + gch + offset, 0),
             c4d.Vector(p0.x, p0.y + gch + offset, 0)]
    cadr = [colors.GetBase()] * 4
    vnadr = [c4d.Vector(0, 0, 1)] * 4
    uvadr = [c4d.Vector(0, 0, 0),
             c4d.Vector(1, 0, 0),
             c4d.Vector(1, 1, 0),
             c4d.Vector(0, 1, 0)]
    bd.DrawTexture(bmp, padr4, cadr, vnadr, uvadr, 4,
                   c4d.DRAW_ALPHA_FROM_IMAGE, c4d.DRAW_TEXTUREFLAGS_INTERPOLATION_NEAREST)
    geclip.Destroy()
    return offset + gch

Is this a bug of the GeClipMap or am I overlooking something / doing something wrong ?

Thanks for your help and Happy Rendering,
Ferdinand