2

我在 Mac OS X 应用程序上使用 OpengGL 在NSOpenGLView.

该应用程序是一个电影播放器​​。它将电影帧解码为CVOpenGLTextureRef(这是 OpenGL 纹理),我使用GL_QUAD. 一切正常。

以下是代码的相关部分。

// "image" is the CVOpenGLTextureRef containing the movie frame as texture
GLenum textureTarget = CVOpenGLTextureGetTarget(image);
GLuint textureName = CVOpenGLTextureGetName(image);

glEnable(textureTarget);
glBindTexture(textureTarget, textureName); 

glBegin(GL_QUADS);
// Draw the quads
//Note: textureTagret is NOT GL_TEXTURE_2D, therefore texture coordinates
//are NOT scaled to [0, 1] 

glTexCoord2f(0.0f, imageRect.size.height);
glVertex2f (0.0f, 0.0f);

glTexCoord2f(0.0f, 0.0f); 
glVertex2f (0.0f, windowRect.size.height); 

glTexCoord2f(imageRect.size.width, 0.0f);
glVertex2f (windowRect.size.width, windowRect.size.height);

glTexCoord2f(imageRect.size.width, imageRect.size.height);
glVertex2f (windowRect.size.width,0.0f); 

glEnd();
glDisable(textureTarget);
glFlush();

它工作得很好,我可以调整窗口大小,并且纹理正确映射到较小的窗口。

请参阅此处了解从全屏到 500x280 像素的不同窗口大小: 没有 FBO

我现在想使用 FBO 渲染到纹理,我开始制作一个非常简单的实现,其中包括将电影帧渲染到屏幕外的 FBO(纹理),然后将该纹理绑定到屏幕上绘制。

这是代码:

// "image" is the CVOpenGLTextureRef containing the movie frame as texture
GLenum textureTarget = CVOpenGLTextureGetTarget(image);
GLuint textureName = CVOpenGLTextureGetName(image);

////////////////////////////////////////////////////////////////////
// the creation on the FBO is done only once on program start:

GLuint fboId;
GLuint textureId;
float targetWidth = 2048;
float targetHeight = 2048;

// create a texture object
glGenTextures(1, &textureId);
glBindTexture(textureTarget, textureId);
glTexParameterf(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(textureTarget, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap
glTexImage2D(textureTarget, 0, GL_RGBA8, targetWidth, targetHeight, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(textureTarget, 0);

// create a framebuffer object
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

// attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                           textureTarget, textureId, 0);

// check FBO status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
    return FALSE;

// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
///////////////////////////////////////////////////////////////////////////////

// Render to texture

glEnable(textureTarget);
glBindTexture(textureTarget, textureName);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glClear(GL_COLOR_BUFFER_BIT);   

glBegin(GL_QUADS);
// Draw the quads

glTexCoord2f(0.0f, imageRect.size.height);
glVertex2f (0.0f, 0.0f);        

glTexCoord2f(0.0f, 0.0f); 
glVertex2f (0.0f,imageRect.size.height);

glTexCoord2f(imageRect.size.width, 0.0f);
glVertex2f (imageRect.size.width, imageRect.size.height);

glTexCoord2f(imageRect.size.width, imageRect.size.height);
glVertex2f (imageRect.size.width,0.0f);

glEnd();
glFlush();

// Bind newly rendered texture
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(textureTarget, textureId);
glGenerateMipmapEXT(textureTarget);

// draw on-screen
glBegin(GL_QUADS);
// Draw the quads
//Note: textureTagret is NOT GL_TEXTURE_2D, therefore texture coordinates
//are NOT scaled to [0, 1] 

glTexCoord2f(0.0f, imageRect.size.height);
glVertex2f (0.0f, 0.0f);

glTexCoord2f(0.0f, 0.0f); 
glVertex2f (0.0f, windowRect.size.height); 

glTexCoord2f(imageRect.size.width, 0.0f);
glVertex2f (windowRect.size.width, windowRect.size.height);

glTexCoord2f(imageRect.size.width, imageRect.size.height);
glVertex2f (windowRect.size.width,0.0f); 

glEnd();
glDisable(textureTarget);
glFlush();

代码不能正常工作,因为图像/纹理不仅是颠倒的,而且纹理映射也是错误的。只有当窗口全屏时它才能正常工作,否则它的行为真的很奇怪。

见下图: 与 FBO

如您所见,纹理在窗口内正确缩放,但它会根据全屏窗口大小和实际窗口大小之间的差异按比例“裁剪”。

我已经尝试了一切都没有成功。

由于这是我第一次使用 OpenGL,我是否遗漏了什么?我要疯了。。

4

1 回答 1

2
// Render to texture

glEnable(textureTarget);
glBindTexture(textureTarget, textureName);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glClear(GL_COLOR_BUFFER_BIT);   

我错过了在这里设置帧缓冲区对象的视口和投影。

glBegin(GL_QUADS);
// Draw the quads

glTexCoord2f(0.0f, imageRect.size.height);
g    lVertex2f (0.0f, 0.0f);        

glTexCoord2f(0.0f, 0.0f); 
glVertex2f (0.0f,imageRect.size.height);

glTexCoord2f(imageRect.size.width, 0.0f);
glVertex2f (imageRect.size.width, imageRect.size.height);

glTexCoord2f(imageRect.size.width, imageRect.size.height);
glVertex2f (imageRect.size.width,0.0f);

glEnd();
glFlush();
于 2012-02-06T13:51:44.463 回答