3

enter image description here

How can i improve the quality of line drawn using openGL. I dont know if im doing this the best way . Im using ShareRenderer and line. But as you can see in the image round corners dont render very well. Im getting points in touch down and drag, i thought this would be easy to draw a line but i guess this needs to done differently in openGL. I want to trace over letters with a finger for learning to write. I can use openGL-es 1 or 2 , doesn't matter. The device used here for the image was Samsung S3.

  @Override
    public void render(float delta) {
        super.render(delta);
        if(mPoints.size() < maxPoints) return;
        shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
        for(int i=0; i < maxPoints-1; i++) {
            Vector3 pnt = mPoints.get(i); 
            if(pnt.x == 0 && pnt.y == 0) continue;
            Vector3 pnt2 = mPoints.get(i+1); 
            if(pnt2.x == 0 && pnt2.y == 0) continue;
            shapeRenderer.line(pnt.x,  pnt.y, pnt2.x, pnt2.y);
        }
        shapeRenderer.end();

    }
@Override
public void resize(int width, int height) {
    super.resize(width, height);
    shapeRenderer.setProjectionMatrix(getCamera().combined);
    Gdx.gl20.glLineWidth(200);
    Gdx.gl.glEnable(GL20.GL_BLEND);
}

@Override
    public boolean touchDown(int x, int y, int pointer, int button) {
        currentFinger = pointer;
        if (++numStrokes >= 2) { //number of strokes for a letter
            numStrokes = 0;
            clearAllPoints();
            currentPointIndex = 0;
        }
        setPoint(0, 0);
        return false;
    }

@Override
public boolean touchDragged(int x, int y, int pointer) {
    if(currentFinger!=pointer) return false;
   Vector3 pnt = mPoints.get(currentPointIndex);
   tempVector.set(x, y, 0);
   getCamera().unproject(tempVector);
   float dx = Math.abs(tempVector.x - pnt.x);
   float dy = Math.abs(tempVector.y - pnt.y);
   if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        setPoint(x, y);
   }
   return false;
}

UPDATED render method below to draw filled rectangles and circles, filled circles works much better.

public void render(float delta) {
        super.render(delta);
        if(mPoints.size() < maxPoints) return;
        shapeRenderer.begin(ShapeRenderer.ShapeType.FilledRectangle);
        for(int i=0; i < maxPoints-1; i++) {
            Vector3 pnt = mPoints.get(i); 
            if(pnt.x == 0 && pnt.y == 0) continue;
            Vector3 pnt2 = mPoints.get(i+1); 
            if(pnt2.x == 0 && pnt2.y == 0) continue;

            //This creates a rectangle from the set of points see : http://stackoverflow.com/questions/7854043/drawing-rectangle-between-two-points-with-arbitrary-width
            dist.set(pnt2.x - pnt.x, pnt2.y - pnt.y, 0);
            pVector.set(dist.y, -dist.x, 0); //Find perpendicular (right angle) to points , basically swap x and y , make one negative
            float length = (float) Math.sqrt(pVector.x * pVector.x + pVector.y * pVector.y); //Thats length of perpendicular

            normVector.set(pVector.x - length, pVector.y-length, 0);
            //shapeRenderer.filledCircle(pnt.x, pnt.y, lineWidth);
            shapeRenderer.filledRect(pnt.x - pVector.x * rectWidth/2 , pnt.y - pVector.y * rectWidth /2, rectWidth, rectWidth);
        }
        shapeRenderer.end();

    }
tsukimi
  • 1,605
  • 2
  • 21
  • 36

2 Answers2

3

OpenGL line width other than 1.0 is not well supported in OpenGL ES, so you should avoid it on Android (See Libgdx gl10.glLineWidth()).

To get a smoother, more rounded looking "fat lines", draw each touch point as a circle, and connect points that are more than a couple pixels apart with a rectangle.

See:

Community
  • 1
  • 1
P.T.
  • 24,557
  • 7
  • 64
  • 95
  • Thanks for the great answer. I tried filled circles, looks much better. I then tried rectangles , didn't seem to render properly.If i update the code above can you see what is wrong with the implementation? – tsukimi Jan 09 '14 at 03:31
  • Please ask a new question. Also, you'll need to provide some indication beyond "didn't seem to render properly". I suggest trying to draw some fixed example inputs (e.g., points at know, separated locations so you can see what is being drawn.) – P.T. Jan 09 '14 at 06:33
0

TO smoother any line or shape you can use feature of Multisample_anti-aliasing

to do this what you have to do is:

replace the parameters in Gdx.gl.glClear(); use this:

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat().coverageSampling?GL20.GL_COVERAGE_BUFFER_BIT_NV:0));

and in addition to this go to default packages like android html desktop etc and add this line

for android:

config.numSamples =2;

for ios:

config.multisample = GLKViewDrawableMultisample.valueOf("2");

for desktop:

config.samples = 3;

I am new to libGDX so i found this the easiest way to do it with any shape..

Ashwani
  • 1,294
  • 1
  • 11
  • 24