简体   繁体   English

尝试在设备上绘制纹理三角形失败,但模拟器工作。为什么?

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

I have a series of OpenGL-ES calls that properly render a triangle and texture it with alpha blending on the emulator (2.0.1). 我有一系列OpenGL-ES调用,可以在模拟器(2.0.1)上使用alpha混合正确渲染三角形并对其进行纹理处理。 When I fire up the same code on an actual device (Droid 2.0.1), all I get are white squares. 当我在实际设备(Droid 2.0.1)上启动相同的代码时,我得到的只是白色方块。

This suggests to me that the textures aren't loading, but I can't figure out why they aren't loading. 这告诉我纹理没有加载,但我无法弄清楚它们为什么不加载。 All of my textures are 32-bit PNGs with alpha channels, under res/raw so they aren't optimized per the sdk docs . 我的所有纹理都是带有alpha通道的32位PNG,在res / raw下,所以它们没有按照sdk文档进行优化。

Here's how I am loading my textures: 这是我加载纹理的方式:

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

Here's how I am rendering the texture: 这是我渲染纹理的方式:

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

And here are the options I have enabled: 以下是我启用的选项:

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

Edit: I just tried supplying a BitmapOptions to the BitmapFactory.decodeResource() call, but this doesn't seem to fix the issue, despite manually setting the same preferredconfig, density, and targetdensity. 编辑:我刚刚尝试向BitmapFactory.decodeResource()调用提供BitmapOptions,但这似乎无法解决问题,尽管手动设置相同的preferredconfig,density和targetdensity。

Edit2: As requested, here is a screenshot of the emulator working. Edit2:根据要求,这是模拟器工作的屏幕截图。 The underlaying triangles are shown with a circle texture rendered onto it, the transparency is working because you can see the black background. 底层三角形显示为圆形纹理,透明度正常,因为您可以看到黑色背景。

removed dead ImageShack link 删除了死的ImageShack链接

Here is a shot of what the droid does with the exact same code on it: 下面是机器人使用完全相同的代码执行的操作:

removed dead ImageShack link 删除了死的ImageShack链接

Edit3: Here are my BitmapOptions, updated the call above with how I am now calling the BitmapFactory, still the same results as below: sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; 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;

Here are my vertices, texture coords, and indices: 这是我的顶点,纹理坐标和索引:

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

Is there anyway to dump the contents of the texture once it's been loaded into OpenGL ES? 无论如何,一旦将纹理内容加载到OpenGL ES中,它是否会转储? Maybe I can compare the emulator's loaded texture with the actual device's loaded texture? 也许我可以将模拟器的加载纹理与实际设备的加载纹理进行比较?

I did try with a different texture (the default android icon) and again, it works fine for the emulator but fails to render on the actual phone. 我尝试使用不同的纹理(默认的android图标),再次,它适用于模拟器,但无法在实际手机上呈现。

Edit4: Tried switching around when I do texture loading. Edit4:当我进行纹理加载时尝试切换。 No luck. 没运气。 Tried using a constant offset of 0 to glGenTextures, no change. 尝试使用0到glGenTextures的常量偏移0,没有变化。

Is there something that I'm using that the emulator supports that the actual phone does not? 有没有我正在使用的模拟器支持实际的手机没有?

Edit5: Per Ryan below, I resized my texture from 200x200 to 256x256, and the issue was NOT resolved. 编辑5:下面的每个Ryan,我将纹理从200x200调整为256x256,问题未得到解决。

Edit: As requested, added the calls to glVertexPointer and glTexCoordPointer above. 编辑:根据要求,将调用添加到上面的glVertexPointer和glTexCoordPointer。 Also, here is the initialization of vertexBuffer, textureBuffer, and indexBuffer: 另外,这里是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);

I had exactly this issue when I moved from SDK 3 to 4. My textures would display on the emulator but not on the real device (Motorola Milestone/Droid). 当我从SDK 3移到4时,我确实遇到了这个问题。我的纹理将显示在模拟器上,但不会显示在真实设备上(Motorola Milestone / Droid)。

All your textures must be binary powers of two. 你的所有纹理都必须是2的二进制幂。 Mine were 256x256. 我的是256x256。 However the reason the textures don't display is that the OS is scaling them from their binary power sizes to display on the Milestone's high density screen. 然而,纹理不显示的原因是操作系统正在从二进制功率大小缩放它们以显示在Milestone的高密度屏幕上。

The solution is easy - just move the textures to the drawable-nodpi directory and the OS won't scale them when it loads them. 解决方案很简单 - 只需将纹理移动到drawable-nodpi目录,操作系统在加载时就不会缩放它们。

Im also new to Android OpenGL ES dev. 我也是Android OpenGL ES dev的新手。 I own a Milestone (euro version for Droid). 我拥有里程碑(Droid的欧元版)。

From what i can see so far, firing several tutorial apps from different books/websites on my milestone, it seems this phone handle OpenGL ES in a different way than all other android phones released so far. 从目前为止我所看到的,在我的里程碑上从不同的书籍/网站发布几个教程应用程序,似乎这款手机处理OpenGL ES的方式与迄今为止发布的所有其他Android手机不同。

I think its related to the OpenGL extensions supported on the device. 我认为它与设备支持的OpenGL扩展有关。

check this link for the list of the supported extensions, im pretty sure a code guru will find why exactly the droid is handling opengl es in such a weird way. 检查此链接以获取支持的扩展名列表,我非常确定代码大师会发现为什么droid正以这种奇怪的方式处理opengl。

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

Hope this helps.. a bit 希望这个对你有帮助


EDITED : 编辑:

I tweaked the manifest.xml and noticed when using 我调整了manifest.xml并在使用时注意到了

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

the resources aren't loading at all. 资源根本没有加载。

When using 使用时

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

resources are loading fine. 资源正在加载。

So i switched back to 所以我换回了

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

and changed the way the bitmap is loaded. 并改变了加载位图的方式。

Try to replace : 尝试替换:

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

with : 用:

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) {
        }
    }

Textures are loading fine on my milestone with that code, hope this work for yours ! 使用该代码在我的里程碑上加载纹理,希望这项工作适合您的!

Make sure you load your bitmaps with a appropriate BitmapConfig that is not scaling your image behind the scenes, because this happens. 确保使用适当的BitmapConfig加载位图,而不是在幕后缩放图像,因为这种情况会发生。

Also, is there a reason you are storing your pngs in /raw/ instead of /drawable/? 另外,你有没有理由将你的png存储在/ raw /而不是/ drawable /?

Dullahx's edited answer solved my problem on the same issue. Dullahx编辑的答案解决了我在同一问题上的问题。 thanks a lot, it was bugging me the last two days! 非常感谢,这最近两天让我烦恼!

I was trying to map a texture on samsung galaxy tab, which was displayed successfully on the emulator but only the plane was displayed on the device. 我试图在三星galaxy选项卡上映射纹理,该选项卡已在模拟器上成功显示,但只有平面显示在设备上。

I replaced my code: 我替换了我的代码:

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

with this one: 这一个:

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

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

and it worked on the device too! 它也在设备上工作!

But be careful about the minSdkVersion if you are also trying to map a texture on a fullscreen size rectangle like me. 但是如果你还试图在像我这样的全屏尺寸矩形上映射纹理,请注意minSdkVersion。 If I use 如果我使用

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

on samsung galaxy tab, my plane was not rendered fullscreen. 在三星星系标签上,我的飞机没有全屏显示。 It was rendered according to the fullscreen size of a device using sdk version 3. I changed this to 它是根据使用sdk版本3的设备的全屏大小呈现的。我将其更改为

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

and my fullscreen rectangle is back with its texture on. 我的全屏矩形背面有纹理。

Hope this helps, too. 希望这也有帮助。

I am unsure of what your problem is, I'm pretty new to development in general, but my OpenGL android problems with difference between the emulator and the phone were: 我不确定你的问题是什么,我对一般的开发都很陌生,但我的OpenGL android问题与模拟器和手机之间的区别是:

-Emulator can support non 2^x dimensions for bitmaps, phone cannot -Emulator flipped screen in NDK for openGL so I had to use negative coordinates to define the view in the emulator, while my G1 used the coordinates non-negated. -Emulator可以支持非2 ^ x维度的位图,手机不能-Emulator翻转屏幕在NDK中用于openGL所以我不得不使用负坐标来定义模拟器中的视图,而我的G1使用的坐标是非否定的。

Hopefully this is able to help you in someway. 希望这能够在某种程度上帮助你。

I think that it maybe that you are having trouble loading the texture from the APK. 我认为你可能无法从APK加载纹理。 Try copying the texture to the SDCard and see if you can load it from there. 尝试将纹理复制到SD卡,看看是否可以从那里加载它。

are you using the GL11 interface somewhere? 你在某处使用GL11接口吗? GL11 is not supported by all devices. 并非所有设备都支持GL11。 and also remove the glColor line, perhaps your texture is displayed but over-painted by the color? 并删除glColor线,也许您的纹理显示但是被颜色覆盖? here some code snippet how i display my texture-meshes: 这里有一些代码片段,我如何显示我的纹理网格:

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.

相关问题 Android模拟器互联网连接问题-真实设备正常工作。 - Android emulator internet connection issues - real device works. Admob Adview的作品。 为什么? - Admob Adview works. Why? 连接到本地 SQL Server 数据库可在模拟器上运行,但在真实设备上失败 - Connection to local SQL Server database works on emulator but fails on real device 在Android 3.1的WebView中加载URL在设备上失败,但在模拟器上有效 - Loading URL in WebView for Android 3.1 fails on device but works on emulator React Native构建在模拟器上失败,但在设备上可以正常工作 - React Native build fails on emulator but works fine on device ProGuard-应用程序可在模拟器中正常运行,但在尝试构建APK时失败 - ProGuard - Application works fine in emulator, but fails when trying to build apk HttpURLConnection在模拟器上有效,但在设备上无效 - HttpURLConnection works on emulator but not on the device Gif可在模拟器上运行,但不能在设备上运行 - Gif Works on emulator but not on device 应用程序适用于模拟器但不适用于设备? - App works on emulator but not on device? 按钮在模拟器上有效,但在设备上无效 - Button works on emulator but not on device
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM