Howdy, Stranger!

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

Mesh textures for polygons of 4 vertices or more

edited February 2015 in Questions Posts: 277

Hi there!

I've got another of these mesh textures questions. This one is probably hopeless but I'd kick myself if it weren't.

I have many bodies of different shapes (not only triangles) that I want to texture and draw.

I've read this great tutorial : http://codea.io/talk/discussion/1244/mesh-tutorial

and managed to draw textures to triangles using

meshes[meshId].vertices = triangulate(points)   
meshes[meshId].texture = readImage("texture1")
meshes[meshId].texCoords = {vec2(0,0),vec2(1,0),vec2(0,1)}

Which gives this, and I like it:

When I try to draw polygons of 4 vertices, I do this:

meshes[meshId].vertices = triangulate(points)
meshes[meshId].texture = readImage("texture1")
meshes[meshId].texCoords = {vec2(0,0),vec2(1,0),vec2(0,1),vec2(0,1),vec2(1,1),vec2(1,0)}

as explained in the tutorial.

It works as expected :

the polygons are each divided in triangles and the texture is applied to stitched triangles. The dividing line is quite visible, that's quite normal and fine in most case.

Except, I'm feeling fancy... Ahahaha.

Is there a way to trick to mesh texture rendering system so that we would avoid these stitch-lines. by, for instance, rendering way larger than the polygon, but only showing the shape of that polygon (as if each polygon was cookie-cuting a larger, square, texture...)?

Like this:

I'm probably dreaming, but I thought I'd ask.

Cheers!

Tagged:

Comments

  • Not sure what you're asking here...if you're asking how to render only part of an image, it actually is quite easy. Say you want to render 90% of the image, I believe it would be

    meshes[meshId].texCoords = {vec2(0.05,0.05),vec2(0.95,0.05),vec2(0.05,0.95),vec2(0.05,0.95),vec2(0.95,0.95),vec2(0.95,0.05}
    

    That would render 90% of the texture onto the mesh, being the inner 90% rectangle.
    Please tell me if this is what wou were looking for. If not, I'll try to help you if you can elaborate more on what you're looking for.

  • edited February 2015 Posts: 277

    Oh, ok, that wasn't clear you're right. It's kind of difficult to explain...

    Ultimately, I want to draw complex textured polygons without seeing any seam, or sharp texture transitions, inside each polygon (as triangulation does). As if each polygon was cookie-cuting a larger, square, texture...

    like this:

  • dave1707dave1707 Mod
    edited February 2015 Posts: 7,604

    @Rodolphe Here's a simple mesh of 2 triangles. Set m to 0 to show colors or set m to 1 to show a texture. These don't show the dividing line. Is this what you're after.

    EDIT: Corrected an error.

    displayMode(FULLSCREEN)
    
    function setup()    
    
        m=0 -- set to 0 for colors, 1 for texture
    
        myMesh = mesh()   
        myMesh.vertices = {vec2(100,100),vec2(500,100),vec2(400,600),
                           vec2(100,100),vec2(100,400),vec2(400,600)}                                           
        myMesh.texCoords = {vec2(0,0),vec2(1,0),vec2(1,1),
                            vec2(0,0),vec2(0,1),vec2(1,1)}  
    
        if m==0 then      
            myMesh:setColors(230,230,230,255)          
            myMesh:color(1,255,0,0,255)
            myMesh:color(2,0,255,0,255)
            myMesh:color(3, 0, 0, 255,255)
            myMesh:color(4,255,0,0,255)
            myMesh:color(5,0,255,0,255)
            myMesh:color(6, 0, 0, 255,255)
        else
            myMesh.texture = "Cargo Bot:Game Area"
        end
    end
    
    function draw()
        myMesh:draw()
    end
    
    
  • Posts: 277

    Wow! it is what I'm after indeed. I don't get what the major difference is with what I'm doing, though. I'm tweeting my code to make it work like yours, I'll get back to you. Thanks a lot!

  • (Untested)

    points = {<the list of points>}
    mi = points[1] -- will end up holding the lower left of the bounding box
    ma = points[1] -- will end up holding the upper right of the bounding box
    for k,v in ipairs(points) do
        mi.x = math.min(mi.x,v.x)
        mi.y = math.min(mi.y,v.y)
        ma.x = math.max(ma.x,v.x)
        ma.y = math.max(ma.y,v.y)
    end
    vertices = triangulate(points)
    texCoords = {}
    for k,v in ipairs(vertices) do
        u = v - mi
        u.x = u.x/(ma.x - mi.x)
        u.y = u.y/(ma.y - mi.y)
        table.insert(texCoords,u) -- u is now v rescaled to "bounding box" coordinates
    end
    myMesh.vertices = vertices
    myMesh.texCoords = texCoords
    
  • edited February 2015 Posts: 277

    Thanks @LoopSpace, testing it right now...

    EDIT: doesn't work for now, can't seem to find the the upper right of the bounding box...

    RE-EDIT: I tried with less than optimal mi and ma, and it works like a charm. I just need to figure out how to find the bounding box for real... Thank you so much!!!!!

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Rodolphe - the above approach requires your texture image to be bigger than the bounding box.

    If this becomes impractical, and you need to tile an image (ie use it multiple times) across a large area, I have a shader based approach that will do it.

  • Can you post the code that isn't working? My code ought to find the bounding box so I'm curious as to why it isn't working.

  • Posts: 277

    Oh, alright @LoopSpace, I made it work looking at it this morning. Thanks! Thanks @Ignatz, too, I'll let you know if thais becomes an issue.

  • Hi everyone, sorry to post on an old thread (new to posting and not sure if that is bad forum etiquette).
    I am trying to implement the method described by @LoopSpace to texture polygons with 6+ vertices using an image. Basically, I have a texture image the size of the screen that I am trying to "cookie-cut" as described by @Rodolphe, but instead of taking a cut out of the image the mesh just becomes one color (my assumption is that it is taking one pixel from the image and texturing the whole mesh with that).

    I have posted my code below. Please let me know if I am doing something wrong or if I should try a different approach to get the results I am looking for. I appreciate in advance any help!

    function Meshdraw:init(x)
    
        mymesh = mesh()
        img = readImage("Documents:screen") 
        mymesh.texture = img
        mi = points[1]
        ma = points[1]
        for k,v in ipairs(points) do
            mi.x = math.min(mi.x,v.x)
            mi.y = math.min(mi.y,v.y)
            ma.x = math.max(ma.x,v.x)
            ma.y = math.max(ma.y,v.y)
        end
    
       vertices = triangulate(points)
       texCo = {}
    
        for k,v in ipairs(vertices) do 
            u = v - mi
            u.x = u.x/(ma.x - mi.x)
            u.y = u.y/(ma.y - mi.y)
            table.insert(texCo,u)
        end
    
        mymesh.vertices = vertices 
        mymesh.texCoords = texCo
        mymesh:setColors(color(255)) 
    end
    
    function Meshdraw:draw()
        mymesh:draw()
    end
    
  • dave1707dave1707 Mod
    edited December 2016 Posts: 7,604

    @cmingo Here's an example that you might be able to use. I created the points to look like 4 seperate meshes, but the points can also be changed to be one irregular shaped mesh. I'm showing the Sprite with the same size as the texture.

    EDIT: Don't worry about bringing up an old thread if it has a purpose. Just don't bring up an old thread just to say you like it.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        spriteMode(CORNER)
        img=readImage("Cargo Bot:Startup Screen")
        myMesh=mesh()
        points =    {   vec2(100,100),vec2(200,100),vec2(100,200),
                        vec2(100,200),vec2(200,200),vec2(200,100),
                        vec2(250,100),vec2(400,100),vec2(300,400),
                        vec2(100,210),vec2(260,210),vec2(180,400),
                        vec2(210,370),vec2(280,370),vec2(255,250)   
                    }
        mi=vec2(9999,9999)
        ma=vec2(-9999,-9999)
        for k,v in pairs(points) do
            mi.x = math.min(mi.x,v.x)
            mi.y = math.min(mi.y,v.y)
            ma.x = math.max(ma.x,v.x)
            ma.y = math.max(ma.y,v.y)
        end
        texCoords = {}
        for k,v in ipairs(points) do
            u = v - mi
            u.x = u.x/(ma.x - mi.x)
            u.y = u.y/(ma.y - mi.y)
            table.insert(texCoords,u)
        end
        myMesh.vertices = points
        myMesh.texCoords = texCoords
        myMesh.texture=img
    end
    
    function draw()
        background(0)
        fill(255)
        text("Mesh overlay",230,450)
        myMesh:draw()
        text("Normal sprite",630,450)
        sprite(img,500,100,270,300)
    end
    
  • @dave1707 Thank you so much for this! I was able to tweak the example a little to do exactly what I wanted. I've attached my resulting code just in case someone runs into the same exact problem I was having.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        spriteMode(CORNER)
        img=readImage("Cargo Bot:Startup Screen")
        myMesh=mesh()
        points = {vec2(100,100),vec2(200,100),vec2(200,300),vec2(150,350),vec2(100,200),vec2(100,100)}
    
        mi=vec2(9999,9999)
        ma=vec2(-9999,-9999)
        for k,v in pairs(points) do
            mi.x = math.min(mi.x,v.x)
            mi.y = math.min(mi.y,v.y)
            ma.x = math.max(ma.x,v.x)
            ma.y = math.max(ma.y,v.y)
        end
    
        texCoords = {}
        for k,v in ipairs(points) do
            u = v - mi
            u.x = u.x/WIDTH 
            u.y = u.y/HEIGHT 
            table.insert(texCoords,u)
        end
        myMesh.vertices = triangulate(points)
        myMesh.texCoords = triangulate(texCoords)
        myMesh.texture=img
    end
    
    function draw()
        background(0)
        fill(255)
        text("Mesh overlay",230,450)
        myMesh:draw()
        text("Normal sprite",630,450)
        sprite(img,500,100,270,300)
    end
    
    
Sign In or Register to comment.