经由道/ C#的OpenGL 16位显示
-
21-08-2019 - |
题
我有真实出来的检测器装置,其中然后获取的图像中呈现的一个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);
}
解决方案
如果您创建一个纹理glTexImage的“类型”参数仅仅是数据类型的纹理数据是在之前它是由OpenGL图像转换成自己的格式。要使用每通道16位,你需要像GL_LUMINANCE16为格式(内部格式保持GL_LUMINANCE)创建一个纹理。如果有对OpenGL 1.4检查没有GL_LUMINANCE16如果GL_EXT_texture可与GL_LUMINANCE16_EXT尝试。
其中的一个应该工作。但是,如果它不就可以编码您的16位值与GL_LUMINANCE_ALPHA两个8位对和着色器内再次对其进行解码。
其他提示
我从来没有在超过每通道8位深度较高(深)工作,但这里是我想尝试第一次:
关闭滤波上的纹理,看看它是如何影响输出。
设置纹理glHints到最好的质量。
您可以考虑使用单个信道浮点纹理通过GL_ARB_texture_float
,GL_ATI_texture_float
或GL_NV_float_buffer
扩展之一如果硬件支持它,我不记得如果GL 1.4具有浮点纹理与否虽然。