The 2nd solution: Show the value
Very well, with the experiment above, we can know the brief of the var in shader. But the info is too simple, and it is complicated to use. We want to watch the exact value, we know we can control the whole screen with shader, so in abstracto we can draw anything to screen include number.
Now let us make the problem simple, assume myVar is a int and its region is [0,9], then we can get a logic:
if myVar is 1, then draw specified pixels in a specified area with specified color(draw 1);
if myVar is 2, then draw specified pixels in a specified area with specified color(draw 2);
...
if myVar is 9, then draw specified pixels in a specified area with specified color(draw 9);
if myVar is 0, then draw specified pixels in a specified area with specified color(draw 0);
It looks good, now we can make shader output the 10 number of 1~0. Continue to make the problem simpler, start with the easiest place, only to draw a number 1 on the screen, the code is below:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( x > 0.99 ){
// the right set green
gl_FragColor = vec4(0,1,0,1);
}
}
Ok, it works, now we can add more, for example we can add a judgement with if myVar is number 1, if it is true the shader will draw a green number 1 with white background in this area.
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( myVar == 1 && x > 0.99 ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
One by one, we can draw the number 2~0 with the same method:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( myVar == 1 && x > 0.99 ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
if( myVar == 2 && (the coordinate of 2) ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
...
if( myVar == 0 && (the coordinate of 0) ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
Optimize the code:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if(( myVar == 1 && x > 0.99 ) ||
( myVar == 2 && (the coordinate of 2)) ||
...
( myVar == 0 && (the coordinate of 0))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
It is ok, change it to a function:
// LED char
void ledChar(int n, float xa,float xb, float ya, float yb){
float x = vTexCoord.x;
float y = vTexCoord.y;
float x1 = xa;
float x2 = xa+xb;
float y1 = ya;
float y2 = ya+yb;
float ox = (x2+x1)/2.0;
float oy = (y2+y1)/2.0;
float dx = (x2-x1)/10.0;
float dy = (y2-y1)/10.0;
float b = (x2-x1)/20.0;
int num = n;
// debug area
if(x >= x1 && x <= x2 && y >= y1 && y <= y2) {
// background is blue
gl_FragColor = vec4(0,0,1,.5);
// draw 1~0 in a rect
if((num==1 && (x > x2-dx)) ||
(num==2 && ((y > y2-dy) || (x > x2-dx && y > oy-dy/2.0) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (x < x1+dx && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==3 && ((y > y2-dy) || (x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==4 && ((x < x1+dx && y > oy-dy/2.0) ||(x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0))) ||
(num==5 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==6 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==7 && ((y > y2-dy) || (x > x2-dx))) ||
(num==8 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx) || (y<y1+dy))) ||
(num==9 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)||(y > oy-dy/2.0 && y < oy+dy/2.0)|| (x>x2-dx) || (y<y1+dy))) ||
(num==0 && ((y > y2-dy) || (x < x1+dx) || (x>x2-dx) || (y<y1+dy)))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
}
The whole shader code is below:
myShader = {
vsBase = [[
// vertex shader
uniform mat4 modelViewProjection;
uniform vec2 uResolution;
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main() {
vColor=color;
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]],
fsBase = [[
// fragment shader
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void ledChar(int,float,float,float,float);
void main() {
lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;
// default is white
gl_FragColor = vec4(.1,.1,.1,1);
// show 1
ledChar(1, 0.9, 0.1, 0.9, 0.1);
}
// LED char
void ledChar(int n, float xa,float xb, float ya, float yb){
float x = vTexCoord.x;
float y = vTexCoord.y;
float x1 = xa;
float x2 = xa+xb;
float y1 = ya;
float y2 = ya+yb;
float ox = (x2+x1)/2.0;
float oy = (y2+y1)/2.0;
float dx = (x2-x1)/10.0;
float dy = (y2-y1)/10.0;
float b = (x2-x1)/20.0;
int num = n;
// debug area
if(x >= x1 && x <= x2 && y >= y1 && y <= y2) {
// set blue
gl_FragColor = vec4(0.2,0.2,0.8,.5);
// draw number 1~0
if((num==1 && (x > x2-dx)) ||
(num==2 && ((y > y2-dy) || (x > x2-dx && y > oy-dy/2.0) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (x < x1+dx && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==3 && ((y > y2-dy) || (x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==4 && ((x < x1+dx && y > oy-dy/2.0) ||(x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0))) ||
(num==5 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==6 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==7 && ((y > y2-dy) || (x > x2-dx))) ||
(num==8 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx) || (y<y1+dy))) ||
(num==9 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)||(y > oy-dy/2.0 && y < oy+dy/2.0)|| (x>x2-dx) || (y<y1+dy))) ||
(num==0 && ((y > y2-dy) || (x < x1+dx) || (x>x2-dx) || (y<y1+dy)))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
}
]]
}
In abstracto, with the foundation code above, we can watch the var value in shader easily, but unfortunately there is a big bug I have not found the reason: when in one mesh run the function ledChar twice, it will make the screen messy.
About how to display number font with shader, I have thought of some other method, one is using vec4 or mat4 to transfer the font data , another is using the texture. I think the last one will be esaier. I will try these ideas later.
Btw, when I have had these ideas, I thought maybe others will have the same idea, so I searched for the keywords shader debug, then I found in StackOverflow some programers were talking about it, one person give the answer similar with the first solution of mine, and one person gave a solution full of imagination–visualization. It looks very interesting. The article linke, I will try the visualization later.