Request: allow setting texture coordinates with sprite() command

It would be great if we could specify the texture rect of a sprite drawn with the sprite() command.

If it’s not possible to add the s, t, tw, th parameters to the end while keping w and h optional, then I propose an alternate version of sprite:

spriterect(image, x, y, s, t, tw, th, w, h)

I have opened up an issue for this at https://bitbucket.org/TwoLivesLeft/codea/issue/151/modify-sprite-function-to-accept-texture

Isn’t that possible with clip()? I don’t know exactly what the s, t, tw, th variables should do, but if I guess correctly, that should just be doable with clip.

no, clip() sets up glScissor. I’m talking about modifying the texture coordinates of a texture mapped onto a quad. s,t is the normalized coordinate for the upper left hand corner of a texture to use when mapping, tw,th is the normalized size of rect to map onto the quad. With the sprite() function, s, t, tw, and th are always 0, 0, 1, 1 respectively. I would like to be able to modify those.

@toadkick iow you want to make 3d sprites? and still be able to use them with regular 2d coord touch. Can someone please write an NDC tutorial for the 3d vectors?

No, this has nothing to do with 3D sprites, it just has to do with texture mapping. All of Codea’s sprites are 6-polygon (2 triangles) “meshes” with a texture mapped to them. The texture coordinates paired with each vertex describe which texels to map onto the sprite’s polygons. What I want to be able to do is choose the texture coordinates from my texture to map onto the polys, instead of mapping the entire texture as it is now.

@toadkick good request.

We can design it as follows:

sprite( image, x, y )
sprite( image, x, y, w ) -- h is computed on aspect ratio
sprite( image, x, y, w, h )
sprite( image, x, y, s, t, tw, th )
sprite( image, x, y, s, t, tw, th, w ) -- as before
sprite( image, x, y, s, t, tw, th, w, h ) 

Or in the following way:

sprite( image, x, y )
sprite( image, x, y, w ) -- h is computed on aspect ratio
sprite( image, x, y, w, h )
sprite( image, x, y, w, h, s, t, tw, th )

The latter is good because it preserves the existing argument ordering in all cases. However the former has the advantage of not requiring you to have to type values for w and h when using explicit texture coordinates.

So it’s either: save on typing, or preserve API consistency. A hard decision.

Alternatively we could do an advanced sprite function that takes a table.

sprite( image, table )

Where table contains the following keys: x, y, w, h, s, t, tw, th

What are your thoughts?

Is it possible to allow nil as values for w and h ? Then you could preserve the ordering? In my head, everything I do not give parameters, it’s always nil.

I don’t like option 3 because I don’t feel it necessary to introduce the overhead of creating a table to pass the parameters. My preference would be for the first one, since a) the API change wouldn’t break existing code, and b) as you mentioned w/h could still be optional. I don’t think option 1 makes the API inconsistent at all, since s, t, tw, th don’t really mean anything unless they are all specified, and since it’s just shifting already optional parameters to the end if s, t, tw, th are specified. Most people will not even notice the change anyway, since currently it’s not even possible to specify s, t, tw, and th. FWIW, Lua’s creators have made similar choices in their own libraries (see table.insert(table, [pos], value)).

@toadkick good argument, option one sounds good to me too.

Just for fun, a function that does it using a mesh, which is cached for reuse:

function spritex(image, x, y, w, h, s, t, tw, th)
    if tmpMesh_ == nil then
        tmpMesh_ = mesh()
        tmpMesh_.texture = image
        tmpMesh_:addRect(0,0,0,0,0)
    end
       
    tmpMesh_.texture = image
    tmpMesh_:setRect(0, x, y, w, h)
    tmpMesh_:setRectTex(0,s,t,tw,th)
    tmpMesh_:setRectColor(0, unpack(fill()))
    tmpMesh_:draw()
end

Nice one, @John. That’s pretty cool.

That is cool @John :slight_smile:

Hey @John, I can’t get this to work.
Could you please write a small example using one of the sample images?