opengl - 为什么 OpenCL 着色器在写入 OpenGL 纹理时会忽略绿色、蓝色和 Alpha channel ?

标签 opengl textures opencl shared

我有一个 opencl 着色器,它尝试将颜色写入纹理,但由于某种原因,只有红色 channel 应用于纹理,其余 channel 被忽略。不仅如此,这个红色 channel 值被复制到所有其他 channel ,给我一些透明的白色。有谁知道为什么会发生这种情况?我在 Mac 上使用 Xcode 进行编程(OpenCL 1.2)。纹理首先使用 OpenGL 创建并与 OpenCL 共享。

这就是我使用 OpenGL 声明我写入的纹理的方式:

void TextureManager::createTexture3D(TextureManager::TexturesInfo 
*texturesInfo, GLuint textureName)
{
    glError();
    glBindTexture(GL_TEXTURE_3D, texturesInfo->tex[textureName]);
    glError();
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glError();
    GLint level = 0, border = 0;

    GLint rgbType = GL_RGBA32F;
    GLint format = GL_RGBA;
    glTexImage3D(GL_TEXTURE_3D, level, rgbType, LPV::LPV_WIDTH, LPV::LPV_HEIGHT, LPV::LPV_DEPTH, border, format, GL_FLOAT, NULL);
    glError();
}

这是使用 OpenCL 创建共享资源的代码:
GLint error;
accume_buffer = clCreateFromGLTexture(context,CL_MEM_READ_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer, &error);
assert(error == CL_SUCCESS);
accume_buffer2 = clCreateFromGLTexture(context,CL_MEM_WRITE_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer2, &error);
assert(error == CL_SUCCESS);

这是运行 opencl 着色器的代码:
void LPV::runComputeShader(){

glFlush();
glFinish();
GLint error = 0;
cl_event opengl_get_completion;
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer, 0,0,&opengl_get_completion);
clWaitForEvents(1, &opengl_get_completion);
clReleaseEvent(opengl_get_completion);
assert(error == CL_SUCCESS);
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer2, 0,0,0);
assert(error == CL_SUCCESS);

error |= clSetKernelArg(computeKernel, 0, sizeof(cl_image), &accume_buffer);
assert( error == CL_SUCCESS);
error |= clSetKernelArg(computeKernel, 1, sizeof(cl_image), (void*)&accume_buffer2);
assert( error == CL_SUCCESS);


GLuint dimensions = 3;
size_t globalWorkSize[] = {LPV::LPV_WIDTH, LPV_HEIGHT, LPV_DEPTH };
size_t localWorkSize[] = { 1, 1, 1};

cl_event kernel_completion;
error = clEnqueueNDRangeKernel(command_queue, computeKernel, dimensions, NULL, globalWorkSize, nullptr, 0, NULL, &kernel_completion);
assert(error == CL_SUCCESS);
error = clWaitForEvents(1, &kernel_completion);
error |= clReleaseEvent(kernel_completion);
assert(error == CL_SUCCESS);


error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer, 0, 0, 0);
assert(error == CL_SUCCESS);
error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer2, 0, 0, 0);
assert(error == CL_SUCCESS);

clFlush(command_queue);
clFinish(command_queue);


}

最后,这是 opencl 着色器本身:
#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable

const sampler_t lpvSampler = CLK_NORMALIZED_COORDS_FALSE | 
CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;


kernel void propagate_lpv
                    (
                      read_only image3d_t src_buffer,
                      write_only image3d_t dest_buffer
                    )
{
    int4 coord;
    coord.x = (int)get_global_id(0);
    coord.y = (int)get_global_id(1);
    coord.z = (int)get_global_id(2);
    coord.w = 1;

float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f);
write_imagef(dest_buffer, coord, color);


}

有谁知道为什么会发生这种情况?谢谢

最佳答案

问题是我使用了错误的语法。遗憾的是,OpenCL 和 GLSL 似乎没有遵循我假设的相同语法。根据 OpenCL 编程指南的正确语法是这样的:

(float4)( float, float, float, float )
(float4)( float2, float, float )
(float4)( float, float2, float )
(float4)( float, float, float2 )
(float4)( float2, float2 )
(float4)( float3, float )
(float4)( float, float3 )
(float4)( float )

所以改变我的路线:
float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f);

到:
float4 color = (float4)(1.0f, 0.0f, 0.0f, 1.0f);

给我一个红色的纹理,这正是我所期望的。

关于opengl - 为什么 OpenCL 着色器在写入 OpenGL 纹理时会忽略绿色、蓝色和 Alpha channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46417627/

相关文章:

OpenGL 无绑定(bind)纹理 : Bind to uniform sampler2D array

c++ - 如何在 openGL 中移动窗口时重绘图片?

c - OpenCL for 循环给出 CL_OUT_OF_RESOURCES

java - OpenGL 纹理面向错误方向的问题

c - Opencl - 减少工作项数量的比率

opengl - GL/CL 互操作性 : Shared Texture

c++ - 绘制图像后颜色消失

java - 在 Java 进度条中实现平滑过渡

unity3d - 统一的 360 查看器,纹理出现在顶部和底部扭曲

opengl - 在 OpenGL 中绑定(bind)纹理