dcsimg
Results 1 to 9 of 9

Thread: Replacing gdiAlphaBlend with RC5/Cairo.

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    628

    Replacing gdiAlphaBlend with RC5/Cairo.

    so, what the title says.
    I need a replacement of gdiAlphaBlend, and I mean all the parameters, copy parts of the source to a destination source.
    what I have found with RC5 I can only copy the whole picture and if the picture is bigger then the surface it will squeeze it inside, and its not what i need.

  2. #2
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,079

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    Hi baka, thanks for starting a new post, and for clarifying that you want all the parameters the same as the GDI+ AlphaBlend function.

    I did spend a bit of time on this today, but I'm new to the RC5/Cairo stuff too, so I encountered some issues. First things first: the AlphaBlend API declaration at MSDN is declared as follows:

    Code:
    BOOL AlphaBlend(
      _In_ HDC           hdcDest,
      _In_ int           xoriginDest,
      _In_ int           yoriginDest,
      _In_ int           wDest,
      _In_ int           hDest,
      _In_ HDC           hdcSrc,
      _In_ int           xoriginSrc,
      _In_ int           yoriginSrc,
      _In_ int           wSrc,
      _In_ int           hSrc,
      _In_ BLENDFUNCTION ftn
    );
    I'm assuming you want the output to go to an hDC (hdcDest), but do you require the source to be an hDC? Or can the source be a Cairo surface?

  3. #3
    Fanatic Member
    Join Date
    Sep 2012
    Posts
    1,018

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    Hi baka, maybe the following link is useful to you:
    http://www.vbforums.com/showthread.p...=1#post5243589

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    18,973

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    Gosh, wouldn't documentation be useful?

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,691

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    There will be no "squeeze", when you leave out the optional dx, dy Params in:
    CC.RenderSurfaceContent SourceSrf_or_SrcImageKey, x, y, [dx], [dy]

    I guess, what you really mean is, how to "Cut-Out" an area from a larger Source-Image - and render that
    (as e.g. from a "Sprite-Panel" which contains a lot of Sprites, all sitting at different coordinates (maybe in different sizes as well).

    The following code demonstrates such a "CutOut-Function" which returns such a SubArea as a separate CairoSurface.
    Code:
    Option Explicit
     
    Private CC As cCairoContext, i As Long
    
    Private Sub Form_Load()
      Set CC = Cairo.CreateSurface(800, 600).CreateContext 'create our Main-DrawingContext
      
      Dim SpritePanel As cCairoSurface 'load the SpritePanel from Disk
      Set SpritePanel = Cairo.CreateSurface(0, 0, , "c:\temp\Ico_1to5.png")
      
      'cut-out the Sprites from the Panel and store them separately (each with its own "nice StringKey") in the ImageList
      For i = 0 To 4
        Cairo.ImageList.AddSurface "Ico" & i + 1, CutFrom(SpritePanel, i * 50, 0, 50, 50)
      Next
      
      'rendering-time
      CC.SetSourceColor vbWhite: CC.Paint 'ensure white BackGround
      
        CC.RenderSurfaceContent "Ico2", 10, 10 'render our Sprite #2 (out of 5)
        CC.RenderSurfaceContent "Ico3", 60, 60 'render our Sprite #3 (out of 5)
        
      Set Me.Picture = CC.Surface.Picture 'flip the result to the Form-Picture
    End Sub
     
    Function CutFrom(Src As cCairoSurface, x, y, dx, dy) As cCairoSurface
      Set CutFrom = Cairo.CreateSurface(dx, dy)
          CutFrom.CreateContext.RenderSurfaceContent Src, -x, -y
    End Function
    The Image I was using within the code-snippet above (as the little "SpritePanel"), was that one here:


    HTH

    Olaf

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    628

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    so what I need to do is to create a "surface" for every "cut and paste" I need?
    but Im doing numerous cut and paste every render! its a 2d multi-layer based game and everything is moving and changing.

    this means i need to rethink a bit, maybe use different methods for different animations to lower the need to use the "cut and paste"
    right now im cuttings a lot of pictures and also when they go outside the DC, this so that i dont render if i dont see it (im only rendering the visible area, even if the game area is a lot bigger)

    I think you should add the next time you update RC5 a new function, maybe RenderSurfaceContentEx, where we can select the area that we want to copy, like gdiAlphaBlend. Im sure its possible using Cairo, that would make things easier. Usually we use a "bitmap collection", could be icons or different gui-art, its quite common and to be forced to cut it into a surface before we render its 1 step too much.

    But I will try it out and see if its will work for my needs.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,691

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    Quote Originally Posted by dilettante View Post
    Gosh, wouldn't documentation be useful?
    As so often lately - you talk about things you have no real clue about...

    Cairo has no direct BitBlt-command because it is not needed (there's more powerful alternatives for such things in
    most of the more advanced 2D- and 3D-graphics-APIs, which all use a bit of indirection in their Blitting-approaches).
    And it is not that hard, to find these alternatives (by googling them).

    - e.g. for OpenGL (which also does not have a direct "BitBlt") the way would be over glTexSubImage2D (in a separate step)
    - with Direct2D (also not having a direct BitBlt-command) the solution would also be "indirect" (by using a separate IWICBitmapClipper-instance)

    Same thing with Cairo basically - a little indirection is required.

    But that's not a "documentation-problem" - it's a plain and simple "study the available APIs for the new Graphics-lib"-problem.

    Besides - documentation for cairo is available in abundance:
    - tons of examples here in the forum, which already covered what I've posted above (dreammanor posted a link already)
    - because of the huge Cairo-tutorial that comes with the RC5 (which in that "completeness" doesn't exist - neither for GDI - nor for GDI+)
    - and secondly, because the RC5-Classes wrap the original cairo-flat-API quite directly

    So (with regards to the last point above) you can always look at the documentation or examples on the cairo-website:
    https://cairographics.org/samples/
    An alternative to what I posted as a demo, would be by a combination of the clip-image, imagepattern examples on the above linked site.

    But you will of course not look at that - far from it - nor will you study the cairo-tutorial.
    Uttering misleading, wrong comments about things you know nothing about, is all you do dile (when it comes to the Runtime-Classes of the VB6-successor).

    Olaf

  8. #8
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,691

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    Quote Originally Posted by baka View Post
    so what I need to do is to create a "surface" for every "cut and paste" I need?
    No, you do the "CutOuts" only at "Resource-Loading-Time" (from your larger "Sprite-Panel-PNGs", which you can remove from memory,
    after all "SubImage-Sprites" were transfered into the Cairo.ImageList under "nice describing Keys".

    The rendering is only one line of code (no cutouts needed anymore) - instead you use the StringKey of the SubImage to render directly from the (smaller) Resource.

    So there's two stages (which will also lead to cleaner code)
    1) Resource-Loading of SubImages at Program-Startup (releasing the large Sprite-Panels memory after that)
    2) Rendering-time (direct and fast Blending to any target-Coordinate on your Scene (using the smaller, memorywise better "CPU-cachable" SubSprites per StringKey).

    Quote Originally Posted by baka View Post
    ... its a 2d multi-layer based game and everything is moving and changing.
    When you talk about "Moving and changing", then you only talk about "Target-Coords" for your Sprites
    (and "which Sprite you mean" wouldn't have to be described with "4 Source-Coords" anymore, but with a StringKey instead)

    Quote Originally Posted by baka View Post
    I think you should add the next time you update RC5 a new function, maybe RenderSurfaceContentEx...
    Nope - as I tried to explain - it is not needed at all (and the needed code for the shown CutOut is just 2 lines - so - a function like that wouldn't save much)

    Blending-Ops work faster, when the "contiguous amount of allocated memory" is "near together" (when we talk about Source-Images).

    A BitBlt-Operation which reads the ScanLines (with appropriate Offsets from a larger "Sprite-Table" has to skip memory-addresses -
    so the "cache-locality" is not as good as with those "pre-cutout" smaller Sprites.

    Edit:
    FWIW - below comes an additional alternative to the CutOut-approach (using a CairoPattern, which is a kind of "Description for a Brush")...
    these patterns can act as a "thin meta-description-object" - "wrapped around" the Source-Surface, which still has the original Data -
    though using the Pattern-Wrapping now allows to describe Offsets (or Rotations, whatever) in the Source-Surface.


    But as said, I'd think that the BltTo-function below would be a bit slower than the Pre-CutOuts:

    Code:
    Option Explicit
     
    Private CC As cCairoContext, SpritePanel As cCairoSurface, i As Long
    
    Private Sub Form_Load()
      Set CC = Cairo.CreateSurface(800, 600).CreateContext 'create our Main-DrawingContext
    
      Set SpritePanel = Cairo.CreateSurface(0, 0, , "c:\temp\Ico_1to5.png")
      
      'cut-out the Sprites from the Panel and store them separately (each with its own "nice StringKey") in the ImageList
      For i = 0 To 4
        Cairo.ImageList.AddSurface "Ico" & i + 1, CutFrom(SpritePanel, i * 50, 0, 50, 50)
      Next
      
      'rendering-time
      CC.SetSourceColor vbWhite: CC.Paint 'ensure white BackGround
    
         CC.RenderSurfaceContent "Ico2", 10, 10 'render our Sprite #2 (out of 5)
         CC.RenderSurfaceContent "Ico3", 60, 60 'render our Sprite #3 (out of 5)
         
         BltTo CC, 210, 10, 50, 50, SpritePanel.CreateSurfacePattern, 50, 0
         BltTo CC, 260, 60, 50, 50, SpritePanel.CreateSurfacePattern, 100, 0
    
      Set Me.Picture = CC.Surface.Picture
    End Sub
     
    Sub BltTo(CC As cCairoContext, x, y, dx, dy, SrcPat As cCairoPattern, xSrc, ySrc)
        CC.Rectangle x, y, dx, dy 'define the target-region, using a normal rectangular path-definition
          Set SrcPat.Matrix = SrcPat.Matrix.TranslateCoords(xSrc - x, ySrc - y) 'shift the Pattern
        CC.Fill , SrcPat 'fill the Pattern into the above defined Rectangle-Coords
    End Sub
    
    Function CutFrom(Src As cCairoSurface, x, y, dx, dy) As cCairoSurface
      Set CutFrom = Cairo.CreateSurface(dx, dy)
          CutFrom.CreateContext.RenderSurfaceContent Src, -x, -y
    End Function
    Olaf
    Last edited by Schmidt; Feb 7th, 2018 at 03:22 AM.

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    628

    Re: Replacing gdiAlphaBlend with RC5/Cairo.

    ic, thanks for all the samples and explanations. i will look into it and see what i can figure out and how to convert my code.
    the idea to add a "alphablend" alternative is to make it easier when converting a vb6 gdi code to vb6 rc5 code, im sure im not alone using gdi/+ apis that way.
    to cut it in pieces is not "bad", is just different and means i need to change a bit of code,
    to explain what happens in the game, in "1" area

    background layers: moving clouds + distant objects.
    - a image 900x398 that moves slowly in parallax. (this would be easy to implement)
    - a 899x127 image: horizontal moving + copy + parallax. (the cloud moves horizontally, and a new copy is rendered after it + parallax) in my gdi version i cut the part that disappears or before it enter the DC, this to speed up the rendering time. i could skip the cutting and see if it will maintain performance.)
    - different objects here and there, they have fixed positions + parallax (they are located between clouds) no problems here, i skip the cutting (but in my gdi i do the same, if they go outside the boundaries, i cut out the part that is not visible)
    - and more clouds, total of 7 clouds moving, and 8 different objects (in different size, some small some big)

    middle layer: the "area", 2981x1970 big platform. we can only see 800x600 at a time, we can move around. the background follows you as well, but it using different parallax creating depth.

    Front layer: the "area's" front part, with ropes and other objects that need to be "in front"
    Front layer: Portals, to enter other areas. the portal is animated, the source is image 340x1166 that contains different effects, the portal itself is 7 different pictures

    (theres no NPC/Enemies in this map, otherwise they will be on top of middle layer)

    to show the "routine" Im using, that most other functions calls when ready:

    Code:
    Sub Render(ByVal Index&, ByVal x&, ByVal y&, ByVal sx&, ByVal sy&, ByVal sw&, ByVal sh&, Optional ByVal Fade&)
        If x > 800 Or y > 600 Then Exit Sub
        If x < 0 Then
            sw = sw + x: If sw < 1 Then Exit Sub
            sx = sx - x
            x = 0
        End If
        If y < 0 Then
            sh = sh + y: If sh < 1 Then Exit Sub
            sy = sy - y
            y = 0
        End If
        If x + sw > 800 Then sw = 800 - x: If sw < 1 Then Exit Sub
        If y + sh > 600 Then sh = 600 - y: If sh < 1 Then Exit Sub
    
        GdiAlphaBlend Image(0).hDC, x, y, sw, sh, Image(Index).hDC, sx, sy, sw, sh, Image(Index).Alpha - Fade
    End Sub
    Image(0) is the "empty" surface that later will be used to render to DC. Theres 11 other Images that the game uses all the time,
    after that its dynamic, loading/unloading for each area. when all the rendering are done, we call:

    Code:
    Sub RenderDC()
        If LTextCount > 0 Then DoText
        StretchBlt desthDC, 0, 0, sys.Width, sys.Height, Image(0).hDC, 0, 0, 800, 600, vbSrcCopy
    End Sub
    theres no refresh or cls. theres 3 modes. 0=nothing. the new render will "paste" itself above image(0) and repaint it. 1=backcolor, using Gdi Brush FillRect, 2=a background picture using BitBlt

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width