Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created February 4, 2012 21:10
Show Gist options
  • Select an option

  • Save roxlu/1740161 to your computer and use it in GitHub Desktop.

Select an option

Save roxlu/1740161 to your computer and use it in GitHub Desktop.
Light rays
#include "Cards.h"
Cards::Cards(rb::World& w)
:world(w)
{
}
Cards::~Cards() {
}
void Cards::create() {
ofEnableNormalizedTexCoords();
vao.bind();
// create the shader and set uniforms + attributes we need.
shader.load("simple");
shader.enable();
// @todo maybe automatically add attributes + uniforms (?)
shader.addAttribute("pos");
shader.addAttribute("tex");
shader.addUniform("diffuse_texture");
shader.addUniform("projection_matrix");
shader.addUniform("modelview_matrix");
shader.addUniform("mode");
// light rays uniforms
shader.addUniform("exposure")
.addUniform("decay")
.addUniform("density")
.addUniform("weight")
.addUniform("lightPositionOnscreen");
shader.uniform1f("exposure", 0.0034f);
shader.uniform1f("decay", 0.99f);
shader.uniform1f("density", 0.84f);
shader.uniform1f("weight", 19.56f);
shader.uniform2f("lightPositionOnScreen", 0.5, 0.5);
shader.enableVertexAttribArray("tex");
shader.enableVertexAttribArray("pos");
// create vertex data for VBO
float s = 0.5;
vd.addVertex(-s, s, 0);
vd.addVertex(s, s, 0);
vd.addVertex(s,-s, 0);
vd.addVertex(-s,-s, 0);
vd.addTexCoord(0,0);
vd.addTexCoord(1,0);
vd.addTexCoord(1,1);
vd.addTexCoord(0,1);
vbo.setVertexData(vd.getVertexPT(), vd.size());
vbo.bind();
vbo.setPosVertexAttribPointer(shader.getAttribute("pos"));
vbo.setTexVertexAttribPointer(shader.getAttribute("tex"));
// we create one collision shape and reuse this for all rigid bodies (cards)
box_shape = world.createBoxShape(0.4, 0.4, 0.01);
// create te cards
int num_cards = 200;
float r = 15;
for(int i = 0; i < num_cards; ++i) {
rbb::Box* box = world.createBoxBody(box_shape, Vec3(ofRandom(-r,r),ofRandom(-r,r),ofRandom(-r,r)), 3.0f);
Card* c = new Card(box);
cards.push_back(c);
}
// load texture
ofImage img;
img.loadImage("diederick2.png");
tex.setPixels(img.getPixels(), img.getWidth(), img.getHeight(), GL_RGBA);
// set our texture to to unit 0
glActiveTexture(GL_TEXTURE0);
tex.bind();
shader.uniform1i("diffuse_texture", 0);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
vbo.unbind();
vao.unbind();
// Create a FBO to grab the scene
raw_fbo.setup(ofGetWidth(), ofGetHeight());
raw_fbo.addTexture(0);
// Plane vbo we render the FBO onto.
Plane::create(1.9,1.9,plane_vd);
plane_vao.bind();
plane_vbo.bind();
shader.enableVertexAttribArray("tex");
shader.enableVertexAttribArray("pos");
plane_vbo.setVertexData(plane_vd.getVertexPT(), plane_vd.size());
glVertexAttribPointer(shader.getAttribute("pos"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexPT), (GLvoid*)offsetof(VertexPT, pos)); eglGetError();
glVertexAttribPointer(shader.getAttribute("tex"), 2, GL_FLOAT, GL_FALSE, sizeof(VertexPT), (GLvoid*)offsetof(VertexPT, tex)); eglGetError();
plane_vbo.unbind();
}
void Cards::update() {
vector<Card*>::iterator it = cards.begin();
while(it != cards.end()) {
(*it)->update();
++it;
}
}
void Cards::drawCards(const Mat4& projectionMatrix, const Mat4& viewMatrix, const int& drawMode) {
shader.uniform1i("mode", drawMode);
tex.bind();
vao.bind();
Mat4 modelview;
vector<Card*>::iterator it = cards.begin();
while(it != cards.end()) {
Card* card = (*it);
modelview = viewMatrix * card->model_matrix;
shader.uniformMat4fv("modelview_matrix", modelview.getPtr());
glDrawArrays(GL_QUADS, 0, 4);
++it;
}
shader.disable();
}
/**
*
* Some important things to remember:
* -----------------------------------
* - make sure to disable depth test because we're merging two planes
* using a blend mode and the planes (plane_vbo/vao) is at the same position).
*
* - use a blend function to blend textures together.
* - we use a identity matrix and a plane with a with these dimensions
* (normalized)
*
*
* -1,1 1,1
* ----------
* | |
* | |
* | |
* | |
* | |
* ----------
* -1,-1 1,-1
*
*
* then when using a identity matrix for the projection we can align this
* nicely onto the window, in such a way is fills up the complete screen.
*
*/
void Cards::draw(const Mat4& projectionMatrix, const Mat4& viewMatrix) {
glDisable(GL_BLEND);
glClearColor(0,0,0,0.0);
shader.enable();
shader.uniformMat4fv("projection_matrix", projectionMatrix.getPtr());
// First pass: draw the cards
// -----------------------------------------------------
raw_fbo.begin();
drawCards(projectionMatrix, viewMatrix, 2);
raw_fbo.end();
// Second pass: apply light rays.
// --------------------------------------------------------
Mat4 ident;
shader.enable();
shader.uniformMat4fv("projection_matrix", ident.getPtr());
shader.uniformMat4fv("modelview_matrix", ident.getPtr());
plane_vao.bind();
shader.uniform1i("mode", 3);
raw_fbo.bindTexture(0);
glDrawArrays(GL_QUADS, 0, 4); // REF: RENDER_RAYS
// Draw cards (which are rendered to texture on a quad
// ---------------------------------------------------
// these blend and depth test settings are pretty important here.
// Because we're drawing directly over RENDER_RAYS (see comment above)
// we need to disable the depth test.
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
plane_vao.bind();
shader.enable();
shader.uniform1i("mode", 2);
raw_fbo.bindTexture(0);
glDrawArrays(GL_QUADS, 0, 4);
// ok, just draw the plane
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
shader.uniform1i("mode", 4);
glDrawArrays(GL_QUADS, 0, 4);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // reset
}
varying vec2 tex_v;
uniform sampler2D diffuse_texture;
uniform int mode;
// ray of light
// -----------------
/*
uniformExposure = 0.0034f;
uniformDecay = 1.0f;
uniformDensity = 0.84f;
uniformWeight = 5.65f;
*/
uniform float exposure;
uniform float decay;
uniform float density;
uniform float weight;
uniform vec2 lightPositionOnScreen;
const int NUM_SAMPLES = 300 ;
//----------------------
void main() {
if(mode == 1) {
gl_FragColor.rgba = vec4(1.0, 1.0, 1.0, 1.0);
}
else if(mode == 2) {
gl_FragColor = texture2D(diffuse_texture, tex_v);
}
else if(mode == 3) {
vec2 deltaTextCoord = vec2(tex_v - lightPositionOnScreen.xy );
vec2 textCoo = tex_v;
deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
float illuminationDecay = 1.0;
for(int i=0; i < NUM_SAMPLES ; i++) {
textCoo -= deltaTextCoord;
vec4 sample = texture2D(diffuse_texture, textCoo );
sample *= illuminationDecay * weight;
gl_FragColor += sample;
illuminationDecay *= decay;
}
gl_FragColor *= exposure;
}
else if(mode == 4) {
// gl_FragColor = texture2D(diffuse_texture, tex_v);
gl_FragColor.rgb = vec3(1.0, 1.0, 1.0);
gl_FragColor.a = 1.0;
}
}
attribute vec4 pos;
attribute vec2 tex;
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
varying vec2 tex_v;
void main() {
tex_v = tex;
gl_Position = (projection_matrix * modelview_matrix * pos);
}
@roxlu
Copy link
Author

roxlu commented Feb 4, 2012

Result

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