diff --git a/zoneb/addons.make b/zoneb/addons.make index ff15376..87ad7a9 100644 --- a/zoneb/addons.make +++ b/zoneb/addons.make @@ -1,3 +1,4 @@ ofxAzureKinect +ofxGpuParticles ofxV4L2 ofxShader diff --git a/zoneb/bin/data/shaders/particles/draw.frag b/zoneb/bin/data/shaders/particles/draw.frag new file mode 100755 index 0000000..460e7f3 --- /dev/null +++ b/zoneb/bin/data/shaders/particles/draw.frag @@ -0,0 +1,17 @@ +uniform sampler2DRect particles0; +uniform sampler2DRect particles1; +uniform sampler2DRect particles2; + +uniform sampler2DRect u_depth; +uniform sampler2DRect u_world; +uniform sampler2DRect u_v4l2cam; +uniform sampler2DRect imageTexture; + +in vec2 texCoordVarying; + +void main() +{ + fragColor = vec4(1);//vec4(texture(u_world, texCoordVarying.st).rgb,1); + // fragColor = vec4(texCoordVarying.st/100,1.0,1.0);//vec4(texture(u_world, texCoordVarying.st).rgb,1); + // fragColor = vec4(texture(imageTexture, texCoordVarying.st).rgb,1); +} diff --git a/zoneb/bin/data/shaders/particles/draw.vert b/zoneb/bin/data/shaders/particles/draw.vert new file mode 100755 index 0000000..cfcbc03 --- /dev/null +++ b/zoneb/bin/data/shaders/particles/draw.vert @@ -0,0 +1,15 @@ +uniform mat4 modelViewProjectionMatrix; +uniform sampler2DRect particles0; +uniform sampler2DRect particles1; +uniform sampler2DRect particles2; + +in vec4 position; +in vec2 texcoord; + +out vec2 texCoordVarying; + +void main() +{ + texCoordVarying = texcoord; + gl_Position = modelViewProjectionMatrix * vec4(texture(particles0, texCoordVarying).xyz, 1.0); +} diff --git a/zoneb/bin/data/shaders/particles/update.frag b/zoneb/bin/data/shaders/particles/update.frag new file mode 100755 index 0000000..7582a5d --- /dev/null +++ b/zoneb/bin/data/shaders/particles/update.frag @@ -0,0 +1,69 @@ +#extension GL_ARB_explicit_attrib_location : enable + +// ping pong inputs +uniform sampler2DRect particles0; +uniform sampler2DRect particles1; +uniform sampler2DRect particles2; + +uniform sampler2DRect u_depth; +uniform sampler2DRect u_world; +uniform sampler2DRect u_v4l2cam; + +uniform ivec2 uFrameSize; +uniform ivec2 uDepthFrameSize; + +uniform vec3 mouse; +uniform float radiusSquared; +uniform float elapsed; + +in vec2 texCoordVarying; + +layout(location = 0) out vec4 posOut; +layout(location = 1) out vec4 velOut; +layout(location = 2) out vec4 misOut; + +void main() +{ + + float depth = texture(u_depth, texCoordVarying.st).x; + vec4 ray = texture(u_world, texCoordVarying.st); + + float vValid = (depth != 0 && ray.x != 0 && ray.y != 0) ? 1 : 0; + + if(depth < 0.012) vValid = 0; + if(depth > 0.04) vValid = 0; + + vec4 posWorld = vec4(1); + posWorld.z = -depth * 65535.0; // Remap to float range. + posWorld.x = ray.x * posWorld.z; + posWorld.y = ray.y * posWorld.z; + + vec3 pos = texture(particles0, texCoordVarying.st).xyz; + pos = posWorld.xyz; + vec3 vel = texture(particles1, texCoordVarying.st).xyz; + + // mouse attraction + vec3 direction = mouse - pos.xyz; + float distSquared = dot(direction, direction); + float magnitude = 500.0 * (1.0 - distSquared / radiusSquared); + vec3 force = step(distSquared, radiusSquared) * magnitude * normalize(direction); + + // gravity + force += vec3(0.0, -0.5, 0.0); + + // accelerate + vel += elapsed * force; + + // bounce off the sides + vel.x *= step(abs(pos.x), 512.0) * 2.0 - 1.0; + vel.y *= step(abs(pos.y), 384.0) * 2.0 - 1.0; + + // damping + vel *= 0.995; + + // move + pos += elapsed * vel; + + posOut = vec4(pos, 1.0); + velOut = vec4(vel, 0.0); +} \ No newline at end of file diff --git a/zoneb/bin/data/shaders/particles/update.vert b/zoneb/bin/data/shaders/particles/update.vert new file mode 100755 index 0000000..45e1b5c --- /dev/null +++ b/zoneb/bin/data/shaders/particles/update.vert @@ -0,0 +1,10 @@ +in vec4 position; +in vec2 texcoord; + +out vec2 texCoordVarying; + +void main() +{ + texCoordVarying = texcoord; + gl_Position = position; +} diff --git a/zoneb/src/ofApp.cpp b/zoneb/src/ofApp.cpp index 1758a96..4188ee6 100644 --- a/zoneb/src/ofApp.cpp +++ b/zoneb/src/ofApp.cpp @@ -55,8 +55,8 @@ void ofApp::setupThermal() void ofApp::setup() { - ofDisableArbTex(); - ofSetVerticalSync(false); + // ofDisableArbTex(); + // ofSetVerticalSync(false); //ofSetLogLevel(OF_LOG_VERBOSE); setupKinect(); @@ -72,6 +72,41 @@ void ofApp::setup() fbos.at("ofcam").allocate(ofGetWidth(), ofGetHeight(), GL_RGBA32F_ARB); gradient.load("gradient.png"); + + // 1,000,000 particles + unsigned w = 512; + unsigned h = 512; + + particles.init(w, h); + + particles.loadShaders("shaders/particles/update", "shaders/particles/draw"); + + float *particlePosns = new float[w * h * 4]; + for (unsigned y = 0; y < h; ++y) + { + for (unsigned x = 0; x < w; ++x) + { + unsigned idx = y * w + x; + particlePosns[idx * 4] = 400.f * x / (float)w - 200.f; // particle x + particlePosns[idx * 4 + 1] = 400.f * y / (float)h - 200.f; // particle y + particlePosns[idx * 4 + 2] = 0.f; // particle z + particlePosns[idx * 4 + 3] = 0.f; // dummy + } + } + particles.loadDataTexture(ofxGpuParticles::POSITION, particlePosns); + delete[] particlePosns; + + // initial velocities + particles.zeroDataTexture(ofxGpuParticles::VELOCITY); + + particles.whateverImages.insert({"u_depth", kinectDevice.getDepthTex()}); + particles.whateverImages.insert({"u_world", kinectDevice.getDepthToWorldTex()}); + particles.whateverImages.insert({"u_v4l2cam", v4l2Tex}); + particles.whateverImages.insert({"imageTexture", gradient.getTexture()}); + + // listen for update event to set additonal update uniforms + ofAddListener(particles.updateEvent, this, &ofApp::onParticlesUpdate); + ofAddListener(particles.drawEvent, this, &ofApp::onParticlesDraw); } void ofApp::exit() @@ -95,6 +130,23 @@ void ofApp::updateThermal() void ofApp::update() { updateThermal(); + + particles.update(); +} + +void ofApp::onParticlesUpdate(ofxShader &shader) +{ + ofVec3f mouse(ofGetMouseX() - .5f * ofGetWidth(), .5f * ofGetHeight() - ofGetMouseY(), 0.f); + shader.setUniform3fv("mouse", mouse.getPtr()); + shader.setUniform1f("elapsed", ofGetLastFrameTime()); + shader.setUniform1f("radiusSquared", 200.f * 200.f); + + shader.setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + shader.setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); +} + +void ofApp::onParticlesDraw(ofxShader &shader) +{ } void ofApp::drawKinect() @@ -155,34 +207,46 @@ void ofApp::drawDebug() void ofApp::draw() { ofBackground(0); - - if (kinectDevice.isStreaming()) - { - auto dtex = kinectDevice.getDepthTex(); - auto wtex = kinectDevice.getDepthToWorldTex(); - particleShader.setUniformTexture("u_depth", dtex); - particleShader.setUniformTexture("u_world", wtex); - particleShader.setUniformTexture("u_v4l2cam", v4l2Tex); - particleShader.setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); - particleShader.setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); - particleShader.render(); - - fbos.at("ofcam").begin(); - drawKinect(); - fbos.at("ofcam").end(); - - drawMain(); - boundShader.draw(0, 0); - } - + // int i = 3; // auto dtex = kinectDevice.getDepthTex(); // auto wtex = kinectDevice.getDepthToWorldTex(); - // particleShader.setUniformTexture("u_depth", dtex); - // particleShader.setUniformTexture("u_world", wtex); - // particleShader.setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); - // particleShader.setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); - // particleShader.render(); - // particleShader.draw(0, 0); + // particles.getUpdateShaderRef().setUniformTexture("u_depth", dtex, i++); + // particles.getUpdateShaderRef().setUniformTexture("u_world", wtex, i++); + // particles.getUpdateShaderRef().setUniformTexture("u_v4l2cam", v4l2Tex, i++); + // particles.getUpdateShaderRef().setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + // particles.getUpdateShaderRef().setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + + // i = 3; + // particles.getDrawShaderRef().setUniformTexture("u_depth", dtex, i++); + // particles.getDrawShaderRef().setUniformTexture("u_world", wtex, i++); + // particles.getDrawShaderRef().setUniformTexture("u_v4l2cam", v4l2Tex, i++); + // particles.getDrawShaderRef().setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + // particles.getDrawShaderRef().setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + if (kinectDevice.isStreaming()) + { + // auto dtex = kinectDevice.getDepthTex(); + // auto wtex = kinectDevice.getDepthToWorldTex(); + // particleShader.setUniformTexture("u_depth", dtex); + // particleShader.setUniformTexture("u_world", wtex); + // particleShader.setUniformTexture("u_v4l2cam", v4l2Tex); + // particleShader.setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + // particleShader.setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + // particleShader.render(); + + // fbos.at("ofcam").begin(); + // drawKinect(); + // fbos.at("ofcam").end(); + + // drawMain(); + // boundShader.draw(0, 0); + particles.whateverImages.at("u_depth") = kinectDevice.getDepthTex(); + particles.whateverImages.at("u_world") = kinectDevice.getDepthToWorldTex(); + particles.whateverImages.at("u_v4l2cam") = v4l2Tex; + + cam.begin(); + particles.draw(); + cam.end(); + } drawDebug(); } diff --git a/zoneb/src/ofApp.h b/zoneb/src/ofApp.h index 5cc116c..61ee0f2 100644 --- a/zoneb/src/ofApp.h +++ b/zoneb/src/ofApp.h @@ -6,6 +6,8 @@ #include "ofxShaderFilter.h" +#include "ofxGpuParticles.h" + #include "ofxV4L2.h" class ofApp @@ -35,6 +37,8 @@ public: void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); + void onParticlesUpdate(ofxShader &shader); + void onParticlesDraw(ofxShader &shader); private: ofxAzureKinect::Device kinectDevice; @@ -51,5 +55,7 @@ private: ofxV4L2 v4l2Cam; ofTexture v4l2Tex; - ofImage gradient; + ofFloatImage gradient; + + ofxGpuParticles particles; };