feat: add kind parameter for beginShape function (supporting LINES, POINTS, TRIANGLE_FAN, TRIANGLE_STRIP, and TRIANGLES)#13
Conversation
…RIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN with fill and stroke
…RIANGLE_STRIP, and TRIANGLES
…_FAN in endShape function
|
Excellent. I just tested all of your example code plus the original versions on Processing's beginShape() reference page. Before merging, I thought worth considering one minor thing. What do you think we should return for incorrect passed kind parameters and un-implemented QUADS, QUAD_STRIP, TESS? Currently, there isn't error checking for incorrect Afterwards, we also need to update the vertex() reference page (to add info about u,v params) and the beginShape reference pages for info on |
|
I wrote this code in L5.lua to handle the error you've mentioned : function beginShape(_kind)
if(_kind ~= nil and not L5_env.shapeKinds[_kind]) then -- Lu_env.shapeKinds = {[POINTS]=true, [TRIANGLES]=true, ...}
error(_kind .. "is not defined" , 2)
end
-- reset custom shape vertices table
L5_env.vertices = {}
L5_env.useTexture = false
L5_env.kind = _kind
endIn Lua, any undefined global variable return nil, so if I called I think to override the returning nil behavior for the undefined variables or it adds overhead? Do you suggest another way to handle this error? |
|
Okay, good to brainstorm this. Unfortunately, I don't think that approach will work since there's no way to catch an undefined variable inside the function. Imagine someone passes an empty variable like BLAH, it will be undefined/nil, which will skip past the |
|
To be clear, I'm saying that |
|
I got to this approach function beginShape(...)
local n = select('#' , ...)
local _kind = select(1, ...)
if(n > 0 and _kind == nil) then
error(_kind .. "is not defined" , 2)
end
if _kind ~= nil and not L5_env.shapeKinds[_kind] then -- to check if you pass strings
error(_kind .. " is not defined", 2)
end
-- reset custom shape vertices table
L5_env.vertices = {}
L5_env.useTexture = false
L5_env.kind = _kind
endbut we can't print the I think we need to override the returning nil behavior for undefined variables to print |
|
I don't mean to leave this as a definitive review, I might be wrong here but I feel like there should also be a default value for |
|
It wouldn't work too as both |
|
No I think you can do it, you're almost there with your implementation. The |
|
@lee2sman can you see this please :D ? |
|
Cool idea @Nitish-bot That seems like a smart approach to solving that. Only alteration I can think of: No argument should fall through to polygon. Technically I think we can actually leave this out as it's a no-op, but there's no harm in leaving it in for verification. And thanks @georgeibrahim1 for all your work. Since the kind are mutually exclusive, So like this: if L5_env.kind == POINTS then
-- ...
return
elseif L5_env.kind == LINES then
-- ...
return
elseif L5_env.kind == TRIANGLES then
-- ...
return
elseif L5_env.kind == TRIANGLE_STRIP then
-- ...
return
elseif L5_env.kind == TRIANGLE_FAN then
-- ...
return
else
-- polygon mode (nil or unrecognized)
endOk, one other thing I wanted to note that seems important. The Love2d wiki points out inefficient / "expensive" functions. The one that concerns us here in creating custom shapes is love.graphics.newMesh. (Although through that discovery I see the same issue with love.graphics.newQuad, which is used in the copy() and blendMode() functions elsewhere in the L5 library, so should also concern us, maybe in a new issue here on github). You'll see this warning at the top of each of those wiki pages: This function can be slow if it is called repeatedly, such as from love.update or love.draw. If you need to use a specific resource often, create it once and store it somewhere it can be reused! Particularly if we are trying to make sure this library is efficient and can work on older hardware we should try to deal with that. One idea for an approach suggested could be to instead of creating a new mesh every draw call, for non-textured polygons we could create one global mesh upfront and just update it. Something like when we set the L5_env variables in define_env_globals() function: What this does: creates an instance of a new mesh only once. Gives it default x,y vertices. Specifies the same max number of vertices that Processing allows (I think): 4096, uses the 'triangulate' polygon fill default, and specifies neither "static" NOR "stream" but "dynamic" which means the vertices COULD change sometimes (such as for an animation) but not every frame (stream). Then we can replace non-textured new Mesh calls in endShape() function: L5_env.mesh:setVertices(verts, 1, #verts)
L5_env.mesh:setDrawMode("triangles")
L5_env.mesh:setDrawRange(1, #verts)
love.graphics.draw(L5_env.mesh)But we'd still just leave the (less efficient) use of newMesh() in place for drawing textures on shapes since they use more complex arrangement of vertices with x,y,u,v. Ok and bear with me as this looks like a monster. I think endShape() would look like like this. But I'm putting it here now for a moment for consideration. |
|
@lee2sman you nailed it wow! , I think my code is a trash now, I'll add your suggestions + implementations for QUADS , QUAD_STRIP , TESS implementations to close this issue. |
I want to know your feedback @lee2sman
Examples :