# stevon8ter's color picker [FINISHED]

@Andrew_Stacey, how would the mesh shader vertices table need to be set? is there a specific order?

The quadrilateral is specified in the table `v`. Vertices 1 and 4 are opposite, as are vertices 2 and 3. So if it were a square, it would be:

``````3 --- 4
|         |
1 --- 2
``````

The quadrilateral is triangulated into `1-2-4` and `1-3-4`. We also pass in the table of vertices to the mesh, this is the line `m.shader.vertices = v`. The colours are passed in similarly: there is an obvious correspondence between the tables of vertices and colours.

The ordering of the vertices - in case you’re interested - in the quadrilateral is using a binary encoding (offset by one since Lua tables start at 1) then splitting into coordinates. In binary, and subtracting one, the above diagram is:

``````10 --- 11
|          |
00 --- 01
``````

so that’s x and y coordinates, except that I’ve put them the wrong way around (not that that matters).

(I haven’t done arbitrary texCoords, it puts the texture on the mesh fitting it in the corners. I intend to extend it.)

@Andrew_Stacey hmmm my head currently doesn’t get the hang of it xo

``````
--Author: Andrew Stacey
--Version: 1.1
--Options:
--Dependencies:

function setup()
a = mesh()

x = WIDTH/2
y = HEIGHT/2

vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y+100), vec2(x+100, y-100)}

col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}

v = {}
c = {}

v[1] = vec[1]    c[1] = col[1]
v[2] = vec[4]    c[2] = col[1]
v[3] = vec[3]    c[3] = col[1]

v[4] = vec[1]    c[4] = col[1]
v[5] = vec[2]    c[5] = col[1]
v[6] = vec[3]    c[6] = col[1]

a.vertices = v
a.colors = c

color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end

function draw()
background(40,40,50)
a:draw()
end

function touched(t)

end

//
//

//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;

//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;

//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader

vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
//

//Default precision qualifier
precision highp float;

//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];

vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);

varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));

} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
lowp vec4 tex = texture2D( texture, vec2(x,y) );
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
gl_FragColor = col*tex;
}
]])
end

``````

I could figure out the right positions

The vertices should be

``````    vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}
``````

and `v[6]` should be `vec[4]`

@Andrew_Stacey the vertices are now correct, howerver, I don’t assign a texture, and yet it displayez ‘Made With Codea’ inside the mesh, nothing else, just that, filled with a gradient

If you dn’t want to assign a texture at all, remove the `lowp vec4 tex = ... ` line and change the gl_FragColor to just col.

(There’s a bug whereby if you have a texture in the shader but don’t assign one then it uses one anyway.)

@Andrew_Stacey I did as you said and it now shows a blank screen

``````
--Author: Andrew Stacey
--Version: 1.1
--Options:
--Dependencies:

function setup()
a = mesh()

x = WIDTH/2
y = HEIGHT/2

vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}

col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}

v = {}
c = {}

v[1] = vec[1]    c[1] = col[1]
v[2] = vec[4]    c[2] = col[1]
v[3] = vec[3]    c[3] = col[1]

v[4] = vec[1]    c[4] = col[1]
v[5] = vec[2]    c[5] = col[1]
v[6] = vec[4]    c[6] = col[1]

a.vertices = v
a.colors = c

color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end

function draw()
background(40,40,50)
a:draw()
end

function touched(t)

end

//
//

//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;

//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;

//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader

vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
//

//Default precision qualifier
precision highp float;

//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];

vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);

varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));

} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
//col = col*tex;
}
]])
end

``````

and yeah, you still gotta remove the comment of col = col*tex
I thought that what the problem because there not being a texture… commenting it out creates a funny effect tho

Sorry! I was typing late at night. I meant to change the col*tex to just col, not the whole line.

``````--The name of the project must match your Codea project name if dependencies are used.
--Project: Place Project Name Here
--Author:
--Version: Alpha 1.0

function setup()
a = mesh()

x = WIDTH/2
y = HEIGHT/2

vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}

col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}

v = {}
c = {}

v[1] = vec[1]    c[1] = col[1]
v[2] = vec[4]    c[2] = col[1]
v[3] = vec[3]    c[3] = col[1]

v[4] = vec[1]    c[4] = col[1]
v[5] = vec[2]    c[5] = col[1]
v[6] = vec[4]    c[6] = col[1]

a.vertices = v
a.colors = c

color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end

function draw()
background(40,40,50)
a:draw()
end

function touched(t)

end

//
//

//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;

//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;

//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader

vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
//

//Default precision qualifier
precision highp float;

//This represents the current texture on the mesh
//uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];

vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);

varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));

} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
//lowp vec4 tex = texture2D( texture, vec2(x,y) );
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
gl_FragColor = col; //*tex;
}
]])
end

``````

@Andrew_Stacey thank you so much, this look so much better + I can probably understand the calculations so thank you so much I’ll work on this when I get home from school

New version on CC (will need same tweaks for non-textured meshes). Much simpler shader code.

@Andrew_Stacey thanks for all your effort in this, once I get some sleep and some time I’ll work on this class some more

I hope to get it running at 60fps for everyone
In my opinion it isn’t looking bad, but I know that noone would use this class, tho I need it for a project, so I thought I might as well share it

Ok no more questions this time

Time for a major UPDATE

http://twolivesleft.com/Codea/CC/alpha/index.php?v=1353

It now has full power of a color picker, including alpha level selector, works with different sizes, tho I wouldn’t make it to small because of touch handling

Example included which shows 2 different-sized color pickers at work

I hope you enjoy this and that I get some critical feedback on this

any sugestions are welcome

Also, I wanna thank @Andrew_Stacey for his great help in the last major parts of color shading

Quite nice. 23Hz on ipad1: good!

@Jmv38 thx I might try to speed it up some more, right now it’s all kinda messy xd

@Jmv38 could you tell me in what circumstances ylu get 23Hz? Like, how many colorpickers are drawn? and how many rings/squares are you touching?

Not much to say really. Just ran the program you posted. There are 2 color pickers showing, one big and one small, and your fps counter says 23. But what is the problem? I think 23 is very good already. You could make it 60hz by putting everything in a single image and sprite it, but is it really worth the effort?

@Jmv38 ok thanks, Idk, I just always want my classes to run as good as they ever could be, but for now I’ll leave it like this, gonna work on my sprite picker first