So I just figured I could perhaps do the following:
- draw the matrix as a series of quads with each vertex’s color value set to it’s normalized data value
- use a GLSL shader to iterate of the pixels and perform some filter
Being very unpro at opengl, my approach was as follows:
-take a standard demo which uses shaders, found here
-simply draw my matrix over the demo’s stuff
-change the shader code to filter some random data as a test
The entire class exceeds the 10.000 char limit, so here’s the relevant stuff
static double[][] data = {{0.5, 1.1, 1.5, 1, 2.0, 3, 3, 2, 1, 0.1},
{1.0, 1.5, 3.0, 5, 6.0, 2, 1, 1.2, 1, 4},
{0.9, 2.0, 2.1, 3, 6.0, 7, 3, 2, 1, 1.4},
{1.0, 1.5, 3.0, 4, 6.0, 5, 2, 1.5, 1, 2},
{0.8, 2.0, 3.0, 3, 4.0, 4, 3, 2.4, 2, 3},
{0.6, 1.1, 1.5, 1, 4.0, 3.5, 3, 2, 3, 4},
{1.0, 1.5, 3.0, 5, 6.0, 2, 1, 1.2, 2.7, 4},
{0.8, 2.0, 3.0, 3, 5.5, 6, 3, 2, 1, 1.4},
{1.0, 1.5, 3.0, 4, 6.0, 5, 2, 1, 0.5, 0.2}
};
int arrayHT = 0;
int arrayWD = 0;
float[] values = null;
private static final String[] edgeFragSource = {
"uniform sampler2D texUnit;",
"void main(void)",
"{",
" vec2 texCoord = gl_TexCoord[0].xy; ",
" vec4 c = texture2D(texUnit, texCoord); ",
" if(c.x>0.4 && c.x<0.5) ",
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); ",
" else ",
" gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); ",
"}"
};
//in the constructor
//convert mock data array into a float[] of the kind we normally use
arrayWD = data[0].length;
arrayHT = data.length;
values = new float[arrayHT * arrayWD];
for (int i = 0; i < arrayHT; i++) {
for (int j = 0; j < arrayWD; j++) {
values[i * arrayWD + j] = (float) data[i][j];
}
}
public void drawFill(GL gl, int current_spacing) {
gl.glBegin(GL.GL_QUADS);
float wd = Width / 2f;
float ht = Height / 2f;
for (int row = 0; row < arrayHT - 1; row++) {
for (int col = 0; col < arrayWD - 1; col++) {
int i1 = (row + 1) * arrayWD + col;
int i2 = row * arrayWD + col;
int i3 = row * arrayWD + col + 1;
int i4 = (row + 1) * arrayWD + col + 1;
//check for valid index and value on quad bounds
if (i2 < values.length && i4 < values.length) {
gl.glColor3f(values[i1] / 8.0f, 0, 0);
gl.glVertex3f((col * current_spacing) / wd - 1, (row * current_spacing + current_spacing) / ht - 1, 0);
gl.glColor3f(values[i2] / 8.0f, 0, 0);
gl.glVertex3f((col * current_spacing) / wd - 1, (row * current_spacing) / ht - 1, 0);
gl.glColor3f(values[i3] / 8.0f, 0, 0);
gl.glVertex3f((col * current_spacing + current_spacing) / wd - 1, (row * current_spacing) / ht - 1, 0);
gl.glColor3f(values[i4] / 8.0f, 0, 0);
gl.glVertex3f((col * current_spacing + current_spacing) / wd - 1, (row * current_spacing + current_spacing) / ht - 1, 0);
}
}
}
gl.glEnd();
}
//in the display function, after drawing the teapot
drawFill(drawable.getGL(), 100);
However, the result is quite odd.
if I run the code and end the display function after drawing the teapot and my own drawFill(),
it will draw the teapot, a ring and my matrix. All good so far.
But if I run the entire display function with the drawing of my matrix inbetween the shader should get to work, but the result is a very, very faint red area that is being drawn and the rest is black. Wrong behaviour according to the filter.
If one would run the program without the painting of my matrix (comment out the drawFill call), the filter seems to work fine. What am I doing wrong?