android opengl位图图像未使用texImage2D渲染
Posted
技术标签:
【中文标题】android opengl位图图像未使用texImage2D渲染【英文标题】:android opengl bitmap image not rendered with texImage2D 【发布时间】:2017-10-03 02:36:37 【问题描述】:我想创建一个挥动的旗帜作为动态壁纸,问题是它不绘制图像(没有错误!)但它成功绘制了其他纹理。 我考虑了其他类似的问题和解决方案,但没有成功。
这是实现 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 我添加了,它不透明,它有白色背景,我用不同的图片测试,它们都有相同的结果 你尝试过 256x256px 大小的 2 种纹理的力量 @codetiger 尝试但没有成功 唯一的机会是 TextureCoords 和你的渲染方式 【参考方案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
【讨论】:
以上是关于android opengl位图图像未使用texImage2D渲染的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 glfw 窗口上没有使用 opengl 显示位图图像?在 C++ 中读取位图图像文件时出现问题
Android 进阶——性能优化之Bitmap位图内存管理及优化
Android 进阶——性能优化之Bitmap位图内存管理及优化