OpenGL ES 中抗锯齿处理
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
本博文中,默认研究OpenGL ES都是针对2.0及以后版本,即带着色器的版本。
对1.x这种固定管线的版本,不考虑去深入研究,也或许会通过1.x中提供的API来研究2.0及以后版本中的相关算法实现。
猜想,可能是这样的,1.x中提供的API,其实后端也是在着色器中写的代码,只不过通过API设置个状态,回头渲染管线根据这些状态来选择是否执行和执行哪一段着色器代码。
只不过在1.x中并未提供着色器语言给开发者,所以也就没办法通过着色器代码来实现了。
真的不知道具体是否如上面猜想,不过感觉最好有2.0及以后的版本中有最起码的1.x中的功能,在着色器中实现,并可以在着色器中调用,这样对于起步研究还是大有益处。
越是复杂的系统,越需要提供最基本的示例,可供入门者使用,确保高楼大厦都有一个缓台可用,每一个缓台让人看到的高度都很直观,但距离确都很舒适,这样才不至于一下子被吓破了胆,提G色变啊!真不是夸张,我对OpenGL 垂涎三四年了,都未曾敢支碰过,怕浪费宝贵的时间;就连流媒体这种东西,我至少还有胆去玩玩它。周围的同事、朋友,无一不提G色变,只要提起OpenGL没有不知道的,但都害怕得要命,已经变成了一种习惯性的思维。
感觉这种现状,确实不太好改变,新生需求的逼迫,也迫使不少人硬着头皮研究、使用,发现这东西不光入门难,入门之后,琐碎的技术知识、计算多得很,要解决的问题也多不胜举。
但至少目前,我还在坚持着,目标明确就好了,朝着他一步一步地做,本来学习、研究和使用OpenGL ES就是个慢工夫的事儿。
转入正题,转一篇别人的 OpenGL中的抗锯贴子,不过很多功能在ES中没有,暂且保留,未来需要做抗锯时,有个切入点:
-----转自:http://www.cocoachina.com/bbs/read.php?tid=28590
各位,我们从第一讲到现在所绘制出的图形的边缘都会存在比较明显的犬齿印,如果边缘不处于水平、垂直或斜45度角的话。
这一讲,我们将介绍如何摆脱这大煞风景的犬齿。
抗犬齿的第一种做法是比较直观、易懂的。我们通过将线段边缘所覆盖到的像素面积进行判断,如果覆盖到了大部分的像素,那么使用线段颜色的比例就高,否则线段颜色的比例就低。
也就是说,我们通过淡化边缘覆盖到一个面积小的像素来达成抗犬齿效果。
我们可以看到红宝石书的第149页,图6-3。像素A、B、M以及N所覆盖到的像素面积很小,因此这些像素基本上就用背景色。
这种方式的算法是:将OpenGL片断的覆盖比例与alpha值相乘,并且将这个值作为新的alpha把片断与帧缓存中对应的像素进行混合。
我们下面将介绍一下如何多线段进行抗犬齿。
首先,我们要用glEnable()开启GL_LINE_SMOOTH,这个用于启动直线的抗犬齿功能。然后我们可以调用glHint()函数来指定,暗示OpenGL做何种质量的抗犬齿。
选项一般有:GL_FASTEST,这个是速度最快,但质量最差的;GL_NICEST,这个是速度最慢,但效果最好的;GL_DONT_CARE,这个是默认方式,没有偏向。
下面贴代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//
// MyView.m
// OpenGLTest
//
// Created by Zenny Chen on 4/25/10.
// Copyright 2010 GreenGames Studio. All rights reserved.
// P44
#import "MyView.h"
#include <OpenGL/OpenGL.h>
#include <math.h>
@implementation
MyView
- (
id
)initWithFrame:(
NSRect
)frame {
self
= [
super
initWithFrame:frame];
if
(
self
) {
// Initialization code here.
}
return
self
;
}
static
const
struct
VertexInfo
{
GLfloat vertices[3];
}vertexList[] = {
// line 1
{-0.8f, 0.0f, -2.0f},
{-0.2f, 0.0f, -2.0f},
// line2
{0.2f, 0.0f, -2.0f},
{0.8f, 0.0f, -2.0f},
};
- (
void
)prepareOpenGL
{
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertexList);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glClearColor(0.4, 0.4, 0.4, 1.0);
glViewport(0, 0, 320, 320);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(10.0f, 0.0f, 0.0f, 1.0f);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(1.5f);
}
- (
void
)drawRect:(
NSRect
)dirtyRect {
// Drawing code here.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_LINES, 0, 2);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glDrawArrays(GL_LINES, 2, 2);
glFlush();
}
@end
|