|
投影视图(没有终点的投影)
投影视图是一种无法分辨物体距离我们远近的视图,因为无论远近它们都一样大小。因此如果你以某个特定大小画一个物品,另一个同样大小的物品离第一个很远但是跟第一个有稍微的错开,那么你是无法分辨那个物品是第一个的。因为两个有同样的大小,它们没有随着距离远近而发生放缩。
透视(有终点的投影)
透视视图是跟我们眼睛所看到的类似的视图。一个在你面前的高个子当然很高。如果这个人距离你有100米远,那么他就还不如你的拇指大。在我们的视图中他会随着距离的远近而放缩。这就是透视。如果是前面那个两个物体的例子,我们就可以根据大小来判断它们的距离远近了。
我们打算创建的第一个视图是使用投影视图的例子。这个视图的建立我们只需要做一次,当然如果我们更改了旋转属性的话,每一次画布创建的时候都需要重新建立这个视图。因此我们需要把onDrawFrame()中的部分代码放入onSurfaceCreated()中去。在那里如果程序刚刚开始运行或者旋转被修改过了的话,与这个视图建立相关的代码会被执行。
java代码:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// preparation
// 定义背景颜色
gl.glClearColor(0f, 0f, 0f, 1.0f);
// 保证只有一面是可以被观察到的
gl.glEnable(GL10.GL_CULL_FACE);
// 逆时针的顺序绘制的一面可以被观察到
gl.glFrontFace(GL10.GL_CCW);
// 哪个不用被绘制
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
initTriangle();
}
// code snipped
@Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
// 清楚颜色和深度缓冲区
// we called above...
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// 设置旋转
gl.glRotatef(_xAngle, 1f, 0f, 0f);
gl.glRotatef(_yAngle, 0f, 1f, 0f);
//gl.glColor4f(0.5f, 0f, 0f, 0.5f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
}
复制代码
你可以看到我们没有将glClear()和glLoadIdentity()函数从onDrawFrame()移到onSurfaceCreated()中去。原因很简单,他们只需要在绘制每一帧时调用。
因为我们需要屏幕的大小来计算屏幕的比率,所以引入变量_width和_height。我们需要把他们置于onSurfaceChanged()函数中,因为这个函数在旋转发生变化时会被调用。
java代码:
private float _width = 320f;
private float _height = 480f;
@Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
_width = w;
_height = h;
gl.glViewport(0, 0, w, h);
}
复制代码
现在我们已经做好准备来创建一个视窗了。下面修改onSurfaceCreated()函数。
java代码:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glMatrixMode(GL10.GL_PROJECTION);
float ratio = _width / _height;
// 投影视图
gl.glOrthof(-1, 1, -1 / ratio, 1 / ratio, 0.01f, 100.0f);
gl.glViewport(0, 0, (int) _width, (int) _height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glEnable(GL10.GL_DEPTH_TEST);
// define the color we want to be displayed as the "clipping wall"
gl.glClearColor(0f, 0f, 0f, 1.0f);
// enable the differentiation of which side may be visible
gl.glEnable(GL10.GL_CULL_FACE);
// which is the front? the one which is drawn counter clockwise
gl.glFrontFace(GL10.GL_CCW);
// which one should NOT be drawn
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
initTriangle();
}
复制代码
系列之Android 游戏教程(一)的帖子链接http://www.eoeandroid.com/thread-102096-1-1.html
系列之Android 游戏教程(二)的帖子链接http://www.eoeandroid.com/thread-102097-1-1.html
系列之Android 游戏教程(三)的帖子链接http://www.eoeandroid.com/thread-102100-1-1.html
系列之Android 游戏教程(四)的帖子链接http://www.eoeandroid.com/thread-103115-1-1.html
系列之Android 游戏教程(五)的帖子链接http://www.eoeandroid.com/thread-103118-1-1.html
系列之Android 游戏教程(七)的帖子链接http://www.eoeandroid.com/thread-103125-1-1.html |
|