2009-02-03 6 views
2

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

К сожалению, полученные текстуры выглядят так, будто они уменьшены до 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.

Спасибо!

EDIT: Для того, чтобы ответить на некоторые другие вопросы, линия с 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); 
     } 
+0

, возможно, нет ... это сложный вопрос. Вы пробовали это на другом языке, например C/C++? Я не знаком с C#, поэтому я не уверен, что проблема с библиотекой C# opengl была бы проблемой или нет. – cbrulak

+0

Как вы загружаете текстуру? (линия с glTexImage была бы полезна) –

+0

Да, также там, где вы устанавливаете формат пикселей (если это имеет значение - я havent работал с 16 бит в OpenGL раньше). – geofftnz

ответ

1

Если вы создаете текстуру, параметр '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

Я не уверен, что какое-либо 1,4-аппаратное обеспечение поддерживает шейдеры, даже ASM. – Branan

+0

Посмотрите на вопрос еще раз, есть шейдер ....поэтому я предполагаю, что так оно и есть. –

+0

он действительно поддерживает шейдеры, и это был правильный звонок. Он также поддерживает GL_LUMINANCE16 без расширения. Большое спасибо! – mmr

0

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

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

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

0

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