16-битный дисплей OpenGl через Tao / C # - PullRequest
2 голосов
/ 03 февраля 2009

У меня есть некоторые научные данные изображения, которые поступают с детекторного устройства в 16-битном диапазоне, который затем отображается на изображении. Для отображения этих данных я использую OpenGL, потому что он должен поддерживать ushorts как часть библиотеки. Мне удалось перенести эти данные в рендеринг текстур на платформе OpenGL 1.4, что является требованием этого проекта.

К сожалению, полученные текстуры выглядят так, как будто они уменьшены до 8 бит, а не до 16 бит. Я проверяю это, генерируя градиентное изображение и отображая его; в то время как само изображение имеет каждый пиксель, отличный от своих соседей, отображаемая текстура показывает узоры в виде полос, где все пиксели рядом друг с другом отображаются как равные значения.

Я попытался сделать это с GlDrawPixels, и полученное изображение на самом деле выглядит так, как будто оно действительно отображает все 16 бит.

Как заставить эти текстуры правильно отображаться?

Чтобы дать больше фона, LUT (LookUp Table) определяется следующим кодом:

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

Где cbias и cScale находятся между 0 и 1.

Спасибо!

РЕДАКТИРОВАТЬ: Чтобы ответить на некоторые другие вопросы, строка с 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();

Формат пикселя устанавливается при инициализации контекста:

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

Ответы [ 3 ]

1 голос
/ 04 февраля 2009

Если вы создаете текстуру, параметр 'type' в glTexImage является только тем типом данных, в котором находятся данные текстуры, прежде чем они будут преобразованы OpenGL в свой собственный формат. Чтобы создать текстуру с 16 битами на канал, вам нужно что-то вроде GL_LUMINANCE16 в качестве формата (внутренний формат остается GL_LUMINANCE). Если нет GL_LUMINANCE16 для OpenGL 1.4, проверьте, доступен ли GL_EXT_texture, и попробуйте его с GL_LUMINANCE16_EXT.

Один из них должен работать. Однако, если это не так, вы можете закодировать свои 16-битные значения как две 8-битные пары с помощью GL_LUMINANCE_ALPHA и снова декодировать их в шейдере.

0 голосов
/ 04 февраля 2009

Вы можете рассмотреть возможность использования одноканальной текстуры с плавающей запятой через одно из расширений GL_ARB_texture_float, GL_ATI_texture_float или GL_NV_float_buffer, если оборудование поддерживает это, я не могу вспомнить, имеет ли GL 1.4 текстуры с плавающей запятой или нет, хотя .

0 голосов
/ 04 февраля 2009

Я никогда не работал на глубине выше (глубже), чем 8 бит на канал, но вот что я попробую сначала:

Отключите фильтрацию текстуры и посмотрите, как она влияет на вывод.

Установите текстуры glHints на лучшее качество.

...