In OpenGL ES 2.0, Android, Is it possible to draw

2019-04-14 10:48发布

问题:

In developing an app to draw line & circle dynamically using user input through motion event, I like to provide the output of drawing in a custom sized SurfaceView Renderer so that I can use the rest of the screen for some other purpose like menu, etc. I have created a SurfaceView in layout and tried to provide the output, but the line gets drawn from the centre of the surfaceview and doesn't follow exactly with the touch event given. Is there any possibility that we can get output through SurfaceView or am I wasting my time in that ?

回答1:

draw a line and circle in opengl es 2.0 in android using touch event in surfaceview..

  Program for Draw Line using touchEvent. when you touch two times, it will draw one line..
    @Override
public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

        case MotionEvent.ACTION_DOWN:

            Log.v("hari", "action down working");

            if (count == 1) {

                dx = ev.getX();
                dy = ev.getY();
                dx = (dx / (getWidth() / 2)) - 1;
                dy = 1 - (dy / (getHeight() / 2));
                Log.i("hari", "line1:" + dx + "," + dy);
                firstX = dx;
                firstY = dy;

            } else if (count == 2) {

                ux = ev.getX();
                uy = ev.getY();
                ux = (ux / (getWidth() / 2)) - 1;
                uy = 1 - (uy / (getHeight() / 2));

                Log.i("hari", "line2:" + ux + "," + uy);
                secondX = ux;
                secondY = uy;

                myRenderer.dx = firstX;
                myRenderer.dy = firstY;

                myRenderer.ux = secondX;
                myRenderer.uy = secondY;

                requestRender();
                count = 0;
            }

            break;

            }

  ----------------------------------------------------------------------------------------------
    My Renderer Program :

    package com.example.ibus;

     import java.nio.ByteBuffer;
     import java.nio.ByteOrder;
     import java.nio.FloatBuffer;


     import javax.microedition.khronos.egl.EGLConfig;
     import javax.microedition.khronos.opengles.GL10;
     import android.opengl.GLES20;
    import android.opengl.GLSurfaceView.Renderer;

    import android.util.Log;


     public class MyRenderer implements Renderer {

MainActivity main;
MyGLsurfaceview myGlsurface;
public volatile boolean myline, mycircle, mydashedline , mysnaptoedge , snapBoolean ;
public volatile double  angle,length;
public volatile float dlsx, dlsy, dlex, dley, dlsx1, dlsy1,
   dlex1, dley1, dltx, dlty, len;
 public volatile double rad, dlrad;
 int n, i;
Lines line;
Circle circle;
Snap snapedge;
// Declare as volatile because we are updating it from another thread
 public volatile float dx, dy, ux, uy, Dist, centerX,centerY,firstX,firstY,
              secondX,secondY, sex, sey;
 private float sx, sy, fx, fy, tx, ty;
 private double radian, rradian;



public MyRenderer(MainActivity mainActivity, MyGLsurfaceview myGlsurfaceView) {
    Log.i("JO", "MyRenderer");
    main = mainActivity;
    myGlsurface = myGlsurfaceView;

}

@Override
public void onDrawFrame(GL10 gl) {
    Log.i("JO", "onDrawFrame");
    // line.draw(x,y);
    Log.i("JO", "onDrawFrame:DX:"+dx+",DY:"+dy+",UX:"+ux+",UY:"+uy);

    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    //GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    if(myline){

    line.draw(dx,dy,ux,uy);
    }


}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    Log.i("JO", "onSurfaceChanged");
    // Adjust the viewport based on geometry changes,
    // such as screen rotation
    GLES20.glViewport(0, 0, width, height);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    Log.i("JO", "onSurfaceCreated");
    // Set the background frame color
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    line = new Lines();

}

public static int loadShader(int type, String shaderCode) {

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
  }
   }

      class Lines {

  final String vertexShaderCode = "attribute vec4 vPosition;"
        + "void main() {" + "  gl_Position = vPosition;" + "}";

  final String fragmentShaderCode = "precision mediump float;"
        + "uniform vec4 vColor;" + "void main() {"
        + "  gl_FragColor = vColor;" + "}";

final FloatBuffer vertexBuffer;
final int mProgram;
int mPositionHandle;
int mColorHandle;

// number of coordinates per vertex in this array
final int COORDS_PER_VERTEX = 3;
float lineCoords[] = new float[6];
final int vertexCount = lineCoords.length / COORDS_PER_VERTEX;
final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex
// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

public Lines() {

    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
    // (number of coordinate values * 4 bytes per float)
            lineCoords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();

    // prepare shaders and OpenGL program
    int vertexShader = MyRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
            vertexShaderCode);
    int fragmentShader = MyRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
            fragmentShaderCode);

    mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
    GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader
                                                    // to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment
                                                        // shader to program
    GLES20.glLinkProgram(mProgram); // create OpenGL program executables
 }

public void draw(float dX,float dY,float uX,float uY) {

    lineCoords[0] = dX;
    lineCoords[1] = dY;
    lineCoords[2] = 0.0f;
    lineCoords[3] = uX;
    lineCoords[4] = uY;
    lineCoords[5] = 0.0f;


    vertexBuffer.put(lineCoords);
    vertexBuffer.position(0);
    // Add program to OpenGL environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_LINES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
          }

           }




      }
   ----------------------------------------------------------------------------------------------