¿Por qué glDrawpixels no procesa mi fondo transparente?

I want to render font in opengl with transparent background. The main problem is that my background is always opaque black !

aquí está mi código:

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
font = ImageFont.truetype("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc", 16)
textsize = font.getsize(u"当前运行列表")
im = Image.new("RGB",textsize,"#000")
draw = ImageDraw.Draw(im)
transparent_area = (0,0,im.size[0],im.size[1])
mask=Image.new('L', im.size, color=0)   
drawmask = ImageDraw.Draw(mask)
drawmask.rectangle(transparent_area, fill=0)
im.putalpha(mask)
draw.text((0,0), u"当前运行列表", font=font, fill="red")
#im.save('render.png')
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1)
glDrawPixels(ix,iy,GL_RGBA,GL_UNSIGNED_BYTE,image)

preguntado el 02 de febrero de 12 a las 10:02

That's just how windowing systems work by default. If you want transparency, you need an OS and WM that support transparent windows (Windows & DWM/Aero for example), then you can create a new transparent window, render the OpenGL stuff to a framebuffer, read the pixels back to RAM, and blit them to the window avoiding the pixels that are transparent. I don't know how to do this in detail, and it's probably going to be really complicated to implement, especially if you want cross-platform support. There really isn't another way to do this. -

2 Respuestas

Cheers, it is not fully clear what are you trying to acheive. You could either be trying to have a transparent font rendered over some other OpenGL geometry, or maybe you want to render contents of the window using OpenGL and make parts of the window transparent (so you can see windows behind it).

To make window transparent, you need to use:

// Set WS_EX_LAYERED on this window 
SetWindowLong(hwnd, 
          GWL_EXSTYLE, 
          GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

// Make this window transparent
int transparentColor = RGB(x, y, z);
SetLayeredWindowAttributes(hwnd, transparentColor, 255, LWA_COLORKEY);

This enables so called color keying on the window, that means anything that is rendered using RGB(x, y, z) gets transparent, and the window is not visible in these parts. Note that this transparency is binary, it is either fully transparent or fully opaque. Also, you need to be using GDI to render to your window. That means either do not use OpenGL at all, and use function like BitBlt() or StretchBlt() instead, or use OpenGL to render into a P-buffer (or into a FBO, framebuffer object), then use glReadPixels() to copy the output, and then use BitBlt() again to display the results using GDI. In your case where you are trying to render a piece of text, you might be better off without using OpenGL.

So, in your example you could make black color transparent, i.e. x = y = z = 0, do not use OpenGL, and create a device independent bitmap (DIB) instead using CreateDIBSection(), fill it with image instead of passing it to glDrawPixels() and render to window using BitBlt().

Respondido 08 Feb 12, 13:02

... Maybe, but your code does not seem portable....finally, my code works and is portable between platforms linux, win32.. I had to check if blending was available before using it. Thanks for your help - sancelote

... which means you actually wanted to do the first thing (transparent font over other stuff rendered using OpenGL), not the one I explained (transparent windows). Try to specify your questions better next time. So, it would be a good thing if you wrote your own answer and accepted it so this question gets closed and people with problem similar to yours know the solution. - los cerdos

added this at beginning

glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE )
glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE )
glPixelStorei( GL_UNPACK_ROW_LENGTH,  0        )
glPixelStorei( GL_UNPACK_SKIP_ROWS,   0        )
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0        )
glPixelStorei( GL_UNPACK_ALIGNMENT,   1        )

Respondido 07 Feb 13, 21:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.