图形学的几道基础练习(计算机图形学)

整理文件夹时发现曾经做的几个作业练习,发出来和大家一起学习吧。

PS:总工程下载:https://download.csdn.net/download/weixin_41918712/10698534


题目①

在一个黑色的窗口中央画出矩形、三角形、点和线。

踩坑记录:一开始画线部分,因为省略了glEnd(),导致生成图像时显示空白窗口。

效果图

题目①源码

#pragma warning(disable:4996)
#include<GL/glut.h>
void myDisplay(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);  //将清空颜色设为黑色
	glClear(GL_COLOR_BUFFER_BIT);  //将窗口的背景设置为:清空颜色
	glColor3f(1.0f, 1.0f, 1.0f);  //画一个矩形
	glRectf(-0.8f, -0.8f, 0.8, 0.8f);
	glBegin(GL_TRIANGLES);  //画两个三角形
	glColor3f(1.0f, 1.0f, 0.0f);  glVertex2f(0.0f, -1.0f);//黄
	glColor3f(1.0f, 0.0f, 1.0f);  glVertex2f(0.8f, 0.5f);//品红
	glColor3f(0.0f, 1.0f, 1.0f);  glVertex2f(-0.8f, 0.5f);//青
	glColor3f(1.0f, 0.0f, 0.0f);  glVertex2f(0.0f, 1.0f);//红
	glColor3f(0.0f, 1.0f, 0.0f);  glVertex2f(0.8f, -0.5f);//绿
	glColor3f(0.0f, 0.0f, 1.0f);  glVertex2f(-0.8f, -0.5f);//蓝
	glEnd();
	glPointSize(10);  //设置点的大小
	glBegin(GL_POINTS);  //画7个点
	glColor3f(1.0f, 1.0f, 0.0f);  glVertex2f(0.0f, 0.7f);//黄
	glColor3f(1.0f, 1.0f, 1.0f);  glVertex2f(0.0f, 0.0f);//白
	glColor3f(0.0f, 1.0f, 1.0f);  glVertex2f(0.53f, -0.33f);//青
	glColor3f(1.0f, 0.0f, 1.0f);  glVertex2f(-0.53f, -0.33f);//品红
	glColor3f(0.0f, 0.0f, 1.0f);  glVertex2f(0.53f, 0.33f);//蓝
	glColor3f(0.0f, 1.0f, 0.0f);  glVertex2f(-0.53f, 0.33f);//绿
	glColor3f(1.0f, 0.0f, 0.0f);  glVertex2f(0.0f, -0.7f);//红
	glEnd();
	glBegin(GL_LINES);//线
	glColor3f(0.0, 0.0, 0.0);
	glLineWidth(6);//线的宽度
	glVertex2f(-0.8f, 0.5f);
	glVertex2f(0.8f, -0.5f);
	glVertex2f(0.0f, -1.0f);
	glVertex2f(0.0f, 1.0f);
	glVertex2f(0.8f, 0.5f);
	glVertex2f(-0.8f, -0.5f);
	glEnd();
	glFinish();  //强制前面的OpenGL命令立即执行,不驻留缓存
}
int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);  //设置窗口在屏幕中的位置
	glutInitWindowSize(400, 400);  //设置窗口的大小
	glutCreateWindow("Hello World!");
	glutDisplayFunc(&myDisplay);
	glutMainLoop();
	return 0;
}

 


题目②

利用OpenGL实现直线光栅化的DDA算法和Bresenham算法。

效果图

题目②源码

#pragma warning(disable:4996)
#include<math.h>
#include <GL/glut.h>
#include<cstdio>
void LineDDA(int x0, int y0, int x1, int y1)/*  LineDDA函数画线  */
{
	int x, y, dx, dy;
	float m;
	dx = x1 - x0;
	dy = y1 - y0;
	m = dy / dx;
	y = y0;
	glColor3f(1.0f, 1.0f, 0.0f);
	glPointSize(1);
	for (x = x0;x <= x1;x++) {
		glBegin(GL_POINTS);
		glVertex2i(x, (int)(y + 0.5));
		glEnd();
		y += m;
	}
}
void Bresenhamline(int x0, int y0, int x1, int y1)/*  Bresenham函数画线  */
{
	int x, y, dx, dy;
	float e;
	dx = x1 - x0;
	dy = y1 - y0;
	e = -dx;
	x = x0;
	y = y0;
	for (int i = 0;i<dx;i++) {
		glBegin(GL_POINTS);
		glVertex2i(x, y);
		x++;
		e = e + 2 * dy;
		if (e >= 0) {
			y++;
			e = e - 2 * dx;
		}
	}
}

void myDisplayLine(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(25.0, 25.0, 75.0, 75.0);
	glPointSize(5);
	glBegin(GL_POINTS);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex2f(0.0f, 0.0f);
	glEnd();
	LineDDA(0, 0, 200, 300);  //调用LineDDA函数画线
	glBegin(GL_LINES);
	glColor3f(1.0f, 0.0f, 0.0f);
	glVertex2f(100.0f, 0.0f);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex2f(180.0f, 240.0f);
	glEnd();
	glFlush();
}
void myDisplayBres(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(25.0, 25.0, 75.0, 75.0);
	glPointSize(5);
	glBegin(GL_POINTS);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex2f(0.0f, 0.0f);
	glEnd();
	Bresenhamline(0, 0, 200, 300);  //调用Bresenhamline函数画线
	glBegin(GL_LINES);
	glColor3f(1.0f, 0.0f, 0.0f);
	glVertex2f(100.0f, 0.0f);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex2f(180.0f, 240.0f);
	glEnd();
	glFlush();
}
void Init() {
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_FLAT);
}
void Reshape(int w, int h) {
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char *argv[])
{
	int i;
	printf("请选择实现直线光栅化的算法:\n1.DDA\t2.Bresenham\n");
	while (scanf("%d", &i))
	{
		if (i == 1 || i == 2)  break;
		else{}
	}
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("Hello World!");
	Init();
	if(i==1)  glutDisplayFunc(myDisplayLine);  //设置mydisplay函数,当需要进行画图时,这个函数就会被调用 
	else if(i==2)  glutDisplayFunc(myDisplayBres);
	else  return 0;
	glutReshapeFunc(Reshape);  //调用此函数,重新建立用作新渲染画布的矩形区域
	glutMainLoop();  //进行一个消息循环(现在只需要知道这个函数可以显示窗口,并且等待窗口关闭才会返回)
	return 0;
}

 


题目③

画顶点分别为A(1,1),B(2,5), C(6,3) 的三角形ABC,同时画出绕B点逆时针旋转90度的三角形A’B’C’,最后在以上基础上再画出绕B点顺时针旋转90度的三角形A’’B’’C’’。

效果图

题目③源码

#pragma warning(disable:4996)
#include <GL/glut.h>;
void init(void)
{
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	gluOrtho2D(-15.0, 15.0, -15.0, 15.0);  //设置x、y显示的范围
	glMatrixMode(GL_MODELVIEW);
}
void drawSquare(void)  //绘制三角形
{
	glBegin(GL_TRIANGLES);  //顶点指定需要按逆时针方向
	glVertex2f(1.0f, 1.0f);
	glVertex2f(2.0f, 5.0f);
	glVertex2f(6.0f, 3.0f);
	glEnd();
}
void myDraw(void)
{
	glClear(GL_COLOR_BUFFER_BIT);  //清空
	glLoadIdentity();  //将当前矩阵设为单位矩阵
	glPushMatrix();  //a:此处的push是为了表明堆栈当前状态
	glColor3f(1.0f, 0.0f, 0.0f);  //红色三角形
	drawSquare();  //调用drawSquare
	glPopMatrix();  //这个pop使得堆栈状态回到a状态
	glPushMatrix();  //作用同a,表明堆栈当前状态
	glTranslatef(7.0, 3.0, 0.0);  //平移变换,x正方向平移7个单位,y正方向平移3个单位
	glPushMatrix();  //c:这里的push保存了上面平移矩阵
	glRotatef(90.0, 0.0, 0.0, 1.0);  //旋转变换,逆时针旋转90°	
	glColor3f(0.0f, 1.0f, 0.0f);
	drawSquare();  //绿色三角形,进行一个旋转和一个平移变换
	glPopMatrix();  //这个pop使得堆栈状态回到c状态,栈里有(7.0, 3.0, 0.0)
	glTranslatef(-10.0, 4.0, 0.0);
	glPushMatrix();  //d:这里的push保存了上面平移矩阵,栈里由底到顶有(7.0, 3.0, 0.0),(-10.0, 4.0, 0.0)
	glRotatef(-90.0, 0.0, 0.0, 1.0);  //旋转变换,顺时针旋转90°
	glColor3f(0.0f, 0.0f, 1.0f);
	drawSquare();  //蓝色三角形,进行一个旋转和一个平移变换
	glFlush();
}
void main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(600, 600);
	glutCreateWindow("Hello World !");
	init();
	glutDisplayFunc(myDraw);
	glutMainLoop();
}

 


✎﹏﹏₯㎕《晴天》re so so si la si la so la si si si si la si la so ...﹍﹍﹍﹍﹍﹍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值