C++ 使用顶点缓冲区对象在OpenGL中绘制曲面时出现不需要的锯齿
首先,我给出了opengl中出现问题的渲染图像的屏幕截图。第四个曲面图像是用Matlab绘制的,它是Opengl中的图像 数据集的Matlab渲染: (前3幅图像是OpenGL从不同角度绘制的有问题的锯齿图形,第4幅图像是MATLAB绘制的正确图像) 该图像是一个1024 x 1024的复数矩阵。每个元素的想象部分是点的高度(在1024x1024高度贴图中),真实部分是点的颜色 在matlab中,我们创建了一个小的高斯形状的山。在OpenGL中,它使用碎布和锯齿进行渲染。“粗糙”在整个图像中传播 此外,根据对象的视角,在直线之外似乎有一个区域,不仅出现了更奇怪的锯齿,而且渲染的图形也会发生高度跳跃/变化 这是什么原因造成的?为什么会出现这种“衣衫褴褛”的情况?这条线是什么?我们现在已经没有什么主意了,我们会报答任何帮助的。下面给出了VBO代码的相关部分。我们基本上为顶点创建一个float4对象。结构中的第一、第二和第三个浮点数对应点的坐标。第四个浮点数(视为4个单字节数字)是RGBA颜色 还请注意,包含高度贴图和颜色信息的复杂矩阵存储在GPU中,因此代码中有对CUDA的调用。当所有数据转储到一个文件中时,matlab成功地绘制了地图,因此数据绝对正确C++ 使用顶点缓冲区对象在OpenGL中绘制曲面时出现不需要的锯齿,c++,opengl,cuda,vbo,C++,Opengl,Cuda,Vbo,首先,我给出了opengl中出现问题的渲染图像的屏幕截图。第四个曲面图像是用Matlab绘制的,它是Opengl中的图像 数据集的Matlab渲染: (前3幅图像是OpenGL从不同角度绘制的有问题的锯齿图形,第4幅图像是MATLAB绘制的正确图像) 该图像是一个1024 x 1024的复数矩阵。每个元素的想象部分是点的高度(在1024x1024高度贴图中),真实部分是点的颜色 在matlab中,我们创建了一个小的高斯形状的山。在OpenGL中,它使用碎布和锯齿进行渲染。“粗糙”在
#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();
}
//内核填充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;
}
}
\uuuuu全局\uuuuu无效填充(无符号整数*位置i,无符号整数M)
{
无符号整数x=blockIdx.x*blockDim.x+threadIdx.x;
无符号整数y=blockIdx.y*blockDim.y+threadIdx.y;
无符号整数bi;
如果(y将第二个三角形替换为:
pos_i[bi++] = x + y*M + 1;
pos_i[bi++] = x + y*M + M + 1;
pos_i[bi++] = x + y*M + M;
而且,我很确定应该是这样
bi = (M*y +x)*6;
将第二个三角形替换为:
pos_i[bi++] = x + y*M + 1;
pos_i[bi++] = x + y*M + M + 1;
pos_i[bi++] = x + y*M + M;
而且,我很确定应该是这样
bi = (M*y +x)*6;
我试过了,但问题仍然存在(锯齿和跳跃高度)。我试过了,但问题仍然存在(锯齿和跳跃高度)。在一个非常小的网格上尝试,在CPU上使用IBO计算。您将使用调试器查看值,并使用纸笔检查值。在一个非常小的网格上尝试,在CPU上使用IBO计算。您将使用调试器查看值,并使用纸笔检查值。