Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Codea 1.5 (Beta 8)



  • Posts: 2,161

    Bug Having ]] in a block-commented region causes an error (such as a[b[2]])

  • Jmv38Jmv38 Mod
    Posts: 3,297

    Thanks @Bortels.
    I am at
    The code lines you listed up there, should i put it in the .htaccess file?

  • Clarification: "Cursor movement and selection keys do not include the last character of a tab."

    I mean an editor tab, i.e. the whole text buffer. That's why it was so annoying to be stuck at the last line to the left of the parentheses, I couldn't move beyond it using the cursor key.

  • Posts: 489

    Does the code below reveal a bug in beta 1.5(8)? I wrote it thinking about punching a hole in a rectangle. On an iPad 2 with iOS 6.0.1 sometimes (but not always) some of the triangles in the mesh do not render - pressing the 'replay' button a few times reveals the problem:

    -- -- RectWithHole -- supportedOrientations(LANDSCAPE_ANY) function setup() myRwh = RectWithHole(400, 300, WIDTH/2, HEIGHT/2, 100, 55, 90) end function draw() local r = math.sin(ElapsedTime * 2) * 64 + 127 local g = math.sin(ElapsedTime * 4) * 64 + 127 local b = math.sin(ElapsedTime * 6) * 64 + 127 background(r, g, b) myRwh:draw() end RectWithHole = class() function RectWithHole:init(width, height, posX, posY, holeX, holeY, radius) width = math.abs(width) / 2 height = math.abs(height) / 2 radius = math.min(math.abs(radius), width, height) holeX = math.min(math.max(holeX, radius - width), width - radius) holeY = math.min(math.max(holeY, radius - height), height - radius) self.width = width self.height = height self.posX = posX self.posY = posY self.holeX = holeX self.holeY = holeY self.radius = radius self.mesh = mesh() local segNo = math.max(4, math.floor(math.pi * radius / 30)) local dAng = math.pi / 4 / segNo local dEdge = 1 / segNo local org = { vec2(width, holeY), vec2(width, height), vec2(holeX, height), vec2(-width, height), vec2(-width, holeY), vec2(-width, -height), vec2(holeX, -height), vec2(width, -height)} local dir = { vec2(0, dEdge * (height - holeY)), vec2(-dEdge * (width - holeX), 0), vec2(-dEdge * (width + holeX), 0), vec2(0, -dEdge * (height - holeY)), vec2(0, -dEdge * (height + holeY)), vec2(dEdge * (width + holeX), 0), vec2(dEdge * (width - holeX), 0), vec2(0, dEdge * (height + holeY))} local ver = {} local col = {} local p1 = vec2(holeX + radius, holeY) local p2 = org[1] for i = 0, segNo * 8 - 1 do local seg = math.floor(i / segNo) local dSeg = i % segNo + 1 local ang = math.pi / 4 * seg + dSeg * dAng local p3 = vec2(holeX + radius * math.cos(ang), holeY + radius * math.sin(ang)) local p4 = org[seg + 1] + dSeg * dir[seg + 1] table.insert(ver, p1) table.insert(ver, p2) table.insert(ver, p4) table.insert(ver, p4) table.insert(ver, p3) table.insert(ver, p1) p1 = p3 p2 = p4 -- Random colours for debugging only local c = color(math.random(127) + 127, math.random(127) + 127, math.random(127) + 127) for j = 1, 6 do table.insert(col, c) end end self.mesh.vertices = ver -- Set vertex colours for debugging only self.mesh.colors = col end function RectWithHole:draw() pushMatrix() resetMatrix() translate(self.posX, self.posY) self.mesh:draw() popMatrix() end function RectWithHole:fill(color) self.mesh:setColors(color) end
  • SimeonSimeon Admin Mod
    edited December 2012 Posts: 5,417

    .@mpilgrem thank you for posting that code. It is very strange behaviour. I'm looking into it now.

    Edit: with lower values for segNo the effect seems to disappear.

    Edit: also the bug doesn't occur with 1.4.6 — I'll have to ask @John for help with this, seems to be a mesh related issue.

  • SimeonSimeon Admin Mod
    Posts: 5,417

    .@mpilgrem @John has found the issue — it occurs when using vec2s in a mesh. Their z-value is uninitialised. This leads to artefacts on thin triangle strips.

    To fix this for now please use vec3 in your mesh with a z value of 0. This doesn't affect 1.4.6 and will be fixed in 1.5 (9).

  • Posts: 505

    Hi. Nice with an update. The expression key is a bit buggy if you press it down and then move quickly to the number keys. Then the keyboard gets grey and it seems like I move the cursor in the code view instead. Also, I think it would be nice if the expression input is canceled if I end the touch event on the expression key.

    Gravity and sound seems to work fine now, good work!

    Btw, anyone have any shader examples using lightning? Would be nice to try out a bit, but haven't had the time to write any code yet. :)

  • Posts: 2,161

    My toroidal Game of Life using shaders had a simple lighting/shadow shader in it so that the torus looked as if it were lit from one angle. No shadows, though (by which I mean that one part of the torus did not cast a shadow on the other). I did this by loading the normals in to the shader using a buffer. I don't remember if I posted the code already ... I think I'm getting to the point where I'll have to keep an public repository of my shaders.

  • Posts: 505

    I haven't seen then code, so I don't think so. :)

    I made an attempt using buffers for the 3D Lab, but I must have made some strange mistakes, so it would be interesting to check out some code that works. I've only made 2d effects with shaders so far.

  • Posts: 2,161


    I've uploaded my shaders to a public repository. You can browse the files directly or check them out using VCS (the format is bazaar, but other VCS's can read them). They're at:

    Of course, you also need the code to use them. However, that'll take a bit more care before publishing because I currently have a single "test" project where all my "little" stuff starts, but I also use it for testing others' code so I can't really just export the whole lot.

  • edited December 2012 Posts: 505

    Thanks for sharing! A small test that uses buffers would be great, because my attempts just looked crazy :). I tried to create normals with v1:cross(v2):normalize() for two points in a triangle, but the result was a bit wierd. Haven't put enough time on it to figure out what is wrong, so a working example would help out. :)

    function createNormals(m)
        local normals = m:buffer("normal")
        for i = 1,#m.vertices,3 do
            local v1 = m:vertex(i)-m:vertex(i+1)
            local v2 = m:vertex(i)-m:vertex(i+2)
            local n = v1:cross(v2):normalize()
            normals[math.floor(i/3)+1] = n
            normals[math.floor(i/3)+2] = n
            normals[math.floor(i/3)+3] = n
  • Jmv38Jmv38 Mod
    Posts: 3,297

    .@tnlogy my shadow code (credits 99% to Andrew Stacey):
    The program code (nor is a table of vec3 that are the normals at each vertice location. There is no universal way to compute it, it depends for instance if your object is mooth or has faces. I can post my code for it if you want)

        ms.shader = shader("Documents:Shadow")
        ms.shader.light = vec3(1,1,0):normalize()
        local tnor = ms:buffer("normal")
        for k,v in ipairs(nor) do 
            tnor[k] = v

    Vertex shader

    // A basic vertex shader
    //This is the current model * view * projection matrix
    // Codea sets it automatically
    uniform mat4 modelViewProjection;
    uniform vec3 light;
    //This is the current mesh vertex position, color and tex coord
    // Set automatically
    attribute vec4 position;
    attribute vec4 color;
    attribute vec2 texCoord;
    attribute vec3 normal;
    //This is an output variable that will be passed to the fragment shader
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    varying lowp float vShade;
    void main()
        //Pass the mesh color to the fragment shader
        vColor = color;
        vTexCoord = vec2(texCoord.x,1.-texCoord.y);
        if (light != vec3(0.,0.,0.)) {
            lowp vec4 nor = modelViewProjection * vec4(normal,0);
            vShade = (dot(,light)+0.2)/1.2;
            if (vShade >1.0) {vShade=1.0;}
            if (vShade <0.2) {vShade=0.2;}
        } else {
            vShade = 1.;
        //Multiply the vertex position by our combined transform
        gl_Position = modelViewProjection * position;

    fragment shader

    // A basic fragment shader
    //This represents the current texture on the mesh
    uniform lowp sampler2D texture;
    //The interpolated vertex color for this fragment
    varying lowp vec4 vColor;
    //The interpolated texture coordinate for this fragment
    varying highp vec2 vTexCoord;
    varying lowp float vShade;
    void main()
        //Sample the texture at the interpolated coordinate
        lowp vec4 col;
     //   col = texture2D( texture, vTexCoord );
        col = vColor;
        col.rgb *= vShade;
        //Set the output color to the texture color
        gl_FragColor = col;
  • Jmv38Jmv38 Mod
    edited December 2012 Posts: 3,297

    Here is my class i use to compute normals

    Vec3sort = class() function Vec3sort:init() end function Vec3sort:blend(ms,color1)     local i=1     local newColors = {}     local r,g,b,a,c,c1     while i<=#(ms.colors) do         c = ms:color(i)         c1 = color1[i]         c.r = c.r * c1.r / 255         c.g = c.g * c1.g / 255         c.b = c.b * c1.b / 255                  newColors[i] = c --print(c1)         i = i + 1     end     return newColors end function Vec3sort:shade(t,lightDir,min,max,slope)     local center, amplitude = (max+min)/2, (max-min)/2     local i=1     local a     local newColors = {}     local steepness = slope or 2     while i<=#t do         -- shadow         a = - t[i]:dot(lightDir) * steepness         if a>1 then a =1 elseif a<-1 then a=-1 end         a = center + amplitude*a         -- set color         a = color(a,a,a,alpha)         newColors[i] = a         i = i + 1     end     return newColors end function Vec3sort:verticeNormals(t)     local out = {}     local s = Vec3sort:intSort(t)     local nf = Vec3sort:faceNormals(t)     local i=1     local imax = #s     local n,v,j,i0,i1,k,p     -- init loop     j=s[i].x ; v = nf[ s[i].y ] ; n=1 ; i0=i ; i1=i     i = i + 1     while i<= imax do         if s[i].x == j then    -- this is the same vector             -- accumulate             v = v + nf[ s[i].y ]             n = n + 1             i1 = i         end         if s[i].x ~= j or i==imax then    -- this is the same vector             -- compute normal             v = v/n             v = v:normalize()             -- save last normal             for k=i0,i1 do                 out[s[k].y] = v             end             -- init loop             j=s[i].x ; v = nf[ s[i].y ] ; n=1 ; i0=i ; i1=i         end         i = i + 1     end     --[[     -- verification     for i=1,#t do         v = out[i]         print(v.x.." "..v.y.." "..v.z)     end     ]]     return out end local clock = os.clock function Vec3sort:faceNormals(t)     local out = {}     local imax = math.floor(#t/3)     local i=1     local v1,v2,v3,a,b,normal     local t1 = clock()+1/40     while i<= imax do         -- get triangle vertices         v1 = t[1 + i*3-3]         v2 = t[1 + i*3-2]         v3 = t[1 + i*3-1]         -- compute normal vector         a = v1-v2         b = v1-v3         normal = a:cross(b):normalize()         -- compute normal vector orientation         a = (v1+v2+v3)/3         b = a:dot(normal)         if b>0 then b=1 else  b=-1 end         normal = normal * b         -- write result         out[1 + i*3-3] = normal         out[1 + i*3-2] = normal         out[1 + i*3-1] = normal         i = i + 1     end     return out end local floor = math.floor function Vec3sort:intSort(t)     -- t is a table ov vec3     local s = {}     local i     for i=1,#t do         s[i] = vec4(t[i].x,t[i].y,t[i].z,i)     end     local function compVec3(a,b)         local out = false         if floor(a[1])<floor(b[1]) then out = true         elseif floor(a[1])==floor(b[1]) then             if floor(a[2])<floor(b[2]) then out = true             elseif floor(a[2])==floor(b[2]) then                 if floor(a[3])<floor(b[3]) then out = true end             end         end         return out     end     table.sort(s,compVec3)     local v     --[[     for i=1,#s do         v = s[i]         print(v.x.." "..v.y.." "..v.z.." "..v.w)     end     ]]     local out={}     local n = 1     out[1] = vec2(n,s[1].w)     for i=2,#s do         if compVec3(s[i-1],s[i]) then n = n + 1 end         out[i] = vec2(n,s[i].w)     end     --[[     for i=1,#s do         v = out[i]         print(v.x.." "..v.y)     end     ]]     return out end function Vec3sort:sort(t)     -- t is a table ov vec3     local s = {}     local i     for i=1,#t do         s[i] = vec4(t[i].x,t[i].y,t[i].z,i)     end     local function compVec3(a,b)         local out = false         if a[1]<b[1] then out = true         elseif a[1]==b[1] then             if a[2]<b[2] then out = true             elseif a[2]==b[2] then                 if a[3]<b[3] then out = true end             end         end         return out     end     table.sort(s,compVec3)     local v     --[[     for i=1,#s do         v = s[i]         print(v.x.." "..v.y.." "..v.z.." "..v.w)     end     ]]     local out={}     local n = 1     out[1] = vec2(n,s[1].w)     for i=2,#s do         if compVec3(s[i-1],s[i]) then n = n + 1 end         out[i] = vec2(n,s[i].w)     end     --[[     for i=1,#s do         v = out[i]         print(v.x.." "..v.y)     end     ]]     return out end

    In the setup i create a 'normals' object to which i pass the mesh vertice table to compute the normals (smooth normals here). You can also use faceNormals() if you want not smooth shadows

    normals = Vec3sort()
    nor = normals:verticeNormals(

    Hope that helps you...

  • Posts: 505

    Thanks for the help. It seems like my calculation of normals was incorrect. I now instead tried loading an OBJ-file with some ugly code, and then it works fine. Nice :)

Sign In or Register to comment.