Warum wurde mein OpenGL-Fragment bei einem Update-Tick nicht mehr neu gezeichnet?

Und

Ich habe eine OpenGL-App für Anfänger erstellt, die einen sich drehenden Stier zeigt, der aus einer obj-Datei geladen wurde. Es hat gut funktioniert und ich habe es meinen Freunden gezeigt. Gestern habe ich die App geöffnet und die Ansicht wird nicht mehr aktualisiert. Wenn ich die Home-Taste drücke und dann erneut auf die App tippe, wird die Ansicht aktualisiert, sodass ich weiß, dass die Hauptschleife aktiv ist.

Ich ging nach Hause und steckte es in Android Studio, um zu bestätigen, dass der Render-Thread einwandfrei ausgelöst wird und view.requestRender();auch aufgerufen wird.

Ich habe keine Ahnung, warum das nicht mehr funktioniert.

Hier ist mein Android-Fragment, das die Ansicht und den Renderer lädt

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    /**
     * Inflate the layout for this fragment
     */
    View root = inflater.inflate(R.layout.glfragment, container, false);

    GLSurfaceView glview = (GLSurfaceView)root.findViewById(R.id.surface_view);

    Log.i("Method", "OpenGLFragment::onCreateView()");

    Context context = this.getActivity().getApplicationContext();

    MyRenderer renderer = new MyRenderer(context);
    glview.setEGLContextClientVersion(2);
    glview.setRenderer(renderer);
    glview.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    loadMeshes(context); // loads obj file into variable tourus

    renderer.addToScene(tourus);

    update = new GraphicsThread(glview);
    update.start();

    return root;
}

@Override
public void onDestroyView() {
    if(update != null) {
        update.quit();
    }

    super.onDestroyView();
}

Hier ist der Grafik-Thread:

public class GraphicsThread extends Thread {
    private GLSurfaceView.Renderer renderer;
    private GLSurfaceView view;

    private boolean isRunning;

    public GraphicsThread(GLSurfaceView view) {
        this.view = view;
        this.isRunning = true;
    }

    @Override
    public void run() {
        while (this.isRunning) {
            view.requestRender(); // I verified this loop is executed just fine
        }
    }

    public void quit() {
        this.isRunning = false;
    }
}

Hier ist MyRendererCode

public class MyRenderer implements GLSurfaceView.Renderer {
    private int program; // default shader program
    private List<Mesh> drawables;
    private Context context;
    private long lastFrameTime;
    private RenderInfo info; // MVP and Light matrices
    private Bitmap bg;

    public MyRenderer(Context context) {
        this.drawables = new ArrayList<>();
        this.context = context;
        this.lastFrameTime = 0;
        this.info = null;
    }

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        info = new RenderInfo(context);

        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        GLES20.glEnable(GLES20.GL_CULL_FACE);
    }

    public void onDrawFrame(GL10 unused){
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        float elapsed = getElapsedTime();

        float rot = 10.0f*elapsed;

        for(Mesh m : drawables) {
            m.rotateX(rot);
            m.draw(info, elapsed);
        }
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        if(width > 0 && height > 0) {
            final float ratio = (float) width / height;
            final float left = -ratio;
            final float right = ratio;
            info.resizePerspective(left, right, 1, -1);
        }
    }

    public void addToScene(Mesh mesh) {
        drawables.add(mesh);
    }

    private float getElapsedTime() {
        long currentTime = SystemClock.elapsedRealtime();
        float elapsed = (float)(currentTime - lastFrameTime) / 1000.0f; //convert ms to seconds
        lastFrameTime = currentTime;

        return elapsed;
    }
}

Zum Schluss zeichne ich hier meine Maschen. RenderInfohat Weltinformationen wie Kamera MVP Matrix und Lichter und ihre Matrizen. Nichts im Zusammenhang mit dem Problem.

public void draw(RenderInfo info, float elapsed) {
    if(!loaded) {
        Log.d("Mesh", "failed to draw");
        return;
    };

    final int program = info.getProgram();

    int position = GLES20.glGetAttribLocation(program, "a_Position");
    int normal = GLES20.glGetAttribLocation(program, "a_Normal");
    int aColor = GLES20.glGetAttribLocation(program, "a_Color");

    //int textcoord = GLES20.glGetAttribLocation(program, "a_TexCoordinate");

    GLES20.glEnableVertexAttribArray(position);
    GLES20.glVertexAttribPointer(position, 3, GLES20.GL_FLOAT, false, 3 * 4, verticesBuffer);

    GLES20.glEnableVertexAttribArray(aColor);
    GLES20.glVertexAttribPointer(aColor, 4, GLES20.GL_FLOAT, true, 4*4, colorBuffer);

    //GLES20.glEnableVertexAttribArray(normal);
    //GLES20.glVertexAttribPointer(normal, 3, GLES20.GL_FLOAT, false, 3 * 4, normalBuffer);

    float[] modelMatrix = new float[16];

    Matrix.setIdentityM(modelMatrix, 0);
    Matrix.setRotateM(modelMatrix, 0, rotX , 1.0f, 0.0f, 0.0f);
    //Matrix.setRotateM(modelMatrix, 0, rotY , 0.0f, 1.0f, 0.0f);
    //Matrix.setRotateM(modelMatrix, 0, rotZ , 0.0f, 0.0f, 1.0f);

    float[] mvpMatrix = info.getMVP(modelMatrix);
    int MVP = GLES20.glGetUniformLocation(program, "u_MVP");
    GLES20.glUniformMatrix4fv(MVP, 1, false, mvpMatrix, 0);

    float[] mvMatrix = info.getMV();
    int MV = GLES20.glGetUniformLocation(program, "u_MV");
    GLES20.glUniformMatrix4fv(MV, 1, false, mvMatrix, 0);

    int lightM = GLES20.glGetAttribLocation(program, "u_LightPos");
    GLES20.glUniformMatrix4fv(lightM, 1, false, info.getLightMatrix(), 0);

    int lightCol = GLES20.glGetAttribLocation(program, "u_LightCol");
    GLES20.glUniform4fv(lightCol, 1, info.getLightColor(), 0);
    Log.d("boogio", "u_LightCol is: " + Integer.toString(lightCol));


    GLES20.glDrawElements(GLES20.GL_TRIANGLES, facesList.size() * 3, GLES20.GL_UNSIGNED_SHORT, facesBuffer);
    GLES20.glDisableVertexAttribArray(position);
    GLES20.glDisableVertexAttribArray(aColor);
    //GLES20.glDisableVertexAttribArray(normal);
}

TL; DR: App wird gut gerendert und zum Aktualisieren verwendet. Plötzlich wird die App nicht mehr visuell aktualisiert (keine Neuzeichnungen). Es wird nur neu gezeichnet, wenn die App für 1 Frame verliert und den Fokus wiedererlangt. Keine Ahnung warum.

xcesco

Sie veröffentlichen nicht den gesamten Code, daher ist es unmöglich, die Situation zu reproduzieren. Alles, was ich tun kann, um Ihnen zu helfen, ist, einige Dinge vorzuschlagen.

1 - Kontext beibehalten und OpenGL-Überprüfungsfehler hinzufügen

Zunächst sollten Sie der GLView mitteilen, dass der OpenGL-Kontext mithilfe des setPreservceEGLContext beibehalten werden soll . Falls sich die Situation dadurch nicht beheben lässt, ist es besser, die DEBUG-Ablaufverfolgung im OpenGL ES-Kontext mithilfe der setDebugFlas- Methode zu aktivieren .


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    /**
     * Inflate the layout for this fragment
     */
    View root = inflater.inflate(R.layout.glfragment, container, false);

    GLSurfaceView glview = (GLSurfaceView)root.findViewById(R.id.surface_view);

    Log.i("Method", "OpenGLFragment::onCreateView()");

    Context context = this.getActivity().getApplicationContext();

    MyRenderer renderer = new MyRenderer(context);
    glview.setEGLContextClientVersion(2);
    // added code
    glview.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); // enable log
    glview.setPreserveEGLContextOnPause(true); // default is false

    glview.setRenderer(renderer);
    glview.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    loadMeshes(context); // loads obj file into variable tourus

    renderer.addToScene(tourus);

    update = new GraphicsThread(glview);
    update.start();

    return root;
}

Dadurch werden Ihrer App in weitere Debug-Informationen hinzugefügt logcat(ich hoffe, Sie wissen bereits, was es ist). Ich denke, Sie werden einige Fehler finden (Zeilen mit OPEN GL-Fehler .. etwas).

Ich vermute, dass Sie die Aktivität erneut öffnen. Der OpenGL-Kontext versucht, Ressourcen zu verwenden, die nicht mehr gültig sind (da der OpenGL-Kontext zerstört wird). Ein typisches Beispiel für Ressourcen, die Sie während der Kontexterstellung neu verwalten müssen, sind Textur- und Shader-Programme.

2 - Überprüfen Sie den Grafik-Thread

Fügen Sie einfach einige Log-Debug-Informationen zu Graphic Thread hinzu:

public class GraphicsThread extends Thread {
      private GLSurfaceView.Renderer renderer;
      private GLSurfaceView view;

      private boolean isRunning;

      public GraphicsThread(GLSurfaceView view) {
        this.view = view;
        this.isRunning = true;
        Log.i("GraphicsThread", "GraphicsThread::constructor()");
      }

    @Override
    public void run() {
        while (this.isRunning) {
            Log.i("GraphicsThread", "requestRender");
            view.requestRender(); // I verified this loop is executed just fine
        }


    }

    public void quit() {
        this.isRunning = false;
        Log.i("GraphicsThread", "GraphicsThread::quit()");
    }
}

Mithilfe der Protokollinformationen in GraphicThread können Sie überprüfen, ob der Thread wie vorgesehen funktioniert.

Einige Erklärungen

  • glview.setPreserveEGLContextOnPause(true);Schont Ressourcen, wenn Sie den Kontext zerstören (Bildschirmrotation oder Aktivität im Hintergrund): Die Alternative besteht darin, alle Ressourcen neu zu erstellen und neu zu laden. Ich nehme an, es wurde gemacht, weil Android-Geräte am Anfang keinen Speicher hatten, um den GLContext zu erhalten, als das GLView zerstört wurde.
  • RENDERMODE_CONTINUOUSLY fordert GLView auf, eine Szene zu zeichnen, wann immer dies möglich ist (und dies ist der beste Weg für das, was ich weiß).

Ich hoffe meine Vorschläge können Ihnen helfen.

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Warum wird bei einer Änderung von $ scope.data in einem onChange-Rückruf chart.js nicht neu gezeichnet?

Warum verarbeitet Gulp mein JS bei Änderungen nicht automatisch neu?

JavaFX wird nicht neu gezeichnet, wenn ein Objekt entfernt wird, das über einem anderen Objekt gezeichnet wurde

Warum ist mein ViewPager in einem CoordinatorLayout nicht mehr gebunden?

Warum endet mein Observable nicht bei einem Fehler?

Warum funktioniert mein Type-Casting bei einem Objekt nicht?

Warum stürzt mein Code nicht mehr ab, nachdem die aSan-Bibliothek hinzugefügt wurde?

Warum funktioniert mein Multiprozessor-Code bei großen Datenmengen nicht mehr?

Warum funktioniert mein Code nicht? neu in Java

Elemente in Recyclerview + Listadapter werden beim Update nicht neu gezeichnet

Warum funktioniert mein Difftool nicht mehr?

Warum wurde ActionBarActivity nicht mehr unterstützt?

Warum funktioniert mein Laravel-Pass nicht mehr, als er vom eingebauten Server auf Vagrant migriert wurde?

DataTables werden nicht neu gezeichnet

Warum rendert OpenGL mein rotes Dreieck nicht?

Warum funktioniert mein Flaschenbefehl bei Heroku nicht?

Warum funktioniert mein Reaktionsformular bei Codesandbox nicht?

Warum funktioniert mein Übergang nicht bei <hr>?

Warum tritt mein Container nicht in Docker-Compose einem vorhandenen Netzwerk bei?

Warum ist mein JScrollPane mit einem JTextArea bei Verwendung von null LayoutManager nicht sichtbar?

Warum kann mein Kafka-Thema bei einem heruntergekommenen Broker nicht konsumiert werden?

Warum funktioniert mein Bash-Skript in einem Terminal, aber nicht bei Verwendung von crontab?

Warum wird der HTML/JS-Fortschrittsbalken bei einem bestimmten Prozentsatz nicht mehr geladen?

Das Highcharts-Diagramm wurde nicht neu gezeichnet, nachdem die Vue-Daten geändert wurden

Warum benötigt mein Programm nicht mehr als 2 GB RAM auf einem 64 GB RAM-System?

Warum wird mein Controller-Aktionsfilter nicht mehr aufgerufen, wenn ich die SSL-Einstellungen mit einem "location" -Element überschreibe?

Neu bei argParse, nicht sicher, wo mein Fehler ist

UIView-Hintergrundfarbe wird bei Frame-Änderungen nicht neu gezeichnet (in dynamisch expandierender TableViewCell)

Warum scrollt mein JPanel in einem JScrollPane nicht?

TOP Liste

  1. 1

    So legen Sie mit dem Interface Builder unterschiedliche führende Speicherplätze für unterschiedliche Geräte fest

  2. 2

    Fügen Sie eine weitere Schaltfläche zu gwt Suggest Box hinzu

  3. 3

    Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

  4. 4

    Wie kann ich in SCSS mehrere Klassen zu einer einzigen kombinieren?

  5. 5

    Wie konvertiert man einen Datenrahmen im langen Format in eine Liste mit einem geeigneten Format?

  6. 6

    Speichern Sie ein MPAndroidChart-Diagramm in einem Bild, ohne es in einer Aktivität anzuzeigen

  7. 7

    Gruppieren Sie Datenrahmenspalten nach ihrem Datum (die Spaltentitel enthalten) und fassen Sie die Instanzen von Einsen und Nullen in R . zusammen

  8. 8

    Tomcat - Leiten Sie den alten Kontextstamm zum neuen Kontextstamm um

  9. 9

    Eclipse Oxygen - Projekte verschwinden

  10. 10

    Wie wählt man Unterschiede mit drei Tabellen aus?

  11. 11

    Tic Tac Toe-Spiel im React-Reset-Button funktioniert nicht

  12. 12

    So berechnen Sie die Verfügbarkeit von Anwendungen (SLA)

  13. 13

    ElasticSearch BulkShardRequest ist aufgrund von org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor fehlgeschlagen

  14. 14

    Wie kann ich den Kaskadenmodus global einstellen?

  15. 15

    Python: Spalten mit demselben Namen zusammenführen, wobei der Mindestwert beibehalten wird

  16. 16

    So erhalten Sie eine gleichmäßige Höhe für alle Eingabefelder

  17. 17

    Wie erstelle ich einen neuen übergeordneten Knoten außerhalb der .ref (/ path) in der Firebase-Echtzeitdatenbank mithilfe von Cloud-Funktionen (Typescript)?

  18. 18

    Was ist schneller: SUM über NULL oder über 0?

  19. 19

    Wie kann ich eine verschachtelte Schleife mit lapply in R ersetzen?

  20. 20

    Kann ich ein Tkinter-Canvas erstellen, das mehrere Zeilen in einem Text-Widget umfasst?

  21. 21

    Ärgerliches Problem mit yaml, das ich nicht lösen kann

heißlabel

Archiv