所以我一直试图用OpenGL ES 2.0创建一个尾随粒子效果(seen here)。不幸的是,似乎OpenGL命令(累积缓冲区)无法在OpenGL中使用。这意味着有必要采用LONG方式。
This主题描述了做这种事情的可能方法。但是我对如何在缓冲区中存储内容并组合缓冲区感到很困惑。所以我的想法是做到以下几点。
到目前为止,我的理解是缓冲区以与纹理相同的方式存储像素数据,只需使用着色器就可以更容易地绘制缓冲区。
所以想法可能是渲染到缓冲区,然后将其移动到纹理中。
我发现这样做的一个理论就是这个
回想起来,你应该创建两个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))
}
BTW这里有一些我觉得有用的资料。
我的主要问题是:有人可以为此写出代码。我想我理解所涉及的理论,但我花了很多时间徒劳地尝试应用它。
如果你想要一个地方开始,我有Xcode project绘制点,并且有一个蓝色的,在这里定期移动屏幕,也没有工作的代码也在他们的
注意:如果你要编写代码,你可以使用任何语言c ++,java,swift,objective-c它将是完美的。只要是OpenGL-ES
答案 0 :(得分:1)
使用相同的变量tex1调用glGenTextures(1, &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;
}
一些笔记。为了使它工作,我不得不添加纹理参数。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
这是因为在我的系统上他们默认为GL_NEAREST_MIPMAP_LINEAR。这对FBO纹理不起作用,因为没有生成mipmap。将它们设置为您喜欢的任何东西
此外,请确保使用
启用纹理glEnable(GL_TEXTURE_2D)
我希望这会有所帮助。