0

在 open GL 中有一个术语叫做拣货。用于确定屏幕上的哪个对象被选中。有人可以向我解释在对象的每个实例中使用拾取和放置基于触摸的侦听器之间的区别。一个多维数据集类。

假设;我想要做的是在屏幕上随机展示多个立方体。我想如果我给 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);
}
}
4

1 回答 1

3

在这种情况下,使用监听器不起作用。

例如,如果您看一下onTouchListener。这基本上是一个只提供一个方法 onTouch() 的接口。现在,当 android 正在处理触摸输入并且目标视图被触摸时,它知道您的侦听器可以通过调用侦听器的 onTouch() 来了解触摸。

使用 OpenGL 时,您会遇到问题,即没有人处理您的 opengl 表面内的触摸输入。你必须自己做。所以没有人会打电话给你的听众。

为什么?您在 gl 表面内渲染的内容取决于您。您只知道实际的几何形状是什么,因此您是唯一可以决定选择哪个对象的人。

您基本上有两个选项可以进行选择:

  • 射线射击 - 通过观察者的眼睛和触摸点将射线射入场景并检查击中了哪个对象。

  • 颜色选择 - 为您的对象分配 id,将 id 编码为颜色,使用此颜色渲染场景。最后检查触摸位置的颜色并解码颜色以获得对象的id。

对于大多数应用程序,我更喜欢第二种解决方案。

于 2013-08-14T11:45:51.497 回答