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

89
example/bin/data/ofxpimapper.xml

@ -36,38 +36,38 @@
<surface type="5">
<vertices>
<vertex>
<x>387.000000000</x>
<x>162.000000000</x>
<y>96.000000000</y>
</vertex>
<vertex>
<x>862.290893555</x>
<x>637.290893555</x>
<y>79.031463623</y>
</vertex>
<vertex>
<x>830.286376953</x>
<x>605.286376953</x>
<y>652.968627930</y>
</vertex>
<vertex>
<x>405.000000000</x>
<x>180.000000000</x>
<y>657.000000000</y>
</vertex>
</vertices>
<texCoords>
<texCoord>
<x>0.224322945</x>
<y>0.023645690</y>
<x>0.159322947</x>
<y>0.055312362</y>
</texCoord>
<texCoord>
<x>0.774270892</x>
<y>0.023645690</y>
<x>0.830520868</x>
<y>0.055312362</y>
</texCoord>
<texCoord>
<x>0.774270892</x>
<y>0.973813117</y>
<x>0.830520868</x>
<y>0.938813090</y>
</texCoord>
<texCoord>
<x>0.224322945</x>
<y>0.973813117</y>
<x>0.159322947</x>
<y>0.938813090</y>
</texCoord>
</texCoords>
<source>
@ -85,8 +85,8 @@
<y>46.077301025</y>
</vertex>
<vertex>
<x>860.523620605</x>
<y>247.922729492</y>
<x>887.000000000</x>
<y>402.000000000</y>
</vertex>
<vertex>
<x>1379.000000000</x>
@ -126,20 +126,20 @@
<surface type="5">
<vertices>
<vertex>
<x>1276.000000000</x>
<y>204.000000000</y>
<x>1364.000000000</x>
<y>252.000000000</y>
</vertex>
<vertex>
<x>724.000000000</x>
<y>387.000000000</y>
<x>742.000000000</x>
<y>392.000000000</y>
</vertex>
<vertex>
<x>707.000000000</x>
<y>809.000000000</y>
<x>795.000000000</x>
<y>857.000000000</y>
</vertex>
<vertex>
<x>1284.000000000</x>
<y>708.000000000</y>
<x>1372.000000000</x>
<y>756.000000000</y>
</vertex>
</vertices>
<texCoords>
@ -168,4 +168,49 @@
<perspectiveWarping>1</perspectiveWarping>
</properties>
</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>

279
src/Surfaces/CircleSurface.cpp

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

17
src/Surfaces/CircleSurface.h

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

Loading…
Cancel
Save