Android的OpenGL ES的触摸添加对象 [英] Android OpenGL ES add object on touch

查看:224
本文介绍了Android的OpenGL ES的触摸添加对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个小的Andr​​oid应用程序,将用户的触摸到一个立方体。 Z向深度始终是-10,屏幕始终处于横向模式。这个问题似乎是问了很多次,但我不能让它运行,请原谅我,因为我是新手OpenGL的。
我很困惑的屏幕坐标/窗口坐标/对象协调与gluUnproject使用。据我所知,屏幕是当用户触摸,我们从运动得到x和y偶数。窗口坐标,当我们加载的身份,和对象坐标,当我们变换矩阵来获得对象的坐标。是这样吗?

这是我的code,矩阵堆叠是Android的API样本。请指出我在做什么错了。


制图部:

 公共无效平局(GL10 GL){
    对于(GLObject glObject:名单){
        如果(glObject!= NULL){
            gl.glLoadIdentity();
            glObject.draw(GL);
        }
    }
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    如果(isTouching){
        布尔ADDOBJECT = FALSE;
        对于(GLObject glObject:名单){
            ADDOBJECT = glObject.checkTouch(GL,X,Y);
        }
        如果(!ADDOBJECT){
            我++;
            Log.d(I,I +);
            addGLObject(GL);
        }
        isTouching = FALSE;
    }
}


下面是code添加对象

 私人无效getMatrix(GL10 GL,INT模式,漂浮[]垫){
    GLView.matrixTrackingGL.glMatrixMode(模式);
    GLView.matrixTrackingGL.getMatrix(垫,0);
}
公共无效addGLObject(GL10 GL){
    浮[] XY = getWorldCoordinate(GL,X,Y);    如果(XY!= NULL){
// XY [0] =(浮子)(X - Main.SCREEN_WIDTH / 2)/ 10;
//
// XY [1] =(浮点)(Main.SCREEN_HEIGHT / 2 - Y)/ 10;        GLObject glObject =新GLObject(颜色,XY [0],XY [1]);
        Log.d(对象位置,X:+ XY [0] +Y:+ XY [1]);
        list.add(glObject);
    }
}
私人浮动[] getWorldCoordinate(GL10 GL,诠释的x,int y)对{
    浮动[] = modelMatrix新的浮动[16];
    浮动[] = projMatrix新的浮动[16];
    INT []视= {0,0,Main.SCREEN_WIDTH,Main.SCREEN_HEIGHT};
    getMatrix(GL,GL10.GL_MODELVIEW,modelMatrix);
    getMatrix(GL,GL10.GL_PROJECTION,projMatrix);    浮动[] =输出新的浮动[4];
    GLU.gluUnProject(X,视口[1] +视[3] - Y,-10,modelMatrix,0,projMatrix,0,视口,0,输出,0);
    返回新的浮动[] {输出[0] /输出[3],输出[1] /输出[3]};
}


 公共类GLObject {
    私人浮动[] =顶点{1.000000f,1.000000f,-1.000000f,1.000000f,
    -1.000000f,-1.000000f,-1.000000f,-1.000000f,-1.000000f,
    -1.000000f,1.000000f,-1.000000f,1.000000f,1.000000f,1.000000f,
    1.000000f,-1.000001f,1.000000f,-1.000000f,-1.000000f,
    1.000000f,-1.000000f,1.000000f,1.000000f,};
私人短[]面孔= {0,1,2,0,2,3,4,7,6,4,6,5,0,4,5,0,
    5,1,1,5,6,1,6,2,2,6,7,2,7,3,4,0,3,4,3,7};
私人浮动[]颜色;
私人浮动[] =腐烂{0.0,0.0,0.0};
私人浮动位X,positionY;
私人INT阿尔法= 0;//我们的顶点缓冲。
私人FloatBuffer vertexBuffer;//我们的索引缓冲区。
私人ShortBuffer faceBuffer;公共GLObject(){
    在里面();
}公共GLObject(浮动[]颜色,浮动X,浮法Y){
    this.colors = colors.clone();
    this.positionX = X;
    this.positionY = Y;    如果(positionX.intValue()%2 == 0){
        腐[0] = 1.0F;
    }其他{
        如果(positionY.intValue()%2 == 0){
    腐[1] = 1.0F;
    }其他{
        腐[2] = 1.0F;
    }
    }
    在里面();
}私人无效的init(){
    ByteBuffer的VBB = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(顶点);
    vertexBuffer.position(0);    IBB的ByteBuffer = ByteBuffer.allocateDirect(faces.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    faceBuffer = ibb.asShortBuffer();
    faceBuffer.put(面);
    faceBuffer.position(0);
}公共布尔checkTouch(GL10 GL,诠释的x,int y)对{
    布尔isTouched = FALSE;
    ByteBuffer的像素= ByteBuffer.allocate(4);    gl.glReadPixels(X,Main.SCREEN_HEIGHT - Y,1,1,GL10.GL_RGBA,
            GL10.GL_UNSIGNED_BYTE,像素);
    Log.d(COLOR,
            pixels.get(0)++ pixels.get(1)++ pixels.get(2)+
                    + pixels.get(3));
            // isTouched总是假的测试随时添加对象屏幕
    返回isTouched;
}公共无效画(GL10 GL){
    //逆时针绕。
    gl.glFrontFace(GL10.GL_CCW); // OpenGL的文档
    //启用剔除脸。
    gl.glEnable(GL10.GL_CULL_FACE); // OpenGL的文档
    //什么面临着脸上剔除删除。
    gl.glCullFace(GL10.GL_BACK); // OpenGL的文档    //启用顶点缓冲器写入和过程中使用的
    //渲染。
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL的文档。
    //启用颜色
    gl.glColor4f(颜色[0],颜色[1],颜色[2],1.0F);
    //指定顶点的阵列的位置和数据格式
    //坐标绘制时使用。
    gl.glPushMatrix();
    gl.glTranslatef(位X,positionY,-10);
    //旋转
    阿尔法+ = 1;
    gl.glRotatef(α,腐[0],腐[1],腐[2]);
    // 画
    gl.glVertexPointer(3 GL10.GL_FLOAT,0,// OpenGL的文档
            vertexBuffer);    gl.glDrawElements(GL10.GL_TRIANGLES,faces.length,// OpenGL的文档
            GL10.GL_UNSIGNED_SHORT,faceBuffer);
    gl.glPopMatrix();
    //禁用顶点缓冲区。
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL的文档
    //禁用脸部剔除。
    gl.glDisable(GL10.GL_CULL_FACE); // OpenGL的文档
}

}


的onDraw:

 公共无效onDrawFrame(GL10 GL){
        // TODO自动生成方法存根
        //清除屏幕和深度缓存。
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL的文档。
                GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        //重置投影矩阵
        gl.glLoadIdentity();
        GLU.gluPerspective(GL,90.0f,Main.SCREEN_WIDTH / Main.SCREEN_HEIGHT,3.0F,100.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(GL,4.0F,2.0F,1.0F,
                0.0,0.0,0.0,0.0,1.0F,0.0);
        //绘制对象
        glObjectManager.draw(GL);
    }


解决方案

它无关,与横向模式,问题是,你是-10 Z轴平移的立方体。尝试把-100值和所有的立方体将在中心。然后尝试把0的Z值(X,Y,0)。该立方体将大大再出从屏幕的中心,更接近您预期的那样。

看<一个href=\"http://tle.tafevc.com.au/toolbox/file/9495cce8-17b5-a8a5-d9b3-47c0c142d88d/1/sketches_and_drawings_lo.zip/3204a_20_reading_drawings/images/brick_perspective.jpg\" rel=\"nofollow\">http://tle.tafevc.com.au/toolbox/file/9495cce8-17b5-a8a5-d9b3-47c0c142d88d/1/sketches_and_drawings_lo.zip/3204a_20_reading_drawings/images/brick_perspective.jpg对透视投影的一个例子。当立方体在z = 0,即什么是形象。但是当z = -10,它更接近屏幕(X)和较小的中心,因为它遵循蓝线出到地平线

I am building a small Android application which will add a cube on user's touch. The z depth is always -10, screen is always in landscape mode. This question seems to be asked many times, but I cannot get it running, forgive me as I am newbie to opengl. I am quite confused about the screen coordinate/window coordinate/object coordinate to use with the gluUnproject. As I understand, screen is when user touch and we get x and y from motion even. Window coordinate is when we load the identity, and object coordinate is when we transform the identity matrix to get object's coordinate. Is that right?

And here is my code, the matrix stacking is from android api sample. Please point out what I am doing wrong.


The drawing part:

public void draw(GL10 gl) {
    for (GLObject glObject : list) {
        if (glObject != null) {
            gl.glLoadIdentity();
            glObject.draw(gl);
        }
    }
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    if (isTouching) {
        boolean addObject = false;
        for (GLObject glObject : list) {
            addObject = glObject.checkTouch(gl, x, y);
        }
        if (!addObject) {
            i++;
            Log.d("i", i + "");
            addGLObject(gl);
        }
        isTouching = false;
    }
}


Here is the code for adding object

private void getMatrix(GL10 gl, int mode, float[] mat) {
    GLView.matrixTrackingGL.glMatrixMode(mode);
    GLView.matrixTrackingGL.getMatrix(mat, 0);
}
public void addGLObject(GL10 gl) {
    float[] XY = getWorldCoordinate(gl, x, y);

    if (XY != null) {
//          XY[0] = (float) (x - Main.SCREEN_WIDTH / 2) / 10;
//
//          XY[1] = (float) (Main.SCREEN_HEIGHT / 2 - y) / 10;

        GLObject glObject = new GLObject(colors, XY[0], XY[1]);
        Log.d("Object position", "X: " + XY[0] + " Y: " + XY[1]);
        list.add(glObject);
    }
}
private float[] getWorldCoordinate(GL10 gl, int x, int y) {
    float[] modelMatrix = new float[16];
    float[] projMatrix = new float[16];
    int[] viewport = {0, 0, Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT};


    getMatrix(gl, GL10.GL_MODELVIEW, modelMatrix);
    getMatrix(gl, GL10.GL_PROJECTION, projMatrix);

    float[] output = new float[4];
    GLU.gluUnProject(x, viewport[1] + viewport[3] - y, -10, modelMatrix, 0, projMatrix, 0, viewport, 0, output, 0);
    return new float[] {output[0]/output[3], output[1]/output[3]};
}


public class GLObject {
    private float[] vertices = { 1.000000f, 1.000000f, -1.000000f, 1.000000f,
    -1.000000f, -1.000000f, -1.000000f, -1.000000f, -1.000000f,
    -1.000000f, 1.000000f, -1.000000f, 1.000000f, 1.000000f, 1.000000f,
    1.000000f, -1.000001f, 1.000000f, -1.000000f, -1.000000f,
    1.000000f, -1.000000f, 1.000000f, 1.000000f, };
private short[] faces = { 0, 1, 2, 0, 2, 3, 4, 7, 6, 4, 6, 5, 0, 4, 5, 0,
    5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 4, 0, 3, 4, 3, 7 };
private float[] colors;
private float[] rot = { 0.0f, 0.0f, 0.0f };
private Float positionX, positionY;
private int alpha = 0;

// Our vertex buffer.
private FloatBuffer vertexBuffer;

// Our index buffer.
private ShortBuffer faceBuffer;

public GLObject() {
    init();
}

public GLObject(float[] colors, float x, float y) {
    this.colors = colors.clone();
    this.positionX = x;
    this.positionY = y;

    if (positionX.intValue() % 2 == 0) {
        rot[0] = 1.0f;
    } else {
        if (positionY.intValue() % 2 == 0) {
    rot[1] = 1.0f;
    } else {
        rot[2] = 1.0f;
    }
    }
    init();
}

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

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

public boolean checkTouch(GL10 gl, int x, int y) {
    boolean isTouched = false;
    ByteBuffer pixels = ByteBuffer.allocate(4);

    gl.glReadPixels(x, Main.SCREEN_HEIGHT - y, 1, 1, GL10.GL_RGBA,
            GL10.GL_UNSIGNED_BYTE, pixels);
    Log.d("COLOR",
            pixels.get(0) + " " + pixels.get(1) + " " + pixels.get(2) + " "
                    + pixels.get(3));
            // isTouched always false to test always add object to screen
    return isTouched;
}

public void draw(GL10 gl) {
    // Counter-clockwise winding.
    gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
    // Enable face culling.
    gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
    // What faces to remove with the face culling.
    gl.glCullFace(GL10.GL_BACK); // OpenGL docs

    // Enabled the vertices buffer for writing and to be used during
    // rendering.
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// OpenGL docs.
    // Enable color
    gl.glColor4f(colors[0], colors[1], colors[2], 1.0f);
    // Specifies the location and data format of an array of vertex
    // coordinates to use when rendering.
    gl.glPushMatrix();
    gl.glTranslatef(positionX, positionY, -10);
    // rotate
    alpha += 1;
    gl.glRotatef(alpha, rot[0], rot[1], rot[2]);
    // draw
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
            vertexBuffer);

    gl.glDrawElements(GL10.GL_TRIANGLES, faces.length,// OpenGL docs
            GL10.GL_UNSIGNED_SHORT, faceBuffer);
    gl.glPopMatrix();
    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
    // Disable face culling.
    gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
}

}


onDraw:

public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // Clears the screen and depth buffer.
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        // Reset the projection matrix
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 90.0f, Main.SCREEN_WIDTH/Main.SCREEN_HEIGHT, 3.0f, 100.0f); 
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl, 4.0f, 2.0f, 1.0f, 
                0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);    
        // draw object
        glObjectManager.draw(gl);
    }

解决方案

It has nothing to do with landscape mode, the problem is that you are translating your cube by -10 on the z axis. Try putting values of -100 and all the cubes will be at the center. Then try putting 0 for the z value (x, y, 0). The cubes will be much further out from the center of the screen and closer to where you expect them to be.

Look at http://tle.tafevc.com.au/toolbox/file/9495cce8-17b5-a8a5-d9b3-47c0c142d88d/1/sketches_and_drawings_lo.zip/3204a_20_reading_drawings/images/brick_perspective.jpg for an example of perspective projection. When the cube is at z=0, that is what is in the image. But when z=-10, it is closer to the center of the screen (the X) and smaller, because it follows the blue lines out to the horizon.

这篇关于Android的OpenGL ES的触摸添加对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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