2011-02-23 3 views
1

내가 이것을 묻는 이유는 Droid와 Nexus One, 우리 두 대의 테스트 폰에서 잘 실행되지만 최근에 인수 한 Atrix 4G에서는 올바르게 작동하지 않기 때문입니다. 무엇이 그려 지는지에 대한 비뚤어진 버전입니다. 모든 색상이 시안 색, 마젠타 색 및 노란색 (약)의 교대 라인으로 대체되며, 이는 모래 입자의 기본 색상 중 하나가 나타나야한다고 생각하게합니다 그것이있는 줄에 따라 누락되었습니다. 불분명 한 설명을 드려 죄송합니다. 이미지가 있지만 계정에 10 개의 평판이 없으므로 게시 할 수 없습니다. 차이는 이유는 OpenGL 또는 측면에서 ATRIX 4G와 다른 휴대 전화 사이에 무엇인지에Atrix 4G와 다른 Android 휴대 전화간에 OpenGl 렌더링의 차이점은 무엇입니까?

/* 
* gl.c 
* -------------------------- 
* Defines the gl rendering and initialization 
* functions appInit, appDeinit, and appRender. 
*/ 

#include "gl.h" 
#include <android/log.h> 

unsigned int textureID; 

float vertices[] = 
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; 
float texture[] = 
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; 
unsigned char indices[] = 
{0, 1, 3, 0, 3, 2}; 
int texWidth = 1, texHeight = 1; 


void glInit() 
{ 
    //Set some properties 
    glShadeModel(GL_FLAT); 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 

    //Generate the new texture 
    glGenTextures(1, &textureID); 
    //Bind the texture 
    glBindTexture(GL_TEXTURE_2D, textureID); 

    //Enable 2D texturing 
    glEnable(GL_TEXTURE_2D); 
    //Disable depth testing 
    glDisable(GL_DEPTH_TEST); 

    //Enable the vertex and coord arrays 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 


    //Set tex params 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    //Set up texWidth and texHeight texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, emptyPixels); 
    //Free the dummy array 
    free(emptyPixels); 

    //Set the pointers 
    glVertexPointer(2, GL_FLOAT, 0, vertices); 
    glTexCoordPointer(2, GL_FLOAT, 0, texture); 
} 

void glRender() 
{ 
    //Check for changes in screen dimensions or work dimensions and handle them 
    if(dimensionsChanged) 
    { 
     vertices[2] = (float) screenWidth; 
     vertices[5] = (float) screenHeight; 
     vertices[6] = (float) screenWidth; 
     vertices[7] = (float) screenHeight; 

     texture[2] = (float) workWidth/texWidth; 
     texture[5] = (float) workHeight/texHeight; 
     texture[6] = (float) workWidth/texWidth; 
     texture[7] = (float) workHeight/texHeight; 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     if (!flipped) 
     { 
      glOrthof(0, screenWidth, screenHeight, 0, -1, 1); //--Device 
     } 
     else 
     { 
      glOrthof(0, screenWidth, 0, -screenHeight, -1, 1); //--Emulator 
     } 

     dimensionsChanged = FALSE; 
     zoomChanged = FALSE; 
    } 
    else if(zoomChanged) 
    { 
     texture[2] = (float) workWidth/texWidth; 
     texture[5] = (float) workHeight/texHeight; 
     texture[6] = (float) workWidth/texWidth; 
     texture[7] = (float) workHeight/texHeight; 

     zoomChanged = FALSE; 
    } 
    //__android_log_write(ANDROID_LOG_INFO, "TheElements", "updateview begin"); 
    UpdateView(); 
    //__android_log_write(ANDROID_LOG_INFO, "TheElements", "updateview end"); 

    //Clear the screen 
    glClear(GL_COLOR_BUFFER_BIT); 

    //Sub the work portion of the tex 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, workWidth, workHeight, GL_RGB, GL_UNSIGNED_BYTE, colors); 

    //Actually draw the rectangle with the text on it 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices); 
} 

어떤 아이디어 : 여기

은 텍스처링 및 렌더링을 수행 우리의 gl.c 파일의 코드입니다 우리의 애플 리케이션은 그것이 일반적으로 많이하고있는 일을하고있다! 미리 감사드립니다. http://imgur.com/Oyw64

답변

3

답장 시간이 조금 늦다는 것을 알고 있습니다 만, 혼합 된 색상을 보는 진정한 이유는 OpenGL의 스캔 라인 패킹 정렬 때문입니다. 드라이버 버그 또는 2 크기의 텍스처 문제가 아닌 것입니다.

귀하의 glTexSubImage2D 전화는 GL_RGB 형식으로 데이터를 전송하므로 귀하의 colors 버퍼는 픽셀 당 3 바이트라고 생각합니다. 확률은 Droid와 Nexus One 휴대폰의 기본 팩 정렬은 1이지만 Tegra 2의 기본값은 4입니다. 즉, 3 바이트 배열이 모든 주사선 다음에 드라이버가 예상하는 것과 정렬되지 않을 수 있으며 바이트 하나 또는 두 개 다음 스캔 라인에서 건너 뜁니다. 그 결과 색상이 나타납니다. 이 두 가지 크기의 텍스처로 작동하는 이유는 버퍼가 다음 스캔 라인에서 제대로 정렬 되었기 때문입니다. 기본적으로 이미지의 비트 심도에 관계없이 각 스캔 라인을 4 바이트로 패딩해야하는 BMP로드와 동일한 문제입니다.

glPixelStorei(GL_PACK_ALIGNMENT, 1);을 호출하여 맞춤 포장을 명시 적으로 비활성화 할 수 있습니다. 이 값을 변경하면 OpenGL에서 텍스처 데이터를 해석하는 방식에만 영향을 미치므로이 값을 변경하면 성능 저하가 입니다. 텍스처가 그래픽 서브 시스템으로 전송되면 스캔 라인은 하드웨어에 가장 적합한 포맷으로 저장되지만 드라이버는 여전히 데이터를 올바르게 압축 해제하는 방법을 알아야합니다. 그러나 매 프레임마다 텍스처 데이터를 변경하기 때문에 드라이버가 하나의 텍스처를 업로드하기 위해 memcpy()을 수행 할 수있는 대신, TextureHeight * memcpy()을 업로드해야 업로드 할 수 있습니다.이 경우 큰 병목 현상이 될 수는 없지만 최상의 성능을 원하는 경우 시작시 glGetIntegerv(GL_PACK_ALIGNMENT, &align);을 사용하여 드라이버의 기본 팩 정렬을 쿼리하고 런타임에 버퍼를 조정할 수 있습니다.

여기에 참조 용으로 specification on glPixelStore()이 있습니다.

+0

죄송합니다. 동의하는 데 조금 늦었지만 감사합니다! 실제로 작동합니다. – Ryan

0

ATRIX 4G는 엔비디아의 테그 라 GPU를 사용하는 최초의 저명한 전화입니다 : 여기

는 같은 모습의 예입니다. 따라서 이전 Android 기기와는 완전히 다른 OpenGL 구현이 있습니다. 버그 테그 라 하드웨어 + 소프트웨어 조합을 관찰하고 있거나 응용 프로그램이 정의되지 않은 동작에 의존하고 있으며 다른 장치에서 운이 좋았습니다.

Nvidia에 버그 보고서를 제출할 수 있습니다.

+0

고맙습니다. 다른 개발자는 명시 적으로 언급 한 이유로 setEGLSurfaceChooser()를 명시 적으로 호출해야한다고 제안했습니다. – Ryan

1

좋아, 우리는 마침내 실제 문제를 발견. glSubTexImage2D()는 Tegra 2를 포함하여 일부 GPU의 경우 실제로 WIDTH가 2의 제곱이지만 높이는 필요하지 않습니다. 우리는 2의 거듭 제곱이되어야하는 텍스처 였지만 우리는 틀렸어. 우리는 약간의 레코딩 작업을해야 할 것입니다.하지만 결국이 작업이 끝날 것입니다 (AT LAST !!).

관련 문제