Нарисуйте прямоугольник со скругленными углами, используя единственный вызов glDrawElement (triangle_strip …) в OpenGL ES

Я хочу нарисовать прямоугольник с закругленными углами в OpenGLES, с помощью одного вызова glDraw.
Я также попробовал это. и поделился этим в ответе.

Надеюсь, это будет полезно.

3

Решение

Я попытался нарисовать прямоугольник с закругленными углами в OpenGLES с помощью одного вызова glDraw.
Ниже приведен фрагмент кода:

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

Здесь я рассчитал только 2 вершины для каждого закругленного угла.
Но можно увеличить его, чтобы получить больше плавности.
Но соответствующие изменения должны быть сделаны в массиве «индексы»

Много оптимизаций может быть сделано в этом коде.

2

Другие решения

Я изменил код, чтобы получить входные данные (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

По вопросам рекламы [email protected]