【问题标题】:OpenGl 16 bit display via Tao/C#通过 Tao/C# 显示 OpenGL 16 位
【发布时间】:2010-10-05 05:44:53
【问题描述】:

我有一些科学图像数据,这些数据从检测器设备发出,范围为 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);
        }

【问题讨论】:

  • 也许不是......这是一个棘手的问题。你有没有用另一种语言尝试过这个,比如 C/C++ ?我不熟悉 C#,所以我不确定 C# opengl 库是否会成为问题。
  • 如何加载纹理? (带有 glTexImage 的行会有所帮助)
  • 是的,也是你设置像素格式的地方(如果这很重要 - 我之前没有在 OpenGL 中使用过 16 位)。

标签: c# opengl textures 16-bit tao-framework


【解决方案1】:

如果您创建纹理,则 glTexImage 的“类型”参数只是纹理数据在 OpenGL 将其转换为自己的格式之前所在的数据类型。要创建每通道 16 位的纹理,您需要 GL_LUMINANCE16 之类的格式(内部格式仍然是 GL_LUMINANCE)。如果 OpenGL 1.4 没有 GL_LUMINANCE16,请检查 GL_EXT_texture 是否可用,并尝试使用 GL_LUMINANCE16_EXT。

其中一个应该可以工作。但是,如果不是,您可以使用 GL_LUMINANCE_ALPHA 将您的 16 位值编码为两个 8 位对,然后在着色器中再次对其进行解码。

【讨论】:

  • 我不确定是否有任何 1.4 硬件支持着色器,甚至包括 ASM 的
  • 它确实支持着色器,这是正确的选择。它还支持没有扩展的 GL_LUMINANCE16。非常感谢!
【解决方案2】:

我从来没有在每通道 8 位以上(更深)的深度上工作过,但这是我首先要尝试的:

关闭纹理过滤,看看它如何影响输出。

将纹理 glHints 设置为最佳质量。

【讨论】:

    【解决方案3】:

    如果硬件支持,您可以考虑通过GL_ARB_texture_floatGL_ATI_texture_floatGL_NV_float_buffer 扩展之一使用单通道浮点纹理,但我不记得 GL 1.4 是否具有浮点纹理.

    【讨论】:

      猜你喜欢
      • 2017-03-17
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      相关资源
      最近更新 更多