Android Open Gl Выбор объектов
В открытом GL есть термин, называемый сбор. Какой используется, чтобы определить, какой объект на экране был выбран. Может кто-нибудь объяснить мне, в чем разница между выбором и размещением сенсорного слушателя в каждом экземпляре объекта ex. Класс Cube.
Гипотетически; То, что я хочу сделать, это показать несколько кубов на экране в случайном порядке. Я подумал, что если я назначу слушателю класс Cube, при касании куба слушатель должен выстрелить соответственно для каждого нажатого куба.
Это код, к которому я бы добавил слушателя. Будет ли это возможно или выбор необходим?
public class Cube extends Shapes {
private FloatBuffer mVertexBuffer;
private FloatBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
private Triangle[] normTris = new Triangle[12];
private Triangle[] transTris = new Triangle[12];
// every 3 entries represent the position of one vertex
private float[] vertices =
{
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f
};
// every 4 entries represent the color (r,g,b,a) of the corresponding vertex in vertices
private float[] colors =
{
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
// every 3 entries make up a triangle, every 6 entries make up a side
private byte[] indices =
{
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
};
private float[] createVertex(int Index)
{
float[] vertex = new float[3];
int properIndex = Index * 3;
vertex[0] = vertices[properIndex];
vertex[1] = vertices[properIndex + 1];
vertex[2] = vertices[properIndex + 2];
return vertex;
}
public Triangle getTriangle(int index){
Triangle tri = null;
//if(index >= 0 && index < indices.length){
float[] v1 = createVertex(indices[(index * 3) + 0]);
float[] v2 = createVertex(indices[(index * 3) + 1]);
float[] v3 = createVertex(indices[(index * 3) + 2]);
tri = new Triangle(v1, v2, v3);
// }
return tri;
}
public int getNumberOfTriangles(){
return indices.length / 3;
}
public boolean checkCollision(Ray r, OpenGLRenderer renderer){
boolean isCollide = false;
int i = 0;
while(i < getNumberOfTriangles() && !isCollide){
float[] I = new float[3];
if(Shapes.intersectRayAndTriangle(r, transTris[i], I) > 0){
isCollide = true;
}
i++;
}
return isCollide;
}
public void translate(float[] trans){
for(int i = 0; i < getNumberOfTriangles(); i++){
transTris[i].setV1(Vector.addition(transTris[i].getV1(), trans));
transTris[i].setV2(Vector.addition(transTris[i].getV2(), trans));
transTris[i].setV3(Vector.addition(transTris[i].getV3(), trans));
}
}
public void scale(float[] scale){
for(int i = 0; i < getNumberOfTriangles(); i++){
transTris[i].setV1(Vector.scalePoint(transTris[i].getV1(), scale));
transTris[i].setV2(Vector.scalePoint(transTris[i].getV2(), scale));
transTris[i].setV3(Vector.scalePoint(transTris[i].getV3(), scale));
}
}
public void resetTransfomations(){
for(int i = 0; i < getNumberOfTriangles(); i++){
transTris[i].setV1(normTris[i].getV1().clone());
transTris[i].setV2(normTris[i].getV2().clone());
transTris[i].setV3(normTris[i].getV3().clone());
}
}
public Cube()
{
Buffer[] buffers = super.getBuffers(vertices, colors, indices);
mVertexBuffer = (FloatBuffer) buffers[0];
mColorBuffer = (FloatBuffer) buffers[1];
mIndexBuffer = (ByteBuffer) buffers[2];
}
public Cube(float[] vertices, float[] colors, byte[] indices)
{
if(vertices != null) {
this.vertices = vertices;
}
if(colors != null) {
this.colors = colors;
}
if(indices != null) {
this.indices = indices;
}
Buffer[] buffers = getBuffers(this.vertices, this.colors, this.indices);
mVertexBuffer = (FloatBuffer) buffers[0];
mColorBuffer = (FloatBuffer) buffers[1];
mIndexBuffer = (ByteBuffer) buffers[2];
for(int i = 0; i < getNumberOfTriangles(); i++){
normTris[i] = getTriangle(i);
transTris[i] = getTriangle(i);
}
}
public void draw(GL10 gl)
{
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// draw all 36 triangles
gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
}
1 ответ
Использование Слушателя в этом случае не работает.
Если вы, например, посмотрите на onTouchListener. Это в основном интерфейс, предоставляющий только один метод onTouch(). Теперь, когда android обрабатывает сенсорные вводы и касается целевого вида, он знает, что ваш слушатель может быть проинформирован о касании, вызвав onTouch () вашего слушателя.
При использовании OpenGL у вас есть проблема, что никто не обрабатывает сенсорный ввод внутри вашей поверхности OpenGL. Вы должны сделать это самостоятельно. Так что нет никого, кто позвонит вашему слушателю.
Зачем? То, что вы визуализируете внутри своей поверхности, зависит от вас. Вы знаете только, какова реальная геометрия, и, следовательно, вы единственный, кто может решить, какой объект был выбран.
У вас есть два варианта выбора:
Съемка лучей - Снимите луч через глаз зрителя и точку касания в сцене и проверьте, какой объект был поражен.
Выбор цвета - назначьте идентификаторы вашим объектам, закодируйте идентификатор как цвет, визуализируйте сцену этим цветом. наконец, проверьте цвет в позиции касания и декодируйте цвет, чтобы получить идентификатор объекта.
Для большинства приложений я бы предпочел второе решение.