opengl 消除棱角

/*************************************************************************
	> File Name: Star.c
	> Author: halfopen
	> Mail: halfopen@yeah.net
	> Created Time: 2015年11月11日 星期四 17时12分46秒
 ************************************************************************/

#include<stdio.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<math.h>

#define PI 3.14159262423

int width=400, height=400;
static double	y=sin(PI/5)*tan(PI/5)-cos(PI/5); 
static GLint axis = 2;
static GLfloat theta[] = {0.0,0.0,0.0};

float points[10][3] = {-1,-1,1,
	1,-1,1,
	1,-1,-1,
	-1,-1,-1,
	-1,1,1,
	1,1,1,
	1,1,-1,
	-1,1,-1,
	0,3,0,
	3,0,0};
int faces[16][3]={1,2,5,
	2,6,5,

	2,10,6,
	6,10,7,
	2,3,10,
	3,7,10,
	
	5,6,9,
	6,7,9,

	7,8,9,
	5,9,8,

	1,5,4,
	5,8,4,
	
	1,4,2,
	4,3,2,

	8,7,4,
	7,3,4
	};
int points_list[10]={0};

float c = PI / 180.0f; //弧度和角度转换参数
int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向
float r = 1.5f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标
GLfloat scale = 1.0;
void drawModel()
{
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		glColor3f(255,255,255);
		for(int i=0;i<16;i++)
		{	glBegin(GL_POLYGON); 
				glVertex3f(points[ faces[i][0] -1][0] , points[faces[i][0]-1][1],points[faces[i][0]-1][2] );
				glVertex3f(points[ faces[i][1] -1][0] , points[faces[i][1]-1][1],points[faces[i][1]-1][2] );
				glVertex3f(points[ faces[i][2] -1][0] , points[faces[i][2]-1][1],points[faces[i][2]-1][2]);
			glEnd();	
		}
		glFlush();
}

void smooth()
{	for(int i=0;i<10;i++)
	{	printf("point:%d->%.2f %.2f %.2f\n",i+1,points[i][0],points[i][1],points[i][2]);
		//printf("change to:\n");
//		points[i][0] = points[i][0] /2.0;
//		points[i][1] = points[i][1] /3.0;
//		points[i][2] = points[i][2] /4.0;
		
		for(int j=0;j<16;j++)points_list[j]=0;
		for(int j=0;j<16;j++)
		{	if(faces[j][0]==i+1 || faces[j][1]==i+1 || faces[j][2]==i+1)
			{	points_list[ faces[j][0]-1 ]=1;
				points_list[ faces[j][1]-1 ]=1;
				points_list[ faces[j][2]-1 ]=1;
			}
		}
		printf("find:");
		float x=0,y=0,z=0;	//
		int count = 0;
		for(int l=0;l<16;l++)
		{	if(points_list[l] == 1)
			{	//printf("->%d ",l+1);
				count++;
				x += points[i][0] - points[l][0];
				y += points[i][1] - points[l][1];
				z += points[i][2] - points[l][2];
//				printf("(%f %f %f)-(%f %f %f)=(%f %f %f)\n",points[i][0], points[i][1],points[i][2], 
//					points[l][0],points[l][1],points[l][2],
//					x,y,z);
			}
		}
		x = x/(count-1);
		y = y/(count-1);
		z = z/(count -1);
		printf(" ->x:%f y:%f z:%f\n",x,y,z);
		points[i][0] = points[i][0] /(1 + 0.1*fabs(x));
		points[i][1] = points[i][1] /(1 + 0.1*fabs(y));
		points[i][2] = points[i][2] /(1 + 0.1*fabs(z));
		glutPostRedisplay();
	}
}

static void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//printf("At:%.2f %.2f %.2f\n",r*cos(c*du),h,r*sin(c*du)); //这就是视点的坐标
	glPushMatrix();
	glLoadIdentity();
	glRotatef(theta[0]/2, 1.0, 0.0, 0.0);
	glRotatef(theta[1]/2, 0.0, 1.0, 0.0);
	glRotatef(theta[2]/2, 0.0, 0.0, 1.0);		
	glScalef(scale, scale, scale);
	glColor3f(1.0f, 0.0f, 0.0f);
	drawModel();
	glPopMatrix();
	glFlush();
	
	glutSwapBuffers(); 
}


/* This routine inputs new control points */
static void mouse(int button, int state, int x, int y)
{
        glFlush();

}

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

/* This routine handles keystroke commands */
void keyboard(unsigned char key, int x, int y)
{	
        switch (key)
    		{
				case 'j':
					axis = 0;
					theta[axis] += 2.0;
					if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
					glutPostRedisplay();break;
				case 'k':
					axis = 1;
					theta[axis] += 2.0;
					if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
					glutPostRedisplay();break;
				case 'l':
					axis = 2;
					theta[axis] += 2.0;
					if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
					glutPostRedisplay();break;
                case 'q': case 'Q':
                    exit(0);
                    break;
                case 'c': case 'C':
					glTranslatef(0.0f,-20.0f,-40.0f);
					puts("c");
                    break;
                case 'e': case 'E':
                    break;
                case 'b': case 'B':
                    break;
                case 'i': case 'I':
                    break;
				case 'h': case 'H':scale+=0.1;glutPostRedisplay();
                    break;
				case 'n': case 'N':scale-=0.1;glutPostRedisplay();
                    break;
                case 's': case 'S':
					smooth();
                    break;
            
    }

}

void spinCube()
{
		theta[axis] += 2.0;
		if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
		glutPostRedisplay();
}

void reshape(int w, int h)
{
        width = w;
        height = h;

        /* Set the transformations */
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
        glMatrixMode(GL_MODELVIEW);
        glViewport(0, 0, w, h);

}
int main(int argc, char **argv)
{
        /* Intialize the program */
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(width, height);
        glutCreateWindow("star");

        /* Register the callbacks */
        glutDisplayFunc(display);

        glutMouseFunc(mouse);
        glutKeyboardFunc(keyboard);
        glutReshapeFunc(reshape);
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glEnable(GL_MAP1_VERTEX_3);

		init();
		glutMainLoop();
		return 0;
}

原图形:


转换之后:


3.1基本图元光栅扫描演示系统 (1)设计目标 图形的绘制实质上是像素的操作,像素有三个参数,位置坐标x、y以及颜色c。本设计使用正方形模拟像素,保持屏幕的纵横比为4:3,将基本图元(直线、圆和椭圆)在像素级别上绘制出来。由于圆是椭圆的特例,即长轴和短轴长度相等的椭圆,可以使用键盘的约束来解决。本设计要求在像素级别演示直线的走样、反走样和颜色渐变;演示椭圆(含圆)的走样和反走样。详细功能要求如下: 使用静态切分视图,将屏幕切分为左右窗格。左窗格是控制窗格,右窗格为显示窗格。 保持右窗格的二维设备坐标系不变,原点位于客户区左上角,x轴水平向右为正,y轴铅直向下为正。 在右窗格内绘制40×30个正方形代表虚拟像素网格,使用橡皮筋技术动态演示基本图元的绘制过程。 在左窗格内借助快捷颜色按钮选择直线的起点和终点颜色,或双击“起点”或“终点”颜色按钮弹出系统颜色对话框,从中选择直线的起点和终点颜色。在右窗格选择直线段的起点像素和终点像素位置,分别绘制走样直线、反走样直线、颜色渐变直线。要求:在移动鼠标的过程中时,按下Shift键可绘制水平或垂直直线。 在左窗格选择椭圆(含圆)的线条颜色,在右窗格内选择两个像素作为椭圆(包含圆)的外接矩形的左上角点和右下角点,分别绘制走样椭圆(含圆)、反走样椭圆(包含圆)。要求:在移动鼠标的过程中,按下Shift键可以绘制圆。 在状态栏动态显示鼠标在右窗格内的虚拟像素坐标,虚拟像素的坐标取为虚拟像素网格的中心点坐标,需要从设备坐标系转换到虚拟像素坐标系,即右窗格网格左上角点的虚拟像素坐标为(0,0),网格右下角点的虚拟像素坐标为(39,29)。 (2)设计效果 单击左窗格的“直线”按钮后,在右窗格内使用鼠标绘制的走样直线,如图Ⅰ-1所示。 单击左窗格的“直线”按钮,同时选中“反走样”复选框后,在右窗格内使用鼠标绘制的反走样直线如图Ⅰ-2所示。 单击左窗格的“直线”按钮,同时为直线选择了起点和终点颜色后,在右窗格内使用鼠标绘制的颜色渐变直线如图Ⅰ-3所示。 单击左窗格的“直线”按钮,为直线选择了起点和终点颜色后,同时选中“反走样”复选框,在右窗格内使用鼠标绘制的颜色渐变反走样直线如图Ⅰ-4所示。 单击左窗格的“椭圆”按钮后,在右窗格内使用鼠标绘制的走样椭圆如图Ⅰ-5所示。 单击左窗格的“椭圆”按钮同时选中“反走样”复选框后,在右窗格内绘制的反走样椭圆如图Ⅰ-6所示。 单击左窗格的“椭圆”按钮后,在右窗格内拖动鼠标的同时按下Shift键绘制的走样圆如图Ⅰ-7所示。 单击左窗格的“椭圆”按钮同时选中“反走样”复选框后,在右窗格内拖动鼠标的同时按下Shift键绘制的反走样圆如图Ⅰ-8所示。 3.2递归动态球体演示系统 (1)设计目标 在正八面体的基础上构建球体。正八面体的顶点位于球面上,正八面体的体心设为球心。 将正八面体每个正三角形表面的三条边的中点连接形成四个小正三角形,并将三个中点拉伸到球面上。对每个小正三角形进行同样的递归操作可以构造出球体线框模型。 请使用不同深度的递归划分法分别绘制无光照线框球,有光照线框球、无光照表面球和有光照表面球。给定沿x,y,z坐标轴3个方向的位移量和绕x,y,z坐标轴的旋转角度,控制球体在窗口客户区内运动。当球体和客户区边界发生碰撞后,改变运动方向。请使用三维正交变换绘制递归动态球体。 (2)设计效果 使用静态切分视图,将窗口切分为左右窗格。左窗格为继承于CForemView类的表单视图类CLeftPortion,右窗格为一般视图类CTestView。 右窗格的三维坐标系原点位于客户区中心,x轴水平向右为正,y轴铅直向上为正, z轴垂直于屏幕指向观察者。 左窗格放置代表“球体控制”、“模型分类”、“光源开关”、“平移变换”和“旋转变换”4个组框控件。“球体控制”组框提供“球体半径”和“球面级数”2个滑动条;“模型分类”组框提供“线框”和“表面”2个单选按钮;“光源开关”分类组框提供“关”和“开”2个单选按钮;“平移变换”组框提供“X方向”、“Y方向”和“Z方向”3个滑动条;“旋转变换”组框提供“绕X轴”、“绕Y轴”和“绕Z轴”3个滑动条。 球体在右窗格内根据左窗格的设定值运动,并和客户区边界发生碰撞。 当球面级数的值为8时,右窗格内的球体退化为正八面体。当球面级数的值为32时,在右窗格内的正八面体的每个等边三角形的三条边上取3个中点并用直线连接,形成4个小正三角形。将3个中点的模长扩展至球体半径长度,得到递归球体。当球面级数增加时,对每个小正三角形面片继续进行同样的递归,最终生成递归球体。 根据左窗格的参数值,分别绘制无光照和有光照消隐线框球、无光照和有光照表面球。其中无光照消隐线框采用走样直线绘制,颜色为白色;有光照消隐线框球采用反走样颜色渐变直线绘制;光照表面球使
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值