2011-12-21 12 views
0

テクスチャを動的に生成し、NDKを使ってそれをクワッドにマッピングする簡単なプログラムを試しました。エミュレータではすべて正常ですが、実際のデバイスでは失敗しました。ここ は私のコードです:実際のデバイスでOpenGL ESでテクスチャをマッピングできない

private static class Renderer implements GLSurfaceView.Renderer 
{ 
    @Override 
    public void onDrawFrame(GL10 gl) 
    { 
     nativeDrawFrame(); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) 
    { 
     nativeInit(width, height); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) 
    { 
     // do nothing... 
    } 
} 

とネイティブコード:画面上の領域には、その色を変え続けて:それはちょうど私が期待どおりに動作エミュレータ上

const static GLfloat vertices_f[4][2] = 
{ 
    { 0.0f, 0.0f }, 
    { 100.0f, 0.0f }, 
    { 100.0f, 100.0f }, 
    { 0.0f, 100.0f } 
}; 

const static GLfloat texCoords_f[4][2] = 
{ 
    { 0.0f, 0.0f }, 
    { 1.0f, 0.0f }, 
    { 1.0f, 1.0f }, 
    { 0.0f, 1.0f } 
}; 

JNIEXPORT void JNICALL Java_com_sangfor_gltest_GLView_nativeInit(JNIEnv * env, jobject obj, jint width, jint height) 
{ 
    if (!bitmap) 
    { 
     // allocate dynamic texture memory 
     bitmap = memalign(16, 1024*1024); 
     if (!bitmap) 
     { 
      __android_log_print(ANDROID_LOG_ERROR, "native-render", "failed allocation."); 
      return; 
     } 
    } 

    glViewport(0, 0, width, height); 
    //glMatrixMode(GL_PROJECTION); 
    //glLoadIdentity(); 
    //glOrthox(0, 0x10000, 0, 0x10000, 0x10000, -0x10000); 
    //glClearColorx(0, 0, 0, 0); 
    glGenTextures(1, &texture); 
    __android_log_print(ANDROID_LOG_INFO, "native-render", "texture = %d", texture); 
    // glVertexPointer(2, GL_FIXED, 0, vertices); 
    // glTexCoordPointer(2, GL_FIXED, 0, texCoords); 
    //glEnableClientState(GL_COLOR_ARRAY); 
    glColor4x(0x10000, 0x10000, 0x10000, 0x10000); 
    glEnable(GL_TEXTURE_2D); 
    glDisable(GL_BLEND); 
    glDisable(GL_ALPHA_TEST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
} 

JNIEXPORT void JNICALL Java_com_sangfor_gltest_GLView_nativeDrawFrame(JNIEnv * env, jobject obj) 
{ 
    struct timeval tv; 
    unsigned char color_value; 

    glClear(GL_COLOR_BUFFER_BIT); 

    // fill texture according to current timestamp 
    gettimeofday(&tv, NULL); 
    color_value = (unsigned char)(tv.tv_usec * 0.000255f); 
    memset(bitmap, color_value, 1024*1024); 
    __android_log_print(ANDROID_LOG_INFO, "native-render", "color_value = %d", color_value); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glEnableClientState(GL_VERTEX_ARRAY); 

    glTexCoordPointer(2, GL_FLOAT, 0, texCoords_f); 
    glVertexPointer(2, GL_FLOAT, 0, vertices_f); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
    glFlush(); 
} 

。 しかし、実際のデバイス(Samsung Galaxy S 2.3.3とAsus Transformer TF101 3.2.1)で実行すると、白いブロックが表示され、テクスチャマッピングが機能していないようです。

私は追加してコメントアウト投影変換、glEnable(GL_TEXTURE_2D)を呼び出すことにより、テクスチャマッピングを可能にする、glDisable(...)を呼び出すことにより、アルファブレンディングとテストを無効にし、機能をinitにglBindTextureglTexImage2Dを移動し、32×32が、これらの作品のどれにテクスチャサイズを変更してみました。

実際のデバイスだけでテクスチャマッピングが失敗する理由を知る手助けができますか? GPUの制限などはありますか?

EDIT:私はスプーンの提案を試みて、実際の問題を発見しました。どのテクスチャをバインドしても、デバイスはテクスチャを使用してクワッドをレンダリングするので、glBindTexture(GL_TEXTURE_2D, 0)は正常に動作しますが、glBindTexture(GL_TEXTURE_2D, 1)と返されるものはすべてglGenTextures(...)で返されません。つまり、1つのテクスチャしか保存できませんが、2つ以上使用する必要があります。

答えて

0

白いブロックは、テクスチャリングが機能しているが、テクスチャが正しくロードされていないことを意味します。

実際のマッピングが問題であった場合は、テクスチャが表示されますが、すべての色が歪んでしまいます。

glGenTextures()で示される実際の値を確認してください。 OpenGL-es 1.xをAndroid 2.2以降のバージョンで使用した場合、glGenTextures()は0,1,2,3などのIDを与えるのではなく、実際に乱数を投げたことがわかりました。手動で供給する必要があるかもしれません自分のIDと使用しないでくださいglGenTextures()

また、ピクセルデータがファイルから正しく読み込まれていることを確認してください。ファイル名が間違っているかファイルがありませんが、アプリケーションを続行できるようなエラー処理を行っている場合は、空の白いテクスチャが表示されることがあります。描画するときに次に

public class Texture{ 

private int textureId = -1; 
// initialise to -1 

public int getTextureId(){ 
    return textureId; 
} 

public void loadTexture(GL10 gl, Context context){ 

    String[] filenamesplit = filename.split("\\."); 

    name = filenamesplit[filenamesplit.length-2]; 

    int[] textures = new int[1]; 
    //Generate one texture pointer... 
    //GLES20.glGenTextures(1, textures, 0);    
    textures[0] = ((IridianGraphicsEngine)context).texturecount; 
    ((IridianGraphicsEngine)context).texturecount++; 

    //...and bind it to our array 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); 

    //Create Nearest Filtered Texture 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    //Different possible texture parameters, e.g. GLES20.GL_CLAMP_TO_EDGE 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

    Bitmap bitmap = FileUtil.openBitmap(name, context); 

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

    bitmap.recycle(); 

    textureId = textures[0]; 

} 
} 

これは私がそれをやった方法です:

および/または新しいテクスチャ

UPDATEを追加するときのresフォルダをリフレッシュしたり、プロジェクトをきれいにすることを忘れないでください

public class Mesh{ 

private Texture texture; 

public void draw(GL10 gl){ 

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

    // Pass the vertex buffer in 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, 
          vertices); 

    int textureId = texture.getTextureId(); 

    if(textureID>=0){ 

     // Enable Textures 
     gl.glEnable(GL10.GL_TEXTURE_2D); 

     // Get specific texture. 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID); 

     // Use UV coordinates. 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

     // Pass in texture coordinates   
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordinates); 

    } 

    // Pass in vertex normals 
    gl.glNormalPointer(GL10.GL_FLOAT, 0, normals); 

    gl.glEnableClientState(GL10.GL_NORMAL_ARRAY); 

    gl.glDrawElements(GL10.GL_TRIANGLES, numindices,GL10.GL_UNSIGNED_SHORT, indices); 

    gl.glDisableClientState(GL10.GL_NORMAL_ARRAY); 

    if(textureID>=0){ 
     // Disable buffers   
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    } 

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 

} 

しかしこれは、すべてJavaであると

を描画するためのテクスチャ読み込みとOpenGL-ES 1.1用のOpenGL-ES 2.0の奇妙なミックスを使用しています0
+0

感謝。私は 'glGenTextures()'によって返された値をチェックしました。それは10万を超える乱数を投げた。私は手動で供給された番号0を使用し、それは働いた! [documentation](http://www.khronos.org/opengles/documentation/opengles1_0/html/glBindTexture.html)によると、0は各テクスチャのデフォルトテクスチャを表す予約テクスチャ名と思われます_と_はバインドされています初期化時にはそのために1を試しましたが、失敗しました。 –

+0

問題が解決しない場合は、EDITを参照してください。 –

+0

'init()'では、 'glGenTexture'の後に' glBindTexture() 'を呼び出すか、手動でIDを割り当ててから、テクスチャパラメータを設定する必要があります。これはおそらく、最初のテクスチャ以外のテクスチャパラメータを設定していないので、うまくいかない理由です。私の答えを私の実装に加えました。私のものはすべてJavaですが、それは問題ではありません。 2.3.4を実行している火の火の上で動作します。 –

0

私はJNIネイティブメソッドを別のラッパークラスに移動しました。これはAndroid NDKのgl2-jniの例と似ていますが、問題は解決しました。私はラッパークラスで静的なネイティブコードを実装することによって違いが生じるのはなぜか分かりませんが、とにかく、うまくいきます。

GLJNILib.java

// Wrapper for native library 
public class GLJNILib { 

    static { 
     System.loadLibrary("gljni"); 
    } 

    /** 
    * @param width the current view width 
    * @param height the current view height 
    */ 
    public static native void init(int width, int height); 
    public static native void step(); 
} 

GLJNIView.java返信用

// some other stuff 

private class Renderer implements GLSurfaceView.Renderer { 
    private static final String TAG = "Renderer"; 
    public void onDrawFrame(GL10 gl) { 
     GLJNILib.step(); 
    } 

    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     GLJNILib.init(width, height); 
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     // Do nothing. 
    } 
} 

// some other stuff 
関連する問題