OpenGL 问答之 4 GLU
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
OpenGL FAQ / 4 GLU
What is GLU? How is it different from OpenGL?
如果你把 OpenGL 想做一个低层次的 3D 图形库的话,那么就可以认为 GLU 是增加一些 OpenGL 未提供的高层次的功能。GLU 的一些特性包括:
If you think of OpenGL as a low-level 3D graphics library, think of GLU as adding some higher-level functionality not provided by OpenGL. Some of GLU's features include:
- 2D 图像缩放以及 mipmap 增量的创建
Scaling of 2D images and creation of mipmap pyramids- 对象坐标向设备坐标转换,反之亦然
Transformation of object coordinates into device coordinates and vice versa- 支持样条曲面表线表面
Support for NURBS surfaces- 支持凹面的细分曲面圆角处理多边形交接处(理解翻译,有待确认)
Support for tessellation of concave or bow tie polygonal primitives- 专门的转换矩阵用于创建透视和正交投影,定位像机和选择/拾取
Specialty transformation matrices for creating perspective and orthographic projections, positioning a camera, and selection/picking- 渲染盘状物、圆柱体和球体
Rendering of disk, cylinder, and sphere primitives- 将 OpenGL 的错误值解释成 ASCII 码文本
Interpreting OpenGL error values as ASCII textGLU 的最佳信息源是 OpenGL 的红宝书和蓝宝书以及 GLU 规范,这些资料你可以从 OpenGL org 网站获取到。
The best source of information on GLU is the OpenGL red and blue books and the GLU specification, which you can obtain from the OpenGL org Web page.
4.020 GLU 如何渲染球体、柱体和盘状物?
How does GLU render sphere, cylinder, and disk primitives?
There is nothing special about how GLU generates these primitives. You can easily write routines that do what GLU does. You can also download the Mesa source, which contains a GLU distribution, and see what these routines are doing.
The GLU routines approximate the specified primitive using normal OpenGL primitives, such as quad strips and triangle fans. The surface is approximated according to user parameters. The vertices are generated using calls to the sinf() and cosf() math library functions.
If you are interested in rendering cylinders and tubes, you'll want to examine the GLE library. GLE comes as part of the GLUT distribution.
4.030 gluPickMatrix()是如何工作的?
How does gluPickMatrix() work?
It simply translates and scales so that the specified pick region fills the viewport. When specified on the projection matrix stack, prior to multiplying on a normal projection matrix (such as gluPerspective(), glFrustum(), glOrtho(), or gluOrtho2D()), the result is that the view volume is constrained to the pick region. This way only primitives that intersect the pick region will fall into the view volume. When glRenderMode() is set to GL_SELECT, these primitives will be returned.
4.040 如何使用 GLU 细分曲面程序?
How do I use GLU tessellation routines?
GLU provides tessellation routines to let you render concave polygons, self-intersecting polygons, and polygons with holes. The tessellation routines break these complex primitives up into (possibly groups of) simpler, convex primitives that can be rendered by the OpenGL API. This is done by providing the data of the simpler primitives to your application from callback routines that your application must provide. Your app can then send the data to OpenGL using normal API calls.
An example program is available in the GLUT distribution under progs/redbook/tess.c. (Download the GLUT distribution).
The usual steps for using tessellation routines are:
1. Allocate a new GLU tessellation object:
GLUtesselator *tess = gluNewTess();
2. Assign callbacks for use with this tessellation object:
gluTessCallback (tess, GLU_TESS_BEGIN, tcbBegin);gluTessCallback (tess, GLU_TESS_VERTEX, tcbVertex);gluTessCallback (tess, GLU_TESS_END, tcbEnd);
2a. If your primitive is self-intersecting, you must also specify a callback to create new vertices:
gluTessCallback (tess, GLU_TESS_COMBINE, tcbCombine);
3. Send the complex primitive data to GLU:
// Assumes:// GLdouble data[numVerts][3];// ...and assumes the array has been filled with 3D vertex data.gluTessBeginPolygon (tess, NULL);gluTessBeginContour (tess);for (i=0; i<sizeof(data)/(sizeof(GLdouble)*3);i++) gluTessVertex (tess, data[i], data[i]);gluTessEndContour (tess);gluEndPolygon (tess);
4. In your callback routines, make the appropriate OpenGL calls:
void tcbBegin (GLenum prim);{ glBegin (prim);}void tcbVertex (void *data){ glVertex3dv ((GLdouble *)data);}void tcbEnd ();{ glEnd ();}void tcbCombine (GLdouble c[3], void *d[4], GLfloat w[4], void **out){ GLdouble *nv = (GLdouble *) malloc(sizeof(GLdouble)*3); nv[0] = c[0]; nv[1] = c[1]; nv[2] = c[2]; *out = nv; }
The above list of steps and code segments is a bare-bones example and is not intended to demonstrate the full capabilities of the tessellation routines. By providing application-specific data as parameters to gluTessBeginPolygon() and gluTessVertex() and handling the data in the appropriate callback routines, your application can color and texture map these primitives as it would a normal OpenGL primitive.
4.050 为什么我的细分曲面回调函数未被调用?
Why aren't my tessellation callback routines called?
Normally your tessellation callback routines are executed when you call gluEndPolygon(). If they are not being called, an error has occurred. Typically this is caused when you haven't defined a GLU_TESS_COMBINE* callback for a self-intersecting primitive.
You might try defining a callback for GLU_TESS_ERROR to see if it's called.
4.060 怎样使用 GLU 样条曲线函数?
How do I use GLU NURBS routines?
The GLU NURBS interface converts the B-Spline basis control points into Bezier basis equivalents and calls directly to the OpenGL Evaluator routines to render the surface.
An example program is available in the GLUT distribution under progs/redbook/surface.c. (Download the GLUT distribution).
4.070 如何使用 gluProject() 和 gluUnProject() ?
How do I use gluProject() and gluUnProject()?
两个函数都带一个视图模型矩阵、投影矩阵和 OpenGL 视角作为参数。
Both routines take a ModelView matrix, Projection matrix, and OpenGL Viewport as parameters.gluProject() 还带一个 XYZ 对象空间坐标。它返回转换后对应的 XYZ 窗口或设备坐标
gluProject() also takes an XYZ-object space coordinate. It returns the transformed XYZ window (or device) coordinate equivalent.gluUnProject() 正好相反。它带一个 XYZ 窗口坐标,并返回一个往回转换对应的 XYZ 对象坐标。
gluUnProject() does the opposite. It takes an XYZ window coordinate and returns the back-transformed XYZ object coordinate equivalent.窗口空间 Z 的概念经常混淆。它是深度缓冲值,用 0.0 到 1.0 范围的 GLdouble 类型值表示。假定一个默认值 glDepthRange() ,一个窗口坐标带一个 0.0 的 Z 值相当于在近裁切面位置的眼睛坐标。同样地,一个窗口空间的 Z 坐标值是 1.0 就相当于眼睛空间坐标定位在了远裁切面。你可以获取任何窗口空间的 Z 坐标值,只要使用 glReadPixels() 读取深度缓冲即可。
The concept of window space Z is often confusing. It's the depth buffer value expressed as a GLdouble in the range 0.0 to 1.0. Assuming a default glDepthRange(), a window coordinate with a Z value of 0.0 corresponds to an eye coordinate located on the zNear clipping plane. Similarly, a window space Z value of 1.0 corresponds to an eye space coordinate located on the zFar plane. You can obtain any window space Z value by reading the depth buffer with glReadPixels().
费了不少功夫,查那些晦涩的词儿的意思,没太理解,感觉翻译出来的东西,没啥营养似的。
看来这个东西,俺是外行,只能看看热闹了。
有看懂的内行,帮指指门道吧,谢啦!