2012-01-30 2 views
5

저는 Geforce 330M에서 CUDA Toolkit 4.0으로 텍스처를위한 OpenCL-OpenGL interop을 시도하고 있습니다.CL/GL-Interop 용 OpenGL 텍스처 형식 유형이 잘못 되었습니까?

프레임을 캡처하고 그 데이터를 OpenCL 커널에 대한 입력 이미지 (Image2D)로 사용하고 싶습니다. 커널은 데이터를 조작하고 첨부 된 OpenGL 텍스처가있는 이미지 객체 인 Image2DGL에 데이터를 기록해야합니다. 기본적으로는 다음과 같습니다

_______________  RGB  _______________ 
|    | uint8*  |    | CL_RGBA/CL_UNORM_INT8 
| Grabber  | ------------> | Image2D  | -------------------------. 
| avcodec  |    | [input]  |       | 
|_______________|    |_______________|       | 
                      |  
                      V 
_______________     _______________      _______________ 
|    |    |    |      |    | 
| Texture  | ------------> | Image2DGL | <-----------------> | Kernel  | 
|_______________|    | [output] |      |_______________| 
           |_______________| 
Internal 
Format: GL_RGBA 
Format: GL_RGBA 
Type: ? 

는 그와 같은 질감을 초기화하고 있습니다 :

GLuint tex = 0; 

void initTexture(int width, int height) 
{ 
    glGenTextures(1, &tex); 
    glBindTexture(GL_TEXTURE_RECTANGLE, tex); 
// now here is where I need assistance: The type parameter of the Texture (GL_FLOAT) 
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL); 
} 


편집 : 나뿐만 아니라 GL_UNSIGNED_INT의 유형을 가질 수 있습니다. 내가 루프를 쓰고 있어요마다에서

ImageFormat format; 
format.image_channel_data_type = CL_UNORM_INT8; 
format.image_channel_order = CL_RGBA; 
srcImgBuffer = Image2D(clw->context, CL_MEM_READ_WRITE, format, width, height, 0, NULL, &err); 

렌더링 : 다음

texMems.push_back(Image2DGL(clw->context, CL_MEM_READ_WRITE, GL_TEXTURE_RECTANGLE, 0, tex, &err)); 

내가 원본 이미지 (입력 이미지) 생성 : 다음


나는 공유 이미지 (Image2DGL)를 작성 데이터를 srcImgBuffer :

// write the frame to the image buffer 
clw->queue.enqueueWriteImage(srcImgBuffer, CL_TRUE, origin, region, 0, 0, (void*)data, NULL, NULL); 

또한 나는 커널 인수를 설정 해요 : 내가 획득하고 GL 객체를 해제 할

tex_kernel.setArg(0, texMems[0]); 
tex_kernel.setArg(1, srcImgBuffer); 
tex_kernel.setArg(2, width); 
tex_kernel.setArg(3, height); 

전후. 테스트 커널은 다음과 같습니다

__kernel void init_texture_kernel(__write_only image2d_t out, __read_only image2d_t in, int w, int h) 
{ 
    const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; 

    int2 coords = { get_global_id(0), get_global_id(1) }; 
    float4 pixel = read_imagef(in, smp, coords); 
    float4 test = { (float)coords.x/(float)w , 0, 0, 1}; 
    write_imagef(out, coords, pixel); 
} 

image_channel_data_type 커널에서 float로서 읽을 수 및 정규화 된 값으로 해석됩니다. 출력 이미지가 옳지 않은 것처럼 보입니다. 잘못된 데이터 해석 때문에 슬라이스 된 그림 (줄무늬)이 있습니다. 앞서 언급 한 것처럼 오류는 텍스처 유형의 초기화 내에 있다고 가정합니다. GL_FLOAT 시도 (커널의 이미지에 float으로 쓰고 있음).

Results: Image as PPM dump from the decoder (left), Texture output scattered (right)

왼쪽 하나는 디코더의 밖으로 PPM이며, 오른쪽에 하나 내가 다시 내 출력 텍스처 얻고 것입니다.

누군가가 실제로 여기까지 읽은 경우 : 문제를 해결하기 위해 텍스처 유형에 대한 제안 사항이 있으십니까?


편집 : 내가 직접 텍스처로 캡처 한 프레임을 결합하면, 비디오가 확인한다. 그래서 CL-GL 인터페이스와 관련이 있어야합니다.


+0

Image2DGL에서 오류를 반환 했습니까? 직사각형 텍스처 대신 일반 2D 텍스처를 사용하면 어떻게됩니까? –

+0

아니요, Image2DGL에서 오류가 없습니다. 2D를 시도한 후에 텍스쳐 좌표를 정규화하고 랩뿐만 아니라 Mag/Min 필터를 설정했지만 출력이 전혀 없습니다. – rdoubleui

답변

1

나는 결국 명백한 표시되지 솔루션 함께했다. 나는 RGB 비디오를 가지고있다. 그러므로 RGB로 프레임을 캡쳐했습니다. 이것은 텍스처에 잘 표시 될 수 있습니다. 그러나, 한 번에 (커널 코드에서 볼 수 있듯이) 단지 3 개의 채널 만있는 버퍼에서 float4을 잡으면, 물론 엉망이 될 것입니다. 아하.

라인 수를보고 내 실수를했을 수도 있습니다. 나는 512 라인 중 384 라인을 요청했는데, 이것은 .75의 비율로 나타납니다.

나는 단순히 RGBA를 잡기 위해 내 grabber (libavcodec 사용)를 요구했고 그것은 4 채널 영상을 갖기 위해 그것을 채울 것입니다.

이 질문은 폐업 할 예정입니다.

2

나는 glTexture2D에 마지막 인수가 null의 경우, 포맷 형식 인수 할 수있는 유효한 OpenGL을 포맷/타입 있다고 생각 -하지만 그들은 사용되지 않고 아무것도에 영향을주지 않습니다.당신이 포인트 질감을 떠 가지고 싶다면, 당신은 올바른 internal_format 인수를 전달하여 지정해야합니다

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); 
+0

당신이 의미하는 바를 이해할 수 있습니다. 그러나 소스 데이터는 uint8 유형이고 텍스쳐에 대한 correspondig 유형을 찾고 있습니다. 8 비트 데이터 형식을 실제로 볼 수 없습니다. – rdoubleui

+0

처음에 텍스처를 한 번 초기화하지 않으면 어떤 출력도 볼 수 없으므로 필요한만큼 가져갑니다. 그러나 나는'GL_RGBA8' 또는'GL_RGBA32F'을 가질 수 있습니다. 나는 그것을 이해하지 못한다. – rdoubleui

+0

glTexImage2D의 7 번째와 8 번째 인수는 마지막 인수에서 어떤 형식 및 유형 데이터가 전달되는지 지정합니다. glTexImage2D에 데이터를 전달하지 않으면이 두 인수의 값이 아무런 영향을 미치지 않습니다. –