OpenGL绘制圆角矩形、空心圆角矩形
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 编辑 ]