2015-12-18 2 views
1

Я нахожусь в OpenGL es 2.0 с glKit, пытающимся отобразить на устройствах iOS.Проблемы с рисованием в текстуру буфера кадра. Он рисует пустой

В основном моя цель заключается в том, чтобы вместо рисования рисовать основной буфер на текстуру. Затем визуализируйте эту текстуру на экране. Я пытался следовать another topic on so. К сожалению, они упоминают что-то о силе двух (они предполагают, что касается разрешения), но я не знаю, как это исправить. В любом случае, это моя быстрая интерпретация кода из этой темы.

import Foundation 
import GLKit 
import OpenGLES 

class RenderTexture { 
    var framebuffer:GLuint = 0 
    var tex:GLuint = 0 
    var old_fbo:GLint = 0 

    init(width: GLsizei, height: GLsizei) 
    { 
     glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING), &old_fbo) 

     glGenFramebuffers(1, &framebuffer) 
     glGenTextures(1, &tex) 

     glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer) 
     glBindTexture(GLenum(GL_TEXTURE_2D), tex) 
     glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), nil) 
     glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex, 0) 

     glClearColor(0, 0.1, 0, 1) 
     glClear(GLenum(GL_COLOR_BUFFER_BIT)) 

     let status = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER)) 
     if (status != GLenum(GL_FRAMEBUFFER_COMPLETE)) 
     { 
      print("DIDNT GO WELL WITH", width, " " , height) 
      print(status) 
     } 

     glBindFramebuffer(GLenum(GL_FRAMEBUFFER), GLenum(old_fbo)) 
    } 

    func begin() 
    { 
     glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING), &old_fbo) 
     glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer) 
    } 

    func end() 
    { 
     glBindFramebuffer(GLenum(GL_FRAMEBUFFER), GLenum(old_fbo)) 
    } 
} 

Тогда, что касается рендеринга, у меня кое-что происходит.

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

func drawTriangle(texture: GLuint) 
    { 
     loadBuffers() 
     //glViewport(0, 0, width, height) 
     //glClearColor(0, 0.0, 0, 1.0) 
     //glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT)) 


     glEnable(GLenum(GL_TEXTURE_2D)) 
     glActiveTexture(GLenum(GL_TEXTURE0)) 

     glUseProgram(texShader) 
     let loc1 = glGetUniformLocation(texShader, "s_texture") 
     glUniform1i(loc1, 0) 


     let loc3 = glGetUniformLocation(texShader, "matrix") 
     if (loc3 != -1) 
     { 
      glUniformMatrix4fv(loc3, 1, GLboolean(GL_FALSE), &matrix) 
     } 

     glBindTexture(GLenum(GL_TEXTURE_2D), texture) 
     glDrawArrays(GLenum(GL_TRIANGLE_STRIP), 0, 6) 
     glDisable(GLenum(GL_TEXTURE_2D)) 

     destroyBuffers() 
    } 

У меня также есть функция, которая рисует пару точек на экране. Вам действительно не нужно видеть методы, но это работает. Вот как я узнаю, что OpenGL рисует из текстуры буфера и НЕ предварительно загруженную текстуру.

Наконец, вот суть кода, который я пытаюсь сделать.

func initialize() 
{ 
     nfbo = RenderTexture(width: width, height: height) 
} 

fun draw() 
{ 
     glViewport(0, 0, GLsizei(width * 2), GLsizei(height * 2)) //why do I have to multiply for 2 to get it to work????? 
     nfbo.begin() 
     drawDots() //Draws the dots 
     nfbo.end() 
     reset() 
     drawTriangle(nfbo.tex) 
} 

В конце всего этого все, что нарисовано, является пустым экраном. Если есть еще какой-нибудь код, который поможет вам разобраться в этом, дайте мне знать. Я попытался обрезать его, чтобы сделать его менее раздражающим для вас.

Примечание: Учитывая всю силу двух вещей, я пробовал передать класс fbo 512 x 512 на всякий случай, если бы это работало, будучи силой двух. К сожалению, он этого не сделал.

Другое примечание: все, что я делаю, будет 2D, поэтому мне не нужны буферы глубины?

+0

Почему не просто отлаживать его, принимая считанных пикселей, а также проверить, если какой-либо ошибки гл. –

+0

@ Ta-Zvi, какие функции проверяют на ошибки gl? И как мне тогда интерпретировать. –

+0

Также я не могу заставить функцию glReadPixels работать –

ответ

2

вчера я увидел точно такую ​​же проблему.

после долгих часов работы, я узнал, почему.

трюк настройке текстурной карты со следующим:

glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE); 
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE); 

иначе, вы не будете ничего на карте текстуры рисовать.

Причина заключается в том, что в то время как ios поддерживает карты текстур, которые не обладают мощностью 2. для этого требуется GL_CLAMP_TO_EDGE. иначе это не сработает.

он должен действительно сообщить о неполном фреймбуфере. мне потребовалось довольно много времени, чтобы отладить эту проблему!

здесь родственном обсуждения:

Rendering to non-power-of-two texture on iPhone

Смежные вопросы