OpenGL ES 1.1 2D 环带纹理 iPhone

发布于 2024-12-04 05:13:50 字数 2107 浏览 2 评论 0原文

我希望在以下方面得到一些帮助。我正在尝试在 OpenGL ES 1.1 中为 iPhone 游戏在另一个对象顶部渲染一个环形。环本质上是两个圆之间的差异。

我为戒指本身准备了一张图形,它的中心是透明的。

我原本希望只创建一个圆圈,然后将纹理应用到它上面。纹理是占据纹理完整尺寸的环的图片(即环的外侧接触纹理的四个边)。在所使用的图形中,环的中心是透明的。

它的中心需要是透明的,以便让下面的物体显示出来。环渲染正确,但中心是一个实心黑色块,不透明。我将不胜感激任何帮助解决这个问题。

我用来渲染圆圈的代码如下(根本没有优化:我将在适当的缓冲区等中移动坐标以供以后的代码使用,但我以这种方式编写它只是为了尝试让它工作......)

if (!m_circleEffects.empty())
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    int segments = 360;
    for (int i = 0; i < m_circleEffects.size(); i++)
    {            
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glTranslatef(m_circleEffects[i].position.x, m_circleEffects[i].position.y, 0);

        glBindTexture(GL_TEXTURE_2D, m_Texture);

        float radius = 1.764706;

        GLfloat circlePoints[segments * 3];
        GLfloat textureCoords[segments * 2];

        int circCount = 3;
        int texCount = 2;

        for (GLfloat i = 0; i < 360.0f; i += (360.0f / segments))
        {
            GLfloat pos1 = cosf(i * M_PI / 180);
            GLfloat pos2 = sinf(i * M_PI / 180);

            circlePoints[circCount] = pos1 * radius;
            circlePoints[circCount+1] = pos2 * radius;
            circlePoints[circCount+2] = (float)z + 5.0f;

            circCount += 3;

            textureCoords[texCount] = pos1 * 0.5 + 0.5;
            textureCoords[texCount+1] = pos2 * 0.5 + 0.5;

            texCount += 2;
        }

        glVertexPointer(3, GL_FLOAT, 0, circlePoints);
        glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);

        glDrawArrays(GL_TRIANGLE_FAN, 0, segments);  
    }

    m_circleEffects.clear();  

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

我一直在尝试创建一个环而不是一个圆圈,但我还没有能够做到这一点。

我想最好的方法实际上不是创建一个圆,而是创建一个环,然后也获得等效的纹理坐标。我仍在试验环的宽度,但是,环的半径很可能是整个圆宽度的 1/4。

我仍然是 OpenGL 的菜鸟,并试图理解它。预先感谢任何可能有帮助的指示/片段。

谢谢。

I would appreciate some help with the following. I'm trying to render a ring shape on top of another object in OpenGL ES 1.1 for an iPhone game. The ring is essentially the difference between two circles.

I have a graphic prepared for the ring itself, which is transparent in the centre.

I had hoped to just create a circle, and apply the texture to that. The texture is a picture of the ring that occupies the full size of the texture (i.e. the outside of the ring touches the four sides of the texture). The centre of the ring is transparent in the graphic being used.

It needs to be transparent in the centre to let the object underneath show through. The ring is rendering correctly, but is a solid black mass in the centre, not transparent. I'd appreciate any help to solve this.

Code that I'm using to render the circle is as follows (not optimised at all: I will move the coords in proper buffers etc for later code, but I have written it this way to just try and get it working...)

if (!m_circleEffects.empty())
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    int segments = 360;
    for (int i = 0; i < m_circleEffects.size(); i++)
    {            
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glTranslatef(m_circleEffects[i].position.x, m_circleEffects[i].position.y, 0);

        glBindTexture(GL_TEXTURE_2D, m_Texture);

        float radius = 1.764706;

        GLfloat circlePoints[segments * 3];
        GLfloat textureCoords[segments * 2];

        int circCount = 3;
        int texCount = 2;

        for (GLfloat i = 0; i < 360.0f; i += (360.0f / segments))
        {
            GLfloat pos1 = cosf(i * M_PI / 180);
            GLfloat pos2 = sinf(i * M_PI / 180);

            circlePoints[circCount] = pos1 * radius;
            circlePoints[circCount+1] = pos2 * radius;
            circlePoints[circCount+2] = (float)z + 5.0f;

            circCount += 3;

            textureCoords[texCount] = pos1 * 0.5 + 0.5;
            textureCoords[texCount+1] = pos2 * 0.5 + 0.5;

            texCount += 2;
        }

        glVertexPointer(3, GL_FLOAT, 0, circlePoints);
        glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);

        glDrawArrays(GL_TRIANGLE_FAN, 0, segments);  
    }

    m_circleEffects.clear();  

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

I've been experimenting with trying to create a ring rather than a circle, but I haven't been able to get this right yet.

I guess that the best approach is actually to not create a circle, but a ring, and then get the equivalent texture coordinates as well. I'm still experimenting with the width of the ring, but, it is likely that the radius of the ring is 1/4 width of the total circle.

Still a noob at OpenGL and trying to wrap my head around it. Thanks in advance for any pointers / snippets that might help.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

贱人配狗天长地久 2024-12-11 05:13:50

您需要做的是使用 Alpha 混合,它根据颜色的 Alpha 值(您所说的在纹理中心为零,意味着透明)将颜色相互混合。因此,您必须通过以下方式启用混合:

glEnable(GL_BLEND);

并设置标准混合函数以使用颜色的 alpha 分量作为不透明度:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

但请始终记住,为了看到透明对象正确地混合在后面的对象上,您需要在后面渲染对象到前台订购。

但是,如果您仅使用 alpha 作为对象/无对象指示符(仅值 0 或 1)并且不需要部分透明的颜色(例如玻璃),则无需对对象进行排序。在这种情况下,您应该使用 alpha 测试根据 alpha 值丢弃片段,这样它们就不会污染深度缓冲区并防止渲染后面的对象。 alpha 测试集

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);

只会渲染 alpha 大于 0.5 的片段(~像素),并将完全丢弃所有其他片段。如果您只有 alpha 值 0(无对象)或 1(对象),这正是您所需要的,在这种情况下,您实际上不需要启用混合,甚至不需要将对象从后到前排序。

What you need to do is use alpha blending, which blends colors into each other based on their alpha values (which you say are zero in the texture center, meaning transparent). So you have to enable blending by:

glEnable(GL_BLEND);

and set the standard blending functions for using a color's alpha component as opacity:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

But always keep in mind in order to see the transparent object correctly blended over the object behind, you need to render your objects in back to front order.

But if you only use the alpha as a object/no-object indicator (only values of either 0 or 1) and don't need partially transparent colors (like glass, for example), you don't need to sort your objects. In this case you should use the alpha test to discard fragments based on their alpha values, so that they don't pollute the depth-buffer and prevent the behind lying object from being rendered. An alpha test set with

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);

will only render fragments (~pixels) that have an alpha of more than 0.5 and will completely discard all other fragments. If you only have alpha values of 0 (no object) or 1 (object), this is exactly what you need and in this case you don't actually need to enable blending or even sort your objects back to front.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文