Увеличивайте при долгом нажатии, используя открытые - PullRequest
0 голосов
/ 06 июня 2018

Я хочу реализовать увеличение при долгом нажатии.При длительном нажатии появится круг, где отмеченная область будет отображаться как увеличение.Мне нужно использовать opengles.

Я создал круг, используя opengles.Он также двигается пальцем.Код, как показано ниже:

Круг вызова onDrawFrame:

public void onDrawFrame(GL10 gl) {
    GLES20.glClearColor(0.53333f, 0.53333f, 0.53333f, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | glES20.GL_DEPTH_BUFFER_BIT);

    if(mMagnifyCircle != null && bLongPressed) {
        mMagnifyCircle.draw();
    }
}

Рисунок круга следующим образом:

public class GLCircle {

private float[] mColor;
private int mProgram;

private float mCenterX;
private float mCenterY;
private float mRadius;

private static final int COORDS_PER_VERTEX = 2;
private static float VERTEX_COORDINATES[] = {
        -1f,   1f,   // top left
        -1f,  -1f,   // bottom left
         1f,  -1f,   // bottom right
         1f,   1f,   // top right
};

private FloatBuffer mVertexBuffer;
private ShortBuffer mDrawListBuffer;

private final short mDrawOrder[] = {0, 1, 2, 0, 2, 3}; // order to draw vertices

public GLCircle(float[] color) {
    mColor = color;

    String vertexShaderSource = "" +
            "attribute vec2 aPosition; \n" +
            "void main() \n" +
            "{ \n" +
            "   gl_Position = vec4(aPosition, 0., 1.); \n" +
            "} \n";

    String fragmentShaderSource = "" +
            "precision highp float;\n" +
            "uniform vec2 aCirclePosition;\n" +
            "uniform float aRadius; \n" +
            "uniform vec4 aColor; \n" +
            "const float threshold = 0.005;\n" +
            "void main() \n" +
            "{ \n" +
            "   float d, dist;\n" +
            "   dist = distance(aCirclePosition, gl_FragCoord.xy);\n" +
            "   if(dist == 0.)\n" +
            "       dist = 1.;\n" +
            "   d = aRadius / dist;\n" +
            "   if(d >= 1.)\n" +
            "        gl_FragColor = aColor;\n" +
            "   else if(d >= 1. - threshold) \n" +
            "   {\n" +
            "        float a = (d - (1. - threshold)) / threshold;\n" +
            "        gl_FragColor = vec4(aColor.r, aColor.g, aColor.b, a); \n" +
            "    }\n" +
            "    else\n" +
            "        gl_FragColor = vec4(0., 0., 0., 0.);\n" +
            "} \n";

    int vertexShader = compileVertexShader(vertexShaderSource);
    int fragmentShader = compileFragmentShader(fragmentShaderSource);
    mProgram = linkProgram(vertexShader, fragmentShader);
    if (BuildConfig.DEBUG) {
        validateProgram(mProgram);
    }

    ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_COORDINATES.length * 4);
    vertexByteBuffer.order(ByteOrder.nativeOrder());
    mVertexBuffer = vertexByteBuffer.asFloatBuffer();
    mVertexBuffer.put(VERTEX_COORDINATES);
    mVertexBuffer.position(0);

    ByteBuffer drawByteBuffer = ByteBuffer.allocateDirect(mDrawOrder.length * 2);
    drawByteBuffer.order(ByteOrder.nativeOrder());
    mDrawListBuffer = drawByteBuffer.asShortBuffer();
    mDrawListBuffer.put(mDrawOrder);
    mDrawListBuffer.position(0);
}

private static int linkProgram(int vertexShaderId, int fragmentShaderId) {
    final int programObjectId = GLES20.glCreateProgram();
    if (programObjectId == 0) {
        return 0;
    }

    GLES20.glAttachShader(programObjectId, vertexShaderId);
    GLES20.glAttachShader(programObjectId, fragmentShaderId);

    GLES20.glLinkProgram(programObjectId);

    final int[] linkStatus = new int[1];
    GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);

    if (linkStatus[0] == 0) {
        // If it failed, delete the program object. glDeleteProgram(programObjectId);
        GLES20.glDeleteProgram(programObjectId);
        return 0;
    }
    return programObjectId;
}

private static boolean validateProgram(int programObjectId) {
    GLES20.glValidateProgram(programObjectId);
    final int[] validateStatus = new int[1];
    GLES20.glGetProgramiv(programObjectId, GLES20.GL_VALIDATE_STATUS, validateStatus, 0);
    return validateStatus[0] != 0;
}

private static int compileVertexShader(String shaderCode) {
    return compileShader(GLES20.GL_VERTEX_SHADER, shaderCode);
}

private static int compileFragmentShader(String shaderCode) {
    return compileShader(GLES20.GL_FRAGMENT_SHADER, shaderCode);
}

private static int compileShader(int type, String shaderCode) {
    final int shaderObjectId = GLES20.glCreateShader(type);
    if (shaderObjectId == 0) {
        return 0;
    }
    GLES20.glShaderSource(shaderObjectId, shaderCode);
    GLES20.glCompileShader(shaderObjectId);

    final int[] compileStatus = new int[1];
    GLES20.glGetShaderiv(shaderObjectId, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

    if (compileStatus[0] == 0) {
        GLES20.glDeleteShader(shaderObjectId);
        return 0;
    }
    return shaderObjectId;
}

public void draw() {
    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    GLES20.glUseProgram(mProgram);

    int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    int vertexStride = COORDS_PER_VERTEX * 4;
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, mVertexBuffer);

    GLES20.glUniform4fv(GLES20.glGetUniformLocation(mProgram, "aColor"), 1, mColor, 0);
    GLES20.glUniform2f(GLES20.glGetUniformLocation(mProgram, "aCirclePosition"), mCenterX, mCenterY);
    GLES20.glUniform1f(GLES20.glGetUniformLocation(mProgram, "aRadius"), mRadius);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, mDrawOrder.length, GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer);
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

public float getCenterX() {
    return mCenterX;
}

public void setCenterX(float centerX) {
    mCenterX = centerX;
}

public float getCenterY() {
    return mCenterY;
}

public void setCenterY(float centerY) {
    mCenterY = centerY;
}

public float getRadius() {
    return mRadius;
}

public void setRadius(float radius) {
    this.mRadius = radius;
}

}

Перемещение по касанию пальца:

    @Override
public boolean onTouch(View v, MotionEvent event) {
    boolean bResult = false;
    float x = 0,y = 0;

    if (event.getAction() == MotionEvent.ACTION_DOWN){
        x = event.getRawX();
        y = event.getRawY();
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        bLongPressed = false;
        requestRenderer();
        GLES20.glClearColor(0.53333f, 0.53333f, 0.53333f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        v.performClick();
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        x = event.getRawX();
        y = event.getRawY();
    }

    requestRenderer();
    mMagnifyCircle.setCenterX(x);
    mMagnifyCircle.setCenterY(y);
    mMagnifyCircle.setRadius(200);
    return bResult;
}

Мой вопрос:

  1. Если я перемещаю палец по оси x, круг проходит пальцем.Но если я перемещаю палец по оси Y, круг идет в противоположном направлении.Как можно решить это?
  2. Круг уже прозрачен.Но я хочу увеличить только площадь круга.Как я могу это сделать?

Ожидаемый результат будет выглядеть следующим образом:

Expected feature will be look like below:

1 Ответ

0 голосов
/ 07 июня 2018

В пространстве вида координаты y указывают снизу вверх.

view space

Это означает, что компонент y равен gl_FragCoordравно 0 в нижней части области просмотра и высоте окна в верхней части области просмотра.

Но для aCirclePosition, который устанавливается в mCenterX, mCenterY, верхней части окнаравен 0, а нижняя часть соответствует высоте окна.

Чтобы решить эту проблему, вы должны знать высоту окна по высоте (window_height в следующем фрагменте кода) и перевернутьу координаты.это можно сделать, установив форму aCirclePosition:

int pos_loc = GLES20.glGetUniformLocation(mProgram, "aCirclePosition");
GLES20.glUniform2f(pos_loc, mCenterX, window_height-mCenterY);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...