手机版网站模板 免费,石家庄工程职业学院,哪个网站做学历认证,深圳封控区最新政策1.OpenGL的环境配置#xff1a;
集成开发环境Visual Studio Community 2019的安装#xff1a;
在Windows一栏选择使用C的桌面开发#xff1b;再转到“单个组件”界面#xff0c;在“编译器、生成工具和运行时”一栏选择用于“Windows的C CMake工具”#xff1b;然后转到…1.OpenGL的环境配置
集成开发环境Visual Studio Community 2019的安装
在Windows一栏选择使用C的桌面开发再转到“单个组件”界面在“编译器、生成工具和运行时”一栏选择用于“Windows的C CMake工具”然后转到“语言包”勾选“英语”。
2.CMake的安装
下载对应平台的CMake安装包打开安装包按流程安装CMake。
3.Git的安装
下载对应平台的Git安装包打开安装包按流程安装Git其中有选择编辑器的选项有安装VSCode的建议选择VSCode作为默认的编辑工具。
4.Vcpkg的安装
在github使用Git克隆仓库到安装目录进入到vcpkg文件使用管理员身份打开Powershell运行bootstrap引导脚本执行 .\bootstrap-vcpkg.bat 构建vcpkg构建完成后执行.\vcpkg integrate install命令将vcpkg聚合到visual stuido。
5.系统环境变量设置
验证路径是否添加成功随便一个文件夹内开一个终端输入vcpkg执行后没用跳出错误就说明vcpkg环境配置成功。
6.OpenGL库安装GLFWGLADGLM
7.构建并运行实验1.1
在项目文件夹下打开命令行然后执行 cmake -B . 执行后会在当前项目文件夹内生成main.sln文件点击打开在出现的VS界面中可以看到“解决方案管理器”里面右键点击 “main”项目将其设置为启动项之后即可编译运行程序。
8.绘制出参考图片样式的二维图形
增加顶点数组对象VAO由3个增到5个包括新增的圆形和椭圆。
GLuint vao[5], program;//由3增到5加了圆形和椭圆
VAO是顶点数组对象Vertex Array Object的缩写。它是OpenGL中的一个对象用于存储一组顶点属性的状态。简单来说VAO能够保存多个VBO顶点缓冲对象和EBO元素缓冲对象的配置使得在绘制图形时只需绑定相应的VAO即可直接使用之前设置好的顶点数据和属性配置从而简化了绘图过程。GLuint vao[5]: 声明了一个长度为5的无符号整数数组vao用于存储5个顶点数组对象的句柄即vao这些对象可以用于绘制几何图形。最初只有3个VAO用来绘制三角形、矩形、线现在增加到5个其中包括了用于绘制圆形和椭圆的VAO。GLuint program: 声明了一个无符号整数变量program用于存储一个OpenGL着色器程序的句柄用于控制图形的渲染。 在init初始函数中定义生成椭圆和圆形的点。
// 定义椭圆的点
glm::vec2 ellipse_vertices[ELLIPSE_NUM_POINTS];
glm::vec3 ellipse_colors[ELLIPSE_NUM_POINTS];
// 定义圆形的点
glm::vec2 circle_vertices[CIRCLE_NUM_POINTS];
glm::vec3 circle_colors[CIRCLE_NUM_POINTS];
glm::vec2表示一个二维向量用于存储二维坐标顶点位置。glm::vec3表示一个三维向量包含红、绿、蓝三个分量用于存储颜色值RGB。定义数组来存储绘制椭圆和圆形所需的顶点位置和颜色数据数组的大小由预先定义的常量ELLIPSE_NUM_POINTS椭圆顶点数量和CIRCLE_NUM_POINTS圆形顶点数量决定。 定义完后调用生成椭圆和圆形形状顶点位置的函数。
函数 generateEllipsePoints 用于生成椭圆或圆的顶点位置和颜色。
void generateEllipsePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex, int numPoints,glm::vec2 center, double scale, double verticalScale)
函数的参数包括
glm::vec2 vertices[]用于存储生成的椭圆或圆形的顶点位置。glm::vec3 colors[]用于存储每个顶点的颜色信息。int startVertexIndex为顶点数组的起始索引即从数组的哪个位置开始填充顶点数据。int numPoints是要生成的椭圆或圆形的顶点数量。glm::vec2 center是椭圆或圆形的中心位置。double scale是椭圆的水平半轴长度或圆的半径。double verticalScale是椭圆的垂直半轴长度。如果 verticalScale 为 1.0则生成的形状是一个圆如果 verticalScale 不等于 1.0则生成的是一个椭圆。
// 调用生成椭圆和圆形形状顶点位置的函数
generateEllipsePoints(ellipse_vertices, ellipse_colors, 0, ELLIPSE_NUM_POINTS, glm::vec2(-0.5, 0.7), 0.2, 0.5);
generateEllipsePoints(circle_vertices, circle_colors, 0, CIRCLE_NUM_POINTS, glm::vec2(0.6, 0.7), 0.2, 1.0);
椭圆的生成一个中心在 (-0.5, 0.7)水平半轴为 0.2垂直半轴为 0.5 的椭圆的顶点位置并将这些顶点及其对应的颜色值存储到 ellipse_vertices 和 ellipse_colors 数组中。圆形的生成一个中心在 (0.6, 0.7)半径为 0.2 的圆形的顶点位置并将这些顶点及其颜色值存储到 circle_vertices 和 circle_colors 数组中。 初始化圆和椭圆的数据。
生成和配置顶点数组对象 (VAO) 和顶点缓冲对象 (VBO)以将顶点数据如位置和颜色上传到 GPU即在渲染中GPU能够正确地访问和使用这些数据进行绘制。
生成并绑定 VAO
glGenVertexArrays(1, vao[3]); // 生成 VAO ID
glBindVertexArray(vao[3]); // 绑定 VAO使其成为当前操作的目标
生成并绑定 VBO
glGenBuffers(1, vbo[0]); // 生成位置数据的 VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // 绑定位置 VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(ellipse_vertices), ellipse_vertices, GL_STATIC_DRAW); // 将位置数据上传到 GPU
配置顶点属性指针
location glGetAttribLocation(program, vPosition);// 获取位置属性在着色器中的位置
glEnableVertexAttribArray(location); // 启用位置属性
glVertexAttribPointer(
location, // 属性位置
2, // 每个顶点包含两个分量 (x, y)
GL_FLOAT, // 数据类型为浮点数
GL_FALSE, // 不需要归一化
sizeof(glm::vec2),// 步幅即每两个顶点之间的字节间隔
BUFFER_OFFSET(0) ); // 数据从 VBO 开头开始读取
类似的步骤也用于颜色数据的配置
glGenBuffers(1, vbo[1]); // 生成颜色数据的 VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); // 绑定颜色 VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(ellipse_colors), ellipse_colors, GL_STATIC_DRAW); // 上传颜色数据
cLocation glGetAttribLocation(program, vColor); // 获取颜色属性在着色器中的位置
glEnableVertexAttribArray(cLocation); // 启用颜色属性
glVertexAttribPointer(
cLocation, // 属性位置
3, // 每个颜色包含三个分量 (r, g, b)
GL_FLOAT, // 数据类型为浮点数
GL_FALSE, // 不需要归一化
sizeof(glm::vec3),// 步幅
BUFFER_OFFSET(0));// 数据从 VBO 开头开始读取
重复上述步骤进行其他对象的初始化
针对不同的形状包括椭圆和圆形需要分别生成和配置它们的 VAO 和 VBO。可以通过重复上述步骤来完成这些操作。 在display函数中绘制椭圆和圆形。
// 画椭圆
glBindVertexArray(vao[3]);
glDrawArrays(GL_TRIANGLE_FAN, 0, ELLIPSE_NUM_POINTS);
// 画圆形
glBindVertexArray(vao[4]);
glDrawArrays(GL_TRIANGLE_FAN, 0, CIRCLE_NUM_POINTS);
glBindVertexArray绑定 VAO将编号为 vao[3] 的 VAO 绑定为椭圆将编号为 vao[4] 的 VAO 绑定为圆这两个VAO 是之前初始化椭圆和圆顶点和颜色数据时创建的包含了椭圆和圆的顶点属性配置。glDrawArrays绘制椭圆和圆其中GL_TRIANGLE_FAN指定绘制的图元类型为三角形扇形Triangle Fan即顶点数组中的第一个顶点将作为扇形的中心点后续的顶点将围绕这个中心点形成多个相邻的三角形。对于椭圆和圆形使用 GL_TRIANGLE_FAN 可以绘制出一个封闭的形状。0则表示从顶点数组的第一个顶点开始绘制。最后一个参数则指定绘制的顶点数量。 代码填充后点击运行结果如下图所示。 整体程序代码运行的整体流程
初始化: 设置GLFW和OpenGL生成图形数据配置渲染管道。调用glfwInit()来初始化GLFW库调用init()函数生成图形的顶点和颜色数据并将这些数据发送到GPU初始化OpenGL资源。
渲染循环: 持续绘制图形并响应用户输入。main()函数中包含一个while循环持续运行直到用户关闭窗口。在循环内程序会处理输入调用display()函数进行绘制交换缓冲区处理事件。清理和退出: 释放资源结束程序。渲染循环结束后程序退出释放所有分配的资源包括VAO、VBO和着色器程序。使用glfwTerminate()关闭GLFW并清理所有分配的资源。当用户关闭窗口或手动退出循环时程序结束运行返回到操作系统。 9.自行设计不同的图形颜色效果
整设计思路
首先将背景分成左上浅蓝色、右上浅黄色、左下浅紫色、右下浅绿色四块。左上是一条鱼的形状一个黄色三角形是尾巴一个红色菱形是身体一个白色小圆形是眼睛。右上是一棵树从上往下是三层规模递增的绿色半圆形树桩是一个棕色小矩形状。左下是一个胡萝卜三个倾斜的绿色小矩形是胡萝卜叶子一个橘色倾斜三角形是胡萝卜肉体。右下是一个棒棒糖由多个渐变圆环形成糖果一个灰色矩形是棒棒糖棍。 背景绘制
定义和生成背景分割的四个矩形的点以及颜色。在init()函数中初始化背景数据包括点以及颜色。在display()函数中绘制背景。背景是四个不同颜色的矩形每个矩形可以由6个三角形绘制而成。 //绘制背景 glBindVertexArray(vao[0]); glDrawArrays(GL_TRIANGLES, 0, 6 * NUM_RECTANGLES); 10.左上鱼的绘制
定义和生成鱼眼睛圆形、鱼尾巴三角形、鱼身体菱形的点以及颜色。
在进行鱼尾巴的绘制时我在原本生成三角形的每个顶点generateTrianglePoints这个函数增添了rotationAngle旋转角度这个参数使得绘制的三角形能够进行旋转。旋转的原理首先定义旋转矩阵:用于计算点绕原点的旋转变换然后应用旋转:将顶点坐标通过旋转矩阵转换到新的位置最后平移将旋转后的顶点平移到目标中心位置。
// 获得三角形的每个顶点
void generateTrianglePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex, glm::vec2 center, glm::vec2 scale, glm::vec3 vertexColors[], double rotationAngle)
{ for (int i 0; i 3; i) { double currentAngle getTriangleAngle(i); glm::vec2 vertex glm::vec2(sin(currentAngle), cos(currentAngle)) * scale; // 应用旋转矩阵 double rotatedX vertex.x * cos(rotationAngle) - vertex.y * sin(rotationAngle); double rotatedY vertex.x * sin(rotationAngle) vertex.y * cos(rotationAngle); // 计算旋转后的顶点位置 vertices[startVertexIndex i] glm::vec2(rotatedX, rotatedY) center; colors[startVertexIndex i] vertexColors[i]; }
}
同样的在进行鱼身体的绘制时我也在原本生成矩形的每个顶点generateRectanglePoints这个函数增添了rotationAngle旋转角度这个参数使得绘制的矩形能够进行旋转当正方形顺时针旋转45度时即可得到菱形。
// 计算矩形每个顶点的函数
void generateRectanglePoints(glm::vec2 vertices[], glm::vec3 colors[], int startVertexIndex, glm::vec2 center, glm::vec2 scale, double rotationAngle, glm::vec3 color)
{ int vertexIndex startVertexIndex; for (int i 0; i 4; i) { double currentAngle getSquareAngle(i); // 计算旋转后的坐标 glm::vec2 point glm::vec2(sin(currentAngle), cos(currentAngle)) * scale; glm::vec2 rotatedPoint glm::vec2( point.x * cos(rotationAngle) - point.y * sin(rotationAngle), point.x * sin(rotationAngle) point.y * cos(rotationAngle) ); // 应用平移 vertices[vertexIndex] rotatedPoint center; colors[vertexIndex] color; vertexIndex; }
}
在init()函数中初始化鱼各个部分的数据包括点以及颜色。使用 glGenVertexArrays 和 glGenBuffers 生成 VAO 和 VBO再使用 glBindVertexArray 绑定 VAO以及使用 glBindBuffer 绑定 VBO并上传数据。在display()函数中绘制鱼。在这里需要注意的是由于鱼眼睛是在鱼身体上面的一定要先画鱼身体再画眼睛这样才不会被覆盖。 //绘制鱼尾巴 glBindVertexArray(vao[2]); glDrawArrays(GL_TRIANGLES, 0, TRIANGLE_NUM_POINTS); //绘制鱼身体 glBindVertexArray(vao[3]); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); //绘制鱼眼睛 glBindVertexArray(vao[1]); glDrawArrays(GL_TRIANGLE_FAN, 0, CIRCLE_NUM_POINTS); 11.其他图案同理绘制最终效果如下