Draw a rounded rectangle using a single call to glDrawElement (triangle_strip ...) in OpenGL ES

I want to draw a rounded rectangle in Opengl, with one call to glDraw. I also tried. and shared it in response.

Hope this will be helpful.

+3
source share
2 answers

I tried drawing a rounded rectangle in opengl with one call to glDraw.
The following is a snippet of code:

// -0.3f,   -0.2f,  0.0f,   // 0
//  0.3f,  -0.2f,  0.0f,    // 1
// -0.3f,   0.2f,  0.0f,    // 2
//  0.3f,    0.2f,  0.0f,   // 3
//  0.6f,   0.2f,  0.0f,    // 4
//  0.6f,   -0.2f,  0.0f,   // 5
//  0.6f,  -0.5f,  0.0f,    // 6
//  0.3f,  -0.5f,  0.0f,    // 7
// -0.3f,   -0.5f,  0.0f,   // 8
// -0.6f,  -0.5f,  0.0f,    // 9
// -0.6f,  -0.2f,  0.0f,    // 10
// -0.6f,   0.2f,  0.0f,    // 11
// -0.6f,    0.5f,  0.0f,   // 12
// -0.3f,   0.5f,  0.0f,    // 13
//  0.3f,    0.5f,  0.0f,   // 14
//  0.6f,   0.5f,  0.0f // 15
//
//            8_______________________7
//            /|                      |\
//          9/ |                      | \6
//        10/  |                      |  \5
//         /___|______________________|___\
//       1 |   |2                    3|   |4
//         |   |                      |   |
//         |   |                      |   |
//      12 |___|______________________|___|19
//         \   |0                    1|   /
//        13\  |                      |  /18
//         14\ |                      | /17
//            \|______________________|/
//            15                      16
//

static GLfloat vertRndRect[N];
// first store the vertices 0,1,2,3,4 in vertRndRect array
// then calculate the value for vertices 5 and 6 using the below code
for (i = 30; i < 90; i = i + 30)  // change this line to create more vertices but 'indices' array will change
{
float X_cen = vert1[9]; 
float Y_cen = vert1[10];
    vertRndRect[iVertCnt++]  = X_cen + (cos(degreesToRadians(i)) * rad); 
    vertRndRect[iVertCnt++]  = Y_cen + (sin(degreesToRadians(i)) * rad); 
vertRndRect[iVertCnt++]  = 0.0f; // Z
}
// Then store  vertices 7 and 8 to vertRndRect array
// then calculate the value for vertices 9 and 10 using the below code
for (i =  120; i < 180; i = i + 30)
{
float X_cen = vert1[6];
float Y_cen = vert1[7];
    vertRndRect[iVertCnt++]  = X_cen + (cos(degreesToRadians(i)) * rad);
    vertRndRect[iVertCnt++]  = Y_cen + (sin(degreesToRadians(i)) * rad);
vertRndRect[iVertCnt++]  = 0.0f; // Z
}

// Then store  vertices 11 and 12 to vertRndRect array
// then calculate the value for vertices 13 and 14 using the below code
for (i = 210; i < 270;  i = i + 30)
{
float X_cen = vert1[0];
float Y_cen = vert1[1];
    vertRndRect[iVertCnt++]  = X_cen + (cos(degreesToRadians(i)) * rad);
    vertRndRect[iVertCnt++]  = Y_cen + (sin(degreesToRadians(i)) * rad);
vertRndRect[iVertCnt++]  = 0.0f; // Z
}

// Then store  vertices 15 and 16 to vertRndRect array
// then calculate the value for vertices 13 and 14 using the below code
for (i = 300; i < 360;  i = i + 30)
{
float X_cen = vert1[3];
float Y_cen = vert1[4];
    vertRndRect[iVertCnt++]  = X_cen + (cos(degreesToRadians(i)) * rad);
    vertRndRect[iVertCnt++]  = Y_cen + (sin(degreesToRadians(i)) * rad);
vertRndRect[iVertCnt++]  = 0.0f; // Z
}
// Then store  vertices 19
//////////////////////////
GLushort indices[] = {  0, 1, 2, 3, 3, 4, 
                            5, 5, 3, 6, 7, 7, 
                            3, 8, 2, 9, 10, 10, 
                            2, 11, 0, 12, 13, 13, 
                            0, 14, 15, 15, 0, 16, 
                            1, 17, 18, 18, 1, 19, 3, 4
                         };
//////////////////////////
glDrawElements(GL_TRIANGLE_STRIP, 38, GL_UNSIGNED_SHORT,indices); // 38 is size of 'indices' array

Here I calculated only 2 vertices for each rounded corner.
But you can increase it to achieve greater smoothness.
But the corresponding changes must be made in the "indexes" array

Many optimizations can be made in this code.

+2
source

, (TopLeft Corner Position, width height) 10 .

     // 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);
    ////////////////////////

.

+2

All Articles