簡體   English   中英

OpenGL紋理呈現為黑色

[英]OpenGL Texture rendering as black

我正在使用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);

我已經有一個CGImageRef,我知道它可以正確地渲染為NSImage。

我這樣渲染紋理:

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);

呈現代碼在不同的類中,但是上下文應通過且相同。

對於這個問題,我幾乎在其他所有情況下都嘗試過該建議,但無濟於事。

glTexImage2D的倒數第二個參數是:

類型
指定像素數據的數據類型。 以下符號值被接受: GL_UNSIGNED_BYTEGL_BYTEGL_UNSIGNED_SHORTGL_SHORTGL_UNSIGNED_INTGL_INTGL_FLOATGL_UNSIGNED_BYTE_3_3_2GL_UNSIGNED_BYTE_2_3_3_REVGL_UNSIGNED_SHORT_5_6_5GL_UNSIGNED_SHORT_5_6_5_REVGL_UNSIGNED_SHORT_4_4_4_4GL_UNSIGNED_SHORT_4_4_4_4_REVGL_UNSIGNED_SHORT_5_5_5_1GL_UNSIGNED_SHORT_1_5_5_5_REVGL_UNSIGNED_INT_8_8_8_8GL_UNSIGNED_INT_8_8_8_8_REVGL_UNSIGNED_INT_10_10_10_2 ,和GL_UNSIGNED_INT_2_10_10_10_REV

GL_TEXTURE_2D在那里沒有意義,應該與imageData元素的數據類型imageData

您還應該使用glGetErrorARB_debug_output檢查OpenGL錯誤。 您將立即看到出現了什么問題:

Source:OpenGL   Type:Error  ID:5    Severity:High   Message:GL_INVALID_ENUM in glTexImage2D(incompatible format = GL_RGBA, type = GL_TEXTURE_2D)

此代碼中存在一些問題。 以下是使事情正常運行的關鍵:

  • 正如@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作為數據參數要干凈得多,就像我在上面顯示的調用中所做的那樣。
  • 由於您使用的是OpenGL 3.2,因此實際上不需要使用FBO入口點的EXT形式。 這是OpenGL 3.x中的標准功能。 只要您始終使用EXT表單,它就可能起作用。但是,如果將EXT表單與標准入口點混合使用,則可能會帶來難以置信的驚喜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM