unity glbindframebufferoes 要包含什么库

OpenGL(九)使用 FrameBufferObject - 松阳论道主题 : 谁解释一下opengles中的EAGLContext, FrameBuffer和RenderBuffer的关系?
级别: 侠客
可可豆: 1104 CB
威望: 1104 点
在线时间: 897(时)
发自: Web Page
来源于&&分类
谁解释一下opengles中的EAGLContext, FrameBuffer和RenderBuffer的关系?&&&
刚开始学习opengles,&&正在看新建时候得到的那个旋转方块的例子。程序运行时候,最开始时建立环境。细看之下,无非是一些相互关联。其中出现四个关键的概念,layer, context,&&framebuffer,&&renderbuffer.[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];将context和layer关联。glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);将framebuffer和renderbuffer关联glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);[context presentRenderbuffer:GL_RENDERBUFFER_OES];将context和rendererbuffer关联。=============================现在问题来了,layer, context, 我知道是什么东西来的。但我就想不明白framebuffer和rendererbuffer代表什么东西。framebuffer应该是我们说的游戏中的一桢。但为什么要用两种不同的缓冲。他们两者之间的关系是什么?我想它们之间的关系一定是很关键的。
级别: 新手上路
可可豆: 360 CB
威望: 360 点
在线时间: 42(时)
发自: Web Page
楼主,这个苹果的文档或许对你有帮助:
级别: 骑士
可可豆: 5520 CB
威望: 5520 点
在线时间: 531(时)
发自: Web Page
引用 A renderbuffer object is a 2D image buffer allocated by the application. Therenderbuffer can be used to allocate and store color, depth, or stencil valuesand can be used as a color, depth, or stencil attachment in a framebufferobject. A renderbuffer is similar to an off-screen window system provideddrawable surface, such as a pbuffer. A renderbuffer, however, cannot bedirectly used as a GL texture.A framebuffer object (often referred to as an FBO) is a collection of color,depth, and stencil buff state that describes propertiessuch as the size and format of the color, depth, and stencil buffers attachedto the FBO; and the names of the texture and renderbuffer objects attachedto the FBO. Various 2D images can be attached to the color attachmentpoint in the framebuffer object. These include a renderbuffer object thatstores color values, a mip-level of a 2D texture or a cubemap face, or even amip-level of a 2D slice in a 3D texture. Similarly, various 2D images containingdepth values can be attached to the depth attachment point of an FBO.These can include a renderbuffer, a mip-level of a 2D texture or a cubemapface that stores depth values. The only 2D image that can be attached to thestencil attachment point of an FBO is a renderbuffer object that storesstencil values.
级别: 新手上路
可可豆: 873 CB
威望: 853 点
在线时间: 479(时)
发自: Web Page
引用 引用第2楼猪头于 09:48发表的&&: 明白了,谢谢猪头
级别: 天使
发帖: 90659
可可豆: 922081 CB
威望: 921946 点
在线时间: 5508(时)
发自: Web Page
呵呵,这个真要解释起来还真够费事的……
新浪围脖地址:http://t.sina.com.cn/CPU Dasher for OS X: https://itunes.apple.com/cn/app/cpu-dasher/id?mt=12
级别: 新手上路
可可豆: 30 CB
威望: 30 点
在线时间: 7(时)
发自: Web Page
这个问题在帮助文档里解释的最清楚了。虽然帮助文档其他方面一般
关注本帖(如果有新回复会站内信通知您)
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 关注CVP公众号
扫一扫 浏览移动版他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)OpenGL中的FBO对象(含源码) - Nin+.Lee - 博客园
作者:Nin+.Lee
* 本文属原创,转载请注明出处。
在OpenGL的渲染管线中,几何数据和纹理通过一系列变换和测试,最终被渲染成屏幕上的二维像素。那些用于存储颜色值和测试结果的二维数组的几何被称为帧缓冲区(frame buffer)。这些二维数组按用途划分,可分为颜色缓冲区(color buffer),深度缓冲区(depth buffer),模版缓冲区(stencil buffer)和累加缓冲区(accumulation buffer)。当我们创建了一个可供OpenGL绘制用的窗体后,窗体系统会为我们生成一个默认的帧缓冲区,这个帧缓冲区完全是由窗体系统来管理的,且仅用于将渲染后的图像输出到窗口的显示区域。
然而,我们可以使用OpenGL提供的GL_EXT_framebuffer_object扩展功能来创建额外的帧缓冲区。GL_EXT_framebuffer_object扩展功能中,提出了帧缓冲区对象(framebuffer object,缩写为FBO,下文中将使用FBO来代表帧缓冲区对象)的概念,用于对帧缓冲区进行建模。这样一来,无论是窗体系统创建的帧缓冲区,还是用于屏外渲染的帧缓冲区,都是FBO的实例。有了FBO,程序员就可以重定向渲染目标到其他的存储空间,比如将渲染目标重定向到纹理空间,实现渲染到纹理功能(Render to Texture)。
上文提到过帧缓冲区中包含的二维数组按用途划分,可分为颜色缓冲区(color buffer),深度缓冲区(depth buffer),模版缓冲区(stencil buffer)和累加缓冲区(accumulation buffer)。FBO中也提供了与颜色缓冲区、深度缓冲区和模版缓冲区相对应的功能(注意,FBO没有提供与累加缓冲区对应的功能)。但是,这并不意味着FBO会直接为这些缓冲区分配空间。FBO只是为这些缓冲区提供一个或多个挂接点。我们需要分别为各个缓冲区创建对象,申请空间,然后挂接到相应的挂接点上。FBO提供的挂接点如下图所示。
可以看出,FBO提供了多个颜色缓冲区挂接点GL_COLOR_ATTACHMENT0_EXT ... GL_COLOR_ATTACHMENTn_EXT、一个深度缓冲区挂接点GL_DEPTH_ATTACHMENT_EXT和一个模板缓冲区挂接点GL_STENCIL_ATTACHMENT_EXT。颜色缓冲区挂接点的个数是因不同厂商和不同型号的显卡而异的。你可以通过GL_MAX_COLOR_ATTACHMENTS_EXT查询当前显卡所支持的颜色缓冲区挂接点的最大个数。FBO提供多个颜色缓冲区挂接点的用意是,允许程序员进行多目标渲染(使用GL_ARB_draw_buffers扩展功能)。
能够与FBO挂接的对象有两种,一种是纹理对象(texture object),另一种是渲染缓冲区对象(renderbuffer object)。纹理对象,就是我们平日为模型设置纹理贴图时使用的对象;而渲染缓冲区对象可以用作不具有纹理格式的缓冲区,如深度缓冲区和模板缓冲区。当然,渲染缓冲区对象也可以用来渲染场景。
前面提到过,窗体系统创建的帧缓冲区也有对应的FBO的实例。但是,这个FBO与其他通过手工创建的FBO相比有许多不同。第一,通过手工创建的FBO不能用于将渲染结果直接显示到窗口输出区,通过手工创建的FBO只能用于屏外渲染(Off-screen Rendering);第二,窗体系统生成的FBO在创建的时候就拥有颜色缓冲区,深度缓冲区,模版缓冲区,且创建后就为这些缓冲区分配了空间。而手工创建的FBO需要手动为其添加各个缓冲区,并为其申请空间。窗体系统创建的FBO中的各个缓冲区对象不能与手动创建的FBO的挂接点挂接,反之亦然。
创建、绑定和删除一个FBO
我们可以使用glGenFramebuffersEXT()来向OpenGL申请一个或者多个闲置的FBO的ID。注意,就算成功地申请到了闲置的ID,OpenGL也不会马上为其创建实例。只用当调用glBindFramebufferEXT ()绑定FBO的时候OpenGL才会真正的创建一个FBO实例(这和其他glBind*函数极为相似)。在FBO被绑定之后,这个FBO就会被OpenGL当作当前的操作对象,后续的操作都被视为对被绑定的FBO进行的操作。窗体系统创建的FBO的ID默认为0。我们可以通过调用glDeleteFramebuffersEXT()函数来释放FBO的实例,如果要删除的FBO实例正在被使用,则OpenGL会自动绑定窗口系统创建的FBO(ID为0)。
渲染缓冲区对象
FBO创建完成后,还不能对其进行什么实质性的操作。因为,FBO的各个挂接点上还没有挂接实际的存储对象。我们需要手动创建这些对象,并将其与既存的FBO对象进行挂接。上文提到过,能够与FBO挂接的对象有两种,一种是纹理对象(texture object),另一种是渲染缓冲区对象(renderbuffer object)。读者可能对纹理对象比较熟悉,因为在为模型进行纹理贴图的时候,经常要使用这种对象。然而,对于渲染缓冲对象,读者可能会不太熟悉,因为这是OpenGL扩展中新引入的功能。下文将着重介绍渲染缓冲区对象的内容。
渲染缓冲区对象主要是为了实现屏外渲染(Off-screen Rendering)而设计的。渲染缓冲区对象主要用做FBO的深度缓冲区和模板缓冲区。可以使用glGenRenderbuffersEXT()函数来申请一个或多个闲置的渲染缓冲区对象ID(非负整数)。ID 0被OpenGL所保留。注意,申请了闲置ID之后,OpenGL并没有创建实际的对象,需要调用glBindRenderbufferEXT()函数来绑定并创建实际的对象。如果绑定ID 0,OpenGL会解除先前设定的渲染缓冲区对象。
上文提到过,渲染缓冲区对象实际上是某种二维数组的抽象。在绑定了一个渲染缓冲区对象之后,需要使用glRenderbufferStorage()函数为其分配二维数组存储空间。注意,同一个FBO中的各个二维数组空间的行数(或列数)应该相同。
同FBO类似,可以使用glDeleteRenderbuffersEXT()函数来删除一个渲染缓冲区对象。
可以使用glFramebufferRenderbufferEXT()函数将渲染缓冲区对象挂接到FBO上;使用glFramebufferTexture2D()。如果挂接的ID为0,则OpenGL将解除先前的绑定。当被绑定纹理对象或渲染缓冲区对象被删除,则他们会被自动从当前正在使用的FBO上解除挂接。如果纹理对象或渲染缓冲区对象被挂接到多个FBO上,他们被删除的时候,只会从当前被绑定的FBO上解除挂接,而不会从未被绑定的FBO上解除绑定。
FBO的完整性
在向FBO输出渲染结果之前,需要测试FBO的完整性。如果FBO不完整,任何渲染操作都会失败。我们可以使用glCheckFramebufferStatusEXT()函数来测试FBO的完整性(此函数不能在glBegin()和glEnd()函数之间调用)。FBO完整性的判别法则如下:
与FBO挂接的二维数组对象的长度和宽度必须不能为0。
如果一个二维数组对象被挂接到FBO的颜色缓冲区挂接点时,二维数组必须具有内部颜色格式(GL_RGBA, GL_DEPTH_COMPONENT, GL_LUMINANCE等)。
如果一个二维数组对象被挂接到FBO的深度缓冲区挂接点时,二维数组必须具有内部深度格式(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_EXT等)。
如果一个二维数组对象被挂接到FBO的模板缓冲区挂接点时,二维数组必须具有内部模板格式(GL_STENCIL_INDEX, GL_STENCIL_INDEX8_EXT等)。
FBO至少挂接有一个二维数组缓冲区对象。
同一个FBO上挂接的二维数组对象必须拥有相同的长度和宽度。
所有的颜色缓冲区挂接点上挂接的二维数组对象必须具有相同的内部格式。
当所有上述的准备工作都完成之后,就可以调用glBindFramebufferEXT()来绑定一个FBO。随后,就可一像操作窗体系统提供的帧缓冲区一样操作当前绑定的FBO了。日常的3D渲染操作这里不再赘述。这里主要强调像素操作的使用。OpenGL提供了glBlitFramebufferEXT()函数进行像素操作。
示例代码使用FBO实现渲染到纹理(Render to texture)功能。编译代码需要链接GLEW和SDL两个库。
Song Ho Ahn, OpenGL Frame Buffer Object (FBO), (需FQ)
Dave Shreiner, OpenGL Programming Guide The Official Guide to Learning OpenGL, Versions 3.0 and 3.1 7th Edition
Rob 'phantom' Jones, OpenGL Frame Buffer Object 101,+BIT祝威+悄悄在此留下版了个权的信息说:
CSharpGL(29)初步封装Texture和Framebuffer
+BIT祝威+悄悄在此留下版了个权的信息说:
Texture和Framebuffer
Texture和Framebuffer是OpenGL进行3D渲染高级效果必不可少的利器。有了Texture和Framebuffer就可以实现体渲染(Volume Rendering)等效果。现在到了对Texture和Framebuffer的创建、修改、使用进行封装的时候。
+BIT祝威+悄悄在此留下版了个权的信息说:
CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入()
+BIT祝威+悄悄在此留下版了个权的信息说:
封装Texture
过程式的Texture
首先观察一下平时是如何创建和使用Texture对象的。
+BIT祝威+悄悄在此留下版了个权的信息说:
创建Texture
以创建2D Texture为例。
1 uint CreateTexture(Bitmap bitmap)
glActiveTexture(OpenGL.GL_TEXTURE0);
var id = new uint[1];
OpenGL.GenTextures(1, id);
OpenGL.BindTexture(target, id[0]);
OpenGL.TexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_R, (int)OpenGL.GL_CLAMP_TO_EDGE);
OpenGL.TexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, (int)OpenGL.GL_CLAMP_TO_EDGE);
OpenGL.TexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, (int)OpenGL.GL_CLAMP_TO_EDGE);
OpenGL.TexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, (int)OpenGL.GL_REPEAT);
OpenGL.TexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, (int)OpenGL.GL_REPEAT);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
OpenGL.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA, bitmap.Width, bitmap.Height, 0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, bitmapData.Scan0);
bitmap.UnlockBits(bitmapData);
return id[0];
CreateTexture&
使用Texture
使用上述Texture的方式:
1 void UseTexture(string textureNameInShader, uint textureId)
uint target = OpenGL.GL_TEXTURE0;
glActiveTexture(target);
OpenGL.BindTexture(OpenGL.GL_TEXTURE_2D, textureId);
SetUniform("textureNameInShader", target - OpenGL.GL_TEXTURE0);
9 int SetUniform(string uniformName, uint v0)
int location = GetUniformLocation(uniformName);
if (location &= 0)
glUniform1ui(GetUniformLocation(uniformName), v0);
封装的Texture
从上述创建Texture的过程可知,创建Texture主要有2个步骤:设置Sampler和填充Texture数据。Sampler就是各个滤波选项。填充数据就是用glTexImage2D()一类的命令指定Texture的内容。
1 void Initialize()
glActiveTexture(this.ActiveTexture);
OpenGL.GenTextures(1, id);
BindTextureTarget target = this.T
OpenGL.BindTexture(target, id[0]);
this.Sampler.Bind(this.ActiveTexture - OpenGL.GL_TEXTURE0, target);
this.ImageFiller.Fill(target);
OpenGL.GenerateMipmap((MipmapTarget)((uint)target));// TODO: does this work?
//this.SamplerBuilder.Unbind(OpenGL.GL_TEXTURE0 - OpenGL.GL_TEXTURE0, this.Target);
OpenGL.BindTexture(this.Target, 0);
+BIT祝威+悄悄在此留下版了个权的信息说:
Sampler中主要就是那几个滤波选项。
/// &summary&
/// texture's settings.
/// &/summary&
public class SamplerParameters
public TextureWrapping wrapS = TextureWrapping.ClampToE
public TextureWrapping wrapT = TextureWrapping.ClampToE
public TextureWrapping wrapR = TextureWrapping.ClampToE
public TextureFilter minFilter = TextureFilter.L
public TextureFilter magFilter = TextureFilter.L
public SamplerParameters() { }
+BIT祝威+悄悄在此留下版了个权的信息说:
Sampler的唯一任务就是在创建Texture时指定某些滤波。
/// &summary&
/// texture's settings.
/// &/summary&
public abstract class SamplerBase
protected MipmapFilter mipmapF
public SamplerParameters Parameters { get; protected set; }
/// &summary&
/// texture's settings.
/// &/summary&
/// &param name="parameters"&&/param&
/// &param name="mipmapFilter"&&/param&
public SamplerBase(SamplerParameters parameters, MipmapFilter mipmapFilter)
if (parameters == null)
this.Parameters = new SamplerParameters();
this.Parameters =
this.mipmapFilter = mipmapF
/// &summary&
/// &/summary&
/// &param name="unit"&OpenGL.GL_TEXTURE0 etc.&/param&
/// &param name="target"&&/param&
public abstract void Bind(uint unit, BindTextureTarget target);
实际上为了简化指定Sampler的操作,OpenGL提供了一个Sampler对象。这里顺便也把它封装了。
/// &summary&
/// texture's settings.
/// &/summary&
public partial class Sampler : SamplerBase, IDisposable
/// &summary&
/// sampler's Id.
/// &/summary&
public uint Id { get; private set; }
/// &summary&
/// texture's settings.
/// &/summary&
/// &param name="parameters"&&/param&
/// &param name="mipmapFiltering"&&/param&
public Sampler(
SamplerParameters parameters = null,
MipmapFilter mipmapFiltering = MipmapFilter.LinearMipmapLinear)
: base(parameters, mipmapFiltering)
private bool initialized = false;
/// &summary&
/// &/summary&
public void Initialize(uint unit, BindTextureTarget target)
if (!this.initialized)
this.DoInitialize(unit, target);
this.initialized = true;
private void DoInitialize(uint unit, BindTextureTarget target)
var ids = new uint[1];
OpenGL.GenSamplers(1, ids);
this.Id = ids[0];
//OpenGL.BindSampler(unit, ids[0]);
OpenGL.BindSampler(unit, ids[0]);
/* Clamping to edges is important to prevent artifacts when scaling */
OpenGL.SamplerParameteri(ids[0], OpenGL.GL_TEXTURE_WRAP_R, (int)this.parameters.wrapR);
OpenGL.SamplerParameteri(ids[0], OpenGL.GL_TEXTURE_WRAP_S, (int)this.parameters.wrapS);
OpenGL.SamplerParameteri(ids[0], OpenGL.GL_TEXTURE_WRAP_T, (int)this.parameters.wrapT);
/* Linear filtering usually looks best for text */
OpenGL.SamplerParameteri(ids[0], OpenGL.GL_TEXTURE_MIN_FILTER, (int)this.parameters.minFilter);
OpenGL.SamplerParameteri(ids[0], OpenGL.GL_TEXTURE_MAG_FILTER, (int)this.parameters.magFilter);
// TODO: mipmap not used yet.
OpenGL.BindSampler(unit, 0);
/// &summary&
/// texture's settings.
/// &/summary&
/// &param name="unit"&OpenGL.GL_TEXTURE0 etc.&/param&
/// &param name="target"&&/param&
public override void Bind(uint unit, BindTextureTarget target)
if (!this.initialized) { this.Initialize(unit, target); }
OpenGL.BindSampler(unit, this.Id);
+BIT祝威+悄悄在此留下版了个权的信息说:
当然也可以不用这个OpenGL的Sampler对象,直接用glTexParameteri()等指令。这就像是一个假的Sampler对象在工作。
/// &summary&
/// texture's settings.
/// &/summary&
public class FakeSampler : SamplerBase
/// &summary&
/// texture's settings.
/// &/summary&
/// &param name="parameters"&&/param&
/// &param name="mipmapFiltering"&&/param&
public FakeSampler(SamplerParameters parameters, MipmapFilter mipmapFiltering)
: base(parameters, mipmapFiltering)
/// &summary&
/// texture's settings.
/// &/summary&
/// &param name="unit"&OpenGL.GL_TEXTURE0 etc.&/param&
/// &param name="target"&&/param&
public override void Bind(uint unit, BindTextureTarget target)
/* Clamping to edges is important to prevent artifacts when scaling */
OpenGL.TexParameteri((uint)target, OpenGL.GL_TEXTURE_WRAP_R, (int)this.parameters.wrapR);
OpenGL.TexParameteri((uint)target, OpenGL.GL_TEXTURE_WRAP_S, (int)this.parameters.wrapS);
OpenGL.TexParameteri((uint)target, OpenGL.GL_TEXTURE_WRAP_T, (int)this.parameters.wrapT);
/* Linear filtering usually looks best for text */
OpenGL.TexParameteri((uint)target, OpenGL.GL_TEXTURE_MIN_FILTER, (int)this.parameters.minFilter);
OpenGL.TexParameteri((uint)target, OpenGL.GL_TEXTURE_MAG_FILTER, (int)this.parameters.magFilter);
// TODO: mipmap filter not working yet.
FakeSampler
当然,有的时候根本不需要指定任何滤波选项。这可以用一个空的Sampler类型实现。
/// &summary&
/// do nothing about sampling in building texture.
/// &/summary&
public class NullSampler : SamplerBase
/// &summary&
/// do nothing about sampling in building texture.
/// &/summary&
public NullSampler() : base(null, MipmapFilter.LinearMipmapLinear) { }
/// &summary&
/// do nothing.
/// &/summary&
/// &param name="unit"&OpenGL.GL_TEXTURE0 etc.&/param&
/// &param name="target"&&/param&
public override void Bind(uint unit, BindTextureTarget target)
// nothing to do.
+BIT祝威+悄悄在此留下版了个权的信息说:
ImageFiller
填充数据就是用&glTexImage2D()&、&glTexStorage2D()&等指令设置Texture的内容。ImageFiller就是封装这一操作的。
/// &summary&
/// build texture's content.
/// &/summary&
public abstract class ImageFiller
/// &summary&
/// build texture's content.
/// &/summary&
/// &param name="target"&&/param&
public abstract void Fill(BindTextureTarget target);
对于常见的以&System.Drawing.Bitmap&为数据源填充Texture的情形,可以用下面的BitmapFiller。它可以作为1D/2D的Texture对象的填充器。
/// &summary&
/// build texture's content with Bitmap.
/// &/summary&
public class BitmapFiller : ImageFiller
private System.Drawing.B
private int
private uint
private int
private uint
private uint
/// &summary&
/// build texture's content with Bitmap.
/// &/summary&
/// &param name="bitmap"&&/param&
/// &param name="level"&0&/param&
/// &param name="internalformat"&OpenGL.GL_RGBA etc.&/param&
/// &param name="border"&0&/param&
/// &param name="format"&OpenGL.GL_BGRA etc.&/param&
/// &param name="type"&OpenGL.GL_UNSIGNED_BYTE etc.&/param&
public BitmapFiller(System.Drawing.Bitmap bitmap,
int level, uint internalformat, int border, uint format, uint type)
this.bitmap =
this.level =
this.internalformat =
this.border =
this.format =
this.type =
/// &summary&
/// build texture's content with Bitmap.
/// &/summary&
/// &param name="target"&&/param&
public override void Fill(BindTextureTarget target)
// generate texture.
Lock the image bits (so that we can pass them to OGL).
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
if (target == BindTextureTarget.Texture1D)
OpenGL.TexImage1D((uint)target, 0, this.internalformat, bitmap.Width, 0, this.format, this.type, bitmapData.Scan0);
else if (target == BindTextureTarget.Texture2D)
OpenGL.TexImage2D((uint)target, 0, this.internalformat, bitmap.Width, bitmap.Height, 0, this.format, this.type, bitmapData.Scan0);
{ throw new NotImplementedException(); }
Unlock the image.
bitmap.UnlockBits(bitmapData);
BitmapFiller
还有一个常见的填充方式&glTexStorage2D()&,可以用下面的TexStorageImageFiller实现。
/// &summary&
/// &/summary&
public class TexStorageImageFiller : ImageFiller
private int
private uint internalF
private int
private int
/// &summary&
/// &/summary&
/// &param name="levels"&&/param&
/// &param name="internalFormat"&&/param&
/// &param name="width"&&/param&
/// &param name="height"&&/param&
public TexStorageImageFiller(int levels, uint internalFormat, int width, int height)
// TODO: Complete member initialization
this.levels =
this.internalFormat = internalF
this.width =
this.height =
/// &summary&
/// &/summary&
/// &param name="target"&&/param&
public override void Fill(BindTextureTarget target)
switch (target)
case BindTextureTarget.Unknown:
case BindTextureTarget.Texture1D:
case BindTextureTarget.Texture2D:
OpenGL.TexStorage2D(TexStorage2DTarget.Texture2D, levels, internalFormat, width, height);
case BindTextureTarget.Texture3D:
case BindTextureTarget.TextureCubeMap:
case BindTextureTarget.TextureBuffer:
TexStorageImageFiller
+BIT祝威+悄悄在此留下版了个权的信息说:
创建Texture
用封装的类型创建Texture的方式如下:
1 Texture Create(Bitmap bitmap)
var texture = new Texture(BindTextureTarget.Texture2D,
new BitmapFiller(bitmap, 0, OpenGL.GL_RGBA32F, 0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE),
new SamplerParameters(
TextureWrapping.ClampToEdge,
TextureWrapping.ClampToEdge,
TextureWrapping.ClampToEdge,
TextureFilter.Linear,
TextureFilter.Linear));
texture.Initialize();
使用Texture
Texutre.Id就是用&glGenTextures()&获得的id。Texture中记录了此Texture的ActiveTexture、Target等属性。配合CSharpGL中的&samplerValue&,我们有:
/// &summary&
/// get &see cref="samplerValue"/& from this texture.
/// &/summary&
/// &param name="texture"&&/param&
/// &returns&&/returns&
public static samplerValue ToSamplerValue(this Texture texture)
return new samplerValue(
texture.Target,
texture.Id,
texture.ActiveTexture);
这就可以用到设置shader中需要的Texture上:
this.SetUniform("tex", texture.ToSamplerValue());
封装Framebuffer
过程式的Framebuffer
首先观察一下平时是如何创建和使用Framebuffer对象的。
创建Framebuffer
为关注重点,这里直接传入Texture的Id。
1 uint Create(int width, int height, uint textureId)
// create framebuffer.
var frameBufferId = new uint[1];
glGenFramebuffers(1, frameBufferId);
glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, frameBufferId);
// attach texture as a color buffer.
glFramebufferTexture2D(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_COLOR_ATTACHMENT0, OpenGL.GL_TEXTURE_2D, textureId, 0);
// create a depth buffer.
var renderbufferId = new uint[1];
glGenRenderbuffers(1, renderbufferId);
glBindRenderbuffer(OpenGL.GL_RENDERBUFFER, renderbufferId[0]);
glRenderbufferStorage(OpenGL.GL_RENDERBUFFER, OpenGL.GL_DEPTH_COMPONENT, width, height);
// attach depth buffer.
glFramebufferRenderbuffer(OpenGL.GL_RENDERBUFFER, OpenGL.GL_DEPTH_ATTACHMENT, OpenGL.GL_RENDERBUFFER, renderbufferId);
glBindFramebuffer(OpenGL.GL_RENDERBUFFER, 0);
return frameBufferId;
使用Framebuffer
使用方式与Texture类似,只要绑定就可以了。
glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, frameBufferId);
用完再解绑。
glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, 0);
封装的Framebuffer
Framebuffer就是一个盒子,单独创建一个Framebuffer基本上是没什么用的。必须Attach一些colorbuffer/depthbuffer/texture才能发挥作用。
一个Framebuffer能够绑定多个texture和colorbuffer,只能绑定一个depthbuffer。
Renderbuffer
colorbuffer和depthbuffer都属于Renderbuffer的一种,其创建方式相同,只不过有一个标识其为colorbuffer还是depthbuffer的标志不同。
创建Renderbuffer很简单。
/// &summary&
/// Create, update, use and delete a renderbuffer object.
/// &/summary&
public partial class Renderbuffer
uint[] renderbuffer = new uint[1];
/// &summary&
/// Framebuffer Id.
/// &/summary&
public uint Id { get { return renderbuffer[0]; } }
/// &summary&
/// Create, update, use and delete a renderbuffer object.
/// &/summary&
/// &param name="width"&&/param&
/// &param name="height"&&/param&
/// &param name="internalformat"&GL_DEPTH_COMPONENT, GL_RGBA etc.&/param&
/// &param name="bufferType"&&/param&
public Renderbuffer(int width, int height, uint internalformat, RenderbufferType bufferType)
this.Width =
this.Height =
this.BufferType = bufferT
glGenRenderbuffers(1, renderbuffer);
glBindRenderbuffer(OpenGL.GL_RENDERBUFFER, renderbuffer[0]);
glRenderbufferStorage(OpenGL.GL_RENDERBUFFER,
internalformat, width, height);
public int Width { get; set; }
public int Height { get; set; }
public RenderbufferType BufferType { get; private set; }
public enum RenderbufferType
DepthBuffer,
ColorBuffer,
+BIT祝威+悄悄在此留下版了个权的信息说:
创建Framebuffer
创建Framebuffer也很简单,实际上只是调用了一个&glGenFramebuffers(1, frameBuffer);&命令。
/// &summary&
/// Create, update, use and delete a framebuffer object.
/// &/summary&
public partial class Framebuffer : IDisposable
uint[] frameBuffer = new uint[1];
/// &summary&
/// Framebuffer Id.
/// &/summary&
public uint Id { get { return frameBuffer[0]; } }
/// &summary&
/// Create an empty framebuffer object.
/// &/summary&
public Framebuffer()
glGenFramebuffers(1, frameBuffer);
/// &summary&
/// &/summary&
public enum FramebufferTarget : uint
/// &summary&
/// used to draw(write only) something.
/// &/summary&
DrawFramebuffer = OpenGL.GL_DRAW_FRAMEBUFFER,
/// &summary&
/// used to read from(read only).
/// &/summary&
ReadFramebuffer = OpenGL.GL_READ_FRAMEBUFFER,
/// &summary&
/// both read/write.
/// &/summary&
Framebuffer = OpenGL.GL_FRAMEBUFFER,
使用Framebuffer
使用方式与Texture类似,只要绑定就可以了。
framebuffer.Bind();// glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, framebufferId);
用完再解绑。
framebuffer.Unbind();// glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, 0);
这与未封装的使用方式没什么区别。
基于目前我对Texture和Framebuffer的了解,现在只能封装到这个地步。
+BIT祝威+悄悄在此留下版了个权的信息说:
阅读(...) 评论()}

我要回帖

更多关于 ffmpeg unity bind 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信