Having issues with drawing to a frame buffer texture. It draws blank

I am in OpenGL es 2.0 with glKit trying to render to iOS devices.

Basically my goal is to instead of drawing to the main buffer draw to a texture. Then render that texture to the screen. I have been trying to follow another topic on it. Unfortunately they mention something about the power of two (im assuming with regards to resolution) but I don’t know how to fix it. Anyway here is my swift interpretation of the code from that topic.


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

Then as far as rendering I have some things going on.

A code that theoretically renders any texture full screen. This has been tested with two manually loaded pngs (using no buffer changes) and works great.

  func drawTriangle(texture: GLuint)
        {
            loadBuffers()

            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()
        }

I also have a function that draws a couple dots on the screen. You dont really need to see the methods but it works. This is how I am going to know that OpenGL is drawing from the buffer texture and NOT a preloaded texture.

Finally here is the gist of the code I am trying to do.

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

At the end of all this all that is drawn is a blank screen. If there is any more code that would help you figure things out let me know. I tried to trim it to make it less annoying for you.

Note: Considering the whole power of two thing I have tried passing the fbo class 512 x 512 just in case it would make things work being a power of two. Unfortunately it didnt do that.

Another Note: All I am doing is going to be 2D so I dont need depth buffers right?

Another Note: Something odd that the sample code I built this off of is doing is that when rendering the triangle it is calling both glActive Texture, and glBindTexture.

Another Note: For some reason some opengl es code says that you need to put OES after a lot of the frame-buffer calls. According to a lot of documentation, and the sample code I built this on it is not necessary. I also tried it in a way that was probably correct and it did not work.

Another Note: I am calling glGetErrors() every frame and it always prints “0”

Note that OpenGL ES 2.0 only requires support for 64x64 textures. But if you can create a 512x512 texture from a PNG file, there should be no problem using a 512x512 texture as a framebuffer attachment.

A depth buffer is optional. If you don’t have one, OpenGL will behave as if depth testing is disabled regardless of glEnable(GL_DEPTH_TEST).

Nothing odd about that. glActiveTexture() selects the active texture unit, glBindTexture() binds a texture to the active texture unit. If you never source data from more than one texture at a time, you can just leave texture unit 0 active (the initial state).

Such code may have been written for OpenGL ES 1.0, which would require the use of the OES_framebuffer_object extension. Framebuffer objects are part of core OpenGL ES 2.0.

Thankyou much for that! That makes lot of things narrowed down and will make it easier to figure out what is going on.

Are you saying that opengl es only allows 64 x 64 textures?

No. It only requires an implementation to support 64x64 textures. Implementations are free to support larger textures, and most will.

Oh ok. Finally after couple days of trying to get this to work I found it! It would appear that my texture wasn’t made right, probably a parameter thing. I tried writing into a texture unit made by glkit and it worked!