Как визуализировать GL_SHORT в Java (Endian)? - PullRequest
0 голосов
/ 21 февраля 2019

Я использую com.jogamp.opengl.GL2 для рендеринга 3d-текстуры шорт за пределами экрана, а затем разрешаю результаты с помощью glReadPixels.Когда мои значения 3d-текстуры все положительные, я ожидаю получить результаты.Но когда у меня отрицательные значения, я не могу понять, как настроить opengl для получения правильных результатов.Я пробовал glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 1); и glPixelStorei(GL2.GL_UNPACK_SWAP_BYTES, 1);.Я перепробовал все 4 комбинации GL_PACK / UNPACK_SWAP_BYTES и все результаты неверны.

Данные охватывают диапазон от -1024 до +1024 (или около этого диапазона), поэтому в качестве альтернативы я нормализую и денормализую после (+4096 затем -4096 для хорошей меры).Это дает мне правильные результаты, но это кажется действительно хакерским.Есть ли правильный способ отрисовки и разрешения 16-битного подписанного через Java?

Вот основной код:

    private int upload3DTexture(GL2 gl2, ShortBuffer data) 
    {

        int texName[] = new int[1];
        gl2.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 2);
        gl2.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 2);
        gl2.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 1);
        gl2.glPixelStorei(GL2.GL_UNPACK_SWAP_BYTES, 1);
        gl2.glGenTextures(1, texName, 0);
        gl2.glEnable(GL2.GL_TEXTURE_3D);        
        gl2.glBindTexture(GL2.GL_TEXTURE_3D, texName[0]);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_R, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl2.glTexEnvi(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
        ((java.nio.Buffer)data).rewind();
        gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2.GL_R16, nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);

        return texName[0];
    }

    private int upload3DTexture(GL2 gl2, ShortBuffer data) 
    {

        int texName[] = new int[1];
        gl2.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 2);
        gl2.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 2);
        gl2.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 1);
        gl2.glPixelStorei(GL2.GL_UNPACK_SWAP_BYTES, 1);
        gl2.glGenTextures(1, texName, 0);
        gl2.glEnable(GL2.GL_TEXTURE_3D);        
        gl2.glBindTexture(GL2.GL_TEXTURE_3D, texName[0]);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_WRAP_R, GL2.GL_CLAMP_TO_BORDER);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl2.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl2.glTexEnvi(GL2.GL_TEXTURE_3D, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
        ((java.nio.Buffer)data).rewind();
        gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2.GL_R16, nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);

        return texName[0];
    }


    private short[] renderAndResolve() {
        short[] volume= new short[64];
        short index = 0;
        for (int z = 0; z < 4; z++) {
            for (int y = 0; y < 4; y++) {
                for (int x = 0; x < 4; x++) {
                    volume[index] = (short)(-100*z + y);
                    index++;
                }
            }
        }
        ShortBuffer shortBuffer = ShortBuffer.wrap(volume);
        texID = upload3DTexture(gl2, shortBuffer);

        display();
        ShortBuffer resultBuffer = ShortBuffer.allocate(nSlices * nRows);
        resolve(resultBuffer, 4, 4);
        return resolve.array();
    }

    private void resolveDisplay(ShortBuffer slice, int  w, int h)
    {
        GL2 gl2 = drawable.getGL().getGL2(); // The object that contains all the OpenGL methods.

        fbo.bind(gl2);
        gl2.glReadBuffer(GL2.GL_COLOR_ATTACHMENT0);
        ((java.nio.Buffer)slice).rewind();
        int xd = (frameWidth  - w)/2;
        int yd = (frameHeight - h)/2;
        gl2.glReadPixels(xd, yd, w, h, GL2.GL_RED, GL2.GL_SHORT, slice);
        fbo.unbind(gl2);
        ((java.nio.Buffer)slice).rewind();
    }

1 Ответ

0 голосов
/ 21 февраля 2019

проблема вызвана внутренним форматом текстуры.

gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2.GL_R16,
                 nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);

Внутренний формат GL_R16 для хранилища данных изображения текстуры не является опаленным форматом,но это 16-битный формат без знака.

Я не знаю, какую версию OpenGL вы используете.

Рабочий стол OpenGL предоставляет внутренний формат данных GL_R16_SNORM, представляющий собой 16-битный целочисленный формат данных со знаком - см. glTexImage3D.
GL_R16_SNORM isреализован в интерфейсе GL2GL3:

 gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2GL3.GL_R16_SNORM,
                  nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);

OpenGL ES (3.0) обеспечивает единый 8-битный формат с единым целым GL_R8_SNORM.
GL_R8_SNORM реализован интерфейс GL2ES3:

 gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2ES3.GL_R8_SNORM,
                  nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);

В качестве альтернативы для настольных компьютеров OpenGL и OpenGL ES предусмотрен формат 16 с плавающей запятой:

например

gl2.glTexImage3D(GL2.GL_TEXTURE_3D, 0, GL2.GL_R16F,
                 nCols, nRows, nSlices, 0, GL2.GL_RED, GL.GL_SHORT, data);
...