我正在尝试在我正在开发的游戏中实现一些简单的3D功能。我正在利用 LibGDX游戏引擎来实现这个目标,因为它似乎很好地与OpenGL ES集成,但是由于我无法弄清楚如何创建一个简单的{{1来自Java中的图像的对象。
我的目标是让一个立方体在3D空间中旋转,上面有一些纹理。问题是,虽然我设法渲染立方体并让它旋转,但我似乎找不到任何关于如何将图像实际解码为Buffer
以便纹理立方体的教程,代码示例或文档。我已经找到了很多说明如何在Android中执行此操作的示例,但这限制了您必须在Android SDK中使用Buffer
方法,这对我来说不是一个选项,因为我试图允许我的代码可移植到许多平台。
正是出于这个原因,我得出的结论是,我必须找到一种方法将图像(BitmapFactory.decodeResource(<your_image here>)
文件)解码为.bmp
,以便利用{{1我发现用OpenGL ES打包的方法。
我已经尝试了许多替代方案来尝试寻找解决方案,其中一些包括:
以下是我用于渲染多维数据集的一些代码。为了清楚起见,省略了许多OpenGL“切换翻转”,所以如果你认为我错过了什么,请发表评论,我会确认它是否只是在另一个班级的另一部分。
我知道这段代码会过于扼要筛选,所以我尽力在必要时对其进行评论。
请注意,此代码表示我当前的实现,并且是与下面的“调试信息”部分相关联的代码。
Texture.bind()
如何将图像直接解码为Java中的Texture
?如果无法做到这一点,那么我该如何尝试在LibGDX中构建我的3D对象呢?我还应该咨询其他资源吗?
最后更新时间:2013年3月19日美国东部时间下午12:45
以下是与我的应用程序的当前调试过程相关的一些信息。随着我逐步解决这个问题,我将对此进行更新:
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);
}
,也许这个实现是正确的,我只是在其他地方遗漏了一些语法?Buffer
对象是正确的路线。我会尝试继续这个实现并更新我的结果!我以前无法找到它,因为它被LibGDX团队认为是“弃用”,所以我不确定这是否会很快被替换。回答我的问题时应该考虑的一些事项是:
应该注意的是,我使用LibGDX Game Engine进行此操作,因此,我还将在论坛上发布有关此问题的信息。
此外,似乎有很多方法可以从图片中获取Invalid memory access of location 0x0 rip=0x11dc77564
,但是无法从Mesh
中提取BufferedImage
。我只是忽略了这里明显的东西吗? Buffer
真的应该是我需要的吗?
我不希望在构建路径中包含Android SDK并使用简单的BufferedImage
方法。
出于兼容性原因,我目前正在尝试使用OpenGL ES 1.0实现此目的。
答案 0 :(得分:2)
我认为你想避免原始的OpenGL纹理和缓冲API,并坚持使用Libgdx Mesh
和Texture
包装器。他们隐藏了一堆OpenGL细节。当然,如果您有兴趣了解OpenGL的详细信息,这将无济于事。 (但也许你可以使用Libgdx API,然后查看它们的来源,看看到底发生了什么)。
第一步是确保您的Mesh
(或您的原始mVertexBuffer
OpenGL顶点列表(如果您没有使用Mesh
)包含有效(u,v)纹理坐标与每个顶点。这些坐标将在渲染时引用“当前”纹理。见https://code.google.com/p/libgdx/wiki/MeshColorTexture#Texture。
首先,定义网格以包含每个顶点的纹理信息:
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)坐标。
第二步是在render
调用期间绑定纹理,因此Mesh
中的(u,v)坐标可以引用:
texture.bind();
mesh.render(GL10.GL_TRIANGLES, 0, 3);
您不需要直接使用任何OpenGL纹理或顶点API。