#include "ofApp.h"
void ofApp::setup(){
particleSize = 30.0f;
timeStep = 0.005f;
numParticles = 1000;
width = ofGetWindowWidth();
height = ofGetWindowHeight();
string shadersFolder;
if(ofIsGLProgrammableRenderer()){
shadersFolder="shaders_gl3";
}else{
shadersFolder="shaders";
}
if(ofIsGLProgrammableRenderer()){
updatePos.load(shadersFolder+"/passthru.vert", shadersFolder+"/posUpdate.frag");
updateVel.load(shadersFolder+"/passthru.vert", shadersFolder+"/velUpdate.frag");
}else{
updatePos.load("",shadersFolder+"/posUpdate.frag");
updateVel.load("",shadersFolder+"/velUpdate.frag");
}
updateRender.setGeometryInputType(GL_POINTS);
updateRender.setGeometryOutputType(GL_TRIANGLE_STRIP);
updateRender.setGeometryOutputCount(6);
updateRender.load(shadersFolder+"/render.vert",shadersFolder+"/render.frag",shadersFolder+"/render.geom");
textureRes = (int)sqrt((float)numParticles);
numParticles = textureRes * textureRes;
vector<float> pos(numParticles*3);
for (int x = 0; x < textureRes; x++){
for (int y = 0; y < textureRes; y++){
int i = textureRes * y + x;
pos[i*3 + 0] = ofRandom(1.0);
pos[i*3 + 1] = ofRandom(1.0);
pos[i*3 + 2] = 0.0;
}
}
posPingPong.allocate(textureRes, textureRes, GL_RGB32F);
posPingPong.src->getTexture().loadData(pos.data(), textureRes, textureRes, GL_RGB);
posPingPong.dst->getTexture().loadData(pos.data(), textureRes, textureRes, GL_RGB);
vector<float> vel(numParticles*3);
for (int i = 0; i < numParticles; i++){
vel[i*3 + 0] = ofRandom(-1.0,1.0);
vel[i*3 + 1] = ofRandom(-1.0,1.0);
vel[i*3 + 2] = 1.0;
}
velPingPong.allocate(textureRes, textureRes, GL_RGB32F);
velPingPong.src->getTexture().loadData(vel.data(), textureRes, textureRes, GL_RGB);
velPingPong.dst->getTexture().loadData(vel.data(), textureRes, textureRes, GL_RGB);
sparkImg.load("spark.png");
imgWidth = sparkImg.getWidth();
imgHeight = sparkImg.getHeight();
renderFBO.allocate(width, height, GL_RGB32F);
renderFBO.begin();
ofClear(0, 0, 0, 255);
renderFBO.end();
mesh.setMode(OF_PRIMITIVE_POINTS);
for(int x = 0; x < textureRes; x++){
for(int y = 0; y < textureRes; y++){
mesh.addVertex({x,y,0});
mesh.addTexCoord({x, y});
}
}
}
void ofApp::update(){
velPingPong.dst->begin();
ofClear(0);
updateVel.begin();
updateVel.setUniformTexture("backbuffer", velPingPong.src->getTexture(), 0);
updateVel.setUniformTexture("posData", posPingPong.src->getTexture(), 1);
updateVel.setUniform1i("resolution", (int)textureRes);
updateVel.setUniform2f("screen", (float)width, (float)height);
updateVel.setUniform1f("timestep", (float)timeStep);
velPingPong.src->draw(0, 0);
updateVel.end();
velPingPong.dst->end();
velPingPong.swap();
posPingPong.dst->begin();
ofClear(0);
updatePos.begin();
updatePos.setUniformTexture("prevPosData", posPingPong.src->getTexture(), 0);
updatePos.setUniformTexture("velData", velPingPong.src->getTexture(), 1);
updatePos.setUniform1f("timestep",(float) timeStep );
posPingPong.src->draw(0, 0);
updatePos.end();
posPingPong.dst->end();
posPingPong.swap();
renderFBO.begin();
ofClear(0,0,0,0);
updateRender.begin();
updateRender.setUniformTexture("posTex", posPingPong.dst->getTexture(), 0);
updateRender.setUniformTexture("sparkTex", sparkImg.getTexture() , 1);
updateRender.setUniform1i("resolution", (float)textureRes);
updateRender.setUniform2f("screen", (float)width, (float)height);
updateRender.setUniform1f("size", (float)particleSize);
updateRender.setUniform1f("imgWidth", (float)sparkImg.getWidth());
updateRender.setUniform1f("imgHeight", (float)sparkImg.getHeight());
ofPushStyle();
ofEnableBlendMode( OF_BLENDMODE_ADD );
ofSetColor(255);
mesh.draw();
ofDisableBlendMode();
glEnd();
updateRender.end();
renderFBO.end();
ofPopStyle();
}
void ofApp::draw(){
ofBackground(0);
ofSetColor(100,255,255);
renderFBO.draw(0,0);
ofSetColor(255);
ofDrawBitmapString("Fps: " + ofToString( ofGetFrameRate()), 15,15);
}
void ofApp::keyPressed(int key){
}
void ofApp::keyReleased(int key){
}
void ofApp::mouseMoved(int x, int y ){
}
void ofApp::mouseDragged(int x, int y, int button){
}
void ofApp::mousePressed(int x, int y, int button){
}
void ofApp::mouseReleased(int x, int y, int button){
}
void ofApp::mouseEntered(int x, int y){
}
void ofApp::mouseExited(int x, int y){
}
void ofApp::windowResized(int w, int h){
}
void ofApp::gotMessage(ofMessage msg){
}
void ofApp::dragEvent(ofDragInfo dragInfo){
}
Comments