Mac OS XアプリケーションでOpenGLを使用して、NSOpenGLView
にテクスチャを描画しています。FBO:レンダリングされたテクスチャを描画するときに、テクスチャをレンダリングするときに間違ったテクスチャマッピング
アプリはムービープレーヤーです。ムービーフレームを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を使用しているため、何か不足していますか?私はクレイジーになってきています。..
悪いOh..my ...あなたの答えをありがとうございました。 ウィンドウのサイズ変更時にのみビューポートと投影を設定していました。私は、FBOとバックバッファの2つの異なるビューポートと投影を指定する必要があることを認識しませんでした。これはテクスチャマッピングの問題を解決しますが、(明らかに)テクスチャはまだ上下逆さまです。私は 'glTexCoord2f'と' glVertex2f'の関連を変更することができますが、なぜそれを修正する必要があるのでしょうか?バックバッファに直接描画すると、テクスチャは正しく向きが変わります。FBOに描画するときに何かを変更する必要がありますか? – Andrea3000
@ Andrea3000:あなたはそれを逆さまに描いているので、まあ、反転しています。画像の原点は、左下であり、右上ではなく、あなたが想定しているようです。ビューポートと投影の設定については、OpenGLの初心者に伝えていることは約80%です。ウィンドウのサイズ変更ハンドラではなく、描画関数で設定してください。 FBOを使用するとき、またはHUDなどを描画するときに問題になるので、ウィンドウのサイズ変更ハンドラはこのための悪い場所です。すべてのOpenGL操作(静的データアップロードを除く)は、描画関数に属します。 – datenwolf
OpenGLに関するご意見ありがとうございます、私はそれらを念頭に置いておきます;-)フリップされた画像について:FBOとバックバッファは異なる座標系を持っていますか?バックバッファに描画され、FBOに描画されたときに反転され、バックバッファに描画されたときに、イメージがどのように正しくなるか理解できないので、私はあなたに尋ねます。 'glTexCoord2f'と' glVertex2f'はどちらの場合も同じです。 – Andrea3000