Howdy, Stranger!

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

Codea 1.5 Beta

SimeonSimeon Admin Mod
edited November 2012 in Beta Posts: 5,364

Hi Beta Testers.

Build 1 of Codea 1.5 is uploading now. It's still a bit rough around the edges. More example projects are coming, and it's still missing some documentation, but most of the new features are included.

I've set up a small introduction to shaders, here:

http://twolivesleft.com/Codea/1.5/

(Note that the new documentation search and "related" links are not yet working.)

I'm looking forward to hearing what your impressions.

Tagged:
«1345678

Comments

  • BortelsBortels Mod
    Posts: 1,557

    Woot! Something to mess with this weekend.

  • Posts: 503

    Nice! And a Tween library also, will be interesting to try out!

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    Finished reading the docs - can't wait to try this. It looks like you "did it right" - I have a grin on my face ear-to-ear; the Camera support was icing on the cake. (How do you pick which camera?)

    PS. Working on my 3rd gen ipad. Good example app. TIme to dig. I'm wondering how I'm going to get my real work done today - I may have to "put this away" for a few hours to avoid distraction.

    PPS. Answering my own question - cameraSource(). W00t!

  • Posts: 2,161

    What's happened to my z-ordering on my meshes? The triangles seem to be being drawn in the order of specification. Do I need to explicitly set a shader or something?

  • Posts: 2,161

    I miss the X at the bottom left when the keyboard isn't there. The arrow at top right is too small for my fat fingers.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    .@AndrewStacey me too — the X at the bottom will be coming back. Is Z-buffer broken? I'll look into it.

  • Posts: 2,161

    Yippee on the X.

    Yes, the z-buffer is definitely broken. I've just tried it with the code from my martrices blog post and the squares are drawn in order of definition, which looks really weird when rotating a cube!

  • SimeonSimeon Admin Mod
    Posts: 5,364

    That's odd, the 3D Lab example still works for me and that relies on the z-buffer. Does it break for you too?

  • Posts: 2,161

    Narrowed it down to setContext. If I put a setContext(img) somewhere then it breaks the z-buffering for subsequent draws.

    -- end of setup
        nf = 0
    end
    
    -- start of draw
    function draw()
        nf = nf + 1
        if nf == 120 then
            img = image(100,100)
        setContext(img)
        end
    

    then z-buffering suddenly turns off.

    In other news, the camera is awesome! I have a picture sliding puzzle game and I added it in so you can take a picture to do the puzzle with.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    Thanks for finding that, Andrew! That's a big help.

  • Posts: 2,161

    That's why they call it beta!

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    So - I feel like Barbie: "GLSL is hard".

    but - that's good. That's why it's fun.

    Most of the examples I look at online seem to have the model, view, and projection matrices passed as seperate entities. But - in the vertex shader in Codea, it's passing ( model * view * projection ). This is puzzling to me. Is this an OpenGL ES 2.0 thing? (it doesn't seem to be - but my selection so far of working ipad shader stuff is small).

    I am thinking that maybe, perhaps, the whole "normalize and clip and present" is already present in Codea itself, and so we don't do it? We would, presumably, do similar shenanigans by how we set up the mesh we're embedding the shader in - no?

    What I'm trying is to make a simple model (a cube would be fine) and light it. Don't tell me how! (yet) - This is how I learn. But if there's still some missing element, let me know. :-)

  • SimeonSimeon Admin Mod
    edited November 2012 Posts: 5,364

    It's faster to do the multiplication once, on the CPU than to do modelviewprojection for every vertex.

    You can however create custom uniforms for those matrices in your shader and set them in Codea:

    MyShader.modelMatrix = modelMatrix()

    Edit: To do lighting you will need to use a normal attribute. The intention is to have this link automatically to mesh normals, but I'm not sure if @John has implemented that yet. You can use custom attribute array by using the (currently undocumented) buffer class with meshes.

  • BortelsBortels Mod
    Posts: 1,557

    If the ipad sleeps when you're in a shader editor, and you go back in - Codea aborts.

    When you bring up the keyboard in a shader when you're toward the bottom of the code, the keyboard slides up to obscure the code you're editing.

    If you get a really long error message ("...rator '-' exists taking 'int' and 'float' (and no implicit type conversion allowed in GLSL 1.10)") - it obscures the line you made the error on, so you can't correct the error. (Hmm - lie. you can backspace. But if you navigate off that line, you can't put the cursor there. You can exit the shader, go back in, and the syntax errors don't show yet - and fix it then. Hmm. )

  • SimeonSimeon Admin Mod
    Posts: 5,364

    Thanks for those bug reports, @Bortels. Not sure of the best way to deal with the long-error-message one. I'll have to think about it.

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    So - do we expect 1.5 to ship with a model loader?

    Because I have a teapot (I need to shade something) that's not going to load itself.

    But before I go write a dumb-as-a-box-of-rocks .obj file loader - I figured I'd see if one was likely to be forthcoming. (Hmm - I should search the forum to see if someone beat me to it first...)

    PS. Looks like they beat me to it, in that I see a loader and can convert. :-)

  • SimeonSimeon Admin Mod
    Posts: 5,364

    Not for 1.5 — I do want one eventually but we won't have time to design it until all the features for 1.5 are completed.

    There will be some build-in 3D models in the shader lab (presets that you can select to preview your shader).

  • BortelsBortels Mod
    Posts: 1,557

    Ok - unrelated (maybe) editor bug. Steps to reproduce:

    1) portrait mode.
    2) poke the eye for help (cruel!)
    3) tap to move cursor into program text on a line that wraps.
    4) Type. Text is not showing up where the cursor is.

    When I kill the help text - the cursor is where the text is inserting, not where I tapped.

  • BortelsBortels Mod
    Posts: 1,557

    Just thinking ahead - picking a model format, then allowing import/export/picking of models like you do for images and shaders would be keen.

    I'd like to say 'm = mesh("Documents:Teapot")'

    I'd also like to say 'm = mesh("http://home.bortels.us/teapot.ply")'

    or image() or shader() for that matter. Just suggestions.

    I can load the 2.7 meg teapot in under 2 seconds. NOT TOO SHABBY. Haven't parsed it yet.

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    So - not all PLY is PLY. Just sayin.

    PS. I just caught myself; this happens every time. What I want to be doing is learning shaders and finding bugs in 1.5 - and what I've done for the last hour is research into writing a PLY loader (a robust one) in lua. Good stuff - worth doing - and completely irrelevant to something that might be useful for a beta test.

    Yak Shaving. It is my life.

  • Posts: 503

    Works really nice, good job! Will try it out a bit more this weekend! It would be nice if the shader lab populated the time variable if it exists in the shader.

  • Posts: 2,161

    Bug with watch. The first two watches are a bit funny. The first gets an extra table, the second is always nil. After that they straighten out.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    .@tnlogy the plan is to have those variables become interactive — like the colour picker in the main editor. So you could tap the time variable and slide a slider to change it. Or tap a texture to choose a new sample texture, and so on.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    .@Andrew_Stacey so any sequence of two watch() expressions causes odd behaviour?

  • edited November 2012 Posts: 2,161

    No, it was the first two in a project and after those two then all the others were fine.

    I was experimenting with the camera project. I added watch("camWidth") and watch("camHeight") and got the first as table:<junk> 480 and the second as nil. This puzzled me somewhat as if I printed those two then I got 0 and 0 (the discrepancy on values is because I was printing from setup before the camera had been initialised). So then I added dummy variables testa = camWidth and testb= camHeight to the camera setup routine and watched those. They were fine and gave the expected result. So then I added watch("nothing") watch("nothingelse") at the start and those two were table:<junk> nil and nil and all the other watches then worked just fine (there were six in total by this stage).

  • Posts: 489

    I am running out of superlatives for Codea. Christmas has come early.

    It would be good if the final version of version 1.5 could fix issue #203, so that it is easy again to take screen shots of what can be produced with the extended API.

  • JohnJohn Admin Mod
    edited November 2012 Posts: 616

    .@mpilgrem yeah we know what is causing this particular issue and will fix it for the 1.5 release.

  • Posts: 384

    Hi @Simeon - my impression of the beta is that it is great! I liked how you kept the examples simple. I would like the code arguments things to stick around rather than fade - I like to mull over my options. :)

    The camera is wonderful and shaders will be an interesting area of growth. I presume you will ship a few more sample ones with it. Although I will have to learn how shaders work, I was able to mess around and alter the colours. A question: if your shader is like the ripple one, how does the preview work if there is no frequency input that you get with parameter() in the actual project?

  • Posts: 503

    Interactive sounds great :)

    It's nice to easely edit the shaders from the Lua code view. But, maybe there is a need for a pause button in the shader view. When I modified an ink shader (used for my profile picture) I crashed Codea when I changed the step parameter in a for-loop and it was x+= .0 before I changed it to 1.0.

  • Posts: 503

    @Fred Simeon mentioned above that they will be interactive with sliders for the parameters.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    .@tnlogy yeah the immediate re-compilation can cause issues like that. I was thinking to have Codea recompile the shader on a short timer, about 0.2-0.5 seconds after your last key press. So rapid typing doesn't continuously recompile at every keystroke.

    However I definitely think we need a pause button too (this would also be a way of hiding obtrusive error messages).

  • BortelsBortels Mod
    Posts: 1,557

    that, or have a "see it now" button. (Plus maybe "revert to last working" option)

  • BortelsBortels Mod
    Posts: 1,557

    tween() confuses me. I can interrupt it (in the example) - but not always? I think it's a bug in the "tapCount" count in the example, actually. (Ah - yes. A bug in me - I tend to double-tap, which set the count > 1. Changing "== 1" to "> 0" made it work better for me)

    Just trying to understand it - you tween(), and that essentially runs as a background thread, until the animation is complete - right? Unless you tween.resetAll(). Is there a way to reset a specific tween?

  • SimeonSimeon Admin Mod
    Posts: 5,364

    To reset a particular tween you can use the ID returned from tween()

    local tid = tween( 1.0, someObject, {someTarget} )
     
    tween.reset( tid )
    tween.stop( tid )

    Tween doesn't run in a background thread, but it does get updated automatically at the same rate as the draw() function is called.

  • Posts: 2,161

    Is there a good tutorial on shaders somewhere? I'm trying some experiments and I don't know if it is shaders that I don't understand or Codea's implementation of them.

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    Nope.

    But having said that, this one is better than most: http://www.aerotwist.com/tutorials/an-introduction-to-shaders-part-1/

    it's based on webgl and three.js, so at least it's accessible. (Part 2 is actually more "meaty", but you go thru part 1 to get there)

  • Posts: 2,161

    Okay, here's my first go.

    Codea program

    function setup()
        m = mesh()
        local nsteps = 200
        local w = 5
        local h = 1/nsteps
        for n=1,nsteps do
            m:addRect(0,(n-.5)*h,w,h)
        end
        m.shader = shader("Documents:ExperimentOne")
        m.shader.time = 1
        a = vec2(0,0)
        b = vec2(100,0)
        c = vec2(200,200)
        d = vec2(200,300)
        m.shader.a = a
        m.shader.b = b
        m.shader.c = c
        m.shader.d = d
        m:setColors(255,255,25)
    end
    
    function draw()
        background(75, 104, 90, 255)
        strokeWidth(5)
        line(a.x,a.y,b.x,b.y)
        line(b.x,b.y,c.x,c.y)
        line(c.x,c.y,d.x,d.y)
        fill(160, 172, 22, 255)
        noStroke()
        ellipse(a.x,a.y,20)
        ellipse(b.x,b.y,20)
        ellipse(c.x,c.y,20)
        ellipse(d.x,d.y,20)
        m:draw()
    end
    
    function touched(touch)
        if touch.state == BEGAN then
        for k,v in ipairs({a,b,c,d}) do
            if v:distSqr(vec2(touch.x,touch.y)) < 900 then
                pt = v
            end
        end
        elseif pt then
            pt.x = touch.x
            pt.y = touch.y
        m.shader.a = a
        m.shader.b = b
        m.shader.c = c
        m.shader.d = d
        end
    end
    

    Vertex Shader


    // // A basic vertex shader // //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; attribute vec4 color; attribute vec2 texCoord; //This is an output variable that will be passed to the fragment shader varying lowp vec4 vColor; varying highp vec2 vTexCoord; uniform vec2 a; uniform vec2 b; uniform vec2 c; uniform vec2 d; uniform float time; void main() { highp float t = position.y/time; highp float tt = 1.0 - t; highp vec2 bpos = tt*tt*tt*a + 3.0*tt*tt*t*b + 3.0*tt*t*t*c + t*t*t*d; highp vec2 bdir = tt*tt*(b-a) + 2.0*tt*t*(c-b) + t*t*(d-c); bdir = vec2(bdir.y,-bdir.x); bdir = position.x*bdir/length(bdir); bpos = bpos + bdir; highp vec4 bzpos = vec4(bpos.x,bpos.y,0,1); //Pass the mesh color to the fragment shader vColor = color; vTexCoord = vec2(texCoord.x, 1.0 - texCoord.y); //Multiply the vertex position by our combined transform gl_Position = modelViewProjection * bzpos; }

    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; void main() { //Sample the texture at the interpolated coordinate lowp vec4 col = vColor; if (vTexCoord.x < .2) col.a = col.a*vTexCoord.x/.2; if (vTexCoord.x > .8) col.a = col.a*(1.-vTexCoord.x)/.2; //Set the output color to the texture color gl_FragColor = col; }

    What I need now is a list of available functions, a bit of guidence on syntax (what language is this?) and an explanation of what lowp and highp mean.

  • Posts: 2,161

    In other news:

    1. camera + harmony = fun
    2. the shader lab doesn't like it if you exit Codea while editing a shader. It crashes when I go back to Codea.
  • SimeonSimeon Admin Mod
    Posts: 5,364

    Interesting - just tried it out. Your shader draws a spline?

    This is the GLSL ES spec: http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf

    lowp, mediump and highp are precision specifiers. The actual ranges for them are specified at the bottom of page 33 of the spec. The spec calls them "minimum" ranges, but iOS devices tend to stick to those minimums.

    For example, a lowp float goes from -2, 2

    A lowp integer goes from -256, 256.

    It's much faster to use lowp in calculations than highp.

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    And - the language is "GLSL Shader language". No, really. (it's modeled to be familiar to people used to C/C++) It is optimized to do things the GPU does well (matrix math, vector stuff, and so on) and not have things the GPU doesn't need (strings, for example).

    You may also see HLSL floating around out there - that's the Microsoft DirectX version. Not identical, but similar enough to mechanically translate between them.

    I linked to a quick reference card above - the last 2 pages have a list of functions and so on.

  • Posts: 2,161

    Thanks for the reference, Bortels, and the spec, Simeon. I also found http://www.raywenderlich.com/10862/how-to-create-cool-effects-with-custom-shaders-in-opengl-es-2-0-and-cocos2d-2-x which felt like quite a gentle introduction.

    What is meant to happen if you use a shader that refers to a texture but no texture is set? When I had two meshes using the same shader then the one without a texture seemed to get something from the one with the texture. And when I had no texture then it behaved differently to when I had no shader (the shader was the "default" one which I guess ought to do "nothing").

  • Posts: 503

    Do you have any examples using two textures in a shader? It seems like there is a bug that all sampler variables get the mesh.texture texture instead. Unless I've missed something? Tried assigning an image element. Maybe would be nice if you could use the texture name directly?

    In the editor it would be nice with an imageRef() that shows the image picker dialog, when you need image-element for the texture.

  • Posts: 2,161

    And in reading around I learnt about frame buffers. This looks like a way to store information between runs. Is this possible at the moment? If not, will it be so? This would be fantastic for dynamic shaders.

  • edited November 2012 Posts: 580

    I know everyone is excited about shaders, but there are a couple of other new features that are also pretty exciting! :) One such feature is the ability to read, list, and save tabs in a project. To celebrate, I've created a function that, given a URL that points to a file, will create a new tab in the current project with the contents of the downloaded file.

    -- ImportURL
    
    -- Usage: importURL([tabname,] url)
    function importURL(tabname, url)
        tabname, url = url and tabname, url or tabname
    
        if not tabname then
            tabname = url:sub(#url - url:reverse():find("/", 1) + 2, #url)
            tabname = tabname:sub(1, tabname:find("%.", 1) - 1)
        end
    
        http.request(url, function(data, status, headers)
            if status == 200 then
                saveProjectTab(tabname, data)
                print("Tab '"..tabname.."' created")
            else
                print("Failed to download '"..url.."' to '"..tabname.."'")
            end
        end)
    end
    

    I recommend making a project with this as the only file in it (other than main), so that you can include it as a dependency for other projects. Then just call importURL() in your project with the URL of the file you want to download and import as a tab. Here's an example of downloading the awesome middleclass.lua from kikito's public github repo:

    importURL("https://raw.github.com/kikito/middleclass/master/middleclass.lua")
    

    When complete, a new tab named "middleclass" will be created in your project with the contents of middleclass.lua. You can also specify the desired tab name as an optional first argument if you'd like:

    importURL("MiddleClass", "https://raw.github.com/kikito/middleclass/master/middleclass.lua")
    

    One thing to be aware of is that the new tab will not appear until after you exit your project and re-enter it.

    .@Simeon: I'm not sure how easy this would be to do, but it might be worth considering to make Codea aware of when saveProjectTab() is called while a program is executing, and when execution ends and flow is returned to the editor, reload all of the tabs.

  • edited November 2012 Posts: 580

    As a bit of added fun I've created another bit of code that will download ImportURL.lua from my github repo, use loadstring() to inject the importURL function into the global namespace, and then call importURL to actually download the ImportURL.lua file and create a tab for it in your project. Put this in your setup() function:


    local url = "https://raw.github.com/apendley/CodeaMisc/master/ImportURL.lua" http.request(url, function(data, status, headers) if status == 200 then assert(loadstring(data))() importURL(url) end end)

    After you run the program, exit, and re-enter the project, you will now have an ImportURL tab with the importURL function! :)

  • Posts: 503

    About editing shaders again :). I think it would be nice if when editing a shader used in a program, to get the option to start the lua program from the shader view. When modifying a shader you move back and forth a lot between shader editor and lua editor just to press the play button for the lua code.

  • Posts: 2,161

    Yes, I was thinking that too. Especially when the shader has parameters then the shader preview is pretty useless. In those circumstances I'd quite like to be able to turn off the automatic version and be able to go quickly to a particular project.

  • BortelsBortels Mod
    edited November 2012 Posts: 1,557

    Did we enable file io and os.pwd? I'm about to leave, so can't test. Thinking of making a time-lapse camera thing, was trying to figure out how to save the images. (I figure I'll have to export them and make them into a movie on the pc...)

    The tab stuff looks exciting, in a very utility kind of way, but I'm into that... What happens if I save binary data into a tab?

  • edited November 2012 Posts: 580

    io and os.getenv are there. I've been able to create, write to, and read from files in Codea's Documents, Library/Caches, and tmp folders by getting Codea's root location using os.getenv('HOME'). I have not yet figured out how (or it's not possible) to create directories, or list the files in a directory.

    I'm willing to bet saving binary data into a tab will achieve nothing good, since Codea treats all tabs as .lua files.

Sign In or Register to comment.