我試圖顯示在以有效的方式使用OpenGL和C++一個XY規則的網格限定的數學表面F(X,Y):如何優化在OpenGL中顯示大量四邊形?
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油漆代碼:
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();
}
問題是,這很慢,nx = ny = 1000,fps〜= 1。 如何優化這個更快?
編輯:(!謝謝)以下你的建議,關於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;
}
我想我明白,我怎麼可以創建一個VBO,它初始化爲XYZ(),它在發送給GPU一個去,但如何繪圖時使用VBO。我知道這可以在頂點着色器或glDrawElements中完成?我認爲後者更容易?如果是這樣的話:glDrawElements文檔中沒有看到任何QUAD模式!
EDIT2: 這樣我就可以循環通過所有的NX * NY四邊形,並繪製每個人:
GL_UNSIGNED_INT indices[4];
// ... set indices
glDrawElements(GL_QUADS, 1, GL_UNSIGNED_INT, indices);
?
請勿使用glBegin和glEnd,而應使用Vertex Buffers。網絡上有很多信息,只是谷歌的信息。頂點緩衝區允許你存儲,而不必重新上傳它的每一幀在GPU內存的頂點數據。這應該會給你帶來巨大的性能提升。 – s3rius
現代的OpenGL沒有'GL_QUADS'或'GL_QUAD_STRIP'。它們使用'GL_TRIANGLES'進行模擬。 – dupersuper
謝謝。將每個四邊形替換爲2個三角形應該很容易,但是我猜想重寫爲三角形帶會導致更高的fps,因爲我只能調用glDrawElements nx次(或者只調用一次?)而不是nx * ny次? – Andy