glDrawPixels/glCopyPixels 获得放大视图,产生严重夹紧的图像
尽管之前有一个问题(此处提出),但我们的项目仅限于使用 glDrawPixels,因此我们有做一些黑客活动。
功能要求之一是能够在图像的单击区域上显示放大的视图; 因此,在查看图像时,我想单击鼠标,然后在鼠标所在的位置显示 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 框架,如果这很重要的话。
Despite an earlier question (asked here), our project is constrained to using glDrawPixels, so we have to do some hackery.
One of the feature requirements is to be able to have a magnified view show up on a clicked region of an image; so, looking at an image, I want to click the mouse, and have a 200% image window show up where the mouse is. As I drag my cursor, the window should follow the cursor.
The context is set up like:
The Big Red Book has code that looks like this:
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);
And then the call to make the smaller-but-zoomed image looks like
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);
where mStartY and mStartX are the points where the click happened.
Problem is, the window that shows up is really mangling the lookup tables, and really clamping the image down to essentially a black-and-white binary image (ie, no shades of grey).
The data is a black-and-white unsigned short array, and is set with this code:
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);
Now, according to this documentation, I should use GL_PIXEL_MAP_I_TO_I and set INDEX_SCALE and INDEX_BIAS to zero, but doing that does not change the result, that the image is severely clamped. And by 'severely clamped' I mean it's either black or white, with very few shades of grey, but the original non-magnified image looks like what's expected.
So, how do I avoid the clamping of the magnified view? Should I make a second control that follows the cursor and gets filled in with data from the first control? That approach seems like it would take the array copies outside of the graphics card and into C#, which would almost by definition be slower, and so make the control nonresponsive.
Oh, I'm using C# and the Tao framework, if that matters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
答案如下。 问题是 LUT 被应用了两次,因此在调用副本之前,调用:
然后,一旦完成,调用:
这样,我所描述的“极端钳位”就被删除了。
@thing2k - 您的解决方案导致复制发生在显卡外部,因此减慢了鼠标拖动的绘图速度,但没有修复双夹。
Here's the answer. The problem is that the LUT is being applied twice, so before calling the copy, call:
Then, once done, call:
That way, the 'extreme clamping' I was describing is removed.
@thing2k-- your solution causes the copy to happen outside the graphics card, so slows down the drawing on mouse drag, but doesn't fix the double clamp.
拜托,请在顶部和全身撒上大量的糖、糖蜜、糖粉和高果糖玉米糖浆,解释一下为什么你不能只使用纹理映射来绘制这个图像。
纹理映射是 OpenGL 的一个核心、基本、日常、常规、普通、标准、典型、预期且总体上不错的功能。 它的版本是1.4。 为什么不使用它作为起点呢?
Please, pretty please with loads of sugar, molasses, sprinkles and a mist of high-fructose corn syrup on top and all over, explain why you cannot just use texture-mapping to draw this imagery.
Texture-mapping is a core, basic, everyday, run of the mill, garden-variety, standard, typical, expected, and just generally nice feature of OpenGL. It is in version 1.4. Why not use it as a starting point?
如果我理解正确的话,那么这应该与您使用 glReadPixels 和 glDrawPixels 之后的内容接近。
抱歉,这是 C++ 而不是 C#,但 OpenGL 功能应该仍然相同。
希望这可以帮助。
If I understand you correctly then this should be close to what you after, using glReadPixels and glDrawPixels.
Sorry it's C++ not C# but the OpenGL function should still be the same.
Hope this helps.