【OpenGL修行】几何图形绘制

OpenGL程序范例

  • 初学者请看注释
#include<GL/glut.h>
void myDisplay() {
	glClear(GL_COLOR_BUFFER_BIT);//GL_COLOR_BUFFER_BIT表示清除颜色
	glRectf(-0.5f, -0.5f, 0.5f, 0.5f);//画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标。
	glFlush();//显示
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);//对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示方式,其中GLUT_RGB表示使用RGB颜色, GLUT_SINGO表示单缓冲
	glutInitWindowPosition(100, 100);//位置
	glutInitWindowSize(400, 400);//窗口大小
	glutCreateWindow("my first opengl-cpp");//创建窗口
	glutDisplayFunc(&myDisplay);//操作函数
	glutMainLoop();//消息循环
	return 0;
}

绘图格式

代码格式

void myDisplay(void)
{
     glClear(GL_COLOR_BUFFER_BIT);
     glBegin( /* 在这里填上你所希望的模式 */ );
        /* 在这里使用glVertex*系列函数 */
        /* 指定你所希望的顶点位置 */
     glEnd();
     glFlush();
}

绘图模式

  • GL_POINTS:把每个顶点作为一个点进行处理,顶点n定义了点n,绘制N个点。

  • GL_LINES: 把每个顶点作为一个独立的线段,顶点2n-1和2n之间定义了n条线段,绘制N/2条线段

  • GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,绘制n-1条线段。

  • GL_LINE_LOOP: 绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,绘制n条线段。

  • GL_TRIANGLES: 把每个顶点作为一个独立的三角形,顶点3n-2,3n-1和3n定义了第n个三角形,绘制了N/3个三角形。

  • GL_TRIANGLE_STPIP:绘制一组相连的三角形,对于奇数n,顶点n,n+1,和n+2定义了第n个三角形;对于偶数n,顶点n+1,n和n+2定义了第n个三角形,绘制N-2个三角 形。

  • GL_QUADS: 绘制由四个顶点组成的一组单独的四边形。顶点4n-3,4n-2,4n-1和4n定义了第n个四边形。绘制了N/4个四边形。

  • GL_QUAD_STRIP:绘制一组相连的四边形。每个四边形是由一对顶点及其后给定的一对顶点共同确定的。顶点2n-1,2n,2n+2和2n+1定义了第n个四边形,绘制了N/2-1个 四边形。

  • GL_POLYGON: 绘制了一个凸多边形。顶点1到n定义了这个多边形。

绘图实例

线段

#include<GL/glut.h>
void myDisplay() {
	glClear(GL_COLOR_BUFFER_BIT);//GL_COLOR_BUFFER_BIT表示清除颜色
	glBegin(GL_POINTS);//点要在begin()和end()函数之间
	glVertex2f(0.0f, 0.0f);//x, y
	glVertex2f(0.5f, 0.0f);
	glEnd();
	glFlush();//显示
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);//对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示方式,其中GLUT_RGB表示使用RGB颜色, GLUT_SINGO表示单缓冲
	glutInitWindowPosition(100, 100);//位置
	glutInitWindowSize(400, 400);//窗口大小
	glutCreateWindow("my first opengl-cpp");//创建窗口
	glutDisplayFunc(&myDisplay);//操作函数
	glutMainLoop();//消息循环
	return 0;
}

在这里插入图片描述

#include<GL/glut.h>
#include<math.h>
void myDisplay() {
	glClear(GL_COLOR_BUFFER_BIT);//GL_COLOR_BUFFER_BIT表示清除颜色
	glBegin(GL_POLYGON);
	int n = 50;
	const GLfloat r = 0.5f, pi = 3.1415926f;
	for (int i = 0; i < n; i++)
		glVertex2f(r * cos(2 * pi / n * i), r * sin(2 * pi / n * i));
	glEnd();
	glFlush();//显示
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);//对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示方式,其中GLUT_RGB表示使用RGB颜色, GLUT_SINGO表示单缓冲
	glutInitWindowPosition(100, 100);//位置
	glutInitWindowSize(400, 400);//窗口大小
	glutCreateWindow("my first opengl-cpp");//创建窗口
	glutDisplayFunc(&myDisplay);//操作函数
	glutMainLoop();//消息循环
	return 0;
}

在这里插入图片描述
若要画空心的圆就不要使用GL_POLYGON模式,因为OpenGL中的凸多边形全都是实心的,换成GL_LINE_LOOP模式就ok啦。

在这里插入图片描述

五角星

#include<GL/glut.h>
#include<math.h>
void Display() {
	GLfloat pi = 3.1415926f, m = 1.0f, a;
	a = sqrt((m * m) / 2 * (1 - cos(72 * pi / 180)));
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_LINE_LOOP);
	glVertex2f(0, a);//A
	glVertex2f(a * cos(54 * pi / 180), -a * sin(54 * pi / 180));//C
	glVertex2f(-a * cos(18 * pi / 180), a * sin(18 * pi / 180));//E
	glVertex2f(a * cos(18 * pi / 180), a * sin(18 * pi / 180));//B
	glVertex2f(-a * cos(54 * pi / 180), -a * sin(54 * pi / 180));//D
	glEnd();
	glFlush();
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("五角星");
	glutDisplayFunc(&Display);
	glutMainLoop();
	return 0;
}

大家看过上一个画圆的代码后应该发现OpenGL的绘图需要自己计算坐标。关于五角星这个代码中的坐标数学求解,若读者觉得自己ok,可略过此部分。

不知道大家是否还记得三角形中的余弦定理:
c 2 = a 2 + b 2 − 2 a b cos ⁡ C c^2=a^2+b^2-2ab\cos{C} c2=a2+b22abcosC
由于五角星与正五边形共用五个顶点,所以从正五边形中求出边a,再通过a使用三角函数求出各个点的坐标。
在这里插入图片描述

由上图可知:
m 2 = a 2 + a 2 − 2 a a cos ⁡ 72 m^2=a^2+a^2-2aa\cos{72} m2=a2+a22aacos72
化简得:
a = m 2 2 × ( 1 − cos ⁡ 72 ) a=\sqrt{\frac{m^2}{2\times(1-\cos{72})}} a=2×(1cos72)m2
我们令m=1.0f,即可求出a边长度。
即可推出:
B的坐标为 ( a × cos ⁡ 18 , a × sin ⁡ 18 ) (a\times\cos{18},a\times\sin{18}) (a×cos18a×sin18)
C的坐标为 ( a × cos ⁡ 54 , − a × sin ⁡ 54 ) (a\times\cos{54},-a\times\sin{54}) (a×cos54a×sin54)
D的坐标为 ( − a × cos ⁡ 54 , − a × sin ⁡ 54 ) (-a\times\cos{54},-a\times\sin{54}) (a×cos54a×sin54)
E的坐标为 ( − a × cos ⁡ 18 , a × sin ⁡ 18 ) (-a\times\cos{18},a\times\sin{18}) (a×cos18a×sin18)
再通过A-C-E-B-D-A的顺序绘图即可得到五角星图案。
在这里插入图片描述

正弦函数

#include<GL/glut.h>
#include<math.h>
void Display() {
	GLfloat x, fm=0.1f;
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_LINES);
	glVertex2f(1.0f, 0);
	glVertex2f(-1.0f, 0);
	glVertex2f(0, 1.0f);
	glVertex2f(0, -1.0f);
	glEnd();
	glBegin(GL_LINE_STRIP);
	for (x = -1.0f/fm; x < 1.0f/fm; x += 0.01f)
		glVertex2f(x*fm, sin(x)*fm);
	glEnd();
	glFlush();
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("正弦函数");
	glutDisplayFunc(&Display);
	glutMainLoop();
	return 0;
}

因为正弦函数在窗口中画不下,所以对图像进行了压缩,把sin(10.0f)处的图像画在sin(1.0f)处,并乘以0.1f进行高度压缩。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chaoql

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值