-
-
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
