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过程概括如下:

         private Framebuffer CreateFramebuffer(int width, int height)
{
var texture = new Texture(TextureTarget.Texture2D,
new NullImageFiller(width, height, GL.GL_RGBA, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE),
new SamplerParameters(
TextureWrapping.Repeat,
TextureWrapping.Repeat,
TextureWrapping.Repeat,
TextureFilter.Linear,
TextureFilter.Linear));
texture.Initialize();
this.BindingTexture = texture;
Renderbuffer colorBuffer = Renderbuffer.CreateColorbuffer(width, height, GL.GL_RGBA);
Renderbuffer depthBuffer = Renderbuffer.CreateDepthbuffer(width, height, DepthComponentType.DepthComponent24);
var framebuffer = new Framebuffer();
framebuffer.Bind();
framebuffer.Attach(colorBuffer);//
framebuffer.Attach(texture);//
framebuffer.Attach(depthBuffer);// special
framebuffer.SetDrawBuffers(GL.GL_COLOR_ATTACHMENT0 + );// as in 1 in framebuffer.Attach(texture);//
framebuffer.CheckCompleteness();
framebuffer.Unbind();
return framebuffer;
}

使用Framebuffer

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

         public void RenderBeforeChildren(RenderEventArgs arg)
{
if (this.Width <= || this.Height <= ) { return; } var viewport = new int[];
GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport); this.framebuffer = this.helper.GetFramebuffer(this.Width, this.Height);
framebuffer.Bind();
GL.Instance.Viewport(, , this.Width, this.Height);
{
int[] value = new int[];
GL.Instance.GetIntegerv((uint)GetTarget.ColorClearValue, value);
{
vec3 color = this.BackgroundColor.ToVec3();
GL.Instance.ClearColor(color.x, color.y, color.z, 0.0f); // 0.0f for alpha channel, in case that transparent background is needed.
GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);
}
{
var args = new RenderEventArgs(this.Camera);
foreach (var item in this.Children)
{
RenderAction.Render(item, args);
}
}
{
GL.Instance.ClearColor(value[], value[], value[], value[]);// recover clear color.
}
}
GL.Instance.Viewport(viewport[], viewport[], viewport[], viewport[]);// recover viewport.
this.framebuffer.Unbind();
}

使用RTT

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

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

总结

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

CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture)的更多相关文章

  1. OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)

    原文地址http://www.songho.ca/opengl/gl_fbo.html 但有改动. OpenGL Frame BufferObject(FBO) Overview: 在OpenGL渲染 ...

  2. OpenGL帧缓存对象(FBO:Frame Buffer Object)

    http://blog.csdn.net/dreamcs/article/details/7691690 转http://blog.csdn.net/xiajun07061225/article/de ...

  3. OpenGL帧缓存对象(FBO:Frame Buffer Object) 【转】

    http://blog.csdn.net/dreamcs/article/details/7691690 原文地址http://www.songho.ca/opengl/gl_fbo.html 但有改 ...

  4. 【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object) 【转】

    http://blog.csdn.net/xiajun07061225/article/details/7283929/ OpenGL Frame BufferObject(FBO) Overview ...

  5. WebGL简易教程(十三):帧缓存对象(离屏渲染)

    目录 1. 概述 2. 示例 2.1. 着色器部分 2.2. 初始化/准备工作 2.2.1. 着色器切换 2.2.2. 帧缓冲区 2.3. 绘制函数 2.3.1. 初始化顶点数组 2.3.2. 传递非 ...

  6. OpenGL读取帧缓存数据

    https://blog.csdn.net/niu2212035673/article/details/80251949 简述有些时候我们可能需要获取渲染后的图像数据,比较常用的函数是glReadPi ...

  7. [译]Vulkan教程(17)帧缓存

    [译]Vulkan教程(17)帧缓存 Framebuffers 帧缓存 We've talked a lot about framebuffers in the past few chapters a ...

  8. 【Cocos2d-x 3.x】 精灵帧缓存和纹理缓存

    转自泰然网(Cocos2d-x 3.x官方文档):精灵帧缓存:http://www.tairan.com/archives/6378/   纹理缓存: http://www.tairan.com/ar ...

  9. SpriteFrameCache 精灵帧缓存

    //获取精灵帧缓存的单例对象 auto  spriteFrameCache = SpriteFrameCache::getInstance(); //从plist文件添加多个精灵帧 spriteFra ...

随机推荐

  1. 55 Jump Game i && 45 Jump Game ii

    Jump Game Problem statement: Given an array of non-negative integers, you are initially positioned a ...

  2. 【Java SE】如何用Java实现直接选择排序

    摘要:直接选择排序属于选择排序的一种,但是它的排序算法比冒泡排序的速度要快一些,由于它的算法比较简单,所以也比较适合初学者学习掌握. 适宜人群:有一定Java SE基础,明白Java的数据类型,数组的 ...

  3. Java并发,看到了,就记录下呗

    在这篇博客中,主要把之前看的书的内容记录一下,个人感觉还是可以的,原题是这样的:开发一个高效的缓存.这里指的是单机. 首先我来看当前的一个版本 public interface Computable& ...

  4. 微信公众号开发笔记3-sdk接入(nodejs)

    另一个2小时 access_token是需要2小时更新一次,在这里,又引入了一个2小时获取一次的字段,这个字段是: jsapi_ticket,这个字段是接入sdk的前提.与access_token类似 ...

  5. 智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

    1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉. 即程序员每次 new 出来的内存都要手动 delete,否则会造 ...

  6. 如何设置SecureCRT快捷键

    第一步,打开Tools -> Keymap Editor: 2.用鼠标点击要设置的快捷键,这里以F3为例,然后选择Map Select Key 3.弹出的对话框中,Function一栏选择Run ...

  7. 关于初学loadrunner的心得体会

    自参加工作两年以来,深感个人知识底蕴浅薄,为此,自身也在多方寻找所需业务技能.loadrunner负载测试工具,作为性能测试典型工具之一,对于我个人的知识的丰富化起到一定作用,但也仅仅是对工作能力的略 ...

  8. 浅谈RSA加密

    RSA背景 在1976年以前,传统的加解密过程是: 1.A采用某种手段对数据进行加密. 2.数据传输到B的手中. 3.B逆向的实施A加密采用的步骤. 4.数据被还原. 这就是所谓的对称加密. 解密和加 ...

  9. kotlin 语言入门指南(三)--编码习惯

    这章主要讲当前 kotlin 的一些编码习惯. 命名 如无疑问,kotlin 的命名风格与以下的java风格一样: --驼峰命名法(不要使用下划线) --类名首字母大写 --方法和属性名首字母小写 - ...

  10. 开涛spring3(9.3) - Spring的事务 之 9.3 编程式事务

    9.3  编程式事务 9.3.1  编程式事务概述 所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理. Spring框架提供一致的事务抽象,因此对于JDBC还是JTA事务都是 ...