在调用android opengl ES进行纹理贴图的时候,发现有的机器上能显示图片,有的机器上不能显示。是因为图片的尺寸不是2的N次幂,部分显卡不支持非2的N次幂纹理贴图。
将图片放大到2的N次幂,比如100 * 200的图片就放大到128 * 256。
为了显示图片不拉伸,坐标顶点使用原图的宽高比例。
第一次发贴,求通过,求指教
private class MyRenderer implements GLSurfaceView.Renderer {
private Bitmap bitmap;
private float[] vertex;
private float[] texture;
private short[] index;
private FloatBuffer mVertexBuffer;
private FloatBuffer mTextureBuffer;
private ShortBuffer mIndexBuffer;
private int mTextureID;
public MyRenderer(Context context, int bitmapRes) {
initData(context, bitmapRes);
initBuffer();
private void initData(Context context, int bitmapRes) {
Bitmap resBitmap = BitmapFactory.decodeResource(context.getResources(), bitmapRes);
int width = resBitmap.getWidth();
int height = resBitmap.getHeight();
int widthPowerOfTwo = getPowerOfTwo(width);
int heightPowerOfTwo = getPowerOfTwo(height);
int newWidth = (int) Math.pow(2, widthPowerOfTwo + 1);
int newHeight = (int) Math.pow(2, heightPowerOfTwo + 1);
newWidth = newWidth == width * 2 ? width : newWidth;
newHeight = newHeight == height * 2 ? height : newHeight;
bitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
Rect rect = new Rect(0, 0, newWidth, newHeight);
canvas.drawBitmap(resBitmap, null, rect, new Paint());
resBitmap.recycle();
float heightToWidth = (float) height / width;
vertex = new float[]{
-1.0f, -heightToWidth, 0,
1f, -heightToWidth, 0,
-1f, heightToWidth, 0,
1f, heightToWidth, 0
texture = new float[]{
0f, 1.0f,
1.0f, 1.0f,
0f, 0f,
1.0f, 0f
index = new short[]{0, 1, 2, 3};
public int getPowerOfTwo(long number) {
if (number <= 0) {
return -1;
return getPowerOfTwo(number / 2) + 1;
private void initBuffer() {
ByteBuffer vbb = ByteBuffer.allocateDirect(vertex.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(texture.length * 4);
tbb.order(ByteOrder.nativeOrder());
mTextureBuffer = tbb.asFloatBuffer();
mTextureBuffer.put(texture);
mTextureBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(index.length * 2);
ibb.order(ByteOrder.nativeOrder());
mIndexBuffer = ibb.asShortBuffer();
mIndexBuffer.put(index);
mIndexBuffer.position(0);
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
glDisable(GL_DITHER);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glClearColor(.5f, .5f, .5f, 1);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
int[] textures = new int[1];
glGenTextures(1, textures, 0);
mTextureID = textures[0];
glBindTexture(GL_TEXTURE_2D, mTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = (float) width / height;
glFrustumf(-ratio, ratio, -1, 1, 3, 70);
@Override
public void onDrawFrame(GL10 gl) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 8, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
glFrontFace(GL_CCW);
glVertexPointer(3, GL_FLOAT, 0, mVertexBuffer);
glEnable(GL_TEXTURE_2D);
glTexCoordPointer(2, GL_FLOAT, 0, mTextureBuffer);
glDrawElements(GL_TRIANGLE_STRIP, index.length, GL_UNSIGNED_SHORT, mIndexBuffer);
在调用android opengl ES进行纹理贴图的时候,发现有的机器上能显示图片,有的机器上不能显示。是因为图片的尺寸不是2的N次幂,部分显卡不支持非2的N次幂纹理贴图。将图片放大到2的N次幂,比如100 * 200的图片就放大到128 * 256。为了显示图片不拉伸,坐标顶点使用原图的宽高比例。 private class MyRenderer implements GLSurfa
从OpenGL ES官方API中,我们可以知道从OpenGL ES2.0开始,加载纹理时,对图片的宽高已不再要求未2的N次方比例。这一点在许多情况下还是非常有用的,例如:来自视频或摄像头的数据可能不为2的N次方。
但从实际设备测试可知,对于OpenGL ES2.0的终端设备,不同厂商的设备表现可能不同,因此,对于加载的纹理,若可以使用2的N次方纹理,还是要尽量保持2的N次方。
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_
首先要知道为什么untiy中的图片需要是2的N次方
第一:底层图形学只识别2的N次方的图片,OpenGL仅支持分辨率为2mx2n的纹理,非2的N次方的图片会转化为2的N次方的图片,这个转化的过程十分耗时
第二:ios pvrtc的原因,有些GUP不支持NPOT,遇到NPOT会有一个转换POT的过程,浪费性能
第一:把不规则的图打成图集
第二:如果是一些NGUI的texture UGUI的RawImage就尽量的按照最接近的尺寸来做比如123*58那么让美术提供 128*64的图,可...
1、图片的纹理像素在Unity3D中需要遵循2的N次方,由图形学决定的,只识别2的N次方。
非2的N次方的图片会转化为2的N次方图片(500 x 500 → 512 x 512),是因为转化过程比较慢,由运行程序转换十分耗时,所以Unity3D提前将资源转化为符合标准的图片。
2、ios pvrtc的原因,有些GUP不支持NPOT,遇到NPOT会有一个转换POT的过程,浪费性能,
因此...
ggplot2是一种用于数据可视化的R语言包,可以用于绘制各种类型的图表,包括柱状图。在ggplot2中,可以使用纹理填充来增强柱状图的可视化效果。
纹理填充是将不同的纹理应用到不同的数据组或分组的柱子上,以区分它们之间的差异。ggplot2提供了一些内置的纹理,如点、线和斜线等。此外,用户还可以通过自定义纹理来进一步增强图表的可视化效果。
使用ggplot2绘制纹理填充的柱状图需要使用到geom_bar()函数,并将纹理填充参数指定为fill。例如,可以通过以下代码生成一个使用纹理填充的柱状图:
library(ggplot2)
# 创建数据框
df <- data.frame(
group = c("A", "B", "C", "D"),
value = c(10, 20, 30, 40)
# 创建柱状图,并设置纹理填充参数
ggplot(df, aes(x = group, y = value, fill = group)) +
geom_bar(stat = "identity", fill = NA) +
geom_bar(stat = "identity", aes(fill = group), position = "dodge", pattern = "stripe") +
labs(title = "纹理填充的柱状图", x = "组别", y = "数值")
在上述代码中,使用了fill参数来指定每个数据组对应的颜色,同时使用了pattern参数来指定纹理填充方式为条纹。通过使用position参数来设置柱子的位置,可以将同一组别的柱子进行分组显示。
综上所述,ggplot2提供了丰富的功能和灵活性,可以轻松制作具有纹理填充的柱状图,为数据分析和展示带来更好的效果。