まず、問題のあるレンダリングされた画像のスクリーンショットをopenglで提供します。4番目の表面画像はMatlabによって描画され、Openglでの画像のようになります。
。
。
。
データセットのMatlabレンダリング:
(最初の3つの画像は、さまざまな角度でのOpenGLからの問題のある鋸歯状の描画であり、4番目の画像は正しいMATLAB描画画像です)
画像は1024x1024の複素数行列です。各要素の虚数部はポイントの高さ(1024x1024の高さマップ)であり、実数部はポイントの色です。
matlabで、小さなガウス型の山を作成しました。OpenGLでは、ぼろきれとセレーションでレンダリングされます。「ぼろぼろ」は画像全体に広がります。
さらに、オブジェクトの表示角度に応じて、線を超えた領域があり、セレーションのより奇妙なバージョンが発生するだけでなく、レンダリングされたグラフィックスが高さをジャンプ/変更するように見えます。
これを引き起こす原因は何ですか?なぜこの「不規則さ」が起こっているのですか、そしてその線は何ですか?私たちは今、すべてのアイデアを使い果たしており、どんな助けにも感謝します。VBOコードの関連部分を以下に示します。基本的に、頂点のfloat4オブジェクトを作成します。構造内の1番目、2番目、3番目の浮動小数点数は、ポイントの調整に対応しています。4番目のフロート(4つの1バイト数として扱われる)はRGBA色です。
また、高さマップと色情報を含む複雑なマトリックスがGPUに格納されているため、コードでCUDAが呼び出されることにも注意してください。すべてのデータがファイルにダンプされると、matlabはマップを正常に描画するため、データは間違いなく正しいものになります。
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
void initGL()
{
...
glViewport(0, 0, window_width, window_height);
glEnable(GL_BLEND);
glEnable(GL_COLOR_MATERIAL);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 0.1, 15.0);
...
}
void display()
{
camx += camx_v;
camy += camy_v;
camx_v=0;
camy_v=0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 1, /* look from camera XYZ */
0, 0, 0, /* look at the origin */
0, 1, 0); /* positive Y up vector */
drawGround();
glTranslatef(camx, camy, translate_z);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 16, BUFFER_OFFSET(0));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 16, BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_i);
glDrawElements(GL_TRIANGLES, (mesh_width-1) * (mesh_height-1) * 6, GL_UNSIGNED_INT, (GLvoid*)0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glutSwapBuffers();
}
void createVBO(GLuint* vbo, struct cudaGraphicsResource **vbo_res,
unsigned int vbo_res_flags)
{
glGenBuffers(1, vbo);
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
unsigned int size = mesh_width * mesh_height * 4 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
cutilSafeCall(cudaGraphicsGLRegisterBuffer(vbo_res, *vbo, vbo_res_flags));
}
void createIBO(GLuint* vbo, struct cudaGraphicsResource **vbo_res,
unsigned int vbo_res_flags, unsigned int numofindice)
{
glGenBuffers(1, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *vbo);
unsigned int size = (mesh_width-1) * (mesh_height-1) * numofindice * sizeof(GLuint);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
cutilSafeCall(cudaGraphicsGLRegisterBuffer(vbo_res, *vbo, vbo_res_flags));
}
void main()
{
initGL();
createVBO(&vbo, &cuda_vbo_resource, cudaGraphicsMapFlagsWriteDiscard);
createIBO(&vbo_i, &cuda_vbo_resource_i, cudaGraphicsMapFlagsWriteDiscard, 6);
glutMainLoop();
}
//プログラムの初期化時に1回呼び出されるGPUのインデックスバッファを埋めるためのカーネル。
__global__ void fillIBO(unsigned int* pos_i, unsigned int M)
{
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
unsigned int bi;
if(y<M-1 && x<M-1)
{
bi = ((M-1)*y +x)*6;
//TRI
pos_i[bi++] = x + y*M + 1;
pos_i[bi++] = x + y*M + M + 1;
pos_i[bi++] = x + y*M;
pos_i[bi++] = x + y*M;
pos_i[bi++] = x + y*M + M + 1;
pos_i[bi++] = x + y*M + M;
}
}