2012-02-02 104 views
-1

我想用透明背景在opengl中渲染字体。 主要问题是我的背景总是不透明的黑色!为什么glDrawpixels不渲染我的透明背景?

这里是我的代码:

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) 
+0

这是视窗系统默认情况下是如何工作的。如果你想透明,你需要一个支持透明窗口的操作系统和WM(例如Windows&DWM/Aero),那么你可以创建一个新的透明窗口,将OpenGL的东西渲染到帧缓冲区,将像素读回RAM,将它们投射到窗口避免透明的像素。我不知道如何详细地做这件事,实施起来可能会非常复杂,特别是如果您想要跨平台支持的话。真的没有其他的方法来做到这一点。 – 2012-02-02 11:11:10

回答

0

干杯,它不是完全清楚什么是你想acheive。你可以尝试在某些其他OpenGL几何体上渲染透明字体,也可以使用OpenGL渲染窗体的内容,并使窗体的某些部分透明(以便可以在窗体后面看到窗口)。

为了使窗口透明,您需要使用:

// 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); 

在窗口上。这使得所谓的色键,这意味着使用RGB(X,Y,Z)得到透明渲染什么,该窗口在这些部分中不可见。请注意,此透明度是二元的,它是完全透明的或完全不透明的。另外,你需要使用GDI来渲染你的窗口。这意味着要么根本不使用OpenGL,而要使用像BitBlt()或StretchBlt()这样的函数,或者使用OpenGL渲染成P缓冲区(或FBO,帧缓冲区对象),然后使用glReadPixels()来复制输出,然后再次使用BitBlt()来显示使用GDI的结果。在您尝试渲染一段文字的情况下,如果不使用OpenGL,可能会更好。因此,在你的例子中,你可以使黑色透明,即x = y = z = 0,不使用OpenGL,而是使用CreateDIBSection()创建一个设备无关位图(DIB),而用图像填充它将其传递给glDrawPixels()并使用BitBlt()渲染到窗口。

+0

...也许,但你的代码似乎并不便携....终于,我的代码工作,并且可以在平台linux,win32之间移植。我必须在使用它之前检查混合是否可用。感谢您的帮助 – sancelot 2012-02-08 14:39:14

+1

...这意味着您实际上想要做的第一件事(透明的字体比其他使用OpenGL呈现的东西),而不是我解释的(透明窗口)。尝试下次更好地指出你的问题。所以,如果你自己写了自己的答案并接受了答案,这将是一件好事,因此这个问题会得到解决,而有类似问题的人也会知道解决方案。 – 2012-02-09 09:32:46

0

加入这个在开始

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  )