OpenGL: RoundBox绘制

实现了16种roundBox,见图

 

核心绘制码在RoundBox.h文件:

#ifndef ROUNDBOXRENDER_H
#define ROUNDBOXRENDER_H
// 7/8/2010 RYF
// QQ: 546952710
// Email: dizuo@126.com
struct RoundBoxRender
{
	// 产生一个渐变的效果:
	//		shadetop叠加top
	//		shadedown叠加到down 可以为负
	//		rad为圆角的半径
	/* linear horizontal shade within button or in outline */
	/* view2d scrollers use it */
	static void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
	{
		float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
		{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
		float div = maxy - miny;
		float coltop[3], coldown[3], color[4];
		int a;
		/* mult */
		for(a = 0; a < 7; a++)
		{
			vec[a][0] *= rad; vec[a][1] *= rad;
		}
		/* get current color, needs to be outside of glBegin/End */
		glGetFloatv(GL_CURRENT_COLOR, color);
		/* 'shade' defines strength of shading */	
		coltop[0]= color[0]+shadetop; if(coltop[0]>1.0) coltop[0]= 1.0;
		coltop[1]= color[1]+shadetop; if(coltop[1]>1.0) coltop[1]= 1.0;
		coltop[2]= color[2]+shadetop; if(coltop[2]>1.0) coltop[2]= 1.0;
		coldown[0]= color[0]+shadedown; if(coldown[0]<0.0) coldown[0]= 0.0;
		coldown[1]= color[1]+shadedown; if(coldown[1]<0.0) coldown[1]= 0.0;
		coldown[2]= color[2]+shadedown; if(coldown[2]<0.0) coldown[2]= 0.0;
		glShadeModel(GL_SMOOTH);
		glBegin(mode);
		/* start with corner right-bottom */
		if(roundboxtype & 4)
		{
			round_box_shade_col(coltop, coldown, 0.0);
			glVertex2f(maxx-rad, miny);
			for(a  =0; a < 7; a++)
			{
				round_box_shade_col(coltop, coldown, vec[a][1]/div);
				glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
			}
			round_box_shade_col(coltop, coldown, rad/div);
			glVertex2f(maxx, miny + rad);
		}
		else
		{
			round_box_shade_col(coltop, coldown, 0.0);
			glVertex2f(maxx, miny);
		}
		/* corner right-top */
		if(roundboxtype & 2)
		{
			round_box_shade_col(coltop, coldown, (div - rad) / div);
			glVertex2f(maxx, maxy-rad);
			for(a=0; a<7; a++)
			{
				round_box_shade_col(coltop, coldown, (div - rad + vec[a][1]) / div);
				glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
			}
			round_box_shade_col(coltop, coldown, 1.0);
			glVertex2f(maxx-rad, maxy);
		}
		else
		{
			round_box_shade_col(coltop, coldown, 1.0);
			glVertex2f(maxx, maxy);
		}
		/* corner left-top */
		if(roundboxtype & 1)
		{
			round_box_shade_col(coltop, coldown, 1.0);
			glVertex2f(minx + rad, maxy);
			for(a = 0; a < 7; a++)
			{
				round_box_shade_col(coltop, coldown, (div - vec[a][1]) / div);
				glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
			}
			round_box_shade_col(coltop, coldown, (div - rad) / div);
			glVertex2f(minx, maxy - rad);
		}
		else
		{
			round_box_shade_col(coltop, coldown, 1.0);
			glVertex2f(minx, maxy);
		}
		/* corner left-bottom */
		if(roundboxtype & 8)
		{
			round_box_shade_col(coltop, coldown, rad/div);
			glVertex2f(minx, miny+rad);
			for(a=0; a<7; a++)
			{
				round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div);
				glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
			}
			round_box_shade_col(coltop, coldown, 0.0);
			glVertex2f(minx+rad, miny);
		}
		else
		{
			round_box_shade_col(coltop, coldown, 0.0);
			glVertex2f(minx, miny);
		}
		glEnd();
		glShadeModel(GL_FLAT);
	}
	static void setType(int nType){ 
		roundboxtype = nType % 16;
	}
protected:
	static void round_box_shade_col(float *col1, float *col2, float fac)
	{
		float col[3];
		col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
		col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
		col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
		glColor3fv(col);
	}
	static int roundboxtype;
};
int RoundBoxRender::roundboxtype = 3;
#endif

gl_round_box_shade中mode支持:GL_LINE_LOOP,GL_POLYGON,GL_TRIANGLE_FAN

round_box_shade_col:col1颜色和col2颜色,根据混合因子fac进行混合,产生中间颜色。

 

主程序基于glut:

#include <cstdio>
#include <cstdlib>
#include <GL/glut.h>
#include <cmath>
#include <ctime>
//#include "BezierLinkRender.h"
#include "RoundBoxRender.h"
//
//global
GLuint gColorStable[] = 
{
	(0xFF0000),	//red 
	(0xDC143C),	//crimson
	(0x9400D3),	//violet
	(0xFFA000),	//orange
	(0xFFFF00),	//yellow
	(0xFFD700),	//glod
	(0x00FF00),	//green
	(0x90FF90),	//lightgreen
	(0x006400),	//darkgreen
	(0x556B2F),	//olivegreen		//very good color绿橄榄
	(0x0000FF),	//blue
	(0x00008B),	//darkblue
	(0x4169E1),	//royalblue
	(0x5555FF),	//skyblue
	(0x191970),	//midnightbue
	(0xFF00FF),	//fuchsia
	(0x00FFFF),	//aqua
	(0xffb6c1),	//pink
	(0xFF91A4),	//salmonpink
	(0x30D5C8),	//turquoise
	(0x008080),	//darkturpuoise
	(0xA9A9A9),	//gray
	(0xD3D3D3),	//lightgray
	(0x808080)	//darkgray
};
float g_fWidth = 500;
float g_fHeight = 500;
float g_fDepth = 100;
float g_fAngle = .0;
int		gRoundboxtype = 0;
//
void renderBitmapString2D(float x, float y, void *font, char *string);
void getColorFromTable(GLuint rgb, float vec[3]);
void init(void) 
{
	RoundBoxRender::setType(gRoundboxtype);
	printf("%d/n", gRoundboxtype);
	glClearColor (0.9, 0.9, 0.9, 0.0);
	glShadeModel (GL_SMOOTH);
}
void display(void)
{
	const float slotSize = 30.f;
	const float slotColor[] = {0.8f, 0.8f, 0.8f};
	const float slotShadowSize = 2.0f;
	const float slotShadowAlpha = 0.7;
	glClear (GL_COLOR_BUFFER_BIT);
	glColor3f (1.0, 1.0, 1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, g_fWidth, 0, g_fHeight, 0, g_fDepth);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(80.f, 80.f, 0.f);		//整体平移
	
	int xPos(0);
	int yPos(0);
	int xOffset(0);
	int yOffset(0);
	for (int i=0; i<16; i++)
	{
		char buffer[10] = {'/0'};
		itoa (i,buffer,10);
		int fontWidOffset = i>10 ? 12 : 5;		//估算量
		int fontHghOffset = 10;					//估算量
		int boxSize = 60;
		
		float colorVec[3];
		getColorFromTable(gColorStable[i], colorVec);
		glColor3fv(colorVec);
		RoundBoxRender::setType(i);
		yOffset = i/4;
		xOffset = i%4;
		glPushMatrix();
		{
			glTranslatef(xPos+xOffset*100, yPos+yOffset*100, 0.f);
			RoundBoxRender::gl_round_box_shade(GL_POLYGON, 0, 0, boxSize, boxSize, 10, 0.3, 0);
			glColor3f(0.f, 0.f, 0.0f);
			renderBitmapString2D(boxSize/2-fontWidOffset, boxSize/2-fontHghOffset, GLUT_BITMAP_TIMES_ROMAN_24, buffer);
		}glPopMatrix();
	}
	//glColor3f(1.0f, 1.0f, 0.0f);
	//ui_draw_link_bezier(&gRect);
	glutSwapBuffers();
}
void reshape (int w, int h)
{
	glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	gluPerspective(60,1.0,1.5,20);
	glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
	switch (key) 
	{
	case 27:
		exit(0);
		break;
	}
	glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
	if(button==GLUT_LEFT_BUTTON)
		switch(state)
	{
		case GLUT_DOWN:
			break;
		case GLUT_UP:
			break;
	}
	glutPostRedisplay();
}
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize (500, 500); 
	glutInitWindowPosition (100, 100);
	glutCreateWindow (argv[0]);
	init ();
	glutDisplayFunc(display); 
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutMouseFunc( mouse );
	glutMainLoop();
	return 0;
}
void renderBitmapString2D(float x, float y, void *font, char *string)
{
	char *c;
	// set position to start drawing fonts
	glRasterPos2f(x, y);
	// loop all the characters in the string
	for (c=string; *c != '/0'; c++) {
		glutBitmapCharacter(font, *c);
	}
}
void getColorFromTable(GLuint rgb, float vec[3])
{
	GLubyte  r = GLubyte ((rgb >> 16) & 0xFF);
	GLubyte  g = GLubyte ((rgb >> 8) & 0xFF);
	GLubyte  b = GLubyte (rgb & 0xFF);
	vec[0] = r / 255.0f;
	vec[1] = g / 255.0f;
	vec[2] = b / 255.0f;
}

http://blog.csdn.net/ryfdizuo/article/details/5721751

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值