I have a directX11 texture which is of ARGB format. (different pixels has different alpha value, like the one below)
I need to render that texture on a transparent Window which means the desktop should appear behind the texture.
I am using SetLayeredWindowAttributes which could make the window transparent but it's boolean, i.e. a pixel appears either fully transparent or doesn't appear. I need to achieve per-pixel transparency level - where darkness is defined by the alpha value of the pixel (Something like AlphaBlend). How to achieve it?
Use UpdateLayeredWindow instead. Select a 32-bit ARGB bitmap into the source HDC.
A more fancy solution is WS_EX_NOREDIRECTIONBITMAP and ICompositorDesktopInterop but this is probably overkill in this case unless you need to do updates often. MSDN magazine did have a few articles about this. DirectComposition is intended to interop with Direct2D etc. where as UpdateLayeredWindow is much older and predates the DWM and any kind of visual tree rendering.
Related
I wish to make an opengl universal texture transparent hack for the DxWnd tool (an open-source program hosted o SourceForge). The hack should work for every program using opengl to render RGBA textures. DxWnd cah hook and redirect all calls from libraries, including opengl32.dll.
I've read and tried to implement all suggestions about making a texture transparent, including enabling GL_BLEND, disabling GL_CULL_FACE and setting glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). In addition, there's a routine that enforces the alpha bits of all texture pixels.
I expected that, once finished, the result should be a semi-transparent scene, but that doesn't happen.
For instance, the following is a 3d scene from gl hexen II:
and this is the final result, with some textures not transparent and most pixel colors lost:
Just to demonstrate that DxWnd is able to manipulate color pixels (so that this should not be the cause of the problem) this is the same scene with a filter that recolors every texture:
What could be the reason of the problem? How should I fix it? Please, be aware that since DxWnd is hooking a generic program, it may easily have to confront with opengl calls that have an opposite purpose!
What you want is not generally possible just from hooking onto some other application.
You may be able to force blending to be on. But correct transparent rendering is a fundamentally different task from rendering an opaque scene. Because alpha-blended transparency is based on doing per-triangle blending operations with the background, it only really works if you render everything in a back-to-front order.
But as far as the program is concerned, it thinks it is doing opaque rendering. So it's going to render in the order it sees fit to use. Which for more modern applications is probably front-to-back, to take advantage of early depth testing.
And that's the exact opposite order you need to make transparency work. And there's no generic way to control the order of rendering just by hooking onto a few OpenGL functions.
Furthermore, applications tend to try to avoid rendering parts of the scene that are obviously not visible. So if the application thinks that a particular room is not visible because the door to that room isn't visible, then the room and its contents won't be rendered. So even if you could get the order of rendering correct, you'd also need to make the program change what it renders in order to correctly see through stuff.
It should also be noted that doing alpha blending requires that the fragments being rendered have a useful alpha value. But most fragment computations for opaque surfaces will have an alpha value of 1.0. And thus: no blending. And, unless you're dealing with fixed-function OpenGL rendering, or you're willing to manually patch shaders to add your own alpha uniform values, there's no way to change this from outside of the application.
How to change background color of sprites to transparent by changing alpha after loading it to a SDL_Surface. Are there any functions in SDL which use a floodfill kind of algorithm and change all pixel with a given color to transparent on the outside. I don't want it to happen inside the border of the sprite if the same color is used.
Sample Image:
I would like to make the background blue here transparent before I blit it on the window surface using SDL_BlitSurface.
Only a color key (SDL_SetColorKey()) or a full alpha channel are going to help you here.
Note, that you can provide an alpha channel in your source graphics if you use a format such as PNG. If you only sometimes need/want an alpha, then provide the alpha channel in your source graphics and use SDL_SetSurfaceBlendMode() with SDL_BLENDMODE_NONE to blend without the alpha and SDL_BLENDMODE_BLEND to blend with it.
Both SDL_Surface and SDL_Texture support SDL_BlendMode.
Even if SDL provided another method, such as the fill you mentioned. You wouldn't want to use that. It is more difficult, expensive, and unnecessary overhead. You should stick with best practices here.
You may want to look into SDL_Texture and SDL_Renderer and switch to using a "texture atlas" instead of individual surfaces/textures for each image to maximize performance.
What im currently doing is drawing multiple textures on a single IDirect3DTexture9 and then scale it to make a nice animation using ID3DXSprite.
Im searching a way to draw text on that final IDirect3DTexture9, however ID3DXFont does not apparently support it.
TextOut requires the DC of the texture and in consequence requires the texture to be in format D3DFMT_X8R8G8B8, which will make me lose my opacity support.
Is there anyway to do this without coding my own font engine?
DirectX9 and C++
Thanks.
I'm using Qt5 and its OpenGL integration, and am running into a problem when I try to draw translucent objects. When an object is translucent, whatever is visible behind my OpenGL window is shown within the screen area of that object, instead of the object being blended with whatever is already in the colour buffer. I have started watching YouTube videos through my translucent objects, as whatever shows through is live.
Interestingly, the most see-through an object gets seems to occur at half opacity - full opacity renders it solid, while zero opacity renders nothing at all (and whatever was previously in the background of the 3D scene remains there). Rendering translucent objects last does not fix the issue.
I have noticed that this also happens when I enable mipmaps on my textures - as the distance to a point on an object increases, the pixel concerned becomes more translucent and displays whatever is behind the OpenGL window. The issue occurs both on my Windows and OSX machines.
Is this a known issue? Is there a workaround? Google hasn't proven too helpful.
Hah, that's a funny one. I can't tell you what is going on, because it normally takes some extra effort to make windows actually transparent; in Windows you have to select a framebuffer format with an alpha channel and call DwnEnableBlurBehindWindow to actually achieve this effect. And as far as I know Qt doesn't do this.
But if it does here are a few hints:
Make sure you clear your framebuffer to alpha=1
When rendering translucent objects keep the destination alpha value 1, i.e. don't use blending modes and functions that modify the destination alpha value, or force it to 1.
There's actually little use for the alpha channel on the main window framebuffer, except for implementing window translucency effects. Unless you need those you should choose an either pixel format without an alpha channel for your window framebuffer, or keep all its pixels alpha values at full opacity.
I'm writting a simple software renderer,
load 3d model, process vertex, rasterization, texture, lighting,
all that things, all done.
I used SDL(not using OpenGL mode) to draw pixel on its SDL_Surface,
and call SDL_Flip, so one frame appears.
for some reason now I don't want to use SDL,
I just need a double-buffer to draw pixel.
I know there're someway to do this,
OpenGL, Direct3D, gdi,
maybe they're too "advanced" for this project,
what is the direct(or fastest) way to draw pixels to back-buffer on win32 ?
I'd recommend using a graphics API for this (OpenGL or Direct3D), but GDI would be the easiest option. You can create a DIB (Device Independent Bitmap) using the CreateDIBSection function which returns a pointer to the bitmap's memory. You can then modify the pixels of the bitmap however you please and draw it to your window's client area. See chapter 15 of Programming Windows (5th) by Charles Petzold for source code and explanation of this technique.