我要画一个这样的笔划圆:
我尝试使用普通的顶点着色器和片段着色器,例如google samples,顶点坐标为364点:
vertices = new float[364 * 3];
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = 0;
for (int i =1; i <364; i++){
vertices[(i * 3)+ 0] = (float) (0.5 * Math.cos((3.14/180) * (float)i ));
vertices[(i * 3)+ 1] = (float) (0.5 * Math.sin((3.14/180) * (float)i ));
vertices[(i * 3)+ 2] = 0;
}
然后使用以下方法绘制:
int COORDS_PER_VERTEX = 3;
int vertexCount = 364 * 3 / COORDS_PER_VERTEX;
int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 1, vertexCount - 1);
但是结果与预期不符,我的圈子中有4个缺失的部分。
如何像上面的示例一样绘制笔划的圆?
答案 0 :(得分:2)
问题是实现glLineWidth
的方式。根据{{3}}:
宽度非一个的非抗锯齿线段通过在短方向上偏移来栅格化(对于x主线,次方向为y,对于y主线,次方向为x)并沿次要方向复制片段(见图3.3)。
这4个缺失部分对应于您的圆线从x-主要变为y-主要的位置。如果仔细看,您会发现随着x-major和y-major之间的切换,圆也变细了。
最好的选择是放弃画线,而改用三角带渲染实心带。即spec中的“三角线”示例也提出了一些更高级的解决方案。
答案 1 :(得分:0)
大多数库使用“三角线”,我认为这是绘制笔触线的最佳方法,因为您可以设置渐变颜色,控制线的不同部分的线宽并绘制平滑线。
但是,如果您想用单色创建笔划圆,您可以做的一招是创建 strokeWidth 为 1f 的多个圆,然后改变其半径使得每个下一个圆的半径比上一个圆大+(1f / 2)。
我创建了一个OpenGL library,它可以创建多种类型的形状,例如三角形,圆形,三角形等。以下是使用library生成多个圆圈的代码,其结果如上图所示。
lateinit var circles: Circles // OpenGL circles object
fun createCircles() {
val coordinatesInfo = generateCoordinateInfo(400f, 400f, 100f, 20)
// set object for the OpenGL circles
circles = Circles(
// in format: [cx1,cy1,radius1,angle1, cx2,cy2,radius2,angle2,...]
coordinatesInfo = coordinatesInfo,
colors = intArrayOf(Color.RED),
style = STYLE_STROKE,
strokeWidth = 1f,
preloadProgram = program,
gestureDetector = mainGestureDetector,
useSingleColor = true
)
}
/**
* Get the coordinates for the stroke circles
* @param x x coordinate of the circle
* @param y y coordinate of the circle
* @param r radius of the circle
* @param strokeWidth stroke width of the circle
*/
fun generateCoordinateInfo(x: Float, y: Float, r: Float, strokeWidth: Int = 20): FloatArray {
val coordinatesInfo = FloatArray((strokeWidth * 2) * 4)
for (i in 0 until strokeWidth) {
val j = i * 4
coordinatesInfo[j] = x // x
coordinatesInfo[j + 1] = y // y
coordinatesInfo[j + 2] = r - i / 2f // radius
coordinatesInfo[j + 3] = 0f // angle
}
for (i in 0 until strokeWidth) {
val j = (strokeWidth + i) * 4
coordinatesInfo[j] = x // x
coordinatesInfo[j + 1] = y // y
coordinatesInfo[j + 2] = r + i / 2f // radius
coordinatesInfo[j + 3] = 0f // angle
}
return coordinatesInfo
}
fun draw(transformedMatrixOpenGL: FloatArray) {
// draw circles
if (::circles.isInitialized) {
circles.draw(transformedMatrixOpenGL)
}
}