ofxPiMapper fixed for C++17 & oF 12.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

305 lines
7.2 KiB

//
// CircleSurface.cpp
// Copyright (c) 2017 Cristobal Mendoza
// http://cuppetellimendoza.com
#include "CircleSurface.h"
namespace ofx {
namespace piMapper {
CircleSurface::CircleSurface() : QuadSurface() {
setup();
}
CircleSurface::CircleSurface(QuadSurface &surface) {
setup();
setVertices(surface.getVertices());
setTexCoords(surface.getTexCoords());
setPerspectiveWarping(surface.getPerspectiveWarping());
}
CircleSurface::~CircleSurface() {}
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;
////#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
Vec2 t1 = Vec2(0.0f, 0.0f);
Vec2 t2 = Vec2(1.0f, 0.0f);
Vec2 t3 = Vec2(1.0f, 1.0f);
Vec2 t4 = Vec2(0.0f, 1.0f);
defaultTexCoords.push_back(t1);
defaultTexCoords.push_back(t2);
defaultTexCoords.push_back(t3);
defaultTexCoords.push_back(t4);
}
void CircleSurface::draw() {
ofEnableAlphaBlending();
if (source->getTexture() == 0)
{
return;
}
if (!source->getTexture()->isAllocated()){
return;
}
if (source != currentSource) { // Pointer comparison
// Create the mask here
setupTextures();
lastSourceTextureId = UINT_MAX;
currentSource = source;
}
// Save Normie state:
auto isNorm = ofGetUsingNormalizedTexCoords();
// If we get to this part of the function, the mask fbo
// should already be allocated and the mask texture created.
ofEnableNormalizedTexCoords();
// Get the texture from the source an store a copy
// of the source texture's id:
auto sourceTex = ofTexture(*(source->getTexture()));
auto sourceTexId = sourceTex.getTextureData().textureID;
// 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);
}
// 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(Vec2::toOf(defaultTexCoords));
// Draw the Quad:
QuadSurface::draw();
// Reset the texture id of the source
source->getTexture()->getTextureData().textureID = lastSourceTextureId;
// Reset the texture coords of the QuadSurface mesh:
getMesh().clearTexCoords();
getMesh().addTexCoords(texCoords);
if (!isNorm) ofDisableNormalizedTexCoords();
}
void CircleSurface::setFeathering(float f) {
feathering = f;
updateMask = true;
}
void CircleSurface::drawMaskForSource(ofTexture &sourceTex) {
auto quadTexCoords = getMesh().getTexCoords();
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);
ofEnableNormalizedTexCoords();
ofSetColor(255);
ofFill();
ofSetRectMode(OF_RECTMODE_CORNER);
//#ifdef TARGET_RASPBERRY_PI
sourceTex.bind();
maskMesh.draw();
sourceTex.unbind();
// Masking without shaders...
ofPushStyle();
ofEnableBlendMode(OF_BLENDMODE_MULTIPLY);
ofSetColor(255);
ofFill();
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
}
outputFbo.end();
}
void CircleSurface::setupTextures() {
float w = source->getTexture()->getWidth();
float h = source->getTexture()->getHeight();
float dia = 0;
if (w > h) {
dia = h;
} else {
dia = w;
}
float padding = 10;
maskFbo.allocate(w, h);
maskFbo.begin(false);
ofPushStyle();
ofSetupScreenOrtho(w, h, -1, 1);
ofClear(0, 0, 0, 255);
ofFill();
ofSetColor(255);
ofSetCircleResolution(300);
ofDrawEllipse(w/2, h/2, w-padding, h-padding);
ofPopStyle();
maskFbo.end();
outputFbo.allocate(w, h);
outputFbo.begin();
ofClear(0, 0, 0, 255);
outputFbo.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:
// Create 4 points for the 2 triangles
Vec3 p1 = Vec3(0, 0, 0);
Vec3 p2 = Vec3(0, h, 0);
Vec3 p3 = Vec3(w, h, 0);
Vec3 p4 = Vec3(w, 0, 0);
// Create 4 point for the texture coordinates
Vec2 t1 = Vec2(Vec2(0.0f, 1.0f));
Vec2 t2 = Vec2(Vec2(1.0f, 1.0f));
Vec2 t3 = Vec2(Vec2(1.0f, 0.0f));
Vec2 t4 = Vec2(Vec2(0.0f, 0.0f));
// Clear maskMesh
maskMesh.clear();
// Create a surface with the points
maskMesh.addVertex(p1.toOf());
maskMesh.addVertex(p2.toOf());
maskMesh.addVertex(p3.toOf());
maskMesh.addVertex(p4.toOf());
// Add 2 triangles
maskMesh.addTriangle(0, 2, 3);
maskMesh.addTriangle(0, 1, 2);
// Add texture coordinates
maskMesh.addTexCoord(t1.toOf());
maskMesh.addTexCoord(t2.toOf());
maskMesh.addTexCoord(t3.toOf());
maskMesh.addTexCoord(t4.toOf());
}
int CircleSurface::getType() {
return SurfaceType::CIRCLE_SURFACE;
}
}
}