2016-09-10 231 views
4

我正在使用libgdx編寫一個帶OpenGL的JWindow類型UI。出於某種原因,即使在啓用GL20.GL_BLEND後,我的應用仍然具有黑色背景。libgdx透明覆蓋

這裏是我的代碼:

package com.mygdx.game; 

import com.badlogic.gdx.ApplicationAdapter; 
import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.Color; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.graphics.g2d.SpriteBatch; 
import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 
import com.badlogic.gdx.scenes.scene2d.Stage; 
import com.badlogic.gdx.utils.viewport.FitViewport; 

public class MyGdxGame extends ApplicationAdapter { 

    Stage stage; 
    SpriteBatch batch; 
    ShapeRenderer shapeRenderer; 

    @Override 
    public void create() { 
     stage = new Stage(new FitViewport(2560, 1440)); 
     batch = new SpriteBatch(); 
     shapeRenderer = new ShapeRenderer(); 
     shapeRenderer.setAutoShapeType(true); 
    } 

    @Override 
    public void render() { 
     Gdx.gl.glEnable(GL20.GL_BLEND); 
     Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); 

     Gdx.gl.glClearColor(0, 0, 0, .25f); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 



     batch.begin(); 
     shapeRenderer.begin(ShapeRenderer.ShapeType.Line); 
     shapeRenderer.setColor(Color.RED); 
     shapeRenderer.rect(100, 25, 200, 450); 

     shapeRenderer.set(ShapeRenderer.ShapeType.Filled); 
     shapeRenderer.setColor(Color.GREEN); 
     shapeRenderer.rect(303, 24, 10, 451); 
     shapeRenderer.end(); 
     batch.end(); 

     Gdx.gl.glDisable(GL20.GL_BLEND); 
    } 

    @Override 
    public void resize(int width, int height) { 
     stage.getViewport().update(width, height, true); 
    } 

    @Override 
    public void dispose() { 
     stage.dispose(); 
     batch.dispose(); 
     shapeRenderer.dispose(); 
    } 

} 

我發現有人問同樣的事情的線程,但在C(How to make an OpenGL rendering context with transparent background?)。我甚至嘗試將LwglAWTCanvas添加到JWindow中,但我仍然無法使背景透明。

我想要一個清晰的背景,所以我可以在用戶屏幕上繪製矩形/形狀。

謝謝!

+0

的可能的複製[?如何使透明背景的OpenGL渲染上下文(http://stackoverflow.com/questions/4052940/how-to-make-an-opengl-rendering-context-with-transparent-background) – pleluron

+0

不是真的重複,因爲這不是一種本地語言。 –

+0

這就是我想指出的。在java中沒有答案,請參閱[this](http://stackoverflow.com/questions/10276020/lwjgl-window-with-transparent-background)。 – pleluron

回答

3

我能夠使用JNA在Windows上進行這項工作。

import com.badlogic.gdx.backends.lwjgl.LwjglApplication; 
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; 
import com.badlogic.gdx.graphics.Color; 
import com.mygdx.game.CharlatanoOverlay; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.User32; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinUser; 

import static com.sun.jna.platform.win32.WinUser.*; 

public class DesktopLauncher { 

    public static final WinDef.DWORD DWM_BB_ENABLE = new WinDef.DWORD(0x00000001); 
    public static final WinDef.DWORD DWM_BB_BLURREGION = new WinDef.DWORD(0x00000002); 
    public static final WinDef.DWORD DWM_BB_TRANSITIONONMAXIMIZED = new WinDef.DWORD(0x00000004); 

    public static final WinDef.HWND HWND_TOPPOS = new WinDef.HWND(new Pointer(-1)); 

    private static final int SWP_NOSIZE = 0x0001; 
    private static final int SWP_NOMOVE = 0x0002; 

    private static final int WS_EX_TOOLWINDOW = 0x00000080; 
    private static final int WS_EX_APPWINDOW = 0x00040000; 

    public static void main(String[] arg) { 
     LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); 
     System.setProperty("org.lwjgl.opengl.Window.undecorated", "true"); 
     cfg.width = LwjglApplicationConfiguration.getDesktopDisplayMode().width-1; 
     cfg.height = LwjglApplicationConfiguration.getDesktopDisplayMode().height-1; 
     cfg.resizable = false; 
     cfg.fullscreen = false; 
     cfg.initialBackgroundColor = new Color(0, 0, 0, 0); 

     new LwjglApplication(new CharlatanoOverlay(), cfg); 

     WinDef.HWND hwnd; 
     while ((hwnd = User32.INSTANCE.FindWindow(null, "CharlatanoOverlay")) == null) { 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     System.out.println(hwnd); 
     System.out.println(transparentWindow(hwnd)); 
    } 

    public static boolean transparentWindow(WinDef.HWND hwnd) { 
     DWM_BLURBEHIND bb = new DWM_BLURBEHIND(); 
     bb.dwFlags = DWM_BB_ENABLE; 
     bb.fEnable = true; 
     bb.hRgnBlur = null; 
     DWM.DwmEnableBlurBehindWindow(hwnd, bb); 

     int wl = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE); 
     wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT; 
     User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl); 

     wl &= ~(WS_VISIBLE); 

     wl |= WS_EX_TOOLWINDOW; // flags don't work - windows remains in taskbar 
     wl &= ~(WS_EX_APPWINDOW); 

     User32.INSTANCE.ShowWindow(hwnd, SW_HIDE); // hide the window 
     User32.INSTANCE.SetWindowLong(hwnd, GWL_STYLE, wl); // set the style 
     User32.INSTANCE.ShowWindow(hwnd, SW_SHOW); // show the window for the new style to come into effect 
     User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl); 

     return User32.INSTANCE.SetWindowPos(hwnd, HWND_TOPPOS, 0, 0, 2560, 1440, SWP_NOMOVE | SWP_NOSIZE); 
    } 
} 

DWM:

import com.sun.jna.Native; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinNT; 

public class DWM { 

    static { 
     Native.register("Dwmapi"); 
    } 

    public static native WinNT.HRESULT DwmEnableBlurBehindWindow(WinDef.HWND hWnd, DWM_BLURBEHIND pBlurBehind); 

} 

DWM_BLURBEHIND:

import com.sun.jna.Structure; 
import com.sun.jna.platform.win32.WinDef; 

import java.util.Arrays; 
import java.util.List; 

public class DWM_BLURBEHIND extends Structure { 

    public WinDef.DWORD dwFlags; 
    public boolean fEnable; 
    public WinDef.HRGN hRgnBlur; 
    public boolean fTransitionOnMaximized; 

    @Override 
    protected List<String> getFieldOrder() { 
     return Arrays.asList("dwFlags", "fEnable", "hRgnBlur", "fTransitionOnMaximized"); 
    } 

} 
+0

幹得好,我不知道這是可能的。看來我們也可以通過jna訪問xlib,以提供便攜式解決方案。 – pleluron

+0

@pleluron現在正在努力。對於libgdx來說,擁有一個跨平臺的JWindow類型的OpenGL畫布會很棒。 :D –

+0

@ jonathan-beaudoin你有沒有在linux上使用過這個工作?很想有這種效果交叉平臺! – PureSpider