2012-09-14 121 views
2

我有一個852x640的渲染緩衝區和1280x720的紋理。當我渲染紋理時,它會被裁剪,而不是被拉伸。我知道寬高比需要更正,但是我怎樣才能得到它,以便在渲染緩衝區中顯示完整的紋理?渲染大紋理到更小的渲染緩衝區

//------------------------------------- 
    glGenFramebuffers(1, &frameBufferHandle); 
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle); 

    glGenRenderbuffers(1, &renderBufferHandle); 
    glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle); 

    [oglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; 

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderBufferWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderBufferHeight); 

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBufferHandle); 
//------------------------------------- 


static const GLfloat squareVertices[] = { 
    -1.0f, 1.0f, 
    1.0f, 1.0f, 
    -1.0f, -1.0f, 
    1.0f, -1.0f 
}; 

static const GLfloat horizontalFlipTextureCoordinates[] = { 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
}; 

size_t frameWidth = CVPixelBufferGetWidth(pixelBuffer); 
size_t frameHeight = CVPixelBufferGetHeight(pixelBuffer); 

CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                  videoTextureCache, 
                  pixelBuffer, 
                  NULL, 
                  GL_TEXTURE_2D, 
                  GL_RGBA, 
                  frameWidth, 
                  frameHeight, 
                  GL_BGRA, 
                  GL_UNSIGNED_BYTE, 
                  0, 
                  &texture); 


if (!texture || err) { 
    NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err); 
    return; 
} 

glBindTexture(CVOpenGLESTextureGetTarget(texture), CVOpenGLESTextureGetName(texture)); 

glViewport(0, 0, renderBufferWidth, renderBufferHeight); // setting this to 1280x720 fixes the aspect ratio but still crops 

glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle); 

glUseProgram(shaderPrograms[PASSTHROUGH]); 

// Update attribute values. 
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, horizontalFlipTextureCoordinates); 
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Present 
glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle); 
[oglContext presentRenderbuffer:GL_RENDERBUFFER]; 

編輯

我仍然在運行到的問題。我已經包括更多的來源。基本上,我需要將整個原始輸入紋理以寬屏幕形式顯示,同時將原始紋理寫入磁盤。

當渲染到較小的紋理時,事物會自動縮放,這與渲染緩衝區不同嗎?

我想我可以做一個更小的紋理通道,但這會減慢速度。

+2

您將希望將視口尺寸與幀緩衝區的尺寸匹配,而不是使用您的輸入紋理尺寸。 –

+0

@BradLarson進行了更新。 (renderBufferWidth,renderBufferHeight)不是我的幀緩衝區的尺寸? – Dex

+0

不應該在「CVOpenGLESTextureCacheCreateTextureFromImage」中傳遞IMAGE尺寸而不是像素緩衝尺寸的寬度和高度? –

回答

0

哦,男孩,所以答案是,這是一直工作;)事實證明,iPhone 4上的高分辨率預設模式實際上覆蓋的面積比中等分辨率預設更少。這讓我陷入了一個循環,直到Brigadir提出我應該首先完成的事情,檢查GPU快照。

我想通過在GPUImage框架中篡改適當的代碼來計算寬高比問題。 https://github.com/bradLarson/GPUImage

1

首先,保留glViewport(0, 0, renderBufferWidth, renderBufferHeight);852x640。 問題出在你的squareVertices - 看起來像它保持代表紋理大小的座標。您需要將其設置爲等於渲染緩衝區大小。

這個想法是紋理被映射在你的squareVertices矩形上。所以你可以渲染任何尺寸的紋理映射到任何尺寸的矩形 - 紋理圖像將被縮放以適合矩形。

[更新:多頂點]

你的情況應該是:

{ 
0.0f, (float)renderBufferWidth/frameHeight, 
(float)renderBufferWidth/frameWidth, (float)renderBufferHeight/frameHeight, 
0.0f, 0.0f, 
(float)renderBufferWidth/frameWidth, 0.0f, 
}; 

但是,這並不常見很好的解決方案。從理論上講,屏幕上的矩形大小由頂點位置和變換矩陣決定。在屏幕上呈現之前,每個頂點與矩陣相乘。看起來你不設置OpenGL projection matrix。使用正確的正交投影,您的頂點應具有像素等價位置。

+0

您可以請發佈squareVertices應該是什麼? – Dex

+0

我用你的方形頂點,但它仍然無法正常工作。我在右下角有一個小廣場,上面有我看到的同樣的裁剪圖像。 – Dex

+1

在這種情況下,很難提出任何建議。您可以在'XCode OpenGL Frame Capture'工具(如果您有新的iPad/iPhone/iPod)渲染期間查看頂點數據 - 特別是在頂點後變換座標和變換矩陣。 – brigadir

0

因爲我是OpenGL的新手,記得要映射的紋理應該是2的2的冪。 對於例如圖像分辨率應該是... 256x256,512x512。 然後,您可以使用 gl.glScalef(x,y,z)來縮放圖像;根據您的要求相應地發揮作用。 相應地獲取高度和寬度,並將它們放在scalef函數中。 試試這個,我希望這可以工作。

+0

有許多方法可以創建非2的紋理,但在任何情況下,函數「CVOpenGLESTextureCacheCreateTextureFromImage」都應該處理以創建紋理。在這兩種情況下(2的冪或不是2),你只能使用區間[0,1]上的相對位置,縮放矩陣與裁剪或任何東西無關。例如,如果您傳遞glOrtho(0,1,0,1 ...),並且紋理圖像具有與屏幕相同的縱橫比,則不需要縮放矩陣以正確顯示該圖像。 –

0

試試這些功能。我的回答可以從信息進行驗證@songhoa.ca.com

glGenFramebuffers() 
  • 無效glGenFramebuffers(GLsizei N,GLuint * IDS)

    • 數幀緩衝區的建立
  • void glDeleteFramebuffers(GLsizei n,const GLuint * ids)

    • 指向GLuint變量的指針或存儲若干ID的數組。它返回未使用的幀緩衝區對象的ID。ID 0表示默認幀緩衝區,它是窗口系統提供的幀緩衝區。

FBO可以通過調用glDeleteFramebuffers()時不再使用它刪除。

glBindFramebuffer() 

一旦FBO被創建,其具有在使用之前被綁定。

  • 空隙glBindFramebuffer(GLenum目標,GLuint ID)

    • 第一個參數是目標應該是GL_FRAMEBUFFER。

    • 第二個參數是幀緩衝區對象的ID。

一旦FBO綁定,所有的OpenGL操作影響到當前綁定的幀緩衝區對象。對象ID 0保留給默認的窗口系統提供的幀緩衝區。因此,要解除綁定當前幀緩衝區(FBO),請使用glBindFramebuffer()中的ID 0。


嘗試使用這些,或者至少visit the link它可以幫助你很多。對不起,我沒有OpenGL的經驗,但我想貢獻鏈接,並解釋2個函數。我認爲你可以使用這些信息來編寫你的代碼。