2011-02-02 13 views
0

私の図面のパフォーマンスを向上させようとしています。私が実際に行うことは、高さを色として2Dでメッシュを描画することです。私はx-y座標のmesh_xy行列と高さ行列のmesh_zを持っており、プロット要素のためのインデックス行列を構築しています。まず、クライアント側配列を使用しようとしましたが、正常に動作します。次に、mesh_xyをVBOとしてサーバー側に置くことで、最小限の変更を行いました。何もレンダリングされません。誰でも私を助けることができますか?OpenGL VBO(混在インデックス、テックス座標配列)が機能しません。

関連コードが下に貼り付けられます。 draw_bmfm5()は、クライアントサイド配列を使って完璧に機能する関数です。 draw_bmfm6()はVBOです(mesh_xyのみがサーバー側にあります)。私が言及する必要があることは、私のグラフィックスカードは、私が他のプログラムを使ってテストしたVBOをサポートしていることです。

void draw_bmfm5(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    glEnableClientState(GL_INDEX_ARRAY); 
    glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred 
    glTexCoordPointer(1,GL_FLOAT,0,mesh_z); 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_INDEX_ARRAY); 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

//the only difference between 5 and 6 is: 
//we are going to store the mesh_xy into the server side 
GLuint vbo_vertex,vbo_tex,vbo_indx; 
PFNGLGENBUFFERSARBPROC pglGenBuffersARB = 0;      // VBO Name Generation Procedure 
PFNGLBINDBUFFERARBPROC pglBindBufferARB = 0;      // VBO Bind Procedure 
PFNGLBUFFERDATAARBPROC pglBufferDataARB = 0;      // VBO Data Loading Procedure 
#define glGenBuffersARB   pglGenBuffersARB 
#define glBindBufferARB   pglBindBufferARB 
#define glBufferDataARB   pglBufferDataARB 

void create_vbo() 
{ 


    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); 
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); 
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB"); 

    glGenBuffersARB(1,&vbo_vertex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW); 

    glGenBuffersARB(1,&vbo_tex); 

    glGenBuffersARB(1,&vbo_indx); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx); 
    glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW); 


} 
void draw_bmfm6(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    glEnableClientState(GL_INDEX_ARRAY); 
    //glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glVertexPointer(2,GL_FLOAT,0,0); 

    glTexCoordPointer(1,GL_FLOAT,0,mesh_z); 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_INDEX_ARRAY); 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

答えて

2

GL_INDEX_ARRAYは、あなたが何を意味するのかを意味するものではありません。これは、カラーパレットからカラーセレクタを制御することを意味します。これは、パレタイズされたフレームバッファにレンダリングするときにGLで使用されます。 glDrawElementsを呼び出すという単純な事実は、頂点インデックスを使用していることを意味します。有効にするクライアント側配列はありません。

だから... ...あなたはVBOを見たとき、あなたはそれがあなたの呼び出しが混乱して取得する方法を見ることができます。

glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx); 
glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW); 

は、最後の呼び出しが実際にARRAY_BUFFERにバインドされたバッファー、すなわちvbo_texを使用しています。 したがって、インデックスをvbo_texにアップロードして、何もvbo_indxに入れません。

次に、VBOのバインドでは、各Pointerコールに適切なvboを選択していません。

インデックスと頂点は基本的に異なります。あなたはvbosにどちらか一方(好ましくは両方)を置くことができますが、あなたのindex_xy構造体は配列の配列なので、vbosに頂点だけを置くコードを記述します(インデックスは)

はすべて一緒にこれを置く与える:

void create_vbo() 
{ 
    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); 
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); 
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB"); 

    glGenBuffersARB(1,&vbo_vertex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW); 

    glGenBuffersARB(1,&vbo_tex); 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); 
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW); 

} 
void draw_bmfm6(float scale) 
{ 
    glPushMatrix(); 
    glScalef(scale,scale,1.0f); 

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_TEXTURE_1D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default 
    glEnableClientState(GL_VERTEX_ARRAY); // Why was this Disable ? 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate 
    //glEnableClientState(GL_INDEX_ARRAY); // removed 
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex); 
    glVertexPointer(2,GL_FLOAT,0,0); 

    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); // Binding the texcoord buffer 
    glTexCoordPointer(1,GL_FLOAT,0,0); // 0 as offset 
    for(i=0;i<n-1;i++) 
    { 
     glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]); 
    } 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    // glDisableClientState(GL_INDEX_ARRAY); // not needed 

    glDisable(GL_TEXTURE_1D); 
    glPopMatrix(); 

} 

注:私はこのコードをテストしていませんが、私は多くの問題を修正しました。他にもあるかもしれない。

最後に、インデックス配列データをVBOにプッシュするには、バインドしてデータをELEMENT_ARRAY_BUFFERに入れ、glDrawElements呼び出しからバッファにオフセットを渡す必要があります。

+0

Hello Bahbar、詳細な返信をありがとうございます。私はあなたの変更を適用し、それは動作します!パフォーマンスは大幅に向上しました。 1つの質問は、サーバー側の頂点行列mesh_xyをVBOとして置くだけで、クライアント側にmesh_zを残すと(この行列は毎回変わるので)、色は同じで、高さマップmesh_zを反映していません。それは可能ですか?ありがとうございました。あなたの助けが高く評価されます。 – shangping

+0

@shangping:可能です。 glTexCoordPointerをクライアントサイドバッファで呼び出す前に、glBindBuffer(GL_ARRAY_BUFFER、0)を使用してください。 – Bahbar

+0

こんにちはBahbar、クイック返信いただきありがとうございます。それは再び働いた。しかし、問題は、すべてのパフォーマンスの向上が失われ、クライアント側の配列と同じです。コードは次のようになります。\t glBindBufferARB(GL_ARRAY_BUFFER、vbo_vertex); \t glVertexPointer(2、GL_FLOAT、0,0); \t \t glBindBufferARB(GL_ARRAY_BUFFER、0); \t glTexCoordPointer(1、GL_FLOAT、0、mesh_z); 理由は分かりますか? – shangping

関連する問題