Opengl-es onTouchEvents问题还是绘制问题?

时间:2011-07-23 11:06:05

标签: android opengl-es user-input ontouchevent ondraw

我刚开始在我的应用程序中使用opengl并且我很好=)但是我最近碰到了一堵砖墙,因为我一直试图找出用户输入的方法。 我决定从一个简单的过程开始,在触摸屏幕的位置为屏幕绘制一个正方形。不幸的是,该应用程序似乎没有注册输入。

这是我的代码:

此应用会以此活动>>

打开
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class Practice extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    GLSurfaceView view = new GLSurfaceView (this);
    view.setRenderer(new GLSurfaceRenderer());
    setContentView(view);    
}
}

初始化全屏SurfaceView。

接下来是渲染器

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;


public class GLSurfaceRenderer implements Renderer{

private FlatColoredSquare Square;
private float setx = 0;
private float sety = 0; 


    public GLSurfaceRenderer () {   
    Square = new FlatColoredSquare();

}
    public boolean onTouchEvent (MotionEvent event, GL10 gl){
        if (event.getAction() == MotionEvent.ACTION_UP){    
        gl.glPushMatrix();
        gl.glTranslatef(event.getX(), event.getY(), -10);
        Square.draw(gl);
        gl.glPopMatrix();
        }

        return true;

    }



 @Override
public void onDrawFrame(GL10 gl) {
         gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
            GL10.GL_DEPTH_BUFFER_BIT);
         gl.glLoadIdentity();

    gl.glPushMatrix();
    gl.glTranslatef(setx, sety, -10);
    Square.draw(gl);        
    gl.glPopMatrix();
         }






@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glClearDepthf(1.0f);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

}



}

正如您所看到的,有一个onTouchEvent可以获取事件的坐标并将它们设置为顶部的浮点数。然后,绘制方法使用这些坐标来设置方形的位置。我不认为这里的绘制方法足以重新绘制正方形。如何设置绘图方法以更新方形onTouch?除了尝试将方块设置为从onTouch方法内部绘制之外,我还将其留空,如:

public boolean onTouchEvent (MotionEvent event){
        if (event.getAction() == MotionEvent.ACTION_UP){    
        setx = event.getX();
        sety = event.getY();
        }

        return true;

    }

这两个都返回相同的结果=( 那我在做onTouchEvent错了吗? 或者我必须强制绘制方法以某种方式更新? 以及如何正确实施?

感谢您的时间

编辑:

通过将方法移动到Practice类来管理以获取注册onTouchEvent的代码。

编辑:进行了一些改进代码现在可以在一定程度上正常工作,但不是重新绘制所需位置的方块而是取消空白屏幕。

这是编辑练习

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.app.ui.GLSurfaceRenderer;



public class Practice extends Activity {
private GLSurfaceRenderer glSurfaceRenderer;
public static float setx;
public static float sety;




/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    GLSurfaceView view = new GLSurfaceView (this);
    view.setRenderer(glSurfaceRenderer = new GLSurfaceRenderer());

    setContentView(view);
}
@Override
public synchronized boolean onTouchEvent (MotionEvent event){

        if (event.getAction() == MotionEvent.ACTION_UP){
            glSurfaceRenderer.randomMethod(event);
    }

    return true;

}
}

编辑了渲染器类

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;




public class GLSurfaceRenderer implements Renderer{
private float setx; 
private float sety; 

private FlatColoredSquare square;


    public GLSurfaceRenderer () {   
    square = new FlatColoredSquare();


}

    public synchronized void randomMethod(MotionEvent event){
        setx = event.getX();
        sety = event.getY();
    }



@Override
public void onDrawFrame(GL10 gl) {
         gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
            GL10.GL_DEPTH_BUFFER_BIT);
         gl.glLoadIdentity();


             gl.glPushMatrix();
    gl.glTranslatef(setx, sety, -10);
    square.draw(gl);        
    gl.glPopMatrix();

         }








@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glClearDepthf(1.0f);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

}



}

有什么想法吗? 这是方形代码

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

import javax.microedition.khronos.opengles.GL10;

public class FlatColoredSquare {
private float vertices[] = {
        -1.0f, 1.0f, 0.0f,
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        1.0f, 1.0f, 0.0f
};

private short indices[] = {0, 1, 2, 0, 2, 3,};

private FloatBuffer vertexBuffer;

private ShortBuffer indexBuffer;


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

    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length*2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);
}

public void draw(GL10 gl) {
    gl.glColor4f(0.0f, 1.0f, 0.0f, 0.0f);
    gl.glFrontFace(GL10.GL_CCW);
    gl.glEnable(GL10.GL_CULL_FACE);
    gl.glCullFace(GL10.GL_BACK);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, 
                      GL10.GL_UNSIGNED_SHORT, indexBuffer);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisable(GL10.GL_CULL_FACE);
}

}

1 个答案:

答案 0 :(得分:1)

这里有两个问题。

1)您正在使用自己的自定义onTouchEvent()方法。您使用参数onTouchEvent()的方法MotionEvent event, GL10 gl在SDK中没有官方支持。

2)您正在修改明确在另一个线程中运行的数据。触摸事件的线程与GL线程不同。

您的解决方案很简单。在您的活动类中覆盖onTouchEvent(MotionEvent event)(或设置onTouchListener到您的GLSurfaceView类)并在其中的视图类中调用方法(应该声明为synchronized) 。另一种方法是更新不同线程中的逻辑,然后由您决定。