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


Log in to reply