On the left is what we have now, and on the right what we are trying to achieve. Currently, the line is in one solid color with transparency.
Should we draw a pattern image as an overlay above or brush image should be already with such pattern?
Could you please advice a direction on where to look and what to try?
Brush image that is used is on the left, and watercolor pattern that possibly could be used is on the right.
The following code is used to draw a line with brush texture using the stencil buffer to avoid textures transparency overlap:
glClear(GL_STENCIL_BUFFER_BIT.gluint)
glEnable(GL_STENCIL_TEST.gluint)
glStencilOp(GL_KEEP.gluint, GL_KEEP.gluint, GL_REPLACE.gluint)
glStencilFunc(GL_NOTEQUAL.gluint, 1, 1)
glStencilMask(1)
glDrawArrays(GL_POINTS.gluint, 0, count.int32)
glDisable(GL_STENCIL_TEST.gluint)
When I use waifu2x model to scale an image with transparent pixels, the transparent black background seems to bleed into the image. Using bicubic interpolation also has this problem.
As specified in this blog, the transparent background can be filled with color as near as context as possible.
It's simple to find borders of such transparent borders. But is there any algorithm to generate such background?
I have a scene with a sphere in the middle and a camera spinning around it. Now I was wondering if it is possible with Three.JS to make a crop of this viewport so that the sphere for example would appear on the left or right.
I'm not looking to moving the camera or looking at a point besides the sphere, since that would distort the perspective, but a clip or crop of the rendering.
Is this possible?
One potential solution is to position a second canvas over your Three.js canvas, then re-draw the three.js scene onto your second canvas by blitting:
overlayCanvas.getContext('2d').drawImage(threeCanvas, 40, 40, 960, 960, 0, 0, 1200, 1200);
You can read more about the parameters to drawImage() in the documentation, but what this does is crop a certain area of the three.js canvas and stretch it over a larger area of your second canvas. It should be much faster than rendering the scene a second time, and it will display at the size you want it (albeit with some stretching).
You can alleviate the stretching by drawing the original (three.js) scene at a larger size than it would normally be displayed such that the area you want to crop into view is the same size as your secondary canvas.
Aero glass causes alot of people problems trying to draw on it. Anything with an alpha value of 255 seems to be treated as transparent with DWM using an additive blur to draw it. I want a part of client area to use Aero glass with the rest of it treated as opaque, so I don't have to deal with the headache of common controls not rendering properly.
MSDN lists a function DwmEnableBlurBehindWindow which lets you mark part of the client area as blurred by DWM. It takes a DWM_BLURBEHIND pointer which which has an HRGN handle to the region of the window. When I use this function, the entire window becomes transparent with an additive blend, but only the region of the window I passed to DwmEnableBlurBehindWindow gets blurred. Is there a way I can keep the rest of the window from becoming transparent?
What I have looks a bit like:
blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blur.hRgnBlur = CreateRectRgn(0, 0, 90, 90);
blur.fEnable = true;
DwmEnableBlurBehindWindow(hwnd, &blur);
RECT rect;
GetClientArea(&rect);
FillRect(hdc, &rect, CreateSolidBrush(0));
From the MSDN Library article:
The alpha values in the window are honored and the rendering atop the blur will use these alpha values. It is the applications responsiblity for ensuring that the alpha values of all pixels in the window are correct. Some GDI operations do not perserve alpha values so care must be taken when presenting child windows as the alpha values they contribute are unpredicitable.
Make that most GDI operations, like FillRect(). The brush you created is drawn with 24-bit colors, the alpha will be 0. Which makes the window transparent. You'll need to switch to, say, GDI+. Text is particularly troublesome. As well as legacy Windows controls, like EDIT and LISTBOX which draw with GDI.
What color must i paint in the client area in order to make glass appear?
i've extended the frame of my form into the client area using:
DwmExtendFrameIntoClientArea(self.Handle, margins);
i cannot find any official documentation from Microsoft on what color and/or alpha the DWM will look for to replace with glass. The documentation on DwmExtendFrameInClientArea doesn't even mention that a custom color is required. There's only hearsay and myth that a special color is even required.
The closest i can find is a topic on MSDN:
Custom Window Frame Using DWM
For the extended frames to be visible, the regions underlying each of the extended frame's sides must have pixel data that has an alpha value of 0.
Update: And a blog post:
Windows Vista for Developers – Part 3 – The Desktop Window Manager
It so happens that the bit pattern for RGB black (0x00000000) is the same as the bit pattern for 100% transparent ARGB so you can actually draw with “black” GDI brush and assuming you’ve instructed the DWM to blur the painted area, the result will be the desired glass effect.
If i take what they say literally (pixel data with an alpha value of zero), i construct a color with zero alpha, and paint that in the extended area:
Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);
but the glass effect does not appear:
If i ignore the quoted MSDN topic, and instead use fully opaque black (rather than a completely transparent black):
Color fillColor = Color.FromArgb(255, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);
the glass effect does appear:
i am then lead to believe that opaque black is the pixel value that the DWM will look for to replace with glass.
But then how do i paint black items on the glass area?
i've tested painting a black rectangle on the glass area, with a circle next to it. Oddly enough, the rectangle doesn't appear, while the circle does appear; both are the same color:
Brush b = new SolidBrush(Color.FromArgb(255, 0, 0, 0));
e.Graphics.FillRectangle(b, 11, 11, 32, 32);
e.Graphcis.FillEllipse(b, 43, 11, 32, 32);
So what in the world is going on? What is the proper color to paint in the extended frame area to make glass appear?
Update 2
Using Adisak's suggestion to isolate exactly where the stupidness of Aero lives, here i draw a black rectangle inside the black circle:
Does FillEllipse not support drawing black circles?
Update 3
Pondidum wondered if calling Graphics.Clear with a transparent black color would make the glass visible:
e.Graphics.Clear(Color.FromArgb(0,0,0,0));
It does work, but you still can't draw opaque black items on the glass:
Update 4
Looking at Microsoft's Vista Bridge Library (managed wrappers around Vista functionality that won't be added to .NET), they only ever manage to get extended glass frame working on WPF forms, not WinForms.
See also
Aero: How to draw ClearType text on glass?
Aero: How to draw solid colors on glass?
Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);
This is actually rather amusing. It means that you are drawing something completely transparent - so this changes absolutely nothing! :-)
Guess: if black (0,0,0) should mean "glass", how about drawing (1,1,1) to get (almost) black?
One of the blog posts that you linked to above has a discussion about this. The native solution was to use SetLayeredWindowAttributes to switch the color key away from black.
Try setting the TransparencyKey of the form to Color.FromArgb(1,1,1) (or some other suitable value of your choosing) then setting the backcolor of the form (or the part you want to be glass) to that same value.
That's how I got it to work without it making all of my black text transparent/glass.
I couldn't ever figure out how to paint the "glowy" text on the glass though. It always had a black rectangle behind it.