安卓OpenGL:使用texImage2D渲染位图图像失败

4
我希望创建一个波浪般的旗帜作为动态壁纸,但问题是它无法绘制图像(没有错误!),但可以成功绘制其他纹理。我考虑了其他类似的问题和解决方案,但都没有成功。
这是一个实现了GLSurfaceView.Renderer 的 StripesSurfaceView 代码:
    private final class StripesSurfaceView extends GLSurfaceView implements
            GLSurfaceView.Renderer {


        private Context context;

        private int textures[];

        private OpenGLFlag flag;

        private boolean paused = false;

        public StripesSurfaceView(Context context) {
            super(context);
            this.context = context;
            setRenderer(this);
            setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

        }

        @Override
        public final SurfaceHolder getHolder() {
            return WallpaperEngine.this.getSurfaceHolder();
        }

        public final void onDestroy() {
            super.onDetachedFromWindow();
        }

        @Override
        public final void onDrawFrame(GL10 gl) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

            gl.glPushMatrix();

            // rotate
            gl.glRotatef(Constants.FLAG_ROTATION_X, 1.0f, 0.0f, 0.0f);
            gl.glRotatef(Constants.FLAG_ROTATION_Y, 0.0f, 1.0f, 0.0f);
            gl.glRotatef(Constants.FLAG_ROTATION_Z, 0.0f, 0.0f, 1.0f);

            // draw
            flag.draw(gl, paused);

            gl.glPopMatrix();

        }

        @Override
        public final void onSurfaceChanged(GL10 gl, int width,
                int height) {
            float ratio = (float) width / height;

            // flag
            flag = new OpenGLFlag(textures[0], 0, 0, 0, ratio * 2, ratio);

            gl.glShadeModel(GL10.GL_SMOOTH);
            GLES20.glClearDepthf(1.0f);
            GLES20.glEnable(GLES20.GL_DEPTH_TEST);
            GLES20.glDepthFunc(GLES20.GL_LEQUAL);
            GLES20.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GLES20.GL_NICEST);
            GLES20.glEnable(GLES20.GL_BLEND);
            GLES20.glEnable(GL10.GL_POINT_SMOOTH);
            GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); // https://www.opengl.org/sdk/docs/man2/xhtml/glBlendFunc.xml

            GLES20.glViewport(0, 0, width, height);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // https://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml

            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glLoadIdentity();
            GLU.gluLookAt(gl, 0, 0, 3.5f, 0, 0, 0, 0, 1.0f, 0); // https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml

        }

        @Override
        public final void onSurfaceCreated(GL10 gl, EGLConfig config) 
{
            // bind texture
            textures = new int[1];
            GLES20.glEnable(GLES20.GL_TEXTURE_2D);
            GLES20.glGenTextures(textures.length, textures, 0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
            Log.d("gfd", context.getResources()+" :: "+ Constants.FLAG_TEXTURE);
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.s);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
            bitmap.recycle();



        }

    }

}

这里是调用 StripesSurfaceView 的位置:

    private final class WallpaperEngine extends Engine  {


    private StripesSurfaceView mGLSurfaceView;

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {

        super.onCreate(surfaceHolder);
        mGLSurfaceView = new StripesSurfaceView(getApplicationContext());

    }
  // ..... etc

这里是目前的结果:

在此输入图像描述

将纹理转换成波浪效果: 在此输入图像描述


请问您能否在这里发布您的纹理?另外,最容易出现问题的可能是非正方形纹理。 - codetiger
@codetiger 我添加了,它不是透明的,它有白色背景,我用不同的图片进行了测试,它们都有相同的结果。 - Arash
你尝试过使用2的幂次方纹理,例如256x256像素大小吗? - codetiger
@codetiger 尝试了但没有成功。 - Arash
唯一的机会就是 TextureCoords 和渲染方式。 - codetiger
也许你可以尝试注释掉 bitmap.recycle(); - J.Jacobs
1个回答

1
问题使用decodestream解决:
        private Bitmap getBitmapFromAssets(Context context, String fileName, int width, int height) {
            AssetManager asset = context.getAssets();
            InputStream is;
            try {
                is = asset.open(fileName);
            BitmapFactory.Options options = new BitmapFactory.Options();
            Bitmap bit=BitmapFactory.decodeStream(is, null, options);
            return bit;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

我在这里发布了源代码: https://github.com/ataafarin/android-live-wallpaper-wavingflag


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接