我对OpenGL知之甚少,所以请保持温和。
应用程序需要加载位图(来自资源),调整其大小,并在OpenGL纹理中使用它。我有一个可行的实现,但是在Wildfire S上有一个不好的绑定问题。所以我改变了实现并修复了绑定问题(通过切换到ARGB_8888),但这打破了Galaxy Nexus和Nexus One的功能。
我看到三个视觉呈现:
位图(平滑的24位渐变)正确显示,没有条带。
渐变显示,但带有明显的条带
纹理显示为白色,没有位图(或logcat中的问题)
以下是加载位图的方法的两个版本,并注明了每个版本的结果:
// White on Galaxy Nexus. White on Nexus One. Renders correct image (no banding) on Wildfire S
private Bitmap getBitmap1() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.outWidth = getTextureSize();
options.outHeight = getTextureSize();
final Bitmap bmp;
bmp = BitmapFactory.decodeResource(getResources(), bitmapResourceId, options);
return bmp;
}
// Renders correctly (no banding) on Galaxy Nexus. Renders on Nexus One and Wildfire S but with obvious banding.
private Bitmap getBitmap2() {
int textureSize = getTextureSize();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.outWidth = getTextureSize();
options.outHeight = getTextureSize();
final Bitmap bmp;
bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), bitmapResourceId, options), textureSize, textureSize, true);
return bmp;
}
getTextureSize()返回1024。
如何构建一个方法,在所有设备上显示位图而不显示条带,并且没有任何设备显示大白框?
答案 0 :(得分:1)
OpenGL.org有关于该错误的说法:
GL_INVALID_VALUE
,0x0501:当值参数不是leval时给定 该函数的值。这仅针对当地问题;如果 spec允许在某些情况下的值和其他参数 或州指示那些情况,然后GL_INVALID_OPERATION是 结果反而。
第一步是找到导致问题的确切opengl调用。您将不得不进行试验和错误,以查看哪一行引发了该错误。如果您设置程序流程如下:
glSomeCallA()
glGetError() //returns 0
glSomeCallB()
glGetError() //returns 0
glSomeCallC()
glGetError() //returns 0x501
然后你会知道glSomeCallC
是导致错误的操作。如果查看该特定调用的手册页,它将枚举可能导致特定错误发生的所有内容。
在你的情况下我会猜测错误将在glTexImage调用之后为了节省你一些时间,尽管我不是正面的。
如果查看glTexImage man page,它会在列表底部列出可能导致无效值错误的所有内容。我的猜测是你的纹理大于GL_MAX_TEXTURE_SIZE。您可以通过选中glGetIntegerv(GL_MAX_TEXTURE_SIZE);
答案 1 :(得分:1)
<强> getBitmap1 强>
outHeight和outWidth与inJustDecodeBounds一起使用。您不能使用它们来加载缩放的位图。因此,您看到白色纹理的原因是位图不是2的幂。
<强> getBitmap2 强>
你应该保留对decodeResource返回的位图的引用,以便以后可以回收它。
还可以使用options.inScaled = false;
加载位图的未缩放版本。另请注意,如果原始位图不包含alpha通道(Source),createScaledBitmap可能会将位图的深度更改为RGB_565;
问题: 是原始的位图资源方块?如果不是,您的缩放代码将改变可能导致伪像的宽高比。
编辑: 那么如何缩放位图并保留位深? 最简单的解决方案是将带有alpha通道的位图传递到createScaledBitmap。 您也可以像这样扩展自己:
Bitmap newBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
final int width = src.getWidth();
final int height = src.getHeight();
final float sx = 1024 / (float)width;
final float sy = 1024 / (float)height;
Matrix m = new Matrix();
m.setScale(sx, sy);
canvas.drawBitmap(src,m,null );
src.recycle();
另一个编辑: 看看这个Question有关如何处理它的指示。
答案 2 :(得分:1)
色带解决了ooooooooooyyyyyyyeaaaaaaaaaa
我分两个阶段解决了色带问题
1)*当我们使用BitmapFactory解码资源时,它解码RGB565中的资源,显示颜色条带,而不是使用ARGB_8888,所以我使用BitmapFactory.Options将解码选项设置为ARGB_8888
第二个问题是每当我缩放位图时它再次被绑定
2)这是一个艰难的部分,并进行了大量的搜索,最终工作 *用于缩放位图的Bitmap.createScaledBitmap方法在缩放后我还将图像缩小为RGB565格式我得到了带状图像(解决此问题的旧方法是在png中使用至少一个透明像素但没有其他格式如jpg或bmp工作)所以在这里,我创建了一个方法CreateScaledBitmap,用于在生成的比例位图中使用原始位图配置缩放位图(实际上我是通过logicnet.dk复制方法并在java中翻译)
BitmapFactory.Options myOptions = new BitmapFactory.Options();
myOptions.inDither = true;
myOptions.inScaled = false;
myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//important
//myOptions.inDither = false;
myOptions.inPurgeable = true;
Bitmap tempImage =
BitmapFactory.decodeResource(getResources(),R.drawable.defaultart, myOptions);//important
//this is important part new scale method created by someone else
tempImage = CreateScaledBitmap(tempImage,300,300,false);
ImageView v = (ImageView)findViewById(R.id.imageView1);
v.setImageBitmap(tempImage);
//函数
public static Bitmap CreateScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
{
Matrix m = new Matrix();
m.setScale(dstWidth / (float)src.getWidth(), dstHeight / (float)src.getHeight());
Bitmap result = Bitmap.createBitmap(dstWidth, dstHeight, src.getConfig());
Canvas canvas = new Canvas(result);
//using (var canvas = new Canvas(result))
{
Paint paint = new Paint();
paint.setFilterBitmap(filter);
canvas.drawBitmap(src, m, paint);
}
return result;
}
如果我错了,请纠正我。 还要评论它是否适合你。
我很高兴我解决了它,希望它适合你。