注册 登录
编程论坛 C图形专区

OpenGL绘制圆角矩形、空心圆角矩形

if_exist 发布于 2012-04-17 22:28, 2878 次点击

from:
http://www.

只有本站会员才能查看附件,请 登录

大致思路,通过cos , sin 求出指定半径在各个角度上的点,由LINE_STRIP 或者LINE_LOOP
连接成一个圆。但是这个圆进行分段位移。 也就是分四个部分 分别作不同的位移
这样LINE_LOOP 会为我们连接隔开的部分,形成圆角矩形。


程序代码:

    float cirR=20.0,divide=20.0,part=divide/4.0;  //cirR是圆角半径,divide是细分程度
    glColor3f(0.5,0.5,0.5);

    glBegin(GL_LINE_LOOP);
    for (i=part*0.0;i<=part*1.0;i+=1.0) {
        tx=cirR * cos( ang * i / divide )+20.0;
        ty=cirR * sin( ang * i / divide )+20.0;
        glVertex3f(tx,ty,0.0);
    }
    for (i=part*1.0;i<=part*2.0;i+=1.0) {
        tx=cirR * cos( ang * i / divide )-20.0;
        ty=cirR * sin( ang * i / divide )+20.0;
        glVertex3f(tx,ty,0.0);
    }
    for (i=part*2.0;i<=part*3.0;i+=1.0) {
        tx=cirR * cos( ang * i / divide )-20.0;
        ty=cirR * sin( ang * i / divide )-20.0;
        glVertex3f(tx,ty,0.0);
    }
    for (i=part*3.0;i<=part*4.0;i+=1.0) {
        tx=cirR * cos( ang * i / divide )+20.0;
        ty=cirR * sin( ang * i / divide )-20.0;
        glVertex3f(tx,ty,0.0);
    }
    glEnd();





只有本站会员才能查看附件,请 登录

这个看起来有问题 ,衔接线段之间因为偏移产生了锯齿。这个偏移主要还是因为在圆上取点的时候是相邻的。
不过对代码来说是一个简化,在一个循环内算出所有顶点,实现过程有点像分段函数。
程序代码:

    glBegin(GL_LINE_LOOP);
    for (i=0.0;i<=divide;i+=1.0) {
        tx=cirR*cos(6.28*i/divide);
        ty=cirR*sin(6.28*i/divide);
        if (0.0<=i && i<=5.0) {tx+=10.0;ty+=10.0;}
        if (6.0<=i && i<=10.0) {tx-=10.0;ty+=10.0;}
        if (11.0<=i && i<=15.0) {tx-=10.0;ty-=10.0;}
        if (16.0<=i && i<=20.0) {tx+=10.0;ty-=10.0;}
        glVertex3f(tx,ty,0.0);
    }
    glEnd();


只有本站会员才能查看附件,请 登录

简单的圆角矩形已经没问题了,空心的圆角矩形,在这个基础上做个组合,
在一个循环内计算两组坐标,一组是内矩形,一组是外矩形的坐标,然后用QUAD_STRIP  内外坐标相连接
用四边形组成一个空心圆角矩形,其实直接的说法是是组成了一个环状物。
顶点的连接顺序如图:
只有本站会员才能查看附件,请 登录


这次直接上完整代码,对代码进行了修正,复合了第一个和第二个圆角矩形的方法,封装成函数。

RoundRect.c
程序代码:

/*
    Date 2012-04-01
    Code by 523066680@ [www.]
    改动:对函数代码进行了缩减
*/

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <time.h>
#include <math.h>

int winid;

void RoundRect(
    float divide,  //圆角细分数量
    float cirr,    //内圆角半径
    float cirR,    //外圆角半径
    float w,       //内矩形宽度
    float h,       //内矩形高度
    float W,       //外矩形宽度
    float H)       //外矩形高度
{
    float halfW=W/2.0,halfH=H/2.0,halfw=w/2.0,halfh=h/2.0;
    float part=divide/4.0,tx,ty,i,ang=6.28;
    int whois=0;
    float arr[4][4]={
        halfw,halfh,halfW,halfH,
        -halfw,halfh,-halfW,halfH,
        -halfw,-halfh,-halfW,-halfH,
        halfw,-halfh,halfW,-halfH,
    };

    glBegin(GL_QUAD_STRIP);
    for (i=0.0;i<=divide;) {
        tx=cirr * cos( ang * i / divide )+arr[whois][0];
        ty=cirr * sin( ang * i / divide )+arr[whois][1];
        glVertex3f(tx,ty,0.0);
        tx=cirR * cos( ang * i / divide )+arr[whois][2];
        ty=cirR * sin( ang * i / divide )+arr[whois][3];
        glVertex3f(tx,ty,0.0);
        if (whois==0 && i == part*1.0) {whois+=1;i-=1.0;}
        if (whois==1 && i == part*2.0) {whois+=1;i-=1.0;}
        if (whois==2 && i == part*3.0) {whois+=1;i-=1.0;}
        if (whois==3 && i == part*4.0) {whois=0;i-=1.0;}  //i积累满时,for结束,为了完成回环,i-=1.0;
        i+=1.0;
    }
    glEnd();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    glColor3f(0.5,0.5,0.5);
    RoundRect(20.0, 10.0, 20.0, 20.0,50.0, 30.0,35.0);
    glPopMatrix();   
    glutSwapBuffers();
}

void idle(void)
{
    usleep(5000);
    glutPostRedisplay();
}

void reshape(int Width,int Height)
{
    float far=300.0;
    glViewport(0,0,500,500);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,1.0,100.0,900.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0,0.0,far, 0.0,0.0,0.0, 0.0,1.0,far);
}

void init(void)
{
    glClearColor(0.0,0.0,0.0,0.0);
}

void keypress(unsigned char key,int mousex,int mousey)
{
    switch (key) {
    case 'q':
        glutDestroyWindow(winid);
        exit(0);
        break;
    }
}

int main(int argc,char *argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    winid=glutCreateWindow("Press - + w a x y R r");
    init();
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(idle);
    glutKeyboardFunc(keypress);
    glutMainLoop();
    return 0;
}



本人编译环境: MinGW , 编译句gcc RoundRect.c -lglut32 -lglu32 -lopengl32
523066680 @
http://www.

[ 本帖最后由 if_exist 于 2012-4-17 22:30 编辑 ]
1 回复
#2
王靖宇2020-11-18 19:54
有没有联系方式,具体的问一下
1