FBO set up on Android

Started by
2 comments, last by lancemao 13 years, 4 months ago
Hi there,

Sorry I have to ask cause I` m pulling my hair off, some of which are already white. So, I` m trying to get FBO working on Android. I have looked up the internet to write the following code:

ByteBuffer tbb = ByteBuffer.allocateDirect(8);
tbb.order(ByteOrder.nativeOrder());
IntBuffer tb = tbb.asIntBuffer();
gl2.glGenTextures(2, tb);
HUtil.checkError(gl2);
int[] textures = new int[2];
tb.position(0);
tb.get(textures);
gl2.glBindTexture(GL20.GL_TEXTURE_2D, textures[0]);
HUtil.checkError(gl2);
gl2.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, FBO_WIDTH, FBO_HEIGHT, 0,
GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, null);
HUtil.checkError(gl2);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER,
GL20.GL_NEAREST);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER,
GL20.GL_NEAREST);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
GL20.GL_CLAMP_TO_EDGE);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
GL20.GL_CLAMP_TO_EDGE);
HUtil.checkError(gl2);
gl2.glBindTexture(GL20.GL_TEXTURE_2D, 0);

mFBOTexHandle = textures[0];
gl2.glBindTexture(GL20.GL_TEXTURE_2D, textures[1]);
gl2.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_DEPTH_COMPONENT,
FBO_WIDTH, FBO_HEIGHT, 0,
GL20.GL_DEPTH_COMPONENT, GL20.GL_UNSIGNED_SHORT, null);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER,
GL20.GL_NEAREST);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER,
GL20.GL_NEAREST);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
GL20.GL_CLAMP_TO_EDGE);
gl2.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
GL20.GL_CLAMP_TO_EDGE);
gl2.glBindTexture(GL20.GL_TEXTURE_2D, 0);
HUtil.checkError(gl2);


ByteBuffer fbb = ByteBuffer.allocateDirect(4);
fbb.order(ByteOrder.nativeOrder());
IntBuffer bufhandle = fbb.asIntBuffer();

// General frame buffer
gl2.glGenFramebuffers(1, bufhandle);

int[] handles = new int[1];
bufhandle.position(0);
bufhandle.get(handles);
mFBOHandle = handles[0];
// Bind frame buffer
gl2.glBindFramebuffer(GL20.GL_FRAMEBUFFER, mFBOHandle);

// attach texture to frame buffer
gl2.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER,
GL20.GL_DEPTH_ATTACHMENT, GL20.GL_TEXTURE_2D, textures[0], 0);
HUtil.checkError(gl2);
gl2.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER,
GL20.GL_DEPTH_ATTACHMENT, GL20.GL_TEXTURE_2D, textures[1], 0);
HUtil.checkError(gl2);

int status = gl2.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (status == GL20.GL_FRAMEBUFFER_COMPLETE) {
Log.i(TAG, "Frame buffer created. Handle = " + mFBOHandle);
}else{
Log.e(TAG, "Frame buffer can not be created err = " + status);
}

gl2.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);

The FBO creation IS successful. However, when I set the Texture handle to my Frag shader like this:
int texid = mFBOTexHandle;
if (texid > 0){
int loc = gl2.glGetUniformLocation(mProgram, "tex");
gl2.glUniform1i(loc, mFBOTexHandle);
HUtil.checkError(gl2, "Damn we got 1281");
}

I got 1281 error

For your information, I have set Texture width&height to 128 so it is power of 2 and it` s so small that we should not run out of memory. And also I tried to gen mipmap mannually by
gl2.glGenerateMipmap(GL20.GL_TEXTURE_2D);
still doesn` t work


Thanks for your time and any suggestion is really appreciated
Advertisement
You're not supposed to pass texture handles to the shader, rather you pass the texture slot to your shader.

If your texture is bound to glActiveTexture(GL_TEXTURE0), than you set gl2.glUniform1i(loc, 0). If it is bound to GL_TEXTURE1, then you set it to 1. The shader doesn't want to know about the actual texture id generated by glGenTextures, it only cares about which texture unit it is actively bound to.


Also, you're setting two depth attachments to your framebuffer, is this what you mean to be doing?
gl2.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER,GL20.GL_DEPTH_ATTACHMENT, GL20.GL_TEXTURE_2D, textures[0], 0);HUtil.checkError(gl2);gl2.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER,GL20.GL_DEPTH_ATTACHMENT, GL20.GL_TEXTURE_2D, textures[1], 0);HUtil.checkError(gl2);


Finally, it looks like you're both trying to write to textures[0] and read from textures[0] in a sampler in the same pass, which isn't legal to do. You can't read from/ write to the same texture in the same pass.

Maybe explain what you're trying to accomplish here?
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Thank you so much for your time and reply.

Sorry about the two depths. It was a typo, I was trying to see what would happen if I do that. The spec says there must be at least one color attachment for a FBO, it seems that even if there are no such attachment, the FBO can be created successfully anyway.

OK, I tried the slot instead of hanlder and also I added multi-pass. Things are about to work except that I only got the background color and there is no shapes (a cone, in my case). So what I have done are:

mProgram = mDefProgram;
glUseProgram(firstProgram, default one, with Per pixel lighting and stuff)
bind to framebuffer
clear screen with blue color
set attributes
set other uniforms such as viewprojection matrix, camera pos, light, material (no texture)
DrawArray (draw a green cone loaded from 3ds file)
unbind to framebuffer

mProgram = mFBOProgram;
glUseProgram(2nd one, just sample a texture)
gl2.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl2.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
gl2.glBindTexture(GL20.GL_TEXTURE_2D, mFBOTexHandle);
gl2.glActiveTexture(GL20.GL_TEXTURE0);
int loc = gl2.glGetUniformLocation(mProgram, "tex");
gl2.glUniform1i(loc, 0);
and then set up matrix as well as attributes
and then draw a Quad

what I get is a blue quad without cone. If I comment out second pass, I can get a blue backgrounded and a green cone. If I comment out the first part, and set frag shader to return red color, I can get a red quad so that means I got the view-project-normal stuff right for both programs. Right?

So, seems that only the clear part goes onto the second pass. Or is there something I did it wrong?

Thanks for your precious time!

-Lance
Alright. I have fixed this.

It is because my offscreen texture size is too small (128X128), I changed it to 1024, then the beautiful cone is there!

Now, problem is that the cone is not in the center of the screen. But I believe I will figure it out. What a nice day! Thanks again for anyone who spent time on this

This topic is closed to new replies.

Advertisement