OpenGL的ES onTouchEvents问题还是平局问题? [英] Opengl-es onTouchEvents problem or a draw problem?

查看:159
本文介绍了OpenGL的ES onTouchEvents问题还是平局问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用我的应用程序使用OpenGL和我得到它精细=),但最近我撞了南墙,因为我一直在试图找出用户输入的方法。
我决定先从一个简单的过程,在您触摸屏幕的位置绘制一个正方形屏幕。不幸的是应用程序似乎并没有登记输入。

下面是我的code:

该应用程序与本次活动打开>>

 进口android.app.Activity;
进口android.opengl.GLSurfaceView;
进口android.os.Bundle;
进口android.view.Window;
进口android.view.WindowManager;公共类实践活动扩展{
/ **当第一次创建活动调用。 * /
@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow()。setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    GLSurfaceView视图=新GLSurfaceView(本);
    view.setRenderer(新GLSurfaceRenderer());
    的setContentView(视图);
}
}

这初始化一个全屏SurfaceView。

接下来渲染

 进口javax.microedition.khronos.egl.EGLConfig;
进口javax.microedition.khronos.opengles.GL10;进口android.opengl.GLU;
进口android.opengl.GLSurfaceView.Renderer;
进口android.view.MotionEvent;
公共类GLSurfaceRenderer实现渲染{私人FlatColoredSquare广场;
私人浮动SETX = 0;
私人浮动SETY = 0;
    公共GLSurfaceRenderer(){
    广场=新FlatColoredSquare();}
    公共布尔onTouchEvent(MotionEvent事件,GL10 GL){
        如果(event.getAction()== MotionEvent.ACTION_UP){
        gl.glPushMatrix();
        gl.glTranslatef(event.getX(),event.getY(),-10);
        Square.draw(GL);
        gl.glPopMatrix();
        }        返回true;    } @覆盖
公共无效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();
         }
@覆盖
公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
    gl.glViewport(0,0,宽度,高度);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluPerspective(GL,45.0f,(浮点)宽/(浮点)的高度,0.1F,100F);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();}@覆盖
公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){
    gl.glClearColor(0.0,0.0,0.0,0.0);
    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方法内画我也把它像空白:

 公共布尔onTouchEvent(MotionEvent事件){
        如果(event.getAction()== MotionEvent.ACTION_UP){
        SETX = event.getX();
        SETY = event.getY();
        }        返回true;    }

这两个返回相同的结果=(
所以我在做的onTouchEvent错了吗?
或者我必须强制draw方法以某种方式更新?
和我将如何正确地实现这一点?

感谢您的时间

编辑:

设法得到code。通过在移动的方法来实践类注册一个onTouchEvent。

编辑:提出了一些更多的改进code现在正常工作的程度,但不是在所需的地方,而不是我得到了一个空白屏幕清除重绘方

下面编辑实践

 进口android.app.Activity;
进口android.opengl.GLSurfaceView;
进口android.os.Bundle;
进口android.view.MotionEvent;
进口android.view.Window;
进口android.view.WindowManager;
进口android.app.ui.GLSurfaceRenderer;公共类实践活动扩展{
私人GLSurfaceRenderer glSurfaceRenderer;
公共静态浮动SETX;
公共静态浮动SETY;
/ **当第一次创建活动调用。 * /
@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow()。setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    GLSurfaceView视图=新GLSurfaceView(本);
    view.setRenderer(glSurfaceRenderer =新GLSurfaceRenderer());    的setContentView(视图);
}
@覆盖
公共同步布尔onTouchEvent(MotionEvent事件){        如果(event.getAction()== MotionEvent.ACTION_UP){
            glSurfaceRenderer.randomMethod(事件);
    }    返回true;}
}

和编辑渲染器类

 进口javax.microedition.khronos.egl.EGLConfig;
进口javax.microedition.khronos.opengles.GL10;进口android.opengl.GLU;
进口android.opengl.GLSurfaceView.Renderer;
进口android.view.MotionEvent;
公共类GLSurfaceRenderer实现渲染{
私人浮动SETX;
私人浮动SETY;私人FlatColoredSquare方;
    公共GLSurfaceRenderer(){
    方=新FlatColoredSquare();
}    公共同步无效randomMethod(MotionEvent事件){
        SETX = event.getX();
        SETY = event.getY();
    }@覆盖
公共无效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();         }
@覆盖
公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
    gl.glViewport(0,0,宽度,高度);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluPerspective(GL,45.0f,(浮点)宽/(浮点)的高度,0.1F,100F);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();}@覆盖
公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){
    gl.glClearColor(0.0,0.0,0.0,0.0);
    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);}}

任何想法?
下面是正方形code

 进口java.nio.ByteBuffer中;
进口java.nio.ByteOrder中;
进口java.nio.FloatBuffer中;
进口java.nio.ShortBuffer中;进口javax.microedition.khronos.opengles.GL10;公共类FlatColoredSquare {
私人浮动顶点[] = {
        -1.0F,1.0F,0.0,
        -1.0F,-1.0F,0.0,
        1.0F,-1.0F,0.0,
        1.0F,1.0F,0.0
};私人短指数[] = {0,1,2,0,2,3,};私人FloatBuffer vertexBuffer;私人ShortBuffer indexBuffer;
公共FlatColoredSquare(){
    ByteBuffer的VBB = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(顶点);
    vertexBuffer.position(0);    IBB的ByteBuffer = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(指数);
    indexBuffer.position(0);
}公共无效画(GL10 GL){
    gl.glColor4f(0.0,1.0F,0.0,0.0);
    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事件,GL10 GL 在SDK中没有官方的支持。

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

您的解决方案很简单。覆盖<一个href=\"http://developer.android.com/reference/android/view/View.html#onTouchEvent%28android.view.MotionEvent%29\"相对=nofollow> onTouchEvent(MotionEvent事件) (或设置的 onTouchListener 您的 GLSurfaceView 类)在你的活动类,并在其中您的视图类调用一个方法(这应被声明为同步)。另一种方法是在不同的线程来更新逻辑,然而,是由你来决定。

I am just getting started with using opengl in my apps and I get it fine =) but I've hit a brick wall recently as I have been attempting to work out methods of user input. I decided to start with a simple process that draws a square to the screen at the position you touch the screen. Unfortunatly the app doesn't seem to register the input.

Here is my code:

The app opens with this activity >>

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

This initializes a full screen SurfaceView.

Next the renderer

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

}



}

As you can see there is an onTouchEvent that gets the coordinates of the event and sets them to the floats at the top. The draw method then uses these coordinates to set the position of the square. I don't think the draw method here updates enough to redraw the square. How can I set the draw method to update the square onTouch? As well as trying to set the square to draw from inside the onTouch method I have also left it blank like:

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

        return true;

    }

Both of these return the same results =( So am I doing the onTouchEvent wrong? or do I have to force the draw method to update somehow? and how would I implement this properly?

Thank you for your time

EDIT:

Managed to get the code to register an onTouchEvent by moving the method over to the Practice class.

EDIT: Made some more improvements code now works properly to an extent but instead of redrawing the square in the desired place I instead get a blank cleared screen.

Here is edited 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;

}
}

And edited 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);

}



}

Any ideas? Here is the square code

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

}

解决方案

Two problems here.

1) You are using your own, custom onTouchEvent() method. Your method onTouchEvent() with the arguments MotionEvent event, GL10 gl has no official support in the SDK.

2) You are modifying data that explicitly are running in another thread. The touch event's threads differs from the GL thread.

Your solution is simple. Override onTouchEvent(MotionEvent event) (or set an onTouchListener to your GLSurfaceView class) in your activity class and call a method (which should be declared as synchronized) in your view class within it. An alternative is to update logic in a different thread, however, that is up to you to decide.

这篇关于OpenGL的ES onTouchEvents问题还是平局问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆