如何在open-gl中实现平移。我找不到任何答案。
这是我的GLSurface和Render的代码。
public class GLSurface extends GLSurfaceView {
//public static GLRender xRender;
ScaleGestureDetector ScaleDetect;
//MainActivity mMain = (MainActivity) getContext();
//OpenGL XOPL = mMain.xOpenGL;
public static GLRender myGLRender;
public GLSurface(Context context){
super(context);
// Render the view only when there is a change in the drawing data
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
setEGLContextClientVersion(2);
myGLRender = new GLRender();
setRenderer(myGLRender);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
ScaleDetect = new ScaleGestureDetector(context, new ScaleDetectorListener());
}
private float mPreviousX;
private float mPreviousY;
float density = this.getResources().getDisplayMetrics().density;
private static final int MAX_CLICK_DURATION = 300;
private long pressStartTime;
@Override
public boolean onTouchEvent(MotionEvent e) {
ScaleDetect.onTouchEvent(e);
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
if(!ScaleDetect.isInProgress() && e.getPointerCount() == 1) {
float xMoveRange = x - mPreviousX;
float yMoveRange = y - mPreviousY;
float dx = 0.0f;
float dy = 0.0f;
float w = this.getWidth();
float h = this.getHeight();
float NormalizedXRange = xMoveRange / w;
float NormalizedYRange = yMoveRange / h;
//if (Math.abs(xMoveRange) > w / 100 && Math.abs(yMoveRange) < h / 100){
dx = NormalizedXRange * 360;
myGLRender.setAngleX(myGLRender.getXAngle() + dx);
//}
//if (Math.abs(xMoveRange) < w / 100 && Math.abs(yMoveRange) > h / 100){
dy = NormalizedYRange * 360;
myGLRender.setAngleY(myGLRender.getYAngle() + dy);
//}
requestRender();
}
else if (e.getPointerCount() == 3){
float xMoveRange = x - mPreviousX;
float yMoveRange = y - mPreviousY;
myGLRender.setRange(xMoveRange,yMoveRange);
requestRender();
}
break;
case MotionEvent.ACTION_DOWN:
pressStartTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP:
long pressDuration = System.currentTimeMillis() - pressStartTime;
if (pressDuration < MAX_CLICK_DURATION) {
float Nx = (x - Float.parseFloat(Double.toString(this.getWidth())) * 0.5f) / (Float.parseFloat(Double.toString(this.getWidth())) * 0.5f);
float Ny = (y - Float.parseFloat(Double.toString(this.getHeight())) * 0.5f) / (Float.parseFloat(Double.toString(this.getHeight())) * 0.5f);
float Nz = 1.0f;
myGLRender.setNCoordinate(Nx, Ny, Nz);
myGLRender.Selection();
requestRender();
}
break;
}
mPreviousX = x;
mPreviousY = y;
return true;
}
private float sizeCoef = 1;
public class ScaleDetectorListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
float scaleFocusX = 0;
float scaleFocusY = 0;
public boolean onScale(ScaleGestureDetector arg0) {
float scale = arg0.getScaleFactor() * sizeCoef;
sizeCoef = scale;
myGLRender.setZoom(sizeCoef);
requestRender();
return true;
}
public boolean onScaleBegin(ScaleGestureDetector arg0) {
invalidate();
scaleFocusX = arg0.getFocusX();
scaleFocusY = arg0.getFocusY();
myGLRender.setFocus(scaleFocusX,scaleFocusY);
return true;
}
public void onScaleEnd(ScaleGestureDetector arg0) {
scaleFocusX = 0;
scaleFocusY = 0;
myGLRender.setFocus(scaleFocusX,scaleFocusY);
}
}
GLRender
public class GLRender implements GLSurfaceView.Renderer {
private final float[] mMVPMatrix = new float[16];
private final float[] mModelViewMatrix = new float[16];
private final float[] mTranslateMatrix = new float[16];
private final float[] mMVPMatrixforCoord = new float[16];
private final float[] mTranslateMatrixCoord = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mModelViewMatrixCoord = new float[16];
private final float[] mRotationMatrix = new float[16];
private final float[] mRSMatrix = new float[16];
private final float[] mScMatrix = new float[16];
private final float[] mVRMatrix = new float[16];
private final float[] mInvMVPMatrix = new float[16];
private static ArrayList<Line> DrLine = new ArrayList<Line>();
private static ArrayList<Point> DrPoint = new ArrayList<Point>();
private static ArrayList<Line> XGridLine = new ArrayList<Line>();
private static ArrayList<Line> YGridLine = new ArrayList<Line>();
private float ratio;
private float Joint1;
private float Joint2;
private float x1, y1, z1, x2, y2, z2;
private float px, py, pz, ps;
private float[] nearN = new float[4];
private Boolean GridOnOff = false;
private float[] Range = new float[4];
private float[] NewRange = {0.0f, 0.0f, 0.0f, 1.0f};
private static ArrayList<ArrayList<String>> LineArray = new ArrayList<ArrayList<String>>();
private static ArrayList<String> L = new ArrayList<String>();
private static ArrayList<String> P = new ArrayList<String>();
private static ArrayList<ArrayList<String>> PointArray = new ArrayList<ArrayList<String>>();
private static ArrayList<String> EmptyLine = new ArrayList<String>();
private static ArrayList<String> EmptyPoint = new ArrayList<String>();
private ArrayList<ArrayList<ArrayList<String>>> UndoL = new ArrayList<ArrayList<ArrayList<String>>>();
private ArrayList<ArrayList<ArrayList<String>>> UndoP = new ArrayList<ArrayList<ArrayList<String>>>();
private ArrayList<ArrayList<String>>[] UndoLineArray = new ArrayList[10];
private ArrayList<ArrayList<String>>[] UndoPointArray = new ArrayList[10];
private Integer CountUndoLine = 0;
private Integer CountUndoPoint = 0;
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
Line XLine = new Line();
XLine.SetVerts(0.0f, 0.0f, 0.0f, 1.0f / 10, 0.0f, 0.0f);
XLine.SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Line YLine = new Line();
YLine.SetVerts(0.0f, 0.0f, 0.0f, 0.0f, 1.0f / 10, 0.0f);
YLine.SetColor(0.0f, 1.0f, 0.0f, 1.0f);
Line ZLine = new Line();
ZLine.SetVerts(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f / 10);
ZLine.SetColor(0.0f, 0.0f, 1.0f, 1.0f);
Line XX1 = new Line();
XX1.SetVerts(0.11f, -0.02f, 0.0f, 0.13f, 0.02f, 0.0f);
XX1.SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Line XX2 = new Line();
XX2.SetVerts(0.11f, 0.02f, 0.0f, 0.13f, -0.02f, 0.0f);
XX2.SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Line YY1 = new Line();
YY1.SetVerts(-0.02f, 0.11f, 0.0f, 0.02f, 0.11f, 0.0f);
YY1.SetColor(0.0f, 1.0f, 0.0f, 1.0f);
Line YY2 = new Line();
YY2.SetVerts(-0.02f, 0.13f, 0.0f, 0.02f, 0.13f, 0.0f);
YY2.SetColor(0.0f, 1.0f, 0.0f, 1.0f);
Line YY3 = new Line();
YY3.SetVerts(0-.02f, 0.11f, 0.0f, 0.02f, 0.13f, 0.0f);
YY3.SetColor(0.0f, 1.0f, 0.0f, 1.0f);
Line ZZ1 = new Line();
ZZ1.SetVerts(0.0f, -0.02f, 0.13f, 0.0f, 0.0f, 0.13f);
ZZ1.SetColor(0.0f, 0.0f, 1.0f, 1.0f);
Line ZZ2 = new Line();
ZZ2.SetVerts(0.0f, 0.0f, 0.13f, 0.0f, 0.02f, 0.11f);
ZZ2.SetColor(0.0f, 0.0f, 1.0f, 1.0f);
Line ZZ3 = new Line();
ZZ3.SetVerts(0.0f, 0.0f, 0.13f, 0.0f, 0.02f, 0.15f);
ZZ3.SetColor(0.0f, 0.0f, 1.0f, 1.0f);
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, 0.5f + NewRange[0], 0.5f + NewRange[1], 1.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mVRMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
Matrix.setIdentityM(mRotationMatrix, 0);
Matrix.rotateM(mRotationMatrix, 0, mXAngle, 0, 1f, 0);
Matrix.rotateM(mRotationMatrix, 0, mYAngle, 1f, 0, 0);
Matrix.setIdentityM(mScMatrix, 0);
Matrix.scaleM(mScMatrix,0,mScale,mScale,mScale);
Matrix.setIdentityM(mRSMatrix,0);
Matrix.multiplyMM(mRSMatrix, 0, mRotationMatrix, 0, mScMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mVRMatrix, 0, mRSMatrix, 0);
Matrix.setIdentityM(mModelViewMatrixCoord,0);
Matrix.translateM(mModelViewMatrixCoord,0, 0.8f, -0.8f, 0.0f);
Matrix.multiplyMM(mTranslateMatrixCoord,0,mModelViewMatrixCoord,0,mRotationMatrix,0);
Matrix.multiplyMM(mMVPMatrixforCoord, 0, mVRMatrix, 0, mTranslateMatrixCoord, 0);
//Matrix.setIdentityM(mVRMatrix, 0);
//Matrix.multiplyMM(mVRMatrix, 0, mViewMatrix, 0, mRSMatrix, 0);
//Matrix.setIdentityM(mMVPMatrix, 0);
//Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mVRMatrix, 0);
if (GridOnOff) {
Grid();
for (Line XGrid : XGridLine) {
XGrid.draw(mMVPMatrix);
}
for (Line YGrid : YGridLine) {
YGrid.draw(mMVPMatrix);
}
}
Drawer();
if (DrLine.size() > 0) {
for (Line LineX : DrLine) {
LineX.draw(mMVPMatrix);
}
}
if (DrPoint.size() > 0) {
for (Point PointX : DrPoint) {
PointX.draw(mMVPMatrix);
}
}
XLine.draw(mMVPMatrixforCoord);
YLine.draw(mMVPMatrixforCoord);
ZLine.draw(mMVPMatrixforCoord);
XX1.draw(mMVPMatrixforCoord);
XX2.draw(mMVPMatrixforCoord);
YY1.draw(mMVPMatrixforCoord);
YY2.draw(mMVPMatrixforCoord);
YY3.draw(mMVPMatrixforCoord);
ZZ1.draw(mMVPMatrixforCoord);
ZZ2.draw(mMVPMatrixforCoord);
ZZ3.draw(mMVPMatrixforCoord);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
ratio = (float) width / height;
//Matrix.frustumM(mProjectionMatrix, 0, -ratio*10, ratio*10, -10, 10, 1, 9);
Matrix.orthoM(mProjectionMatrix, 0, -ratio, ratio, -1.0f, 1.0f, -5.0f, 5.0f);
}
public static int loadShader(int type, String shaderCode){
int shader = GLES20.glCreateShader(type);
if (shader != 0){
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e("XS", "Could not compile shader " + type + ":");
Log.e("Shade", GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e("XR", glOperation + ": glError " + error);
throw new RuntimeException(glOperation + ": glError " + error);
}
}
private Float TempMaxPointHolder = 0.0f;
private Float MaxPointHolder = 0.0f;
public Float Scaler(){
Float TempScaler = 1.0f;
Double x, y, z, r;
Iterator<ArrayList<String>> MaxPointFinder = PointArray.iterator();
while (MaxPointFinder.hasNext()){
ArrayList<String> MaxPoint = MaxPointFinder.next();
x = Double.parseDouble(MaxPoint.get(1));
y = Double.parseDouble(MaxPoint.get(2));
z = Double.parseDouble(MaxPoint.get(3));
r = Math.abs(Math.sqrt( x * x + y * y + z * z));
TempMaxPointHolder = r.floatValue();
if (TempMaxPointHolder > MaxPointHolder){
MaxPointHolder = TempMaxPointHolder;
}
}
if (MaxPointHolder != 0) {
TempScaler = 0.9f / MaxPointHolder;
}
else {
TempScaler = 1.0f;
}
return TempScaler;
}
public void Drawer(){
Float Scaler = Scaler();
Integer Lindex = 0;
ArrayList<Point> TempDrPoint = new ArrayList<Point>();
ArrayList<Line> TempDrLine = new ArrayList<Line>();
Iterator<ArrayList<String>> Litr = LineArray.iterator();
while (Litr.hasNext()) {
L = Litr.next();
Joint1 = Float.parseFloat(L.get(1));
Joint2 = Float.parseFloat(L.get(2));
Iterator<ArrayList<String>> PitrL = PointArray.iterator();
while (PitrL.hasNext()){
P = PitrL.next();
if (Float.parseFloat(P.get(0)) == Joint1) {
x1 = Float.parseFloat(P.get(1)) * Scaler;
y1 = Float.parseFloat(P.get(2)) * Scaler;
z1 = Float.parseFloat(P.get(3)) * Scaler;
}
if (Float.parseFloat(P.get(0)) == Joint2) {
x2 = Float.parseFloat(P.get(1)) * Scaler;
y2 = Float.parseFloat(P.get(2)) * Scaler;
z2 = Float.parseFloat(P.get(3)) * Scaler;
}
}
Line TempLine = new Line();
TempLine.SetVerts(x1, y1, z1, x2, y2, z2);
if (L.get(3) == "0") {
TempLine.SetColor(1.0f, 1.0f, 1.0f, 1.0f);
}
else if (L.get(3) == "1"){
TempLine.SetColor(0.66f, 0.73f, 0.21f, 1.0f);
}
TempDrLine.add(TempLine);
Lindex = Lindex + 1;
}
setDrLine(TempDrLine);
Integer Pindex = 0;
Iterator<ArrayList<String>> Pitr = PointArray.iterator();
while (Pitr.hasNext()){
P = Pitr.next();
px = Float.parseFloat(P.get(1)) * Scaler;
py = Float.parseFloat(P.get(2)) * Scaler;
pz = Float.parseFloat(P.get(3)) * Scaler;
ps = Float.parseFloat(P.get(4));
Point TempPoint = new Point();
TempPoint.SetPointVerts(px, py, pz);
if (ps == 0.0f) {
TempPoint.SetPointColor(0.659f, 0.659f, 0.659f, 1.0f);
}
else if (ps == 1.0f) {
TempPoint.SetPointColor(0.68f, 0.07f, 0.32f, 1.0f);
}
TempDrPoint.add(TempPoint);
Pindex = Pindex + 1;
}
setDrPoint(TempDrPoint);
}
public volatile float mXAngle;
public volatile float mYAngle;
public void setRange (float XRange, float YRange){
Matrix.invertM(mInvMVPMatrix,0 , mMVPMatrix, 0);
Range[0] = XRange;
Range[1] = YRange;
Range[2] = 0.0f;
Range[3] = 1.0f;
Log.d("XXX", String.valueOf(XRange));
Log.d("YYY", String.valueOf(YRange));
Matrix.multiplyMV(NewRange, 0, mInvMVPMatrix, 0, Range, 0);
}
public void setGridOnOff (Boolean OnOff){
GridOnOff = OnOff;
}
public Boolean getGridOnOff(){
return GridOnOff;
}
public ArrayList<Line> getDrLine() {
return DrLine;
}
public ArrayList<Point> getDrPoint(){
return DrPoint;
}
public void setDrLine(ArrayList<Line> XDrLine) {
DrLine = XDrLine;
}
public void setDrPoint(ArrayList<Point> XDrPoint) {
DrPoint = XDrPoint;
}
public float getXAngle() {
if (mXAngle > 360 || mXAngle < -360){
return 0.0f;
}
else {
return mXAngle;
}
}
public float getYAngle(){
if (mYAngle > 360 || mYAngle < -360){
return 0.0f;
}
else {
return mYAngle;
}
}
public void setAngleX(float Xangle) {
mXAngle = Xangle;
}
public void setAngleY(float Yangle) {
mYAngle = Yangle;
}
public volatile float mScale = 1;
public volatile float mXFocus;
public volatile float mYFocus;
public void setZoom(float scale){
mScale = scale;
}
public void setFocus(float XFocus, float YFocus){
mXFocus = XFocus;
mYFocus = YFocus;
}
public float getmScale(){
return mScale;
}
public float getmXFocus(){
return mXFocus;
}
public float getmYFocus(){
return mYFocus;
}
public void setLineArray(ArrayList<ArrayList<String>> XLine){
this.LineArray = XLine;
}
public ArrayList<ArrayList<String>> getLineArray(){
ArrayList<ArrayList<String>> TempLine = new ArrayList<>();
Iterator<ArrayList<String>> LItr = LineArray.iterator();
while (LItr.hasNext()){
ArrayList<String> TempLineInner = new ArrayList<String>(LItr.next());
TempLine.add(TempLineInner);
}
return TempLine;
}
public void setUndoL(ArrayList<ArrayList<String>> UndoLine){
if (CountUndoLine < 10) {
UndoLineArray[CountUndoLine] = UndoLine;
CountUndoLine = CountUndoLine + 1;
}
else {
CountUndoLine = 0;
UndoLineArray[CountUndoLine] = UndoLine;
}
}
public ArrayList<ArrayList<ArrayList<String>>> getUndoL() {
return UndoL;
}
public void setUndoP(ArrayList<ArrayList<String>> UndoPoint){
if (CountUndoPoint < 10) {
UndoPointArray[CountUndoPoint] = UndoPoint;
CountUndoPoint = CountUndoPoint + 1;
}
else {
CountUndoPoint = 0;
UndoPointArray[CountUndoPoint] = UndoPoint;
}
}
public ArrayList<ArrayList<ArrayList<String>>> getUndoP() {
return UndoP;
}
public void setPointArray(ArrayList<ArrayList<String>> XPoint){
this.PointArray = XPoint;
}
public ArrayList<ArrayList<String>> getPointArray(){
ArrayList<ArrayList<String>> TempPoint = new ArrayList<>();
Iterator<ArrayList<String>> PItr = PointArray.iterator();
while (PItr.hasNext()){
ArrayList<String> TempPointInner = new ArrayList<String>(PItr.next());
TempPoint.add(TempPointInner);
}
return TempPoint;
}
public ArrayList<String> getEmptyPoint(){
return new ArrayList<> (EmptyPoint);
}
public void setEmptyPoint(ArrayList<String> EPoint){
EmptyPoint = EPoint;
}
public ArrayList<String> getEmptyLine(){
return new ArrayList<> (EmptyLine);
}
public void setEmptyLine(ArrayList<String> ELine){
EmptyLine = ELine;
}
public void setNCoordinate(float NNx,float NNy,float NNz) {
nearN[0] = NNx;
nearN[1] = -NNy;
nearN[2] = NNz;
nearN[3] = 1.0f;
}
private float[] v1 = new float[3];
private float[] v2 = new float[3];
private float[] v3 = new float[3];
private float[] v4 = new float[4];
private float[] v5 = new float[4];
private float[] v6 = new float[4];
private float[] v7 = new float[4];
private float[] v8 = new float[3];
private float[] v9 = new float[3];
private float[] NewPoint = new float[4];
private float[] OldPoint = new float[4];
private Boolean PointSelect = false;
}