旋转Android上使用OpenGL ES围绕另一个球体 [英] Rotating a sphere around another using OpenGL ES on Android

查看:353
本文介绍了旋转Android上使用OpenGL ES围绕另一个球体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:我想在OpenGL ES的Andr​​oid上创建一个太阳系。我已经有了一些领域。现在,我想使球在轨道上绕上最大球体中心(像行星围绕太阳旋转)。我怎么做?自己周围球体的旋转工作,但我不知道如何使它绕另一个领域。

另外,我有颜色的问题。必须有一个问题在什么地方我的code,因为我所有的行星是灰色的。我试图让太阳的红色,但它坚持灰色,我不知道为什么。我用gl.glColor4f这应该工作,但事实并非如此。

请帮忙,这是非常紧迫的,因为我需要的东西运行在周一,一月28日,因为这是一个程序,我做我的研究,我真的不知道如何解决这些问题。请帮忙。谢谢。

下面是我的code:

 进口javax.microedition.khronos.egl.EGLConfig;
进口javax.microedition.khronos.opengles.GL;
进口javax.microedition.khronos.opengles.GL10;进口my.pack.graphics.primitives.Sphere;进口android.app.Activity;
进口android.content.Context;
进口android.opengl.GLSurfaceView;
进口android.opengl.GLU;
进口android.opengl.GLUtils;
进口android.os.Bundle;
进口android.util.FloatMath;
进口android.util.Log;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.view.MotionEvent;
进口android.widget.Toast;进口java.nio.ByteBuffer中;
进口java.nio.ByteOrder中;
进口java.nio.FloatBuffer中;
进口java.nio.IntBuffer中;
进口java.nio.ShortBuffer中;公共类GLES06延伸活动{
    私人GLSurfaceView touchableGLSurfaceView;    私人最终诠释MENU_RESET = 1,MENU_PAN = 2,MENU_ZOOM = 3;
    私人最终诠释GROUP_DEFAULT = 0,GROUP_PAN = 1,GROUP_ZOOM = 2;
    私人布尔潘= FALSE;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);    touchableGLSurfaceView =新TouchableGLSurfaceView(本);
    的setContentView(touchableGLSurfaceView);
    touchableGLSurfaceView.setFocusableInTouchMode(真);
    touchableGLSurfaceView.requestFocus();
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
    menu.add(GROUP_DEFAULT,MENU_RESET,0,复位);
    menu.add(GROUP_PAN,MENU_PAN,0,潘);
    menu.add(GROUP_ZOOM,MENU_ZOOM,0,放大);
    返回super.onCreateOptionsMenu(菜单);
    }    @覆盖
    prepareOptionsMenu(菜单菜单)上公共布尔{
    如果(PAN){
        menu.setGroupVisible(GROUP_PAN,FALSE);
        menu.setGroupVisible(GROUP_ZOOM,真);
    }其他{
        menu.setGroupVisible(GROUP_PAN,真);
        menu.setGroupVisible(GROUP_ZOOM,FALSE);
    }
    返回super.on prepareOptionsMenu(菜单);
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
    开关(item.getItemId()){
        案例MENU_RESET:
            TouchableGLSurfaceView.resetViewing();
            Toast.makeText(这一点,轨迹球复位
                            Toast.LENGTH_SHORT).show();
            touchableGLSurfaceView.requestRender();
            返回true;
        案例MENU_PAN:
            Toast.makeText(这一点,摇激活
                            Toast.LENGTH_SHORT).show();
            潘=真;
            TouchableGLSurfaceView.guiZoom = FALSE;
            返回true;
        案例MENU_ZOOM:
            Toast.makeText(这一点,变焦激活
                            Toast.LENGTH_SHORT).show();
            潘= FALSE;
            TouchableGLSurfaceView.guiZoom = TRUE;
            返回true;
    }
    返回super.onOptionsItemSelected(项目);
    }    @覆盖
    保护无效onResume(){
    super.onResume();
    touchableGLSurfaceView.onResume();
    }    @覆盖
    保护无效的onPause(){
    super.onPause();
    touchableGLSurfaceView.onPause();
    }
 } //可触摸GLSurfaceView与
 //虚拟轨迹球旋转控制的实现
类TouchableGLSurfaceView扩展GLSurfaceView {
    私人OurRenderer ourRenderer;    静态公共布尔guiZoom = TRUE;
    //可能的接触状态
    最终静态INT无= 0;
    最终静态INT旋转= 1;
    最终静态INT ZOOM = 2;
    最终静态INT潘= 3;
    INT touchState =无;    最后静浮MIN_DIST = 50;
    静态INT oldDistance = 0;
    静态INT的centerX = 0,centerY = 0;
    静态INT oldCenterX = 0,oldCenterY = 0;    静浮EYE_DISTANCE,EYE_DISTANCE_INC;
    静浮PAN_X,PAN_Y,PAN_INC;
    静浮CURRENT_QUATERNION [],LAST_QUATERNION [];
    静浮TRANSFORM_MATRIX [];    静态INT OLD_MOUSE_X,OLD_MOUSE_Y,MOUSE_BUTTON_ preSSED;    静态INT WINDOW_W = 600;
    静态INT WINDOW_H = 800;    静浮zNear = 1.0F,zFar = 1000.0f;    静态的 {
    CURRENT_QUATERNION =新的浮动[4];
    LAST_QUATERNION =新的浮动[4];
    TRANSFORM_MATRIX =新的浮动[16];
    }    公共TouchableGLSurfaceView(上下文的背景下){
    超级(上下文);
    ourRenderer =新OurRenderer();
    setRenderer(ourRenderer);    ourRenderer.autoRotate = TRUE;
    setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }    @覆盖
    公共布尔onTouchEvent(MotionEvent事件){
    浮X = event.getX();
    浮Y = event.getY();    浮P1X,P1Y,P2X,P2Y;
    //正常化鼠标位置
    P1X =(2.0F * OLD_MOUSE_X - WINDOW_W)/ WINDOW_W;
    P1Y =(WINDOW_H - 2.0F * OLD_MOUSE_Y)/ WINDOW_H;
    P2X =(2.0F * X - WINDOW_W)/ WINDOW_W;
    P2Y =(WINDOW_H - 2.0F * Y)/ WINDOW_H;    开关(event.getAction()及MotionEvent.ACTION_MASK){
        案例MotionEvent.ACTION_DOWN:
            touchState =转动;
            OLD_MOUSE_X =(INT)X;
            OLD_MOUSE_Y =(INT)Y;
            打破;
        案例MotionEvent.ACTION_POINTER_DOWN:
            //辅助触摸事件开始:记得距离
            oldDistance =(INT)calcDistance(事件);
            //和中点
            calcMidpoint(事件);
            oldCenterX =的centerX;
            oldCenterY = centerY;
            如果(oldDistance> MIN_DIST){
                如果(guiZoom){
                    touchState = ZOOM;
                }其他{
                    touchState = PAN;
                }
            }
            打破;
        案例MotionEvent.ACTION_MOVE:
            如果(touchState ==旋转){
                //单指旋转
                Trackball.trackball(LAST_QUATERNION,P1X,P1Y,
                                                                         P2X,P2Y);
                OLD_MOUSE_X =(INT)X;
                OLD_MOUSE_Y =(INT)Y;
                Trackball.add_quats(LAST_QUATERNION,
                                              CURRENT_QUATERNION,CURRENT_QUATERNION);
                requestRender();
            }否则如果(touchState == ZOOM){
                //双指缩放,缩放取决于改变
                                       距离
                INT DIST =(int)的calcDistance(事件);
                如果(DIST> MIN_DIST){
                    如果(DIST> oldDistance)
                    EYE_DISTANCE - = EYE_DISTANCE_INC;
                    否则,如果(DIST< oldDistance)
                    EYE_DISTANCE + = EYE_DISTANCE_INC;
                    oldDistance = DIST;
                    requestRender();
                }
            }否则如果(touchState == PAN){
                INT DIST =(int)的calcDistance(事件);
                calcMidpoint(事件);
                如果(DIST> MIN_DIST){
                    如果(的centerX> oldCenterX)
                    PAN_X - = PAN_INC;
                    如果(的centerX< oldCenterX)
                    PAN_X + = PAN_INC;
                    如果(centerY> oldCenterY)
                    PAN_Y + = PAN_INC;
                    如果(centerY< oldCenterY)
                    PAN_Y - = PAN_INC;
                    oldCenterX =的centerX;
                    oldCenterY = centerY;
                    requestRender();
                }
            }
            打破;
        案例MotionEvent.ACTION_UP:
            touchState =无;
            打破;
        案例MotionEvent.ACTION_POINTER_UP:
            touchState =转动;
            //更新触摸向下位置拖动事件持有手指
            开关(event.getActionIndex()){
                情况下0:
                    OLD_MOUSE_X =(int)的event.getX(1);
                    OLD_MOUSE_Y =(int)的event.getY(1);
                    打破;
                情况1:
                    OLD_MOUSE_X =(int)的event.getX(0);
                    OLD_MOUSE_Y =(int)的event.getY(0);
                    打破;
            }
            打破;
    }
    返回true;
}私人浮动calcDistance(MotionEvent事件){
    浮X = event.getX(0) - event.getX(1);
    浮Y = event.getY(0) - event.getY(1);
    返回FloatMath.sqrt(X * X + Y * Y);
}私人无效calcMidpoint(MotionEvent事件){
    的centerX =(int)的((event.getX(0)+ event.getX(1))/ 2);
    centerY =(int)的((event.getY(0)+ event.getY(1))/ 2);
}//渲染器接口的实现
私有类OurRenderer实现GLSurfaceView.Renderer {    //一些变量对我们的行星和卫星的宣言
    私人领域的阳光;
    私人领域的Merkur;
    私人领域金星;
    私人领域王尔德;
    私人领域海王星;
    私人领域天王星;
    私人领域土星;
    私人领域木星;    私人长期milSecPerRotation = 20 * 1000;
    私人双角= 0.0;
    私人长期lastTime;    公共布尔自动旋转= TRUE;    公共OurRenderer(){        //定义我们的行星和卫星        //沿Z轴以闪电般的球体
        //半径:球体的半径
        //切片:沿z轴的细分数目
        //堆栈:围绕z轴的细分数目
        太阳=新球体(4.0F,10,10);
        默克=新球(0.5F,10,10);
        金星=新球(0.9F,10,10);
        王尔德=新球(1.0F,10,10);
        海王星=新球(1.5F,10,10);
        天王星=新球(1.5F,10,10);
        土星=新球(2.5F,10,10);
        木星=新球(3.0F,10,10);    }    公共无效onDrawFrame(GL10 GL){
        //第一件事要做:清屏和深度缓冲
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);        //重新设置模型视图矩阵
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();        //设置环境光的颜色
        浮model_ambient [] = {0.5F,0.5F,0.5F,1.0F};
        ByteBuffer的BB1 = ByteBuffer.allocateDirect(model_ambient.length * 4);
        bb1.order(ByteOrder.nativeOrder());
        FloatBuffer FB1 = bb1.asFloatBuffer();
        fb1.put(model_ambient);
        fb1.position(0);
        gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT,FB1);        //设置LIGHT0的灯光位置
        浮light_position [] = {1.0F,1.0F,1.0F,0.0};
        ByteBuffer的BB2 = ByteBuffer.allocateDirect(light_position.length * 4);
        bb2.order(ByteOrder.nativeOrder());
        FloatBuffer FB2 = bb2.asFloatBuffer();
        fb2.put(light_position);
        fb2.position(0);
        gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_POSITION,FB2);        //启用LIGTH和照明
        gl.glEnable(GL10.GL_LIGHT0);
        gl.glEnable(GL10.GL_LIGHTING);        //通过设置观察变换操纵模型视图矩阵
        gl.glTranslatef(-PAN_X,-PAN_Y,-EYE_DISTANCE);
        Trackball.build_rotmatrix(TRANSFORM_MATRIX,CURRENT_QUATERNION);
        gl.glMultMatrixf(TRANSFORM_MATRIX,0);        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        gl.glColor4x(65536,0,0,65536);        //创建一个自动旋转
        很长一段时间= System.currentTimeMillis的();
        长deltaTime =时间lastTime;
        lastTime =时间;
        如果(自动旋转){
            角=(浮点)(角度+ 360.0 / milSecPerRotation *
                                                                       deltaTime);
            如果(角度> 360.0f)
                角 - = 360;        }
        //构建行星和卫星并确定位置,旋转和
                  颜色        gl.glPushMatrix();
            gl.glColor4f(1.0F,0.0,0.0,1.0F);
            sun.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,8.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            merkur.draw(GL);
            gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,16.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            venus.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,24.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            erde.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,32.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            neptun.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,40.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            uranus.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,48.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            saturn.draw(GL);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0,56.0f,0.0);
            gl.glRotatef((浮点)角,0.0,0.0,-1.0F);
            jupiter.draw(GL);
        gl.glPopMatrix();
    }    //调整视口
    //设置投影矩阵
    公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
        gl.glViewport(0,0,宽度,高度);        漂浮的aspectRatio =(浮点)宽/高;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(GL,45.0f,的aspectRatio,zNear,zFar);
        GLU.gluLookAt(GL,0.0,0.0,5.0F,0.0,0.0,0.0,0.0,1.0F,
                                                                             0.0);
        gl.glMatrixMode(GL10.GL_MODELVIEW);        lastTime = System.currentTimeMillis的();
    }    //创建视口
    //一些OpenGL的初始化功能
    公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);        gl.glClearColor(0,0,0,1);
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glShadeModel(GL10.GL_SMOOTH);
        //gl.glShadeModel(GL10.GL_FLAT);
        gl.glEnable(GL10.GL_DEPTH_TEST);        resetViewing();
    }
}//的视图参数复位
静态无效resetViewing(){
    EYE_DISTANCE = 0.5F;
    EYE_DISTANCE_INC = 0.5F;
    PAN_X = 0.0;
    PAN_Y = 0.0;
    PAN_INC = 0.1F;    //初始化轨迹球
    Trackball.trackball(CURRENT_QUATERNION,0.0,0.0,0.0,0.0);
}
}


解决方案

要拿到球移动类似的行星,旋转和平移再

  glPushMatrix();
  gluLookAt(...); //摄像机转型应该影响到每一个人
  sun.draw(GL);  //画出地球和月球
  glPushMatrix();
    glRotatef(日,0,1,0);
    的glTranslatef(0,earthRadius,0);
    glPushMatrix();
      glRotatef(小时,0,1,0);
      earth.draw(GL);
      的glTranslatef(0,moonRadius,0);
      moon.draw(GL); //月亮是地球静止轨道,因此它不旋转
    glPopMatrix();
  glPopMatrix();  //绘制火星
  glPushMatrix();
    glRotatef(martianDay,0,1,0);
    的glTranslatef(0,marsRadius,0);
    mars.draw(GL);
  glPopMatrix();glPopMatrix();

调用顺序通常被称为依赖的转变,因为转变的影响变革的行动时,他们同样 glPushMatrix / glPopMatrix 块里面以后调用。

至于颜色的问题,那是因为你有照明启用,并从照明覆盖所产生的颜色(OpenGL的范围内,不是在你的顶点数组)与顶点传递。这本身不是一个问题,但它需要比使光照模型的环境更加的一部分。具体而言,您需要指定的材料属性的为对象。看看 glMaterialf

I have the following problem: I'm trying to create a solar system in OpenGL ES on Android. I already have some spheres. Now I want to make the spheres rotate in an orbit around the biggest sphere in the center (like the planets rotate around the sun). How do I do that? The rotation of a sphere around itself works, but I don't know how to make it rotate around another sphere.

Also, I have a problem with colors. There must be a problem somewhere in my code, because all my "planets" are grey. I tried to make the sun red, but it sticks to grey and I don't know why. I used gl.glColor4f and that should work, but it doesn't.

Please help, this is VERY urgent, because I need the thing running by Monday, the 28th of January, because this is a program I'm doing for my studies and I really have no idea how to fix these problems. Please help. Thank you.

Here is my code:

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;

import my.pack.graphics.primitives.Sphere;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.Toast;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

public class GLES06 extends Activity {
    private GLSurfaceView touchableGLSurfaceView;

    private final int MENU_RESET = 1, MENU_PAN = 2, MENU_ZOOM = 3;
    private final int GROUP_DEFAULT = 0, GROUP_PAN = 1, GROUP_ZOOM = 2;
    private boolean PAN = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    touchableGLSurfaceView = new TouchableGLSurfaceView(this);
    setContentView(touchableGLSurfaceView);
    touchableGLSurfaceView.setFocusableInTouchMode(true);
    touchableGLSurfaceView.requestFocus();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(GROUP_DEFAULT, MENU_RESET, 0, "Reset");
    menu.add(GROUP_PAN, MENU_PAN, 0, "Pan");
    menu.add(GROUP_ZOOM, MENU_ZOOM, 0, "Zoom");
    return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
    if (PAN) {
        menu.setGroupVisible(GROUP_PAN, false);
        menu.setGroupVisible(GROUP_ZOOM, true);
    } else {
        menu.setGroupVisible(GROUP_PAN, true);
        menu.setGroupVisible(GROUP_ZOOM, false);
    }
    return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case MENU_RESET:
            TouchableGLSurfaceView.resetViewing();
            Toast.makeText(this, "trackball reset",               
                            Toast.LENGTH_SHORT).show();
            touchableGLSurfaceView.requestRender();
            return true;
        case MENU_PAN:
            Toast.makeText(this, "panning activated", 
                            Toast.LENGTH_SHORT).show();
            PAN = true;
            TouchableGLSurfaceView.guiZoom = false;
            return true;
        case MENU_ZOOM:
            Toast.makeText(this, "zooming activated", 
                            Toast.LENGTH_SHORT).show();
            PAN = false;
            TouchableGLSurfaceView.guiZoom = true;
            return true;
    }
    return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {
    super.onResume();
    touchableGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
    super.onPause();
    touchableGLSurfaceView.onPause();
    }
 }

 // touchable GLSurfaceView with
 // an implementation of a virtual trackball rotation control
class TouchableGLSurfaceView extends GLSurfaceView {
    private OurRenderer ourRenderer;

    static public boolean guiZoom = true;
    // possible touch states
    final static int NONE = 0;
    final static int ROTATE = 1;
    final static int ZOOM = 2;
    final static int PAN = 3;
    int touchState = NONE;

    final static float MIN_DIST = 50;
    static int oldDistance = 0;
    static int centerX = 0, centerY = 0;
    static int oldCenterX = 0, oldCenterY = 0;

    static float EYE_DISTANCE, EYE_DISTANCE_INC;
    static float PAN_X, PAN_Y, PAN_INC;
    static float CURRENT_QUATERNION[], LAST_QUATERNION[];
    static float TRANSFORM_MATRIX[];

    static int OLD_MOUSE_X, OLD_MOUSE_Y, MOUSE_BUTTON_PRESSED;

    static int WINDOW_W = 600;
    static int WINDOW_H = 800;

    static float zNear = 1.0f, zFar = 1000.0f;

    static {
    CURRENT_QUATERNION = new float[4];
    LAST_QUATERNION = new float[4];
    TRANSFORM_MATRIX = new float[16];
    }

    public TouchableGLSurfaceView(Context context) {
    super(context);
    ourRenderer = new OurRenderer();
    setRenderer(ourRenderer);

    ourRenderer.autoRotate=true;
    setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    float p1x, p1y, p2x, p2y;
    // normalize mouse positions
    p1x = (2.0f * OLD_MOUSE_X - WINDOW_W) / WINDOW_W;
    p1y = (WINDOW_H - 2.0f * OLD_MOUSE_Y) / WINDOW_H;
    p2x = (2.0f * x - WINDOW_W) / WINDOW_W;
    p2y = (WINDOW_H - 2.0f * y) / WINDOW_H;

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            touchState = ROTATE;
            OLD_MOUSE_X = (int) x;
            OLD_MOUSE_Y = (int) y;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            // secondary touch event starts: remember distance
            oldDistance = (int) calcDistance(event);
            // and midpoint
            calcMidpoint(event);
            oldCenterX = centerX;
            oldCenterY = centerY;
            if (oldDistance > MIN_DIST) {
                if (guiZoom) {
                    touchState = ZOOM;
                } else {
                    touchState = PAN;
                }
            }
            break;
        case MotionEvent.ACTION_MOVE:  
            if (touchState == ROTATE) {
                // single finger rotate
                Trackball.trackball(LAST_QUATERNION, p1x, p1y, 
                                                                         p2x, p2y);
                OLD_MOUSE_X = (int) x;
                OLD_MOUSE_Y = (int) y;
                Trackball.add_quats(LAST_QUATERNION, 
                                              CURRENT_QUATERNION, CURRENT_QUATERNION);
                requestRender();
            } else if (touchState == ZOOM) {
                // double-finger zoom, zoom depends on changing 
                                       distance
                int dist = (int) calcDistance(event);
                if (dist > MIN_DIST) {
                    if (dist > oldDistance)
                    EYE_DISTANCE -= EYE_DISTANCE_INC;
                    else if (dist < oldDistance)
                    EYE_DISTANCE += EYE_DISTANCE_INC;
                    oldDistance = dist;
                    requestRender();
                }
            } else if (touchState == PAN) {
                int dist = (int) calcDistance(event);
                calcMidpoint(event);
                if (dist > MIN_DIST) {
                    if (centerX > oldCenterX)
                    PAN_X -= PAN_INC;
                    if (centerX < oldCenterX)
                    PAN_X += PAN_INC;
                    if (centerY > oldCenterY)
                    PAN_Y += PAN_INC;
                    if (centerY < oldCenterY)
                    PAN_Y -= PAN_INC;
                    oldCenterX = centerX;
                    oldCenterY = centerY;
                    requestRender();
                }
            }
            break;
        case MotionEvent.ACTION_UP:
            touchState = NONE;
            break;
        case MotionEvent.ACTION_POINTER_UP:
            touchState = ROTATE;
            // update touch down location for drag event to holding finger
            switch (event.getActionIndex()) {
                case 0:
                    OLD_MOUSE_X = (int) event.getX(1);
                    OLD_MOUSE_Y = (int) event.getY(1);
                    break;
                case 1:
                    OLD_MOUSE_X = (int) event.getX(0);
                    OLD_MOUSE_Y = (int) event.getY(0);
                    break;
            }
            break;
    }
    return true;
}

private float calcDistance(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
}

private void calcMidpoint(MotionEvent event) {
    centerX = (int) ((event.getX(0) + event.getX(1)) / 2);
    centerY = (int) ((event.getY(0) + event.getY(1)) / 2);
}

// the implementation of the renderer interface
private class OurRenderer implements GLSurfaceView.Renderer {

    //Declaration of some variables for our planets and moons
    private Sphere sun;
    private Sphere merkur;
    private Sphere venus;
    private Sphere erde;
    private Sphere neptun;
    private Sphere uranus;
    private Sphere saturn; 
    private Sphere jupiter;

    private long milSecPerRotation=20*1000;
    private double angle=0.0f;
    private long lastTime;

    public boolean autoRotate=true;

    public OurRenderer() {

        // Defining our planets and moons

        // spheres along z-axis with lightning
        // radius: the radius of the sphere
        // slices: the number of subdivisions along the z-axis
        // stacks: the number of subdivisions around the z-axis
        sun = new Sphere(4.0f, 10, 10);
        merkur = new Sphere(0.5f, 10,10);
        venus = new Sphere(0.9f, 10,10);
        erde = new Sphere(1.0f, 10,10);
        neptun = new Sphere(1.5f, 10,10);
        uranus = new Sphere(1.5f, 10,10);
        saturn = new Sphere(2.5f, 10,10);
        jupiter = new Sphere(3.0f, 10,10);



    }

    public void onDrawFrame(GL10 gl) {
        // the first thing to do: clear screen and depth buffer
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // reset modelview matrix
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();

        // set ambient light color
        float model_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
        ByteBuffer bb1 = ByteBuffer.allocateDirect(model_ambient.length * 4);
        bb1.order(ByteOrder.nativeOrder());
        FloatBuffer fb1 = bb1.asFloatBuffer();
        fb1.put(model_ambient);
        fb1.position(0);
        gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, fb1);

        // set light position of LIGHT0
        float light_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
        ByteBuffer bb2 = ByteBuffer.allocateDirect(light_position.length * 4);
        bb2.order(ByteOrder.nativeOrder());
        FloatBuffer fb2 = bb2.asFloatBuffer();
        fb2.put(light_position);
        fb2.position(0);
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, fb2);

        // enable ligth and lighting
        gl.glEnable(GL10.GL_LIGHT0);
        gl.glEnable(GL10.GL_LIGHTING);

        // manipulate modelview matrix by setting viewing transformation
        gl.glTranslatef(-PAN_X, -PAN_Y, -EYE_DISTANCE);
        Trackball.build_rotmatrix(TRANSFORM_MATRIX, CURRENT_QUATERNION);
        gl.glMultMatrixf(TRANSFORM_MATRIX, 0);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        gl.glColor4x(65536, 0, 0, 65536);

        // create an automatic rotation
        long time = System.currentTimeMillis();
        long deltaTime = time-lastTime;
        lastTime=time;
        if (autoRotate) {
            angle = (float) (angle + 360.0 / milSecPerRotation * 
                                                                       deltaTime);
            if (angle > 360.0f)
                angle -= 360;

        }    


        //Building the planets and moons and defining position, rotation and 
                  color

        gl.glPushMatrix();
            gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
            sun.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 8.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            merkur.draw(gl);
            gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 16.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            venus.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 24.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            erde.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 32.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            neptun.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 40.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            uranus.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 48.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            saturn.draw(gl);
        gl.glPopMatrix();
        gl.glPushMatrix();
            gl.glTranslatef(0.0f, 56.0f, 0.0f);
            gl.glRotatef((float) angle, 0.0f, 0.0f, -1.0f);
            jupiter.draw(gl);
        gl.glPopMatrix();
    }

    // resize of viewport
    // set projection matrix
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);

        float aspectRatio = (float) width / height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 45.0f, aspectRatio, zNear, zFar);
        GLU.gluLookAt(gl, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
                                                                             0.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);

        lastTime = System.currentTimeMillis();
    }

    // creation of viewport
    // initialization of some opengl features
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

        gl.glClearColor(0, 0, 0, 1);
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glShadeModel(GL10.GL_SMOOTH);
        //gl.glShadeModel(GL10.GL_FLAT);
        gl.glEnable(GL10.GL_DEPTH_TEST);

        resetViewing();
    }
}

// reset of view parameters
static void resetViewing() {
    EYE_DISTANCE = 0.5f;
    EYE_DISTANCE_INC = 0.5f;
    PAN_X = 0.0f;
    PAN_Y = 0.0f;
    PAN_INC = 0.1f;

    // trackball init
    Trackball.trackball(CURRENT_QUATERNION, 0.0f, 0.0f, 0.0f, 0.0f);
}
}

解决方案

To get the spheres to move like planets, rotate and then translate.

glPushMatrix();
  gluLookAt( ... );  // The camera transformation should affect everyone
  sun.draw(gl);

  // Draw the earth and moon
  glPushMatrix();
    glRotatef( day, 0, 1, 0 );
    glTranslatef( 0, earthRadius, 0 );
    glPushMatrix();
      glRotatef( hour, 0, 1, 0 );
      earth.draw(gl);
      glTranslatef( 0, moonRadius, 0 );
      moon.draw(gl); // the moon is geostationary, so it doesn't rotate
    glPopMatrix();
  glPopMatrix();

  // Draws mars
  glPushMatrix();
    glRotatef( martianDay, 0, 1, 0 );
    glTranslatef( 0, marsRadius, 0 );
    mars.draw(gl);
  glPopMatrix();

glPopMatrix();

This sequence of calls is often called "dependent transformations", since the actions of transformation influence transformations called later when they're inside of the same glPushMatrix/glPopMatrix block.

As for the color issue, it's because you have lighting enabled, and colors generated from lighting overwrite (within the OpenGL; not in your vertex arrays) passed in with the vertices. That's not a problem in itself, but it requires more than enabling the ambient part of the light model. Specifically, you need to specify material properties for your objects. Take a look at glMaterialf.

这篇关于旋转Android上使用OpenGL ES围绕另一个球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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