Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created May 6, 2012 15:37
Show Gist options
  • Save roxlu/2622978 to your computer and use it in GitHub Desktop.
Save roxlu/2622978 to your computer and use it in GitHub Desktop.
Caustic simulation / shaders - openFrameworks
#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;
};
@roxlu
Copy link
Author

roxlu commented May 6, 2012

Result:

Caustic:

Flowmap (texcoord displacement)

Diffuse

@szehnder
Copy link

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

@roxlu
Copy link
Author

roxlu commented Jul 14, 2012

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

@emmanuelflores
Copy link

Nice example roxlu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment