Question

J'ai des données d'image scientifiques qui sort d'un dispositif de détection dans une gamme de 16 bits qui est ensuite rendu dans une image. Pour afficher ces données, j'utilise OpenGL, car il devrait soutenir ushorts dans le cadre de la bibliothèque. J'ai réussi à obtenir ces données dans des textures de rendu sur une plate-forme OpenGL 1.4, une limitation qui est une exigence de ce projet.

Malheureusement, les textures résultantes ressemblent, ils sont réduits à 8 bits, au lieu de 16 bits. Je teste en générant une image de gradient et de l'afficher; tandis que l'image elle-même a chaque pixel différente de ses voisins, la texture affichée montre des motifs à bandes, où tous les pixels côté de l'autre sont montrant des valeurs comme égales.

Je l'ai essayé de le faire avec GlDrawPixels, et l'image résultante ressemble réellement il est rendu vraiment tous les 16 bits.

Comment puis-je forcer ces textures à afficher correctement?

Pour donner plus de fond, la LUT (Table LookUp) est déterminée par le code suivant:

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

Où cbias et CSCALE sont comprises entre 0 et 1.

Merci!

EDIT: Pour répondre à quelques-unes des autres questions, la ligne avec 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();

Le format de pixel est défini lorsque le contexte est initialisé:

        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);
        }
Était-ce utile?

La solution

Si vous créez une texture du paramètre « type » de glTexImage est que le type de données que vos données de texture est avant d'être converti par OpenGL dans son propre format. Pour créer une texture avec 16 bits par canal dont vous avez besoin quelque chose comme GL_LUMINANCE16 au format (format interne reste GL_LUMINANCE). S'il n'y a pas GL_LUMINANCE16 pour le contrôle OpenGL 1.4 si GL_EXT_texture est disponible et essayez avec GL_LUMINANCE16_EXT.

L'un d'entre eux devrait fonctionner. Toutefois, si cela ne vous pouvez encoder vos valeurs 16 bits en deux 8 paires de bits avec GL_LUMINANCE_ALPHA et le décoder à nouveau dans un shader.

Autres conseils

Je ne l'ai jamais travaillé à des profondeurs plus élevées (plus profondes) que 8bit par canal, mais voici ce que je vais essayer d'abord:

Désactiver le filtrage de la texture et de voir comment il affecte la sortie.

Set texturation glHints à la meilleure qualité.

Vous pouvez envisager d'utiliser une texture unique à virgule flottante canal à travers l'un des GL_ARB_texture_float, ou GL_ATI_texture_float extensions si le GL_NV_float_buffer matériel prend en charge, je ne me souviens pas si GL 1.4 a des textures en virgule flottante ou non si .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top