1

私は Siphon フレームワークを使用して、ビデオのフレームをサーバーからクライアント アプリケーションにプッシュしようとしています。

Siphon では、通常の画像の代わりに OpenGL テクスチャを使用する必要があります。

このため、CGImageRef をテクスチャとしてレンダリングし、送信して公開しようとしています。

私はCGLコンテキストを次のように作成しています:

CGLPixelFormatAttribute attribs[13] = {
    kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core, // This sets the context to 3.2
    kCGLPFAColorSize,     (CGLPixelFormatAttribute)24,
    kCGLPFAAlphaSize,     (CGLPixelFormatAttribute)8,
    kCGLPFAAccelerated,
    kCGLPFADoubleBuffer,
    kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1,
    kCGLPFASamples,       (CGLPixelFormatAttribute)4,
    (CGLPixelFormatAttribute)0
};

CGLPixelFormatObj pix;
GLint npix;
CGLChoosePixelFormat(attribs, &pix, &npix);

CGLCreateContext(pix, 0, &_ctx);

NSImageとして適切にレンダリングできることがわかっているCGImageRefをすでに持っています。

私はテクスチャを次のようにレンダリングしています:

CGLLockContext(cgl_ctx);

if (_texture) {
    glDeleteTextures(1, &_texture);
}

int width = 1920;
int height = 1080;

GLubyte* imageData = malloc(width * height * 4);
CGContextRef imageContext = CGBitmapContextCreate(imageData, width, height, 8, width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, width, height), image);
CGContextRelease(imageContext);

GLuint frameBuffer;
GLenum status;

glGenFramebuffersEXT(1, &frameBuffer);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_TEXTURE_2D, imageData);

status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    NSLog(@"OpenGL Error");
}

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

CGLUnlockContext(cgl_ctx);

レンダリング コードは別のクラスにありますが、コンテキストは通過する必要があり、同じです。

この問題の他のほとんどすべてのインスタンスでアドバイスを試しましたが、役に立ちませんでした。

4

2 に答える 2

1

このコードにはいくつかの問題があります。以下は、物事を機能させるために重要です。

  • @orost による以前の回答でも指摘されているように、呼び出しのパラメーターglTexImage2D()は無効です。そのはず:

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    
  • テクスチャが FBO ターゲットとしてアタッチされることはありません。FBO を設定する際には、次のものが必要です。

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, _texture, 0);
    

おそらく実行を妨げないいくつかの項目がありますが、とにかくそれらを変更することをお勧めします。

  • レンダリングしてコンテンツを作成する場合は、テクスチャのデータを指定する必要はありません。glTexImage2D()とにかく、渡すデータは初期化されていないため、あまり効果がありません。上記の呼び出しで既に行ったように、データ引数NULLとして渡す方がはるかにクリーンです。
  • EXTOpenGL 3.2 を使用しているため、FBO エントリ ポイントの形式を使用する必要はまったくありません。これは、OpenGL 3.x の標準機能です。このEXTフォームは、一貫して使用している限り機能する可能性がありますが、標準のエントリ ポイントと組み合わせると、予想外の事態が発生するリスクがあります。
于 2015-06-10T02:18:29.243 に答える