gpt4 book ai didi

c - 使用 OpenGL 从使用 CUDA 生成的顶点缓冲区对象绘制图像

转载 作者:太空狗 更新时间:2023-10-29 15:29:19 24 4
gpt4 key购买 nike

我正在使用 CUDA 生成此 ABGR 输出图像。有问题的图像存储在 uchar4 数组中。数组的每个元素代表图像中每个像素的颜色。显然,这个输出数组是一个二维图像,但它在 CUDA 中被分配为交错字节的线性内存。

我知道 CUDA 可以轻松地将此数组映射到 OpenGL 顶点缓冲区对象。我的问题是,假设我有图像中每个像素的 RGB 值,以及图像的宽度和高度,我如何使用 OpenGL 将此图像绘制到屏幕上?
我知道必须涉及某种着色器,但由于我的知识很少,所以我不知道着色器如何使用每个像素的颜色,而是将其映射到正确的屏幕像素。

我知道我应该增加我在 OpenGL 方面的知识,但这似乎是一项微不足道的任务。如果有一种简单的方法可以让我绘制这幅图像,我宁愿不花太多时间学习 OpenGL。

最佳答案

我终于想出了一个简单的方法来做我想做的事。不幸的是,我不知道 Robert 在 NVIDIA 网站上谈论的样本的存在。

长话短说,绘制图像最简单的方法是在 OpenGL 中定义像素缓冲区对象,向 CUDA 注册缓冲区并将其作为 uchar4 的输出数组传递给 CUDA 内核。这是一个基于 JOGL 和 JCUDA 的快速伪代码,显示了所涉及的步骤。大部分代码是从 NVIDIA 网站上的示例中获取的:

1) 创建 OpenGL 缓冲区

GL2 gl = drawable.getGL().getGL2();

int[] buffer = new int[1];

// Generate buffer
gl.glGenBuffers(1, IntBuffer.wrap(buffer));
glBuffer = buffer[0];

// Bind the generated buffer
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, glBuffer);
// Specify the size of the buffer (no data is pre-loaded in this buffer)
gl.glBufferData(GL2.GL_ARRAY_BUFFER, imageWidth * imageHeight * 4, (Buffer)null, GL2.GL_DYNAMIC_DRAW);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

// The bufferResource is of type CUgraphicsResource and is defined as a class field
this.bufferResource = new CUgraphicsResource();

// Register buffer in CUDA
cuGraphicsGLRegisterBuffer(bufferResource, glBuffer, CUgraphicsMapResourceFlags.CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);

2)初始化纹理并设置纹理参数

GL2 gl = drawable.getGL().getGL2();
int[] texture = new int[1];

gl.glGenTextures(1, IntBuffer.wrap(texture));
this.glTexture = texture[0];

gl.glBindTexture(GL2.GL_TEXTURE_2D, glTexture);

gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);


gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA8, imageWidth, imageHeight, 0, GL2.GL_BGRA, GL2.GL_UNSIGNED_BYTE, (Buffer)null);

gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

3) 运行 CUDA 内核并在 OpenGL 的显示循环中显示结果。

this.runCUDA();

GL2 gl = drawable.getGL().getGL2();

gl.glBindBuffer(GL2.GL_PIXEL_UNPACK_BUFFER, glBuffer);

gl.glBindTexture(GL2.GL_TEXTURE_2D, glTexture);
gl.glTexSubImage2D(GL2.GL_TEXTURE_2D, 0, 0, 0,
imageWidth, imageHeight,
GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, 0); //The last argument must be ZERO! NOT NULL! :-)

gl.glBindBuffer(GL2.GL_PIXEL_PACK_BUFFER, 0);
gl.glBindBuffer(GL2.GL_PIXEL_UNPACK_BUFFER, 0);

gl.glBindTexture(GL2.GL_TEXTURE_2D, glTexture);
gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glDisable(GL2.GL_DEPTH_TEST);
gl.glDisable(GL2.GL_LIGHTING);
gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);

gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();

gl.glViewport(0, 0, imageWidth, imageHeight);


gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex2f(-1.0f, -1.0f);


gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex2f(1.0f, -1.0f);


gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex2f(1.0f, 1.0f);


gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex2f(-1.0f, 1.0f);
gl.glEnd();

gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPopMatrix();

gl.glDisable(GL2.GL_TEXTURE_2D);

3.5) CUDA 调用:

public void runCuda(GLAutoDrawable drawable) {

devOutput = new CUdeviceptr();
// Map the OpenGL buffer to a resource and then obtain a CUDA pointer to that resource
cuGraphicsMapResources(1, new CUgraphicsResource[]{bufferResource}, null);
cuGraphicsResourceGetMappedPointer(devOutput, new long[1], bufferResource);

// Setup the kernel parameters making sure that the devOutput pointer is passed to the kernel
Pointer kernelParams =
.
.
.
.

int gridSize = (int) Math.ceil(imageWidth * imageHeight / (double)DESC_BLOCK_SIZE);

cuLaunchKernel(function,
gridSize, 1, 1,
DESC_BLOCK_SIZE, 1, 1,
0, null,
kernelParams, null);
cuCtxSynchronize();

// Unmap the buffer so that it can be used in OpenGL
cuGraphicsUnmapResources(1, new CUgraphicsResource[]{bufferResource}, null);
}

PS:感谢 Robert 提供示例链接。我还要感谢那些在没有任何有用反馈的情况下对我的问题投反对票的人!

关于c - 使用 OpenGL 从使用 CUDA 生成的顶点缓冲区对象绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21765604/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com