簡體   English   中英

嘗試在設備上繪制紋理三角形失敗,但模擬器工作。為什么?

[英]Trying to draw textured triangles on device fails, but the emulator works. Why?

我有一系列OpenGL-ES調用,可以在模擬器(2.0.1)上使用alpha混合正確渲染三角形並對其進行紋理處理。 當我在實際設備(Droid 2.0.1)上啟動相同的代碼時,我得到的只是白色方塊。

這告訴我紋理沒有加載,但我無法弄清楚它們為什么不加載。 我的所有紋理都是帶有alpha通道的32位PNG,在res / raw下,所以它們沒有按照sdk文檔進行優化。

這是我加載紋理的方式:

private void loadGLTexture(GL10 gl, Context context, int reasource_id, int texture_id)
{
    //Get the texture from the Android resource directory
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions);

    //Generate one texture pointer...
    gl.glGenTextures(1, textures, texture_id);
    //...and bind it to our array
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[texture_id]);

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

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

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    //Clean up
    bitmap.recycle();
}

這是我渲染紋理的方式:

        //Clear
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    //Enable vertex buffer
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
        //Push transformation matrix
        gl.glPushMatrix();
        //Transformation matrices
        gl.glTranslatef(x, y, 0.0f);
        gl.glScalef(scalefactor, scalefactor, 0.0f);
        gl.glColor4f(1.0f,1.0f,1.0f,1.0f);
        //Bind the texture
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[textureid]);
        //Draw the vertices as triangles
        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
        //Pop the matrix back to where we left it
        gl.glPopMatrix();
            //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

以下是我啟用的選項:

        gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
        gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do
        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);

編輯:我剛剛嘗試向BitmapFactory.decodeResource()調用提供BitmapOptions,但這似乎無法解決問題,盡管手動設置相同的preferredconfig,density和targetdensity。

Edit2:根據要求,這是模擬器工作的屏幕截圖。 底層三角形顯示為圓形紋理,透明度正常,因為您可以看到黑色背景。

刪除了死的ImageShack鏈接

下面是機器人使用完全相同的代碼執行的操作:

刪除了死的ImageShack鏈接

Edit3:這是我的BitmapOptions,更新了上面的調用,我現在調用了BitmapFactory,結果如下:sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;

sBitmapOptions.inDensity = 160;
sBitmapOptions.inTargetDensity = 160;
sBitmapOptions.inScreenDensity = 160;
sBitmapOptions.inDither = false;
sBitmapOptions.inSampleSize = 1;
sBitmapOptions.inScaled = false;

這是我的頂點,紋理坐標和索引:

    /** The initial vertex definition */
    private static final float vertices[] = { 
                                        -1.0f, -1.0f, 0.0f, 
                                        1.0f, -1.0f, 0.0f,
                                        -1.0f, 1.0f, 0.0f,
                                        1.0f, 1.0f, 0.0f
                                                        };
    /** The initial texture coordinates (u, v) */   
private static final float texture[] = {            
                                    //Mapping coordinates for the vertices
                                    0.0f, 1.0f,
                                    1.0f, 1.0f,
                                    0.0f, 0.0f,
                                    1.0f, 0.0f
                                    };
/** The initial indices definition */   
private static final byte indices[] = {
                                        //Faces definition
                                        0,1,3, 0,3,2
                                        };

無論如何,一旦將紋理內容加載到OpenGL ES中,它是否會轉儲? 也許我可以將模擬器的加載紋理與實際設備的加載紋理進行比較?

我嘗試使用不同的紋理(默認的android圖標),再次,它適用於模擬器,但無法在實際手機上呈現。

Edit4:當我進行紋理加載時嘗試切換。 沒運氣。 嘗試使用0到glGenTextures的常量偏移0,沒有變化。

有沒有我正在使用的模擬器支持實際的手機沒有?

編輯5:下面的每個Ryan,我將紋理從200x200調整為256x256,問題未得到解決。

編輯:根據要求,將調用添加到上面的glVertexPointer和glTexCoordPointer。 另外,這里是vertexBuffer,textureBuffer和indexBuffer的初始化:

ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
loadGLTextures(gl, this.context);

當我從SDK 3移到4時,我確實遇到了這個問題。我的紋理將顯示在模擬器上,但不會顯示在真實設備上(Motorola Milestone / Droid)。

你的所有紋理都必須是2的二進制冪。 我的是256x256。 然而,紋理不顯示的原因是操作系統正在從二進制功率大小縮放它們以顯示在Milestone的高密度屏幕上。

解決方案很簡單 - 只需將紋理移動到drawable-nodpi目錄,操作系統在加載時就不會縮放它們。

我也是Android OpenGL ES dev的新手。 我擁有里程碑(Droid的歐元版)。

從目前為止我所看到的,在我的里程碑上從不同的書籍/網站發布幾個教程應用程序,似乎這款手機處理OpenGL ES的方式與迄今為止發布的所有其他Android手機不同。

我認為它與設備支持的OpenGL擴展有關。

檢查此鏈接以獲取支持的擴展名列表,我非常確定代碼大師會發現為什么droid正以這種奇怪的方式處理opengl。

http://www.rbgrn.net/content/345-hands-on-motorola-droid-opengl-es-specs

希望這個對你有幫助


編輯:

我調整了manifest.xml並在使用時注意到了

<uses-sdk android:minSdkVersion="6"/>

資源根本沒有加載。

使用時

<uses-sdk android:minSdkVersion="3"/>

資源正在加載。

所以我換回了

<uses-sdk android:minSdkVersion="6"/>

並改變了加載位圖的方式。

嘗試替換:

  //Get the texture from the Android resource directory 
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions); 

用:

InputStream is = context.getResources().openRawResource(your.resource.there);
    Bitmap bitmap = null;
    try {
        bitmap = BitmapFactory.decodeStream(is);

    } finally {
        //Always clear and close
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }

使用該代碼在我的里程碑上加載紋理,希望這項工作適合您的!

確保使用適當的BitmapConfig加載位圖,而不是在幕后縮放圖像,因為這種情況會發生。

另外,你有沒有理由將你的png存儲在/ raw /而不是/ drawable /?

Dullahx編輯的答案解決了我在同一問題上的問題。 非常感謝,這最近兩天讓我煩惱!

我試圖在三星galaxy選項卡上映射紋理,該選項卡已在模擬器上成功顯示,但只有平面顯示在設備上。

我替換了我的代碼:

plane.loadBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.jay));

這一個:

InputStream is = context.getResources().openRawResource(R.drawable.jay);

// Load the texture.
plane.loadBitmap(BitmapFactory.decodeStream(is));

它也在設備上工作!

但是如果你還試圖在像我這樣的全屏尺寸矩形上映射紋理,請注意minSdkVersion。 如果我使用

 <uses-sdk android:minSdkVersion="3"/>

在三星星系標簽上,我的飛機沒有全屏顯示。 它是根據使用sdk版本3的設備的全屏大小呈現的。我將其更改為

<uses-sdk android:minSdkVersion="8"/>

我的全屏矩形背面有紋理。

希望這也有幫助。

我不確定你的問題是什么,我對一般的開發都很陌生,但我的OpenGL android問題與模擬器和手機之間的區別是:

-Emulator可以支持非2 ^ x維度的位圖,手機不能-Emulator翻轉屏幕在NDK中用於openGL所以我不得不使用負坐標來定義模擬器中的視圖,而我的G1使用的坐標是非否定的。

希望這能夠在某種程度上幫助你。

我認為你可能無法從APK加載紋理。 嘗試將紋理復制到SD卡,看看是否可以從那里加載它。

你在某處使用GL11接口嗎? 並非所有設備都支持GL11。 並刪除glColor線,也許您的紋理顯示但是被顏色覆蓋? 這里有一些代碼片段,我如何顯示我的紋理網格:

void draw(GL10 gl) {

    // Enabled the vertices buffer for writing and to be used during
    // rendering.
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    // Specifies the location and data format of an array of vertex
    // coordinates to use when rendering.
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    gl.glEnable(GL10.GL_TEXTURE_2D);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
            GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
            GL10.GL_LINEAR);

    gl.glBindTexture(GL10.GL_TEXTURE_2D, myTextureId);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    gl.glDrawArrays(drawMode, 0, verticesCount);

    gl.glDisable(GL10.GL_TEXTURE_2D);
    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM