News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Glass and blend efect

Started by caraveiro, November 18, 2011, 10:59:45 PM

Previous topic - Next topic

caraveiro

I'm just learning GDI+ and I found this reference manual:

http://www.autohotkey.com/forum/topic70935.html


Now, I want to apply some glass effect into a bmp image (see attached image from oxygen4.6.2 free iconset):

I think I need this:

1. Make a copy of the original image.
2. Make a mask of the glass effect.
3. A way to increase the white level of the copied image.
4. A way to make some gradient of the white level image.
5. blend or mix both images using the mask.

Before reinvent the wheel....  does anybody has done this before?


After this I want to make  a crystal reflex affect, just like itunes does. any idea?

best regards.


By the way: here is  my -blind- code to load a memory file image using the Gdi+, I just take some pieces from this forum.
I dunno if everything is "legal" with GDI+ methods.... I will read the methods next week. Any way... you're welcome to flame my code!

The pMemoryFile parameter is a (Invoke GlobalAlloc,GPTR,eax) object with a copy of the bmp/jpg/pgn/etc file.
The dFileSize is a ancient reptilium dna code


align 4
Dib32FromGDIPlusMemory          proc pMemoryFile:DWORD,dFileSize:DWORD
                                ;
                                LOCAL dLastError:DWORD
                                LOCAL hBuffer:DWORD
                                LOCAL pBuffer:DWORD
                                LOCAL pStream:DWORD
                                LOCAL dToken:DWORD
                                LOCAL oBmp:DWORD
                                LOCAL hBmp:DWORD
                                LOCAL GdipSI:GdiplusStartupInput
                                ;
        ;
        xor eax,eax
        mov dLastError,eax
            ;
        xor eax,eax
        mov GdipSI.GdiplusVersion,1
        mov GdipSI.DebugEventCallback,eax
        mov GdipSI.SuppressBackgroundThread,eax
        mov GdipSI.SuppressExternalCodecs,eax
        mov hBmp,eax
        Invoke GdiplusStartup,addr dToken,addr GdipSI,0                 ;Init the GDI+ Engine. ;token:DWORD, inputbuf:GdiplusStartupInput, Optional outputbuf:DWORD = 0
        .if eax!=S_OK
            xor eax,eax           
        .else
            Invoke CreateStreamOnHGlobal,pMemoryFile,FALSE,addr pStream ;Create a Stream from the hBuffer
            .if eax==S_OK
                Invoke GdipCreateBitmapFromStream,pStream,addr oBmp     ;Create a Bmp Object
                Invoke GdipCreateHBITMAPFromBitmap,oBmp,addr hBmp,0     ;Create a regular hBmp from oBmp ; bitmap:DWORD, hbmReturn:DWORD, background:DWORD
                Invoke GdipDisposeImage,oBmp                            ;Delete the oBmp Object ;image:DWORD
                mov eax,pStream
                push eax
                mov eax,dword ptr [eax]
                call [eax].IStream.IUnknown.Release                     ;Delete the Stream
            .endif
            ;Invoke GdiplusShutdown,addr dToken                         ;Kill the GDI+ Engine ;addr dToken: returns S_OK
            ;Invoke GdiplusShutdown,NULL                                ;Kill the GDI+ Engine ;NULL:        returns S_OK
            Invoke GdiplusShutdown,dToken                              ;Kill the GDI+ Engine ;dToken       returns S_OK           
            ;Invoke GdiplusShutdown,addr szTexts                        ;Kill the GDI+ Engine ;addr szTexts returns S_OK           
            ;.if eax==S_OK
            ;    Invoke MessageBox,NULL,addr szTexts,NULL,NULL
            ;.endif
            ;
            .if hBmp==0                                                 ;Oops! the pMemoryFile has an invalid or bad format
                Invoke SetLastError,ERROR_NOT_SUPPORTED
                xor eax,eax
            .else
                mov eax,hBmp                 
            .endif
        .endif                           
        ;
        Exit_Dib32FromGDIPlusFile:
        ;
    ret
Dib32FromGDIPlusMemory          endp

Best regards
"knowledge is now free at last, everything should be free from now on, enjoy knowledge and life and work for everybody else"
+ORC
http://www.fravia.com

qWord

Your example look like made with an Image editor (Photoshop,...). You will get similarly results by drawing parts of a huge, white circle with an opacity of ~15% (alpaha=0.15) over the button-image. Using a radial gradint brush for the circle would be fine tuning :8)

BTW: the GDIp-initialization should be done at process begin and not if the functions are needed (overheap)
FPU in a trice: SmplMath
It's that simple!

caraveiro

Quote from: qWord on November 19, 2011, 01:53:53 AM

BTW: the GDIp-initialization should be done at process begin and not if the functions are needed (overheap)

Nice tip!

What about this:

            ;Invoke GdiplusShutdown,addr dToken                         ;Kill the GDI+ Engine ;addr dToken: returns S_OK
            ;Invoke GdiplusShutdown,NULL                                ;Kill the GDI+ Engine ;NULL:        returns S_OK
            Invoke GdiplusShutdown,dToken                              ;Kill the GDI+ Engine ;dToken       returns S_OK           
            ;Invoke GdiplusShutdown,addr szTexts                        ;Kill the GDI+ Engine ;addr szTexts returns S_OK     


Why, no matter how the GdiplusShutdown is called, always returns  S_OK ?

I'll swim deep in the GDI+ api to guess about it!

Thank you!
"knowledge is now free at last, everything should be free from now on, enjoy knowledge and life and work for everybody else"
+ORC
http://www.fravia.com

qWord

The flow for a 'normal' window application:

...
Invoke GdiplusStartup,addr dToken,addr GdipSI,0
...
<window creation>
...
<message loop>
...
invoke GdiplusShutdown,dToken
invoke ExitProcess,0
FPU in a trice: SmplMath
It's that simple!

Farabi

For creating alpha effect, you have to add each channel from 2 pixel from 2 image and then average it. Or, you can set Pic A each channel for10% and Pic B each channel 90% and then add it. That simple. But, if you used GPU, it is automatically, and for 800x600 pixel it only took 1% each 30 picture.

And for glass effect you have to bias it. For example, pixel from POINT(100,100) substrac the Y by 10 for every pixel on the region.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Farabi

Here is the code, NigthWare Optimized it
nwBlendPixel proc pixel:dword,pixel2:dword,percent:dword

; NightWare algo from www.masm32.com

mov eax,percent ; 0 to 100
mov edx,0FFh
mul edx
mov edx,42949673
mul edx ; become 0 to 255 in edx

shl edx,24 ; A,_,_,_

mov eax,pixel ; _,R,G,B read pixel
or eax,edx ; A,R,G,B add alpha
mov edx,pixel2 ; _,R,G,B read pixel2

pxor MM7,MM7 ; MM7 = 0,0,0,0 , 0,0,0,0
movq MM6,QWORD PTR Sprite_Simd_Mask_RVB_unpck_1 ; MM6 = 0,0,0,1 , 0,1,0,1
movd MM1,eax ; MM1 = _,_,_,_ , A,R,G,B (pixel)
movd MM0,edx ; MM0 = _,_,_,_ , A,R,G,B (pixel2)
punpcklbw MM1,MM7 ; MM1 = 0,A,0,R , 0,G,0,B
punpcklbw MM0,MM7 ; MM0 = 0,A,0,R , 0,G,0,B
movq MM2,MM1 ; MM2 = 0,A,0,R , 0,G,0,B
pshufw MM2,MM2,0FFh ; MM2 = 0,A,0,A , 0,A,0,A
movq MM3,QWORD PTR Sprite_Simd_Mask_RVB_unpck_255 ; MM3 = 0,0,0,255 , 0,255,0,255
psubw MM3,MM2 ; MM3 = 0,~A,0,~A , 0,~A,0,~A
paddw MM2,MM6 ; MM2 = 0,A+1,0,A+1 , 0,A+1,0,A+1
paddw MM3,MM6 ; MM3 = 0,~A+1,0,~A+1 , 0,~A+1,0,~A+1
pmullw MM1,MM2 ; MM1 = A*A,R*A , G*A,B*A
pmullw MM0,MM3 ; MM0 = A*0,R*A , G*A,B*A
paddw MM0,MM1 ; MM0 = A*0+A*0,R*A+R*A , G*A+G*A,B*A+B*A
psrlw MM0,8 ; MM0 = 0,A,0,R , 0,G,0,B
packuswb MM0,MM7 ; MM0 = _,_,_,_ , A,R,G,B
movd eax,MM0 ; A,R,G,B new
emms
and eax,000FFFFFFh ; _,R,G,B only keep RGB

ret
nwBlendPixel endp


Try to take 2 pixel from the same coordinate from 2 picture, and the blend it on a new picture. Youll see it.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

caraveiro

Wow, Just played around BlendPixel... that's what I need...

also found usefull this link to make the elaborate gradient:

http://www.flounder.com/gradientfiller.htm

Thank you!

;)

Quote from: Farabi on November 19, 2011, 04:40:28 AM
Here is the code, NigthWare Optimized it
nwBlendPixel proc pixel:dword,pixel2:dword,percent:dword

; NightWare algo from www.masm32.com

mov eax,percent ; 0 to 100
mov edx,0FFh
mul edx
mov edx,42949673
mul edx ; become 0 to 255 in edx

shl edx,24 ; A,_,_,_

mov eax,pixel ; _,R,G,B read pixel
or eax,edx ; A,R,G,B add alpha
mov edx,pixel2 ; _,R,G,B read pixel2

pxor MM7,MM7 ; MM7 = 0,0,0,0 , 0,0,0,0
movq MM6,QWORD PTR Sprite_Simd_Mask_RVB_unpck_1 ; MM6 = 0,0,0,1 , 0,1,0,1
movd MM1,eax ; MM1 = _,_,_,_ , A,R,G,B (pixel)
movd MM0,edx ; MM0 = _,_,_,_ , A,R,G,B (pixel2)
punpcklbw MM1,MM7 ; MM1 = 0,A,0,R , 0,G,0,B
punpcklbw MM0,MM7 ; MM0 = 0,A,0,R , 0,G,0,B
movq MM2,MM1 ; MM2 = 0,A,0,R , 0,G,0,B
pshufw MM2,MM2,0FFh ; MM2 = 0,A,0,A , 0,A,0,A
movq MM3,QWORD PTR Sprite_Simd_Mask_RVB_unpck_255 ; MM3 = 0,0,0,255 , 0,255,0,255
psubw MM3,MM2 ; MM3 = 0,~A,0,~A , 0,~A,0,~A
paddw MM2,MM6 ; MM2 = 0,A+1,0,A+1 , 0,A+1,0,A+1
paddw MM3,MM6 ; MM3 = 0,~A+1,0,~A+1 , 0,~A+1,0,~A+1
pmullw MM1,MM2 ; MM1 = A*A,R*A , G*A,B*A
pmullw MM0,MM3 ; MM0 = A*0,R*A , G*A,B*A
paddw MM0,MM1 ; MM0 = A*0+A*0,R*A+R*A , G*A+G*A,B*A+B*A
psrlw MM0,8 ; MM0 = 0,A,0,R , 0,G,0,B
packuswb MM0,MM7 ; MM0 = _,_,_,_ , A,R,G,B
movd eax,MM0 ; A,R,G,B new
emms
and eax,000FFFFFFh ; _,R,G,B only keep RGB

ret
nwBlendPixel endp


Try to take 2 pixel from the same coordinate from 2 picture, and the blend it on a new picture. Youll see it.
"knowledge is now free at last, everything should be free from now on, enjoy knowledge and life and work for everybody else"
+ORC
http://www.fravia.com

qWord

caraveiro,
do you want to use GDI+ or not?
I'm not sure why Farabi has shown these SSEx code, but it is absolutely not needed when using the GDI+.
FPU in a trice: SmplMath
It's that simple!

qWord

In the attachment an example, which is using linear and path-gradients to get a glass-effect.
Because some calculations are needed, I've used my own macros, which can be downloaded here.

FPU in a trice: SmplMath
It's that simple!

daydreamer

here is an example how you can blend with right textures

Farabi

Quote from: qWord on November 23, 2011, 08:39:59 PM
In the attachment an example, which is using linear and path-gradients to get a glass-effect.
Because some calculations are needed, I've used my own macros, which can be downloaded here.



:eek Thats so complicated. Is that how to use GDI+? I never checked the performance, but is it had any 2D acceleration? Compared to NW code above, is GDI+ faster?
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Farabi

Quote from: caraveiro on November 23, 2011, 06:22:39 PM
Wow, Just played around BlendPixel... that's what I need...

also found usefull this link to make the elaborate gradient:

http://www.flounder.com/gradientfiller.htm

Thank you!

;)

Quote from: Farabi on November 19, 2011, 04:40:28 AM
Here is the code, NigthWare Optimized it
nwBlendPixel proc pixel:dword,pixel2:dword,percent:dword

; NightWare algo from www.masm32.com

mov eax,percent ; 0 to 100
mov edx,0FFh
mul edx
mov edx,42949673
mul edx ; become 0 to 255 in edx

shl edx,24 ; A,_,_,_

mov eax,pixel ; _,R,G,B read pixel
or eax,edx ; A,R,G,B add alpha
mov edx,pixel2 ; _,R,G,B read pixel2

pxor MM7,MM7 ; MM7 = 0,0,0,0 , 0,0,0,0
movq MM6,QWORD PTR Sprite_Simd_Mask_RVB_unpck_1 ; MM6 = 0,0,0,1 , 0,1,0,1
movd MM1,eax ; MM1 = _,_,_,_ , A,R,G,B (pixel)
movd MM0,edx ; MM0 = _,_,_,_ , A,R,G,B (pixel2)
punpcklbw MM1,MM7 ; MM1 = 0,A,0,R , 0,G,0,B
punpcklbw MM0,MM7 ; MM0 = 0,A,0,R , 0,G,0,B
movq MM2,MM1 ; MM2 = 0,A,0,R , 0,G,0,B
pshufw MM2,MM2,0FFh ; MM2 = 0,A,0,A , 0,A,0,A
movq MM3,QWORD PTR Sprite_Simd_Mask_RVB_unpck_255 ; MM3 = 0,0,0,255 , 0,255,0,255
psubw MM3,MM2 ; MM3 = 0,~A,0,~A , 0,~A,0,~A
paddw MM2,MM6 ; MM2 = 0,A+1,0,A+1 , 0,A+1,0,A+1
paddw MM3,MM6 ; MM3 = 0,~A+1,0,~A+1 , 0,~A+1,0,~A+1
pmullw MM1,MM2 ; MM1 = A*A,R*A , G*A,B*A
pmullw MM0,MM3 ; MM0 = A*0,R*A , G*A,B*A
paddw MM0,MM1 ; MM0 = A*0+A*0,R*A+R*A , G*A+G*A,B*A+B*A
psrlw MM0,8 ; MM0 = 0,A,0,R , 0,G,0,B
packuswb MM0,MM7 ; MM0 = _,_,_,_ , A,R,G,B
movd eax,MM0 ; A,R,G,B new
emms
and eax,000FFFFFFh ; _,R,G,B only keep RGB

ret
nwBlendPixel endp


Try to take 2 pixel from the same coordinate from 2 picture, and the blend it on a new picture. Youll see it.

:lol What was that website talking about? They used 3D notation for 2D function or it is just because I did not read it completely yet? That was funny. I was the firs person in here who said shading as gradient, because it was a gradual color changing, but not that stupid. Or maybe it was really me 6 years ago, you know how stupid I was before right?  :lol
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Farabi

Now I understood what the website  talking about, he refer to a TRIVERTEX coloring on 3D using his tools, That is not obscure, if you know about the UV mapping and a fTRI function I invented youll see that, this tools is usefull for coloring your vertex.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

qWord

Quote from: Farabi on November 24, 2011, 10:59:37 AM:eek Thats so complicated. Is that how to use GDI+? I never checked the performance, but is it had any 2D acceleration? Compared to NW code above, is GDI+ faster?
If available, Hardware acceleration is used! Generally it is simple to create gradients with GDI+, but it may be complicated to dimension them meaningfull (the same applies to OpenGL and DirectX).
Also, you can not compare NW's routine with code, which is dynamically creating and blending gradients. I can't see the relationship between NW's code and caraveiro's question, because he claims to use GDI+.
FPU in a trice: SmplMath
It's that simple!

caraveiro

Quote from: qWord on November 23, 2011, 06:43:09 PM
caraveiro,
do you want to use GDI+ or not?
I'm not sure why Farabi has shown these SSEx code, but it is absolutely not needed when using the GDI+.

Oh, now, GDI+ is my New Religion!

qWord, thank you very much!

Amen, Brother!...!

:cheekygreen:
"knowledge is now free at last, everything should be free from now on, enjoy knowledge and life and work for everybody else"
+ORC
http://www.fravia.com