LibGDX OpenGL线条质量改善

3

在这里输入图片描述

如何改善使用OpenGL绘制的线条质量?我不知道我是否以最好的方式进行操作。我正在使用ShareRenderer和line。但是,正如您在图像中看到的那样,圆角的渲染效果不是很好。 我通过Touch Down和Drag获取点,我认为这应该很容易画一条直线,但我想这需要在openGL中用不同的方法来完成。我希望用手指跟踪字母以学习书写。我可以使用openGL-es 1或2,没有关系。这张图片所使用的设备是三星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;
}

以下是更新后的渲染方法,用于绘制填充矩形和圆形,填充圆形效果更好。

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 : https://dev59.com/OWsz5IYBdhLWcg3wg4Cv
            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();

    }
2个回答

3

感谢您的出色回答。我尝试了实心圆,看起来好多了。然后我尝试了矩形,似乎无法正确渲染。如果我更新上面的代码,您能看出实现有什么问题吗? - tsukimi
请提出一个新的问题。此外,您需要提供一些除了“似乎无法正确渲染”的指示。我建议尝试绘制一些固定的示例输入(例如,在已知的分离位置上绘制点,以便您可以看到正在绘制的内容)。 - P.T.

0

为了使任何线条或形状更加平滑,您可以使用Multisample_anti-aliasing功能。

要做到这一点,您需要执行以下操作:

替换Gdx.gl.glClear()中的参数;使用以下内容:

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

除此之外,还需进入默认包,如android、html、desktop等,并添加以下行:

对于Android:

config.numSamples =2;

针对iOS:

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

适用于桌面:

config.samples = 3;

我对libGDX还很陌生,所以我觉得这是实现任何形状最简单的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接