美文网首页libGdx专题
libGdx使用mesh画线

libGdx使用mesh画线

作者: 大旺旺的弟弟小旺旺 | 来源:发表于2022-03-28 14:25 被阅读0次

使用mesh画线,并贴上纹理。画线类

public class MashLine extends Group {
    private float mRadius = 0.0f;
    private float mThickness = 0.0f;
    private Array<Vector2> mPoints = null;
    private Boolean bDrawOutlines = false;
    private Boolean bDrawConstruction = false;
    ShapeRenderer shapeRender = null;
    ShaderProgram shader = null;
    Mesh mesh = null;
    FloatArray vertextArr = null;
    Texture texture = null;
    HashSet<TVertexData> vertexSet = null;

    public MashLine() {
        setSize(720,1280);
        setTouchable(Touchable.disabled);
        mRadius = 5.0f;
        mPoints = new Array<Vector2>();
        bDrawOutlines = true;
        bDrawConstruction = true;
        shapeRender = new ShapeRenderer();
        shader = new ShaderProgram(Gdx.files.internal("surface_vertex.gles"), Gdx.files.internal("surface_fragment.gles"));
        vertextArr = new FloatArray();
        texture = new Texture("line.png");
        texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
        texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
        mPoints = new Array<>();
        mThickness = texture.getHeight() / 2;
        vertexSet = new LinkedHashSet<>();





        addListener(new ClickListener() {
            Vector2 tmp = new Vector2();

            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                tmp.setZero();
                tmp.set(x, y);
                mPoints.add(tmp.cpy());
                return super.touchDown(event, x, y, pointer, button);
            }

            @Override
            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
                super.touchUp(event, x, y, pointer, button);
                if (mPoints.size > 1){
                    Gdx.app.log("xx", "point size:" + mPoints.size);
                    if (mesh != null) {
                        mesh.dispose();
                    }
                    MeshTools meshtools = new MeshTools();
                    vertextArr = meshtools.convert(mPoints, texture, mThickness);
                    int num = vertextArr.size / 4;
                    mesh = new Mesh(
                            true,
                            num,
                            num,
                            new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"),
                            new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord0")
                    );
                    mesh.setVertices(vertextArr.toArray());

                    ShortArray indexs = new ShortArray();
                    for (int i = 0; i < num; i++) {
                        indexs.add(i);
                    }
                    Gdx.app.log("", "" + indexs.size);
                    mesh.setIndices(indexs.toArray());
                    vertexSet.clear();
                    vertextArr.clear();
                }
            }
        });

    }

    public void setClear(){
        mPoints.clear();
    }

    public void setPoint(Vector2 vector2){
        mPoints.add(vector2.cpy());
        if (mPoints.size > 1) {
            MeshTools meshtools = new MeshTools();
            vertextArr = meshtools.convert(mPoints, texture, mThickness);
            int num = vertextArr.size / 4;
            mesh = new Mesh(
                    true,
                    num,
                    num,
                    new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"),
                    new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord0")
            );
            mesh.setVertices(vertextArr.toArray());

            ShortArray indexs = new ShortArray();
            for (int i = 0; i < num; i++) {
                indexs.add(i);
            }
            Gdx.app.log("", "" + indexs.size);
            mesh.setIndices(indexs.toArray());
            vertexSet.clear();
            vertextArr.clear();
        }
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        for (int i = 0; i < mPoints.size; i++) {
            Vector2 vec = mPoints.get(i);
            shapeRender.setColor(Color.RED);
            shapeRender.begin(ShapeRenderer.ShapeType.Filled);
            shapeRender.circle(vec.x, vec.y, mRadius);
            shapeRender.end();
        }
        for (int i = 0; i < mPoints.size; i++) {
            int a = i-1<0 ? 0 : i - 1;
            int b = i;
            int c = i + 1 >= mPoints.size ? mPoints.size - 1 : i + 1;
            int d = i + 2 >= mPoints.size ? mPoints.size - 1 : i + 2;
            drawSegment(mPoints.get(a), mPoints.get(b), mPoints.get(c), mPoints.get(d));
        }
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        if (mesh != null) {
            Gdx.gl.glDepthMask(false);
            Gdx.gl.glEnable(GL20.GL_BLEND);
            Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
            Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
            texture.bind();
            shader.begin();
            shader.setUniformMatrix("u_worldView", batch.getProjectionMatrix());
            mesh.render(shader, GL20.GL_TRIANGLE_STRIP);
            shader.end();

            Gdx.gl.glDepthMask(true);
        }
    }


    void insertData( TVertexData data, FloatArray array) {
        Gdx.app.log("", data.toString());
        array.add(data.pos.x);
        array.add(data.pos.y);

        array.add(data.u);
        array.add(data.v);
    }

    void drawSegment(Vector2 p0, Vector2 p1,Vector2 p2 ,Vector2 p3 ) {
        if (p1.equals(p2)) return;

        Vector2 line = p2.cpy().sub(p1).nor();

        Vector2 normal = new Vector2(-line.y, line.x).nor();

        Vector2 tangent1 =  (p0 == p1) ? line : ((p1.cpy().sub(p0).nor().add(line)).nor());
        Vector2 tangent2 =  (p2 == p3) ? line : ((p3.cpy().sub(p2).nor().add(line)).nor());
        Vector2 miter1 = new Vector2(-tangent1.y, tangent1.x);
        Vector2 miter2 = new Vector2(-tangent2.y, tangent2.x);


        float length1 = mThickness / normal.dot(miter1);
        float length2 = mThickness / normal.dot(miter2);

        shapeRender.begin(ShapeRenderer.ShapeType.Line);

        if (bDrawConstruction) {
            Gdx.gl.glLineWidth(1.0f);
            shapeRender.setColor(Color.BLACK);
            shapeRender.line(p1, p2);
            // draw normals in stippled red
            shapeRender.setColor(Color.RED);
            Gdx.gl.glEnable(GL20.GL_LINE_STRIP);
            drawDashedLine(Color.RED, shapeRender, new  Vector2(5f, 5f), p1.cpy().sub(normal.cpy().scl(mThickness)), p1.cpy().add(normal.cpy().scl(mThickness)), 0.5f);
            drawDashedLine(Color.RED, shapeRender, new  Vector2(5f, 5f), p2.cpy().sub(normal.cpy().scl(mThickness)), p2.cpy().add(normal.cpy().scl(mThickness)), 0.5f);
            Gdx.gl.glDisable(GL20.GL_LINE_STRIP);

            shapeRender.setColor(Color.GRAY);
            Gdx.gl.glEnable(GL20.GL_LINE_STRIP);
            shapeRender.line(p1.cpy().sub(normal.cpy().scl(mThickness)), p2.cpy().sub(normal.cpy().scl(mThickness)));
            shapeRender.line(p1.cpy().add(normal.cpy().scl(mThickness)), p2.cpy().add(normal.cpy().scl(mThickness)));
            Gdx.gl.glDisable(GL20.GL_LINE_STRIP);
        }

        if (bDrawOutlines) {
            Gdx.gl.glLineWidth(1.5f);
            shapeRender.setColor(Color.BLACK);
            Vector2 v0 = p1.cpy().sub(miter1.cpy().scl(length1));
            Vector2 v1 = p2.cpy().sub(miter2.cpy().scl(length2));

            Vector2 v2 = p1.cpy().add(miter1.cpy().scl(length1));
            Vector2 v3 = p2.cpy().add(miter2.cpy().scl(length2));

            shapeRender.line(v0, v1);
            shapeRender.line(v2, v3);

            Gdx.gl.glEnable(GL20.GL_LINE_STRIP);
            drawDashedLine(Color.BLACK, shapeRender,new  Vector2(5f, 5f), p1.cpy().sub(miter1.cpy().scl(length1)), p1.cpy().add(miter1.cpy().scl(length1)), 0.5f);
            drawDashedLine(Color.BLACK, shapeRender, new Vector2(5f, 5f), p1.cpy().sub(miter1.cpy().scl(length1)), p2.cpy().add(miter2.cpy().scl(length2)), 0.5f);
            drawDashedLine(Color.BLACK, shapeRender,new Vector2(5f, 5f), p2.cpy().sub(miter2.cpy().scl(length2)), p2.cpy().add(miter2.cpy().scl(length2)), 0.5f);
            Gdx.gl.glDisable(GL20.GL_LINE_STRIP);
        }
        shapeRender.end();
    }

    void drawDashedLine(Color color ,ShapeRenderer renderer,Vector2 dashes ,Vector2 start,Vector2 end ,Float width) {
        if (dashes.x == 0.0f) {
            return;
        }
        float dirX = end.x - start.x;
        float dirY = end.y - start.y;

        float length = Vector2.len(dirX, dirY);
        dirX /= length;
        dirY /= length;

        float curLen = 0f;
        float curX = 0f;
        float curY = 0f;

        renderer.setColor(color);

        while (curLen <= length) {
            curX = start.x + dirX * curLen;
            curY = start.y + dirY * curLen;
            renderer.rectLine(curX, curY, curX + dirX * dashes.x, curY + dirY * dashes.x, width);
            curLen += dashes.x + dashes.y;

        }
    }

    private Vector2 save4() {
        this.x = ((Math.round(this.x * 10000f)) / 10000f);
        this.y = ((Math.round(this.y * 10000f)) / 10000f);
        return null;
    }
}

控制顶点

package wk.demo.block.screen.load;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.tony.rider.test.MashLine;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import wk.demo.block.Bse;
import wk.demo.block.BseInterpolation;
import wk.demo.block.constant.Constant;
import wk.demo.block.utils.ShapeDraw;

public class GameView extends Group {
    private ShapeDraw shapeDraw;
    MashLine line ;
    public GameView(){
        setDebug(true);
        setSize(Constant.width,720);
        xx();
        line = new MashLine();
        addActor(line);
        this.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                if (y>720)return;
                super.clicked(event, x, y);
                long l = System.currentTimeMillis() - lastTime;
                lastTime = System.currentTimeMillis();
                if (l<1000){
                    Image image = new Image(new Texture("white_cir.png"));
                    addActor(image);
                    image.setPosition(x,y);
                    image.addListener(imgaeListener);
                    array.add(image);
                    array1.clear();
                    controlPoint.clear();
                    for (int i = 0; i < array.size; i++) {
                        controlPoint.add(array.get(i).getPosition());
                    }
                    jisuan(controlPoint);

                }
            }
        });

        Image image = new Image(new Texture("white_squ.png"));
        image.setPosition(getWidth() - 260,830);
        addActor(image);


        Image image1 = new Image(new Texture("white_squ.png"));
        addActor(image1);
        image1.setY(830);


        Image image3 = new Image(new Texture("white_squ.png"));
        addActor(image3);
        image3.setY(830);
        image3.setX(0,Align.center);
        image3.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                super.clicked(event, x, y);
               image1.setScale(1,1);
            }
        });

        image.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                super.clicked(event, x, y);
//                image1.addAction(Actions.scaleTo(3,3,3, new Bse(array1)));
                BseInterpolation bseInterpolation = new BseInterpolation();
                bseInterpolation.setCurve(0.25F, 0, 0.75F, 1F);
                image1.addAction(Actions.scaleTo(3,3,3, bseInterpolation));
                save();
            }
        });


    }
    Image image;
    private boolean start = false;
    private long lastTime = Integer.MIN_VALUE;
    private ClickListener imgaeListener = new ClickListener(){
        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            return super.touchDown(event, x, y, pointer, button);
        }

        @Override
        public void touchDragged(InputEvent event, float x, float y, int pointer) {
            super.touchDragged(event, x, y, pointer);
            event.getTarget().setPosition(event.getStageX(),event.getStageY());
            array1.clear();
            controlPoint.clear();
            for (int i = 0; i < array.size; i++) {
                controlPoint.add(array.get(i).getPosition());
            }
            jisuan(controlPoint);

            line.setClear();

            for (int i = 0; i < array1.size; i++) {
                Vector2 vector2 = array1.get(i);
                line.setPoint(vector2);
            }}

        @Override
        public void clicked(InputEvent event, float x, float y) {
            super.clicked(event, x, y);
        }
    };

    private Array<Vector2> controlPoint = new Array<Vector2>();
    private Array<Image> array = new Array<>();
    private Array<Vector2> array1 = new Array<>();
    Vector2 sss = new Vector2(360,0);
    public void xx() {
//        [{x:69,y:732},{x:366,y:111},{x:300,y:774},{x:681,y:684}]
//        controlPoint.add(new Vector2(69, 732)); //起点
//        controlPoint.add(new Vector2(366, 111)); //控制点
//        controlPoint.add(new Vector2(300, 774)); //控制点
//        controlPoint.add(new Vector2(681, 684)); //终点

        controlPoint.add(new Vector2(0, 0)); //起点
        controlPoint.add(sss);
        controlPoint.add(new Vector2(710, 0)); //终点
        for (Vector2 vector2 : controlPoint) {
            Image image = new Image(new Texture("white_cir.png"));
            addActor(image);
            image.setPosition(vector2.x,vector2.y);
            image.addListener(imgaeListener);
            array.add(image);
        }
       jisuan(controlPoint);
        shapeDraw = new ShapeDraw();
        addActor(shapeDraw);
        shapeDraw.setArray(array1);
        shapeDraw.setLine(controlPoint);
    }

    public void jisuan(Array<Vector2> controlPoint){
        int n = controlPoint.size - 1; //
        int i, r;
        float u;
        // u的步长决定了曲线点的精度
        for (u = 0; u <= 1; u += 0.01) {
            Vector2 p[] = new Vector2[n + 1];
            for (i = 0; i <= n; i++) {
                p[i] = new Vector2(controlPoint.get(i));
            }
            for (r = 1; r <= n; r++) {
                for (i = 0; i <= n - r; i++) {
                    p[i].x = (1 - u) * p[i].x + u * p[i + 1].x;
                    p[i].y = (1 - u) * p[i].y + u * p[i + 1].y;
                }
            }
            array1.add(p[0]);
        }
    }

    public void save(){
        try {
            FileWriter stream = new FileWriter(new File("./text.txt"));
            for (Vector2 vector2 : controlPoint) {
                stream.write(vector2.x+", "+vector2.y+" ");
            }
            stream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private float timess = 0;
    private int index= 0;
    private int deIndex = 1;
    @Override
    public void act(float delta) {
        super.act(delta);
        timess += delta;
        if (start) {
            if (timess > 0.1F){
                sss.y = sss.y +5;
                array1.clear();
                jisuan(controlPoint);
                if (index>=array1.size-1)deIndex =-1;
                if (index<=0)deIndex = 1;
                Vector2 vector2 = array1.get(index);
                image.setPosition(vector2.x,vector2.y,Align.center);
                timess = 0;
                index+=deIndex;
            }
        }
    }
}

效果:


image.png

相关文章

网友评论

    本文标题:libGdx使用mesh画线

    本文链接:https://www.haomeiwen.com/subject/yispjrtx.html