使用FBO创建透明PNG会创建一个空图像

时间:2014-03-13 17:54:03

标签: java opengl lwjgl

我正在制作一个Minecraft mod,我正在尝试将块的所有图标渲染为透明的PNG图像。这是我第一次使用OpenGL而我无法找到我遇到的问题:输出只是一个透明的PNG图像,里面没有任何内容。

请注意,Minecraft也适用于帧缓冲。

一开始,这段代码会创建帧缓冲区,深度缓冲区和纹理。

        // Clear some buffers
        glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Create and bind framebuffer
        int fbo = glGenFramebuffersEXT();
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

        // Create and bind depthbuffer
        int drb = glGenRenderbuffersEXT();
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size, size);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);

        // Create and bind texture
        int tex = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, tex);

        // Specify a texture image
        glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, size, size, 0,GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);

        // Bind texture to framebuffer
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);

此部分呈现块或项目...... (请注意,在Minecraft Framebuffer中渲染时,此部件渲染效果很好)

        // Render a Minecraft block or item
        // Commented out code is used for lighting and size
        glLoadIdentity();
        glEnable(GL12.GL_RESCALE_NORMAL);
        //RenderHelper.enableGUIStandardItemLighting();
        //glScalef(10F, 10F, 10F);
        itemRenderer.renderItemIntoGUI(mc.fontRenderer, mc.getTextureManager(), is, 0, 0);
        //glScalef(0.1F, 0.1F, 0.1F);
        //RenderHelper.disableStandardItemLighting();
        glDisable(GL12.GL_RESCALE_NORMAL);

        /* Draw a rectangle - Testing purposes
        glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3f(0, 0, 0);
        glVertex3f(1, 0, 0);
        glVertex3f(0, 1, 0);
        glEnd();
        */

        // Unbind framebuffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

最后使用先前创建的纹理创建图像... 最后一部分是Minecraft ScreenshotHelper类的重编辑版本。

        // Based on the minecraft screenshot-helper
        int k = size * size;

        if (pixelBuffer == null || pixelBuffer.capacity() < k)
        {
            pixelBuffer = BufferUtils.createIntBuffer(k);
            pixelValues = new int[k];
        }

        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        pixelBuffer.clear();

        glBindTexture(GL_TEXTURE_2D, tex);
        glGetTexImage(GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);

        pixelBuffer.get(pixelValues);
        TextureUtil.func_147953_a(pixelValues, size, size);
        BufferedImage bufferedimage = null;

        bufferedimage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);

        for (int i1 = 0; i1 < size; ++i1)
        {
            for (int j1 = 0; j1 < size; ++j1)
            {
                bufferedimage.setRGB(j1, i1, pixelValues[i1 * size + j1]);
            }
        }

        // Create directory and finally the png file
        File file = new File(mc.mcDataDir, "renders");
        file.mkdir();
        try {
            ImageIO.write(bufferedimage, "png", new File(file, GameData.itemRegistry.getNameForObject(is.getItem()).replace(":", "_").concat(".png")));
        } catch (IOException e) {
            e.printStackTrace();
        }

图像创建得很好,但没有任何内容!它只是一个透明的500x500 PNG图像。

修改1 使用glGetError函数,我发现在绑定fbo后它返回GL_INVALID_ENUM并且glCheckFramebufferStatusEXT返回0.

编辑2 显然在使用glCheckFramebufferStatusEXT后,glGetError始终会返回此错误。

编辑3 愚蠢的我,我把错误的枚举放在glCheckFramebufferStatusEXT中。现在我从GL_FRAMEBUFFER_COMPLETE_EXT回来了。

编辑4 更新了代码。仍然没有得到任何形象。我还提供了一些用于绘制三角形的测试代码。这也没有呈现任何东西。现在,GitHub也提供了代码。

有人可以指出我做错了吗?

0 个答案:

没有答案