带纹理iPhone的OpenGL ES 1.1 2D环

时间:2011-09-13 21:45:26

标签: iphone opengl-es textures geometry

我将非常感谢以下方面的帮助。我正在尝试在OpenGL ES 1.1中为iPhone游戏渲染另一个对象之上的环形状。戒指本质上是两个圆圈之间的差异。

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

我原本希望创建一个圆圈,并将纹理应用到该圆圈。纹理是占据纹理的整个尺寸的环的图片(即,环的外部​​接触纹理的四个边)。环的中心在使用的图形中是透明的。

它需要在中心透明,让下方的物体显示出来。环正确渲染,但在中心是一个坚固的黑色质量,不透明。我很感激有任何帮助来解决这个问题。

我用来渲染圆圈的代码如下(根本没有优化:我会在适当的缓冲区中移动coords以用于以后的代码,但是我已经用这种方式编写它以试图让它工作。 ..)

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上仍然是一个菜鸟,并试图绕过它。提前感谢任何可能有帮助的指针/片段。

感谢。

1 个答案:

答案 0 :(得分:1)

你需要做的是使用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(对象),这正是您所需要的,在这种情况下,您实际上不需要启用混合甚至将对象排序到前面。