gpt4 book ai didi

c# - glframebuffertexture 和 glbindtexture 的区别

转载 作者:行者123 更新时间:2023-11-30 23:10:14 24 4
gpt4 key购买 nike

OpenGL 中 glframebuffertextureglbindtexture 这两个函数在使用上的具体区别是什么。

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

我很难尝试以正确的顺序进行调用,我想知道我是否对何时需要将纹理绑定(bind)到帧缓冲区以及何时需要将纹理分配给帧缓冲区感到困惑。

我已经阅读了有关这些函数的文档,但它们并没有真正解释这些函数与帧缓冲区上下文中的关系。

我基本上没有将任何东西渲染回屏幕。

例如,如果我使用 SharpFont(FreeType 绑定(bind)库)渲染文本,我有一个用于整个渲染字符串的帧缓冲区和一个用于渲染每个字符的帧缓冲区。

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

  1. 从 FB0(屏幕空间)开始,

  2. 创建 FB 1,

  3. 使用 TX 1(创建然后绑定(bind)到然后附加)设置 FB 1(绑定(bind)到 FB 1),

  4. 绑定(bind)回FB0,

  5. 绑定(bind)到 FB1(开始渲染),

  6. 创建FB2,

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

  8. 绑定(bind)回FB1,

  9. 绑定(bind)TX2

  10. 使用四边形渲染 TX2(据说)

  11. 在 7 重复下一个字符,直到结束

  12. 绑定(bind)回 FB0

  13. 使用四边形渲染 TX1(据说)。


帧缓冲区(UI 对象)

    public class OGLFrameBuffer : IFrameBuffer {

private int frameBufferId = -1;
private int frameBufferTexture = -1;

private IDrawer ctx;

public OGLFrameBuffer(IDrawer dCtx) { ctx = dCtx; }

public void SetupFrameBuffer(float width, float height) {

//Generate Frame Buffer if not exists;
if (frameBufferId == -1) {
frameBufferId = GL.GenFramebuffer();
}

//set current frame buffer
ctx.PushUseFrameBuffer(this, new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height)));

if (frameBufferTexture != -1)
GL.DeleteTexture(frameBufferTexture);

//Generate Texture with buffer size;
frameBufferTexture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, frameBufferTexture);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)Math.Ceiling(width), (int)Math.Ceiling(height), 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);

GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, frameBufferTexture, 0);

//return to previous buffer
ctx.PopFrameBuffer();

}

public void SetupFrameBuffer(float width, float height, byte[] data, VIPixelFormat pixelFormat) {

PixelFormat oglPixFmt;

switch (pixelFormat) {
case VIPixelFormat.VIPF_RGBA:
oglPixFmt = PixelFormat.Bgra;
break;
case VIPixelFormat.VIPF_GREYSCALE:
oglPixFmt = PixelFormat.Red;
break;
case VIPixelFormat.VIPF_RGB:
default:
oglPixFmt = PixelFormat.Bgr;
break;
}

//Generate Frame Buffer if not exists;
if (frameBufferId == -1) {
frameBufferId = GL.GenFramebuffer();
}

//set current frame buffer
ctx.PushUseFrameBuffer(this, new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height)));

if (frameBufferTexture != -1)
GL.DeleteTexture(frameBufferTexture);

//Generate Texture with buffer size;
frameBufferTexture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, frameBufferTexture);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

if (pixelFormat == VIPixelFormat.VIPF_GREYSCALE) {
//GL.ClearColor(1f, 1f, 1f, 1f);
//GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
}

GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)Math.Ceiling(width), (int)Math.Ceiling(height), 0, oglPixFmt, PixelType.UnsignedByte, data);

GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, frameBufferTexture, 0);

//return to previous buffer
ctx.PopFrameBuffer();

}

public int GetFrameBufferId() {
return frameBufferId;
}

public int GetFrameBufferTexture() {
return frameBufferTexture;
}
}

相关上下文调用:

        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 将纹理作为渲染目标关联到帧缓冲区。

这意味着当您发出绘图调用时,该纹理将由您的片段着色器的输出写入(如果启用,则使用混合)。

GlBindTexture 告诉 OpenGL 你想读取这个纹理(例如通过 sampler2D)

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

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

当你想做一个 glTexParameter 时,你必须先绑定(bind)你正在处理的纹理。或使用动态搜索广告; glTexture参数/

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

关于c# - glframebuffertexture 和 glbindtexture 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45483483/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com