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 を使用するのはこれが初めてなので、何か不足していますか? 気が狂いそう..