为什么这个 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);
}
}
以下是我从代码中看到的内容(仅包含镜面照明组件): https://i. sstatic.net/KX612.png
仅使用环境照明组件:https://i.sstatic .net/b3Lf6.png
仅使用漫射照明组件:https://i.sstatic。 net/AHixo.png
可能有趣的是我调用 glOrtho 时的 zNear/zFar 参数似乎没有剪切任何内容。我是否正确设置了场景以查看镜面高光(我确实尝试将灯光放置在顶点附近)?
Why aren't specular highlights showing up in the binary produced by the following code?
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);
}
}
Here is what I see from the code as is (with just a specular lighting component): https://i.sstatic.net/KX612.png
With just an ambient lighting component: https://i.sstatic.net/b3Lf6.png
With just a diffuse lighting component: https://i.sstatic.net/AHixo.png
Possibly of interest is that the zNear/zFar parameters in my call to glOrtho don't seem to clip anything. Have I properly set up the scene to even view a specular highlight (I did try to position the light near a vertex)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
OpenGL ES 仅接受 GL_FRONT_AND_BACK。请参阅此处的 glMaterial
http://www.khronos.org/opengles/ sdk/1.1/docs/man/glMaterial.xml
OpenGL ES only accept GL_FRONT_AND_BACK. See glMaterial here
http://www.khronos.org/opengles/sdk/1.1/docs/man/glMaterial.xml
好吧,在我又把头撞到墙上几个小时后,我决定在设备上实际运行代码而不仅仅是模拟器上运行代码。你不知道吗,经过一些调整后,它似乎工作得很好!
这是一个新的示例,其中包含我所做的更改和一个更好的场景来说明所感知到的问题:
我遇到的最大奇怪之处是必须从 GL_FRONT 切换到 GL_FRONT_AND_BACK,我不知道为什么它不能仅与 GL_FRONT (或只是GL_BACK,我也尝试过,以防我的绕组向后或其他什么情况)。
是模拟器上的新示例:i.imgur.com/ldAND.png
这 设备:i.imgur.com/Ukqqm.png
Well, after banging my head against the wall for a few more hours, I decided on the novel idea of actually running the code on a device instead of just the emulator. Wouldn't you know, after a few tweaks, it seems to work fine!
Here's a new sample with the changes I made and a better scene to illustrate the perceived problem:
The biggest oddity I ran across is having to switch from GL_FRONT to GL_FRONT_AND_BACK, I have no clue why it wouldn't work with just GL_FRONT (or just GL_BACK, which I also tried in case my winding was backwards or something).
Here's the new sample on the emulator: i.imgur.com/ldAND.png
And on the actual device: i.imgur.com/Ukqqm.png