【问题标题】:gl texture error on some phones某些手机​​上的 gl 纹理错误
【发布时间】:2011-12-06 23:02:25
【问题描述】:

我在几部手机上发现我的 glSurfaceView 中的一些纹理在谷歌搜索后没有加载(只显示白色),我设置 setDebugFlags(DEBUG_CHECK_ERROR) 以获取下面列出的以下错误日志。 MenuButton.java 中的第 40 行是:

gl.glGenTextures(1, textures, 0);

textures 是我的纹理指针,声明为:

private int[] textures = new int[1];

我很难过,因为我只在 Droid Pro 和其他几部手机上看到过这个问题,而且我不确定 gl.glGenTextures 的值是如何无效的。任何想法都会很有用。

编辑:菜单按钮的代码贴在下面。

12-06 17:46:31.720: E/AndroidRuntime(2984): android.opengl.GLException: invalid value
12-06 17:46:31.720: E/AndroidRuntime(2984): at android.opengl.GLErrorWrapper.glGenTextures(GLErrorWrapper.java:350)
12-06 17:46:31.720: E/AndroidRuntime(2984): at com.huskybuspurchased.MenuButton.<init>(MenuButton.java:40)
12-06 17:46:31.720: E/AndroidRuntime(2984): at com.huskybuspurchased.CampusMap.onSurfaceCreated(CampusMap.java:112)
12-06 17:46:31.720: E/AndroidRuntime(2984): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1348)
12-06 17:46:31.720: E/AndroidRuntime(2984): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)
12-06 17:46:31.728: I/hb(2984): rendering thread paused.

问题的图片:

package com.huskybus;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.graphics.Bitmap;
import android.opengl.GLUtils;
import android.util.Log;
import android.view.MotionEvent;

public class MenuButton {
//Our texture.
private float texture[] = {
        //Mapping coordinates for the vertices
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f, 
};
// The order we like to connect them.
private byte indices[] = {0,1,3,2};
// Our vertex buffer.
private FloatBuffer vertexBuffer;
// Our index buffer.
private ByteBuffer indexBuffer;
//texture buffer.
private FloatBuffer textureBuffer;
//Our texture pointer.
private int[] textures = new int[1];
private int width;
private int height;
private float rotation;
public MenuButton(Bitmap graphic,int _rotation,GL10 gl, int _width, int _height) {
    rotation=_rotation;
    width=_width;
    height=_height;

        //Generate one texture pointer...
        gl.glGenTextures(1, textures, 0);
        //...and bind it to our array
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
        //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, graphic, 0);
        graphic.recycle();

    float vertices[] = {
            0, -height, 0.0f, //LB
            width, -height, 0.0f,  //RB
            0, 0, 0.0f,  //LT
            width, 0, 0.0f,   //RT
        };

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuf.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    //
    byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuf.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);
    //
    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(indices);
    indexBuffer.position(0);        
}

/**
 * This function draws our square on screen.
 * @param gl
 */
public void draw(GL10 gl) {
    //Bind our only previously generated texture in this case
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    //Point to our buffers
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    //Set the face rotation
    gl.glFrontFace(GL10.GL_CCW);
    //Enable the vertex and texture state
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    gl.glRotatef(rotation, 0, 0, 1);
    //Draw the vertices as triangles, based on the Index Buffer information
    gl.glDrawElements(GL10.GL_TRIANGLE_FAN, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
    gl.glRotatef(360-rotation, 0, 0, 1);

    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    //Disable the texture buffer.
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    // Disable face culling.
    gl.glEnable(GL10.GL_CULL_FACE);
}
public boolean amIHit(float[] matrixValues,MotionEvent event) {
    if  (((event.getX())>(0)&&((event.getX()))<5+width)&&((event.getY())>0)&&(event.getY()<width))  {   
        Log.e("sys","hit menu button.");
        return true;
    }
    return false;       
}

}

【问题讨论】:

  • 我还刚刚在 motodev 网站上的 Droid Pro SDK 上测试了我的应用程序,它在摩托罗拉提供的模拟器中运行良好
  • 您的纹理尺寸是 2 的倍数(16、32、64、128 等)吗?或者可能是硬件问题?也许没有足够的视频内存用于纹理(尝试减小大小(但仍保持 2 的倍数)并查看结果是否不同)?
  • 顺便说一句; “如果 n 为负,则生成 GL_INVALID_VALUE。”根据opengl.org/sdk/docs/man/xhtml/glGenTextures.xml
  • 它们是 2 的幂,我怀疑它的视频内存不足,因为如果我禁用 GLWrapper,它会继续加载其他更大的纹理。它也可以在内存较少且 GPU 功能较弱的原始 droid 上完美运行
  • 我想你可以在glbenchmark.com 上查看它(和其他相关手机),看看你的项目中是否有某些东西不受支持...

标签: android opengl-es textures glsurfaceview


【解决方案1】:

glSurfaceView 选择一个要渲染的表面,不同的 android 设备支持不同的表面,不幸的是我们没有一个通用的子集被所有人支持。所以选择起来很棘手。
默认情况下,glSurfaceView 会尝试查找接近 16 位深度缓冲区的表面。
因此,您需要使用具有 16 位深度缓冲区或可能为 24 位的纹理来使用图像。更高位深度的图像可能会导致某些设备出现问题。!!

【讨论】:

【解决方案2】:

您不一定需要调用 glGenTextures。你可以给你的纹理任何你想要的数值——glGenTextures 只是为了方便获取尚未使用的纹理编号。

【讨论】:

  • 不幸的是,当我不加载纹理时,仍然无法加载
  • 很遗憾,我们需要更多信息才能继续。
猜你喜欢
  • 2012-02-22
  • 1970-01-01
  • 2014-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多