为什么glDrawpixels不渲染我的透明背景?

0 投票
2 回答
822 浏览
提问于 2025-04-17 12:11

我想在OpenGL中显示字体,并且希望背景是透明的。主要的问题是我的背景总是黑色的不透明!

这是我的代码:

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)

2 个回答

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

你好,似乎你想要实现的目标还不是很清楚。你可能是想在某些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-buffer(或者叫FBO,帧缓冲对象),然后用glReadPixels()来复制输出,最后再用GDI的BitBlt()来显示结果。在你想渲染一段文字的情况下,可能不使用OpenGL会更好。

所以,在你的例子中,你可以把黑色变成透明,也就是x = y = z = 0,不使用OpenGL,而是使用CreateDIBSection()创建一个设备无关位图(DIB),然后用图像填充它,而不是传递给glDrawPixels(),最后用BitBlt()来渲染到窗口。

撰写回答