2

在开发应用程序以通过运动事件使用用户输入动态绘制线和圆时,我喜欢在自定义大小的 SurfaceView Renderer 中提供绘图输出,以便我可以将屏幕的其余部分用于其他目的,如菜单等。我在布局中创建了一个 SurfaceView 并尝试提供输出,但是这条线是从 SurfaceView 的中心绘制的,并且与给定的触摸事件不完全一致。有没有可能我们可以通过 SurfaceView 获得输出,还是我在浪费时间?

4

1 回答 1

1

使用surfaceview中的触摸事件在android中的opengl es 2.0中绘制一条线和圆..

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

           }




      }
   ----------------------------------------------------------------------------------------------
于 2013-05-13T10:30:07.710 回答