【OpenGL】绘制表情并实现二维基本变换:平移、旋转、缩放

该博客介绍了使用OpenGL进行二维基本变换,包括平移、旋转和缩放,通过GL_TRIANGLE_FAN和GL_LINE_STRIP绘制圆面、圆弧和脸蛋来创建表情,并实现了键盘控制的动态变换。代码详细展示了如何绘制圆面、圆弧和脸蛋,以及如何响应键盘事件进行视角调整。
摘要由CSDN通过智能技术生成

【OpenGL】绘制表情并实现二维基本变换:平移、旋转、缩放

1.绘制目标

二维基本变换:平移、旋转、缩放
• glTranslate*()
• glRotate*()
• glScale*()
• 小提示:对圆盘进行三角化,然后基于GL_TRIANGLE_FAN绘制。
在这里插入图片描述

2.核心代码

2.1 绘制圆面

/// <summary>
/// 绘制圆面
/// </summary>
/// <param name="r">圆面半径</param>
/// <param name="circle_x">圆面x坐标</param>
/// <param name="circle_y">圆面y坐标</param>
/// <param name="_R">颜色R</param>
/// <param name="_G">颜色G</param>
/// <param name="_B">颜色B</param>
void DrawCirclePointGpBlackSet(double r, double circle_x, double circle_y, double _R, double _G, double _B)
{
	glColor3f(_R, _G, _B);
	glBegin(GL_TRIANGLE_FAN);

	for (double i = -r; i <= r; i += 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, y + circle_y);
	}
	for (double i = r; i >= -r; i -= 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, -y + circle_y);
	}
	for (double i = -r; i <= r; i += 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, y + circle_y);
	}
	glEnd();
}

2.2 绘制圆弧

/// <summary>
/// 绘制圆弧
/// </summary>
/// <param name="r">圆面半径</param>
/// <param name="circle_x">圆面x坐标</param>
/// <param name="circle_y">圆面y坐标</param>
/// <param name="_R">颜色R</param>
/// <param name="_G">颜色G</param>
/// <param name="_B">颜色B</param>
void DrawArcPointGpSet(double r, double circle_x, double circle_y, double _R, double _G, double _B)
{
	glColor3f(_R, _G, _B);
	glBegin(GL_LINE_STRIP);

	for (double i = r; i >= -r; i -= 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, -y + circle_y);
	}
	glEnd();
}

2.3 绘制脸蛋

/// <summary>
/// 绘制脸蛋
/// </summary>
/// <param name="face_x">脸蛋的x坐标</param>
/// <param name="face_y">脸蛋的y坐标</param>
/// <param name="face_r">脸蛋的半径坐标</param>
void DrawFace(double face_x, double face_y, double face_r)
{
	glPushMatrix();
	// 黄色的脸蛋
	DrawCirclePointGpBlackSet(face_r, face_x, face_y, 255, 215, 0);
	// 黑色的眼睛
	DrawCirclePointGpBlackSet(face_r / 6, face_x - face_r / 3, face_r / 10, 0, 0, 0);
	DrawCirclePointGpBlackSet(face_r / 6, face_x + face_r / 3, face_r / 10, 0, 0, 0);
	// 红色嘴巴
	DrawArcPointGpSet(face_r / 3, face_x, face_y - face_r / 3, 255, 0, 0);

	glPopMatrix();
}

2.4 键盘操作

void KeyBoards(int key, int x, int y)
{
	switch (key)
	{
	case GLUT_KEY_UP:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(xDir, ++yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_LEFT:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(--xDir, yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_DOWN:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(xDir, --yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_RIGHT:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(++xDir, yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_INSERT:
		glMatrixMode(GL_MODELVIEW);
		glRotatef(++angle, 0, 0, 1);
		glutPostRedisplay();
		break;

	case GLUT_KEY_END:
		glMatrixMode(GL_MODELVIEW);
		glRotatef(--angle, 0, 0, 1);
		glutPostRedisplay();
		break;
	}
}

3.全部代码

#define GLEW_STATIC
#define FREEGLUT_STATIC

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>

GLdouble xDir = 0.0;
GLdouble yDir = 0.0;
GLdouble zDir = 0.0;
GLfloat angle = 0.0;

void _init()
{
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

/// <summary>
/// 绘制圆面
/// </summary>
/// <param name="r">圆面半径</param>
/// <param name="circle_x">圆面x坐标</param>
/// <param name="circle_y">圆面y坐标</param>
/// <param name="_R">颜色R</param>
/// <param name="_G">颜色G</param>
/// <param name="_B">颜色B</param>
void DrawCirclePointGpBlackSet(double r, double circle_x, double circle_y, double _R, double _G, double _B)
{
	glColor3f(_R, _G, _B);
	glBegin(GL_TRIANGLE_FAN);

	for (double i = -r; i <= r; i += 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, y + circle_y);
	}
	for (double i = r; i >= -r; i -= 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, -y + circle_y);
	}
	for (double i = -r; i <= r; i += 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, y + circle_y);
	}
	glEnd();
}

/// <summary>
/// 绘制圆弧
/// </summary>
/// <param name="r">圆面半径</param>
/// <param name="circle_x">圆面x坐标</param>
/// <param name="circle_y">圆面y坐标</param>
/// <param name="_R">颜色R</param>
/// <param name="_G">颜色G</param>
/// <param name="_B">颜色B</param>
void DrawArcPointGpSet(double r, double circle_x, double circle_y, double _R, double _G, double _B)
{
	glColor3f(_R, _G, _B);
	glBegin(GL_LINE_STRIP);

	for (double i = r; i >= -r; i -= 0.001)
	{
		double x = i;
		double y = sqrt(r * r - x * x);
		glVertex2f(x + circle_x, -y + circle_y);
	}
	glEnd();
}

/// <summary>
/// 绘制脸蛋
/// </summary>
/// <param name="face_x">脸蛋的x坐标</param>
/// <param name="face_y">脸蛋的y坐标</param>
/// <param name="face_r">脸蛋的半径坐标</param>
void DrawFace(double face_x, double face_y, double face_r)
{
	glPushMatrix();
	// 黄色的脸蛋
	DrawCirclePointGpBlackSet(face_r, face_x, face_y, 255, 215, 0);
	// 黑色的眼睛
	DrawCirclePointGpBlackSet(face_r / 6, face_x - face_r / 3, face_r / 10, 0, 0, 0);
	DrawCirclePointGpBlackSet(face_r / 6, face_x + face_r / 3, face_r / 10, 0, 0, 0);
	// 红色嘴巴
	DrawArcPointGpSet(face_r / 3, face_x, face_y - face_r / 3, 255, 0, 0);

	glPopMatrix();
}

void KeyBoards(int key, int x, int y)
{
	switch (key)
	{
	case GLUT_KEY_UP:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(xDir, ++yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_LEFT:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(--xDir, yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_DOWN:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(xDir, --yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_RIGHT:
		glMatrixMode(GL_MODELVIEW);
		glTranslated(++xDir, yDir, zDir);
		glutPostRedisplay();
		break;
	case GLUT_KEY_INSERT:
		glMatrixMode(GL_MODELVIEW);
		glRotatef(++angle, 0, 0, 1);
		glutPostRedisplay();
		break;

	case GLUT_KEY_END:
		glMatrixMode(GL_MODELVIEW);
		glRotatef(--angle, 0, 0, 1);
		glutPostRedisplay();
		break;
	}
}

void display() {
	glClear(GL_COLOR_BUFFER_BIT);

	DrawFace(0, 0, 3);

	glutSwapBuffers();
}

void reshape(int w, int h) {
	glViewport(0, 0, w, h);

	glMatrixMode(GL_PROJECTION);

	glLoadIdentity();

	gluOrtho2D(-8.f, 8.f, -8.f, 8.f);
}

int main(int argc, char** argv) {

	glutInit(&argc, argv);

	glutInitContextVersion(3, 3);

	glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);

	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

	glutInitWindowPosition(0, 0); // 左上角相对位置
	glutInitWindowSize(600, 600); // 窗口大小
	glutCreateWindow("OpenGL");

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);

	glewExperimental = GL_TRUE;
	glewInit();

	_init();

	glutSpecialFunc(&KeyBoards);  //注册键盘事件(特殊字符)
	glutDisplayFunc(&display);   //回调函数 

	glutMainLoop();
	return 0;
}

4.运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

敲代码两年半的练习生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值