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

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

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 ...﹍﹍﹍﹍﹍﹍

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程解决的问题: 作为游戏行业或者图形学从业者,你是否面临以下问题: 到底openGL底层如何实现的? 到底矩阵操作变换是怎么做到的? 到底光栅化的算法以及原理是什么? 到底如何才能从3D世界投射到2D屏幕呢? 图形学有这么多的矩阵操作,到底如何推导如何应用呢? 学完这门课程,你应该就可以从底层了解一个初级的openGL图形接口如何实现,图形学最底层的封装到底面临哪些挑战;跟随我们一行一行写完代码,你就会得到一个迷你版本的openGL图形库,你可以深度体会图形从模型变换,观察矩阵变换,投影矩阵变换一直到光栅化纹理操作的全套模拟流程。 课程介绍: 本课程将带领学员不使用任何图形库,实现从0到1的图形学接口封装以及算法讲解,并且带领大家手敲代码,一行一行进行实现。 涵盖了(环境搭建,绘制点,Bresenham算法绘制完美直线,三角形拆分绘制算法,颜色插值算法,图片操作,图片二次插值放缩算法,纹理系统接口搭建及封装,矩阵操作理论以及实践,openGL类似接口封装,3D世界的图形学理论及接口封装等) 最终将带领大家通过C++实现一个3D世界的图形接口,方便所有人入门图形学,进行接下来的openGL接口以及GPU编程的学习   本课程为系列课程的第一步入门,且带领所有人进行实现,更加实用,可以让大家打牢图形学基础知识及编程技能
学习计算机图形学的路线可以包括以下步骤: 1. 掌握基础数学知识:计算机图形学涉及很多数学概念,如线性代数、向量和矩阵运算、几何学等。建议先学习这些基础数学知识,以便更好地理解后续的图形学概念和算法。 2. 学习图形学基础概念:了解计算机图形学的基本原理,包括坐标系统、颜色表示、光照模型、渲染管线等。可以阅读相关的教材或在线教程,如《计算机图形学原理与实践》等。 3. 学习图形库和API:掌握使用图形库和API进行图形编程的基本技巧。常用的图形库包括OpenGL和DirectX,它们提供了一套函数和工具集,用于图形渲染、对象建模和交互等。 4. 学习图形算法和技术:了解常用的图形算法和技术,如线段裁剪、多边形填充、光照计算、纹理映射等。掌握这些算法和技术可以帮助你实现各种复杂的图形效果。 5. 实践项目和练习:通过实践项目和练习来巩固所学的知识。可以从简单的图形渲染开始,逐渐扩展到更复杂的场景和效果。参与开源项目或自己设计和实现小游戏也是一个很好的锻炼机会。 6. 深入研究和学术探索:如果你对图形学有更深入的兴趣,可以进一步研究和学术探索。阅读相关的研究论文、参加学术会议,了解最新的图形学进展和技术。 记住,图形学是一个广阔而复杂的领域,需要持续的学习和实践才能掌握。不断地编写代码、阅读文献、参与讨论和交流,将有助于你不断提升自己的图形学技能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值