做纹理贴图的时候具体的贴图坐标是如何设置纠结了很长时间,下面把关于顶点坐标和贴图坐标的设置详细记下来
OpenGL坐标系如下所示
顶点坐标注意事项:顶点需要注意顺序,顶点一般是一个面一个面的设置,一个面四个点六个面,因为默认的是后面的面不绘制,是通过点的顺序顺时针还是逆时针判断前面还是后面,情况是逆时针为前面,所以要你认为前面的地方设置为逆时针的,后面的地方为顺时针的。
关于上图的我的顶点坐标如下
private int[] quarter = {
//正前面
-x,-y,z, //2 0
x,-y,z, //1 1
x,y,z, //0 2
-x,y,z, //3 3
//正后面
-x,-y,-z, //6 4
-x,y,-z, //7 5
x,y,-z,
//4 6
x,-y,-z, //5 7
//上面
-x,y,z, //3 8
x,y,z, //0 9
x,y,-z, //4 10
-x,y,-z, //7 11
//下面
-x,-y,z, //2 12
-x,-y,-z, //6 13
x,-y,-z, //5 14
x,-y,z, //1 15
//左面
-x,-y,-z, //6 16
-x,-y,z, //2 17
-x,y,z, //3 18
-x,y,-z, //7 19
//右面
x,-y,-z, //5 20
x,y,-z, //4 21
x,y,z,//0 22
x,-y,z, //1 23
};
下面是各个面有两个三角形组成的数组
// 三角形索引数据
//因为glDrawElements用的模式为GL10.GL_TRIANGLE_STRIP
//所以三角形是连在一起的,0,1,3,2代表顶点013组成的三角形和132组成的三角形真好组成一个面
ByteBuffer indices1 = ByteBuffer.wrap(new byte[]{
//前面
0,1,3,2,
});
ByteBuffer indices2 = ByteBuffer.wrap(new byte[]{
//后面
4,5,7,6,
});
ByteBuffer indices3 = ByteBuffer.wrap(new byte[]{
//上面
8,9,11,10,
});
ByteBuffer indices4 = ByteBuffer.wrap(new byte[]{
//下面
12,13,15,14,
});
ByteBuffer indices5 = ByteBuffer.wrap(new byte[]{
//左面
16,17,19,18,
});
ByteBuffer indices6 = ByteBuffer.wrap(new byte[]{
//右面
20,21,23,22,
});
贴图坐标用的是二维贴图,遵循的是uv坐标,将上面的每个面都抛出来作为一个平面如下图所示
注意:按以上图形设置的UV坐标当面旋转到自己正前方的时候有可能图片不是对应正前方的,因为要想旋转到正前方的时候图片也是正的,需要以面旋转到正前方时设定uv坐标,例如:当以X轴顺时针旋转90度,即下面在正前方,这时要原点2,左下6,右下5,右上1的方式设定uv坐标,然后再以顶点的顺序与之对应就好了。贴图坐标和顶点坐标数字对应就好了。这样就不需要考虑左右变换之类的了,只要对应就是在正前方的时候是正的。
下面是我的贴图坐标的数组
//纹理贴图的坐标,这个坐标是跟glDrawElements对应的,就是先设置一下glBindTexture
//就是给那个面设置好贴图后,下一步接着把这个面画出来,所以这个数组的设置是和定点数组和三角形数组对应的
//还要看glBindTexture中的第一个参数GL_TEXTURE_2D,用的几围贴图模式
//注意这里用的是uv坐标,关于具体请看我的CSDN博客——zjk
//只要uv坐标中的点和顶点坐标的点对应就好了(不用管顺时针还是逆时针),uv坐标系的建立以正视图为主(即先把面转到正视图的位置,然后建立UV坐标系,这样的话显示的图片吻合),不用管左右变换这些
//二维的话就是相邻的两个以次是uv,六个面四个点每个点都是(uv)
private int[] texCoords = {
0,y,x,y,x,0,0,0, //前面
0,y,0,0,x,0,x,y, //后面
0,z,x,z,x,0,0,0, //上面
0,0,0,z,x,z,x,0, //下面
0,y,z,y,z,0,0,0, //左面
z,y,z,0,0,0,0,y, //右面 左右兑换了
};
关于立方体纹理贴六个图的例子请看下篇