走样(Aliasing)是由于像素离散采样导致的锯齿、闪烁等问题。反走样技术通过混合像素颜色来平滑边缘。OpenGL中主要针对点、线条和面等进行反走样处理。
线条和点反走样
对点和线形图形元素进行反走样的代码如下所示。
code.vc#.net
// 启用平滑
Gl.glEnable(Gl.GL_LINE_SMOOTH);
Gl.glEnable(Gl.GL_POINT_SMOOTH); // 设置最佳质量提示
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
Gl.glHint(Gl.GL_POINT_SMOOTH_HINT, Gl.GL_NICEST);
// 启用混合(平滑必需)
Gl.glEnable(Gl.GL_BLEND);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
// 设置线宽和点大小
Gl.glLineWidth(1.5F);
Gl.glPointSize(3.0F);
多边形面反走样
对多边形面进行反走样的代码如下所示。
code.vc#.net
Gl.glEnable(Gl.GL_POLYGON_SMOOTH);
Gl.glHint(Gl.GL_POLYGON_SMOOTH_HINT, Gl.GL_NICEST); // 多边形也需要启用混合
Gl.glEnable(Gl.GL_BLEND);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
反走样示例
第3章绘制了直线段、矩形和圆等图形元素,本例在该例的基础上对各图形元素进行反走样,代码如下所示。
code.vc#.net
private void button1_Click(object sender, EventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glEnable(Gl.GL_LINE_SMOOTH);
Gl.glEnable(Gl.GL_BLEND);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
Gl.glPushMatrix();
Gl.glColor3d(1.0, 0.0, 0.0);
Gl.glLineWidth(2);
Gl.glBegin(Gl.GL_LINES);
Gl.glVertex3d(5, 13, 0);
Gl.glVertex3d(12, 5, 0);
Gl.glEnd();
Gl.glPopMatrix();
Gl.glFinish();
Gl.glDisable(Gl.GL_LINE_SMOOTH);
Gl.glDisable(Gl.GL_BLEND);
simpleOpenGlControl1.SwapBuffers();
}
private void button2_Click(object sender, EventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glEnable(Gl.GL_LINE_SMOOTH);
Gl.glEnable(Gl.GL_BLEND);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
Gl.glPushMatrix();
Gl.glColor3d(0.0, 0.0, 1.0);
Gl.glLineWidth(2);
Gl.glBegin(Gl.GL_LINES);
Gl.glVertex3d(-3, 5, 0);
Gl.glVertex3d(-3, -5, 0);
Gl.glVertex3d(-3, -5, 0);
Gl.glVertex3d(3, -5, 0);
Gl.glVertex3d(3, -5, 0);
Gl.glVertex3d(3, 5, 0);
Gl.glVertex3d(3, 5, 0);
Gl.glVertex3d(-3, 5, 0);
Gl.glEnd();
Gl.glPopMatrix();
Gl.glFinish();
Gl.glDisable(Gl.GL_LINE_SMOOTH);
Gl.glDisable(Gl.GL_BLEND);
simpleOpenGlControl1.SwapBuffers();
}
private void button3_Click(object sender, EventArgs e)
{
float[] sngX=new float[52];
float[] sngY=new float[52];
float[] sngZ=new float[52];
float sngAngStep, sngTemp;
int intI;
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
sngAngStep = (float)(6.2832 / 50);
for(intI = 1;intI<=51;intI++)
{
sngTemp = sngAngStep * intI;
sngX[intI] = (float)(8 * System.Math.Cos(sngTemp) + 0.0);
sngY[intI] = (float)(8 * System.Math.Sin(sngTemp) + 0.0);
sngZ[intI] = 0;
}
Gl.glLineWidth(2);
Gl.glColor3f(0, 1, 0);
Gl.glEnable(Gl.GL_LINE_SMOOTH);
Gl.glEnable(Gl.GL_BLEND);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
Gl.glPushMatrix();
for(intI = 1;intI<=50;intI++)
{
Gl.glBegin(Gl.GL_LINES);
Gl.glVertex3d(sngX[intI], sngY[intI], 0);
Gl.glVertex3d(sngX[intI + 1], sngY[intI + 1], 0);
Gl.glEnd();
}
Gl.glPopMatrix();
Gl.glFinish();
Gl.glDisable(Gl.GL_LINE_SMOOTH);
Gl.glDisable(Gl.GL_BLEND);
simpleOpenGlControl1.SwapBuffers();
}
private void button4_Click(object sender, EventArgs e)
{
this.Dispose();
}
运行代码,生成图形如图4-2所示。
\[\]
图4-2 绘制图形并进行反走样