2011-02-23 28 views
1

我問這個問題的原因是我們的應用程序(The Elements)在我們的兩款測試手機Droid和Nexus One上運行良好,但在我們最近收購的Atrix 4G上運行不正確。繪製的東西是一個傾斜的版本,所有的顏色被青色,品紅色和黃色(大約)的交替線代替,這導致我們相信應該顯示沙粒的主要顏色之一缺少基於它在哪一行上。對於不明確的描述,我很抱歉,我們有圖片,但因爲這個帳戶沒有10個聲望,我們無法發佈它們。Atrix 4G和其他Android手機在OpenGl渲染方面有什麼不同?

這是我們gl.c文件的代碼,這確實紋理和渲染:

/* 
* 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); 
} 

任何想法,不同的是在OpenGL或者爲什麼方面的Atrix 4G等手機之間什麼我們的應用程序正在做它一般非常感謝!提前致謝。

這裏是什麼樣子的例子:http://imgur.com/Oyw64

回答

3

我知道答案有點遲,但您看到混合顏色的真正原因是由於OpenGL的掃描線包裝對齊 - 而不是由於驅動程序錯誤或兩次冪的尺寸紋理問題。

你的glTexSubImage2D呼叫發送的數據格式爲GL_RGB,所以我猜你的colors緩衝區是每個像素3個字節。 Droid和Nexus One手機的默認數據包對齊方式爲1,但Tegra 2的默認對齊方式爲4.這意味着您的3字節數組可能會與驅動程序在每條掃描線之後所期望的數據不一致,並且一個或兩個字節將跳過下一個掃描線,導致你看到的顏色。之所以這樣做,是因爲你的緩衝區正好適合下一條掃描線。基本上這與加載BMP的問題相同,每個掃描行必須填充到4個字節,而不管圖像的位深度如何。

您可以通過調用glPixelStorei(GL_PACK_ALIGNMENT, 1);明確禁用任何對齊打包。請注意,更改這隻會影響OpenGL解釋您的紋理數據的方式,所以沒有呈現更改此值的性能損失。紋理髮送到圖形子系統時,掃描線以硬件的最佳格式存儲,但驅動程序仍需知道如何正確解壓數據。但是,由於您要每幀更改紋理數據,而不是驅動程序能夠執行一次上傳整個紋理的操作,所以必須執行TextureHeight * memcpy() s才能上載它。這不太可能是一個主要瓶頸,但是如果您正在尋找最佳性能,則可能需要在啓動時使用glGetIntegerv(GL_PACK_ALIGNMENT, &align);查詢驅動程序的默認包裝對齊方式,並在運行時相應地調整緩衝區。

以下是specification on glPixelStore()作爲參考。

+0

對不起,我接受了一點時間,但謝謝! 這確實有效。 – Ryan 2013-07-30 23:50:12

0

的Atrix的4G是採用Nvidia的Tegra的GPU的第一個突出的手機。因此,它具有與以前的Android設備完全不同的OpenGL實現。無論您是觀察Tegra硬件+軟件組合的缺陷,還是您的應用程序都依賴於未定義的行爲,並且您在其他設備上運行良好。

你可能想用Nvidia提交一個錯誤報告。

+0

謝謝。另一位開發人員建議我們需要明確調用setEGLSurfaceChooser(),很可能是因爲你提到的內容。 – Ryan 2011-02-23 19:58:55

1

好的,我們終於找到了實際的問題。事實證明,glSubTexImage2D()實際上要求WIDTH是包括Tegra 2在內的一些GPU的兩倍,但不是高度的兩倍。我們認爲只有紋理需要是二的冪,那就是我們錯了。我們將不得不做一些重新編碼,但希望這將最終解決(AT LAST !!)。