旋转Android上使用OpenGL ES围绕另一个球体 [英] Rotating a sphere around another using OpenGL ES on Android
问题描述
我有以下问题:我想在OpenGL ES的Android上创建一个太阳系。我已经有了一些领域。现在,我想使球在轨道上绕上最大球体中心(像行星围绕太阳旋转)。我怎么做?自己周围球体的旋转工作,但我不知道如何使它绕另一个领域。
另外,我有颜色的问题。必须有一个问题在什么地方我的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屋!