Qt 如何在OpenGL中优化显示大量四边形? 我尝试用OpenGL和C++以一种有效的方式在XY规则网格上定义一个数学曲面F(x,y): struct XYRegularSurface { double x0, y0; double dx, dy; int nx, ny; XYRegularSurface(int nx_, int ny_) : nx(nx_), ny(ny_) { z = new float[nx*ny]; } ~XYRegularSurface() { delete [] z; } float& operator()(int ix, int iy) { return z[ix*ny + iy]; } float x(int ix, int iy) { return x0 + ix*dx; } float y(int ix, int iy) { return y0 + iy*dy; } float zmin(); float zmax(); float* z; };
以下是迄今为止我的OpenGL绘制代码:Qt 如何在OpenGL中优化显示大量四边形? 我尝试用OpenGL和C++以一种有效的方式在XY规则网格上定义一个数学曲面F(x,y): struct XYRegularSurface { double x0, y0; double dx, dy; int nx, ny; XYRegularSurface(int nx_, int ny_) : nx(nx_), ny(ny_) { z = new float[nx*ny]; } ~XYRegularSurface() { delete [] z; } float& operator()(int ix, int iy) { return z[ix*ny + iy]; } float x(int ix, int iy) { return x0 + ix*dx; } float y(int ix, int iy) { return y0 + iy*dy; } float zmin(); float zmax(); float* z; };,qt,opengl,Qt,Opengl,以下是迄今为止我的OpenGL绘制代码: void color(QColor & col) { float r = col.red()/255.0f; float g = col.green()/255.0f; float b = col.blue()/255.0f; glColor3f(r,g,b); } void paintGL_XYRegularSurface(XYRegularSurface &surface, float zmin, f
void color(QColor & col) {
float r = col.red()/255.0f;
float g = col.green()/255.0f;
float b = col.blue()/255.0f;
glColor3f(r,g,b);
}
void paintGL_XYRegularSurface(XYRegularSurface &surface, float zmin, float zmax) {
float x, y, z;
QColor col;
glBegin(GL_QUADS);
for(int ix = 0; ix < surface.nx - 1; ix++) {
for(int iy = 0; iy < surface.ny - 1; iy++) {
x = surface.x(ix,iy);
y = surface.y(ix,iy);
z = surface(ix,iy);
col = rainbow(zmin, zmax, z);color(col);
glVertex3f(x, y, z);
x = surface.x(ix + 1, iy);
y = surface.y(ix + 1, iy);
z = surface(ix + 1,iy);
col = rainbow(zmin, zmax, z);color(col);
glVertex3f(x, y, z);
x = surface.x(ix + 1, iy + 1);
y = surface.y(ix + 1, iy + 1);
z = surface(ix + 1,iy + 1);
col = rainbow(zmin, zmax, z);color(col);
glVertex3f(x, y, z);
x = surface.x(ix, iy + 1);
y = surface.y(ix, iy + 1);
z = surface(ix,iy + 1);
col = rainbow(zmin, zmax, z);color(col);
glVertex3f(x, y, z);
}
}
glEnd();
}
?1/。使用,缓存GL命令-避免重新计算顶点和昂贵的逐顶点调用开销。如果数据已更新,则需要查看客户端顶点数组(不要与VAO混淆)。现在忽略这个选项
2/。使用自德国劳埃德船级社1.5起提供
由于无论如何都需要VBOs(即现代GL),您至少可以先掌握这一点。1/。使用,缓存GL命令-避免重新计算顶点和昂贵的逐顶点调用开销。如果数据已更新,则需要查看客户端顶点数组(不要与VAO混淆)。现在忽略这个选项
2/。使用自德国劳埃德船级社1.5起提供
既然你无论如何都需要VBOs(即现代GL),你至少可以先解决这个问题。你问了一个相当开放的问题。我建议一切都使用现代(3.0+)OpenGL。几乎所有新的OpenGL特性的要点都是提供一种更快的方式来做事情。像其他人建议的那样,使用数组(顶点)缓冲区对象和顶点数组对象。还要使用元素数组(索引)缓冲区对象。大多数GPU都有一个“变换后缓存”,它存储最后几个变换的顶点,但这只能在调用glDraw*元素函数族时使用。我还建议您在VBO中存储平面网格,其中每个顶点的y=0。从顶点着色器中的heightmap纹理采样y。如果执行此操作,则每当曲面发生更改时,只需更新heightmap纹理,这比更新VBO更容易。对高度贴图使用浮点或整数纹理格式之一,这样您就不必将值限制在0和1之间。好吧,您提出了一个相当开放的问题。我建议一切都使用现代(3.0+)OpenGL。几乎所有新的OpenGL特性的要点都是提供一种更快的方式来做事情。像其他人建议的那样,使用数组(顶点)缓冲区对象和顶点数组对象。还要使用元素数组(索引)缓冲区对象。大多数GPU都有一个“变换后缓存”,它存储最后几个变换的顶点,但这只能在调用glDraw*元素函数族时使用。我还建议您在VBO中存储平面网格,其中每个顶点的y=0。从顶点着色器中的heightmap纹理采样y。如果执行此操作,则每当曲面发生更改时,只需更新heightmap纹理,这比更新VBO更容易。对于高度贴图,请使用浮点或整数纹理格式之一,这样您就不必将值限制在0和1之间 如果是:我在GLDrawerElements的文档中没有看到任何四元模式 如果你想要四边形,请确保你看到的是四边形,而不是四边形 如果是:我在GLDrawerElements的文档中没有看到任何四元模式
如果需要四边形,请确保查看的是,而不是。不要使用glBegin和glEnd,而是使用顶点缓冲区。网络上有很多信息,只有谷歌提供。顶点缓冲区允许您将顶点数据存储在GPU内存中,而无需每帧重新上传。这将大大提高性能。现代OpenGL没有
GL\u四边形
或GL\u四边形
。它们是使用GL\u三角形
模拟的。谢谢。用2个三角形替换每个四边形应该很容易,但我想重写为三角形带将导致更高的fps,因为我只能调用glDrawerElements nx次(或仅一次?),而不是nx*ny次?如果使用退化三角形,只需调用一次,即没有像素将被光栅化的三角形。也可以使用原语重新启动。我认为你在三角形上使用三角形条带的想法是正确的,但是对于更复杂的网格,三角形通常更快,因为它们可以更好地利用PTC。要清楚,如果你只使用三角形而不是条带,您仍然可以通过一次调用glDraweElements
将它们全部传递。不要使用glBegin和glEnd,而是使用顶点缓冲区。网络上有很多信息,只有谷歌提供。顶点缓冲区允许您将顶点数据存储在GPU内存中,而无需每帧重新上传。这将大大提高性能。现代OpenGL没有GL\u四边形
或GL\u四边形
。它们是使用GL\u三角形
模拟的。谢谢。用2个三角形替换每个四边形应该很容易,但我想重写为三角形带将导致更高的fps,因为我只能调用glDrawerElements nx次(或仅一次?),而不是nx*ny次?如果使用退化三角形,只需调用一次,即没有像素将被光栅化的三角形。也可以使用原语重新启动。我认为您在三角形上使用三角形条带的想法是正确的,但是对于更复杂的网格,三角形通常更快,因为它们可以更好地利用PTC。更清楚的是,如果您只使用三角形而不是条带,您仍然可以通过一次调用gldrawerelements
来传递它们。谢谢!按照你的建议,我首先关注VBO。谢谢!按照你的建议,我首先关注VBO。
float* XYRegularSurface::xyz() {
float* data = new float[3*nx*ny];
long i = 0;
for(int ix = 0; ix < nx; ix++) {
for(int iy = 0; iy < ny; iy++) {
data[i++] = x(ix,iy);
data[i++] = y(ix,iy);
data[i] = z[i]; i++;
}
}
return data;
}
GL_UNSIGNED_INT indices[4];
// ... set indices
glDrawElements(GL_QUADS, 1, GL_UNSIGNED_INT, indices);