Вопрос

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

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

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

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

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

        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);
        }
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top