2015-02-11 89 views
0

我一直在努力從OpenGL獲取屏幕截圖,然後在屏幕上渲染相同的圖像。爲此我創建了兩個幀緩衝區。 1用於渲染(ratinaFramebuffer)和1用於使用蘋果紋理緩存繪圖(textureFramebuffer)。同時使用下面的代碼創建(變量名稱除外)。紋理緩存沒有渲染到iOS中的幀緩衝區對象

glGenFramebuffers(1, &ratinaFramebuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, ratinaFramebuffer); 

glGenRenderbuffers(1, &ratinaColorRenderbuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, ratinaColorRenderbuffer); 
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer]; 

glGenRenderbuffers(1, &ratinaDepthRenderbuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, ratinaDepthRenderbuffer); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ratinaDepthRenderbuffer); 

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ; 
if(status != GL_FRAMEBUFFER_COMPLETE) 
{ 
    NSLog(@"failed to make complete framebuffer object %x", status); 
} 

這裏是我的渲染代碼看起來像

glBindTexture(GL_TEXTURE_2D, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

// Clear content 
glBindFramebuffer(GL_FRAMEBUFFER, ratinaFramebuffer); 
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 

glBindFramebuffer(GL_FRAMEBUFFER, textureFramebuffer); 
glViewport(0, 0, self.frame.size.width, self.frame.size.height); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

// Start drawing 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_BLEND); 

static int nColor = 104; 


glClearColor(0, (++nColor & 0xff)/255.0, 55.0/255.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glEnable(GL_DEPTH_TEST); 

CC3GLMatrix *projection = [CC3GLMatrix matrix]; 
float h = 4.0f * self.frame.size.height/self.frame.size.width; 
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10]; 
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); 

CC3GLMatrix *modelView = [CC3GLMatrix matrix]; 
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)]; 
_currentRotation += displayLink.duration * 90; 
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)]; 
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix); 

// 1 
glViewport(0, 0, self.frame.size.width, self.frame.size.height); 

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 

// 2 
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 

glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, _floorTexture); 
glUniform1i(_textureUniform, 0); 

// 3 
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); 

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer2); 

glActiveTexture(GL_TEXTURE0); // unneccc in practice 
glBindTexture(GL_TEXTURE_2D, _fishTexture); 
glUniform1i(_textureUniform, 0); // unnecc in practice 

glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix); 

glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 

glDrawElements(GL_TRIANGLE_STRIP, sizeof(Indices2)/sizeof(Indices2[0]), GL_UNSIGNED_BYTE, 0); 


// Get the image 
CGImageRef cgImage = NULL; 
UIImage *screenImageimage = nil; 
OSStatus res = CreateCGImageFromCVPixelBuffer(renderTarget,&cgImage); 
if (res == noErr) 
{ 
    screenImageimage = [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationUp]; 

} 

在這一點上,圖像是完全被拉入質感。但是當我嘗試以使其在屏幕上,同樣的質地,它是沒有得到拉:(。它顯示了藍色,我在鮮明的色彩,但沒有別的都給予。

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ratinaFramebuffer); 
glBindTexture(GL_TEXTURE_2D, 0); 
glClearColor(0, 255/255.0, 255/255.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glEnable(GL_DEPTH_TEST); 

glViewport(0, 0, self.frame.size.width, self.frame.size.height); 


glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, renderTexture); 


// Display the buffer 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, ratinaColorRenderbuffer); 
[_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
+0

所以,你綁定並繪製到紋理幀緩衝區,並從它得到的圖像似乎工作,但然後你切換到視圖綁定的名望緩衝區,清除它,並呈現給視圖,似乎然後再按預期工作。你真的在哪裏繪製紋理視圖綁定幀緩衝區(ratinaFramebuffer)?簡單地綁定紋理會將所需的紋理設置爲之前設置的活動紋理,但不會將其繪製到任何位置。要繪製它,您將需要與繪製任何其他紋理相同的過程。 – 2015-02-11 17:43:03

+0

感謝您的回答Matic Oblak,我添加了下面的代碼glVertexPointer(3,GL_FLOAT,0,頂點); glTexCoordPointer(2,GL_FLOAT,0,coordinates); glDrawArrays(GL_TRIANGLE_STRIP,0,4); 它顯示了質感,謝謝。但問題是,它是在動畫框中顯示的,而不是完整的屏幕,我怎麼做,請建議 – 2015-02-12 07:18:33

回答

0

問題得到解決,如我是新來的OpenGL和我沒有繪製畫面的幀緩衝,我做到了在屏幕上調用render使用下面的代碼。只是發表如果有人需要看,在beginer水平

GLfloat  coordinates[] = { 0, 1, 
           1, 1, 
           0, 0, 
           1, 0 }; 

GLfloat  width = self.frame.size.width, 
      height = self.frame.size.height; 

GLfloat  vertices[] = { -width/2 + point.x, -height/2 + point.y, 0.0, 
          width/2 + point.x, -height/2 + point.y, 0.0, 
          -width/2 + point.x, height/2 + point.y, 0.0, 
          width/2 + point.x, height/2 + point.y, 0.0 }; 

glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture)); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

glVertexPointer(3, GL_FLOAT, 0, vertices); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

雖然,這顯示紋理,但在一個小框中繪製在另一個幀緩衝區中,儘管頂點和共同點都是完整的屏幕,但並沒有繪製完成屏幕。如果我找到了,將會編輯這個。

1

當你繪製到單獨的幀緩衝區時,你可以附加一個紋理到最後你可以有意識地繪製到紋理本身。完成此繪圖後,您可以像使用其他繪圖一樣將紋理繪製到主屏幕緩衝區中。

有這樣做的時候,你應該檢查幾點:

  • 切換
  • 您必須根據綁定的幀緩衝區設置視當切換
  • 時不要忘記重新綁定幀緩衝區
  • 可能您可能需要清除緩衝區
  • 可能紋理僅在緩衝區的一部分上繪製,例如在1024x1024紋理上繪製600x600屏幕。在這種情況下,您需要生成範圍[0,600/1024]中的頂點座標以繪製正確的部分。這可以通過比較來自紋理邊界幀緩衝區的視口值和紋理大小來檢查。

很難說你現在失去了什麼,但現在最好的辦法是檢查視口。除此之外,如果您只是繪製全屏幕紋理,則不需要將主緩衝區複雜化。您可以禁用該矩陣,並簡單地使用默認的[-1,1]座標系。

相關問題