使用CUDA-OpenGL互操作时,NPOT纹理会导致不良渲染

问题描述

这是代码,现在仅尝试渲染渐变。 我最终要完成的工作是使用CUDA渲染光线跟踪的场景,然后将其显示在屏幕上,并具有移动的能力。 我遇到的主要问题是使计算的图像完全显示,因为现在我只用一个渐变对其进行测试,而当我的屏幕不是两个平方的幂时,我遇到了问题。

#define width 1024
#define height 256
struct cudaGraphicsResource* screen;
uchar4* rendered;
GLFWwindow* window;
GLuint image;
__global__ void computeFrame(uchar4* rendered){
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
    if (x > width || y > height) return;
    int index = y * height + x;
    rendered[index] = make_uchar4(y/(height*1.0f)*255,255);
}
void createTexture(){
    glGenTextures(1,&image);
    glBindTexture(GL_TEXTURE_2D,image);
    glTexImage2D(GL_TEXTURE_2D,GL_RGBA,width,height,GL_UNSIGNED_BYTE,NULL);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D,0);
}
int renderFrame() {
    cudaDeviceSynchronize();
    cudaGraphicsMapResources(1,&screen,0);
    cudaArray* dstArray;
    cudaGraphicsSubResourceGetMappedArray(&dstArray,screen,0);
    dim3 block(16,16);
    dim3 grid((width + block.x - 1) / block.x,(height + block.y - 1) / block.y);
    computeFrame << <grid,block >> > (rendered);
    cudaMemcpyToArray(dstArray,rendered,width * height * sizeof(uchar4),cudaMemcpyDeviceToDevice);
    cudaDeviceSynchronize();
    cudaGraphicsUnmapResources(1,0);
    return 0;

}
void displayFrame() {
    static int frno = 0;
    frno++;
    if (frno > 60) {
        frno = 0;
        printf("60frames passed\n");
    }
    renderFrame();
    glBindTexture(GL_TEXTURE_2D,image);
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-width,-height,-1.0,1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,height);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0,0.0); glVertex3f(-width,0.5);
    glTexCoord2f(1,0.0); glVertex3f(width,1); glVertex3f(width,0.5);
    glTexCoord2f(0.0,1); glVertex3f(-width,0.5);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glfwSwapBuffers(window);
}
int main(int argc,char** argv){
    glfwInit();
    glewInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0);
    window = glfwCreateWindow(width,"Rotaru Leonard Claudiu",NULL,NULL);
    glfwMakeContextCurrent(window);
    cudaSetDevice(0);
    createTexture();
    cudaGraphicsGLRegisterImage(&screen,image,GL_TEXTURE_2D,cudaGraphicsRegisterFlagsNone);
    cudaMalloc(&rendered,width * height * sizeof(uchar4));
    while (true) {
        displayFrame();
    }
    glfwTerminate();
}

这是运行宽度和高度1024的结果: width 1024 height 1024 这是运行宽度1024和高度512的结果: width 1024 height 512

解决方法

将来请提供完整的代码。当您删除包含标头时,它没有帮助。

根据我的测试,至少有几个问题。

  1. 在您的一张屏幕截图中,您可以看到编译器告诉您cudaMemcpyToArraydeprecated。此外,在此设置中使用它无论如何都不正确。因此,我们将其替换为cudaMemcpy2DToArray。代替这个:

    cudaMemcpyToArray(dstArray,rendered,width * height * sizeof(uchar4),cudaMemcpyDeviceToDevice);
    

    使用此:

    cudaMemcpy2DToArray(dstArray,width * sizeof(uchar4),height,cudaMemcpyDeviceToDevice);
    
  2. 您检查内核的边界不正确:

    if (x > width || y > height) return;
    

    应该是:

    if (x >= width || y >= height) return;
    

    这是标准的计算机科学一次性错误。

  3. 您对index的内核计算不正确:

    int index = y * height + x;
    

    应该是:

     int index = y * width + x;
    

    y是您的高度变量,我们必须将其乘以每行的宽度以获得正确的一维索引。

进行了这些更改之后,您的代码对于我来说似乎可以正确运行,高度为256,如图所示。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...