Кэш текстуры не рендерится в буфер кадра Object в iOS

Я работал над получением скриншота из OpenGL и затем рендеринг того же на экране. Для этого я создал два кадровых буфера. 1 для рендеринга (ratinaFramebuffer) и 1 для использования рисования кэша текстур Apple (textureFramebuffer). Создано с использованием приведенного ниже кода (кроме имен переменных).

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];

2 ответа

Когда вы рисуете в отдельный буфер кадра, вы можете прикрепить к нему текстуру, где в конце вы можете эффективно нарисовать текстуру. После того, как этот рисунок завершен, вы можете использовать текстуру так же, как и любую другую, включая рисование в основном экранном буфере.

Есть несколько моментов, которые вы должны проверить при этом:

  • Не забудьте перепрограммировать буфер кадров при переключении
  • Вы должны установить область просмотра в соответствии с буфером связанных кадров при переключении
  • Возможно, вам может понадобиться очистить буфер
  • Возможно, текстура рисуется только на части буфера, например, рисует экран 600x600 на текстуре 1024x1024. В этом случае вам нужно сгенерировать координаты вершины в диапазоне [0, 600/1024], чтобы нарисовать правильную ее часть. Это можно проверить, сравнив значения области просмотра из буфера рамки с текстурой и размером текстуры.

Трудно сказать, чего вам не хватает сейчас, но лучший способ на данный момент - проверить окно просмотра. Кроме того, вам не нужно усложнять основной буфер, если вы просто рисуете полноэкранную текстуру. Вы можете отключить матрицу и просто использовать систему координат [-1,1], которая используется по умолчанию.

Проблема решена, так как я был новичком в openGL, и я не рисовал кадровый буфер экрана, что я и сделал, используя приведенный ниже код при рендеринге при вызове экрана. Просто отправлять сообщения, если кому-то нужно взглянуть на это на начальном уровне

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);

Хотя, это показывает текстуру, но в маленькой рамке, которая нарисована в другом буфере кадра. Он не рисует на весь экран, хотя вершины и координаты имеют полный экран. Глядя на это, будет редактировать это, если я нашел.

Другие вопросы по тегам