Domanda

Ho alcuni dati dell'immagine scientifici che sta venendo fuori da un dispositivo rilevatore in una gamma a 16 bit che poi viene reso in un'immagine. Per visualizzare questi dati, sto usando OpenGL, perché dovrebbe sostenere ushorts come parte della libreria. Sono riuscito a ottenere questi dati in trame di rendering su una piattaforma di 1,4 OpenGL, una limitazione che è un requisito di questo progetto.

Purtroppo, le texture risultanti sembrano stanno venendo ridotte a 8 bit, piuttosto che 16 bit. I test questa immagine generando un gradiente e la visualizzazione; mentre l'immagine stessa ha ogni pixel diverso dai suoi vicini, la struttura mostrata mostra modelli di striscia dove tutti i pixel affiancati vengono visualizzati come valori uguali.

Ho provato a fare questo con GlDrawPixels, e l'immagine risultante in realtà sembra che sia davvero il rendering tutti i 16 bit.

Come posso forzare queste texture per visualizzare correttamente?

Per dare più di fondo, la LUT (LookUp Table) è determinato dalla seguente codice:

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

Dove cbias e CSCALE sono compresi tra 0 e 1.

Grazie!

EDIT: Per rispondere ad alcune delle altre domande, la linea 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();

Il formato di pixel è impostata quando il contesto è inizializzato:

        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);
        }
È stato utile?

Soluzione

Se si crea una texture il parametro 'tipo' di glTexImage è digitare i dati i dati la struttura è in prima di essere convertito da OpenGL nel proprio formato. Per creare una texture a 16 bit per canale è necessario qualcosa come GL_LUMINANCE16 come formato (formato interno rimane GL_LUMINANCE). Se non c'è GL_LUMINANCE16 per OpenGL 1.4 controllo se GL_EXT_texture è disponibile e provare con GL_LUMINANCE16_EXT.

Una di queste dovrebbe funzionare. Tuttavia, se non è possibile codificare i valori a 16 bit come due coppie 8 bit con GL_LUMINANCE_ALPHA e decodificare di nuovo all'interno di uno shader.

Altri suggerimenti

Non ho mai lavorato in profondità maggiore (profondi) rispetto 8bit per canale, ma ecco cosa mi piacerebbe provare prima:

Spegnere il filtraggio sulla texture e vedere come influisce l'uscita.

glHints Set texturing per la migliore qualità.

Si potrebbe considerare l'utilizzo di un solo canale in virgola mobile tessitura attraverso uno dei GL_ARB_texture_float, GL_ATI_texture_float o GL_NV_float_buffer estensioni se l'hardware lo supporta, non riesco a ricordare se GL 1.4 ha le texture in virgola mobile o no però .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top