OpenGL如何在平面上显示网格线
我要显示多个平面以及在这多个平面上面的网格线, 现在显示出来的效果是有时某个平面会盖住了部分的在这个平面上的网格线, 或者某条网格线的部分. 覆盖的情况随角度不同而有所变化.
网格线是用GL_LINE_SMOOTH画的, 深度测试是GL_LESS,
如果把LineWidth变宽, 网格线可能会显示得更多一些.但这样并不好看.
因为平面要从多个方面进行观察, 所以不能采用把网格线画得离开平面一点的做法.
有没有办法使得无论观察角度怎么变化, 都能显示出连续和完整的网格线? 做到轮廓鲜明?
各位可有较好的方法?
问题点数:57、回复次数:5Top
1 楼chenlee()回复于 2001-07-26 01:19:35 得分 57
使用glPolygonOffset()
1)先以正常的方式画平面
2)glEnable(GL_POLYGON_OFFSET_LINE); // 打开polygon offset功能
3)glPolygonOffset(factor, units); // 设置polygon offset的参数
// 参数的具体含义查查msdn就知道了
// 先试试(0, -1)
4)画网格线
5)glDisable(GL_POLYGON_OFFSET_LINE);// 关闭polygon offset功能Top
2 楼c_z_y(用力)回复于 2001-07-26 09:20:58 得分 0
顶楼的实际上是遇到了Z抖动的情况,也就是说由于zbuff有位数限制,所以精度丢失,造成上面情况。chenlee(faint) 的办法很好。
如果是我,我会想另外的办法,能不能用纹理的办法,事先画好网格作为纹理,贴到上面去?Top
3 楼chenlee()回复于 2001-07-26 10:34:46 得分 0
用贴图也行。
不过有个问题,当视点离平面很近的时候,网格线就会显得很模糊。Top
4 楼c_z_y(用力)回复于 2001-07-26 11:50:52 得分 0
嗯!说的也是!Top
5 楼gauss(Powered-by-Internet)回复于 2001-07-30 00:08:59 得分 0
谢谢chenlee宝贵的建议,这几天我上网再查了一下相关的东西,终于得到了较好的解决,
我采用了把平面向深移和线向浅移两者结合的方法,使得网格线被覆盖的概率少了很多,
但是,在画大幅的场景的时候,如果不把线宽调大,还是会有被覆盖的现象。
还有一个问题,就是那个位移公式中的r是什么值,如何获取或者改变?所有的OpenGL文档都是语焉不详,有谁知道?
另外,Unit值的改变好像要幅度很大才有作用,我画的一个10000单位左右的场景,Unit要设成-1000才有一点作用,在超出-1000之后无论怎么变化都是没有用了,这是什么回事?
下面是一篇专门将这个的文章,解决这个问题还有其他的方法的。
也谢谢c_z_y的参与。
13 Drawing Lines over Polygons and Using Polygon Offset
13.010 What are the basics for using polygon offset?
It's difficult to render coplanar primitives in OpenGL for two reasons:
Given two overlapping coplanar primitives with different vertices, floating point round-off errors from the two polygons can generate different depth values for overlapping pixels. With depth test enabled, some of the second polygon's pixels will pass the depth test, while some will fail.
For coplanar lines and polygons, vastly different depth values for common pixels can result. This is because depth values from polygon rasterization derive from the polygon's plane equation, while depth values from line rasterization derive from linear interpolation.
Setting the depth function to GL_LEQUAL or GL_EQUAL won't resolve the problem. The visual result is referred to as stitching, bleeding, or Z fighting.
Polygon offset was an extension to OpenGL 1.0, and is now incorporated into OpenGL 1.1. It allows an application to define a depth offset, which can apply to filled primitives, and under OpenGL 1.1, it can be separately enabled or disabled depending on whether the primitives are rendered in fill, line, or point mode. Thus, an application can render coplanar primitives by first rendering one primitive, then by applying an offset and rendering the second primitive.
While polygon offset can alter the depth value of filled primitives in point and line mode, under no circumstances will polygon offset affect the depth values of GL_POINTS, GL_LINES, GL_LINE_STRIP, or GL_LINE_LOOP primitives. If you are trying to render point or line primitives over filled primitives, use polygon offset to push the filled primitives back. (It can't be used to pull the point and line primitives forward.)
Because polygon offset alters the correct Z value calculated during rasterization, the resulting Z value, which is stored in the depth buffer will contain this offset and can adversely affect the resulting image. In many circumstances, undesirable "bleed-through" effects can result. Indeed, polygon offset may cause some primitives to pass the depth test entirely when they normally would not, or vice versa. When models intersect, polygon offset can cause an inaccurate rendering of the intersection point.
13.020 What are the two parameters in a glPolygonOffset() call and what do they mean?
Polygon offset allows the application to specify a depth offset with two parameters, factor and units. factor scales the maximum Z slope, with respect to X or Y of the polygon, and units scales the minimum resolvable depth buffer value. The results are summed to produce the depth offset. This offset is applied in screen space, typically with positive Z pointing into the screen.
The factor parameter is required to ensure correct results for filled primitives that are nearly edge-on to the viewer. In this case, the difference between Z values for the same pixel generated by two coplanar primitives can be as great as the maximum Z slope in X or Y. This Z slope will be large for nearly edge-on primitives, and almost non-existent for face-on primitives. The factor parameter lets you add this type of variable difference into the resulting depth offset.
A typical use might be to set factor and units to 1.0 to offset primitives into positive Z (into the screen) and enable polygon offset for fill mode. Two passes are then made, once with the model's solid geometry and once again with the line geometry. Nearly edge-on filled polygons are pushed substantially away from the eyepoint, to minimize interference with the line geometry, while nearly planar polygons are drawn at least one depth buffer unit behind the line geometry.
13.030 What's the difference between the OpenGL 1.0 polygon offset extension and OpenGL 1.1 (and later) polygon offset interfaces?
The 1.0 polygon offset extension didn't let you apply the offset to filled primitives in line or point mode. Only filled primitives in fill mode could be offset.
In the 1.0 extension, a bias parameter was added to the normalized (0.0 - 1.0) depth value, in place of the 1.1 units parameter. Typical applications might obtain a good offset by specifying a bias of 0.001.
See the GLUT example, which renders two cylinders, one using the 1.0 polygon offset extension and the other using the 1.1 polygon offset interface.
13.040 Why doesn't polygon offset work when I draw line primitives over filled primitives?
Polygon offset, as its name implies, only works with polygonal primitives. It affects only the filled primitives: GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, and GL_POLYGON. Polygon offset will work when you render them with glPolygonMode set to GL_FILL, GL_LINE, or GL_POINT.
Polygon offset doesn't affect non-polygonal primitives. The GL_POINTS, GL_LINES, GL_LINE_STRIP, and GL_LINE_LOOP primitives can't be offset with glPolygonOffset().
13.050 What other options do I have for drawing coplanar primitives when I don't want to use polygon offset?
You can simulate the effects of polygon offset by tinkering with glDepthRange(). For example, you might code the following:
glDepthRange (0.1, 1.0);
/* Draw underlying geometry */
glDepthRange (0.0, 0.9);
/* Draw overlying geometry */
This code provides a fixed offset in Z, but doesn't account for the polygon slope. It's roughly equivalent to using glPolygonOffset with a factor parameter of 0.0.
You can render coplanar primitives with the Stencil buffer in many creative ways. The OpenGL Programming Guide outlines one well-know method. The algorithm for drawing a polygon and its outline is as follows:
Draw the outline into the color, depth, and stencil buffers.
Draw the filled primitive into the color buffer and depth buffer, but only where the stencil buffer is clear.
Mask off the color and depth buffers, and render the outline to clear the stencil buffer.
On some SGI OpenGL platforms, an application can use the SGIX_reference_plane extension. With this extension, the user specifies a plane equation in object coordinates corresponding to a set of coplanar primitives. You can enable or disable the plane. When the plane is enabled, all fragment Z values will derive from the specified plane equation. Thus, for any given fragment XY location, the depth value is guaranteed to be identical regardless of which primitive rendered it.
Top




