为什么OpenCL着色器在写入OpenGL纹理时忽略绿色,蓝色和Alpha通道?

问题描述:

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

这是我声明我写的使用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); 

给了我一个红色的质感,这是我期望。