如何填充基于OpenGL ES 1.1不同质地的立方体的每一面? [英] How to fill each side of a cube with different textures on OpenGL ES 1.1?

查看:197
本文介绍了如何填充基于OpenGL ES 1.1不同质地的立方体的每一面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请,我需要怎么填上的OpenGL ES 1.1

不同纹理的立方体的每一面教程/ code例子

我发现了很多的教程,但他们没有解释清楚如何把不同的纹理在每个面,没有人可以轻松code中如何做到这一点。例子

我的实际code(从讷河例子)绘制一个立方体具有相同的纹理每个面:

 公共类立方{

/ **缓冲区持有顶点* /
私人FloatBuffer vertexBuffer;
/ **缓冲区保持纹理坐标* /
私人FloatBuffer textureBuffer;
/ **缓冲区持有指数* /
私人ByteBuffer的indexBuffer;

/ **我们的纹理指针* /
私人INT []纹理=新INT [1];

/ **
 *初始顶点定义
 *
 *注意,每个面被定义,甚至
 *如果指数是可用的,因为
 *纹理的我们要实现
 * /
私人浮动顶点[] = {
                    //根据脸部顶点
                    -1.0F,-1.0F,1.0F,//顶点0
                    1.0F,-1.0F,1.0F,// V1
                    -1.0F,1.0F,1.0F,// V2
                    1.0F,1.0F,1.0F,// V3

                    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,

                    -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,

                    -1.0F,1.0F,1.0F,
                    1.0F,1.0F,1.0F,
                    -1.0F,1.0F,-1.0F,
                    1.0F,1.0F,-1.0F,
                                        };

/ **最初纹理坐标(u,v)的* /
私人浮纹[] = {
                    //贴图坐标的顶点
                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                    0.0,0.0,
                    0.0,1.0F,
                    1.0F,0.0,
                    1.0F,1.0F,

                                        };

/ **初始指标的定义* /
专用字节指数[] = {
                    //面临的定义
                    0,1,3,0,3,2,//当着面
                    4,5,7,4,7,6,//面庞
                    8,9,11,8,11,10,// ...
                    12,13,15,12,15,14,
                    16,17,19,16,19,18,
                    20,21,23,20,23,22,
                                        };

/ **
 *立方体的构造。
 *
 *启动缓冲器。
 * /
公共立方(){
    //
    ByteBuffer的byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuf.asFloatBuffer();
    vertexBuffer.put(顶点);
    vertexBuffer.position(0);

    //
    byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuf.asFloatBuffer();
    textureBuffer.put(纹理);
    textureBuffer.position(0);

    //
    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(指标);
    indexBuffer.position(0);
}

/ **
 *对象自己的绘图功能。
 *从渲染调用重绘此实例
 *与价值的可能变化。
 *
 *参数GL  - 总帐上下文
 * /
公共无效画(GL10 GL){
    //在这种情况下pviously生成的纹理绑定我们唯一的$ P $
    gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[0]);

    //指向我们的缓冲区
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    //设置面旋转
    gl.glFrontFace(GL10.GL_CCW);

    //启用顶点和纹理状态
    gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);
    gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,textureBuffer);

    //绘制顶点的三角形,根据索引缓存信息
    gl.glDrawElements(GL10.GL_TRIANGLES,indices.length,GL10.GL_UNSIGNED_BYTE,indexBuffer);

    临行前//禁用客户端状态
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

/ **
 *加载纹理
 *
 *参数GL  - 总帐上下文
 * @参数方面 - 活动场景
 * /
公共无效loadGLTexture(GL10 GL,上下文语境){
    //获取纹理从Android资源目录
    InputStream的是= context.getResources()openRawResource(R.drawable.nehe)。
    点阵位图= NULL;
    尝试 {
        // BitmapFactory是一个Android的图形实用程序,用于图像
        位= BitmapFactory.de codeStream(是);

    } 最后 {
        //始终明确,密切
        尝试 {
            is.close();
            是=无效;
        }赶上(IOException异常E){
        }
    }

    //生成一个纹理指针...
    gl.glGenTextures(1,纹理,0);
    //...and将其绑定到我们的数组
    gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[0]);

    //创建最近过滤的纹理
    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);

    //不同可能纹理参数,例如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);

    //使用了Android GLUtils从我们的位图指定二维纹理图像
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,位图,0);

    //清理
    bitmap.recycle();
}
}
 

解决方案

为了让每一面都有不同的纹理,你需要单独渲染立方体的每一个面。这意味着你需要设置的纹理,然后使面部(用调用glDrawArrays 与glDrawElements )的每个面。所以它看起来是这样的:

 过glEnable(GL_TEXTURE_2D);
... //也许其他国家设置(如缓冲区绑定)
的glVertexPointer(...);
glEnableClientState(GL_VERTEX_ARRAY);
...

每个(面立方体)
{
    glBindTexture(GL_TEXTURE_2D,< face_texture>);
    (4,8,...)或与glDrawElements(...); //画只有一个脸
}

glDisableClientState(GL_VERTEX_ARRAY);
...
glDisable(GL_TEXTURE_2D);
... //也许其他国家清理
 

您不能呈现立方体的所有面在一个电话,如果他们需要不同的纹理。当然,但你仍然可以追究他们都在一个单一的阵列/ VBO,只是使用的参数调用glDrawArrays 与glDrawElements 选择相应的脸,像上面做。

这是一个相当简化的伪code的例子,如果这一切听起来很陌生的你,你应该钻研得更深一些成OpenGL和应用不同的纹理立方体的每一面是你最的问题。

编辑:确定,根据更新后的code:首先,因为所有的顶点'的立场和texCoords都存储在同一个阵列,我们并不需要更改这些每个面。此外,你的指数阵列似乎包含contigously存储为6索引(2个三角形)的每个面所有面。这一切都使得整个局面很容易。就在这个循环对所有的面孔替换现有的与glDrawElements 电话:

 为(i = 0; I< 6,+ I)
{
    gl.glBindTexture(GL10.GL_TEXTURE_2D,纹理[I]); //使用质地第i个脸
    indexBuffer.position(6 * I); //选择第i个脸

    //得出2个三角形组成这张脸
    gl.glDrawElements(GL10.GL_TRIANGLES,6,GL10.GL_UNSIGNED_BYTE,indexBuffer);
}
 

因此​​,对于每个面,我们选择它的​​质地和借鉴,只有2个三角形对应于这张脸。

从code样本的学习,而不是一本书或类似的东西的时候,一般情况下,你至少应该确保你了解每行的code和每个函数参数的含义。只有这样,你可以自由地适应code,以您的需求,并制定解决方案的问题。

Please, I need tutorials/code examples of how to fill each side of a cube with different textures on OpenGL ES 1.1

I found a lot of tutorials but none of them explain clearly how to put different textures in each face and none of them gives easy code examples of how to do it.

My actual code (from nehe examples) that draws a cube with the same texture on each face:

public class Cube {

/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
/** The buffer holding the indices */
private ByteBuffer indexBuffer;

/** Our texture pointer */
private int[] textures = new int[1];

/** 
 * The initial vertex definition
 * 
 * Note that each face is defined, even
 * if indices are available, because
 * of the texturing we want to achieve 
 */ 
private float vertices[] = {
                    //Vertices according to faces
                    -1.0f, -1.0f, 1.0f, //Vertex 0
                    1.0f, -1.0f, 1.0f,  //v1
                    -1.0f, 1.0f, 1.0f,  //v2
                    1.0f, 1.0f, 1.0f,   //v3

                    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,

                    -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,

                    -1.0f, 1.0f, 1.0f,
                    1.0f, 1.0f, 1.0f,           
                    -1.0f, 1.0f, -1.0f,
                    1.0f, 1.0f, -1.0f,
                                        };

/** The initial texture coordinates (u, v) */   
private float texture[] = {         
                    //Mapping coordinates for the vertices
                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f, 

                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f,

                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f,

                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f,

                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f,

                    0.0f, 0.0f,
                    0.0f, 1.0f,
                    1.0f, 0.0f,
                    1.0f, 1.0f,

                                        };

/** The initial indices definition */   
private byte indices[] = {
                    //Faces definition
                    0,1,3, 0,3,2,           //Face front
                    4,5,7, 4,7,6,           //Face right
                    8,9,11, 8,11,10,        //... 
                    12,13,15, 12,15,14,     
                    16,17,19, 16,19,18,     
                    20,21,23, 20,23,22,     
                                        };

/**
 * The Cube constructor.
 * 
 * Initiate the buffers.
 */
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);
}

/**
 * The object own drawing function.
 * Called from the renderer to redraw this instance
 * with possible changes in values.
 * 
 * @param gl - The GL Context
 */
public void draw(GL10 gl) {
    //Bind our only previously generated texture in this case
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //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);

    //Draw the vertices as triangles, based on the Index Buffer information
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

/**
 * Load the textures
 * 
 * @param gl - The GL Context
 * @param context - The Activity context
 */
public void loadGLTexture(GL10 gl, Context context) {
    //Get the texture from the Android resource directory
    InputStream is = context.getResources().openRawResource(R.drawable.nehe);
    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, 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 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();
}
}

解决方案

To make each face have a different texture, you need to render each face of the cube individually. This means for each face you need to set the texture and then render the face (using glDrawArrays or glDrawElements). So it would look something like:

glEnable(GL_TEXTURE_2D);
...                        //maybe other state setup (like buffer bindings)
glVertexPointer(...);
glEnableClientState(GL_VERTEX_ARRAY);
...

for each(face of cube)
{
    glBindTexture(GL_TEXTURE_2D, <face_texture>);
    glDrawArrays(...) or glDrawElements(...);      //draw only a single face
}

glDisableClientState(GL_VERTEX_ARRAY);
...
glDisable(GL_TEXTURE_2D);
...                         //maybe other state cleanup

You cannot render all the faces of the cube in one call if they need different textures. But you can of course still hold them all in a single array/VBO and just use the arguments to glDrawArrays or glDrawElements to select the corresponding face, like done above.

This is a rather simplified pseudo-code example and if all this sounds very alien to you, you should delve a little deeper into OpenGL and applying a different texture to each face of a cube is your least problem.

EDIT: Ok, according to your updated code: First of all, since all your vertices' positions and texCoords are stored in the same arrays, we don't need to change these per face. Furthermore, your index array seems to contain all faces stored contigously as 6 indices (2 triangles) for each face. All this makes the whole situation very easy. Just replace your existing glDrawElements call with this loop over all faces:

for(i=0; i<6; ++i)
{
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[i]);   //use texture of ith face
    indexBuffer.position(6*i);                          //select ith face

    //draw 2 triangles making up this face
    gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, indexBuffer);
}

So for each face we select its texture and draw only the 2 triangles that correspond to this face.

In general when learning from code samples, instead of a book or something similar, you should at least make sure that you understand the meaning of each line of code and each function parameter. Only then you are able to freely adapt the code to your needs and develop solutions for problems.

这篇关于如何填充基于OpenGL ES 1.1不同质地的立方体的每一面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆