0

AWT/Swing アプリケーション用の 3D レンダリング モジュールを作成しています。

優れた FPS を提供するために、Swing/AWT メソッドとグラフィックスを使用して描画することはできません。代わりに、Canvas 要素から Drawing Surface を取得し、それに直接レンダリングします。このようなもの:

public class Window {

    private Component canvas;
    private JAWTDrawingSurface ds;

    public static final JAWT awt;
    static {
        awt = JAWT.calloc();
        awt.version(JAWT_VERSION_1_4);
        if (!JAWT_GetAWT(awt))
            throw new AssertionError("GetAWT failed");
    }

    public void lock() throws AWTException {
        int lock = JAWT_DrawingSurface_Lock(ds, ds.Lock());
        if ((lock & JAWT_LOCK_ERROR) != 0)
            throw new AWTException("JAWT_DrawingSurface_Lock() failed");
    }

    public void unlock() throws AWTException {
        JAWT_DrawingSurface_Unlock(ds, ds.Unlock());
    }

    public void Init2()
    {    
        this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
        try
        {
            lock();
            // Create GL Capabilities
            unlock();
        }
     }

初めて呼び出すときは正常に動作します。しかし、何らかの理由でキャンバスを非表示にした場合 (たとえば、ウィンドウを最小化したり、キャンバスの代わりに別のパネルを表示したり)、ds変数は同じままですが、その後は機能しません。基本的に、変数が表示されていて一番上にある場合にのみ変数を呼び出すことを確認したとしても、dsを使用した呼び出しは例外をスローします。たとえば、lock()関数が機能しなくなります。

なぜだろう?

また、ウィンドウを最小化してから再度最大化すると、基本的に新しい DS を取得しようとしましたが、これも機能しません。新しい DS アドレスは正常に返されますが、その新しいオブジェクトを使用できません。元のものを使用しないでください。

ここで私が見逃している愚かな何かがあるかもしれませんが、何がわかりません。これを整理するのを手伝ってください。ありがとうございました!

4

1 に答える 1

0

ソリューション:

Canvas が非表示の場合、eglMakeCurrent(eglDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT) を呼び出して、現在のコンテキストのバインドを解除します。

描画を再開する必要がある場合は、次のようにする必要があります。

public void Reinit()
{
    System.err.println("Context Reinit()");

    this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
    try
    {
        lock();
        try
        {
            JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo());

            JAWTX11DrawingSurfaceInfo dsiWin = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo());

            this.display = dsiWin.display();
            this.drawable = dsiWin.drawable();

            eglDisplay = eglGetDisplay(display);

            surface = eglCreateWindowSurface(eglDisplay,fbConfigs.get(0),drawable,(int[])null);

            eglMakeCurrent(eglDisplay,surface,surface,context);

            GLES.setCapabilities(glesCaps);

            JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo());
        }
        finally
        {
            unlock();
            System.err.printf("Unlock \n");
        }

    }
    catch (Exception e)
    {
        System.err.println("JAWT Failed" + e.getMessage());
    }
}

ご覧のとおり、ディスプレイとサーフェスを再作成しますが、以前に作成したコンテキストをレンダリングに使用するため、再作成する必要はありません。

于 2020-02-26T05:37:16.910 に答える