Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created February 4, 2012 11:54
Show Gist options
  • Select an option

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

Select an option

Save roxlu/1737415 to your computer and use it in GitHub Desktop.
Shaders, vbo, fbo and vao
#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 = 100;
float r = 5;
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("diederick.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(15,15,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 functoin to blend textures together.
*
*
*/
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.
// --------------------------------------------------------
plane_vao.bind();
shader.enable();
shader.uniform1i("mode", 3);
shader.uniformMat4fv("modelview_matrix", viewMatrix.getPtr());
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);
shader.uniformMat4fv("modelview_matrix", viewMatrix.getPtr());
raw_fbo.bindTexture(0);
glDrawArrays(GL_QUADS, 0, 4);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment