将 2D 位图转换为 3D 立方体模型的有效方法?
我想在 opengl 中创建 32x32 位图的立方体模型。例如,给定《超级马里奥》中 Bob-omb 的 2D 位图,结果应如下所示: http://fc02.deviantart.net/fs49/f/2009/186/f/a/Bob_omb_in_Minecraft_by_Luafox.png 这个想法是将位图中的每个 2D 像素表示为3D 立方体。
每个模型都代表游戏中的敌人,因此我需要能够快速渲染它们。这样做的好方法是什么?
我所做的一项尝试是从位图生成静态 3D 模型,方法是首先创建 32x32x2 的顶点网格,然后在适当的位置从这些顶点创建三角形以形成立方体面。我遇到的一个大问题是如何存储面部的颜色和法线。每个面的三角形需要共享一个顶点,并且该共享顶点需要存储该面的颜色和法线。但是,我认为我没有足够的顶点让每个面具有适当的颜色和法线。我想不出一个优雅的方法来解决这个问题。
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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果将正面渲染为单个纹理映射的 GL_QUAD,并使用 alpha 和 GL_ALPHA_TEST 作为“透明”部分,那么速度会最快。然后将边界(即非正面方块)设置为一个或多个 GL_QUAD_STRIP。
如果您决定将精灵绘制为一系列实际的立方体,例如,如果您想将精灵放大为单独的立方体,或者如果您在小立方体面上有非常详细的纹理,则为一个立方体制作一个显示列表并重复调用该显示列表。
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.
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.
关于存储面部的颜色和法线;我认为您必须接受需要在不同面的相同位置复制顶点。如果两个顶点共享某些属性但其他属性不同,则它们本质上是不同的 - 即使它们共享的一个属性是它们的位置。
因此,您应该构建一些 VBO,并根据需要使用重复的顶点。您可能希望将其作为设计时步骤运行,并将结果保存为方便的格式,以在运行时节省一些工作。
编辑:这并不意味着您需要为每个立方体的每个面的每个角都有单独的顶点。实际上,通过相当简单的实现来渲染您想要的内容(当块在一起时)的最便宜的方法可能是将正面和背面分别渲染为两个三角形,使用颜色纹理,GL_MAG_FILTER,GL_NEARESTGL_MAG_FILTER,GL_NEAREST 纹理坐标的采样和仔细对齐,使用像素着色器在透明纹理像素上进行剪辑。
然后,您需要做更多的工作(不一定在运行时)来计算出哪些面从侧面可见,并将每个面设为几何体(所有这些几何体都是要显示的单个静态 VBO,因此与例如调用每个立方体的显示列表相比,减少了绘制调用的数量和几何成本(不推荐使用,尽管仍然经常有用)。同样,小心地确保它与正面和背面的不可见部分精确连接。
如果你确实想让你的敌人爆炸并让组成的立方体分道扬镳,那么你可以切换到显示每个立方体的更昂贵的版本。
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.
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.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.
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.
只是提示您如何找到一些有趣的读物:搜索“voxel”。
http://en.wikipedia.org/wiki/Voxel
也许你想看一下开源游戏引擎 Cube/Sauerbraten 的源代码,它们基于地图的立方体细分,并附带一个不错的游戏内编辑器:
http://sauerbraten.org/
Just a hint on how you can find some interesting readings about that: search for "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/