2012-02-02 103 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  )