OpenGL 16 bit vertoon via Tao / C #
-
21-08-2019 - |
Vra
Ek het 'n paar wetenskaplike beeld data wat uit 'n detector toestel kom in 'n 16 bit reeks wat dan kry gelewer in 'n beeld. Ten einde hierdie data voor te stel, ek met behulp van OpenGL, want dit ushorts moet ondersteun as deel van die biblioteek. Ek het daarin geslaag om hierdie data in teksture lewering op 'n OpenGL 1.4 platform, 'n beperking wat is 'n vereiste van hierdie projek kry.
Ongelukkig is die gevolg teksture kyk soos hulle is verminder tot 8 stukkies, eerder as 16 stukkies. Ek toets dit deur beeld 'n helling genereer en vertoon dit; terwyl die beeld self het elke pixel anders as sy bure, is die vertoon tekstuur vertoon streep patrone waar al pixels langs mekaar is vertoon as gelyke waardes.
Ek het probeer om dit te doen met GlDrawPixels, en die gevolglike beeld eintlik lyk soos dit is regtig die lewering van al 16 stukkies.
Hoe kan ek dwing hierdie teksture om goed te vertoon?
Vir meer agtergrond gee, die LUT (lookup tabel) word bepaal deur die volgende kode:
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);
Waar cbias en cScale is tussen 0 en 1.
Dankie!
EDIT: Om 'n paar van die ander vrae te beantwoord, die lyn met 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();
Die pixel formaat is ingestel toe die konteks is geïnisialiseer:
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);
}
Oplossing
As jy 'n tekstuur die 'tipe' parameter van glTexImage is net die data tik jou tekstuur data is in voor dit omgeskakel word deur OpenGL in sy eie formaat te skep. 'N tekstuur te skep met 16 bit per kanaal jy iets soos GL_LUMINANCE16 as formaat (interne formaat bly GL_LUMINANCE) nodig. As daar is geen GL_LUMINANCE16 vir OpenGL 1.4 tjek as GL_EXT_texture is beskikbaar en probeer dit met GL_LUMINANCE16_EXT.
Een van hierdie behoort te werk. Maar as dit nie jy kan jou 16 bit waardes enkodeer as twee 8 bit pare met GL_LUMINANCE_ALPHA en dekodeer dit weer binne 'n shader.
Ander wenke
Ek het nog nooit gewerk het in diepte hoër (dieper) as 8bit per kanaal, maar hier is wat ek die eerste keer wil probeer:
Skakel die filter op die tekstuur en sien hoe dit die uitset raak.
Stel texturing glHints om die beste gehalte.
Jy kan oorweeg om 'n enkele kanaal drywende punt tekstuur deur middel van een van die GL_ARB_texture_float
, GL_ATI_texture_float
of GL_NV_float_buffer
uitbreidings as die hardeware ondersteun dit, kan ek nie onthou as GL 1.4 het drywende punt teksture of nie al is.