Почему мы должны использовать снимок только для GLSurfaceView в методе "onDrawFrame"?Иначе, это закончится черным пустым изображением - PullRequest
0 голосов
/ 20 мая 2018

В настоящее время я пытаюсь получить снимок от GLSurfaceView на Android.Мой метод здесь заключается в создании растрового изображения, которое показывает содержимое GLSurfaceView в реальном времени.Фактический алгоритм, который я использую:

Bitmap createBitmapFromView(int x, int y, int width, int height, GL10 gl) throws OutOfMemoryError{
    int buffer[] = new int[width * height];
    int source[] = new int[width * height];

    IntBuffer intBuffer = IntBuffer.wrap(buffer);
    intBuffer.position(0);

    try{
        gl.glReadPixels(x, y, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);

        int offset1, offset2;
        for(int i = 0; i < height; i++){
            offset1 = i * width;
            offset2 = (height - i - 1) * width;

            for(int j = 0; j < width; j++){
                int texturePixel = buffer[offset1 + j];

                int blue = (texturePixel >> 16) & 0xff;
                int red = (texturePixel << 16) & 0x00ff0000;
                int pixel = (texturePixel & 0xff00ff00) | red | blue;

                source[offset2 + j] = pixel;
            }
        }
    } catch(GLException e){
        return null;
    }

    return Bitmap.createBitmap(source, width, height, Bitmap.Config.ARGB_8888);
}

Однако, что касается использования этого метода, моя оригинальная идея состоит в том, чтобы создать класс, расширенный от GLSurfaceView, для создания нового экземпляра GL10 для отображения.Сразу после того, как поверхность была создана, я вызываю эту функцию выше в методе "onSurfaceCreated".Затем я обнаружил, что каждый снимок на данный момент полностью пустой в черном, и похоже, что данные изображения никогда не проходят через этот GLSurfaceView.

После нескольких других тестов с различными местами для использования алгоритма я случайно обнаружил, что только вы вызываете эту функцию внутри метода "onDrawFrame".Поэтому я просто установил логический флаг в рендерере GLSurfaceView, чтобы пометить, нужен ли нам сейчас снимок.Поскольку GLSurfaceView будет продолжать вызывать функцию «onDrawFrame» для обновления, всякий раз, когда флаг имеет значение true, я делаю снимок и устанавливаю флаг в значение false.Наконец-то это работает.

Таким образом, мой вопрос здесь: почему мы должны вызывать метод только для того, чтобы он работал в "onDrawFrame", а не в любом месте, которое может получить экземпляр GL10?Кто-нибудь знает, в чем разница между различными способами вызова метода моментального снимка?

...