绘制到帧缓冲区纹理时遇到问题。它画空白

时间:2015-12-18 05:26:46

标签: swift opengl-es glkit

我在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,所以我不需要深度缓冲吗?

1 个答案:

答案 0 :(得分:3)

昨天我看到了完全相同的问题。

经过几个小时的努力,我发现了原因。

诀窍是使用以下内容配置纹理贴图:

    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