首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图在立方体面上呈现纹理

试图在立方体面上呈现纹理
EN

Stack Overflow用户
提问于 2017-11-30 17:43:06
回答 1查看 109关注 0票数 2

我的纹理如下:

我正在尝试获取纹理中的每个骰子面,以便在OpenGL ES中的立方体的每个面上呈现。但是,用我当前的代码,它呈现如下:

我知道我需要得到纹理协调每个脸,但每次我试图展开纹理协调数组,它打破了我的代码。

最终,如何在纹理文件中获取骰子的每个面,以便在三维立方体上的骰子面上绘制?

以下是3D多维数据集对象类:

代码语言:javascript
复制
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();
}

}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-30 17:58:55

你必须分开立方体的每个面的纹理坐标。立方体的每一部分沿垂直方向占据六分之一的纹理.

这些人脸的纹理编码如下:

  • 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,1/6)

这意味着您可以为这样的脸计算纹理坐标:

代码语言:javascript
复制
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);
}

当然,您还必须为每个面添加顶点坐标:

代码语言:javascript
复制
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);
} 

您必须为每个面绘制顶点数组的适当部分:

代码语言:javascript
复制
    // 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();

注意,您可以放弃所有矩阵旋转和平移操作,如果为每个面生成单独的顶点坐标,则可以使用单个gl.glDrawArrays调用绘制整个立方体:

代码语言:javascript
复制
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]);
}

代码语言:javascript
复制
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 24);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47579531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档