2017-11-30 1 views
2

에 직면 해있다. 하지만, 내 현재의 코드로,이 같은 렌더링 : 나는 각면에 대한 텍스쳐 좌표를 얻을 필요하지만 매번 내가 텍스처 좌표의 배열을 확장하려고 알고나는 다음과 같은 질감을

enter image description here

, 내 나누기 암호.

궁극적으로 텍스처 파일에서 주사위의 각면을 3D 큐브의면에 그려 넣을 수 있습니까?

public class Dice3D { 
private FloatBuffer vertexBuffer; // Buffer for vertex-array 
private FloatBuffer texBuffer; // Buffer for texture-coords-array (NEW) 

private float[] vertices = { // Vertices for a face 
     -1.0f, -1.0f, 0.0f, // 0. left-bottom-front 
     1.0f, -1.0f, 0.0f, // 1. right-bottom-front 
     -1.0f, 1.0f, 0.0f, // 2. left-top-front 
     1.0f, 1.0f, 0.0f // 3. right-top-front 
}; 

float[] texCoords = { // Texture coords for the above face (NEW) 
     0.0f, 1.0f, // A. left-bottom (NEW) 
     1.0f, 1.0f, // B. right-bottom (NEW) 
     0.0f, 0.0f, // C. left-top (NEW) 
     1.0f, 0.0f // D. right-top (NEW) 
}; 

int[] textureIDs = new int[1]; // Array for 1 texture-ID (NEW) 

// Constructor - Set up the buffers 
public Dice3D(Context context) { 
    // Setup vertex-array buffer. Vertices in float. An float has 4 bytes 
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4 * 6); 
    vbb.order(ByteOrder.nativeOrder()); // Use native byte order 
    vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float 

    for (int face = 0; face < 6; face++) { 
     vertexBuffer.put(vertices); 
    } 

    vertexBuffer.position(0); 

    /*vertexBuffer.put(vertices);   // Copy data into buffer 
    vertexBuffer.position(0);   // Rewind*/ 

    // Setup texture-coords-array buffer, in float. An float has 4 bytes (NEW) 
    ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4); 
    tbb.order(ByteOrder.nativeOrder()); 
    texBuffer = tbb.asFloatBuffer(); 
    texBuffer.put(texCoords); 
    texBuffer.position(0); 
} 

// Draw the shape 
public void draw(GL10 gl) { 
    gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation 
    gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face 
    gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display) 

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array (NEW) 
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords buffer (NEW) 

    // front 
    gl.glPushMatrix(); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // left 
    gl.glPushMatrix(); 
    gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // back 
    gl.glPushMatrix(); 
    gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // right 
    gl.glPushMatrix(); 
    gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // top 
    gl.glPushMatrix(); 
    gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // bottom 
    gl.glPushMatrix(); 
    gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Disable texture-coords-array (NEW) 
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glDisable(GL10.GL_CULL_FACE); 


} 

// Load an image into GL texture 
public void loadTexture(GL10 gl, Context context) { 
    gl.glGenTextures(1, textureIDs, 0); // Generate texture-ID array 

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); // Bind to texture ID 
    // Set up texture filters 
    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); 

    // Allocate texture buffer 
    ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * 6); 
    tbb.order(ByteOrder.nativeOrder()); 
    texBuffer = tbb.asFloatBuffer(); 
    // All the 6 faces have the same texture coords, repeat 6 times 
    for (int face = 0; face < 6; face++) { 

     Log.i("Face", String.valueOf(face)); 

     float[] texCoords = {  // Texture coords for the above face (NEW) 
       0.0f, (5.0f-face)/6.0f, // A. left-bottom (NEW) 
       1.0f, (5.0f-face)/6.0f, // B. right-bottom (NEW) 
       0.0f, (6.0f-face)/6.0f, // C. left-top (NEW) 
       1.0f, (6.0f-face)/6.0f // D. right-top (NEW) 
     }; 
     texBuffer.put(texCoords); 
    } 
    texBuffer.position(0);  // Rewind 


    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); 

    for (int face = 0; face < 6; face++) { 
     // Render each face in TRIANGLE_STRIP using 4 vertices 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face*4, 4); 
    } 

    // Construct an input stream to texture image "res\drawable\nehe.png" 
    InputStream istream = context.getResources().openRawResource(R.drawable.completetexture); 
    Bitmap bitmap; 
    try { 
     // Read and decode input as bitmap 
     bitmap = BitmapFactory.decodeStream(istream); 
    } finally { 
     try { 
      istream.close(); 
     } catch(IOException e) { } 
    } 

    // Build Texture from loaded bitmap for the currently-bind texture ID 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
    bitmap.recycle(); 
} 

}

답변

1

당신은 질감 큐브의 각면 좌표를 분리해야합니다 :

다음은 3D 큐브 오브젝트 클래스입니다. 큐브의 각 부분은 수직 방향으로 텍스처의 1/6을 차지합니다. 얼굴 용

텍스처 coordiates은 :

  • 1 : (0, 5/6) - (1, 6/6)
  • 2 : (0, 4/6) - (1- 5/6)
  • 3 : (0, 3/6) - (1, 4/6)
  • 4 : (0, 2/6) - (1, 3/6)
  • 5 : (0, 1/6) - (1, 2/6)
  • 6 : (0, 0/6) - (1,164)
당신은 또한 정점을 추가해야 물론

for (int face = 0; face < 6; face++) { 

    float[] texCoords = {  // Texture coords for the above face (NEW) 
     0.0f, (5.0f-face)/6.0f, // A. left-bottom (NEW) 
     1.0f, (5.0f-face)/6.0f, // B. right-bottom (NEW) 
     0.0f, (6.0f-face)/6.0f, // C. left-top (NEW) 
     1.0f, (6.0f-face)/6.0f // D. right-top (NEW) 
    }; 

    texBuffer.put(texCoords); 
} 

는 각면 좌표 :

이는이 같은 얼굴 텍스처 coordiantes을 caluclate 수 있다는 것을 의미한다

private float[] vertices = { // Vertices for a face 
    -1.0f, -1.0f, 0.0f, // 0. left-bottom-front 
    1.0f, -1.0f, 0.0f, // 1. right-bottom-front 
    -1.0f, 1.0f, 0.0f, // 2. left-top-front 
    1.0f, 1.0f, 0.0f // 3. right-top-front 
}; 

for (int face = 0; face < 6; face++) { 
    vertexBuffer.put(vertices); 
} 

그리고 당신은 그리해야 각 얼굴 정점 어레이의 적절한 부분 :

// front 
    gl.glPushMatrix(); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
    gl.glPopMatrix(); 

    // left 
    gl.glPushMatrix(); 
    gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4); 
    gl.glPopMatrix(); 

    // back 
    gl.glPushMatrix(); 
    gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4); 
    gl.glPopMatrix(); 

    // right 
    gl.glPushMatrix(); 
    gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4); 
    gl.glPopMatrix(); 

    // top 
    gl.glPushMatrix(); 
    gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4); 
    gl.glPopMatrix(); 

    // bottom 
    gl.glPushMatrix(); 
    gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); 
    gl.glTranslatef(0.0f, 0.0f, 1.0f); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4); 
    gl.glPopMatrix(); 


,691 363,210 주, 당신은 모든 매트릭스 회전과 번역 작업을 취소 할 수 있으며, 별도의 정점은 각면 좌표를 생성하는 경우 당신은 gl.glDrawArrays의 단일 호출로 전체 큐브를 그릴 수 있습니다 :

float[] vertices = { // Vertices for a face 
    -1.0f, -1.0f, -1.0f, 
    1.0f, -1.0f, -1.0f, 
    -1.0f, 1.0f, -1.0f, 
    1.0f, 1.0f, -1.0f 
    -1.0f, -1.0f, 1.0f, 
    1.0f, -1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f 
}; 

indices [] = { 
    0, 1, 2, 3, // front 
    4, 0, 6, 2, // left 
    5, 4, 7, 6, // back 
    1, 5, 3, 7, // right 
    2, 3, 6, 7, // top 
    4, 5, 0, 1 // bottom 
} 

for (int i = 0; i < 24; i++) { 
    int vi = indices[i]*3; 
    vertexBuffer.put(vertices[vi + 0]); 
    vertexBuffer.put(vertices[vi + 1]); 
    vertexBuffer.put(vertices[vi + 2]); 
} 

gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 24); 
+0

플로트 얼굴을 넓혀 주시겠습니까? = 각 얼굴 (0.0, 1.0 등)은 자체 변수가 필요합니까? 나는 올바른 좌표를 가지고 있으므로 올바른 길을 가고 있다는 것을 알고 있습니다! 감사! – decprog

+0

은 어느 정도 작동하지만 face = 0에서 텍스처 좌표 만 렌더링합니다. 코드를 위의 loadTexture 메서드 내에 배치했습니다. 배치 한 위치를 표시하도록 편집했습니다. – decprog

+0

내가 말한 것처럼 추가 기능을 추가했지만 여전히 루프의 위치 0에만 얼굴을로드합니다. 버텍스로 texcoords 루프에서 뭔가를해야합니까? 수정 한 내용을 반영하기 위해 상단에있는 내 코드를 편집했습니다. – decprog