Android OpenGL传递OnTouch事件值

时间:2015-09-17 08:31:23

标签: android opengl-es

我遇到了问题。我不知道如何将OnTouch方法中的值x和y传递给私有final类MyRenderer并更新OnDrawFrame tex.draw(,x,y ,,,)函数x和y值能够用我的手指翻译我想要移动的对象。

任何指导和赞赏〜

public class Stage extends GLSurfaceView{

// Stage width and height
private float w, h;

// Screen width and height
private int screenWidth, screenHeight;

// Our native vertex buffer
private FloatBuffer vertexBuffer;

private Texture tex;

@Override
public boolean onTouchEvent(MotionEvent event) {
    final int action = event.getAction() & MotionEvent.ACTION_MASK;
    float x, y;
    int pointerIndex;
    int pointerId;

    if (action == MotionEvent.ACTION_DOWN) {
        pointerId = event.getPointerId(0);
        x = event.getX();
        y = event.getY();
        pointerIndex = 0;
    } else {
        pointerIndex = event.getActionIndex();
        pointerId = event.getPointerId(pointerIndex);
        x = event.getX(pointerIndex);
        y = event.getY(pointerIndex);
    }
    Log.v("this X", String.valueOf(x));
    Log.v("this Y", String.valueOf(y));

    return true;
}

public Stage(Context context, AttributeSet attrs) {
    super(context, attrs);
    setEGLConfigChooser(8, 8, 8, 8, 0, 0);
    setRenderer(new MyRenderer());
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    float vertices[] = {
            -0.5f, -0.5f,  0.0f,  // 0. left-bottom
            0.5f, -0.5f,  0.0f,  // 1. right-bottom
            -0.5f,  0.5f,  0.0f,  // 2. left-top
            0.5f,  0.5f,  0.0f   // 3. right-top
    };

    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    tex = new Texture(R.drawable.kdk);

}

private final class MyRenderer implements GLSurfaceView.Renderer {

    public final void onDrawFrame(GL10 gl) {

        gl.glClear(GLES10.GL_COLOR_BUFFER_BIT);
        gl.glLoadIdentity();
        tex.prepare(gl, GL10.GL_CLAMP_TO_EDGE);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        tex.draw(gl, w / 2, h / 2, tex.getWidth(), tex.getHeight(), 0);

    }

    public final void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glClearColor(0, 0, 0, 0);

        if(width > height) {
            h = 600;
            w = width * h / height;
        } else {
            w = 600;
            h = height * w / width;
        }
        screenWidth = width;
        screenHeight = height;

        gl.glViewport(0, 0, screenWidth, screenHeight);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, w, h, 0, -1, 1);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public final void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Set up alpha blending
        gl.glEnable(GL10.GL_ALPHA_TEST);
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

        // We are in 2D. Why needs depth?
        gl.glDisable(GL10.GL_DEPTH_TEST);

        // Enable vertex arrays (we'll use them to draw primitives).
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // Enable texture coordination arrays.
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        tex.load(getContext());
    }

}

}

其他编码

How to apply drag drop and scale in Android OpenGL ES

1 个答案:

答案 0 :(得分:1)

要实现此目的,您必须在舞台课程中添加 MyRenderer 属性。

这个解决方案可行,但可能不是最好的,所以可以自由评论。

  1. 您需要删除final语句来更改内部类 MyRenderer 的定义:

    编辑:我不确定这个,因为final class将其所有方法设置为final,但可能不是属性。如果有人能够回答它,我会很乐意阅读它。

      

    私人决赛类MyRenderer实现了GLSurfaceView.Renderer

      

    私有类MyRenderer实现GLSurfaceView.Renderer

    1. 阶段类中:

      public class Stage extends GLSurfaceView {
      
          // Stage width and height
          private float w, h;
      
          ...
      
          // The renderer
          MyRenderer mRenderer;
      
          ...
      
          public Stage(Context context, AttributeSet attrs) {
      
              mRenderer = new MyRenderer();
      
              super(context, attrs);
              setEGLConfigChooser(8, 8, 8, 8, 0, 0);
      
              setRenderer(mRenderer);
      
              ...
          }
      }
      
      1. 将setter添加到 MyRenderer 类:

        private class MyRenderer implements GLSurfaceView.Renderer {
        
            float xPos;
            float yPos;
        
            // ...
        
            public void setX(float x) {
                xPos = x;
            }
        
            public void setY(float y) {
                yPos = y;
            }
        
            public void setXY(float x, float y) {
                xPos = x;
                yPos = y;
            }
        }
        
        1. 最后在OnTouch方法中设置这些值。
        2. 编辑:

          设置xPos和yPos默认值:

          private class MyRenderer implements GLSurfaceView.Renderer {
          
              float xPos;
              float yPos;
          
              boolean initialised = false;
          
              ...
          
              public final void onSurfaceChanged(GL10 gl, int width, int height) {
          
                  if (!initialised) {
                      xPos = width /2;
                      yPos = height / 2;
                      initialised = true;
                  }
          
                  ...
              }
          
              ...
          }
          

          编辑2:

          为了避免竞争条件,使用一个函数同时设置X和Y值。输入方法时,它将使用参数中传递的值创建临时变量。这将确保传递的x和y值来自同一个事件。

          private class MyRenderer implements GLSurfaceView.Renderer {
          
              float xPos;
              float yPos;
          
              // ...
          
          
              public void setXY(float x, float y) {
                  xPos = x;
                  yPos = y;
              }
          }