Skip to content

Instantly share code, notes, and snippets.

@mantissa
Created April 26, 2015 19:26
Show Gist options
  • Save mantissa/8f390d497b52c601b9ce to your computer and use it in GitHub Desktop.
Save mantissa/8f390d497b52c601b9ce to your computer and use it in GitHub Desktop.
Drawing instanced meshes using matrices contained in textures (OpenFrameworks)
#version 120
#extension GL_EXT_gpu_shader4 : require
void main(){
gl_FragColor = gl_Color;
}
#version 120
#extension GL_EXT_gpu_shader4 : require
uniform sampler2DRect matrixTexture;
uniform sampler2DRect colorTexture;
uniform mat4 mvpMatrix;
void main(){
float y = 0;
float x = gl_InstanceID*4;
mat4 transformMatrix = mat4(
texture2DRect(matrixTexture, vec2((x+0.5), y+0.5)),
texture2DRect(matrixTexture, vec2((x+1.5), y+0.5)),
texture2DRect(matrixTexture, vec2((x+2.5), y+0.5)),
texture2DRect(matrixTexture, vec2((x+3.5), y+0.5)));
// Multiply the shape coordinates by the transformation matrix
// Offset by the position
vec4 vPos = transformMatrix * gl_Vertex;
// Set the front color to the color passed through with glColor
gl_FrontColor = texture2DRect(colorTexture, vec2((gl_InstanceID+0.5), 0.5));
gl_BackColor = gl_FrontColor;
// Multiply by the model view and projection matrix
gl_Position = mvpMatrix * vPos;
}
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofEnableDepthTest();
ofSetFrameRate(60);
// create a mesh
ofBoxPrimitive box;
box.set(5);
mesh = box.getMesh();
instancingShader.load("DrawInstances");
// how many shapes
nShapes = 300;
// create matrix texture (16 elements per shape)
// and color texture (4 elements per shape)
matrixTexture.allocate(nShapes*4, 1, OF_IMAGE_COLOR_ALPHA);
colorTexture.allocate(nShapes, 1, OF_IMAGE_COLOR_ALPHA);
// create the colors
unsigned char * shapePix = colorTexture.getPixels();
for(int i=0; i<nShapes; i++){
shapePix[i*4] = ofRandom(255);
shapePix[i*4+1] = ofRandom(255);
shapePix[i*4+2] = ofRandom(255);
shapePix[i*4+3] = 255;
}
colorTexture.update();
}
//--------------------------------------------------------------
void ofApp::update(){
float * matPix = matrixTexture.getPixels();
float t = ofGetElapsedTimef();
for(int i=0; i<nShapes; i++){
// create a matrix for each shape
// animate position, orientation and scale using perlin noise
ofVec3f pos;
pos.x = ofNoise(0.001*t, i+0) * 100 -50;
pos.y = ofNoise(0.001*t, i+10) * 100 -50;
pos.z = ofNoise(0.001*t, i+20) * 100 -50;
float angle = ofNoise(0.05*t, i+60) * 360;
ofVec3f axis;
axis.x = ofNoise(0.02*t, i+30);
axis.y = ofNoise(0.02*t, i+40);
axis.z = ofNoise(0.02*t, i+50);
float scale = ofNoise(0.02*t, i+70) * 2.0 + 0.5;
ofMatrix4x4 mat = ofMatrix4x4::newTranslationMatrix(ofVec3f());
mat.rotate(angle, axis.x, axis.y, axis.z);
mat.scale(scale, scale, scale);
mat.translate(pos);
// update the elements of the matrix
// in the texture
float * ptr = mat.getPtr();
int p = i * 16;
for(int j=0; j<16; j++){
matPix[p+j] = ptr[j];
}
}
matrixTexture.update();
}
//--------------------------------------------------------------
void ofApp::draw(){
float t = ofGetElapsedTimef();
// rotate camera based on time
ofVec3f camPos;
camPos.x = cos(t*3*DEG_TO_RAD ) * 100;
camPos.z = sin(t*3*DEG_TO_RAD ) * 100;
cam.setPosition( camPos );
cam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, 1, 0));
cam.begin();
instancingShader.begin();
// set the mvp matrix
// set transformation texture (mat4)
// set color texture
GLuint matLoc = glGetUniformLocation(instancingShader.getProgram(), "mvpMatrix");
ofMatrix4x4 mvpMatrix = cam.getModelViewProjectionMatrix();
if( matLoc != -1 ) glUniformMatrix4fv(matLoc, 1, GL_FALSE, mvpMatrix.getPtr());
instancingShader.setUniformTexture("matrixTexture", matrixTexture.getTextureReference(), 0);
instancingShader.setUniformTexture("colorTexture", colorTexture.getTextureReference(), 1);
mesh.drawInstanced( OF_MESH_FILL, nShapes );
instancingShader.end();
mesh.draw();
cam.end();
}
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
int nShapes;
ofVboMesh mesh;
ofShader instancingShader;
ofFloatImage matrixTexture;
ofImage colorTexture;
ofCamera cam;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment