Browse Source

CircleSurface: refactoring for performance, wip

master
c-mendoza 8 years ago
parent
commit
2122f4bc8a
  1. 8
      example/bin/data/magslideshow_settings.xml
  2. 89
      example/bin/data/ofxpimapper.xml
  3. 279
      src/Surfaces/CircleSurface.cpp
  4. 17
      src/Surfaces/CircleSurface.h

8
example/bin/data/magslideshow_settings.xml

@ -1,14 +1,14 @@
<magSlideShow> <magSlideShow>
<Width>1280</Width> <Width>800</Width>
<Height>720</Height> <Height>600</Height>
<SlideDuration>2</SlideDuration> <!-- Optional default duration for each slide--> <SlideDuration>2</SlideDuration> <!-- Optional default duration for each slide-->
<Loop> <Loop>
<Type>PING-PONG</Type> <!-- NONE | NORMAL | PING-PONG --> <Type>NORMAL</Type> <!-- NONE | NORMAL | PING-PONG -->
<Count>0</Count> <!-- 0 = forever --> <Count>0</Count> <!-- 0 = forever -->
</Loop> </Loop>
<Transition> <Transition>
<Type>Dissolve</Type> <Type>Dissolve</Type>
<Duration>2</Duration> <Duration>3</Duration>
</Transition> </Transition>
<!-- NoResize | Native | Fit | FitProportionally | FillProportionally --> <!-- NoResize | Native | Fit | FitProportionally | FillProportionally -->
<ResizeOption>FitProportionally</ResizeOption> <ResizeOption>FitProportionally</ResizeOption>

89
example/bin/data/ofxpimapper.xml

@ -36,38 +36,38 @@
<surface type="5"> <surface type="5">
<vertices> <vertices>
<vertex> <vertex>
<x>387.000000000</x> <x>162.000000000</x>
<y>96.000000000</y> <y>96.000000000</y>
</vertex> </vertex>
<vertex> <vertex>
<x>862.290893555</x> <x>637.290893555</x>
<y>79.031463623</y> <y>79.031463623</y>
</vertex> </vertex>
<vertex> <vertex>
<x>830.286376953</x> <x>605.286376953</x>
<y>652.968627930</y> <y>652.968627930</y>
</vertex> </vertex>
<vertex> <vertex>
<x>405.000000000</x> <x>180.000000000</x>
<y>657.000000000</y> <y>657.000000000</y>
</vertex> </vertex>
</vertices> </vertices>
<texCoords> <texCoords>
<texCoord> <texCoord>
<x>0.224322945</x> <x>0.159322947</x>
<y>0.023645690</y> <y>0.055312362</y>
</texCoord> </texCoord>
<texCoord> <texCoord>
<x>0.774270892</x> <x>0.830520868</x>
<y>0.023645690</y> <y>0.055312362</y>
</texCoord> </texCoord>
<texCoord> <texCoord>
<x>0.774270892</x> <x>0.830520868</x>
<y>0.973813117</y> <y>0.938813090</y>
</texCoord> </texCoord>
<texCoord> <texCoord>
<x>0.224322945</x> <x>0.159322947</x>
<y>0.973813117</y> <y>0.938813090</y>
</texCoord> </texCoord>
</texCoords> </texCoords>
<source> <source>
@ -85,8 +85,8 @@
<y>46.077301025</y> <y>46.077301025</y>
</vertex> </vertex>
<vertex> <vertex>
<x>860.523620605</x> <x>887.000000000</x>
<y>247.922729492</y> <y>402.000000000</y>
</vertex> </vertex>
<vertex> <vertex>
<x>1379.000000000</x> <x>1379.000000000</x>
@ -126,20 +126,20 @@
<surface type="5"> <surface type="5">
<vertices> <vertices>
<vertex> <vertex>
<x>1276.000000000</x> <x>1364.000000000</x>
<y>204.000000000</y> <y>252.000000000</y>
</vertex> </vertex>
<vertex> <vertex>
<x>724.000000000</x> <x>742.000000000</x>
<y>387.000000000</y> <y>392.000000000</y>
</vertex> </vertex>
<vertex> <vertex>
<x>707.000000000</x> <x>795.000000000</x>
<y>809.000000000</y> <y>857.000000000</y>
</vertex> </vertex>
<vertex> <vertex>
<x>1284.000000000</x> <x>1372.000000000</x>
<y>708.000000000</y> <y>756.000000000</y>
</vertex> </vertex>
</vertices> </vertices>
<texCoords> <texCoords>
@ -168,4 +168,49 @@
<perspectiveWarping>1</perspectiveWarping> <perspectiveWarping>1</perspectiveWarping>
</properties> </properties>
</surface> </surface>
<surface type="5">
<vertices>
<vertex>
<x>341.000000000</x>
<y>222.000000000</y>
</vertex>
<vertex>
<x>341.000000000</x>
<y>990.000000000</y>
</vertex>
<vertex>
<x>1365.000000000</x>
<y>990.000000000</y>
</vertex>
<vertex>
<x>1365.000000000</x>
<y>222.000000000</y>
</vertex>
</vertices>
<texCoords>
<texCoord>
<x>0.016666668</x>
<y>0.006666641</y>
</texCoord>
<texCoord>
<x>0.536666691</x>
<y>0.006666641</y>
</texCoord>
<texCoord>
<x>0.536666691</x>
<y>0.526666641</y>
</texCoord>
<texCoord>
<x>0.016666668</x>
<y>0.526666641</y>
</texCoord>
</texCoords>
<source>
<source-type>image</source-type>
<source-name>image2.jpg</source-name>
</source>
<properties>
<perspectiveWarping>1</perspectiveWarping>
</properties>
</surface>
</surfaces> </surfaces>

279
src/Surfaces/CircleSurface.cpp

@ -26,83 +26,84 @@ void CircleSurface::setup() {
QuadSurface::setup(); QuadSurface::setup();
setPerspectiveWarping(true); setPerspectiveWarping(true);
lastSourceTextureId = UINT_MAX;
updateMask = true; updateMask = true;
// maskIsReady = false; // maskIsReady = false;
glESVertexShader = CIRCLE_SURFACE_STRINGIFY( // glESVertexShader = CIRCLE_SURFACE_STRINGIFY(
attribute vec4 position; // attribute vec4 position;
attribute vec4 color; // attribute vec4 color;
attribute vec4 normal; // attribute vec4 normal;
attribute vec2 texcoord; // attribute vec2 texcoord;
//
uniform mat4 modelViewMatrix; // uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix; // uniform mat4 projectionMatrix;
uniform sampler2D maskTex; // uniform sampler2D maskTex;
//
varying vec4 colorVarying; // varying vec4 colorVarying;
varying vec2 texCoordVarying; // varying vec2 texCoordVarying;
//
void main() { // void main() {
//
//get our current vertex position so we can modify it // //get our current vertex position so we can modify it
vec4 pos = projectionMatrix*modelViewMatrix*position; // vec4 pos = projectionMatrix*modelViewMatrix*position;
//
gl_Position = pos; // gl_Position = pos;
colorVarying = color; // colorVarying = color;
texCoordVarying = texcoord; // texCoordVarying = texcoord;
} // }
); // );
//
glESFragmentShader = CIRCLE_SURFACE_STRINGIFY( // glESFragmentShader = CIRCLE_SURFACE_STRINGIFY(
//#ifdef GL_ES ////#ifdef GL_ES
// define default precision for float, vec, mat. //// define default precision for float, vec, mat.
precision highp float; // precision highp float;
////#endif
//
// uniform sampler2D tex0;
// uniform sampler2D maskTex;
// uniform vec4 globalColor;
//
// varying vec2 texCoordVarying;
//
// void main (void)
// {
// vec2 pos = texCoordVarying;
// vec3 src = texture2D(tex0, pos).rgb;
// float mask = texture2D(maskTex, pos).r;
// gl_FragColor = vec4( src , mask);
// }
// );
//
// gl2FragmentShader = "#version 120\n #extension GL_ARB_texture_rectangle : enable\n";
// gl2FragmentShader += CIRCLE_SURFACE_STRINGIFY(
// uniform sampler2DRect tex0;
// uniform sampler2DRect maskTex;
//
// void main (void) {
// vec2 pos = gl_TexCoord[0].st;
//
// vec3 src = texture2DRect(tex0, pos).rgb;
// float mask = texture2DRect(maskTex, pos).r;
//
// gl_FragColor = vec4(src, mask);
// }
// );
//
//#ifdef TARGET_OPENGLES
// maskShader.setupShaderFromSource(GL_VERTEX_SHADER, glESVertexShader);
// maskShader.setupShaderFromSource(GL_FRAGMENT_SHADER, glESFragmentShader);
// maskShader.bindDefaults();
// maskShader.linkProgram();
//#else
// if (ofIsGLProgrammableRenderer()) {
//
// } else {
// maskShader.setupShaderFromSource(GL_FRAGMENT_SHADER, gl2FragmentShader);
// maskShader.linkProgram();
// }
//#endif //#endif
uniform sampler2D tex0;
uniform sampler2D maskTex;
uniform vec4 globalColor;
varying vec2 texCoordVarying;
void main (void)
{
vec2 pos = texCoordVarying;
vec3 src = texture2D(tex0, pos).rgb;
float mask = texture2D(maskTex, pos).r;
gl_FragColor = vec4( src , mask);
}
);
gl2FragmentShader = "#version 120\n #extension GL_ARB_texture_rectangle : enable\n";
gl2FragmentShader += CIRCLE_SURFACE_STRINGIFY(
uniform sampler2DRect tex0;
uniform sampler2DRect maskTex;
void main (void) {
vec2 pos = gl_TexCoord[0].st;
vec3 src = texture2DRect(tex0, pos).rgb;
float mask = texture2DRect(maskTex, pos).r;
gl_FragColor = vec4(src, mask);
}
);
#ifdef TARGET_OPENGLES
maskShader.setupShaderFromSource(GL_VERTEX_SHADER, glESVertexShader);
maskShader.setupShaderFromSource(GL_FRAGMENT_SHADER, glESFragmentShader);
maskShader.bindDefaults();
maskShader.linkProgram();
#else
if (ofIsGLProgrammableRenderer()) {
} else {
maskShader.setupShaderFromSource(GL_FRAGMENT_SHADER, gl2FragmentShader);
maskShader.linkProgram();
}
#endif
ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f));
ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f));
ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f));
@ -128,6 +129,7 @@ void CircleSurface::draw() {
if (source != currentSource) { // Pointer comparison if (source != currentSource) { // Pointer comparison
// Create the mask here // Create the mask here
setupTextures(); setupTextures();
lastSourceTextureId = UINT_MAX;
currentSource = source; currentSource = source;
} }
@ -144,53 +146,61 @@ void CircleSurface::draw() {
auto sourceTex = ofTexture(*(source->getTexture())); auto sourceTex = ofTexture(*(source->getTexture()));
auto sourceTexId = sourceTex.getTextureData().textureID; auto sourceTexId = sourceTex.getTextureData().textureID;
// Get the quad surface's mesh texture coordinates: // Draw the mask only if the sources are FBO's, videos,
auto quadTexCoords = getMesh().getTexCoords(); // or if the last texture id was UINT_MAX (which means that
// the mask has not yet been draw).
// if (source->getType() == SOURCE_TYPE_FBO ||
// source->getType() == SOURCE_TYPE_VIDEO ||
// lastSourceTextureId == UINT_MAX) {
if (true) {
lastSourceTextureId = sourceTexId;
drawMaskForSource(sourceTex);
}
maskMesh.clearTexCoords(); // Swap the texture id of the source with the one of our
// newly drawn outputFbo:
source->getTexture()->getTextureData().textureID = outputFbo.getTexture().getTextureData().textureID;
auto texCoords = getMesh().getTexCoords();
getMesh().clearTexCoords();
getMesh().addTexCoords(defaultTexCoords);
// Draw the Quad:
QuadSurface::draw();
// Set the mesh's texture coords to the quads. // Reset the texture id of the source
// This gets us the coordinates set in the TextureEditor source->getTexture()->getTextureData().textureID = lastSourceTextureId;
maskMesh.addTexCoords(quadTexCoords);
float w = outputFbo.getWidth(); // Reset the texture coords of the QuadSurface mesh:
float h = outputFbo.getHeight(); getMesh().clearTexCoords();
getMesh().addTexCoords(texCoords);
// Draw the scaled texture into an FBO if (!isNorm) ofDisableNormalizedTexCoords();
scaledSourceFbo.begin(true); }
{
ofClear(0, 0, 0, 255);
ofSetupScreenOrtho(w, h, -1, 1);
ofEnableNormalizedTexCoords();
ofFill();
ofSetColor(255);
sourceTex.bind();
maskMesh.draw();
sourceTex.unbind();
}
scaledSourceFbo.end();
// Now draw the texture, masked, into the outputFbo. void CircleSurface::setFeathering(float f) {
// This enables us to use the TextureEditor to determine feathering = f;
// what part of the source will be masked: updateMask = true;
maskMesh.clearTexCoords(); }
void CircleSurface::drawMaskForSource(ofTexture &sourceTex) {
auto quadTexCoords = getMesh().getTexCoords();
// Set default normalized texCoords maskMesh.clearTexCoords();
maskMesh.addTexCoords(defaultTexCoords);
// Set the mesh's texture coords to the quads.
// This gets us the coordinates set in the TextureEditor
maskMesh.addTexCoords(quadTexCoords);
outputFbo.begin(true); outputFbo.begin(true);
{ {
ofClear(0, 0, 0, 0); ofClear(0, 0, 0, 0);
ofSetupScreenOrtho(w, h, -1, 1);
ofEnableNormalizedTexCoords(); ofEnableNormalizedTexCoords();
ofSetColor(255); ofSetColor(255);
ofFill(); ofFill();
ofSetRectMode(OF_RECTMODE_CORNER); ofSetRectMode(OF_RECTMODE_CORNER);
#ifdef TARGET_RASPBERRY_PI //#ifdef TARGET_RASPBERRY_PI
scaledSourceFbo.getTexture().bind(); sourceTex.bind();
maskMesh.draw(); maskMesh.draw();
scaledSourceFbo.getTexture().unbind(); sourceTex.unbind();
// Masking without shaders... // Masking without shaders...
ofPushStyle(); ofPushStyle();
ofEnableBlendMode(OF_BLENDMODE_MULTIPLY); ofEnableBlendMode(OF_BLENDMODE_MULTIPLY);
@ -199,44 +209,21 @@ void CircleSurface::draw() {
ofDisableNormalizedTexCoords(); ofDisableNormalizedTexCoords();
maskFbo.draw(0, 0); maskFbo.draw(0, 0);
ofPopStyle(); ofPopStyle();
#else //#else
maskShader.begin(); // maskShader.begin();
maskShader.setUniformTexture("maskTex", maskFbo.getTexture(), 1); // maskShader.setUniformTexture("maskTex", maskFbo.getTexture(), 1);
ofSetColor(255); // ofSetColor(255);
ofFill(); // ofFill();
ofSetRectMode(OF_RECTMODE_CORNER); // ofSetRectMode(OF_RECTMODE_CORNER);
scaledSourceFbo.getTexture().bind(); // scaledSourceFbo.getTexture().bind();
maskMesh.draw(); // maskMesh.draw();
scaledSourceFbo.getTexture().unbind(); // scaledSourceFbo.getTexture().unbind();
maskShader.end(); // maskShader.end();
#endif //#endif
} }
outputFbo.end(); outputFbo.end();
getMesh().clearTexCoords();
getMesh().addTexCoords(defaultTexCoords);
// Swap the texture id of the source with the one of our
// newly drawn outputFbo:
source->getTexture()->getTextureData().textureID = outputFbo.getTexture().getTextureData().textureID;
// Draw the Quad:
QuadSurface::draw();
// Reset the texture id of the source
source->getTexture()->getTextureData().textureID = sourceTexId;
// Reset the texture coords of the QuadSurface mesh:
getMesh().clearTexCoords();
getMesh().addTexCoords(quadTexCoords);
if (!isNorm) ofDisableNormalizedTexCoords();
}
void CircleSurface::setFeathering(float f) {
feathering = f;
updateMask = true;
} }
void CircleSurface::setupTextures() { void CircleSurface::setupTextures() {
@ -268,10 +255,10 @@ void CircleSurface::setupTextures() {
ofClear(0, 0, 0, 255); ofClear(0, 0, 0, 255);
outputFbo.end(); outputFbo.end();
scaledSourceFbo.allocate(w, h); // scaledSourceFbo.allocate(w, h);
scaledSourceFbo.begin(); // scaledSourceFbo.begin();
ofClear(0, 0, 0, 255); // ofClear(0, 0, 0, 255);
scaledSourceFbo.end(); // scaledSourceFbo.end();
// This is lifted from QuadSurface::setup to ensure that the two // This is lifted from QuadSurface::setup to ensure that the two
// meshes are similar: // meshes are similar:
@ -283,10 +270,10 @@ void CircleSurface::setupTextures() {
ofVec2f p4 = ofVec2f(w, 0); ofVec2f p4 = ofVec2f(w, 0);
// Create 4 point for the texture coordinates // Create 4 point for the texture coordinates
ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 1.0f));
ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 1.0f));
ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 0.0f));
ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f)); ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 0.0f));
// Clear maskMesh // Clear maskMesh
maskMesh.clear(); maskMesh.clear();

17
src/Surfaces/CircleSurface.h

@ -27,20 +27,20 @@ class CircleSurface : public QuadSurface {
protected: protected:
void setupTextures(); void setupTextures();
void drawMaskForSource(ofTexture &sourceTexture);
ofFbo maskFbo; ofFbo maskFbo;
ofFbo scaledSourceFbo; // ofFbo scaledSourceFbo;
ofFbo outputFbo; ofFbo outputFbo;
ofShader maskShader; // ofShader maskShader;
ofShader gradientShader;
float feathering = 0.0f; float feathering = 0.0f;
bool updateMask; bool updateMask;
bool maskIsReady; bool maskIsReady;
string glESFragmentShader; // string glESFragmentShader;
string glESVertexShader; // string glESVertexShader;
//
string gl2FragmentShader; // string gl2FragmentShader;
string gl2VertexShader; // string gl2VertexShader;
ofMesh maskMesh; ofMesh maskMesh;
@ -54,6 +54,7 @@ class CircleSurface : public QuadSurface {
// This is a total kludge, but it keeps me from messing with the // This is a total kludge, but it keeps me from messing with the
// upstream source. // upstream source.
BaseSource* currentSource = 0; BaseSource* currentSource = 0;
unsigned int lastSourceTextureId;
}; };
} }

Loading…
Cancel
Save