2011-08-25 28 views
0

構建了下面的OpenGL-ES程序,它僅使用環境光渲染一個簡單的紋理立方體,我遇到了一個奇怪的異常,同時嘗試使用GL_FRONT或GL_BACK參數實現「glMaterialfv」函數。在材質與GL_BACK_AND_FRONT參數結合處理正確的同時,GL_FRONT和GL_BACK都不會出現以產生正確的結果。由於我的法線似乎在定向光源的存在下工作,我只能假設我錯過了一些非常明顯的東西。這可能是Android模擬器本身的問題嗎?Android OpenGL「glMaterialfv」函數

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(); 
} 
} 

回答

2

現在已經審查了OpenGL-ES 1.1的文檔,我現在可以確認的是,GL_FRONT和GL_BACK參數僅在完整的OpenGL 1.1規範下的支持。對於目前爲OpenGL-ES平臺開發的人員,我的建議是確保他們的文檔專門覆蓋「ES」OpenGL子集。由於一些錯誤的假設,更不用說公平的嗜睡症,我花了很多小時不必要的測試目標平臺不支持的功能。就像烘烤蛋糕一樣,準備工作就是一切,而且我應該接受的一點是,對於採用這種校園男孩方法來製作其他可靠的API的人來說,這是一個迅速的開始。要重申一下,雖然這對大多數人來說可能是常識,但是如果您正在開發更小的「ES」對象,那麼完整的OpenGL規範沒有多大價值。