如何在 OpenGL ES 1.1 上用不同的纹理填充立方体的每一面?

2024-04-10

请,我需要教程/代码示例,了解如何在 OpenGL ES 1.1 上用不同的纹理填充立方体的每一面

我找到了很多教程,但没有一个教程清楚地解释了如何在每个面上放置不同的纹理,也没有一个提供简单的代码示例来说明如何做到这一点。

我的实际代码(来自 nehe 示例)绘制了每个面上具有相同纹理的立方体:

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();
}
}

要使每个面具有不同的纹理,您需要单独渲染立方体的每个面。这意味着您需要为每个面设置纹理,然后渲染该面(使用glDrawArrays or glDrawElements)。所以它看起来像:

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

如果立方体的所有面需要不同的纹理,则无法在一次调用中渲染它们。但是您当然仍然可以将它们全部保存在一个数组/VBO 中,并且只需使用参数glDrawArrays or glDrawElements选择相应的面,如上所示。

这是一个相当简化的伪代码示例,如果这一切对您来说听起来很陌生,您应该更深入地研究 OpenGL,并将不同的纹理应用于立方体的每个面是您最不关心的问题。

EDIT:好的,根据您更新的代码:首先,由于所有顶点的位置和 texCoords 都存储在相同的数组中,因此我们不需要更改每个面的这些值。此外,您的索引数组似乎包含所有面,每个面连续存储为 6 个索引(2 个三角形)。这一切使得整个情况变得非常容易。只需替换您现有的glDrawElements在所有面上循环调用:

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

因此,对于每个面,我们选择其纹理并仅绘制与该面相对应的 2 个三角形。

一般来说,在学习代码示例时,而不是书本或类似的东西,您至少应该确保您理解每一行代码和每个函数参数的含义。只有这样,您才能自由地调整代码以满足您的需求并开发问题的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 OpenGL ES 1.1 上用不同的纹理填充立方体的每一面? 的相关文章

随机推荐

  • 在 AutoCompleteTextview 中获取过滤后的数组大小

    我正在开发一个用户可以搜索数据的项目 为此 我已经实施了AutoCompleteTextView autoComplete setAdapter new ArrayAdapter
  • 在编写 JS/JSX 文件时是否可以在 VSCode 中调出颜色选择器?

    使用 React 时 如果能够在使用内联样式时访问带有十六进制代码的颜色选择器 那就太好了 有什么扩展或设置可以解决这个问题吗 我自己也遇到了这个问题 所以我构建了颜色选择 https marketplace visualstudio co
  • 不能因为类不是多态而沮丧吗?

    是否可以在没有虚方法的情况下进行继承 编译器表示以下代码不是多态的 Example class A public int a int getA return a class B public A public int b int getB
  • 分配失败 - JavaScript 堆内存不足

    我正在开发一个使用 NextJs 和 ReactJs 开发的项目 突然这个项目出现了分配失败 JavaScript 堆内存不足问题 我已经尝试了网上的所有资源 但是这些资源对我不起作用 我想 也许 next config js 或 webp
  • 如何使用 ElGamal 加密/解密文本文件

    我正在尝试使用 ElGamal 来加密和解密文本文件以进行我的研究 但似乎我无法使其正常工作 我有一组大小从 1kb 1mb 不等的文本文件 我使用 512 位作为密钥大小 我已经知道 就像 RSA 一样 ELGamal 无法加密超过其模数
  • Swift:在使用过滤器函数过滤后调用indexOf时无法将类型值转换为@noescape

    在 Swift 2 中 我收到一个错误 无法转换类型值 String AnyObject 预期的参数类型 noescape String AnyObject 抛出 gt 布尔 today NSDate array String AnyObj
  • 如何提取 SQLite FTS 表中的所有标记?

    出于调试目的 我想查看 SQLite 中全文搜索虚拟表中存在的所有标记 当我查看 FTS 表 名为fts table 我看到以下内容 但是浏览这些表中的数据不会显示标记列表 无论如何我都找不到 如何提取简单的令牌列表 你可以这样做ftx4a
  • 服务器在区域设置中设置为 en-GB,但日期时间解析为 en-US

    我通过将每条记录推送到验证阶段 然后将其放入数据库来处理记录 验证步骤之一需要检查某些列是否是日期 我使用 DateTime TryParse s out DateTime 执行此操作 假设这将使用运行进程的计算机上配置的区域设置 在我的本
  • 如何在 ASMACK 中解析 CustomIQ

    我正在我的应用程序中使用 ASMACK 库 我从我的服务器收到以下 IQ
  • 如何使用 NavController 导航片段而不将其添加到后台堆栈中?

    NavController有方法navigate默认情况下使用 backstack 进行导航 如何在没有后退堆栈的情况下导航到片段 请注意 我不是在问FragmentTransaction 如果你有一个后堆栈 A gt B 并想要获得一个后
  • 插件在 Windows 7 64 位上的 Eclipse 中不起作用

    在我全新的Windows 7机器上 我下载了Eclipse Galileo 和几个Eclipse插件 Android的ADT插件 Subclipse等 重新启动后 这些插件都没有显示在 IDE 中 首选项 菜单等中没有显示任何内容 但如果我
  • Await 将控制权返回给调用者——谁在等待的任务中执行同步代码?

    当遇到等待时 控制权返回给调用者 而等待的任务在后台运行 发出 等待网络请求 响应 我知道等待任务在等待网络响应时不需要线程 因为它实际上并没有运行任何东西 只是在等待 我想问 假设在等待的函数中 有一些同步代码 例如Console Wri
  • SVG图案动画

    我在 svg 中定义了一个模式 我想连续旋转它 我无法在该图案定义上应用动画 我将相同的动画应用于符号 它可以工作 但不能在图案上工作
  • 集成到 VNET 后无法连接到 Azure Function App

    问题概要 Azure Function App 集成到 VNET 且 WEBSITE VNET ROUTE ALL 设置为 1 后将无法访问 这是必需的 以便 Function App 可以安全地连接到 SQL 而无需公开 SQL Erro
  • 在继承类中扩展 wagtail Streamfields

    我有一个抽象类 其中有 ha StreamField 我还有一个继承自 BasePage 的类 CustomPage 我希望 CustomPage 向内容添加新的 StructBlock 我怎么做 class BasePage Page c
  • 如何在php中加密/解密数据?

    我目前是一名学生 正在学习 PHP 我正在尝试在 PHP 中对数据进行简单的加密 解密 我做了一些在线研究 其中一些非常令人困惑 至少对我来说 这就是我想做的 我有一个由这些字段组成的表 用户 ID 姓名 姓名 电子邮件 密码 我想要的是对
  • iPhone 的总内存

    我想知道Total我的 iPhone 中可用的 RAM 为此 我使用了以下代码 注意 请不要将此问题解释为检索 RAM 统计信息 例如 有线 非活动 活动 和 空闲 mach port t host port mach msg type n
  • HTML 5 通知无法在 Chrome 本地工作?

    我找到了以下 HTML 通知示例 它在 Chrome 和 Firefox 中运行良好 下载并在本地尝试后 它不再在 Chrome 中运行 这是预期的行为 Chrome 由于某种原因阻止本地通知 还是有其他原因导致此功能不起作用
  • Apyori 相关性测度

    我在用着Apyori https pypi org project apyori 库作为 Apriori 算法的实现 rules apriori trs min support 0 02 min confidence 0 1 min lif
  • 如何在 OpenGL ES 1.1 上用不同的纹理填充立方体的每一面?

    请 我需要教程 代码示例 了解如何在 OpenGL ES 1 1 上用不同的纹理填充立方体的每一面 我找到了很多教程 但没有一个教程清楚地解释了如何在每个面上放置不同的纹理 也没有一个提供简单的代码示例来说明如何做到这一点 我的实际代码 来