我正在开发一个带有OpenGLES的Android应用程序,但是当我添加一个镜面光时,该对象只会照亮对象的一侧,而我使用相同的代码和一点点修改,因为过剩而且可以正常工作。
这是我的活动代码
private Handler handler = new Handler();
private Handler handlerz = new Handler();
private ArrayList<Bottle> objecttable = new ArrayList<Bottle>();
private boolean start = true;
//ambientlight color
private float[] amblightcolor = {0.5f,0.5f,0.5f,1};
//diffuselight color
private float[] diflightcolor = {1f,1f,1f,1};
//specularlight color
private float[] specularcolor = {1,1,1,1};
//Position of light
private float[] lightpos = {0.0f,0.0f,1f,0};
//direction of light
private float[] lightdir = { 0.0f, 0.0f, -1.0f };
//FloatBuffer to use from light array
private FloatBuffer ambientlight;
private FloatBuffer diffuselight;
private FloatBuffer specularlight;
private FloatBuffer positionlight;
private FloatBuffer lightdirection;
private Random r = new Random();
private Runnable runnable = new Runnable() {
public void run() {
//Make every bottle in list spin more 1 angle for every 50 ms
for (Bottle b : objecttable){
b.angle += 1;
if (b.angle == 360)
b.angle = 0;
}
handler.postDelayed(this, 50);
}
};
private Runnable runnablez = new Runnable() {
public void run() {
//Make every bottle in list move in z axis and if bottle's z is more than 0 it reset to -10 and random position
if (!start){
if (!objecttable.isEmpty())
for (Bottle b : objecttable){
if (b.cz >= 0){
float factorx;
float factory;
if (r.nextBoolean())
factorx = r.nextFloat();
else
factorx = r.nextFloat() *-1;
if (r.nextBoolean())
factory = r.nextFloat();
else
factory = r.nextFloat() *-1;
b.cx = factorx;
b.cy = factory;
b.cz = -10;
}
else
//move rate = speed
b.cz += b.speed;
}
}
handler.postDelayed(this, 10);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Panel p = new Panel(this);
p.setRenderer(new Renderer());
setContentView(p);
handler.post(runnable);
handlerz.post(runnablez);
//Set model to draw from data
Bottle.setModel(this);
}
public class Panel extends GLSurfaceView{
public Panel(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
}
public class Renderer implements GLSurfaceView.Renderer{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
GLES10.glShadeModel(GLES10.GL_SMOOTH);
GLES10.glClearDepthf(1.0f);
GLES10.glEnable(GLES10.GL_DEPTH_TEST);
//initial light properties
initlight();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
GLES10.glViewport(0, 0, width, height);
GLES10.glMatrixMode(GLES10.GL_PROJECTION);
GLES10.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f,
(float) width / (float) height,
0.1f, 100.0f);
GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
GLES10.glLoadIdentity();
}
@Override
public void onDrawFrame(GL10 arg0) {
// TODO Auto-generated method stub
// At begining of program
if (start){
initDrawing();
start = false;
}
else
drawobject();
}
//Make a list for bottle there are new 5 bottles to add with random position
private void initDrawing(){
for (int i=0;i<5;i++){
float factorx;
float factory;
if (r.nextBoolean())
factorx = r.nextFloat();
else
factorx = r.nextFloat() *-1;
if (r.nextBoolean())
factory = r.nextFloat();
else
factory = r.nextFloat() *-1;
objecttable.add(new Bottle(factorx,factory,-10-i,(short) (20*i)));
}
}
//initial light properties
private void initlight(){
ByteBuffer ambl = ByteBuffer.allocateDirect(amblightcolor.length * 4);
ambl.order(ByteOrder.nativeOrder());
ambientlight = ambl.asFloatBuffer();
ambientlight.put(amblightcolor);
ambientlight.position(0);
ByteBuffer difl = ByteBuffer.allocateDirect(diflightcolor.length * 4);
difl.order(ByteOrder.nativeOrder());
diffuselight = difl.asFloatBuffer();
diffuselight.put(diflightcolor);
diffuselight.position(0);
ByteBuffer spcl = ByteBuffer.allocateDirect(specularcolor.length * 4);
spcl.order(ByteOrder.nativeOrder());
specularlight = spcl.asFloatBuffer();
specularlight.put(specularcolor);
specularlight.position(0);
ByteBuffer lpos = ByteBuffer.allocateDirect(lightpos.length * 4);
lpos.order(ByteOrder.nativeOrder());
positionlight = lpos.asFloatBuffer();
positionlight.put(lightpos);
positionlight.position(0);
ByteBuffer ldir = ByteBuffer.allocateDirect(lightdir.length * 4);
ldir.order(ByteOrder.nativeOrder());
lightdirection = ldir.asFloatBuffer();
lightdirection.put(lightdir);
lightdirection.position(0);
GLES10.glFrontFace(GLES10.GL_CCW);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_AMBIENT, ambientlight);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_DIFFUSE, diffuselight);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_SPECULAR, specularlight);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_POSITION, positionlight);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_SPOT_DIRECTION, lightdirection);
GLES10.glLightf(GLES10.GL_LIGHT0,GLES10.GL_SPOT_CUTOFF,15.0f);
GLES10.glMaterialfv(GLES10.GL_FRONT_AND_BACK, GLES10.GL_SPECULAR, specularlight);
GLES10.glMaterialf(GLES10.GL_FRONT_AND_BACK, GLES10.GL_SHININESS,128);
}
//draw every bottles in list using blend and light effect
private void drawobject(){
GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT | GLES10.GL_DEPTH_BUFFER_BIT);
GLES10.glEnable(GLES10.GL_BLEND);
GLES10.glBlendFunc (GLES10.GL_SRC_ALPHA, GLES10.GL_ONE_MINUS_SRC_ALPHA);
GLES10.glEnable(GLES10.GL_LIGHTING);
GLES10.glEnable(GLES10.GL_COLOR_MATERIAL);
GLES10.glMaterialfv(GLES10.GL_FRONT_AND_BACK, GLES10.GL_SPECULAR, specularlight);
GLES10.glMaterialf(GLES10.GL_FRONT_AND_BACK, GLES10.GL_SHININESS,128);
GLES10.glEnable(GLES10.GL_LIGHT0);
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
GLES10.glEnableClientState(GLES10.GL_NORMAL_ARRAY);
for(Bottle b : objecttable)
b.draw();
GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
GLES10.glDisableClientState(GLES10.GL_NORMAL_ARRAY);
GLES10.glDisable(GLES10.GL_BLEND);
GLES10.glDisable(GLES10.GL_COLOR_MATERIAL);
GLES10.glDisable(GLES10.GL_LIGHT0);
GLES10.glDisable(GLES10.GL_LIGHTING);
}
}
瓶类代码
public class Bottle {
//center of bottle x , y and z
public float cx;
public float cy;
public float cz;
//Angle of bottle
public short angle = 0;
//bottle's speed to move in z axis
public float speed = 0.02f;
//3D model data
public static FloatBuffer vertexBuffer;
public static FloatBuffer normalBuffer;
//3D model object use to import wavefront model to this object and make it to vertexBuffer and normalBuffer
public static BottleMdl Model;
public Bottle(float x, float y,float z,short ang) {
cx = x;
cy = y;
cz = z;
angle = ang;
}
//Bottle draw
public void draw(){
GLES10.glPushMatrix();
//translate the center of bottle
GLES10.glTranslatef(cx, cy, cz);
//Rotate the bottle by angle for making it spin
GLES10.glRotatef(angle, 1, 0, 0);
GLES10.glColor4f(0.05f, 0.05f, 0.05f, 0.8f);
GLES10.glVertexPointer(3, GLES10.GL_FLOAT, 0, vertexBuffer);
GLES10.glNormalPointer(GLES10.GL_FLOAT, 0, normalBuffer);
GLES10.glDrawArrays(GLES10.GL_TRIANGLES, 0, Model.numberofvertexs);
GLES10.glPopMatrix();
}
//Set a model data to vertexbuffer and normalbuffer
public static void setModel(Context context){
Model = new BottleMdl(context);
ByteBuffer vbb = ByteBuffer.allocateDirect(Model.vertexs.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(Model.vertexs);
vertexBuffer.position(0);
ByteBuffer nbb = ByteBuffer.allocateDirect(Model.normals.length * 4);
nbb.order(ByteOrder.nativeOrder());
normalBuffer = nbb.asFloatBuffer();
normalBuffer.put(Model.normals);
normalBuffer.position(0);
}
}
程序将首先安装灯光然后读取对象arraylist中的数据通过移动-z并在x轴上旋转对象并绘制来进行翻译。
图像应该是过剩的
http://i1187.photobucket.com/albums/z399/GalmTwo/glut_result.png
正如你所看到的那样,它在瓶子两侧闪耀,看起来就像光线位置固定一样
但是在android模拟器中
http://i1187.photobucket.com/albums/z399/GalmTwo/android_result.png
第一个是正确的,但当它翻转到瓶子的另一侧时,它看起来不像光一直在移动,但我非常确定我在变换任何东西之前设置了光位置并且在过剩中它工作正常
请帮我解决这个问题,或者给我一个镜像光的示例代码,可以在android中正常工作我试着整天解决这个问题,但我不能 谢谢你的帮助,抱歉我的英语不好。