我试图在每张脸上制作一个不同纹理的立方体。
我的前脸和后脸现在都在工作。现在我正试图制作立方体的正确面孔。但是有些事情出错了,因为我做了正确的面孔,但纹理显示有错误(就像拉伸和切碎一样),我的代码中有一些不好的东西,我不知道是什么。
这是我的代码
public class Cube {
private FloatBuffer vertexBuffer;//Vertices
private FloatBuffer textureBuffer;//Texture coordinates
private ByteBuffer indexBuffer;//Indices
private int[] textures = new int[6];//Texture pointer
private float vertices[] = { //8 vertices of the cube
-1.0f, -1.0f, 1.0f, // 0
1.0f, -1.0f, 1.0f, // 1
-1.0f, 1.0f, 1.0f, // 2
1.0f, 1.0f, 1.0f, // 3
-1.0f, -1.0f, -1.0f,// 4
1.0f, -1.0f, -1.0f, // 5
-1.0f, 1.0f, -1.0f, // 6
1.0f, 1.0f, -1.0f, // 7
};
private byte indices[] = { //Faces definition
0,1,2, 1,3,2, //front face (*)
6,7,5, 6,5,4, //rear face (**)
1,5,3, 5,7,3, //right face (***) //problems here
};
private float texture[] = {//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
public Cube()
{
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
public void draw(GL10 gl) {
//Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
//Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//para que no pinte los poligonos que no se ven
//gl.glEnable(GL10.GL_CULL_FACE);
for(int i=0; i<3; i++) //<6 por que tenemos 6 texturas que queremos poner en las 6 caras de un cubo.
{
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[i]);
indexBuffer.position(6*i); //como cada dos triangulos (cuadrado) forman una cara, estos dos triangulos son 6 indices del array de indices, por lo tanto avanzamos 6 posiciones en el indexBuffer para pintar el siguiente cuadrado.
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, indexBuffer); //el segundo parametro es 6 por que solo queremos pintar una cara (cuadrado) por textura.
}
//gl.glDisable(GL10.GL_CULL_FACE); //para que no pinte los poligonos que no se ven
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
public void loadGLTexture(GL10 gl, Context context) {
loadTexture(gl,context,R.drawable.s1,0);
loadTexture(gl,context,R.drawable.s2,1);
loadTexture(gl,context,R.drawable.s3,2);
loadTexture(gl,context,R.drawable.s4,3);
loadTexture(gl,context,R.drawable.s5,4);
loadTexture(gl,context,R.drawable.s6,5);
}
public void loadTexture(GL10 gl, Context context, int drawable, int textureNumber)
{
//Get the texture from the Android resource directory
InputStream is = context.getResources().openRawResource(drawable);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
//Generate one texture pointer...
gl.glGenTextures(1, textures, textureNumber);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[textureNumber]);
//Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//Clean up
bitmap.recycle();
}
}
答案 0 :(得分:2)
在OpenGL中,顶点是位置和/或纹理坐标和/或颜色和/或任意更多属性的组合。因此,尽管列出了12个纹理坐标,但是从数据中获取的所有OpenGL都是8个不同的顶点,每个顶点都有一个位置和一个纹理坐标。
你的右脸由两个三角形组成,一个有顶点1,5和3,另一个有顶点5,7和3.因此,它在概念上与顶点1,5,7和3的四边形相同。
根据您自己的数据,该四边形具有顶点:
location: 1.0f, -1.0f, 1.0f; coordinate: 1.0f, 1.0f
location: 1.0f, -1.0f, -1.0f; coordinate: 1.0f, 1.0f
location: 1.0f, 1.0f, -1.0f; coordinate: 1.0f, 0.0f
location: 1.0f, 1.0f, 1.0f; coordinate: 1.0f, 0.0f
因此,您希望它能够显示沿着纹理右侧延伸的一维直线,并在整个面上展开。这就是你所看到的吗?
如果要为侧面的角提供唯一的纹理坐标,则需要为它们提供唯一的顶点(尽管它们位于其他顶点的顶部)。