Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为大网格实现VBOs并获得平滑动画?_C++_Opengl_Vbo_Maya - Fatal编程技术网

C++ 如何为大网格实现VBOs并获得平滑动画?

C++ 如何为大网格实现VBOs并获得平滑动画?,c++,opengl,vbo,maya,C++,Opengl,Vbo,Maya,我正在Maya中创建一个一分钟长的动画,并打算在OpenGL中渲染它。我在大学里做这个项目 这个场景只包括一张扭曲表情的人脸。网格有大约2200个四边形面 我发现了一个perl脚本,可以将波前对象文件转换为顶点和法线数组。我打算在Maya中以24fps的速度制作动画,然后将每一帧中的网格导出到波前对象文件,然后通过perl脚本运行所有网格,该脚本将为我提供顶点和法线数组 因此,为了测试可行性,我将Maya中动画的两帧转换为对象文件,并通过脚本运行它(调整后),这给了我数千次glVertex和gl

我正在Maya中创建一个一分钟长的动画,并打算在OpenGL中渲染它。我在大学里做这个项目

这个场景只包括一张扭曲表情的人脸。网格有大约2200个四边形面

我发现了一个perl脚本,可以将波前对象文件转换为顶点和法线数组。我打算在Maya中以24fps的速度制作动画,然后将每一帧中的网格导出到波前对象文件,然后通过perl脚本运行所有网格,该脚本将为我提供顶点和法线数组

因此,为了测试可行性,我将Maya中动画的两帧转换为对象文件,并通过脚本运行它(调整后),这给了我数千次
glVertex
glNormal
调用。我把所有这些都复制到我的C++程序中并编译了。它运行平稳

考虑到当我将60秒*24帧的
glVertex
glNormal
语句复制到程序中时程序会有多大,我想尝试使用VBOs。所以,我读了一些关于它的文章,但是我不太了解它的实现

所以我的第一个问题是:在这种情况下,实现VBOs的最佳方法是什么

我在考虑顶点和法线的2D数组,每帧一个;和
glBufferDataARB()
的“用法”参数的
GL\u STATIC\u DRAW\u ARB

比方说,如果我的动画有5帧长,我的面网格由2200个顶点和法线组成,那么我将创建:

GLfloat face_vertices[5][2200] = {.....};
GLfloat face_normals[5][2200] = {.....};
我的第二个问题:上面的代码在VBOs中是否工作或性能“良好”

此外,我不确定这些信息是否重要,但我的计算机运行的是Intel 82945G图形卡,我非常确定我学院的PC也运行Intel。我只是想提一下

更新

性能也是一个问题

我在考虑顶点和法线的2D数组,每帧一个;及

我认为这是不正确的解决方案。有了这么多的数据,流式传输是有意义的。例如,在内存中保留1秒的动画,根据需要加载其余动画。我相信这个场景中有
GL\u STREAM.****
标志

更好的解决方案是从maya及其动画导出骨骼。(在这种情况下,需要一个永远不会改变的网格)

只有在导出某些计算代价非常昂贵的内容时,才有权导出逐帧逐顶点动画。我能想到的唯一真实场景是3D流体网格(拓扑结构每帧都会改变,等等)——其他一切都可以在CPU或GPU上计算。然而,您的帖子并没有表明这是您的场景。所以,根据墨菲定律,我必须假设,对于一个可以用不同方法解决的问题,你们使用的是低效的解决方案

:上述代码在VBOs中是否正常工作或运行良好


无法回答,因为您没有说明如何绘制数据。通过多次滥用着色器、alpha混合或渲染同一事物,即使使用简单的几何体,也可以使任何机器屈服。

如果可以平滑运行两帧动画,则可以平滑运行60*24帧的“glVertex和glNormal语句”,如果可以从Maya动画自动生成GL调用。这种方法的唯一问题是,您的源代码和二进制可执行文件将非常庞大。这就是使您的方法“糟糕”的问题

因此,首先,不必对每个顶点数据调用一个glVertex,您可以将数据放在一个数组(或std::vector)中,并使用一个简单的循环对其进行迭代:

std::vector<int> idx;
std::vector<vertex> frame_data;
...
glBegin(GL_QUADS);
for(int i = 0; i < idx.size(); ++i) {
  glVertex3f(frame_data[idx].x, frame_data[idx].y, frame_data[idx].z);
  glNormal3f(frame_data[idx].nx, frame_data[idx].ny, frame_data[idx].nz);
}
glEnd();
请注意,v_计数不是2200。这是您的四边形计数,因此该数字与idx大小有关,而不是与帧_数据有关,即同一顶点可用于多个四边形面


您将需要两个缓冲区,一个用于保存idx的静态缓冲区(带有GL_static_DRAW的GL_元素_数组_缓冲区),因为这在执行期间不会更改,另一个用于保存顶点数据的“流”缓冲区(带有GL_stream_DRAW的GL_数组_缓冲区)。最后一个使用“GL_STREAM_DRAW”,因为您需要为动画的每一帧重写其内容。请参阅。

您是如何完成钻机的?顶点是否线性映射到关节?如果是,您可以轻松地将带有骨骼和动画的网格导出到波前文件中,并让众多游戏引擎之一读取该文件。他们中的一些能够在硬件着色器上播放动画,但我不确定Intel是否在支持列表中。哦,我在这方面做了很大的尝试。对于VBO优化,它们仅适用于使用旧(固定,例如无着色器)管道的静态网格。所以,如果英特尔的能力不是很强,你所能做的就是使用一些VBO——每一个都对应一帧。@Rekin“它们只适用于使用旧管道的静态网格”——嗯?你这是什么意思?顺便说一句,他没有使用任何索具,只是一个简单的变形模拟。谢谢你的回复,我会调查他们…现在有点不知所措。请参阅UPDATE@SigTerm,我打算用glpaurements()绘制它。
struct vertex {
  float x, y, z; // Position
  float nx, ny, nz; // Normal
};
...
vertex frame_data[v_count];
uint16_t idx[2200 * 4]; // 4 vertices makes one face