关于OpenMesh与OpenGL

编程入门 行业动态 更新时间:2024-10-27 12:28:19

关于<a href=https://www.elefans.com/category/jswz/34/1681953.html style=OpenMesh与OpenGL"/>

关于OpenMesh与OpenGL

文章目录

  • OpenMesh官网
  • OpenMesh是什么?他能做什么?
  • 直接无源码安装
  • 测试
    • 报错:
    • 效果:
  • 学习openmesh
    • 学习openmesh的流程如下:
    • 第一步,了解openmesh库的基本概念
    • 第二步,查看openmesh的官方示例,了解简单的接口api
    • 练习,自己写一个立方体
    • 开启一个小项目,比如:如何加载output.off这个模型,修改和保存
  • OpenMesh架构
  • openflipper的安装
  • openGL库的安装
    • 为什么要安装openGL?
    • GLFW的安装
    • GLAD安装
    • 配置GLFW 和 GLAD
      • 1) 配置GLFW
      • 2) 配置 GLAD
      • 3) 测试OpenGL
  • openmesh与opengl结合使用
  • 一些感悟
  • 一些细碎知识点
    • 1.OpenGL的状态通常被称为OpenGL上下文(Context)。
    • 2.如何快速上手openmesh,照着这个教程,一共十五章,看完基本就是OK了

OpenMesh官网

开放网格 - 计算机图形学和多媒体 (rwth-aachen.de)

OpenMesh是什么?他能做什么?

OpenMesh是一个C++库,OpenFlipper这个软件就是由OpenMesh开发的

直接无源码安装

非常好用,都不用cmake了

测试

  • 建一个cpp的空项目,项目名称叫TestOpenMesh

  • 将编译模式改为release

  • 建一个TestOpenMesh.cpp

  • 配置头文件:
    打开项目属性-VC++目录-包含目录,添加包含目录D:\vs2022\openmesh\install\OpenMesh 9.0\include如下:

  • 配置库文件:
    打开项目属性-链接器-常规-附加依赖库目录,添加附加库目录D:\vs2022\openmesh\install\OpenMesh 9.0\lib如下:

  • 配置附加依赖项.lib文件:*
    打开项目属性-链接器-输入-附加依赖项,添加附加库目录OpenMeshCored.libOpenMeshToolsd.lib如下:
OpenMeshCored.lib
OpenMeshToolsd.lib

  • 配置预处理器添加宏:

打开项目属性-C/C++-预处理器,添加附加宏_USE_MATH_DEFINES

测试代码

#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>typedef OpenMesh::PolyMesh_ArrayKernelT<>  MyMesh;int main()
{MyMesh mesh;// generate verticesMyMesh::VertexHandle vhandle[8];vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1));vhandle[1] = mesh.add_vertex(MyMesh::Point(1, -1, 1));vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 1));vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1));vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1));vhandle[5] = mesh.add_vertex(MyMesh::Point(1, -1, -1));vhandle[6] = mesh.add_vertex(MyMesh::Point(1, 1, -1));vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1));// generate (quadrilateral) facesstd::vector<MyMesh::VertexHandle>  face_vhandles;face_vhandles.clear();face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[3]);//逆时针mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[7]);face_vhandles.push_back(vhandle[6]);face_vhandles.push_back(vhandle[5]);face_vhandles.push_back(vhandle[4]);//顺时针mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[4]);face_vhandles.push_back(vhandle[5]);//顺时针mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[5]);face_vhandles.push_back(vhandle[6]);//逆时针mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[3]);face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[6]);face_vhandles.push_back(vhandle[7]);//逆时针mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[3]);face_vhandles.push_back(vhandle[7]);face_vhandles.push_back(vhandle[4]);//顺时针mesh.add_face(face_vhandles);// write mesh to output.objtry{if (!OpenMesh::IO::write_mesh(mesh, "output.off")){std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;return 1;}}catch (std::exception& x){std::cerr << x.what() << std::endl;return 1;}return 0;
}

报错:

1>OpenMeshCored.lib(BaseProperty.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BaseProperty.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(ArrayKernel.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(ArrayKernel.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PLYReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PLYReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(VTKWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(VTKWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PLYWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PLYWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OBJWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OBJWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(STLWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(STLWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(STLReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(STLReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(IOManager.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(IOManager.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OFFWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OFFWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OBJReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OBJReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OFFReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OFFReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PolyConnectivity.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PolyConnectivity.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(omstream.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(omstream.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMFormat.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(OMFormat.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BaseWriter.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BaseWriter.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BaseReader.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BaseReader.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PropertyCreator.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(PropertyCreator.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BinaryHelper.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(TestOpenMesh.obj 中)
1>OpenMeshCored.lib(BinaryHelper.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“MD_DynamicRelease”(TestOpenMesh.obj 中)
1>LINK : warning LNK4098: 默认库“MSVCRTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
1>OpenMeshCored.lib(BaseWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(BaseReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(PropertyCreator.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OFFReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(PolyConnectivity.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(omstream.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OMFormat.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(STLReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(IOManager.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OFFWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OBJReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(VTKWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(PLYWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OBJWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(STLWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(ArrayKernel.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OMWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(PLYReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(OMReader.obj) : error LNK2001: 无法解析的外部符号 __imp__invalid_parameter
1>OpenMeshCored.lib(BaseWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(BaseReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(PropertyCreator.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OFFReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(PolyConnectivity.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(omstream.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OMFormat.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(STLReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(IOManager.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OFFWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OBJReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(VTKWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(PLYWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OBJWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(STLWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(ArrayKernel.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OMWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(PLYReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OMReader.obj) : error LNK2001: 无法解析的外部符号 __imp__CrtDbgReport
1>OpenMeshCored.lib(OMWriter.obj) : error LNK2001: 无法解析的外部符号 __imp__calloc_dbg
1>OpenMeshCored.lib(OMReader.obj) : error LNK2001: 无法解析的外部符号 __imp__calloc_dbg
1>OpenMeshCored.lib(OMFormat.obj) : error LNK2001: 无法解析的外部符号 __imp__calloc_dbg
1>D:\vs2022\code\TestOpenMesh\x64\Release\TestOpenMesh.exe : fatal error LNK1120: 3 个无法解析的外部命令

产生这个问题的原因是:当前工程是Release版本,而引用的库文件时Debug版本,所以你需要重复配置一下上面的操作,在Debug模式下!

效果:

学习openmesh

好了,我们现在已经成功搭建了openmesh的运行环境,现在我们来根据一些流程来学习openmesh,

在开启学习openmesh的流程之前,我们需要了解两个重要的资料:

一,openmesh的介绍网址:

/

如下:这个自己去看

二,openmesh的文档网址:

如下:这个自己去看

.html

学习openmesh的流程如下:

第一步,了解openmesh库的基本概念

顶点、边、面

  1. 顶点 (Vertices):

    • 顶点是在三维空间中定义的一个点。在OpenMesh中,每个顶点通常包含一个或多个坐标==(x、y、z)==来表示其位置。
    • 顶点是模型的基本构成单元之一,它们可以用来描述物体的各个特征点。
  2. 边 (Edges):

    • 边是两个顶点之间的连接。在OpenMesh中,边也可以具有附加的属性,如权重或方向。
    • 一条边连接两个顶点,形成一个线段或曲线。
  3. 面 (Faces):

    • 面是由三个更多相邻的顶点组成的多边形,通常是一个平面的一部分。在OpenMesh中,常用的面是三角形和四边形。
    • 面定义了模型的表面。

第二步,查看openmesh的官方示例,了解简单的接口api

练习,自己写一个立方体

报错:

PolyMeshT::add_face: complex edge

解决方法:

/article/1725293

openmesh的顶点顺序要看半边结构的顺序

再来看一下stl文件格式:

我们可以看到:stl文件格式也是遵循半边结构的

openmesh与stl文件的不同点是:如果你没有遵循半边结构,openmesh直接判断你是错的;

stl文件则不会,只是发亮面会反.

开启一个小项目,比如:如何加载output.off这个模型,修改和保存

#if 1
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>typedef OpenMesh::TriMesh_ArrayKernelT<>  MyMesh;int main()
{MyMesh mesh;// 从文件中加载模型if (!OpenMesh::IO::read_mesh(mesh, "triangle.off")){std::cerr << "Error: Cannot read mesh from file 'output.off'" << std::endl;return 1;}// 获取第一个顶点的句柄MyMesh::VertexHandle vh = *(mesh.vertices_begin());// 获取顶点的当前位置MyMesh::Point current_pos = mesh.point(vh);// 修改顶点的位置mesh.set_point(vh, MyMesh::Point(current_pos[0] - 1.0, current_pos[1], current_pos[2]));// 保存模型if (!OpenMesh::IO::write_mesh(mesh, "modified_output.off")){std::cerr << "Error: Cannot write mesh to file 'modified_output.off'" << std::endl;return 1;}return 0;
}#else#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>typedef OpenMesh::PolyMesh_ArrayKernelT<>  MyMesh;int main()
{// 创建一个Mesh对象MyMesh mesh;// 添加顶点MyMesh::VertexHandle vhandle[4];vhandle[0] = mesh.add_vertex(MyMesh::Point(0.0, 0.0, 0.0));//0vhandle[1] = mesh.add_vertex(MyMesh::Point(1.0, 0.0, 0.0));//1vhandle[2] = mesh.add_vertex(MyMesh::Point(0.0, 1.0, 0.0));//2vhandle[3] = mesh.add_vertex(MyMesh::Point(0.0, 0.0, 1.0));//3// 添加面std::vector<MyMesh::VertexHandle> face_vhandles;face_vhandles.clear();face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[2]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);// 保存网格到文件OpenMesh::IO::write_mesh(mesh, "triangle.off");return 0;
}#endif

也就是说,stl文件格式要求的顺序和openmesh要求的顺序都是一致的,网格结构的顺序!!!

OpenMesh架构

OpenMesh架构允许自定义网格:用户可以以顶点,边和面指定任意特征,也可以从一组预定义的属性中进行选择,然后将这些属性传播到网格内核.内核负责网格元素的内部存储,可以选择使用数组或双链表作为容器类型.由于具有不同属性的网格将导致不同的cpp类型,OPenMesh使用泛型编程来实现这些网格上操作的算法

openflipper的安装

/

openGL库的安装

为什么要安装openGL?

在计算机上显示三维模型,通常需要使用OpenGL或其他图形库来实现图形渲染。OpenMesh本身并不包含用于渲染图形的功能。

OpenGL小游戏教程

科普一下:OpenGL本身是一个图形渲染API,并不是一个库。要使用OpenGL,你需要安装GLFW库和GLAD库,来协助你管理窗口和处理OpenGL的扩展。

我一开始以为:OpenGL是一个库

GLFW的安装

.html

然后解压就好了,我们应该用的是lib-vc2022(我猜的,具体应该如何后面会有具体操作的)

GLAD安装

/

gl要选4.0以上的

配置GLFW 和 GLAD

1) 配置GLFW

1.使用vs2022创建一个空项目testOpenGL,并在项目下新建testOpenGL.cpp文件

2.右击testOpenGL.cpp,打开项目所在文件夹,在openGL的文件夹下创建includes和libs两个文件夹;

3.copy库

  • glfw解压文件lib-vc2022文件夹下的==.lib文件拷贝进刚刚创建的libs==下(说明刚才猜的没错),
  • 同时将glfw解压文件include下的==.h文件拷贝进刚刚创建的includes==下

开始拷贝:

4.在项目名处右键->属性->VC++目录->引用目录->编辑:粘贴项目文件夹下的.h文件所在目录地址

5.库目录->编辑:粘贴项目文件夹下的.lib文件所在目录

6.为项目添加依赖项:仍然是属性->链接器->输入->附加依赖项->编辑,将opengl32.lib,glfw3.lib,msvcrt.lib添加进去

opengl32.lib
glfw3.lib
msvcrt.lib

注意!!!这里一定要看!是关于msvcrt.lib的!!!

这里我踩过一个坑:msvcrt.lib 是Microsoft Visual C++ 运行时库,它是用于处理C++程序的标准运行时库。

在使用 Visual Studio 时,通常会自动链接到相应的运行时库,因此不需要显式地将 msvcrt.lib 添加到附加依赖项中。

如果你手动将 msvcrt.lib 添加到附加依赖项中,可能会导致链接错误,因为这样做可能会引起运行时库的冲突。

所以,如果你的项目没有特殊的需求,最好不要手动添加 msvcrt.lib 到附加依赖项中,让 Visual Studio 自动处理运行时库的链接。如果你对运行时库有特殊的需求,可能需要谨慎处理,以避免引起冲突。

所以,不要加msvcrt.lib这个库(既然如此,为什么我上面步骤还写了,这个教程是看其他教程一步一步实操的,我不知道那个人为啥要这么写,一步一步的循序渐进的更好一点),不然你看,把编译器整不会了,你还不知道啥错误,如下:

2) 配置 GLAD

  1. GLAD的include下,

    glad文件夹和KHP文件夹

    拷贝进

    项目文件夹下的includes下,

    并将GLAD的src下的glad.c拷贝进项目文件夹下

  2. 进入vs,添加源文件->现有项,将glad.c添加进项目

3) 测试OpenGL

//测试代码
#include"glad/glad.h"
#include"includes/glfw3.h"
#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window); // settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// uncomment this statement to fix compilation on OS X
#endifGLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "I love OpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl; return -1;}while (!glfwWindowShouldClose(window)){processInput(window);glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate(); return 0;
}
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}

openmesh与opengl结合使用

#if 1
#include "glad/glad.h"
#include "includes/glfw3.h"
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>typedef OpenMesh::TriMesh_ArrayKernelT<>  MyMesh;int main()
{MyMesh mesh;// 从文件中加载模型if (!OpenMesh::IO::read_mesh(mesh, "triangle.off")){std::cerr << "Error: Cannot read mesh from file 'output.off'" << std::endl;return 1;}// 获取第一个顶点的句柄MyMesh::VertexHandle vh = *(mesh.vertices_begin());// 获取顶点的当前位置MyMesh::Point current_pos = mesh.point(vh);// 修改顶点的位置mesh.set_point(vh, MyMesh::Point(current_pos[0] - 1.0, current_pos[1], current_pos[2]));// 保存模型/*if (!OpenMesh::IO::write_mesh(mesh, "modified_output.off")){std::cerr << "Error: Cannot write mesh to file 'modified_output.off'" << std::endl;return 1;}*/// 初始化GLFWif (!glfwInit()){return -1;}// 创建一个OpenGL窗口GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", NULL, NULL);if (!window){glfwTerminate();return -1;}glfwMakeContextCurrent(window);// 初始化GLADif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){return -1;}// 设置OpenGL渲染环境glViewport(0, 0, 800, 600);// ... (设置投影矩阵和视图矩阵,创建VBO,编写着色器等)// 创建顶点缓冲对象 (VBO)GLuint vbo;glGenBuffers(1, &vbo);// 绑定VBOglBindBuffer(GL_ARRAY_BUFFER, vbo);// 将模型的顶点数据传输到VBOglBufferData(GL_ARRAY_BUFFER, mesh.n_vertices() * sizeof(MyMesh::Point),&mesh.points()[0], GL_STATIC_DRAW);// 创建顶点数组对象 (VAO)GLuint vao;glGenVertexArrays(1, &vao);// 绑定VAOglBindVertexArray(vao);// 启用顶点属性数组glEnableVertexAttribArray(0);// 设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);// 解绑VAOglBindVertexArray(0);// 顶点着色器代码const char* vertexShaderSource = R"(#version 330 corelayout (location = 0) in vec3 position;void main(){gl_Position = vec4(position, 1.0);}
)";// 片段着色器代码const char* fragmentShaderSource = R"(#version 330 coreout vec4 FragColor;void main(){FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色}
)";// 创建着色器程序对象GLuint shaderProgram = glCreateProgram();// 创建顶点着色器对象并编译GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);// 创建片段着色器对象并编译GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);// 将顶点着色器和片段着色器附加到着色器程序glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);// 链接着色器程序glLinkProgram(shaderProgram);// 删除着色器对象(已经链接到程序中)glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 渲染循环while (!glfwWindowShouldClose(window)){glClear(GL_COLOR_BUFFER_BIT);// 渲染模型// 绑定VAO和着色器程序glUseProgram(shaderProgram);glBindVertexArray(vao);// 绘制模型glDrawArrays(GL_TRIANGLES, 0, mesh.n_vertices());// 解绑VAOglBindVertexArray(0);glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate();return 0;
}#else#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>typedef OpenMesh::PolyMesh_ArrayKernelT<>  MyMesh;int main()
{// 创建一个Mesh对象MyMesh mesh;// 添加顶点MyMesh::VertexHandle vhandle[4];vhandle[0] = mesh.add_vertex(MyMesh::Point(0.0, 0.0, 0.0));//0vhandle[1] = mesh.add_vertex(MyMesh::Point(1.0, 0.0, 0.0));//1vhandle[2] = mesh.add_vertex(MyMesh::Point(0.0, 1.0, 0.0));//2vhandle[3] = mesh.add_vertex(MyMesh::Point(0.0, 0.0, 1.0));//3// 添加面std::vector<MyMesh::VertexHandle> face_vhandles;face_vhandles.clear();face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[2]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[1]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);face_vhandles.clear();face_vhandles.push_back(vhandle[2]);face_vhandles.push_back(vhandle[0]);face_vhandles.push_back(vhandle[3]);mesh.add_face(face_vhandles);// 保存网格到文件OpenMesh::IO::write_mesh(mesh, "triangle.off");return 0;
}#endif

一些感悟

我发现一个很简单但是很实用的规律:在是OpenMesh编辑一个3D图像时,除了底部应该是顺时针,其他面都应该是逆时针。

要验证也很容易验证:在OpenMesh中编辑3D图像时,通常会遵循==“右手法则”==。这意味着当你站在多边形的外侧时,如果你用右手的拇指指向多边形的法线方向(也就是垂直于多边形的方向),那么其他手指的方向就是多边形的边缘顺时针方向。

所以,对于底部而言,它的法线方向应该是朝向多边形内部,所以多边形的边缘顺时针方向是正确的。对于其他面,法线方向应该朝向外部,因此多边形的边缘顺时针方向是逆时针的。

我一开始不管是尝试用stl去写一个3d图像,还是尝试使用OpenMesh来写一个3d图像,总是一次性写不对,总要来回改一下,知道了这个简单的规律就不会再犯错了

一些细碎知识点

1.OpenGL的状态通常被称为OpenGL上下文(Context)。

我常常在一些大佬的代码中看到xxx上下文,我常常为此感到不解,现在看来,上下文就可以理解为状态

而OpenGL自身是一个巨大的状态机(State Machine)。所以,上下文和状态,状态机的概念相关!

2.如何快速上手openmesh,照着这个教程,一共十五章,看完基本就是OK了

更多推荐

关于OpenMesh与OpenGL

本文发布于:2023-12-06 11:05:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1667407.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:OpenMesh   OpenGL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!