Pergunta

Eu tenho alguns dados de imagem científicas que está saindo de um dispositivo detector em uma faixa de 16 bits que então é renderizado em uma imagem. Para exibir esses dados, eu estou usando OpenGL, porque ele deve apoiar ushorts como parte da biblioteca. Eu consegui obter esses dados em texturas de renderização em um 1,4 plataforma OpenGL, uma limitação que é uma exigência do projeto.

Infelizmente, as texturas resultantes parecem que estão sendo reduzida para 8 bits, em vez de 16 bits. I testar esta através da geração de uma imagem de gradiente e exibi-lo; enquanto a própria imagem tem cada pixel diferente de seus vizinhos, a textura exibida está mostrando padrões de listras, onde todos os pixels ao lado do outro estão aparecendo como valores iguais.

Eu tentei fazer isso com glDrawPixels, ea imagem resultante, na verdade, parece que está realmente prestando todos os 16 bits.

Como posso forçar essas texturas para exibir corretamente?

Para dar mais fundo, a LUT (consulta à tabela) está a ser determinada pelo seguinte código:

        String str = "!!ARBfp1.0\n" +
            "ATTRIB tex = fragment.texcoord[0];\n" +
            "PARAM cbias = program.local[0];\n" +
            "PARAM cscale = program.local[1];\n" +
            "OUTPUT cout = result.color;\n" +

            "TEMP tmp;\n" +
            "TXP tmp, tex, texture[0], 2D;\n" +
            "SUB tmp, tmp, cbias;\n" +
            "MUL cout, tmp, cscale;\n" +
            "END";

        Gl.glEnable(Gl.GL_FRAGMENT_PROGRAM_ARB);
        Gl.glGenProgramsARB(1, out mFragProg);
        Gl.glBindProgramARB(Gl.GL_FRAGMENT_PROGRAM_ARB, mFragProg);

        System.Text.Encoding ascii = System.Text.Encoding.ASCII;
        Byte[] encodedBytes = ascii.GetBytes(str);
        Gl.glProgramStringARB(Gl.GL_FRAGMENT_PROGRAM_ARB, Gl.GL_PROGRAM_FORMAT_ASCII_ARB, 
            count, encodedBytes);

        GetGLError("Shader");
        Gl.glDisable(Gl.GL_FRAGMENT_PROGRAM_ARB);

Onde cbias e CSCALE estão entre 0 e 1.

Obrigado!

EDIT: Para responder a algumas das outras questões, a linha com glTexImage:

        Gl.glBindTexture(Gl.GL_TEXTURE_2D, inTexData.TexName);

        Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_LUMINANCE, inTexData.TexWidth, inTexData.TexHeight,
            0, Gl.GL_LUMINANCE, Gl.GL_UNSIGNED_SHORT, theTexBuffer);

        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);   // Linear Filtering
        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);   // Linear Filtering

        theTexBuffer = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();

O formato de pixel é definido quando o contexto é inicializado:

        Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();// The pixel format descriptor
        pfd.nSize = (short)Marshal.SizeOf(pfd);                        // Size of the pixel format descriptor
        pfd.nVersion = 1;                                               // Version number (always 1)
        pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW |                          // Format must support windowed mode
                    Gdi.PFD_SUPPORT_OPENGL |                            // Format must support OpenGL
                    Gdi.PFD_DOUBLEBUFFER;                               // Must support double buffering
        pfd.iPixelType = (byte)Gdi.PFD_TYPE_RGBA;                      // Request an RGBA format
        pfd.cColorBits = (byte)colorBits;                              // Select our color depth
        pfd.cRedBits = 0;                                               // Individual color bits ignored
        pfd.cRedShift = 0;
        pfd.cGreenBits = 0;
        pfd.cGreenShift = 0;
        pfd.cBlueBits = 0;
        pfd.cBlueShift = 0;
        pfd.cAlphaBits = 0;                                             // No alpha buffer
        pfd.cAlphaShift = 0;                                            // Alpha shift bit ignored
        pfd.cAccumBits = 0;                                     // Accumulation buffer
        pfd.cAccumRedBits = 0;                                          // Individual accumulation bits ignored
        pfd.cAccumGreenBits = 0;
        pfd.cAccumBlueBits = 0;
        pfd.cAccumAlphaBits = 0;
        pfd.cDepthBits = 16;                                     // Z-buffer (depth buffer)
        pfd.cStencilBits = 0;                                 // No stencil buffer
        pfd.cAuxBuffers = 0;                                            // No auxiliary buffer
        pfd.iLayerType = (byte)Gdi.PFD_MAIN_PLANE;                     // Main drawing layer
        pfd.bReserved = 0;                                              // Reserved
        pfd.dwLayerMask = 0;                                            // Layer masks ignored
        pfd.dwVisibleMask = 0;
        pfd.dwDamageMask = 0;

        pixelFormat = Gdi.ChoosePixelFormat(mDC, ref pfd);    // Attempt to find an appropriate pixel format

        if (!Gdi.SetPixelFormat(mDC, pixelFormat, ref pfd))
        {  // Are we not able to set the pixel format?
            BigMessageBox.ShowMessage("Can not set the chosen PixelFormat.  Chosen PixelFormat was " + pixelFormat + ".");
            Environment.Exit(-1);
        }
Foi útil?

Solução

Se você criar uma textura do parâmetro 'tipo' de glTexImage é apenas os dados digite seus dados de textura está em antes de ser convertido por OpenGL em seu próprio formato. Para criar uma textura com 16 bits por canal que você precisa de algo como GL_LUMINANCE16 como o formato (formato interno restos GL_LUMINANCE). Se não houver GL_LUMINANCE16 para OpenGL 1.4 seleção se GL_EXT_texture está disponível e experimentá-lo com GL_LUMINANCE16_EXT.

Um destes deve funcionar. No entanto, se não você pode codificar seus valores de 16 bits como dois pares 8 bits com GL_LUMINANCE_ALPHA e decodificá-lo novamente dentro de um shader.

Outras dicas

Eu nunca trabalhei em profundidades maiores (mais profunda) do que 8 bits por canal, mas aqui está o que eu tentaria primeiro:

Desligue a filtragem da textura e ver como isso afeta a saída.

Definir texturização glHints a melhor qualidade.

Você poderia considerar o uso de um único canal de textura de ponto flutuante através de um dos GL_ARB_texture_float, GL_ATI_texture_float ou GL_NV_float_buffer extensões se os suportes de hardware de TI, não me lembro se GL 1.4 tem texturas de ponto flutuante ou não embora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top