为什么在Eclipse中使用调试器运行时OpenGL纹理呈现正常,但在自己运行应用程序时呈现白色?

时间:2012-02-23 04:18:18

标签: android opengl-es textures

我有一个精灵类和另一个使用OpenGLSurvace视图扩展精灵类来渲染的类。它看起来像这样

public class Invader extends Sprite {

    static int mTextureId = -1;

    Invader(Context context, float x, float y, float angle)
    {
        super(context, x, y, angle);
        super.setSize(width, height);
//      super.setPos(x, y);
//      super.setAngle(angle);

        // Check to see if the texture is loaded already.  If it is a valid texture
        // id, don't bother loading it again
        if (mTextureId < 0)
        {
            super.loadBitmap(context.getResources(), R.drawable.piano_key_white);
        }
        else
        {
            super.setTexture(mTextureId);
        }
    }

    @Override
    protected int getTexture()
    {
        return mTextureId;
    }

    @Override
    protected void setTexture(int textureId)
    {
        mTextureId = textureId; 
    }

}

如您所见,它使用一个静态指针指向使用loadBitmap函数加载的纹理,该函数调用decodeResource函数来创建OpenGL纹理。当我通过Eclipse使用SDK插件从调试器运行应用程序时,一切看起来都很棒。当我在手机上正常运行应用程序时,除了这个将Invader渲染为白色方块(这是对象的颜色)的类外,一切都呈现得很好。

从我发现的情况来看,纹理可能没有正确加载,因此绘制了一个纯白色的正方形。我无法弄清楚为什么它在Debug中工作,而不是在正常执行期间。有任何想法吗?当程序没有通过远程调试运行时会有什么不同?

5 个答案:

答案 0 :(得分:1)

以下是您需要做的事情:

  1. 将纹理放在“res / drawable”文件夹
  2. 在加载过程中禁用纹理缩放,代码为:
  3. 纹理数组分配(duh;))

    // Texture and geometry data
    private int [] m_textureID = new int[1];
    

    并加载:

            // Load the texture from resource
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;
        Bitmap bitmap = BitmapFactory.decodeResource(m_resources, R.drawable.tex, options);
    
        gl.glGenTextures(1, m_textureID, 0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textureID[0]);
        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);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    
        // Free resources
        bitmap.recycle();
    
        // Do some error checking
        if(m_textureID[0] == 0)
            throw new RuntimeException("Error loading texture!");
    

答案 1 :(得分:1)

我明白了;我认为这是一个很好的教训。我的班级看起来很喜欢这样的

public class Sprite {
    private static int mTextureID = -1;
    private static boolean mShouldLoadTexture = true;
...
    onReder(GL10 gl) {
         if (mShouldLoadTexture) {
               mTextureID = loadTexture(gl, someBitmap);
               mShouldLoadTexture = false;
         }
    }
}

另一个静态类包含一个sprite列表

public static class SpriteList {
    private static Vector<Sprite> mSprites;
    ...
}

当我将它作为调试运行而不是仅仅从手机上的启动器运行它之间的区别是,包是所有静态类被重置,而手机上的启动器没有必须重置静态类。

所以,当我第一次将它作为 debug 运行时,类会看到它需要加载纹理,然后在GL10对象中分配纹理指针,并将其指定给 static mTextureID。此时,mTextureID包含有效的GL纹理指针。

现在,我会退出调试,断开与eclipse的连接,并在手机上运行启动器。因为Sprite类的容器尚未重置,所以mTextureID仍然有一些值指向不存在的GL纹理id。此外,mShouldLoadTexture将保持“false”,这意味着该类不会尝试从位图重新加载纹理。因此,onRender()会尝试使用指向无效纹理ID的指针并改为渲染白框。

我简化了场景,使其更容易理解。我知道静态容器在这个例子中没有多大意义,但认为它说明了我发现了什么。当我让包含类不再是 static 时,一切都按照它应该运行。

答案 2 :(得分:0)

确保纹理大小为2的幂。各种设备不会正确加载纹理,除非它们符合那些大小的构造。

IE

1×2 2×2 512x256 128×128 等

答案 3 :(得分:0)

我有同样的问题。对我来说,我的纹理会在我第一次在调试模式下启动应用程序时加载,但如果我从应用程序退出手机并再次打开它,我的所有纹理都会消失。除非我从IDE中再次启动应用程序,否则无法加载纹理。

对我来说,我采取了删除静态字段并完全修复它的建议(我有一个静态字段,它保持一个正方形的旋转角度,循环通过一组不同的纹理和一个保持数量的静态字段纹理列表中的当前纹理。)

我仍然不明白为什么有静态字段会导致这种情况。

对于记录YES我的纹理是2的幂的维度,我把它们放在drawable-nodpi文件夹中。

答案 4 :(得分:0)

我有类似的问题,问题是,连接到adb时运行发明了一些延迟。这种延迟导致我的应用程序仅在非常特定的条件下工作,并且在没有这些延迟的情况下根本不工 我希望这可以帮助别人。