因为需求,我需要在opengl中把顶点集渲染到纹理中,然后传到CUDA中进行处理,随着鼠标的拖动,视点会相应变化,因此需要动态的生成纹理,并持续传入到CUDA中
请问,这样是否可行,对速度有多大影响?
这样应该是可行的,不过不是“生成”。
CUDA Runtime提供了cudaGraphicsGLRegisterBuffer/Image()函数,可以将opengl的buffer/texture/renderbuffer绑定为CUDA的显存指针或者array。
然后您根据您的喜好,可以将指针或者array绑定到cuda的texture;或者不绑定,直接在kernel中处理; 或者复制到host memory等。
对于您的第二个问题,我没有评估过cudaGraphicsGLRegisterBuffer之类的函数的具体性能,无法提供数据。
感谢楼主莅临CUDAZone China,
祝您周末愉快!
以及上文中您用cudaGraphicsGLRegisterImage得到的cuda array, 您不仅仅可以将其绑定到cuda的纹理引用,还可以绑定到cuda的表面,这样在kenrel里可以实现写入(注意写入是下次生效的)。
如果您还需要更详细的信息,可以看手册(《CUDA C/C++ Progamming Guide》以及《CUDA Toolkit Reference Manual》)。
前者本论坛有售,价格10个CUDA币。
谢谢,我使用了cudaGraphicsGLRegisterImage()函数,然后在CUDA当中绑定到纹理中。那么我想知道,在register和map成功之后,下次纹理再变化的时候,是否还需要再次map,l因为纹理会随着视点的变化,而不断变化,我大概试了一下,感觉速度有很大影响,不知道是什么原因,
楼主您好!
是否需要反复map,这个我不懂,我也不是OpenGL用户。
建议楼主自己试验下,或者,
建议您咨询其他版主/会员。
(注意今日是星期日,大家都可能不在。您的消息可能要等其他版主/会员周一上线。)
感谢您的来访,
祝您周末愉快。
这是我的代码
GenFrontFaceTexture();//生成纹理一张纹理,保存在fronttex中
//以下是映射到CUDA的过程
glBindTexture(GL_TEXTURE_2D, fronttex);
cudaGraphicsGLRegisterImage(&resource,fronttex,GL_TEXTURE_2D,cudaGraphicsMapFlagsWriteDiscard);
cudaGraphicsMapResources(1,&resource,0);
cudaGraphicsSubResourceGetMappedArray(&cuArrayFront,resource,0,0) ;
glBindTexture(GL_TEXTURE_2D, 0);
// 绑定到CUDA纹理
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(); //
cudabacktex.normalized = true; //归一
cudabacktex.addressMode[0] = cudaAddressModeClamp; //循环寻址方式
cudabacktex.addressMode[1] = cudaAddressModeClamp;
cudabacktex.filterMode = cudaFilterModeLinear; //线性滤波,
cutilSafeCall(cudaBindTextureToArray(cudafronttex, cuArrayFront, channelDesc));
当fronttex发生变化时,以上的映射过程是否需要重复,请各位高手指点
已经一天无人回复此问题了。
那么我对给出给出如下建议,希望能起到抛砖引玉的作用:
(1)楼主尝试不重新Map/Bind过程,然后看当贵代码改变了fronttex的时候,您的kernel是否可以直接执行。
(2)在(1)成功的基础上,检测当fronttex改变后,kernel读取出来的纹理元素的值是否相应发生改变。
如果(1)(2)都成功了,则楼主成功获取经验“GL纹理改变无需重新映射/绑定”。
如果(1)(2)任何一个失败,则楼主可成功获取经验“一旦改变必须重新绑定”。
此过程可能消耗楼主5-10分钟的时间,但无论结果如何,楼主都可以获得肯定性的答案。届时,欢迎楼主再次返回来,将自己的经验告知其他朋友,以反哺论坛。
此建议谨当抛砖引玉了。
现在我目前做的给大家汇报一下,没有达到预期目的,还请各位帮我分析一下。
首先放出代码,为方便大家分析,这里给出最简洁的形式:
void main()
{
…//一些准备工作
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
initPixelBuffer();//使用PBO将CUDA处理后的纹理传回OPENGL
SetupResourceForRender();//生成纹理准备工作
GenFrontFaceTexture();//生成第一个纹理
GenBackFaceTexture();//生成第二个纹理
MapTexToCuda();//注册到CUDA并绑定到纹理上
}
void display()
{
// use OpenGL to build view matrix
GLfloat modelView[16];
//视点旋转,生成旋转矩阵
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.5f,0.5f,0.5f);
glRotatef(-viewRotation.x, 1.0, 0.0, 0.0);
glRotatef(-viewRotation.y, 0.0, 1.0, 0.0);
glTranslatef(-0.5f,-0.5f,-0.5f);
glTranslatef(-viewTranslation.x, -viewTranslation.y, -viewTranslation.z);
glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
glPopMatrix();
invViewMatrix[0] = modelView[0]; invViewMatrix[1] = modelView[4]; invViewMatrix[2] = modelView[8]; invViewMatrix[3] = modelView[12];
invViewMatrix[4] = modelView[1]; invViewMatrix[5] = modelView[5]; invViewMatrix[6] = modelView[9]; invViewMatrix[7] = modelView[13];
invViewMatrix[8] = modelView[2]; invViewMatrix[9] = modelView[6]; invViewMatrix[10] = modelView[10]; invViewMatrix[11] = modelView[14];
eyePosition = mul(invViewMatrix, make_float4(0.0f, 0.0f, 0.0f, 1.0f));//计算新视点坐标
//以下三行用作实验,分别注释和解除注释
//GenFrontFaceTexture();
//GenBackFaceTexture();
//MapTexToCuda();
render();//render过程调用核函数,主要就是将生成的纹理原封不动的写回PBO,再在OPENGL中显示
// display results
//从PBO中读出纹理,并进行显示,为简洁考虑,此处略掉
…
glutSwapBuffers();
glutReportErrors();
}
主要进行了两个实验
第一个:将display函数中的三行生成纹理和映射的代码注释掉,即只保留main函数初始化时的第一次生成
结果:显示正确,但因为去掉了连续生成过程,所以图像不能转动
第二个:将display函数中的三行生成纹理和映射的代码去掉注释
结果:显示不正确,现象为图像变小了,减小到原来的1/3,并且有断续的显示和消失,并且显示bps从60减到30左右
现在暂时把是否再次映射的讨论放在一边,想请各位帮忙看看,为什么在display中加上持续生成纹理的代码以后,图像会变小呢,并且会一会显示出来,一会又消失呢,并且那时也没有转动图像,是因为效率的问题吗,
运行一段时间,GL警告,内存不足,会是什么原因?
关于我8楼提出的问题,display中加上持续生成纹理的代码以后,图像会变小的原因,大家看看我的分析有没有道理?
我在生成纹理的函数中,有一个设置视点的语句
gluLookAt(eyePosition.x,eyePosition.y,eyePosition.z, 0.5f,0.5f,0.5f, 0, 1, 0);
这句会不会影响到下面的显示纹理的过程?