OpenGL ES for Android研究总结

来源:互联网 发布:极限矩阵猛禽x2 编辑:程序博客网 时间:2024/06/07 20:02

GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ)

 

0>  如果没有主动调用这个函数,系统默认相当于调用了GLU.gluLookAt(gl, 0, 0, 0, 0, 0, 0, 0, 1, 0);

       调用gl.glTranslatef(0,0,-1); 这个API后看到的效果等同于调用了GLU.gluLookAt(gl, 0, 0, 1, 0, 0, 0, 0, 1, 0);但调用后者不会影响当前全景坐标系。

1>  eyeX, eyeY, eyeZ 是观察者所在点对应于在当前全景坐标系下的坐标。

2>  centerX, centerY, centerZ是观察者的视线中心点在当前全景坐标系下的坐标。考虑你的手机屏幕这个平面,这个平面垂直于观察者的视线,所有屏幕上显示的物体形状,大小,其实是在全景坐标系下的物体沿视线投影到手机屏幕这个面的形状和大小。

3> upX, upY, upZ代表从(0,0,0)到 (x,y,z)的直线,它表示了观察者认为的“上”方向。改变这几个值相当于观察者的视线不变,自己的脸沿垂直于视线的平面旋转。

 

gl.glTranslatef(0,0,-1);

 

改变当前的全景坐标系, 使坐标系整体向屏幕内平移一个单位,这样所有的物体就看起来向屏幕内平移了一个单位。

 

 

glTexCoordPointer

坐标决定纹理贴图的大小,但是真正的纹理内容的左边总是在(0,1)之间,所以这个贴图越大,内容所占的比例就越小.

然后glTexCoordPointer决定的纹理贴图贴到glVertexPointer决定的”画布”上.这个过程是一比一的,”画布”是多大,纹理贴图就做相应的变形适合”画布”形状.

最后把画布显示在glViewport决定的屏幕显示区域,但是上面提到了,屏幕显示区域是一个坐标在(-1,+1)之间的一个正方形,所以”画布”的面积越大,即坐标范围越大,在显示这一步时是会被裁的,只剩(-1,+1)部分的图像.

 

贴图的方法

首先图片的操作依然是Bitmap作为图片的元素,如何读取Bitmap就不说了,在Opengl中准备可以贴的图片需要一个过程,首先,需要申明你需要贴图的图名字,这个是一个unsigned int ,用未用过的int来标志每一个你需要的texture,这个过程是通过:

 

gl.glGenTextures(1, textures, 0);

//1 代表制需要创建一个名字,textures 是个int 数组,用于把创建的名字存储回这个数组中,0是说从第0个位置开始存储。

 

再创建好Texture名字后,需要把对应的名字跟具体的Texture关联,所谓的关联其实就是为对应的Texture设置好属性,此时名字的属性已经设置好了,还有不少属性可以设置,最关键的是要指明该Texture的类型,并且该Texture具体的图片:

gl.glBindTexture(GL10.GL_TEXTURE_2Dtextures[0]);

//此处是用于申明当前所有对GL_TEXTURE_2D的操作都是对textures[0]的操作,这两个是一体。

 

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

//为GL_TEXTURE_2D当前的Texture指定图片,第一个0是指等级, 但是我换成1就显示不出来了。第二个0代表border边缘的宽度,此处只能为0(Opengl Es中对不少选择做了限制)

 

其中还有一些关于边缘的设置,例如当图片小于目标时如何处理,图片大于时如何处理之类的选项:

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);

 

此时,你已经为每一个名称的Texture指定好了应该指定的参数,这些过程可能会比较慢,不能老做,应该放在一个地方统一进行。当所有Texture指定好了,就可以开始使用每一个Texture了,使用时是先通过

gl.glBindTexture(GL10.GL_TEXTURE_2Dtextures[0]);

指定你当前准备使用的Texture,这个是非常快的,可以频繁使用。

指定好后,通过为每一个目标Vertext 指定对应 贴图中的位置来确定,该贴图最终被贴上去的样子,所以也需要准备一个Texture的FloatBuffer。其中因为贴图是2d所以指定的是2纬坐标,1为对应图片的宽或者高,从0 到1之间取数。

激活

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

跟着画出点的时候,就把贴图给画出来了。

 

贴图时的坐标问题

根据Per-Erik Bergman的说明, UV maping的坐标对应如下

所以顶点坐标数组应该为 

        float textureCoordinates[] = { 0.0f, 1.0f, //
                1.0f, 1.0f, //
                0.0f, 0.0f, //
                1.0f, 0.0f, //
        };

 

绘图平面有交叠时的遮挡问题

绘制A物体平面,在物体A所在平面的某一区域再绘制B平面。 当从平面的角度看时,B完全遮挡了A。 但是从远处立体远观时,B和A的遮挡情况就不一定了,有时后B反而被A遮挡。

这个原因是视区范围的深度范围太大,以至于在32位内无法判定深度值大小差别。
典型的修改方法是最近的z深度值放大。例如:
gluPerspective(...,...,10,100000000);
改为 gluPerspective(...,...,100,100000000);