简体   繁体   English

带有纹理iPhone的OpenGL ES 1.1 2D戒指

[英]OpenGL ES 1.1 2D Ring with Texture iPhone

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. 我正在尝试为iPhone游戏在OpenGL ES 1.1中的另一个对象上渲染环形形状。 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 (ie 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. 我仍在尝试环的宽度,但是环的半径很可能是整个圆的1/4宽度。

Still a noob at OpenGL and trying to wrap my head around it. 还是OpenGL的新手,并试图将我的头缠住它。 Thanks in advance for any pointers / snippets that might help. 在此先感谢您提供的所有提示/摘要。

Thanks. 谢谢。

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). 您需要做的是使用Alpha混合,它可以根据颜色的Alpha值将它们彼此混合(在纹理中心为零,表示透明)。 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: 并设置将颜色的alpha分量用作不透明度的标准混合功能:

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. 但是,如果仅将alpha用作对象/无对象指示符(仅值为0或1),并且不需要部分透明的颜色(例如玻璃),则无需对对象进行排序。 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. 在这种情况下,您应该使用alpha测试根据其alpha值丢弃片段,以使它们不会污染深度缓冲区并防止渲染后面的对象。 An alpha test set with 具有的Alpha测试集

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. 只会渲染alpha大于0.5的片段(〜像素),并将完全丢弃所有其他片段。 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. 如果您只有0(无对象)或1(对象)的alpha值,这正是您所需要的,在这种情况下,您实际上不需要启用混合甚至将对象排序回到最前面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM