J.D*_*Doe 10 opengl-es ios opengl-es-2.0 swift
所以我一直试图用OpenGL ES 2.0 创建一个尾随粒子效果(见到这里).不幸的是,似乎OpenGL命令(累积缓冲区)无法在OpenGL中使用.这意味着有必要走长路.
本主题描述了执行此类操作的可能方法.但是我对如何在缓冲区中存储内容并组合缓冲区感到很困惑.所以我的想法是做以下事情.
到目前为止,我的理解是缓冲区以与纹理相同的方式存储像素数据,只需使用着色器可以更容易地绘制缓冲区.
因此,想法可能是渲染到缓冲区,然后将其移动到纹理中.
我发现这样做的一个理论就是这个
回想起来,你应该创建两个FBO(每个都有自己的纹理); 使用默认的帧缓冲区是不可靠的(不保证在帧之间保留内容).
绑定第一个FBO后,清除它然后正常渲染场景.渲染场景后,使用纹理作为源并使用混合将其渲染到第二个FBO(第二个FBO永远不会被清除).这将导致第二个FBO包含新场景和之前的场景的混合.最后,第二个FBO应直接渲染到窗口(这可以通过渲染纹理四边形来完成,类似于前一个操作,或者使用glBlitFramebuffer).
实质上,第一个FBO取代了默认的帧缓冲区,而第二个FBO取代了累积缓冲区.
综上所述:
初始化:
对于每个FBO: - glGenTextures - glBindTexture - glTexImage2D - glBindFrameBuffer - glFramebufferTexture2D
每一帧:
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo1)glClear glDraw*//场景
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo2)glBindTexture(tex1)glEnable(GL_BLEND)glBlendFunc glDraw*//全屏四边形
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,0)glBindFrameBuffer(GL_READ_FRAMEBUFFER,fbo2)glBlitFramebuffer
不幸的是它没有足够的代码(尤其是初始化让我开始).
但我已经尝试过,到目前为止我所得到的只是一个令人失望的空白屏幕.我真的不知道我在做什么,所以可能这段代码是错误的.
var fbo1:GLuint = 0
var fbo2:GLuint = 0
var tex1:GLuint = 0
Init()
{
//...Loading shaders OpenGL etc.
//FBO 1
glGenFramebuffers(1, &fbo1)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo1)
//Create texture for shader output
glGenTextures(1, &tex1)
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
//FBO 2
glGenFramebuffers(1, &fbo2)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo2)
//Create texture for shader output
glGenTextures(1, &tex1)
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
}
func drawFullScreenTex()
{
glUseProgram(texShader)
let rect:[GLint] = [0, 0, GLint(width), GLint(height)]
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
//Texture is allready
glTexParameteriv(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_CROP_RECT_OES), rect)
glDrawTexiOES(0, 0, 0, width, height)
}
fun draw()
{
//Prep
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo1)
glClearColor(0, 0.1, 0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
//1
glUseProgram(pointShader);
passTheStuff() //Just passes in uniforms
drawParticles(glGetUniformLocation(pointShader, "color"), size_loc: glGetUniformLocation(pointShader, "pointSize")) //Draws particles
//2
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo2)
drawFullScreenTex()
//3
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), 0)
glBindFramebuffer(GLenum(GL_READ_FRAMEBUFFER), fbo2)
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_NEAREST))
}
Run Code Online (Sandbox Code Playgroud)
BTW这里有一些我认为有用的资料.
我的主要问题是: 有人可以为此写出代码.我想我理解所涉及的理论,但我花了很多时间徒劳地尝试应用它.
如果你想要一个地方开始,我有一个绘制点的Xcode项目,并且有一个蓝色的项目在这里定期移动屏幕,同样也没有工作的代码.
注意:如果你要编写代码,你可以使用任何语言c ++,java,swift,objective-c它将是完美的.只要它适用于OpenGL-ES
您glGenTextures(1, &tex1)使用同一变量 tex1 调用两次。这会覆盖该变量。当您稍后调用 时glBindTexture(GLenum(GL_TEXTURE_2D), tex1),它不会绑定 fbo1 对应的纹理,而是绑定 fbo2 对应的纹理。每个 fbo 都需要不同的纹理。
作为参考,下面是我的一个工作程序的示例,它使用多个 FBO 并渲染到纹理。
GLuint fbo[n];
GLuint tex[n];
init() {
glGenFramebuffers(n, fbo);
glGenTextures(n, tex);
for (int i = 0; i < n; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
glBindTexture(GL_TEXTURE_2D, tex[i]);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[i], 0);
}
}
render() {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw scene into buffer 0
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(cbo[0]);
//Draw full screen tex
...
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(cbo[n - 1]);
// Draw to screen
return;
}
Run Code Online (Sandbox Code Playgroud)
一些笔记。为了让它工作,我必须添加纹理参数。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Run Code Online (Sandbox Code Playgroud)
这是因为在我的系统上它们默认为 GL_NEAREST_MIPMAP_LINEAR。这对于 FBO 纹理不起作用,因为没有生成 mipmap。将它们设置为您喜欢的任何内容。
另外,请确保您启用了纹理
glEnable(GL_TEXTURE_2D)
Run Code Online (Sandbox Code Playgroud)
我希望这个能帮上忙。
| 归档时间: |
|
| 查看次数: |
733 次 |
| 最近记录: |