FBO: Отрисовка в текстуру, неверное отображение текстуры при рисовании отрисованной текстуры
Я использую OpengGL в приложении Mac OS X для рисования текстуры на 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, я что-то упускаю? Я начинаю сходить с ума..
1 ответ:
// 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();
Comments