如何使用OpenGL ES 2在Android中绘制类似于画布的路径? [英] How to draw path like canvas in Android using OpenGL ES 2?

查看:179
本文介绍了如何使用OpenGL ES 2在Android中绘制类似于画布的路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Android中尝试过Canvas,并且可以通过在屏幕上移动手指来绘制草图或绘制路径. 现在,我想使用OpenGL 2做同样的事情. 我是OpenGL编程的新手,但是我尝试了几种使用GLES20.glDrawArray(...)和Line Shape类绘制线条的方法 但这仍然是一条直线,不像我使用画布时那样,是我想要的自由形式的路径. 而且,如果我每次ACTION_MOVE尝试绘制每个线段,由于将每个线段存储在ArrayList中,经常会发生并发修改异常. OpenGL是否有任何帮助API来实现这一目标? 如果有或没有,我该怎么做? 谢谢!

解决方案

如果要沿路径绘制一致的线,则实际上是在尝试绘制许多相互连接的短线./p>

我认为最直观的方法是将路径上的每个点添加到一个点数组中,然后维护一个float缓冲区,其中每三个项描述路径上的单个点(x,y, z).然后,对于添加到此顶点缓冲区的每个点,应在索引缓冲区中添加两个整数.如果您不熟悉索引缓冲区,它的工作方式(当您处理行时)是告诉OpenGL哪个顶点连接了两个.例如:

假设您有3分.在顶点缓冲区内,您将有9个浮点数-3点*每个点3个坐标.我们希望第一点连接到第二点,第二点连接到第三点.我们可以使用索引缓冲区来做到这一点.在索引缓冲区中,我们将为每个顶点连接放置2个整数.为了将第一个点连接到第二个点,我们将播放器0& 1进入缓冲区.这就是说顶点缓冲区中的第1 3个坐标与顶点缓冲区中的第2 3个坐标相连.然后,我们将放置1& 2在索引缓冲区中.这表示顶点缓冲区中的第2个3坐标已连接到顶点缓冲区中的第3个3坐标-依此类推.

Vertex Buffer:
{
  0, 0, 0, // Index 0
  1, 1, 1, // Index 1
  2, 3, 4  // Index 2
}

Index Buffer:
{
  0, 1, // Connect Index 0 to Index 1
  1, 2  // Connect Index 1 to Index 2
}

您将需要调用glDrawElements而不是glDrawArrays,但是思路是一样的-您只需要为索引维护一个额外的缓冲区,并确保每次添加新缓冲区时始终更新两个缓冲区点.

关于并发修改异常-您在这里需要注意一点.如果在遍历数组时向数组添加一个点(例如,使用"for each"样式循环),则将发生这种情况.一个好的解决方案是用一个同步块将与点数组的所有交互都包含在内,并将数组本身用作互斥体:

Adding:
synchronized(myPointArray)
{
  myPointArray.add(newPoint);
}


Iterating:
synchronized(myPointArray)
{
  for (PointF point : myPointArray)
  {
    // do stuff with the point
  }
}

这应该让您入门.

I have tried Canvas in Android, and I can make sketch or path by moving my finger on the screen. Now, I want to do the same thing using OpenGL 2. I'm new to OpenGL programming but I have tried several method to draw a Line using GLES20.glDrawArray(...) and a Line Shape class but still, this just make a straight line not like a free-form path i wanted just like when I use canvas. and also, if i try to draw per line segment each time ACTION_MOVE, concurrent modification exception often happens since i store each Line segment in an ArrayList. is there any helping API by OpenGL to achieve this? if there's or there isn't, how can i make this? Thanks!

解决方案

If you want to draw a consistent line along a path, then you're in fact trying to draw many short lines which are all connected to each other.

I think the most intuitive way of doing this, is adding each point on the path into an array of points, and then, maintaining a float buffer, where each 3 items describe a single point on the path (x,y,z). Then, for every point which is added to this vertex buffer, you should add two integers into an index buffer. If you're new to index buffers, the way it works (when you're working with lines), is it tells OpenGL which two vertexes are connected. For instance:

Say you have 3 points. Inside the Vertex buffer, you would have 9 floats - 3 points * 3 coordinates for each point. We would like the 1st point to be connected to the 2nd, and the 2nd point to be connected to the 3rd. We can do this by using an Index Buffer. In the index buffer, we will place 2 integers for every vertex connection. For connecting the 1st point to the 2nd, we will player 0 & 1 into the buffer. This says that the 1st 3 coordinates in the vertex buffer are connected to the 2nd 3 coordinates in the vertex buffer. Then, we will place 1 & 2 in the index buffer. This says that the 2nd 3 coordinates in the vertex buffer are connected to the 3rd 3 coordinates in the vertex buffer - and so on.

Vertex Buffer:
{
  0, 0, 0, // Index 0
  1, 1, 1, // Index 1
  2, 3, 4  // Index 2
}

Index Buffer:
{
  0, 1, // Connect Index 0 to Index 1
  1, 2  // Connect Index 1 to Index 2
}

You will need to call glDrawElements rather than glDrawArrays, but the idea is the same - you only need to maintain an additional buffer for the indexes, and make sure to always update both buffers each time you add a new point.

As for the concurrent modification exception - you need to be a bit careful here. If you add a point to the array while you're iterating over the array (for example, with a "for each" style loop), then this will happen. A good solution is to surround any interaction with the point array with a synchronize block, and use the array itself as a mutex:

Adding:
synchronized(myPointArray)
{
  myPointArray.add(newPoint);
}


Iterating:
synchronized(myPointArray)
{
  for (PointF point : myPointArray)
  {
    // do stuff with the point
  }
}

This should get you started.

这篇关于如何使用OpenGL ES 2在Android中绘制类似于画布的路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆