FBO call surrogate

Hi All,

I have the following working code with a line marked “this line”.

Suppose the FBO is not available on some hardwares, what is the standard OpenGL surrogate for “this line”?

I discovered that Shaders can be available while FBO not on some implementations, so I wanted to try the slow way to keep shaders alive.

Thanks in advance,

Alberto

glActiveTexture(gl.TEXTURE0);

// this line
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, blurredTextureName, 0);

glEnable(GL_TEXTURE_2D);    
glBindTexture(GL_TEXTURE_2D, sharpTextureName);
glUseProgram(ShaderProgram);
              
DrawQuadOnTexture();

Pbuffers, or glCopyTexImage2D.

I probably explain me poorly I am trying to understand what the marked FBO line does and lookign for a standard OpenGL equivalent.

Any idea?

Thanks,

Alberto

You are right, it’s probably the glCopyTexImage2D I need. I’ll try and let you know.

No, in practice the marked line determines what texture will be modified, while the line:

glBindTexture(GL_TEXTURE_2D, sharpTextureName);

determines what texture the shader keeps as source.

How can I specify the destination texture with standard OpenGL?

Thanks,

Alberto

How can I specify the destination texture with standard OpenGL?

The primary purpose of FBO is to allow you to use a texture as its framebuffer. This is because before FBO, you couldn’t do that.

In short, you cannot do exactly what you want with “standard” OpenGL. If you don’t want to use FBO, you will have to render to the main framebuffer and use glCopyTexSubImage2D to copy the results to a texture.

Sounds good, so I need to change my shaders to look for framebuffer pixel colors instead of the binded texture texel I use with FBO, right?

Sounds good, so I need to change my shaders to look for framebuffer pixel colors instead of the binded texture texel I use with FBO, right?

Um, no.

Given some of the names you’ve chosen, it looks like you’re trying to do some shader-based blurring of a texture, and capture the result of that in another texture.

To do that without FBO, you do the following:

1: Get the un-blurred texture (eg: texture 1)
2: Bind it to your shader.
3: Render to the framebuffer.
4: Copy the un-blurred texture with glCopyTexSubImage into the blurred texture (eg: texture 2)
5: You’re done.

Your shader is not changed in any way.

As far as I understand, you should not change your shaders at all since when you bind a fbo, it is like your are drawing into theframebuffer. In other words there is nothing linked to fbos in your shader you just draw into a texture instead of the framebuffer and you choose this in your application.

Korval,

Thanks so much for your help.

It is step 2) that I don’t know how to do.

How can I bind a texture to a shader without using FBO?

Thanks,

Alberto

dletozeun,

I don’t know how to explain it. The shader looks for original texture texel color and alter it in the destination texture.

I need to indicate to the shader what it the original texture and don’t know how to do (always in the case FBO aren’t available).

Thanks,

Alberto

As it has been said before, without fbo it is not possible to draw to a texture, but you can read a texture giving this one to a shader as a sampler2D.

The only thing you can do is to render your data in directly in the framebuffer or an auxiliary buffer (pBuffer) and then copy buffer data to a texture using glCopyTexSubImage. Finally you can reuse this texture as input parameter to your shader for a second pass.
Re-read what Korval said, it is very clear.

So you don’t specify nothing about destination buffer or texture to your shader, all is done in your application. Without fbo you have:

input_texture -> shader -> framebuffer|pbuffer - copy to texture(glCopyTexSubImage) -> output_texture

with a fbo:

input_texture -> shader -> output_texture

Here is the shader code. What will it read from the texture2D() func without having a suorce texture?!?

Therefore I cannot share the same shader code. I need two diffrent shader: in case of missing FBO i will read framebuffer values, right?

void main()
{

      int i;
      vec4 sum = vec4(0.0);

      for (i = 0; i < KernelSize; i++) 
      {
          vec4 tmp = texture2D(BaseImage, gl_TexCoord[0].st + vec2(Offset[i], 0));
          sum += tmp * KernelValue[i];
      }

      gl_FragColor = sum;
                                     
}

What is BaseImage? It is a uniform sampler2D.

You affected to this sampler the texture unit ID in your application and you bound an input texture to this texture unit using glBindTexture. Source texture is not linked to a fbo!

fbo is only set to render TO texture in your case.

Please read more about framebuffer objects and GLSL shaders, It looks like you have an understanding problem about what fbo really are.

http://www.gamedev.net/reference/articles/article2331.asp
http://www.gamedev.net/reference/programming/features/fbo2/

texture2D is just a glsl function that fetches a texel at given texture coordinates in a given texture through a sampler2D. It does not read the framebuffer.

dletozeun,

You said:
“As it has been said before, without fbo it is not possible to draw to a texture”

Now you say I need to bind the texture with ID 0.

Is it possible or not to use this shader unmodified without FBO?

Thanks,

Alberto

…as an input texture. You can’t draw to an output texture without a fbo but you can read one in a shader.

So I need to use something like this?

glBindTexture(GL_TEXTURE_2D, sharpTextureName);
glUseProgram(ShaderProgram);

DrawQuadOnTexture();

glUseProgram(0);     

glBindTexture(GL_TEXTURE_2D, blurredTextureName);

glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, textureSize, textureSize, 0);


Tested and works great. Thanks a lot dletozeun for your help!

Yes exactly. You are welcome.

Hi again,

I was so happy to see everything working that the first machine I tested the code on (different from developing machine) display a empty texture (the one FBO uses as render to texture). In practice the one I specify here:

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, blurredTextureName, 0);

Summarizing: I am drawing the model shadow on a texture, blurring the shadow image and displaying the texture under the model (in two passes, using two textures).

The machine where everything works fine is:

ATI FireGL 7200
OpenGL version 2.0.6663
Shading language 1.10

The other, where the issue is present (shaders works on this machine, I installed renderMonkey and see all shaders effects):

ATI Radeon 9550 / X1050
OpenGL version 2.1.7873
Shading language 1.20

I attach the GLIntercept output to list exaclty what I am doing.

Do you see something wrong?

Thanks,

Alberto

Shader initialization and variable loading:


glGetString(GL_VERSION)="2.1.7873 Release" 
glGetString(GL_SHADING_LANGUAGE_VERSION)="1.20" 
glCreateShader(GL_FRAGMENT_SHADER)=1 
glCreateShader(GL_FRAGMENT_SHADER)=2 
glShaderSource(1,1,0x2481c0,0x0000)
glShaderSource(2,1,0x2481c0,0x0000)
glCompileShader(1)
glCompileShader(2)
glGetShaderiv(1,GL_COMPILE_STATUS,0x415d794)
glGetShaderiv(2,GL_COMPILE_STATUS,0x415d790)
glCreateProgram()=3 
glAttachShader(3,1)
glLinkProgram(3)
glCreateProgram()=4 
glAttachShader(4,2)
glLinkProgram(4)
glGetProgramiv(3,GL_LINK_STATUS,0x415d78c)
glGetProgramiv(4,GL_LINK_STATUS,0x415d788)
glUseProgram(3)
glGetUniformLocation(3,"BaseImage")=38 
glGetUniformLocation(3,"Offset")=19 
glGetUniformLocation(3,"KernelValue")=0 
glUniform1i(38,0)
glUniform1fv(19,19,[-0.035156])
glUniform1fv(0,19,[0.007935])
glUseProgram(4)
glGetUniformLocation(4,"BaseImage")=38 
glGetUniformLocation(4,"Offset")=19 
glGetUniformLocation(4,"KernelValue")=0 
glUniform1i(38,0)
glUniform1fv(19,19,[-0.035156])
glUniform1fv(0,19,[0.007935])
glUseProgram(0)

FBO preparation, drawing on texture, shader execution and FBO cleanup:

glGenFramebuffersEXT(1,0x133bafc)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,1)
glBindTexture(GL_TEXTURE_2D,2)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_BGRA,GL_UNSIGNED_BYTE,0x0000)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,2,0)
glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)=GL_FRAMEBUFFER_COMPLETE_EXT 
glBindTexture(GL_TEXTURE_2D,0)

/* drawing begins here */

glClearColor(0.000000,0.000000,0.000000,0.000000)
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-7.308236,7.308236,-7.308236,7.308236,-1000000.000000,1000000.000000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glMultMatrixf([1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000])
glTranslated(-2.500000,0.000000,-1.000000)
glViewport(0,0,256,256)
glDisable(GL_CULL_FACE)
glDisable(GL_DEPTH_TEST)
glDisable(GL_BLEND)
glDisable(GL_LIGHTING)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL)
glColor3ub(0,0,0)
glCallList(522)

/* shaders execution */

glActiveTexture(GL_TEXTURE0)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,3,0)
glBindTexture(GL_TEXTURE_2D,2)
glUseProgram(3)
glEnable(GL_TEXTURE_2D)
glBegin(GL_QUADS) GLSL=3  Textures[ (0,2) ] 
glTexCoord2f(0.000000,0.000000)
glVertex2d(-4.808236,-7.308236)
glTexCoord2f(1.000000,0.000000)
glVertex2d(9.808236,-7.308236)
glTexCoord2f(1.000000,1.000000)
glVertex2d(9.808236,7.308236)
glTexCoord2f(0.000000,1.000000)
glVertex2d(-4.808236,7.308236)
glEnd()
glDisable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D,3)
glUseProgram(4)
glEnable(GL_TEXTURE_2D)
glBegin(GL_QUADS) GLSL=4  Textures[ (0,3) ] 
glTexCoord2f(0.000000,0.000000)
glVertex2d(-4.808236,-7.308236)
glTexCoord2f(1.000000,0.000000)
glVertex2d(9.808236,-7.308236)
glTexCoord2f(1.000000,1.000000)
glVertex2d(9.808236,7.308236)
glTexCoord2f(0.000000,1.000000)
glVertex2d(-4.808236,7.308236)
glEnd()
glDisable(GL_TEXTURE_2D)
glUseProgram(0)

/* FBO cleanup */

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0)
glDeleteFramebuffersEXT(1,0x133bb0c)


glGenFramebuffersEXT(1,0x133bafc)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,1)

What is this? oÔ

You are binding the framebuffer object with id 1 and and generating a fbo id at the @ 0x133bafc. The generated value could be different than 1 and if you use this one to bind the fbo latter you could have problems.

Anyxay, there is a coding problem here, you store an ID and don’t use it after.