将二维位图转换成三维立方体模型的有效方法?

时间:2023-02-09 13:24:58

I want to create cube model of a 32x32 bitmap in opengl. For example, the result should look something like this given a 2D bitmap of Bob-omb from Super Mario: http://fc02.deviantart.net/fs49/f/2009/186/f/a/Bob_omb_in_Minecraft_by_Luafox.png The idea is to represent each 2D pixel from the bitmap as a 3D cube.

我想在opengl中创建32x32位图的立方体模型。例如,如果给出一个来自超级马里奥的Bob-omb的2D位图:http://fc02.deviantart.net/fs49/f/2009/186/ f/f/f/a/a/bob_omb_in_minecraft_by_luafox.png,那么结果应该是这样的。

Each model will represent an enemy in a game so I need to be able to render these quickly. What would be a good way of doing this?

每个模型都代表一个游戏中的敌人,所以我需要能够快速渲染它们。有什么好办法呢?

One attempt I've made is to generate a static 3D model from the bitmap by first creating a 32x32x2 grid of vertices and then creating triangles from these vertices in the appropriate places to form the cube faces. One big problem I'm having though is how to store the colors and normals for the faces. The triangles of each face need to share a vertex and that shared vertex needs to store the color and the normal for that face. However, I don't think I have enough vertices for each face to have the appropriate color and normal. I can't think of an elegant way to solve this.

我所做的一个尝试是从位图中生成一个静态的3D模型,首先创建一个32x32x2的顶点网格,然后在适当的位置创建这些顶点的三角形,以形成立方体的面。我遇到的一个大问题是如何存储人脸的颜色和法线。每个面的三角形需要共享一个顶点,这个共享顶点需要为那个面存储颜色和法线。然而,我不认为我有足够的顶点给每个面以合适的颜色和法线。我想不出一个优雅的方法来解决这个问题。

3 个解决方案

#1


0  

Regarding storing colors and normals for the faces; I think you have to accept that you need to duplicate vertices in the same position for the different faces. If two vertices share some attributes but differ in others, they are essentially different - even if one attribute that they share is their position.

关于存储人脸的颜色和法线;我认为你必须接受,你需要在相同的位置复制不同的顶点。如果两个顶点共享一些属性,但在其他属性上有所不同,那么它们本质上是不同的——即使它们共享的一个属性是它们的位置。

So, you should build some VBOs, with duplicate vertices as necessary. You may want to run this as a design-time step and save the results into a convenient format to save some work at runtime.

因此,您应该构建一些VBOs,在必要时使用重复的顶点。您可能希望将其作为设计时步骤运行,并将结果保存为方便的格式,以便在运行时保存一些工作。

edit: That doesn't mean that you need to have separate vertices for every single corner of every face of every cube. Actually, the cheapest way to render what you want (while the blocks are together) with a reasonably easy implementation would probably be to render the front and back each as two triangles, using a texture for colour, GL_MAG_FILTER, GL_NEAREST sampling and careful alignment of texture coordinates, using a pixel shader to clip on transparent texels.

编辑:这并不意味着您需要为每个立方体的每个面每个角落都有单独的顶点。实际上,最便宜的方式来呈现你想要的东西(虽然块在一起),相当容易实现可能会呈现前后各两个三角形,使用纹理颜色,GL_MAG_FILTER,GL_NEAREST采样和小心对齐的纹理坐标,使用像素着色器夹在透明的纹素。

You will then need to do a bit more work (not necessarily at run time) to work out which faces will be visible from the sides, and make each of those as geometry (all of that geometry being a single static VBO to display, thus reducing both the number of draw calls and geometry cost as compared to for example calling a -deprecated, although still often useful- display list for each cube). Again, with care you can ensure that this precisely joins with the invisible parts of the front and back faces.

你将需要做更多的工作(不一定是在运行时),面临着来自双方的可见,和使每个几何(所有的几何作为一个单一的静态VBO显示,从而减少绘制调用的数量和几何成本相比,例如调用弃用,尽管通常仍然有用——显示列表为每个数据集)。同样,如果小心的话,您可以确保它与前脸和后脸的隐形部分精确地结合在一起。

If you do then want to have your enemies blow up and have the constituent cubes go their separate ways, you can then switch to a more expensive version displaying every single cube.

如果你真的想让你的敌人爆炸,让组成立方体各走各的路,你可以切换到更贵的版本,显示每个立方体。

#2


2  

You'll be fastest if you render the front face as a single texture mapped GL_QUAD, using alpha and GL_ALPHA_TEST for the 'transparent' parts. You then make the boundary, i.e. the non front-facing squares, as one or more GL_QUAD_STRIPs.

如果将前面的面板作为一个纹理映射到GL_QUAD,使用alpha和GL_ALPHA_TEST作为“透明”部分,那么您将是最快的。然后,将边界(即非正面的正方形)设置为一个或多个gl_quad_strip。

If you are determined to draw the sprite as a series of actual cubes, for example if you want to blow up the sprite into separate cubes, or if you have very detailed textures on the small cube faces, then make a display list for one cube and call that display list repeatedly.

如果你决心把雪碧的一系列实际的数据集,例如,如果你想炸毁雪碧为独立的数据集,或者如果你有非常详细的材质的小立方体脸上,然后显示列表为一个多维数据集和反复调用,显示列表。

#3


0  

Just a hint on how you can find some interesting readings about that: search for "voxel". http://en.wikipedia.org/wiki/Voxel

关于如何找到一些有趣的阅读资料,这里有一个提示:搜索“体素”。http://en.wikipedia.org/wiki/Voxel

Maybe you would like to take a look to the source code of the open source game engines Cube/Sauerbraten, that are based on cubes subdivision for the maps, and come with a nice in-game editor: http://sauerbraten.org/

也许您想看一下开源游戏引擎Cube/Sauerbraten的源代码,它是基于立方体对地图的细分,并且有一个不错的游戏编辑器:http://sauerbraten.org/

#1


0  

Regarding storing colors and normals for the faces; I think you have to accept that you need to duplicate vertices in the same position for the different faces. If two vertices share some attributes but differ in others, they are essentially different - even if one attribute that they share is their position.

关于存储人脸的颜色和法线;我认为你必须接受,你需要在相同的位置复制不同的顶点。如果两个顶点共享一些属性,但在其他属性上有所不同,那么它们本质上是不同的——即使它们共享的一个属性是它们的位置。

So, you should build some VBOs, with duplicate vertices as necessary. You may want to run this as a design-time step and save the results into a convenient format to save some work at runtime.

因此,您应该构建一些VBOs,在必要时使用重复的顶点。您可能希望将其作为设计时步骤运行,并将结果保存为方便的格式,以便在运行时保存一些工作。

edit: That doesn't mean that you need to have separate vertices for every single corner of every face of every cube. Actually, the cheapest way to render what you want (while the blocks are together) with a reasonably easy implementation would probably be to render the front and back each as two triangles, using a texture for colour, GL_MAG_FILTER, GL_NEAREST sampling and careful alignment of texture coordinates, using a pixel shader to clip on transparent texels.

编辑:这并不意味着您需要为每个立方体的每个面每个角落都有单独的顶点。实际上,最便宜的方式来呈现你想要的东西(虽然块在一起),相当容易实现可能会呈现前后各两个三角形,使用纹理颜色,GL_MAG_FILTER,GL_NEAREST采样和小心对齐的纹理坐标,使用像素着色器夹在透明的纹素。

You will then need to do a bit more work (not necessarily at run time) to work out which faces will be visible from the sides, and make each of those as geometry (all of that geometry being a single static VBO to display, thus reducing both the number of draw calls and geometry cost as compared to for example calling a -deprecated, although still often useful- display list for each cube). Again, with care you can ensure that this precisely joins with the invisible parts of the front and back faces.

你将需要做更多的工作(不一定是在运行时),面临着来自双方的可见,和使每个几何(所有的几何作为一个单一的静态VBO显示,从而减少绘制调用的数量和几何成本相比,例如调用弃用,尽管通常仍然有用——显示列表为每个数据集)。同样,如果小心的话,您可以确保它与前脸和后脸的隐形部分精确地结合在一起。

If you do then want to have your enemies blow up and have the constituent cubes go their separate ways, you can then switch to a more expensive version displaying every single cube.

如果你真的想让你的敌人爆炸,让组成立方体各走各的路,你可以切换到更贵的版本,显示每个立方体。

#2


2  

You'll be fastest if you render the front face as a single texture mapped GL_QUAD, using alpha and GL_ALPHA_TEST for the 'transparent' parts. You then make the boundary, i.e. the non front-facing squares, as one or more GL_QUAD_STRIPs.

如果将前面的面板作为一个纹理映射到GL_QUAD,使用alpha和GL_ALPHA_TEST作为“透明”部分,那么您将是最快的。然后,将边界(即非正面的正方形)设置为一个或多个gl_quad_strip。

If you are determined to draw the sprite as a series of actual cubes, for example if you want to blow up the sprite into separate cubes, or if you have very detailed textures on the small cube faces, then make a display list for one cube and call that display list repeatedly.

如果你决心把雪碧的一系列实际的数据集,例如,如果你想炸毁雪碧为独立的数据集,或者如果你有非常详细的材质的小立方体脸上,然后显示列表为一个多维数据集和反复调用,显示列表。

#3


0  

Just a hint on how you can find some interesting readings about that: search for "voxel". http://en.wikipedia.org/wiki/Voxel

关于如何找到一些有趣的阅读资料,这里有一个提示:搜索“体素”。http://en.wikipedia.org/wiki/Voxel

Maybe you would like to take a look to the source code of the open source game engines Cube/Sauerbraten, that are based on cubes subdivision for the maps, and come with a nice in-game editor: http://sauerbraten.org/

也许您想看一下开源游戏引擎Cube/Sauerbraten的源代码,它是基于立方体对地图的细分,并且有一个不错的游戏编辑器:http://sauerbraten.org/