【问题标题】:zoom out in OpenGL in android在android中缩小OpenGL
【发布时间】:2014-04-02 14:16:04
【问题描述】:

我正在使用 3D 对象并渲染它并通过扩展 GLSurfaceView 实现 Renderer 来显示它,问题是如何通过捏合和捏合进行缩小。

下面是我的课

package com.example.objLoader;

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.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.os.Debug;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class ManishRenderer extends GLSurfaceView implements Renderer { 
/** Triangle instance */
private OBJParser parser;
private TDModel model;

/* Rotation values */
private float xrot;                 //X Rotation
private float yrot;                 //Y Rotation

/* Rotation speed values */

private float xspeed;               //X Rotation Speed ( NEW )
private float yspeed;               //Y Rotation Speed ( NEW )

private float z = 320.0f;

private float oldX;
    private float oldY;
private final float TOUCH_SCALE = 0.8f;     //Proved to be good for normal rotation ( NEW )

private float[] lightAmbient = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightPosition = {0.0f, -3.0f, 2.0f, 1.0f};
private FloatBuffer lightAmbientBuffer;
private FloatBuffer lightDiffuseBuffer;
private FloatBuffer lightPositionBuffer;

public ManishRenderer(Context ctx) {
    super(ctx);



    parser=new OBJParser(ctx);
    model=parser.parseOBJ("/storage/sdcard1/man.obj");  
    Debug.stopMethodTracing();
    this.setRenderer(this);
    this.requestFocus();
    this.setFocusableInTouchMode(true);

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(lightAmbient.length * 5024);
    byteBuf.order(ByteOrder.nativeOrder());
    lightAmbientBuffer = byteBuf.asFloatBuffer();
    lightAmbientBuffer.put(lightAmbient);
    lightAmbientBuffer.position(0);

    byteBuf = ByteBuffer.allocateDirect(lightDiffuse.length * 5024);
    byteBuf.order(ByteOrder.nativeOrder());
    lightDiffuseBuffer = byteBuf.asFloatBuffer();
    lightDiffuseBuffer.put(lightDiffuse);
    lightDiffuseBuffer.position(0);

    byteBuf = ByteBuffer.allocateDirect(lightPosition.length * 5024);
    byteBuf.order(ByteOrder.nativeOrder());
    lightPositionBuffer = byteBuf.asFloatBuffer();
    lightPositionBuffer.put(lightPosition);
    lightPositionBuffer.position(0);
}
/**
 * The Surface is created/init()
 */
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbientBuffer);      
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuseBuffer);      
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);    
    gl.glEnable(GL10.GL_LIGHT0);        
    gl.glShadeModel(GL10.GL_SMOOTH);            
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    
    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); 
}

/**
 * Here we do our drawing
 */
public void onDrawFrame(GL10 gl) {
    //Clear Screen And Depth Buffer
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    gl.glLoadIdentity();                    
    gl.glEnable(GL10.GL_LIGHTING);
    gl.glTranslatef(0.0f, -1.2f, -z);   //Move down 1.2 Unit And Into The Screen 6.0
    gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);   //X
    gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);   //Y
    model.draw(gl);                     //Draw the square
    gl.glLoadIdentity();        
    xrot += xspeed;
    yrot += yspeed;

}

/**
 * If the surface changes, reset the view
 */
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       //Prevent A Divide By Zero By
        height = 1;                         //Making Height Equal One
    }

    gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
    gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
    gl.glLoadIdentity();                    //Reset The Projection Matrix

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 1100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();                    //Reset The Modelview Matrix
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    //
    float x = event.getX();
    float y = event.getY();

    //If a touch is moved on the screen
    if(event.getAction() == MotionEvent.ACTION_MOVE) {
        //Calculate the change
        float dx = x - oldX;
        float dy = y - oldY;
        //Define an upper area of 10% on the screen
        int upperArea = this.getHeight() / 10;

        //Zoom in/out if the touch move has been made in the upper
        if(y < upperArea) {
            z -= dx * TOUCH_SCALE / 2;

        //Rotate around the axis otherwise
        } else {                
            xrot += dy * TOUCH_SCALE;
            yrot += dx * TOUCH_SCALE;
        }        

    //A press on the screen
    } else if(event.getAction() == MotionEvent.ACTION_UP) {


    }

    //Remember the values
    oldX = x;
    oldY = y;

    //We handled the event
    return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    //
    if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

    } else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

    } else if(keyCode == KeyEvent.KEYCODE_DPAD_UP) {
        z -= 3;

    } else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
        z += 3;

    } else if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {

    }

    //We handled the event
    return true;
}}

试过 SurfaceView Zoom IN and OUT functionality using Custom Camera

但这不是我要搜索的:(我没有 UI 即 xml 部分,我可以在其中添加放大缩小的小部件

【问题讨论】:

  • 您的问题是关于“如何”检测缩放区域,何时使用多点触控完成捏缩放,或者如何使用 OpenGL 进行缩放?
  • @prabindh 问题是关于在surfaceview上进行捏合和拉出时如何进行缩放
  • 您是在 3D 对象或表面视图上应用捏缩放?

标签: android opengl-es rendering


【解决方案1】:

您需要实现 OnScaleGestureDetector 并创建 ScaleGestureDetector 来监听捏合和捏出事件。

例如我用它作为 GLSurfaceView 的内部类:

...

private float sizeCoef = 1;

...

private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener{

    float scaleFocusX = 0;
    float scaleFocusY = 0;

    public boolean onScale(ScaleGestureDetector arg0) {
        float scale = arg0.getScaleFactor() * sizeCoef;

        sizeCoef = scale;

        requestRender();

        return true;
    }

    public boolean onScaleBegin(ScaleGestureDetector arg0) {
        invalidate();

        scaleFocusX = arg0.getFocusX();
        scaleFocusY = arg0.getFocusY();

        return true;
    }

    public void onScaleEnd(ScaleGestureDetector arg0) {
        scaleFocusX = 0;
        scaleFocusY = 0;
    }
} 

您还必须在 onDrawFrame() 方法中添加一些代码:

public void onDrawFrame(GL10 gl) {
    //Clear Screen And Depth Buffer
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    gl.glLoadIdentity();                    
    gl.glEnable(GL10.GL_LIGHTING);
    gl.glTranslatef(0.0f, -1.2f, -z);   //Move down 1.2 Unit And Into The Screen 6.0
    gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);   //X
    gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);   //Y

    gl.glScalef(sizeCoef, sizeCoef, 0);  // if You have a 3d object put sizeCoef as all parameters

    model.draw(gl);                     //Draw the square
    gl.glLoadIdentity();        
    xrot += xspeed;
    yrot += yspeed;

}

【讨论】:

【解决方案2】:

我建议您查看 GLU.glLookAt(),它允许您设置眼睛和中心点。然后,您可以根据缩放值前后移动眼睛。

您也可以使用 android.openglMatrix 类。并使用 perspectiveMatrix 和 lookAtMatrix 函数,然后将它们组合在一起并将它们设置为您的 projectionMatrix。

【讨论】:

    【解决方案3】:

    SDK 可以帮助您一点,使用standard Gesture detector。有关如何实现此 ScaleGestureDetector 的更多详细信息,请参阅here

    基本步骤是将触摸事件传递给 ScaleGestureDetector,当缩放事件发生时,您将在侦听器上收到回调,您可以在其中更改缩放状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-27
      • 2015-02-28
      • 2020-11-06
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多