我在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(纹理),然后将该纹理绑定到屏幕上绘制。
以下是代码:
// "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();
代码无法正常工作,因为图像/纹理不仅是颠倒的,而且纹理映射也是错误的。它只在窗口全屏时才能正常工作,否则表现得非常奇怪。
见下图:
正如您所看到的,纹理在窗口内正确缩放,但它会与全屏窗口大小和实际窗口大小之间的差异成比例地“裁剪”。
我尝试过一切都没有成功。
由于这是我第一次使用OpenGL,我错过了什么?我变得疯了......
答案 0 :(得分: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();