Android ImageView накладывается поверх неожиданного поведения Opengl ES - PullRequest
1 голос
/ 08 августа 2011

Я пытаюсь добавить оверлей к приложению Android opengl ES, и в настоящее время я задаю ImageView и отрабатываю код из демонстрации API SurfaceViewOverlay, эффективно объединяя два приложения, которые я написал, одно на основе Canvas и одно с opengl ES .

Из-за слияния двух проектов было задействовано большое количество копировальной пасты, что привело меня к случайному использованию нулевого поверхностного держателя. Удивительно, но это сработало, но бросило большое количество предупреждений. Однако при изменении его на поверхностный держатель панели opengl приложение зависает и не отображает содержимое из opengl или ImageView.

Я поиграл с кодом, чтобы убедиться, что я ничего не инициализировал, и подтвердил поведение как на HTC Desire, так и на Samsung Galaxy (оба работают под управлением 2.2)

Canvas c = null;
SurfaceHolder surfaceHolder2D = null; // this works but throws occational Null Pointer exceptions on the first canvas.drawText
//SurfaceHolder surfaceHolder2D = rsurfaceHolder; // this locks the application. 
//rsurfaceHolder is initialized with getHolder() in the opengl class and this worked with both when they where separate. 
//The change to ImageView was to get around issues with multiple SurfaceViews in an application having indeterminate Z order

try
{
    if (Global.RUNNING == 1)
    {
        c = surfaceHolder2D.lockCanvas(null); // when canvas is null this line can be ommited and it still works
        synchronized (surfaceHolder2D)
        {
            rpanel2D.onDraw(c);
        }
    }
    else
        sleep(1000);
}
catch (Exception e)
{
    e.printStackTrace();
}
finally
{
    if (c != null)
    {
        surfaceHolder2D.unlockCanvasAndPost(c);
    }
}

Так что же происходит на земле, и как правильно это сделать? Я предполагаю, что когда я пишу на пустой холст, компилятор что-то делает и отправляет в нужное место независимо от этого.

Оставить все как есть, на самом деле не вариант, по нескольким причинам, в том числе не полагая, что это будет работать на нескольких версиях Android, он наводняет журналы постоянным потоком предупреждений со значительным падением частоты кадров и работает только если onDraw становится недействительным при каждом вызове.

Что касается функции onDraw, то она просто использует canvas.drawText с this.invalidate ()

Любопытно, создавая новый холст и рисуя его и пытаясь сделать недействительным или используя setImageResource (с новым или нулевым), выдается «CalledFromWrongThreadException: только исходный поток, создавший иерархию представления, может касаться его видов», но не при рисовании на нулевой холст. В ответ я переместил этот вызов из потока openGL, хотя это работает в течение нескольких секунд, вскоре после прекращения обновления ImageView. Он находится в розыгрыше и до сих пор вызывается, так как счетчик, который я поместил туда, чтобы подтвердить, что он увеличивается, даже если дисплей не увеличивается. Если скрыть или скрыть наложение, оно снова заработает на несколько секунд.

Любая помощь будет принята с благодарностью. Если я на неправильном пути, пожалуйста, дайте мне знать. Моя альтернатива - сделать это в BMP, создать новую текстуру и нарисовать ее в квад, но я думаю, что это вызовет проблемы с тысячами текстур, созданных за минуту.

Заранее спасибо. -К

1 Ответ

1 голос
/ 11 октября 2011

Я не уверен, чего вы пытаетесь достичь - не было бы лучше, если бы оба рендеринга были сделаны с использованием OpenGL? Предполагая, что другого пути нет, я бы посоветовал создать FrameLayout и добавить к нему два вида (GLSurfaceView и ImageView). Если вам нужно изменить элементы пользовательского интерфейса, вы должны сделать это из потока пользовательского интерфейса, изменение элементов из потока GL вызовет ошибку; так что будьте уверены и сделайте любые изменения внутри runOnUiThread Runnable.

...