Pregunta

Tengo algunos datos de imágenes científicas que va a salir de un dispositivo detector en un rango de 16 bits que luego se hizo en una imagen. Con el fin de mostrar estos datos, estoy usando OpenGL, ya que debe soportar ushorts como parte de la biblioteca. Me las he arreglado para obtener estos datos en representación texturas en una plataforma de 1.4 OpenGL, una limitación que es un requisito de este proyecto.

Por desgracia, las texturas resultantes se ven como que están siendo reducidos a 8 bits, en lugar de 16 bits. I probar esta mediante la generación de una imagen de gradiente y la visualización de ella; mientras que la imagen en sí tiene cada píxel diferente de sus vecinos, la textura que se muestra está mostrando patrones de rayas en donde todos los píxeles de una al lado de otra están apareciendo como valores iguales.

He intentado hacer esto con GlDrawPixels, y la imagen resultante en realidad parece que está realmente haciendo todos los 16 bits.

¿Cómo puedo forzar estas texturas para mostrar correctamente?

Para dar más antecedentes, el LUT (tabla de búsqueda) se determina por el código siguiente:

        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);

Donde cbias y CSCALE están entre 0 y 1.

Gracias!

EDIT: Para responder a algunas de las otras preguntas, la línea con 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();

El formato de píxel se establece cuando se inicializa el contexto:

        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);
        }
¿Fue útil?

Solución

Si crea una textura el parámetro 'tipo' de glTexImage es sólo el tipo de datos los datos de textura es de antes de que se convierte mediante OpenGL en su propio formato. Para crear una textura con 16 bits por canal se necesita algo así como GL_LUMINANCE16 como el formato (formato interno permanece GL_LUMINANCE). Si no hay GL_LUMINANCE16 para OpenGL 1.4 de verificación si GL_EXT_texture está disponible y tratar con GL_LUMINANCE16_EXT.

Uno de ellos debería funcionar. Sin embargo si no se puede codificar sus valores de 16 bits como dos pares de 8 bits con GL_LUMINANCE_ALPHA y decodificar de nuevo dentro de un shader.

Otros consejos

Nunca he trabajado en profundidades mayores (más profundas) que 8 bits por canal, pero esto es lo que me gustaría probar primero:

Desactivar el filtrado de la textura y ver cómo afecta a la salida.

glHints Conjunto de texturizado a mejor calidad.

Se podría considerar el uso de un único canal de punto flotante a través de la textura uno de los GL_ARB_texture_float, GL_ATI_texture_float o GL_NV_float_buffer extensiones si el hardware lo soporta, no puedo recordar si GL 1.4 tiene texturas de punto flotante o no, aunque .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top