为什么在以下代码生成的二进制文件中没有出现镜面高光?
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参数似乎没有任何内容。我是否正确设置场景甚至可以查看镜面反射高光(我确实尝试将光线定位在顶点附近)?
答案 0 :(得分: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
答案 1 :(得分:2)
OpenGL ES只接受GL_FRONT_AND_BACK。请参阅glMaterial here
http://www.khronos.org/opengles/sdk/1.1/docs/man/glMaterial.xml