2010-12-13 58 views
2

为什么在下面的代码生成的二进制文件中不出现镜面高光?为什么这个Android镜面照明示例不按预期工作?

package com.example.helloandroid; 

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.opengl.GLSurfaceView.Renderer; 

public class TestRenderer implements Renderer { 
    private FloatBuffer vb; 
    private FloatBuffer mab, mdb, msb; 

    private FloatBuffer lPos; 
    private FloatBuffer lab, ldb, lsb; 

    public TestRenderer() { 
     vb = ByteBuffer.allocateDirect(24 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     vb.put(new float[]{ 
      110.0f, 240.0f, 
      110.0f, 190.0f, 
      160.0f, 240.0f, 
      160.0f, 190.0f, 
      210.0f, 240.0f, 
      210.0f, 190.0f, 
      110.0f, 290.0f, 
      110.0f, 240.0f, 
      160.0f, 290.0f, 
      160.0f, 240.0f, 
      210.0f, 290.0f, 
      210.0f, 240.0f}); 
     vb.position(0); 
     mab = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     mab.put(new float[]{1.0f, 0.0f, 0.0f, 1.0f}); 
     mab.position(0); 
     mdb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     mdb.put(new float[]{0.0f, 1.0f, 0.0f, 1.0f}); 
     mdb.position(0); 
     msb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     msb.put(new float[]{0.0f, 0.0f, 1.0f, 1.0f}); 
     msb.position(0); 

     lPos = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     lPos.put(new float[]{160.0f, 240.0f, 10.0f, 1.0f}); 
     lPos.position(0); 
     lab = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     // THIS WORKS.. 
     lab.put(new float[]{0.0f, 0.0f, 0.0f, 1.0f}); 
     lab.position(0); 
     ldb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     // SO DOES THIS.. 
     ldb.put(new float[]{0.0f, 0.0f, 0.0f, 1.0f}); 
     ldb.position(0); 
     // BUT NOT THIS 
     lsb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     lsb.put(new float[]{1.0f, 1.0f, 1.0f, 1.0f}); 
     lsb.position(0); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 

     gl.glEnable(GL10.GL_LIGHTING); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

     gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_AMBIENT, mab); 
     gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_DIFFUSE, mdb); 
     gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_SPECULAR, msb); 

     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lPos); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lab); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, ldb); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lsb); 
     gl.glEnable(GL10.GL_LIGHT0); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     gl.glViewport(0, 0, width, height); 

     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     gl.glOrthof(0.0f, width, 0.0f, height, -1.0f, 1.0f); 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
     gl.glTranslatef(0.0f, 0.0f, -1.0f); 
    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

     gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vb); 
     gl.glNormal3f(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 6); 
     gl.glDrawArrays(GL10.GL_LINE_STRIP, 6, 6); 
    } 
} 

以下是我从代码中看到如(只有镜面照明分量):http://i.imgur.com/4kvIx.png

只需环境照明部件:http://i.imgur.com/80Tjx.png

只需漫射照明组件: http://i.imgur.com/r5PkO.png

可能感兴趣的是我在调用glOrtho时的zNear/zFar参数似乎没有夹住任何东西。我是否正确设置了场景以查看镜面高光(我尝试将光线定位在顶点附近)?

回答

2

好吧,在将我的头靠在墙上多了几个小时后,我决定在设备上运行代码而不是模拟器。你不知道,经过一些调整,它似乎工作正常!

这里与我所做的更改和美好的场景一个新的样本来说明感知的问题:

package com.example.helloandroid; 

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.opengl.GLSurfaceView.Renderer; 
import android.opengl.GLU; 

public class TestRenderer implements Renderer { 
    private int rows; 
    private int cols; 

    private FloatBuffer vb; 
    private FloatBuffer mab, mdb, msb; 

    private FloatBuffer lPos; 
    private FloatBuffer lab, ldb, lsb; 

    public TestRenderer(int rows, int cols) { 
     this.rows = rows; 
     this.cols = cols; 

     vb = ByteBuffer.allocateDirect(4 * (rows - 1) * cols * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     for(int row = 0; row < (rows - 1); ++row) 
      for(int col = 0; col < cols; ++col) { 
       vb.put(col * 320.0f/(cols - 1)); vb.put((row + 1) * 480.0f/(rows - 1)); 
       vb.put(col * 320.0f/(cols - 1)); vb.put(row * 480.0f/(rows - 1)); 
      } 
     vb.position(0); 
//  vb = ByteBuffer.allocateDirect(24 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
//  vb.put(new float[]{ 
//   0.0f, 50.0f, 
//   0.0f, 0.0f, 
//   50.0f, 50.0f, 
//   50.0f, 0.0f, 
//   100.0f, 50.0f, 
//   100.0f, 0.0f, 
//   0.0f, 100.0f, 
//   0.0f, 50.0f, 
//   50.0f, 100.0f, 
//   50.0f, 50.0f, 
//   100.0f, 100.0f, 
//   100.0f, 50.0f}); 
//  vb.position(0); 
     mab = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     mab.put(new float[]{1.0f, 0.0f, 0.0f, 1.0f}); 
     mab.position(0); 
     mdb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     mdb.put(new float[]{0.0f, 1.0f, 0.0f, 1.0f}); 
     mdb.position(0); 
     msb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     msb.put(new float[]{0.0f, 0.0f, 1.0f, 1.0f}); 
     msb.position(0); 

     lPos = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     lPos.put(new float[]{-180.0f, 0.0f, 300.0f, 1.0f}); 
     lPos.position(0); 
     lab = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     // THIS WORKS.. 
     lab.put(new float[]{0.1f, 0.0f, 0.0f, 1.0f}); 
     lab.position(0); 
     ldb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     // SO DOES THIS.. 
     ldb.put(new float[]{0.0f, 0.1f, 0.0f, 1.0f}); 
     ldb.position(0); 
     // BUT NOT THIS 
     lsb = ByteBuffer.allocateDirect(4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     lsb.put(new float[]{0.0f, 0.0f, 1.0f, 1.0f}); 
     lsb.position(0); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 

     gl.glEnable(GL10.GL_LIGHTING); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

     gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mab); 
     gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, mdb); 
     gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, msb); 
     gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 128.0f); 

     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lPos); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lab); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, ldb); 
     gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lsb); 
     gl.glEnable(GL10.GL_LIGHT0); 

     gl.glDisable(GL10.GL_TEXTURE); 
     gl.glFrontFace(GL10.GL_CCW); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     gl.glViewport(0, 0, width, height); 

     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
//  gl.glOrthof(0.0f, width, 0.0f, height, -1.0f, 1.0f); 
     GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 999.0f, 1001.0f); 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

     gl.glLoadIdentity(); 
     gl.glTranslatef(-160.0f, -240.0f, -1000.0f); 

     gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vb); 
     gl.glNormal3f(0.0f, 0.0f, 1.0f); 
     for(int row = 0; row < rows - 1; ++row) { 
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 2 * row * cols, 2 * cols); 
//   gl.glDrawArrays(GL10.GL_LINE_STRIP, 2 * row * cols, 2 * cols); 
     } 
//  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 6); 
//  gl.glDrawArrays(GL10.GL_LINE_STRIP, 6, 6); 
    } 

} 

我跑过最大的奇异之处不必从GL_FRONT切换到GL_FRONT_AND_BACK,我不知道为什么它不适用于仅仅GL_FRONT(或者仅仅是GL_BACK,我也尝试过,以防我的绕组倒退或其他情况)。

这里的模拟器上的新样本:i.imgur.com/ldAND.png

和实际设备上:i.imgur.com/Ukqqm.png

相关问题