我刚刚开始在我的应用程序中使用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获取事件的坐标,并将它们设置为顶部的浮动。绘制方法然后使用这些坐标来设置正方形的位置。我认为这里的draw方法更新不够,无法重新绘制正方形。我如何设置draw方法来更新square onTouch?除了尝试将正方形设置为从onTouch方法内部绘制之外,我还将其保留为空白,如
public boolean onTouchEvent (MotionEvent event){
if (event.getAction() == MotionEvent.ACTION_UP){
setx = event.getX();
sety = event.getY();
}
return true;
}
返回相同的结果=(我的onTouchEvent做错了吗?还是我必须强制draw方法更新?我该如何正确地实现它?
感谢您的宝贵时间
编辑:通过将方法移动到Practice类来注册onTouchEvent。
编辑:做了一些更多的改进代码现在在一定程度上正常工作,但不是在想要的地方重新绘制正方形,而是得到一个空白的清除屏幕。
编辑后的Practice
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;
}
}
和编辑Renderer Class
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)你正在使用你自己的,自定义的onTouchEvent()
方法。你的方法onTouchEvent()
和参数MotionEvent event, GL10 gl
在SDK中没有官方支持。
2)你正在修改另一个线程中显式运行的数据。touch事件的线程不同于GL线程。
你的解决方案很简单。在你的活动类中覆盖onTouchEvent(MotionEvent event)
(或将onTouchListener
设置为你的GLSurfaceView
类),并在视图类中调用一个方法(应该声明为synchronized
)。另一种方法是在不同的线程中更新逻辑,但是,这取决于您的决定。