因此,我一直在尝试使用OpenGL ES 2.0创建尾随的粒子效果(请参见此处)。不幸的是,使之成为可能的OpenGL命令(累积缓冲区)似乎在OpenGL ES中不可用。这意味着必须走很长的路。
本主题描述了执行此操作的一种可能方法。但是,我对如何将内容存储在缓冲区中以及合并缓冲区感到非常困惑。因此,我的想法是执行以下操作。
到目前为止,我的理解是缓冲区以与纹理相同的方式存储像素数据,只是缓冲区可以更轻松地绘制为使用着色器。
因此,想法可能是渲染到缓冲区,然后将其移动到纹理中。
我发现这样做的一种理论是
回想起来,您应该创建两个FBO(每个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))
}
顺便说一句,这是我发现有用的一些资源。
我的主要问题是:有人可以为此写出代码。我想我了解其中涉及的理论,但是我花了很多时间徒劳地尝试应用它。
如果您想要一个开始的地方,我这里有一个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;
}
一些注意事项。为了使其正常工作,我必须添加纹理参数。
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)
我希望这将有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句