这几天在看《OpenGL编程指南》,收获很大。 不仅揭示了绘图的理论,提供的样例代码也非常值得学习。
今天看到 点画多边形,在解释 glPolygonStipple(CONST GLubyte *mask) 函数时,书中说:“mask参数是一个指向32x32位图的指针,后者为解释为0和1的掩码。如果模式中出现的是1,多边形对应像素就会被绘制。否则不绘制。”
可提供的绘图结果让我难以理解其原理。
经过多次尝试后,终于发现其原理:
先设定打开点画多边形模式:glEnable(GL_POLYGON_STIPPLE);
用glPolygonStipple(CONST GLubyte *mask)设定要绘制的图形。
最后不用时要关闭:glDisable(GL_POLYGON_STIPPLE);
绘制时从多边形会从(0,0)开始绘制,每一个是 32x32 =1024像素,从左到右,从上至下绘制。每一行是32个像素,对应mask指向的数组里4个 16进制的数。 如那个昆虫所示: 从左下角开始绘制:由于 fly 数组第一行全为零,说明昆虫最下面两行像素不被绘制。 直到数组第二行开始出现 0x03,对应的二进制数是 0000 0011 ,则从左至右,从下往上,昆虫图的倒数第三行左起前六个像素不绘制,第七个,第八个绘制。 后面同理。
之所以例子得到的图中昆虫不是完整的是因为他的背景矩形不是从坐标原点开始来的。假如从原点开始绘制,就可以看到完整的了。 可以设定一个 32 x 32 像素,从原点开始绘制的矩形,将会得到完整的唯一的图形。见下图所示(我的姓: 冯):
先绘制一个32 x32
的矩形,再打开GL_PLOYGON_STIPPLE 模式,从坐标(32,0)到(64,32)绘制我的姓——冯!
最后上代码:
#include <GL/glut.h>
#include <stdlib.h>
void display(void)
{
GLubyte feng[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xF8, 0x00, 0x00, 0x02, 0x40, 0x00,
0x00, 0x04, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,
0x00, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x80,
0x05, 0x00, 0x40, 0x40, 0x04, 0x80, 0x10, 0x40,
0x04, 0x80, 0x20, 0x40, 0x04, 0x41, 0xFF, 0x00,
0x04, 0x41, 0x81, 0x80, 0x04, 0x21, 0xD0, 0x30,
0x02, 0x21, 0xE0, 0x60, 0x02, 0x20, 0x18, 0x18,
0x02, 0x10, 0x04, 0x00, 0x02, 0x08, 0x02, 0x00,
0x02, 0x10, 0x03, 0x00, 0x02, 0x04, 0x01, 0x00,
0x02, 0x04, 0x01, 0x80, 0x8C, 0x02, 0x00, 0x10,
0x18, 0x01, 0x01, 0x80, 0x10, 0x01, 0x01, 0x00,
0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
/* draw one solid, unstippled rectangle, */
/* then two stippled rectangles */
glRectf (0.0, 0.0, 32.0, 32.0);
glEnable (GL_POLYGON_STIPPLE);
glPolygonStipple (feng);
glRectf (32.0, 0.0, 64.0, 32.0);
glDisable (GL_POLYGON_STIPPLE);
glFlush ();
}
void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (350, 150);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}