C# glframebuffertexture和glbindtexture之间的差异

C# glframebuffertexture和glbindtexture之间的差异,c#,opengl,C#,Opengl,OpenGL中的两个函数glframebuffertexture和glbindtexture之间的确切用法差异是什么 在上下文中,我使用OpenTK为一台嵌入式机器编写了一个使用OpenGL的定制轻量级UI,该机器为UI中的不同组件使用了大量帧缓冲区和各自的纹理。在内部,使用堆栈跟踪帧缓冲区,因为缓冲区内容可以绘制到“父”缓冲区(或者如果没有父缓冲区,则绘制屏幕空间) 我很难让调用按正确的顺序进行,我想知道我是否对何时需要将纹理绑定到帧缓冲区以及何时需要将纹理指定给帧缓冲区感到困惑 我已经阅读了

OpenGL中的两个函数glframebuffertextureglbindtexture之间的确切用法差异是什么

在上下文中,我使用OpenTK为一台嵌入式机器编写了一个使用OpenGL的定制轻量级UI,该机器为UI中的不同组件使用了大量帧缓冲区和各自的纹理。在内部,使用堆栈跟踪帧缓冲区,因为缓冲区内容可以绘制到“父”缓冲区(或者如果没有父缓冲区,则绘制屏幕空间)

我很难让调用按正确的顺序进行,我想知道我是否对何时需要将纹理绑定到帧缓冲区以及何时需要将纹理指定给帧缓冲区感到困惑

我已经阅读了关于这些函数的文档,但是它们并没有真正解释这些函数之间的关系

我基本上没有被渲染回屏幕

例如,如果im使用SharpFont(FreeType绑定库)呈现文本,我有一个帧缓冲区用于整个呈现字符串,一个帧缓冲区用于呈现每个字符

这是我认为在本例中调用的一般顺序

  • 从FB0(屏幕空间)开始

  • 创建FB1

  • 使用TX 1设置FB 1(绑定到FB 1)(创建然后绑定到然后连接)

  • 绑定回FB0

  • 绑定到FB1(开始渲染到)

  • 创建FB2

  • 使用TX 2设置FB 2(绑定到FB 2)(创建然后绑定到然后附加)(包括渲染的字符像素数据)

  • 绑定回FB1

  • 结合TX2

  • 使用四边形渲染TX2(假定)

  • 对下一个字符重复第7步,直到结束

  • 绑定回FB0

  • 使用quad渲染TX1(假定)


  • 帧缓冲区(UI对象)

    相关上下文调用:

            public void PushUseFrameBuffer(IFrameBuffer buf, Size bufferDims) {
            frameBufferStack.Push(buf);
            OGLFrameBuffer frameBuf = (OGLFrameBuffer)buf;
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuf.GetFrameBufferId());
            ctxbounds = new Rectangle(new Point(0, 0), bufferDims);
        }
    
        public void PopFrameBuffer() {
            frameBufferStack.Pop();
    
            if (frameBufferStack.Count != 0) {
                OGLFrameBuffer frameBuf = (OGLFrameBuffer)frameBufferStack.Peek();
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuf.GetFrameBufferId());
            }
            else {
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            }
    
            ctxbounds = windowbounds;
        }
    
    public void DrawBuffer(IFrameBuffer buff, RectangleF textureBounds, Size parentBounds) {
    
            OGLFrameBuffer toDrawFb = (OGLFrameBuffer)buff;
    
            GL.BindTexture(TextureTarget.Texture2D, toDrawFb.GetFrameBufferTexture());
    
            GL.Begin(PrimitiveType.Quads);
    
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex2((textureBounds.X * scale)                         / parentBounds.Width , (textureBounds.Y * scale)                          / parentBounds.Height);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(((textureBounds.X + textureBounds.Width) * scale) / parentBounds.Width , (textureBounds.Y * scale)                          / parentBounds.Height);
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(((textureBounds.X + textureBounds.Width) * scale) / parentBounds.Width , ((textureBounds.Y + textureBounds.Height) * scale) / parentBounds.Height);
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex2((textureBounds.X * scale)                         / parentBounds.Width , ((textureBounds.Y + textureBounds.Height) * scale) / parentBounds.Height);
    
            GL.End();
    
            OGLFrameBuffer curFb = (OGLFrameBuffer)GetCurrentFrameBuffer();
    
            if (curFb != null) {
                GL.BindTexture(TextureTarget.Texture2D, curFb.GetFrameBufferTexture());
            }
            else {
                GL.BindTexture(TextureTarget.Texture2D, 0);
            }
    
            SetColour(1, 1, 1, 1f);
            DrawRectangle(textureBounds);
        }
    

    glFrameBufferTexture将纹理作为渲染目标关联到帧缓冲区

    这意味着当您发出drawcall时,该纹理将由片段着色器的输出写入(如果启用了混合)

    GlBindTexture告诉OpenGL您想要读取该纹理(例如通过一个采样器2D)

    简单地说:glFrameBufferTexture允许您渲染(或写入)此纹理而不是您自己的屏幕,glBindTexture允许您读取纹理内部的数据(它可以是您使用帧缓冲区编写的纹理,也可以是加载图像时编写的纹理)

    编辑:更一般地说,在OpenGL中绑定一个对象会告诉OpenGL它将在所有后续操作中使用该对象

    如果要执行glTexParameter,则必须绑定正在处理的纹理。或使用DSA;纹理参数仪/


    对于缓冲区和其他对象也是一样的

    在阅读了有关如何使用纹理设置帧缓冲区的教程后,它们将绑定到纹理,然后调用glTexParameter。在这种情况下调用glBindTexture真的需要吗?因为我没有实际读取纹理,所以我会有效地将更改写入纹理。是的,确定是指使用(读取)或更改设置(不进行绘制调用)。因此,如果我的帧缓冲区当前绑定到另一个纹理,并且我在0处绑定回缓冲区,这是否意味着帧缓冲区不再引用任何纹理以供使用,或者纹理名称0是opengl初始化时指定的默认纹理?GlBind to 0表示您不想再绑定对象。
            public void PushUseFrameBuffer(IFrameBuffer buf, Size bufferDims) {
            frameBufferStack.Push(buf);
            OGLFrameBuffer frameBuf = (OGLFrameBuffer)buf;
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuf.GetFrameBufferId());
            ctxbounds = new Rectangle(new Point(0, 0), bufferDims);
        }
    
        public void PopFrameBuffer() {
            frameBufferStack.Pop();
    
            if (frameBufferStack.Count != 0) {
                OGLFrameBuffer frameBuf = (OGLFrameBuffer)frameBufferStack.Peek();
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuf.GetFrameBufferId());
            }
            else {
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            }
    
            ctxbounds = windowbounds;
        }
    
    public void DrawBuffer(IFrameBuffer buff, RectangleF textureBounds, Size parentBounds) {
    
            OGLFrameBuffer toDrawFb = (OGLFrameBuffer)buff;
    
            GL.BindTexture(TextureTarget.Texture2D, toDrawFb.GetFrameBufferTexture());
    
            GL.Begin(PrimitiveType.Quads);
    
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex2((textureBounds.X * scale)                         / parentBounds.Width , (textureBounds.Y * scale)                          / parentBounds.Height);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(((textureBounds.X + textureBounds.Width) * scale) / parentBounds.Width , (textureBounds.Y * scale)                          / parentBounds.Height);
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(((textureBounds.X + textureBounds.Width) * scale) / parentBounds.Width , ((textureBounds.Y + textureBounds.Height) * scale) / parentBounds.Height);
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex2((textureBounds.X * scale)                         / parentBounds.Width , ((textureBounds.Y + textureBounds.Height) * scale) / parentBounds.Height);
    
            GL.End();
    
            OGLFrameBuffer curFb = (OGLFrameBuffer)GetCurrentFrameBuffer();
    
            if (curFb != null) {
                GL.BindTexture(TextureTarget.Texture2D, curFb.GetFrameBufferTexture());
            }
            else {
                GL.BindTexture(TextureTarget.Texture2D, 0);
            }
    
            SetColour(1, 1, 1, 1f);
            DrawRectangle(textureBounds);
        }