2011-12-21 2 views
0

동적으로 텍스처를 생성하고 NDK를 사용하여 쿼드에 매핑하는 간단한 프로그램을 시도했습니다. 에뮬레이터에서는 모든 것이 정상이지만 실제 장치에서는 실패합니다. 내가 예상대로 그냥 작동실제 장치에서 OpenGL ES로 텍스처를 매핑 할 수 없습니다.

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

에뮬레이터에 :

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... 
    } 
} 

와 네이티브 코드 : 여기 내 코드 화면에 영역의 색상을 변경 유지합니다. 그러나 실제 장치 (Samsung Galaxy S 2.3.3 및 Asus Transformer TF101 3.2.1)에서 실행하면 흰색 블록이 나타나고 텍스처 매핑이 작동하지 않는 것 같습니다.

나는이 작품의 32 X 32 만 없음으로 변경 텍스처 크기를 추가하고 프로젝션을 주석으로 변환 glEnable(GL_TEXTURE_2D)를 호출하여 텍스처 매핑을 사용, glDisable(...)를 호출하여 알파 블렌딩 및 테스트를 비활성화 기능을 초기화하기 위해서 glBindTextureglTexImage2D를 이동했습니다.

왜 실제 장치에서 텍스처 매핑이 실패하는지 쉽게 알 수 있습니까? GPU 제한이 있습니까?

편집 : 나는 스푼의 제안을 시도하고 실제 문제를 발견했다. 어떤 텍스처를 바인딩하든 디바이스는 이라는 텍스처를 사용하여 쿼드를 렌더링하므로 glBindTexture(GL_TEXTURE_2D, 0)이 제대로 작동하지만 glBindTexture(GL_TEXTURE_2D, 1)glGenTextures(...)에 의해 반환되는 모든 것이 실패합니다. 이것은 하나의 텍스처 만 저장할 수 있다는 것을 의미하지만 2 개 이상을 사용해야합니다.

답변

0

흰색 블록은 텍스처링이 작동하지만 텍스처가 제대로로드되지 않았 음을 의미합니다.

실제 매핑이 문제라면 텍스처가 보이지만 모든 색상이 뒤틀리고 엉망이됩니다.

glGenTextures()으로 표시된 실제 값을 확인하십시오. OpenGL-es 1.x를 이후 버전의 안드로이드 (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를 추가 할 때 고해상도 폴더를 새로 고치거나 심지어 프로젝트를 청소하는 것을 잊지 마세요

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

} 

그러나 이것은 자바의 모든이며

을 그리기위한 OpenGL을-ES 2.0 OpenGL을-ES 1.1 텍스처 로딩에의 이상한 혼합 사용 0
+0

감사합니다. 나는 glGenTextures()에 의해 반환 된 값을 검사했다. 그것은 100,000보다 큰 난수를 던졌습니다. 저는 수동으로 제공된 숫자 0을 사용했습니다. [documentation] (http://www.khronos.org/opengles/documentation/opengles1_0/html/glBindTexture.html)에 따르면, 0은 각 텍스쳐 target_과 _ bound에 대해 기본 텍스쳐를 나타내는 예약 텍스쳐 이름 인 것 같다. initialization_에서 그들을 위해, 그래서 처음에 1 시도했지만 실패했습니다. –

+0

여전히 문제가 있습니다 (EDIT 참조). –

+0

'init()'에서'glGenTexture' (또는 수동으로 ID를 할당) 다음에'glBindTexture()'를 호출 한 다음 텍스처 매개 변수를 설정해야합니다. 첫 번째 텍스처를 제외하고 텍스처 매개 변수를 설정하지 않아서 효과가없는 이유 일 수 있습니다. 내 대답을 내 구현에 추가했습니다. 내 모든 자바 있지만, 그것은 중요하지 않아야합니다. 달리는 불의 작업 2.3.4. –

0

Android NDK의 gl2-jni 예제와 비슷한 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 
관련 문제