ofFBO (float) with ofBox and ofEnableDepthTest() issue

Heya-

I’m having a strange problem dealing with an ofFbo (float), with an ofBox that is having a video texture rendered onto it, and using ofEnableDepthTest();.

I’m combining the fboTrails example with the ofBox example on of 0.8.0, on OSX 10.8.5. No addons.

I’m basically taking a box, binding a video texture to it, and having it drawn in an fbo that has an rect with an alpha layer drawn first, so that it creates a bit of a trail effect. Pretty straightforward.

In putting this together, I realized I had to use ofEnableDepthTest(); or else the ofBox is kind of “see-through” I don’t know how else best to describe it, but someone whose used some of the openGL features and gone back and forth between ofEnableDepthTest(); and ofDisableDepthTest(); will know what I mean.

When I try to add the depth test to my code, my boxes start to get “hidden” behind what I think is my black ofRect. Does anyone know why this might be happening, or what I might be doing wrong and how to fix it?

I pushed the code to Github for easy cloning. You can find it here:

fboTrailsBoxDepthTest

I made a simple keypress so you switch back between enabling/disabling depth test by pressing ‘d’.

You can also press c to clear the FBO (like in the aforementioned example).

The desired effect is a full-volume ofBox with the fbo trails effect for when they move around

Another question I have is: Am I binding the texture correctly? Is there another way to bind it that would be better for my application?

And additionally, I have an “idea” of what ofEnableDepthTest(); does, and by that I mean I can tell the difference visually when its enabled or not. Can anyone shed some light on how it works and why this might be happening?

Please let me know if there is anything I can clarify! Hope to hear from someone soon!

Hello! Sorry to push this thread up again…maybe I wasn’t clear enough in my question.

My question is, how can I an alpha FBO with ofBoxes that have a video texture binded to them? If I disable depth test, the boxes become “see-through”. If I enable depth test, it seems to draw my alpha rect in an undesirable way, as if the boxes are being covered by the rect.

You can toggle between both modes with ‘d’.

I’m trying to basically do what is done in the fboTrails example, but with video texture-binded ofBoxes.

I copy+pasted my code into this thread for simplicity. If anyone can glance over it I’d really appreciate it!

testApp.h

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{

public:
	void setup();
	void update();
	void draw();
    void keyPressed(int key);
    void drawIntoFBO();

	
ofFbo rgbaFboFloat; // with alpha
ofVideoPlayer player;
int fadeAmnt;
ofEasyCam cam; // add mouse controls for camera movement

bool enableDepthTest;

};

testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){

ofBackground(0,0,0);
ofSetFrameRate(60);
ofSetVerticalSync(true);

player.loadMovie("fingers.mov");
player.play();
player.setVolume(0.0);

rgbaFboFloat.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGBA32F_ARB);
rgbaFboFloat.begin();
ofClear(255,255,255, 0);
rgbaFboFloat.end();

enableDepthTest = true;


}

//--------------------------------------------------------------
void testApp::update(){
ofEnableAlphaBlending();

player.update();
rgbaFboFloat.begin();
drawIntoFBO();
rgbaFboFloat.end();

}

//--------------------------------------------------------------
void testApp::draw(){
rgbaFboFloat.draw(0,0);
}


//--------------------------------------------------------------
void testApp::drawIntoFBO(){
//we clear the fbo if c is pressed.
//this completely clears the buffer so you won't see any trails
if( ofGetKeyPressed('c') ){
	ofClear(255,255,255, 0);
}

//some different alpha values for fading the fbo
//the lower the number, the longer the trails will take to fade away.
fadeAmnt = 20;
if(ofGetKeyPressed('1')){
	fadeAmnt = 1;
}else if(ofGetKeyPressed('2')){
	fadeAmnt = 5;
}else if(ofGetKeyPressed('3')){
	fadeAmnt = 15;
}

//1 - Fade Fbo

//this is where we fade the fbo
//by drawing a rectangle the size of the fbo with a small alpha value, we can slowly fade the current contents of the fbo.

 ofPushStyle();
 ofFill();
 ofSetColor(0,0,0, fadeAmnt);
 ofRect(0,0,ofGetWindowWidth(),ofGetWindowHeight());
 ofPopStyle();


//2 - Draw graphics

float movementSpeed = .1;
float cloudSize = ofGetWidth() / 2;
float maxBoxSize = 100;
float spacing = 1;

cam.begin();

for(int i = 0; i < 20; i++) {
    
	ofPushMatrix();
	
	float t = (ofGetElapsedTimef() + i * spacing) * movementSpeed;
	ofVec3f pos(
                ofSignedNoise(t, 0, 0),
                ofSignedNoise(0, t, 0),
                ofSignedNoise(0, 0, t));
	
	float boxSize = maxBoxSize * ofNoise(pos.x, pos.y, pos.z);
	
	pos *= cloudSize;
	ofTranslate(pos);
    ofPushStyle();
    ofEnableNormalizedTexCoords();
    player.getTextureReference().bind();
	ofFill();
    
    if (enableDepthTest) {
        ofEnableDepthTest();
    }
	
    ofDrawBox(boxSize);
    
    if (enableDepthTest) {
        ofDisableDepthTest();
    }
    
    player.getTextureReference().unbind();
    ofDisableNormalizedTexCoords();
    ofPopStyle();
	ofPopMatrix();
}
cam.end();

}

void testApp::keyPressed(int key){
if(key=='d'){
    enableDepthTest = !enableDepthTest;
}
}

depth test + alpha is tricky since things in the background won’t be drawn if you have depth test enabled. The solution is usually to order things from back to front and then draw them in that order.

Hmm interesting! With those tips I also changed some colors around to see where exactly this black overlay was coming from, and it looks like it was from ofBackground in setup (which I guess would be the “first” thing drawn?")

I made some modifications that got the results I was looking for:

  • Disabling the background with ofSetBackgroundAuto(false); in setup seems to work.

  • I also now have to clear the fbo each frame, which I don’t fully understand why but it seems to work now.

  • Moving my alpha rect to draw and drawing on top of the fbo in a more “traditional” fading style.

Here is the resulting code:

testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
ofSetBackgroundAuto(false);
ofBackground(0,0,0);
ofSetFrameRate(60);
ofSetVerticalSync(true);

player.loadMovie("fingers.mov");
player.play();
player.setVolume(0.0);

rgbaFboFloat.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGBA32F_ARB);
rgbaFboFloat.begin();
ofClear(255,255,255, 0);
rgbaFboFloat.end();

enableDepthTest = true;

}

//--------------------------------------------------------------
void testApp::update(){
ofEnableAlphaBlending();
player.update();
rgbaFboFloat.begin();
drawIntoFBO();
rgbaFboFloat.end();
}

//--------------------------------------------------------------
void testApp::draw(){

ofPushStyle();
ofFill();
ofSetColor(0,0,0, fadeAmnt);
ofRect(0,0,ofGetWindowWidth(),ofGetWindowHeight());
ofPopStyle();

rgbaFboFloat.draw(0,0);
}


//--------------------------------------------------------------
void testApp::drawIntoFBO(){
ofClear(0,0,0, 0);

fadeAmnt = 40;

/*
//1 - Fade Fbo

//this is where we fade the fbo
//by drawing a rectangle the size of the fbo with a small alpha value, we can slowly fade the current contents of the fbo.

ofPushStyle();
ofFill();
ofSetColor(0,0,0, fadeAmnt);
ofRect(0,0,ofGetWindowWidth(),ofGetWindowHeight());
ofPopStyle();
*/

if (enableDepthTest) {
    ofEnableDepthTest();
}

//2 - Draw graphics

float movementSpeed = .1;
float cloudSize = ofGetWidth() / 2;
float maxBoxSize = 100;
float spacing = 1;

cam.begin();

for(int i = 0; i < 20; i++) {
    
	ofPushMatrix();
	
	float t = (ofGetElapsedTimef() + i * spacing) * movementSpeed;
	ofVec3f pos(
                ofSignedNoise(t, 0, 0),
                ofSignedNoise(0, t, 0),
                ofSignedNoise(0, 0, t));
	
	float boxSize = maxBoxSize * ofNoise(pos.x, pos.y, pos.z);
	
	pos *= cloudSize;
	ofTranslate(pos);
    ofPushStyle();
    ofEnableNormalizedTexCoords();
    player.getTextureReference().bind();
	ofFill();
	
    ofDrawBox(boxSize);

    player.getTextureReference().unbind();
    ofDisableNormalizedTexCoords();
    ofPopStyle();
	ofPopMatrix();
}
cam.end();


if (enableDepthTest) {
    ofDisableDepthTest();
}

}

void testApp::keyPressed(int key){
if(key=='d'){
    enableDepthTest = !enableDepthTest;
}
}

Thank you again! If there are any modifications you think that might help this, or a better way to implement this, I’d appreciate the advice!