Created
February 4, 2012 11:54
-
-
Save roxlu/1737415 to your computer and use it in GitHub Desktop.
Shaders, vbo, fbo and vao
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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