2 x fbo into sampler2drect?

so i’m trying to get 2 fbo’s into a shader to do some video mixing
and have so far been pretty unsuccessful in finding out
how to pass given textures into a shader.

it seems like this should be pretty straightforward,
just passing a reference to their .texData.textureIDs or something…

they seem to be getting set up correctly (their textureIDs are 1 & 2, accordingly)
and the shader is compiling properly (vertexShader status = 1 / fragmentShader status 1).

just not sure how to get the data from the textures into the samplers…
any ideas would be appreciated, i’ve been trolling for the info for a while to no avail.

cheers,
mark

p.s. i’m also getting this error message, even at 640 x 480:
OF_WARNING: ofxFBOTexture: requested samples too high. Using GL_SAMPLES instead.

not sure what is up with that exactly… but it’s my impression that i need to use
the “GL_RGBA, 4” mode in order to use transparency in the fbo (as i plan to)…
but maybe i’m missing something.

fboMixer.zip

first off, i’d like to apologize not having the exact vocabulary here,
i’m coming at this from years of doing opengl in jitter,
and a bit of dabbling w/ it in cpp and lua.

in jitter lingo, we’re just talking two jit.gl.slabs or (jit.gl.textures)
going into the left & right inlets of a jit.gl.slab…

at any rate, i’ve been reading oodles on how one might select a texture for an input to a shader,
and according to http://nehe.gamedev.net/data/articles/article.asp?article=21:

textures are available in GLSL via sampler, which have to be uniform. But how do we tell GLSL which texture image should be used for which sampler?

Textures are not directly passed to GLSL, but we pass the texture unit where our texture is bound to OpenGL. This works in the following way:
Get the sampler uniform location.
Bind the texture to texture unit i.
Pass i as an integer by glUniform.
Here an example:

  
>     glUseProgramObjectARB(my_program);  
>     int my_sampler_uniform_location = glGetUniformLocationARB(my_program, “my_color_texture”);  
>       
>     glActiveTexture(GL_TEXTURE0 + i);  
>     glBindTexture(GL_TEXTURE_2D, my_texture_object);  
>       
>     glUniform1iARB(my_sampler_uniform_location, i);  
>       
>     

trolling through ofxFBOTexture, it looks like this is exactly what is being done in the setUniformVariable1i fcn:

  
glUniform1iARB(glGetUniformLocationARB(shader, name), value);  

so if i were to say in ofx:

  
_mxShader.setUniformVariable1i("BaseImage", _mxBase.texData.textureID);  

then in my shader:

  
vec4 base = texture2DRect(BaseImage, gl_TexCoord[0].xy);  

it seems like we’re looking at solid gold,
but i end up w/ a blank screen staring at me instead.

i’ve cleaned up some bugs & things here and reposted the code below.

at any rate, this all seems incredibly more mind-boggling complicated than it seems like it should be
so i imagine i must be missing something painfully obvious.
any ideas or leads would be greatly appreciated…

thx 4 alles,
m

fboMixer2.zip

oh & p.s. re: the “requested samples too high” message,
i’m running 10.5.8 on an intel 2.16Ghz MBP w/ a RadeonX1600 card

so i should be able to get a max of 6 samples,
if i’m reading correctly, according to the info here:
http://developer.apple.com/graphicsimaging/opengl/capabilities/GLInfo-1058.html

but dropping a cout on maxSamples into the supportCheck
of ofxFBOTexture yields a value of 0. strange.

Hi,

there’s an old post that I wrote a solution to mixing 2 textures in GLSL here:
http://forum.openframeworks.cc/t/using-ofshader-with-oftexture’s/419/0

It’s a little long but my code is towards the end. This is for 2 regular ofTextures, but the principle would be exactly the same for FBOs.

Also, try a simple version first, using sampler2D instead of 2Drect and using square textures, perhaps that might help you find your problem.

If you still have trouble let me know I’ll have a look at your code and find a solution… :slight_smile:

Just as a note, I got the same thing when I ran ofxFBOTexture on a different machine (geForce9400) that’s also supposed to support GL_EXT_framebuffer_multisample. I’m not sure what’s up with glGetString(GL_EXTENSIONS).

thx for the leads, gimus…
i took your advice & am using only a 2d w/ a square & POT sized fbo (512x512)
and have updated my code based on what i saw on the post you mentioned.

i seem to be getting closer & closer,
am now successfully getting the output of one fbo to show up inside the shader,
but when i try to draw 2, the most recently drawn fbo overrides the previous,
no matter what values i send to the shader.

ideas anyone?

cheers,
mark

fboMixer3.zip

  1. as far as the of warning:

OF_WARNING: ofxFBOTexture: requested samples too high. Using GL_SAMPLES instead.

This isn’t really related to size or graphics card, you have to explicitly setup how many samples are being used in your app if you plan on multisampling. You’ll find that if you add:

window.setGlutDisplayString(“rgba double depth samples>=4”);

to main.cpp before the ofSetupOpenGL call, it shouldn’t error out on you.

  1. for Non-POT textures, you probably want to set up a uniform sampler2DRect, not just sampler2D, and then subsequently call texture2DRect, assuming you have ARB textures enabled. Not sure why you went back to POT, it should be doable with ARB…
    **One general note here while I’m on the subject, with POT textures the texCoords will be normalized 0.0->1.0, but for ARB textures it works based on 0.0->tex_w and 0.0->tex_h.

It will take me a little bit to try to suss out your actual shader issues, but I’ll take a look at your src this weekend and get back to you.

best,
keith

hey keith
thanks for the window tip, will check that out…
re: 2d vs. 2d rect, was just trying to simplify things in the short term,
but yeah i ultimately want to go w/ 2drect so that’s great news all around…
thanks for the help, can’t wait to get this thing working :slight_smile:

cheers,
mark

so here are the issues I can see:

I think all you need in your mxShader setup is:

  
  
_mxShader.loadShader("mx");  
_mxBase.allocate(w, h, GL_RGBA,4);  
_mxBlend.allocate(w, h, GL_RGBA,4);	  
  

don’t need any of the other texture or buffer calls.

then once you have your shader active, you would want to call:

  
  
  
glActiveTexture(GL_TEXTURE0); // activate texture  
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, (GLuint)_mxBase.texData.textureID);  //bind this texture  
_mxShader.setUniformVariable1i("BaseImage", 0); //send which texture to the shader  
  
glActiveTexture(GL_TEXTURE1);  
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, (GLuint)_mxBlend.texData.textureID);  
_mxShader.setUniformVariable1i("BlendImage", 1);   
  

i also don’t think you want to draw your textures within the shader…doesn’t that defeat the purpose of passing them in? The shader will handle all the necessary fragments; I just have a simple textured quad as so:

  
	  
glBegin(GL_QUADS);  
glTexCoord2f(0, 0);  
glVertex2f(0,0);  
glTexCoord2f(w, 0);  
glVertex2f(w,0);  
glTexCoord2i(w, h);  
glVertex2f(w,h);  
glTexCoord2f(0, h);  
glVertex2f(0,h);  
glEnd();  
  

Then in your shaders, make everything a sampler2dRect and texture2dRect. I’d also copy your varying vec2 texCoord into the vert shader and set it equal to vec2(gl_MultiTexCoord0).

That should do it, let me know if you have more questions.

best,
keith

nice, got it!
order of operations was a little tricky,
but seems logical enough now that i think about it.
thanks for all the help…

cheers,
mark

fboMixer4.zip