返回
OpenGL--渲染图形实战
IOS
2024-02-03 21:11:40
写在前面
本文将介绍如何将固定位置上的顶点数据以6种不同的图元展示,并用键盘控制视图变换。具体代码详见:https://github.com/cjf564558856/OpenGLDemo
1. 渲染
在OpenGL中,渲染是一个将对象从模型空间变换到屏幕的过程。它包含几个步骤:
- 模型变换 :将模型从模型空间变换到世界空间。
- 视图变换 :将世界空间中的对象变换到相机空间。
- 投影变换 :将相机空间中的对象变换到裁剪空间。
- 视口变换 :将裁剪空间中的对象变换到屏幕空间。
这四个变换都由矩阵表示,这些矩阵可以通过OpenGL函数glMatrixMode()
、glLoadIdentity()
、glTranslatef()
、glRotatef()
、glScalef()
等来设置。
// 设置模型变换矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f); // 将模型向后平移10个单位
// 设置视图变换矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)width / (float)height, 0.1f, 100.0f); // 设置透视投影
// 设置视口变换矩阵
glViewport(0, 0, width, height); // 设置视口大小
2. 图元
图元是OpenGL用来表示几何形状的基本单位。OpenGL支持多种不同的图元,包括:
- 点
- 线
- 三角形
- 四边形
- 多边形
图元可以使用OpenGL函数glBegin()
、glVertex3f()
、glEnd()
等来绘制。
// 绘制一个三角形
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -1.0f, 0.0f); // 三角形的第一个顶点
glVertex3f(1.0f, -1.0f, 0.0f); // 三角形的第二个顶点
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的第三个顶点
glEnd();
3. 键盘控制
键盘控制是OpenGL中控制视图变换的常用方法。OpenGL提供了几个函数来处理键盘输入,包括:
glutKeyboardFunc()
:注册键盘回调函数。glutSpecialFunc()
:注册特殊键回调函数。glutMainLoop()
:进入OpenGL主循环。
在键盘回调函数中,我们可以根据键盘输入来更新视图变换矩阵,从而改变观察者的视角。
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'w':
glTranslatef(0.0f, 0.1f, 0.0f); // 向上平移
break;
case 's':
glTranslatef(0.0f, -0.1f, 0.0f); // 向下平移
break;
case 'a':
glTranslatef(-0.1f, 0.0f, 0.0f); // 向左平移
break;
case 'd':
glTranslatef(0.1f, 0.0f, 0.0f); // 向右平移
break;
case 'q':
glRotatef(1.0f, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
break;
case 'e':
glRotatef(-1.0f, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
break;
}
glutPostRedisplay(); // 重新绘制场景
}
4. 完整代码
#include <GL/glut.h>
// 定义窗口宽高
const int width = 800;
const int height = 600;
// 定义键盘回调函数
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'w':
glTranslatef(0.0f, 0.1f, 0.0f); // 向上平移
break;
case 's':
glTranslatef(0.0f, -0.1f, 0.0f); // 向下平移
break;
case 'a':
glTranslatef(-0.1f, 0.0f, 0.0f); // 向左平移
break;
case 'd':
glTranslatef(0.1f, 0.0f, 0.0f); // 向右平移
break;
case 'q':
glRotatef(1.0f, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
break;
case 'e':
glRotatef(-1.0f, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
break;
}
glutPostRedisplay(); // 重新绘制场景
}
// 定义显示函数
void display()
{
// 清除颜色缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 设置模型变换矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f); // 将模型向后平移10个单位
// 设置视图变换矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)width / (float)height, 0.1f, 100.0f); // 设置透视投影
// 设置视口变换矩阵
glViewport(0, 0, width, height); // 设置视口大小
// 绘制一个三角形
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -1.0f, 0.0f); // 三角形的第一个顶点
glVertex3f(1.0f, -1.0f, 0.0f); // 三角形的第二个顶点
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的第三个顶点
glEnd();
// 交换前后缓冲区
glutSwapBuffers();
}
// 定义主函数
int main(int argc, char** argv)
{
// 初始化GLUT
glutInit(&argc, argv);
// 设置显示模式
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// 设置窗口大小和位置
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 100);
// 创建窗口
glutCreateWindow("OpenGL Demo");
// 注册键盘回调函数
glutKeyboardFunc(keyboard);
// 注册显示函数
glutDisplayFunc(display);
// 进入GLUT主循环
glutMainLoop();
return 0;
}