/*----------------------------------------------------------------------------*\
| Copyright (C) 2009 - Rafael de O. Lopes Gonçalves and André Shoji Asato |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 3 |
| of the License. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.|
\*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "visocor.h"
static const int LAST_FILTER = N_FILTER_VARIATIONS - 1;
static const int FIRST_FILTER = 0;
static const int FILTER_STEP = 1;
static void recalculateColorFilter(CompScreen * s) {
VISOCOR_SCREEN(s);
int middle;
middle = (LAST_FILTER + FIRST_FILTER) / 2;
if (vs->filterIntensity > middle) {
vs->ir = ((float) vs->filterIntensity - middle)
/ (LAST_FILTER - middle);
vs->ig = 0;
} else {
vs->ig = ((float) middle - vs->filterIntensity) / (middle
- FIRST_FILTER);
vs->ir = 0;
}
vs->ib = 1.0 - vs->ig - vs->ir;
visocorPrintf(CompLogLevelDebug, "ir = %f\tig = %f\tib = %f", vs->ir,
vs->ig, vs->ib);
}
void visocorResetFilter(VISOCORScreen * vs) {
int middle;
middle = (LAST_FILTER + FIRST_FILTER) / 2;
vs->filterIntensity = middle;
vs->ig = 0;
vs->ir = 0;
vs->ib = 1;
}
Bool visocorToggleFilter(CompDisplay * d, CompAction * action,
CompActionState state, CompOption * option, int nOption) {
CompWindow *w;
w = visocorFindWindow(d, option, nOption);
if (w) {
VISOCOR_WINDOW(w);
if (vw->currentState != FILTER) {
visocorToggleWindowToState(w, FILTER);
} else {
visocorToggleWindowToState(w, vw->lastState);
}
}
return TRUE;
}
Bool visocorDecreaseFilter(CompDisplay * d, CompAction * action,
CompActionState state, CompOption * option, int nOption) {
int value;
CompScreen *s;
s = visocorFindScreen(d, option, nOption);
if (s) {
VISOCOR_SCREEN(s);
value = MAX(FIRST_FILTER, vs->filterIntensity - FILTER_STEP);
vs->filterIntensity = value;
recalculateColorFilter(s);
visocorDamageAllWindows(s);
return TRUE;
}
return FALSE;
}
Bool visocorIncreaseFilter(CompDisplay * d, CompAction * action,
CompActionState state, CompOption * option, int nOption) {
CompScreen *s;
int value;
s = visocorFindScreen(d, option, nOption);
if (s) {
VISOCOR_SCREEN(s);
value = MIN(LAST_FILTER, vs->filterIntensity + FILTER_STEP);
vs->filterIntensity = value;
recalculateColorFilter(s);
visocorDamageAllWindows(s);
return TRUE;
}
return FALSE;
}
int getVisocorFilterFragmentFunction(CompScreen * s, CompTexture * texture,
int param) {
VISOCOR_SCREEN(s);
if (vs->visocorFunctions[FILTER][param] == 0) {
CompFunctionData *data;
int target;
char filter_operation[1024];
Bool ok = TRUE;
visocorPrintf(CompLogLevelDebug, "criando um FILTER com a variavel %d",
param);
if (texture->target == GL_TEXTURE_2D)
target = COMP_FETCH_TARGET_2D;
else
target = COMP_FETCH_TARGET_RECT;
data = createFunctionData();
if (data) {
ok &= addTempHeaderOpToFunctionData(data, "tex");
ok &= addTempHeaderOpToFunctionData(data, "temp");
ok &= addFetchOpToFunctionData(data, "tex", NULL, target);
char * format = "DP3 temp.r, tex, {1 , 0 , 0 , 0};\n"
"DP3 temp.g, tex, {0 , 1 , 0 , 0};\n"
"DP3 temp.b, tex, program.env[%d].xyzw;\n"
"MOV temp.a, tex.a;";
sprintf(filter_operation, format, param);
}
ok &= addDataOpToFunctionData(data, filter_operation);
ok &= addColorOpToFunctionData(data, "output", "temp");
if (!ok) {
destroyFunctionData(data);
return 0;
}
vs->visocorFunctions[FILTER][param] = createFragmentFunction(s,
"visocor", data);
;
}
(*s->programEnvParameter4f)(GL_FRAGMENT_PROGRAM_ARB, param, vs->ir, vs->ig,
vs->ib, 1.0f);
return vs->visocorFunctions[FILTER][param];
}