桥豆喵 2021-08-24 19:52 采纳率: 0%
浏览 72
已结题

OpenGL关于glDrawPixels()绘制不出像素数据

最近在学习opengl和cuda混合编程。
使用的库是glfw3.3和glew2.1.0。cuda11.4
glDrawPixels()不能绘制图片是为什么啊?无论是把内存中的数组作为数据源还是绑定了一个有数据的pbo,调用glDrawPixels()之后输出都是一整块黑色。

代码节选如下(文件很多,只挑了相关的贴上):

global void kernel(GLubyte* inPtr, GLubyte* outPtr) {
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outPtr[(x + 1000 * y) * 4 + 0] = 0;
outPtr[(x + 1000 * y) * 4 + 1] = 255;
outPtr[(x + 1000 * y) * 4 + 2] = 255;
outPtr[(x + 1000 * y) * 4 + 3] = 255;
if ((x == 990) && (y == 990)) {
printf("Pixel(%d, %d)\n"
"Input:R:%d\tG:%d\tB:%d\tA:%d\n",
x, y,
inPtr[(x + 1000 * y) * 4 + 0],
inPtr[(x + 1000 * y) * 4 + 1],
inPtr[(x + 1000 * y) * 4 + 2],
inPtr[(x + 1000 * y) * 4 + 3]);
printf("Output:R:%d\tG:%d\tB:%d\tA:%d\n\n",
outPtr[(x + 1000 * y) * 4 + 0],
outPtr[(x + 1000 * y) * 4 + 1],
outPtr[(x + 1000 * y) * 4 + 2],
outPtr[(x + 1000 * y) * 4 + 3]);
}
}
/设置PBO/
void windowObject::setPBO(void) {
glGenBuffers(2, PBO);
/分配显存空间/
/PBO[0]用于存储帧缓存数据/
glBindBuffer(GL_PIXEL_PACK_BUFFER, PBO[0]);
glBufferData(GL_PIXEL_PACK_BUFFER, width * height * 4/RGBA/, NULL, GL_DYNAMIC_READ);
/把缓冲区作为资源分享给CUDA,该缓存区可读可写/
/* 这个绑定缓存区必须在glBufferData()后面逐个共享,不能先都绑定
* BufferData再一起共享显存
/
checkCUDAError(cudaGraphicsGLRegisterBuffer(&inputRes, PBO[0], cudaGraphicsMapFlagsNone));
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
/PBO[1]用于写入像素映射后的数据/
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PBO[1]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height * 4, NULL, GL_DYNAMIC_DRAW);
checkCUDAError(cudaGraphicsGLRegisterBuffer(&outputRes, PBO[1], cudaGraphicsMapFlagsNone));
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
/像素映射的主要过程/
void windowObject::pixelMapping(void) {
/从后缓存中读取数据/
glReadBuffer(GL_BACK);
/绑定像素读取PBO/
glBindBuffer(GL_PIXEL_PACK_BUFFER, PBO[0]);
/像素读取,从左下(0,0)坐标读widthheight的一整个画面
/
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
/读完解绑PBO/
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
/开启像素映射/
checkCUDAError(cudaGraphicsMapResources(1, &inputRes, NULL));
checkCUDAError(cudaGraphicsMapResources(1, &outputRes, NULL));
checkCUDAError(cudaGraphicsResourceGetMappedPointer((void**)&d_inPBO, &inSize, inputRes));
checkCUDAError(cudaGraphicsResourceGetMappedPointer((void**)&d_outPBO, &outSize, outputRes));
}
/像素取消映射/
void windowObject::pixelUnmapping(void) {
checkCUDAError(cudaGraphicsUnmapResources(1, &inputRes, NULL));
checkCUDAError(cudaGraphicsUnmapResources(1, &outputRes, NULL));
}
/绘制映射后的图片/
void windowObject::drawPixels(void) {
glDrawBuffer(GL_BACK);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PBO[1]);
//glRasterPos2i(0, 0);
glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
/绘制完毕后解绑/
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
int main(int argc, char* argv[])
{
...
/设置PBO/
/1个窗口有2个PBO,一个用于读取帧缓存,经过像素映射到另一个PBO,再回传绘制到帧缓存/
/像素映射过程可以用CUDA并行计算/
window[0].setPBO;

/*设置视口数量*/
window[0].setViewports(1, 1);
/*激活MSAA*/
glEnable(GL_MULTISAMPLE);
/*开启深度测试*/
glEnable(GL_DEPTH_TEST);
/*主循环*/
while (!glfwWindowShouldClose(window[0].windowPtr)) {
    /*设置清空时的背景色*/
    glClearColor(0.2f, 0.5f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

...
    /*像素映射渲染*/
    window[0].pixelMapping();
    /*调用CUDA核函数进行像素映射*/
    kernel <<<window[0].gridSize, window[0].blockSize >>> (window[0].d_inPBO, window[0].d_outPBO);
    /*同步主机和设备*/
    checkCUDAError(cudaDeviceSynchronize());
    /*像素取消映射*/
    window[0].pixelUnmapping();
    /*像素绘制*/
    window[0].drawPixels();
    /*完成像素映射后才交换缓存区*/
    glfwSwapBuffers(window[0].windowPtr);
    /*键盘和鼠标输入*/
    window[0].input(model[0]);
    /*检查是否触发了事件(键盘输入、鼠标移动等)*/
    glfwPollEvents();
}

...
}
结果如下:

img

为了debug,重新用glRasterPos2i设定了绘制起点,得到下面的结果:

img

可以发现问题就是glDrawPixels()画了个寂寞。 。是这个函数使用的时候有什么注意事项我给漏了吗。。。

  • 写回答

1条回答 默认 最新

  • 有问必答小助手 2021-08-26 09:41
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


    因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

    评论

报告相同问题?

问题事件

  • 系统已结题 9月1日
  • 修改了问题 8月24日
  • 修改了问题 8月24日
  • 创建了问题 8月24日

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3