本文介绍了在OpenGL ES中使用单个glDrawElement(triangle_strip ...)调用绘制一个圆角矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Opengl es中绘制一个圆角矩形,用一个glDraw调用。
我也试过了。并在答案中分享。

I want to draw a rounded rectangle in Opengl es, with a single glDraw call.I have also tried it. and shared it in the answer.

希望它会有所帮助。

推荐答案

我修改了代码以获取输入(TopLeft Corner Position,width和height),并为每个圆角和其纹理坐标动态生成10个顶点。

I modified the code to get the inputs ( TopLeft Corner Position, width and height) and dynamically generating 10 vertices for each rounded corners and its texture coordinates.

     // Vertices and Texture Coordinates Generation.
    Input: Width and Height, Sx, Sy,Sz (Top Left Vertex Position)
    // To get smooth rounded rectangle, 10 vertices are generated for each rounded corner 

    float Sx = 0.0;
    float Sy = 0.0;
    float verCz = Sz = 0.0;

    float rad;

    if (fWidth > fHeight)
    {
        rad = 0.3f * (fHeight/fWidth);
    }
    else 
    {
        rad = 0.3f * (fWidth/fHeight);
    }

    float invWidth    = 1.0/fWidth ;
    float invHeight   = 1.0/fHeight;
    float radbywidth  = rad * invWidth;
    float radbyheight = rad * invHeight;

    float texCx   = (Sx + fWidth - rad) * invWidth;
    float texCy   = (Sy - rad)          * invHeight; 

    //0 to 9 vertices
    for (i = 0; i <= 90; i = i + 10)
    {
        vertices[iVertCnt++]  = (Sx + fWidth - rad) + (cos(degreesToRadians(i)) * rad); //centre point-X + r*cos
        vertices[iVertCnt++]  = (Sy - rad)          + (sin(degreesToRadians(i)) * rad); //centre point-Y + r*sin
        vertices[iVertCnt++]  = verCz;

        texcoord_RndRect [tex++]  = texCx + (cos(degreesToRadians(i)) * radbywidth); 
        texcoord_RndRect [tex++]  = texCy + (sin(degreesToRadians(i)) * radbyheight); 
    }

    GLfloat vert1[] =
    {
        (Sx + rad),   Sy       , 0.0f,  // 10
        (Sx + rad),   (Sy -rad), 0.0f,  // 11 
    };

    for (i = 0; i < 6; i = i+3)
    {
        vertices[iVertCnt++]        =  vert1[i];
        vertices[iVertCnt++]        =  vert1[i+1];
        vertices[iVertCnt++]        =  vert1[i+2];
        texcoord_RndRect [tex++]    =  vert1[i]   * invWidth;
        texcoord_RndRect [tex++]    =  vert1[i+1] * invHeight;
    }

    texCx   =  (Sx + rad) * invWidth;
    texCy   =  (Sy - rad) * invHeight; 
    ////12 to 21 vertices
    for (i = 90; i <= 180; i = i + 10)   
    {
        vertices[iVertCnt++]  = (Sx + rad) + (cos(degreesToRadians(i)) * rad); //centre point-X + r*cos
        vertices[iVertCnt++]  = (Sy - rad) + (sin(degreesToRadians(i)) * rad); //centre point-Y + r*sin
        vertices[iVertCnt++]  = verCz;

        texcoord_RndRect [tex++]  = texCx +(cos(degreesToRadians(i)) * radbywidth);  // texture will be from 0 to 1 only
        texcoord_RndRect [tex++]  = texCy +(sin(degreesToRadians(i)) * radbyheight); 
    }

    GLfloat vert2[] =
    {
        (Sx)        , (Sy - fHeight + rad),  0.0f,  // 22 
        (Sx + rad ),  (Sy - fHeight + rad),  0.0f,  // 23 
    };

    for (i = 0; i < 6; i = i+3)
    {
        vertices[iVertCnt++]        =  vert2[i];
        vertices[iVertCnt++]        =  vert2[i+1];
        vertices[iVertCnt++]        =  vert2[i+2];
        texcoord_RndRect [tex++]    =  vert2[i]   * invWidth;
        texcoord_RndRect [tex++]    =  vert2[i+1] * invHeight;
    }


    texCx   = (Sx + rad )          * invWidth;
    texCy   = (Sy - fHeight + rad)  * invHeight;
    ////24 to 33 vertices
    for (i = 180; i <= 270; i = i + 10) 
    {
        vertices[iVertCnt++]  = (Sx + rad )         + (cos(degreesToRadians(i)) * rad); //centre point-X + r*cos
        vertices[iVertCnt++]  = (Sy - fHeight + rad) + (sin(degreesToRadians(i)) * rad); //centre point-Y + r*sin
        vertices[iVertCnt++]  = verCz;

        texcoord_RndRect [tex++]  = texCx +(cos(degreesToRadians(i)) * radbywidth);  
        texcoord_RndRect [tex++]  = texCy +(sin(degreesToRadians(i)) * radbyheight); 
    }

    GLfloat vert3[] =
    {
        (Sx + fWidth - rad),   (Sy - fHeight)       ,  0.0f,    // 34
        (Sx + fWidth - rad),   (Sy - fHeight + rad) ,  0.0f,    // 35
    };

    for (i = 0; i < 6; i = i+3)
    {
        vertices[iVertCnt++]        =  vert3[i];
        vertices[iVertCnt++]        =  vert3[i+1];
        vertices[iVertCnt++]        =  vert3[i+2];
        texcoord_RndRect [tex++]    =  vert3[i]   * invWidth;
        texcoord_RndRect [tex++]    =  vert3[i+1] * invHeight;
    }

    //36th vertices
    vertices[iVertCnt++]  = (Sx + fWidth - rad);
    vertices[iVertCnt++]  = (Sy - fHeight + rad);
    vertices[iVertCnt++]  = 0.0f;

    texcoord_RndRect [tex++]  = (Sx + fWidth - rad) * invWidth;  // 11
    texcoord_RndRect [tex++]  = (Sy - fHeight + rad)* invHeight;

    texCx   = (Sx + fWidth - rad) * invWidth;
    texCy   = (Sy - fHeight + rad) *invHeight ; 

    ////37 to 46 to  vertices
    for (i = 270; i <= 360; i = i + 10) 
    {
        vertices[iVertCnt++]  = (Sx + fWidth - rad)  + (cos(degreesToRadians(i)) * rad); //centre point-X + r*cos
        vertices[iVertCnt++]  = (Sy - fHeight + rad) + (sin(degreesToRadians(i)) * rad); //centre point-Y + r*sin
        vertices[iVertCnt++]  = 0.0f;

        texcoord_RndRect [tex++]  = texCx +(cos(degreesToRadians(i))  * radbywidth);  
        texcoord_RndRect [tex++]  = texCy +(sin(degreesToRadians(i))  * radbyheight); 
    }

    GLfloat vert4[] =
    {
        (Sx + fWidth )      ,    (Sy - rad),  0.0f, // 47 
        (Sx + fWidth - rad) ,    (Sy -rad ),  0.0f, // 48 

    };

    for (i = 0; i < 6; i = i+3)
    {
        vertices[iVertCnt++]        =  vert4[i];
        vertices[iVertCnt++]        =  vert4[i+1];
        vertices[iVertCnt++]        =  vert4[i+2];
        texcoord_RndRect [tex++]    =  vert4[i]   * invWidth;
        texcoord_RndRect [tex++]    =  vert4[i+1] * invHeight;
    }

            // Display
    ///////////////////////////////////////
    GLushort indices_topright[] = 
    {   
        0,1,2,3,4,5,6,7,8,9,10,11
    };

    GLushort indices_topleft[] = 
    {   
        12,13,14,15,16,17,18,19,20,21,22,23
    };

    GLushort indices_bottomleft[] = 
    {   
        24,25,26,27,28,29,30,31,32,33,34,35
    };

    GLushort indices_bottomright[] = 
    {   
        36,37,38,39,40,41,42,43,44,45,46,47,48,11,23
    };
    glDrawElements(GL_TRIANGLE_FAN, (sizeof(indices_topright)/sizeof(indices_topright[0])), GL_UNSIGNED_SHORT, indices_topright);
    glDrawElements(GL_TRIANGLE_FAN, (sizeof(indices_topleft)/sizeof(indices_topleft[0])), GL_UNSIGNED_SHORT, indices_topleft);
    glDrawElements(GL_TRIANGLE_FAN, (sizeof(indices_bottomleft)/sizeof(indices_bottomleft[0])), GL_UNSIGNED_SHORT, indices_bottomleft);
    glDrawElements(GL_TRIANGLE_FAN, (sizeof(indices_bottomright)/sizeof(indices_bottomright[0])), GL_UNSIGNED_SHORT, indices_bottomright);
    ////////////////////////

这段代码适用于我。

这篇关于在OpenGL ES中使用单个glDrawElement(triangle_strip ...)调用绘制一个圆角矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 16:58