Last active
August 29, 2015 14:12
-
-
Save dermotbalson/4997536932ad409d0de5 to your computer and use it in GitHub Desktop.
2D to 3D touch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setup() | |
--settings for our rectangle (named "plane" below) | |
plane={} | |
plane.centre=vec3(0,0,0) | |
plane.rotate=vec3(45,0,20) | |
plane.size=vec2(500,500,0) | |
--set up mesh, needed for shader | |
plane.mesh=mesh() | |
local s=plane.size | |
local x1,y1,x2,y2,z=-s.x/2,-s.y/2,s.x/2,s.y/2,s.z | |
plane.mesh.vertices={vec3(x1,y1,z),vec3(x2,y1,z),vec3(x2,y2,z),vec3(x2,y2,z),vec3(x1,y2,z),vec3(x1,y1,z)} | |
plane.mesh.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)} | |
plane.mesh:setColors(color(255,255,0)) | |
parameter.text("Touch","") --shows results | |
img=image(WIDTH,HEIGHT) | |
shaderImg=image(WIDTH,HEIGHT) | |
--CreateImageMap() --USE THIS if your plane/rectangle never changes position, otherwise delete | |
end | |
--create an image map | |
function CreateImageMap() | |
setContext(shaderImg) | |
pushMatrix() | |
SetupPerspective() --see comment below | |
plane.mesh.shader=shader(PlaneShader.v,PlaneShader.f) | |
plane.mesh:draw() | |
setContext() | |
popMatrix() | |
plane.mesh.shader=nil | |
end | |
function draw() | |
background(50) | |
pushMatrix() | |
--the camera position and rotations are put in a separate function, to ensure that | |
--when we draw the hidden shader image, we can get exactly the same settings | |
SetupPerspective() | |
--draw plane | |
plane.mesh:draw() | |
--draw touch to show it worked | |
if p then | |
translate(p.x-plane.size.x/2,p.y-plane.size.y/2,1) | |
fill(255,0,0) | |
ellipse(0,0,20) | |
end | |
popMatrix() | |
end | |
--camera settings, also position and rotation of our rectangle/plane | |
function SetupPerspective() | |
perspective() | |
camera(0,0,900,0,0,-1) | |
translate(plane.centre.x,plane.centre.y,plane.centre.z) | |
rotate(plane.rotate.x,1,0,0) | |
rotate(plane.rotate.y,0,1,0) | |
rotate(plane.rotate.z,0,0,1) | |
end | |
function touched(t) | |
if t.state==ENDED then | |
p=GetPlaneTouchPoint(t) | |
Touch=p | |
end | |
end | |
function GetPlaneTouchPoint(t) | |
--if your rectangle never changes position, delete these commented lines, you don't need them | |
--however, if it moves around, you'll need to draw the shader image for each touch | |
--in that case, uncomment all these lines | |
--[[ | |
shaderImg=image(WIDTH,HEIGHT) | |
setContext(shaderImg) | |
pushMatrix() | |
SetupPerspective() | |
tx,ty=math.floor(t.x+0.5),math.floor(t.y+0.5) | |
clip(tx-1,ty-1,3,3) | |
plane.mesh.shader=shader(PlaneShader.v,PlaneShader.f) | |
plane.mesh:draw() | |
setContext() | |
plane.mesh.shader=nil | |
popMatrix() | |
--]] | |
local x2,y2,x1y1=shaderImg:get(tx,ty) | |
local y1=math.fmod(x1y1,16) | |
local x1=(x1y1-y1)/16 | |
local x,y=(x1+x2*16)/4096*plane.size.x,(y1+y2*16)/4096*plane.size.y | |
return vec2(x,y) | |
end | |
PlaneShader = { | |
v = [[ | |
uniform mat4 modelViewProjection; | |
attribute vec4 position; | |
attribute vec2 texCoord; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
vTexCoord = texCoord; | |
gl_Position = modelViewProjection * position; | |
} | |
]], | |
f = [[ | |
precision highp float; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
highp vec2 T = vTexCoord * 4096.0; | |
highp float x1=mod(T.x,16.0); | |
highp float x2=(T.x - x1) / 16.0; | |
highp float y1=mod(T.y,16.0); | |
highp float y2=(T.y - y1) / 16.0; | |
gl_FragColor = vec4(x2/255.0,y2/255.0,(x1*16.0+y1)/255.0,1.0); | |
} | |
]]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment