OpenGL ES рендерится в текстуру, затем рисует текстуру - PullRequest
7 голосов
/ 30 октября 2009

Я пытаюсь выполнить рендеринг в текстуру, а затем нарисовать эту текстуру на экране, используя OpenGL ES на iPhone. Я использую этот вопрос в качестве отправной точки и рисую в подклассе демонстрационной версии EAGLView от Apple.

Переменные экземпляра:

GLuint textureFrameBuffer;
Texture2D * texture;

Чтобы инициализировать буфер кадра и текстуру, я делаю это:

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

// initWithData results in a white image on the device (works fine in the simulator)
texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"blank320.png"]];

// create framebuffer
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

// attach renderbuffer
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0);

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    NSLog(@"incomplete");

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

Теперь, если я просто рисую свою сцену на экране, как обычно, она работает нормально:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw some triangles, complete with vertex normals
[contentDelegate draw];
[self swapBuffers];

Но, если я рендерину в 'textureFrameBuffer', а затем нарисую 'текстуру' на экране, полученное изображение будет перевернуто и "наизнанку". То есть, похоже, что нормали трехмерных объектов направлены внутрь, а не наружу - передняя грань каждого объекта прозрачна, и я вижу внутреннюю сторону задней грани. Вот код:

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw some polygons
[contentDelegate draw];

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, 1);
[texture drawInRect:CGRectMake(0, 0, 320, 480)];    
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

[self swapBuffers];

Я могу достаточно легко перевернуть изображение вверх-вправо, переставив координаты (glTexCoordPointer) соответствующим образом (в методе drawInRect в Texture2D), но это не решает проблему "наизнанку".

Я попытался заменить текстуру Texture2D на созданную вручную текстуру OpenGL, и результат был таким же. Рисование Texture2D, загруженного из PNG-изображения, работает нормально.

Что касается рисования объектов, в каждой вершине указана единица, нормальная, и GL_NORMALIZE включено.

glVertexPointer(3, GL_FLOAT, 0, myVerts);
glNormalPointer(GL_FLOAT, 0, myNormals);
glDrawArrays(GL_TRIANGLES, 0, numVerts);

Все хорошо отрисовывается, когда отображается на экране; GL_DEPTH_TEST включен и отлично работает.

Есть предложения, как это исправить? Спасибо!

1 Ответ

3 голосов
/ 31 октября 2009

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

Убедитесь, что у вас есть буфер глубины, прикрепленный к вашему внеэкранному FBO. В вашем коде инициализации вы можете добавить следующий фрагмент сразу после glBindFramebufferOES (...) .

// attach depth buffer
GLuint depthRenderbuffer;
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
...