1

I'm having problem. I don't know how to pass the value x and y in the OnTouch method to the private final class MyRenderer and update the OnDrawFrame tex.draw(,x,y,,,) function x and y value to be able to translate the object I want to move with my finger.

Any guidance with be appreciated~

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());
    }

}

}

Other coding

How to apply drag drop and scale in Android OpenGL ES

Community
  • 1
  • 1
Le Parkour
  • 97
  • 1
  • 15

1 Answers1

1

To achieve this you will have to add a MyRenderer attribute to your Stage class.

This solution will work but it is maybe not the best so fell free to comment.


  1. You need to change the definition of your inner class MyRenderer by removing the final statement :

    EDIT : I am not sure about this one because final class will have all its methods set to final but maybe not the attributes. If someone can answer it I'll be glade to read it.

    private final class MyRenderer implements GLSurfaceView.Renderer

    To

    private class MyRenderer implements GLSurfaceView.Renderer


  1. In your Stage class :

    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. Add the setters to your MyRenderer class :

    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. Finally set these values in the OnTouch method.

Edit :

To set the xPos and yPos default value :

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;
        }

        ...
    }

    ...
}

EDIT 2 :

To avoid race condition set the X and Y value at the same time with one function. When entering the method it will create temporary variable with the value passed in parameters. This will ensure that the x and y value passed are from the same Event.

private class MyRenderer implements GLSurfaceView.Renderer {

    float xPos;
    float yPos;

    // ...


    public void setXY(float x, float y) {
        xPos = x;
        yPos = y;
    }
}
WannaGetHigh
  • 3,826
  • 4
  • 23
  • 31
  • It's work! thanks bro but I still have 1 question, how can I save my xPos and yPos value to default w/2 and h/2 ? – Le Parkour Sep 17 '15 at 09:20
  • in your **onSurfaceChanged(GL10 gl, int width, int height)** method you can, the first time you enter this method, set its value. I'll edit my answer – WannaGetHigh Sep 17 '15 at 09:24
  • Ya Sir, it's worked, but when I dragging the object, the object keep on glitching, probably my onTouch method having problem with the pointer touch id... – Le Parkour Sep 17 '15 at 09:31
  • @KenChong This could be a refresh issue. If you need to fix this but you don't know how, ask another question by describing the problem. – WannaGetHigh Sep 17 '15 at 09:44
  • Thanks Sir, I will try to fix it, probably will ask stackoverflow if I fail. – Le Parkour Sep 17 '15 at 09:46
  • This code has race conditions. If the UI thread calls `setX()` followed by `setY()`, the rendering thread could use the values while one of them has updated, but the other one still has the old value. – Reto Koradi Sep 17 '15 at 14:18
  • Then how to overcome the race condition? – Le Parkour Sep 18 '15 at 01:52
  • It's weird when I removed public void setX(float x) { xPos = x; } the setX function still work.... after I added import android.annotation.TargetApi; – Le Parkour Sep 18 '15 at 03:30
  • I think the value is still unable to pass, the setX function is from import android.annotation.TargetApi; which mean this function public void setX(float x) { xPos = x; } is useless – Le Parkour Sep 18 '15 at 04:07
  • @KenChong I named the methods `setX` and `setY` but you can rename them. If the methods already exists in the parent class it is for a reason so just change the name like `setXPosition` in order to keep the other ones working. But if you don't need these methods simply don't use them :) – WannaGetHigh Sep 18 '15 at 09:22
  • Ya this problem was solved, the texture don't move because of missing requestRender(); after call the setXPosition and setYPosition.. – Le Parkour Sep 18 '15 at 09:28
  • @KenChong I also edited my answer to avoid race condition – WannaGetHigh Sep 18 '15 at 09:30
  • Oh ya race condition can be avoid by using synchronized () function – Le Parkour Sep 18 '15 at 09:34