4

我正在尝试在我目前正在开发的游戏中实现一些简单的 3D 功能。我正在使用LibGDX 游戏引擎来实现这个目标,因为它似乎与 OpenGL ES 很好地集成,但是由于我无法弄清楚如何Buffer从 Java 中的图像创建简单对象而遇到了问题。

问题

我的目标是让一个立方体在 3D 空间中旋转,上面有一些纹理。问题是,虽然我设法渲染了立方体并让它旋转,但我似乎找不到任何关于如何将图像实际解码为 aBuffer以纹理立方体的教程、代码示例或文档。我找到了很多示例来说明如何在 Android 中执行此操作,但是这限制了您必须使用BitmapFactory.decodeResource(<your_image here>)Android SDK 中的方法,这对我来说不是一个选项,因为我试图让我的代码可以移植到许多人平台。

正是出于这个原因,我得出的结论是,我必须以某种方式找到一种方法来将图像(.bmp文件)解码为 a Buffer,以便利用Gdx.gl10.glTexImage2D()我发现与 OpenGL ES 打包的方法。

到目前为止我尝试过的

我已经寻求了许多替代方案来尝试找到解决方案,其中包括:

  • 利用LibGDX 包附带Texture.bind()的类中嵌入的方法。Texture
  • 尝试使用 Java ImageIO包解码图像。
  • 使用其他一些解码工具,例如image4j库。

一些代码

这是我用来渲染多维数据集的一些代码。为了清楚起见,省略了很多 OpenGL“开关翻转”,所以如果你认为我遗漏了什么,请发表评论,我会确认它是否只是在另一个类的另一部分。

我知道这段代码很难筛选,所以我已尽力在必要时对其进行评论。

请注意,此代码代表我当前的实现,并且是与下面的“调试信息”部分相关联的代码。

public void draw(){

    // This is used to hold the OpenGL pointer to the texture      
    int[] textures = new int[1];

    // Tells the GPU to render the vertices in a clockwise manner   
    Gdx.gl10.glFrontFace(GL10.GL_CW);

    // Informs OpenGL of the location of the vertices
    Gdx.gl10.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);

    // Bind the texture pointer in OpenGL to the texture
    Gdx.gl10.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    // This is the function I found in LibGDX that I think I am supposed to use?
    mTexture.bind();

    // Some "switch-flipping" in OpenGL
    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
            GL10.GL_NEAREST);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D,
            GL10.GL_TEXTURE_MAG_FILTER,
            GL10.GL_LINEAR);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
            GL10.GL_CLAMP_TO_EDGE);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
            GL10.GL_CLAMP_TO_EDGE);

    Gdx.gl10.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
            GL10.GL_REPLACE);

    // This tells OpenGL to assign my Texture to the 3D Image
    Gdx.gl10.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, 256, 256, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, mTexture);

    // Finally, this draws the objects to the screen
    Gdx.gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}

我的问题

你如何将图像直接解码为BufferJava中的a?如果无法做到这一点,那么我应该如何尝试在 LibGDX 中对我的 3D 对象进行纹理处理?我应该咨询其他资源吗?

调试信息

最后更新时间:美国东部标准时间 2013 年 3 月 19 日下午 12:45

这是与我的应用程序当前调试过程相关的一些信息。随着我在这个问题上的进展,我会更新这个:

  • 目前,当我运行我的应用程序时,我收到一个错误Invalid memory access of location 0x0 rip=0x11dc77564,也许这个实现是正确的,我只是在其他地方遗漏了一些语法?
  • 我目前正在调查我在筛选一些论坛后发现的这个额外资源。
  • 看来该Mesh对象将是此处的正确路线。我将尝试执行此操作并更新我的结果!我之前无法找到它,因为 LibGDX 团队认为它“已弃用”,所以我不确定它是否会很快被替换。

补充信息

回答我的问题时应该考虑的一些事情是:

  • 应该注意的是,我正在使用LibGDX Game Engine执行此操作,因此,我还将在他们的论坛上发布有关此问题的帖子。

  • 此外,似乎有很多方法可以BufferedImage从 Image 中获取 a ,但是没有办法从中提取Buffera BufferedImage。我只是在这里忽略了一些明显的东西吗?BufferedImages 真的是我所需要的吗?

  • 我不希望只在我的构建路径中包含 Android SDK 并使用他们的简单BitmapFactory.decodeResource(<your_image_here>)方法。

  • 出于兼容性原因,我目前正在尝试使用 OpenGL ES 1.0 来实现这一点。

4

1 回答 1

2

我认为您想避免使用原始 OpenGL 纹理和缓冲区 API,并坚持使用 LibgdxMeshTexture包装器。他们隐藏了一堆 OpenGL 细节。当然,如果您有兴趣了解 OpenGL 的详细信息,这不会有什么帮助。(但也许您可以使用 Libgdx API 来处理事情,然后查看它们的源代码以了解实际发生的情况)。

第一步是确保您的Mesh(或您的原始mVertexBufferOpenGL 顶点列表,如果您不使用 a Mesh)包含每个顶点的有效 (u, v) 纹理坐标。这些坐标将在渲染时引用“当前”纹理。请参阅https://code.google.com/p/libgdx/wiki/MeshColorTexture#Texture

首先,定义您的 Mesh 以包含每个顶点的纹理信息:

mesh = new Mesh(true, 3, 3, 
            new VertexAttribute(Usage.Position, 3, "a_position"),
            new VertexAttribute(Usage.ColorPacked, 4, "a_color"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));

(这个网格也有颜色数据,但如果你不想混合原始颜色数据,你可以用“a_color”去掉这条线。)

另一个准备步骤是将纹理文件加载到 Libgdx 纹理中。假设文件打包在标准的“资产”位置,您应该能够使用相对路径加载它:

Texture texture = new Texture("path/to/image.bmp");

Libgdx 通常可以加载和解析 BMP、PNG 和 JPEG 文件格式。对于其他格式,我认为您需要自己创建一个Pixmap对象,然后将其插入Texture.

其次,确保每个顶点都有与之关联的 (u,v) 纹理坐标:

mesh.setVertices(new float[] { -0.5f, -0.5f, 0, Color.toFloatBits(255, 0, 0, 255), 0, 1,
                                0.5f, -0.5f, 0, Color.toFloatBits(0, 255, 0, 255), 1, 1
                                0, 0.5f, 0, Color.toFloatBits(0, 0, 255, 255), 0.5f, 0 });

上面的每一行都为每个顶点定义了“(x, y, z, rgba, u, v)”。(“rgba”是将整个颜色压缩成一个浮点数。)

至此,您已经定义了Mesh带有Color信息和纹理 (u, v) 坐标的 a。

第二步是,在render调用过程中,绑定你的纹理,所以 (u, v) 坐标中Mesh有一些东西可以参考:

texture.bind();
mesh.render(GL10.GL_TRIANGLES, 0, 3);

您不需要直接使用任何 OpenGL 纹理或顶点 API。

于 2013-03-19T16:52:14.157 回答