zoukankan      html  css  js  c++  java
  • CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture)

    CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture)

    渲染到纹理(Render To Texture)是实现很多OpenGL高级效果的一个基础。本文记录了如何用CSharpGL实现RTT。

    下载

    CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入(https://github.com/bitzhuwei/CSharpGL

    开始

    如图所示,我们把teapot贴到一个矩形上了。这是借助RTT实现的。

    RTT步骤如下:

    1. 创建Framebuffer,这Framebuffer里包含一个Texture,这个Texture就是RTT里的Texture。
    2. 绑定Framebuffer,然后正常渲染,然后解绑Framebuffer。(RTT结束)
    3. 此时Framebuffer里包含的Texture已经有了想要的内容,我们可以像使用其他普通Texture一样使用此Texture。

    创建Framebuffer

    Framebuffer里包含若干renderbuffer和一个depthbuffer,就像VertexArrayObject里包含若干VertexBuffer和一个IndexBuffer。

    创建Framebuffer过程概括如下:

     1         private Framebuffer CreateFramebuffer(int width, int height)
     2         {
     3             var texture = new Texture(TextureTarget.Texture2D,
     4                 new NullImageFiller(width, height, GL.GL_RGBA, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE),
     5                 new SamplerParameters(
     6                     TextureWrapping.Repeat,
     7                     TextureWrapping.Repeat,
     8                     TextureWrapping.Repeat,
     9                     TextureFilter.Linear,
    10                     TextureFilter.Linear));
    11             texture.Initialize();
    12             this.BindingTexture = texture;
    13             Renderbuffer colorBuffer = Renderbuffer.CreateColorbuffer(width, height, GL.GL_RGBA);
    14             Renderbuffer depthBuffer = Renderbuffer.CreateDepthbuffer(width, height, DepthComponentType.DepthComponent24);
    15             var framebuffer = new Framebuffer();
    16             framebuffer.Bind();
    17             framebuffer.Attach(colorBuffer);//0
    18             framebuffer.Attach(texture);//1
    19             framebuffer.Attach(depthBuffer);// special
    20             framebuffer.SetDrawBuffers(GL.GL_COLOR_ATTACHMENT0 + 1);// as in 1 in framebuffer.Attach(texture);//1
    21             framebuffer.CheckCompleteness();
    22             framebuffer.Unbind();
    23             return framebuffer;
    24         }

    使用Framebuffer

    创建Framebuffer后,先绑定Framebuffer,再像平时一样渲染,再解绑Framebuffer。

     1         public void RenderBeforeChildren(RenderEventArgs arg)
     2         {
     3             if (this.Width <= 0 || this.Height <= 0) { return; }
     4 
     5             var viewport = new int[4];
     6             GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport);
     7 
     8             this.framebuffer = this.helper.GetFramebuffer(this.Width, this.Height);
     9             framebuffer.Bind();
    10             GL.Instance.Viewport(0, 0, this.Width, this.Height);
    11             {
    12                 int[] value = new int[4];
    13                 GL.Instance.GetIntegerv((uint)GetTarget.ColorClearValue, value);
    14                 {
    15                     vec3 color = this.BackgroundColor.ToVec3();
    16                     GL.Instance.ClearColor(color.x, color.y, color.z, 0.0f); // 0.0f for alpha channel, in case that transparent background is needed.
    17                     GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
    18                 }
    19                 {
    20                     var args = new RenderEventArgs(this.Camera);
    21                     foreach (var item in this.Children)
    22                     {
    23                         RenderAction.Render(item, args);
    24                     }
    25                 }
    26                 {
    27                     GL.Instance.ClearColor(value[0], value[1], value[2], value[3]);// recover clear color.
    28                 }
    29             }
    30             GL.Instance.Viewport(viewport[0], viewport[1], viewport[2], viewport[3]);// recover viewport.
    31             this.framebuffer.Unbind();
    32         }

    使用RTT

    此时Framebuffer里包含的Texture已经有了想要的内容,我们可以像使用其他普通Texture一样使用此Texture。例如本文开始处将Texture贴到一个矩形上。

     

    当然也可以结合Billboard的需求,把Texture贴到Billboard上。

    总结

    最近几个月我在尝试修整CSharpGL,感觉好多了。

  • 相关阅读:
    Dos命令快速设置ip、网关、dns地址
    远程桌面连接保存登陆用户以及密码(凭据)备份方法
    如何启用windows8, windows10中被停用的远程桌面,如何连接windows10远程桌面?
    通过日志恢复SQL Server的历史数据
    http://sourceforge.net/projects/rtspdirectshow/
    iphone上实现H264 硬编码
    利用lipo编译合并iPhone模拟器和真机通用的静态类
    在iOS上使用ffmpeg播放视频
    基于.Net的单点登录(SSO)解决方案
    java实现简单的单点登录
  • 原文地址:https://www.cnblogs.com/bitzhuwei/p/CSharpGL-42-render-to-texture-via-framebuffer.html
Copyright © 2011-2022 走看看