How to: ofMesh and ofFbo => ofShader = distorted ofMesh GLSL

Hello everyone. I need a bit of help learning this (I’ve been reading the orange book this week)

My purpose here is to make something like a terrain shaper. You would draw in an ofFbo by dragging the mouse and the ofMesh follows, distorting the height of all vertex by using the texture that was drawn.

How does one manage this? I tried for a few hourse but my ofMesh remained static and the ofFbo cleared on every click which is not good. I think I am confused with the floating point and non FP coordenates too.

I’ve managed to make the shader that draws onto the ofFbo and I have yet to setup a ping pong algorithm.
I’ve also uploaded the source and the fragment and vertex.

Another question, the picture here shows a strange character pattern I get when I pass the setUniformTexture with a Texture Location of 0, why is this?

Here is the code as a post:
testApp.h

  
#pragma once  
  
#include "ofMain.h"  
  
class testApp : public ofBaseApp{  
public:  
    void setup();  
    void update();  
    void draw();  
  
    void keyPressed  (int key);  
    void mouseDragged(int x, int y, int button);  
    void mousePressed(int x, int y, int button);  
    void mouseReleased(int x, int y, int button);  
    void addCircle(float x, float);  
  
    ofMesh          testMesh;  
    ofFbo           testFboA;  
    ofFbo           testFboB;  
    int             textureResolution;  
    int             meshResolution;  
    ofShader        circleShader;  
    bool            mouseClicked;  
  
};  
  

testApp.cpp

  
  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup(){  
  
    ofSetLogLevel(OF_LOG_VERBOSE);  
	ofBackground(100);  
	mouseClicked = false;  
  
    textureResolution = 256;  
    meshResolution = 32;  
  
    circleShader.load("circleShader.vert", "circleShader.frag");  
    testFboA.allocate( textureResolution, textureResolution, GL_LUMINANCE32F_ARB);  
    testFboB.allocate( textureResolution, textureResolution, GL_LUMINANCE32F_ARB);  
  
    for (int row = 0; row < meshResolution; row++) {  
        for (int col = 0; col < meshResolution; col++) {  
            float reSizeFactor = ( ( (float)textureResolution ) / ( (float)meshResolution-1 ) );  
            float xPos =( (float)col )*reSizeFactor-textureResolution/2;  
            float yPos =( (float)row )*reSizeFactor-textureResolution/2;  
            testMesh.addVertex( ofPoint( xPos, yPos, 0.0f));  
        }  
    }  
    int maxIndexValue = meshResolution*(meshResolution-1)-1;  
    for (int i = 0; i < maxIndexValue; i++){  
        float sideValue = (i+1)%meshResolution;  
        if ( sideValue ==  0) continue;  
        testMesh.addTriangle(                i,                i+1, meshResolution+i );  
        testMesh.addTriangle( meshResolution+i, meshResolution+i+1,              i+1 );  
	}  
  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
  
    if(mouseClicked == true){  
        // Conversion of mouse int screen coordenates to [-1,1] floating point.  
        float posX = ((float)(mouseX))/1024;  
        float posY = ((float)(mouseY))/1024;  
        addCircle( 2*posX-1, 2*posY-1);  
    }  
  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
    ofSetColor(255);  
    ofPushMatrix();  
        ofTranslate(ofGetWindowWidth()/2,ofGetWindowHeight()/2+200);  
        ofRotateX(75);  
        ofScale( 2, 2, 2);  
  
        ofPushMatrix();  
            ofTranslate(0,0,0);  
            testFboA.draw(-128,-128);  
        ofPopMatrix();  
  
        ofPushMatrix();  
            ofTranslate(0,0,100);  
            testMesh.drawWireframe();  
        ofPopMatrix();  
    ofPopMatrix();  
  
    ofDrawBitmapString("Fps: " + ofToString( ofGetFrameRate()), 15,15);  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed(int key){  
  
}  
  
//--------------------------------------------------------------  
void testApp::mouseDragged(int x, int y, int button){  
  
}  
  
//--------------------------------------------------------------  
void testApp::mousePressed(int x, int y, int button){  
    mouseClicked = true;  
}  
  
//--------------------------------------------------------------  
void testApp::mouseReleased(int x, int y, int button){  
    mouseClicked = false;  
}  
  
//--------------------------------------------------------------  
void testApp::addCircle(float x, float y){  
  
    testFboA.begin();  
        ofClear(0);  
        circleShader.begin();  
            circleShader.setUniformTexture("texture", testFboB,0);  
            circleShader.setUniform2f("center", x, y);  
            testMesh.draw();  
            testFboB.draw(0,0);  
        circleShader.end();  
    testFboA.end();  
  
}  
  

circleShader.vert

  
  
varying vec2 coords;  
  
void main() {  
	coords = gl_Vertex.xy;  
	gl_Position = vec4(coords, 1.0, 1.0);  
}  

circleShader.frag

  
uniform sampler2D texture;  
uniform vec2 center;  
varying vec2 coords;  
  
void main(){  
	vec4 valueRed = texture2D(texture, coords);  
	float distance = 1-length(center - coords);  
	distance = sin(distance * 3.1416);  
	valueRed.r += distance;  
	gl_FragColor = valueRed;  
}  

Terrain_ofMesh_ofFBO.zip

I’ve been playing around with the examples from 0.7.4. I’m really amazed at what you can do with all of this but so far I’ve yet to find an example similar to what I am trying to try out.

the ofVbomesh is great and I’ve also played with the pingPongBuffer struct.
Anyway… any help? :smiley:

Also, I’ve noticed some examples have no vertex shader. Isn’t this a requirement?

Thanks!

I didn’t notice where you are offsetting the mesh vertex position. If you want to offset the vertices in a shader, then you will have to use a shader while drawing the mesh, which is outlined in the link below. Or you might want to just get the pixel value from the fbo and then use that to offset the mesh vertices.
This post has proved helpful to me in the past:
http://www.gamedev.net/topic/475213-generate-normal-map-from-heightmap-algorithm/

Thanks NickHardeman
I’ve been confused about how all this works but I think I’m closer with that thread.
I’ll post the example back when I get it working just to help anyone out. :smiley:
Thanks again.

I’m finally getting this to work but I do have one question about the:

  
void setUniformTexture(const char* name, ofBaseHasTexture& img, int textureLocation);  

  
circleShader.setUniformTexture("texture", testFboB,  0);    

When I put 0 as the textureLocation I get that weird openGL pattern with the characters and stuff. When I use 1 I don’t get that pattern. Should the location start at 0?
What is that pattern? I’ve seen it before but I can’t remember where.

-edit->
Another question, I’ve managed to do some stuff but in it seems the GLSL compiler is very very strick, it didn’t compile a floating point 0 because I had to use 0.0 instead.
How do you guys debug shaders? Is there any good newby application for debugging shaders?

The shader might not be finding the texture correctly. Try passing in the texture used by the fbo

  
circleShader.setUniformTexture("texture", testFboB.getTextureReference(),  0);  

Actually I was refering to the 0 at the end of the setUniformTexture but some other thread mentions that that is where one wants the texture to be positioned, it may be wrong I don’t know.
Anyways I am really interested in learning GLSL so I think I’ll take a few days to start from scratch and read up on all threads and your link.

edited…
So I managed to do what I wanted by looking at this example. It also turns out that I hadn’t assigned texture coordenates so the initial code is somewhat useless.
Anyone wanting to do just review this:
https://sites.google.com/site/ofauckland/examples/7-bumpmap-displacement-shader

Remember to make a mesh with .addVertex(), .addTexCoord() and .addIndex(). Use addNormal() to define orientation of the displacement (I think that is what it is called).