尽管有一个较早的问题(问here),但我们的项目仅限于使用glDrawPixels,因此我们必须做一些hackery。
功能要求之一是能够在图像的单击区域上显示放大视图;所以,看着图像,我想点击鼠标,并在鼠标所在的位置显示 200% 的图像窗口。当我拖动光标时,窗口应该跟随光标。
上下文设置如下:
大红皮书的代码如下所示:
Gl.glShadeModel(Gl.GL_FLAT);
Gl.glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 2);
Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_LINE);
Gl.glDisable(Gl.GL_SCISSOR_TEST);
Gl.glDisable(Gl.GL_ALPHA_TEST);
Gl.glDisable(Gl.GL_STENCIL_TEST);
Gl.glDisable(Gl.GL_DEPTH_TEST);
Gl.glDisable(Gl.GL_BLEND);
Gl.glDisable(Gl.GL_DITHER);
Gl.glDisable(Gl.GL_LOGIC_OP);
Gl.glDisable(Gl.GL_LIGHTING);
Gl.glDisable(Gl.GL_FOG);
Gl.glDisable(Gl.GL_TEXTURE_1D);
Gl.glDisable(Gl.GL_TEXTURE_2D);
Gl.glPixelTransferi(Gl.GL_MAP_COLOR, Gl.GL_TRUE);
Gl.glPixelTransferf(Gl.GL_RED_SCALE, 1.0f);
Gl.glPixelTransferi(Gl.GL_RED_BIAS, 0);
Gl.glPixelTransferf(Gl.GL_GREEN_SCALE, 1.0f);
Gl.glPixelTransferi(Gl.GL_GREEN_BIAS, 0);
Gl.glPixelTransferf(Gl.GL_BLUE_SCALE, 1.0f);
Gl.glPixelTransferi(Gl.GL_BLUE_BIAS, 0);
Gl.glPixelTransferi(Gl.GL_ALPHA_SCALE, 1);
Gl.glPixelTransferi(Gl.GL_ALPHA_BIAS, 0);
然后调用使较小但缩放的图像看起来像
int width = (int)((this.Width * 0.2)/2.0);
Gl.glReadBuffer(Gl.GL_FRONT_AND_BACK);
Gl.glRasterPos2i(0, 0);
Gl.glBitmap(0, 0, 0, 0, mStartX - (width*2), mStartY, null);
Gl.glPixelZoom(2.0f, 2.0f);
Gl.glCopyPixels(mStartX - width, mStartY, width, width, Gl.GL_COLOR);
其中 mStartY 和 mStartX 是点击发生的点。
问题是,显示的窗口实际上是在破坏查找表,并且实际上将图像压缩到本质上是黑白二值图像(即,没有灰色阴影)。
数据是一个黑白无符号短数组,并使用以下代码设置:
float step = (65535.0f / (float)(max - min));
mColorTable = new ushort[65536];
int i;
for (i = 0; i < 65536; i++)
{
if (i < min)
mColorTable[i] = 0;
else if (i > max)
mColorTable[i] = 65535;
else
mColorTable[i] = (ushort)((float)(i - min) * step);
}
.... //some irrelevant code
Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_R_TO_R, 65536, mColorTable);
Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_G_TO_G, 65536, mColorTable);
Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_B_TO_B, 65536, mColorTable);
现在,根据这个文档,我应该使用 GL_PIXEL_MAP_I_TO_I 并将 INDEX_SCALE 和 INDEX_BIAS 设置为零,但这样做不会改变结果,即图像被严重钳位。所谓“严重钳制”,我的意思是它不是黑色就是白色,只有很少的灰色阴影,但原始未放大的图像看起来像预期的那样。
那么,如何避免放大视图的钳位呢?我应该创建一个跟随光标并用第一个控件的数据填充的第二个控件吗?这种方法似乎会将数组副本从图形卡带到 C# 中,这几乎按照定义会变慢,因此使控件无响应。
哦,我正在使用 C# 和 Tao 框架,如果这很重要的话。