OpenGL—ES 1.0 2d rounded rectangle

后端 未结 7 448
生来不讨喜
生来不讨喜 2020-12-28 09:46

How to make rounded rectangle in OpenGL, or any polygon with rounded corners?

7条回答
  •  南方客
    南方客 (楼主)
    2020-12-28 10:26

    The following code is coping from my own project, I have added some comments to explain in the code. If will draw a gradient rounded rectangle without border.

    #define GLW_SMALL_ROUNDED_CORNER_SLICES 5  // How many vertexes you want of each corner
    
    #define glwR(rgb) ((float)(((rgb) >> 16) & 0xff) / 255)
    #define glwG(rgb) ((float)(((rgb) >> 8) & 0xff) / 255)
    #define glwB(rgb) ((float)(((rgb)) & 0xff) / 255)
    
    
    typedef struct glwVec2 {
      float x;
      float y;
    } glwVec2;
    
    static glwVec2 glwRoundedCorners[GLW_SMALL_ROUNDED_CORNER_SLICES] = {{0}}; // This array keep the generated vertexes of one corner
    
    static void createRoundedCorners(glwVec2 *arr, int num) {
      // Generate the corner vertexes
      float slice = M_PI / 2 / num;
      int i;
      float a = 0;
      for (i = 0; i < num; a += slice, ++i) {
        arr[i].x = cosf(a);
        arr[i].y = sinf(a);
      }
    }
    
    createRoundedCorners(glwRoundedCorners, GLW_SMALL_ROUNDED_CORNER_SLICES);
    
    void glwDrawRoundedRectGradientFill(float x, float y, float width, float height,
        float radius, unsigned int topColor, unsigned int bottomColor) {
      float left = x;
      float top = y;
      float bottom = y + height - 1;
      float right = x + width - 1;
      int i;
      glDisable(GL_TEXTURE_2D);
      glBegin(GL_QUAD_STRIP);
        // Draw left rounded side.
        for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
          glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
          glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
            bottom - radius + radius * glwRoundedCorners[i].y);
          glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
          glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
            top + radius - radius * glwRoundedCorners[i].y);
        }
        // Draw right rounded side.
        for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
          glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
          glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
            bottom - radius + radius * glwRoundedCorners[i].y);
          glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
          glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
            top + radius - radius * glwRoundedCorners[i].y);
        }
      glEnd();
    }
    

    If you want draw the border, here is the code.

    static void glwDrawRightTopVertexs(float left, float top, float right,
        float bottom, float radius) {
      int i;
      for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
        glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
          top + radius - radius * glwRoundedCorners[i].y);
      }
    }
    
    static void glwDrawRightBottomVertexs(float left, float top, float right,
        float bottom, float radius) {
      int i;
      for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
        glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
          bottom - radius + radius * glwRoundedCorners[i].y);
      }
    }
    
    static void glwDrawLeftBottomVertexs(float left, float top, float right,
        float bottom, float radius) {
      int i;
      for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
        glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
          bottom - radius + radius * glwRoundedCorners[i].y);
      }
    }
    
    static void glwDrawLeftTopVertexs(float left, float top, float right,
        float bottom, float radius) {
      int i;
      for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
        glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
          top + radius - radius * glwRoundedCorners[i].y);
      }
    }
    
    void glwDrawRoundedRectBorder(float x, float y, float width, float height,
        float radius, unsigned int color) {
      float left = x;
      float top = y;
      float bottom = y + height - 1;
      float right = x + width - 1;
      glDisable(GL_TEXTURE_2D);
      glColor3f(glwR(color), glwG(color), glwB(color));
      glBegin(GL_LINE_LOOP);
        glVertex2f(left, top + radius);
        glwDrawLeftTopVertexs(left, top, right, bottom, radius);
        glVertex2f(left + radius, top);
    
        glVertex2f(right - radius, top);
        glwDrawRightTopVertexs(left, top, right, bottom, radius);
        glVertex2f(right, top + radius);
    
        glVertex2f(right, bottom - radius);
        glwDrawRightBottomVertexs(left, top, right, bottom, radius);
        glVertex2f(right - radius, bottom);
    
        glVertex2f(left + radius, bottom);
        glwDrawLeftBottomVertexs(left, top, right, bottom, radius);
        glVertex2f(left, bottom - radius);
      glEnd();
    }
    

提交回复
热议问题