Android OpenGL“glMaterialfv”功能

时间:2011-08-25 07:50:38

标签: android opengl-es

构建了以下OpenGL-ES程序,该程序仅使用环境光渲染一个简单的纹理立方体,我在尝试使用GL_FRONT或GL_BACK参数实现“glMaterialfv”函数时遇到了奇怪的异常。虽然材料与GL_BACK_AND_FRONT参数一起正确处理,但GL_FRONT和GL_BACK似乎都不会产生正确的结果。由于我的法线似乎在定向光源的存在下工作,我只能假设我遗漏了一些非常明显的东西。这可能是Android模拟器本身的一个问题吗?

package tal.cube1;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.graphics.BitmapFactory;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.content.res.*;
import android.graphics.Bitmap;

public class OpenGLRenderer implements Renderer
{ 
 private final float mf_textureCoordinates[] =
 {
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f,
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f,
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f,
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f,
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f,
  0.0f, 0.0f,   0.0f, 1.0f,   1.0f, 1.0f,   1.0f, 0.0f
 };

 private final float mf_normals[] = 
 { 0,  0,  1,    0,  0,  1,    0,  0,  1,    0,  0,  1,
   0,  1,  0,    0,  1,  0,    0,  1,  0,    0,  1,  0,
   0,  0, -1,    0,  0, -1,    0,  0, -1,    0,  0, -1,
   0, -1,  0,    0, -1,  0,    0, -1,  0,    0, -1,  0,
  -1,  0,  0,   -1,  0,  0,   -1,  0,  0,   -1,  0,  0,
   1,  0,  0,    1,  0,  0,    1,  0,  0,    1,  0,  0
 };

 private final float mf_vertices[] =
 {-1,  1,  1,   -1, -1,  1,    1, -1,  1,    1,  1,  1,
  -1,  1, -1,   -1,  1,  1,    1,  1,  1,    1,  1, -1,
   1,  1, -1,    1, -1, -1,   -1, -1, -1,   -1,  1, -1,
  -1, -1,  1,   -1, -1, -1,    1, -1, -1,    1, -1,  1,
  -1,  1, -1,   -1, -1, -1,   -1, -1,  1,   -1,  1,  1,
   1,  1,  1,    1, -1,  1,    1, -1, -1,    1,  1, -1
 };

 private final short mf_indices[] =
 { 0,  1,  2,    0,  2,  3,
   4,  5,  6,    4,  6,  7,
   8,  9, 10,    8, 10, 11,
  12, 13, 14,   12, 14, 15,
  16, 17, 18,   16, 18, 19,
  20, 21, 22,   20, 22, 23
 };

 private final float mf_ambientLight[] =
 {
  1.0f, 1.0f, 1.0f, 1.0f
 };

 private final float mf_ambientMaterial[] =
 {
  1.0f, 0.0f, 0.0f, 1.0f
 };

 private FloatBuffer m_vertexBuffer;
 private FloatBuffer m_normalBuffer;
 private FloatBuffer m_textureBuffer;
 private ShortBuffer m_indexBuffer;
 private Bitmap m_texture;
 private int m_textures[]; 
 private float m_angle = 0.0f;

 public OpenGLRenderer(Resources p_resources)
 {
  super();
  m_texture = BitmapFactory.decodeResource(p_resources, R.drawable.crate);
 }

 @Override public void onSurfaceCreated(GL10 p_gl, EGLConfig p_config)
 {
  ByteBuffer vbb = ByteBuffer.allocateDirect(mf_vertices.length * 4);
  vbb.order(ByteOrder.nativeOrder());
  m_vertexBuffer = vbb.asFloatBuffer();
  m_vertexBuffer.put(mf_vertices);
  m_vertexBuffer.position(0);

  ByteBuffer nbb = ByteBuffer.allocateDirect(mf_normals.length * 4);
  nbb.order(ByteOrder.nativeOrder());
  m_normalBuffer = nbb.asFloatBuffer();
  m_normalBuffer.put(mf_normals);
  m_normalBuffer.position(0);

  ByteBuffer tbb = ByteBuffer.allocateDirect(mf_textureCoordinates.length * 4);
  tbb.order(ByteOrder.nativeOrder());
  m_textureBuffer = tbb.asFloatBuffer();
  m_textureBuffer.put(mf_textureCoordinates);
  m_textureBuffer.position(0);

  ByteBuffer ibb = ByteBuffer.allocateDirect(mf_indices.length * 2);
  ibb.order(ByteOrder.nativeOrder());
  m_indexBuffer = ibb.asShortBuffer();
  m_indexBuffer.put(mf_indices);
  m_indexBuffer.position(0);

  m_textures = new int[1];
  p_gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textures[0]);
  p_gl.glGenTextures(1, m_textures, 0);
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, m_texture, 0);

  p_gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  p_gl.glClearDepthf(1.0f);
  p_gl.glShadeModel(GL10.GL_FLAT);
  p_gl.glDepthFunc(GL10.GL_LEQUAL);
  p_gl.glFrontFace(GL10.GL_CCW);
  p_gl.glCullFace(GL10.GL_BACK);
  p_gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

  p_gl.glDisable(GL10.GL_DITHER);
  p_gl.glEnable(GL10.GL_DEPTH_TEST);
  p_gl.glEnable(GL10.GL_CULL_FACE);
  p_gl.glEnable(GL10.GL_LIGHTING);
  p_gl.glEnable(GL10.GL_TEXTURE_2D);

  p_gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
  p_gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  p_gl.glEnableClientState(GL11.GL_NORMAL_ARRAY);

  p_gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, m_textureBuffer);
  p_gl.glNormalPointer(GL10.GL_FLOAT, 0, m_normalBuffer);
  p_gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_vertexBuffer);

  p_gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, mf_ambientLight, 0);
  p_gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mf_ambientMaterial, 0);
 }

 @Override public void onDrawFrame(GL10 p_gl)
 {
  p_gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
               GL10.GL_DEPTH_BUFFER_BIT);
  p_gl.glLoadIdentity();
  p_gl.glTranslatef(0.0f, 0.0f, -8);
  p_gl.glRotatef(m_angle, 1.0f, 1.0f, 1.0f);
  p_gl.glDrawElements(GL10.GL_TRIANGLES, m_indexBuffer.capacity(),
                      GL10.GL_UNSIGNED_SHORT, m_indexBuffer);
  m_angle += 1.0f;
 }

 @Override public void onSurfaceChanged(GL10 p_gl, int p_width, int p_height)
 {
  p_gl.glViewport(0, 0, p_width, p_height);
  p_gl.glMatrixMode(GL10.GL_PROJECTION);
  p_gl.glLoadIdentity();
  GLU.gluPerspective(p_gl, 45.0f, (float)p_width / (float)p_height,
                     0.1f, 100.0f);
  p_gl.glMatrixMode(GL10.GL_MODELVIEW);
  p_gl.glLoadIdentity();
 }
}

1 个答案:

答案 0 :(得分:2)

现在回顾了OpenGL-ES 1.1文档,我现在可以确认GL_FRONT和GL_BACK参数仅在完整的OpenGL 1.1规范下得到支持。我对目前为OpenGL-ES平台开发的任何人的建议是确保他们的文档专门涵盖“ES”OpenGL子集。由于一些错误的假设,更不用说公平的嗜睡,我花了很多时间不必要地测试目标平台不支持的功能。就像烘烤蛋糕一样,准备就是一切,而且我应该得到一个快速的帮助,因为他们采用这种学校男孩的方法来解决其他问题。重申一下,虽然这对于大多数人来说可能是常识,但如果你正在为其较小的“ES”对应物进行开发,那么完整的OpenGL规范几乎没有价值。