[英]different textures in android
我想在一個立方體上制作盡可能多的紋理。 立方體的每一側應該有不同的紋理(圖片類似於在loadtexture方法android.png中加載的圖片)。 我的代碼的一部分:
public class Square2 {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private FloatBuffer vertexBuffer2; // buffer holding the vertices
[and so on for all 6 sides]
private float vertices[] = {
-1.0f, -1.0f, -1.0f, // V1 - bottom left
-1.0f, 1.0f, -1.0f, // V2 - top left
1.0f, -1.0f, -1.0f, // V3 - bottom right
1.0f, 1.0f, 1.0f // V4 - top right
};
private float vertices2[] = {
1.0f, -1.0f, -1.0f, // V1 - bottom left
1.0f, 1.0f, -1.0f, // V2 - top left
1.0f, -1.0f, 1.0f, // V3 - bottom right
1.0f, 1.0f, 1.0f // V4 - top right
};
[for all 6 sides too]
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private FloatBuffer textureBuffer2; // buffer holding the texture coordinates
[and so on for all 6 sides]
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private float texture2[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
[dont really understand the texture array, is one enough for all sides, even if i want different textures?]
/** The texture pointer */
private int[] textures = new int[6];
public Square2() {
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = byteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(vertices2.length * 4);
byteBuffer2.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer2 = byteBuffer2.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer2.put(vertices2);
// set the cursor position to the beginning of the buffer
vertexBuffer2.position(0);
[and so on for all 6 sides]
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
[and so on]
}
/**
* Load the texture for the square
* @param gl
* @param context
*/
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.android);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// 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 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();
}
/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[1]);
// 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_CW);
// Point to our vertex buffer1 vorn
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//2 rechts
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer2);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer2);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices2.length / 3);
[and so on]
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
不幸的是,這只是給我所有方面相同的紋理。 如何在每側制作不同的紋理? 我是否必須多次調用loadtexture方法或對其進行編輯? 考慮過不回收位圖,這會有所幫助嗎?
Thera是實現這一目標的可能方法。 最直接的方法是加載所有紋理,然后在繪制每側之前綁定一個不同的紋理(因此,您所缺少的就是在每個glDrawArrays
之前使用glBindTexture
)。 對於這種情況,您不需要多個紋理坐標緩沖區,總體上甚至不需要多個頂點緩沖區。 您可以創建1個正方形緩沖區,並用每邊的矩陣對它進行定位(旋轉)(+綁定正確的紋理)。
另一種方法是使用單個紋理,您可以通過glTextureSubImage
所有6張圖像加載到該紋理上(所有圖像均位於紋理的不同部分,沒有重疊),然后對立方體的每一側使用不同的紋理坐標。 這樣,您可以為整個多維數據集創建一個頂點/紋理緩沖區,並可以通過一個glDrawArrays
調用來繪制它。 盡管在您的特定情況下,該頂點不少於4x6 = 24個頂點。
如您所說,您不了解紋理坐標數組。紋理坐標是對應於紋理上相對位置的坐標。 也就是說,(0,0)是texture(image)的左上部分,而(1,1)是texture(image)的右下部分。 如果紋理具有2x2中的4張圖像,並且您想使用左下角的圖像,則紋理坐標將如下所示:
private float texture[] = {
0.0f, 1.0f,
0.0f, .5f,
.5f, 1.0f,
.5f, 0.5f
};
對於大於或小於1.0或小於.0的坐標值,我相信可以將其用於夾緊對象的某些部分或重復紋理(已購買了其中兩個可能的紋理參數,通常在加載紋理時設置) 。 至於紋理坐標的數量,它至少應與glDrawArrays
的最后一個參數一樣多,或者與使用glDrawElements
時最大的index + 1 glDrawElements
。 因此,對於您的特定情況,您只能有1個紋理坐標緩沖區,除非您會改變主意並希望其中一側在其上旋轉圖像並通過更改紋理坐標來解決該問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.