-
-
Save roxlu/2622978 to your computer and use it in GitHub Desktop.
| #include "testApp.h" | |
| const string SHADER_VS = " \ | |
| uniform mat4 projection_matrix; \ | |
| uniform mat4 view_matrix; \ | |
| attribute vec4 pos; \ | |
| attribute vec2 tex; \ | |
| varying vec2 vtex; \ | |
| \ | |
| void main() { \ | |
| gl_Position = projection_matrix * view_matrix * pos; \ | |
| vtex = tex; \ | |
| }"; | |
| const string SHADER_FS = " \ | |
| uniform sampler2D tex_caustic; \ | |
| uniform sampler2D tex_flow; \ | |
| uniform sampler2D tex_color;\ | |
| uniform float time; \ | |
| varying vec2 vtex;\ | |
| \ | |
| void main() {\ | |
| float s = time * 0.1; \ | |
| vec4 color_flow = texture2D(tex_flow, vec2(vtex.s + s, vtex.t)); \ | |
| vec2 flowmap = (color_flow.rg * 2.0 - 1.0) * 0.1; \ | |
| vec4 caustic = texture2D(tex_caustic, vec2(vtex.s +(flowmap.s*2.2), vtex.t +(flowmap.t*1.2))); \ | |
| vec4 color_img = texture2D(tex_color, vec2(vtex.s, vtex.t + flowmap.t)); \ | |
| gl_FragColor = color_img + color_img * (caustic * 1.1); \ | |
| gl_FragColor.a = 0.1 + caustic.r; \ | |
| }"; | |
| testApp::testApp() | |
| :gif(ofGetWidth(), ofGetHeight(), 8) | |
| { | |
| } | |
| //-------------------------------------------------------------- | |
| void testApp::setup(){ | |
| save_gif = false; | |
| ofBackground(22,33,44); | |
| ofSetVerticalSync(true); | |
| ofSetFrameRate(60); | |
| cam.setup(ofGetWidth(), ofGetHeight()); | |
| cam.translate(0,0,1); | |
| // Shader | |
| shader.create(SHADER_VS, SHADER_FS); | |
| glGetError(); | |
| shader.addUniform("projection_matrix") | |
| .addUniform("view_matrix") | |
| .addUniform("tex_caustic") | |
| .addUniform("tex_flow") | |
| .addUniform("tex_color") | |
| .addUniform("time"); | |
| shader.addAttribute("pos") | |
| .addAttribute("tex"); | |
| ofImage img; | |
| img.loadImage("caustic.png"); | |
| tex_caustic.setWrap(GL_REPEAT, GL_REPEAT); | |
| tex_caustic.setPixels(img.getPixels(), img.getWidth(), img.getHeight(), GL_RGB); | |
| img.loadImage("flowmap2.png"); | |
| tex_flow.setWrap(GL_REPEAT, GL_REPEAT); | |
| tex_flow.setPixels(img.getPixels(), img.getWidth(), img.getHeight(), GL_RGB); | |
| img.loadImage("diffuse4.png"); | |
| tex_color.setPixels(img.getPixels(), img.getWidth(), img.getHeight(), GL_RGB); | |
| // VBO + VAO | |
| glGenVertexArraysAPPLE(1, &vao); eglGetError(); | |
| glBindVertexArrayAPPLE(vao); eglGetError(); | |
| float w = 10.0f * 0.5; | |
| float h = 10.0f * 0.5; | |
| ptn.add(VertexPTN(-w,-h,0, 0,0,1, 1,1)); | |
| ptn.add(VertexPTN(w ,-h,0, 0,0,1, 0,1)); | |
| ptn.add(VertexPTN(w , h,0, 0,0,1, 0,0)); | |
| ptn.add(VertexPTN(-w, h,0, 0,0,1, 1,0)); | |
| glGenBuffers(1, &vbo); eglGetError(); | |
| glBindBuffer(GL_ARRAY_BUFFER, vbo); eglGetError(); | |
| glBufferData(GL_ARRAY_BUFFER, ptn.numBytes(), ptn.getPtr(), GL_STATIC_DRAW); eglGetError(); | |
| glEnableVertexAttribArray(shader.getAttribute("pos")); eglGetError(); | |
| glEnableVertexAttribArray(shader.getAttribute("tex")); eglGetError(); | |
| glVertexAttribPointer(shader.getAttribute("pos"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexPTN), (GLvoid*)offsetof(VertexPTN, pos)); eglGetError(); | |
| glVertexAttribPointer(shader.getAttribute("tex"), 2, GL_FLOAT, GL_FALSE, sizeof(VertexPTN), (GLvoid*)offsetof(VertexPTN, tex)); eglGetError(); | |
| } | |
| //-------------------------------------------------------------- | |
| void testApp::draw(){ | |
| glEnable(GL_BLEND); | |
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
| float t = ofGetElapsedTimeMillis() * 0.001; | |
| shader.enable(); | |
| shader.uniformMat4fv("projection_matrix", cam.pm().getPtr()); | |
| shader.uniformMat4fv("view_matrix", cam.vm().getPtr()); | |
| shader.uniform1f("time", t); | |
| // Texture 0 = caustics | |
| shader.uniform1i("tex_caustic", 0); | |
| glActiveTexture(GL_TEXTURE0); | |
| glBindTexture(GL_TEXTURE_2D, tex_caustic.getID()); | |
| // Texture 1 = flow | |
| shader.uniform1i("tex_flow", 1); | |
| glActiveTexture(GL_TEXTURE1); | |
| glBindTexture(GL_TEXTURE_2D, tex_flow.getID()); | |
| // Texture 2 = color | |
| shader.uniform1i("tex_color", 2); | |
| glActiveTexture(GL_TEXTURE2); | |
| glBindTexture(GL_TEXTURE_2D, tex_color.getID()); | |
| // draw | |
| glBindVertexArrayAPPLE(vao); eglGetError(); | |
| glDrawArrays(GL_QUADS, 0, 4); eglGetError(); | |
| if(save_gif && ofGetFrameNum() % 5 == 0) { | |
| ofImage img; | |
| img.grabScreen(0,0,ofGetWidth(), ofGetHeight()); | |
| gif.addFrame(img.getPixels()); | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void testApp::keyPressed(int key){ | |
| if(key == 'g') { | |
| save_gif = !save_gif; | |
| } | |
| else if(key == 's') { | |
| save_gif = false; | |
| string time = ofGetTimestampString(); | |
| string file = ofToDataPath("water_" +time +".gif", true); | |
| gif.save(file.c_str()); | |
| } | |
| } |
| #pragma once | |
| #include "ofMain.h" | |
| #include "Roxlu.h" | |
| #include "VertexBuffer.h" | |
| #include "Gif.h" | |
| using namespace roxlu; | |
| class testApp : public ofBaseApp{ | |
| public: | |
| testApp(); | |
| void setup(); | |
| void update(); | |
| void draw(); | |
| void keyPressed(int key); | |
| void keyReleased(int key); | |
| void mouseMoved(int x, int y); | |
| 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 windowResized(int w, int h); | |
| void dragEvent(ofDragInfo dragInfo); | |
| void gotMessage(ofMessage msg); | |
| GLuint vbo; | |
| GLuint vao; | |
| VertexBufferPTN ptn; | |
| Shader shader; | |
| EasyCam cam; | |
| Texture tex_caustic; | |
| Texture tex_flow; | |
| Texture tex_color; | |
| Gif gif; | |
| bool save_gif; | |
| }; |
Hey roxlu,
I'm taking a look at some of your examples (which are badass by the way), but I've run into a few classes/headers I can't seem to find, namely:
VertexBuffer.h
Gif.h
I'm a noob to openFrameworks, but not coding, so forgive me if this is obvious.
Thanks,
sean zehnder
Hi Sean, thanks for your complements! This snippet isn't supposed to be use a drop in for your app, but it roughly shows you how to use a flow map in a shader. I'm happy to explain more about the way it works, send me a mail/message. In short, it uses a texture (the flowmap) which manipulates the texture coordinates of something you want to draw. If you want to use this you can use a ofShader and textures. Only thing, make sure to call ofEnableNormalizedTexCoords().
Best,
Roxlu
Nice example roxlu
Result:

Caustic:

Flowmap (texcoord displacement)

Diffuse
