我正在从android中的openGl es库中绘制网格物体。当我加载光obj文件然后成功加载。我的意思是它的顶点值小于32767.当我加载顶点值超出此值的重的obj文件时,它的失败。
但是当我将它转换为Long时,它会停止绘制网格。我无法识别出错误在哪里。
我该如何解决这个问题?
public class MyRenderer extends GLSurfaceView implements Renderer {
/** Triangle instance */
private OBJParser parser;
private TDModel model;
/* Rotation values */
private float xrot; //X Rotation
private float yrot; //Y Rotation
/* Rotation speed values */
private float xspeed; //X Rotation Speed ( NEW )
private float yspeed; //Y Rotation Speed ( NEW )
private float z = 50.0f;
private float oldX;
private float oldY;
private final float TOUCH_SCALE = 0.4f; //Proved to be good for normal rotation ( NEW )
private float[] lightAmbient = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightPosition = {0.0f, -3.0f, 2.0f, 1.0f};
private FloatBuffer lightAmbientBuffer;
private FloatBuffer lightDiffuseBuffer;
private FloatBuffer lightPositionBuffer;
public MyRenderer(Context ctx) {
super(ctx);
parser=new OBJParser(ctx);
model=parser.parseOBJ("/sdcard/door.obj");
this.setRenderer(this);
this.requestFocus();
this.setFocusableInTouchMode(true);
ByteBuffer byteBuf = ByteBuffer.allocateDirect(lightAmbient.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
lightAmbientBuffer = byteBuf.asFloatBuffer();
lightAmbientBuffer.put(lightAmbient);
lightAmbientBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(lightDiffuse.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
lightDiffuseBuffer = byteBuf.asFloatBuffer();
lightDiffuseBuffer.put(lightDiffuse);
lightDiffuseBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(lightPosition.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
lightPositionBuffer = byteBuf.asFloatBuffer();
lightPositionBuffer.put(lightPosition);
lightPositionBuffer.position(0);
}
/**
* The Surface is created/init()
*/
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbientBuffer);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuseBuffer);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);
gl.glEnable(GL10.GL_LIGHT0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
/**
* Here we do our drawing
*/
public void onDrawFrame(GL10 gl) {
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glEnable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, -1.2f, -z); //Move down 1.2 Unit And Into The Screen 6.0
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); //X
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); //Y
model.draw(gl); //Draw the square
gl.glLoadIdentity();
xrot += xspeed;
yrot += yspeed;
}
/**
* If the surface changes, reset the view
*/
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, 0.1f, 0.1f, 500.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//
float x = event.getX();
float y = event.getY();
//If a touch is moved on the screen
if(event.getAction() == MotionEvent.ACTION_MOVE) {
//Calculate the change
float dx = x - oldX;
float dy = y - oldY;
//Define an upper area of 10% on the screen
int upperArea = this.getHeight() / 10;
//Zoom in/out if the touch move has been made in the upper
if(y < upperArea) {
z -= dx * TOUCH_SCALE / 2;
//Rotate around the axis otherwise
} else {
xrot += dy * TOUCH_SCALE;
yrot += dx * TOUCH_SCALE;
}
//A press on the screen
} else if(event.getAction() == MotionEvent.ACTION_UP) {
}
//Remember the values
oldX = x;
oldY = y;
//We handled the event
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
//
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
} else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
} else if(keyCode == KeyEvent.KEYCODE_DPAD_UP) {
z -= 3;
} else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
z += 3;
} else if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
}
//We handled the event
return true;
}
}
public class TDModel {
Vector<Float> v;
Vector<Float> vn;
Vector<Float> vt;
Vector<TDModelPart> parts;
FloatBuffer vertexBuffer;
public TDModel(Vector<Float> v, Vector<Float> vn, Vector<Float> vt, Vector<TDModelPart> parts) {
super();
this.v = v;
this.vn = vn;
this.vt = vt;
this.parts = parts;
}
public String toString(){
String str=new String();
str+="Number of parts: "+parts.size();
str+="\nNumber of vertexes: "+v.size();
str+="\nNumber of vns: "+vn.size();
str+="\nNumber of vts: "+vt.size();
str+="\n/////////////////////////\n";
for(int i=0; i<parts.size(); i++){
str+="Part "+i+'\n';
str+=parts.get(i).toString();
str+="\n/////////////////////////";
}
return str;
}
public void draw(GL10 gl) {
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
for(int i=0; i<parts.size(); i++){
TDModelPart t=parts.get(i);
gl.glNormalPointer(GL10.GL_FLOAT, 0, t.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES,t.getFacesCount(),GL10.GL_UNSIGNED_SHORT,t.getFaceBuffer());
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
public void buildVertexBuffer(){
ByteBuffer vBuf = ByteBuffer.allocateDirect(v.size() * 4);
vBuf.order(ByteOrder.nativeOrder());
vertexBuffer = vBuf.asFloatBuffer();
vertexBuffer.put(toPrimitiveArrayF(v));
vertexBuffer.position(0);
}
private static float[] toPrimitiveArrayF(Vector<Float> vector){
float[] f;
f=new float[vector.size()];
for (int i=0; i<vector.size(); i++){
f[i]=vector.get(i);
}
return f;
}
}
public class OBJParser {
int numVertices=0;
int numFaces=0;
Context context;
Vector<Short> faces=new Vector<Short>();
Vector<Short> vtPointer=new Vector<Short>();
Vector<Short> vnPointer=new Vector<Short>();
Vector<Float> v=new Vector<Float>();
Vector<Float> vn=new Vector<Float>();
Vector<Float> vt=new Vector<Float>();
Vector<TDModelPart> parts=new Vector<TDModelPart>();
Vector<Material> materials=null;
public OBJParser(Context ctx){
context=ctx;
}
public TDModel parseOBJ(String fileName) {
BufferedReader reader=null;
String line = null;
Material m=null;
try { //try to open file
reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
} catch(IOException e){
}
try {//try to read lines of the file
while((line = reader.readLine()) != null) {
Log.v("obj",line);
if(line.startsWith("f")){//a polygonal face
processFLine(line);
}
else
if(line.startsWith("vn")){
processVNLine(line);
}
else
if(line.startsWith("vt")){
processVTLine(line);
}
else
if(line.startsWith("v")){ //line having geometric position of single vertex
processVLine(line);
}
/*else
if(line.startsWith("usemtl")){
try{//start of new group
if(faces.size()!=0){//if not this is not the start of the first group
TDModelPart model=new TDModelPart(faces, vtPointer, vnPointer, m,vn);
parts.add(model);
}
String mtlName=line.split("[ ]+",2)[1]; //get the name of the material
for(int i=0; i<materials.size(); i++){//suppose .mtl file already parsed
m=materials.get(i);
if(m.getName().equals(mtlName)){//if found, return from loop
break;
}
m=null;//if material not found, set to null
}
faces=new Vector<Short>();
vtPointer=new Vector<Short>();
vnPointer=new Vector<Short>();
}
catch (Exception e) {
// TODO: handle exception
}
}
else
if(line.startsWith("mtllib")){
materials=MTLParser.loadMTL(line.split("[ ]+")[1]);
for(int i=0; i<materials.size(); i++){
Material mat=materials.get(i);
Log.v("materials",mat.toString());
}
}*/
}
}
catch(IOException e){
System.out.println("wtf...");
}
if(faces!= null){//if not this is not the start of the first group
TDModelPart model=new TDModelPart(faces, vtPointer, vnPointer, m,vn);
parts.add(model);
}
TDModel t=new TDModel(v,vn,vt,parts);
t.buildVertexBuffer();
Log.v("models",t.toString());
return t;
}
private void processVLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
v.add(Float.valueOf(tokens[i]));
}
}
private void processVNLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
vn.add(Float.valueOf(tokens[i]));
}
}
private void processVTLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
vt.add(Float.valueOf(tokens[i]));
}
}
private void processFLine(String line){
String [] tokens=line.split("[ ]+");
int c=tokens.length;
if(tokens[1].matches("[0-9]+")){//f: v
if(c==4){//3 faces
for(int i=1; i<c; i++){
Short s=Short.valueOf(tokens[i]);
s--;
faces.add(s);
}
}
else{//more faces
Vector<Short> polygon=new Vector<Short>();
for(int i=1; i<tokens.length; i++){
Short s=Short.valueOf(tokens[i]);
s--;
polygon.add(s);
}
faces.addAll(Triangulator.triangulate(polygon));//triangulate the polygon and add the resulting faces
}
}
if(tokens[1].matches("[0-9]+/[0-9]+")){//if: v/vt
if(c==4){//3 faces
for(int i=1; i<c; i++){
Short s=Short.valueOf(tokens[i].split("/")[0]);
s--;
faces.add(s);
s=Short.valueOf(tokens[i].split("/")[1]);
s--;
vtPointer.add(s);
}
}
else{//triangulate
Vector<Short> tmpFaces=new Vector<Short>();
Vector<Short> tmpVt=new Vector<Short>();
for(int i=1; i<tokens.length; i++){
Short s=Short.valueOf(tokens[i].split("/")[0]);
s--;
tmpFaces.add(s);
s=Short.valueOf(tokens[i].split("/")[1]);
s--;
tmpVt.add(s);
}
faces.addAll(Triangulator.triangulate(tmpFaces));
vtPointer.addAll(Triangulator.triangulate(tmpVt));
}
}
if(tokens[1].matches("[0-9]+//[0-9]+")){//f: v//vn
if(c==4){//3 faces
for(int i=1; i<c; i++){
Short s=Short.valueOf(tokens[i].split("//")[0]);
s--;
faces.add(s);
s=Short.valueOf(tokens[i].split("//")[1]);
s--;
vnPointer.add(s);
}
}
else{//triangulate
Vector<Short> tmpFaces=new Vector<Short>();
Vector<Short> tmpVn=new Vector<Short>();
for(int i=1; i<tokens.length; i++){
Short s=Short.valueOf(tokens[i].split("//")[0]);
s--;
tmpFaces.add(s);
s=Short.valueOf(tokens[i].split("//")[1]);
s--;
tmpVn.add(s);
}
faces.addAll(Triangulator.triangulate(tmpFaces));
vnPointer.addAll(Triangulator.triangulate(tmpVn));
}
}
if(tokens[1].matches("[0-9]+/[0-9]+/[0-9]+")){//f: v/vt/vn
if(c==4){//3 faces
for(int i=1; i<c; i++){
Short s=Short.valueOf(tokens[i].split("/")[0]);
s--;
faces.add(s);
s=Short.valueOf(tokens[i].split("/")[1]);
s--;
vtPointer.add(s);
s=Short.valueOf(tokens[i].split("/")[2]);
s--;
vnPointer.add(s);
}
}
else{//triangulate
Vector<Short> tmpFaces=new Vector<Short>();
Vector<Short> tmpVn=new Vector<Short>();
//Vector<Short> tmpVt=new Vector<Short>();
for(int i=1; i<tokens.length; i++){
Short s=Short.valueOf(tokens[i].split("/")[0]);
s--;
tmpFaces.add(s);
//s=Short.valueOf(tokens[i].split("/")[1]);
//s--;
//tmpVt.add(s);
//s=Short.valueOf(tokens[i].split("/")[2]);
//s--;
//tmpVn.add(s);
}
faces.addAll(Triangulator.triangulate(tmpFaces));
vtPointer.addAll(Triangulator.triangulate(tmpVn));
vnPointer.addAll(Triangulator.triangulate(tmpVn));
}
}
}
}
07-12 18:23:45.519: E/AndroidRuntime(6037): FATAL EXCEPTION: main
07-12 18:23:45.519: E/AndroidRuntime(6037): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.opengldemo/com.example.opengldemo.MainActivity}: java.lang.NumberFormatException: Value out of range for short: "32776"
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1970)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread.access$600(ActivityThread.java:128)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.os.Handler.dispatchMessage(Handler.java:99)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.os.Looper.loop(Looper.java:137)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread.main(ActivityThread.java:4514)
07-12 18:23:45.519: E/AndroidRuntime(6037): at java.lang.reflect.Method.invokeNative(Native Method)
07-12 18:23:45.519: E/AndroidRuntime(6037): at java.lang.reflect.Method.invoke(Method.java:511)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
07-12 18:23:45.519: E/AndroidRuntime(6037): at dalvik.system.NativeStart.main(Native Method)
07-12 18:23:45.519: E/AndroidRuntime(6037): Caused by: java.lang.NumberFormatException: Value out of range for short: "32776"
07-12 18:23:45.519: E/AndroidRuntime(6037): at java.lang.Short.parseShort(Short.java:218)
07-12 18:23:45.519: E/AndroidRuntime(6037): at java.lang.Short.parseShort(Short.java:194)
07-12 18:23:45.519: E/AndroidRuntime(6037): at java.lang.Short.valueOf(Short.java:260)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.example.opengldemo.OBJParser.processFLine(OBJParser.java:152)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.example.opengldemo.OBJParser.parseOBJ(OBJParser.java:45)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.example.opengldemo.MyRenderer.<init>(MyRenderer.java:50)
07-12 18:23:45.519: E/AndroidRuntime(6037): at com.example.opengldemo.MainActivity.onCreate(MainActivity.java:11)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.Activity.performCreate(Activity.java:4465)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
07-12 18:23:45.519: E/AndroidRuntime(6037): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
07-12 18:23:45.519: E/AndroidRuntime(6037): ... 11 more
答案 0 :(得分:0)
在processFLine方法中,使用Short来存储顶点,法线和其他属性。 但是short只能存储32767作为最大值。因此,如果您使用包含超过32768个顶点或普通或文本条的模型,则会出现此类错误。将其更改为整数。
以下是我加载网格的方法:
public class Mesh {
private Context context;
private final int mBytesPerFloat = 4;
public int vertexCount;
FloatBuffer mPositions;
FloatBuffer mNormals;
FloatBuffer mTextureCoordinates;
private float[] mModelMatrix = new float[16];
int mTextureDataHandle;
/**
*
* @param context
* @param path
*/
public Mesh(Context context, String path, float scale) {
this.context = context;
InputStream is = null;
BufferedReader br = null;
int vCount = 0; // vertices count
int vnCount = 0; // normals count
int vtCount = 0; // texture coordinates count
int fCount = 0; // faces count
try {
is = context.getAssets().open(path);
br = new BufferedReader(new InputStreamReader(is));
String l;
/**
* First pass: collect information
*/
Log.d("ALEKSO", "Collecting model info..");
while ((l = br.readLine()) != null) {
l.trim();
if (l.startsWith("v "))
vCount++;
if (l.startsWith("vn "))
vnCount++;
if (l.startsWith("vt "))
vtCount++;
if (l.startsWith("f "))
fCount++;
}
Log.d("ALEKSO", "vertices: " + vCount);
Log.d("ALEKSO", "vertex normals: " + vnCount);
Log.d("ALEKSO", "texture coords: " + vtCount);
Log.d("ALEKSO", "faces: " + fCount);
br.close();
is.close();
/**
* Second pass: retrieve data
*/
// initialize arrays for data
float vertices[] = new float[vCount * 3];
float normals[] = new float[vnCount * 3];
float texcoords[] = new float[vtCount * 2];
int facesVertices[] = new int[fCount * 3];
int facesNormals[] = new int[fCount * 3];
int facesTexCoords[] = new int[fCount * 3];
int vertexIdx = 0;
int normalIdx = 0;
int texcoordIdx = 0;
int faceIdx = 0;
// read file again
is = context.getAssets().open(path);
br = new BufferedReader(new InputStreamReader(is));
while ((l = br.readLine()) != null) {
l.trim();
if (l.startsWith("v ")) {
String arr[] = l.substring(2).split(" ");
vertices[vertexIdx++] = Float.parseFloat(arr[0]);
vertices[vertexIdx++] = Float.parseFloat(arr[1]);
vertices[vertexIdx++] = Float.parseFloat(arr[2]);
continue;
}
if (l.startsWith("vn ")) {
String arr[] = l.substring(3).split(" ");
normals[normalIdx++] = Float.parseFloat(arr[0]);
normals[normalIdx++] = Float.parseFloat(arr[1]);
normals[normalIdx++] = Float.parseFloat(arr[2]);
continue;
}
if (l.startsWith("vt ")) {
String arr[] = l.substring(3).split(" ");
texcoords[texcoordIdx++] = Float.parseFloat(arr[0]);
texcoords[texcoordIdx++] = Float.parseFloat(arr[1]);
continue;
}
if (l.startsWith("f ")) {
String arr[] = l.substring(2).trim().split(" ");
String parts[] = arr[0].split("/");
facesVertices[faceIdx] = Integer.parseInt(parts[0]) - 1;
facesTexCoords[faceIdx] = Integer.parseInt(parts[1]) - 1;
facesNormals[faceIdx] = Integer.parseInt(parts[2]) - 1;
faceIdx++;
parts = arr[1].split("/");
facesVertices[faceIdx] = Integer.parseInt(parts[0]) - 1;
facesTexCoords[faceIdx] = Integer.parseInt(parts[1]) - 1;
facesNormals[faceIdx] = Integer.parseInt(parts[2]) - 1;
faceIdx++;
parts = arr[2].split("/");
facesVertices[faceIdx] = Integer.parseInt(parts[0]) - 1;
facesTexCoords[faceIdx] = Integer.parseInt(parts[1]) - 1;
facesNormals[faceIdx] = Integer.parseInt(parts[2]) - 1;
faceIdx++;
continue;
}
}
float meshVertices[] = new float[facesVertices.length * 3];
float meshNormals[] = new float[facesNormals.length * 3];
float meshTexCoords[] = new float[facesTexCoords.length * 2];
int nid = 0, tid = 0, vid = 0;
for (int i = 0; i < fCount * 3; i++) {
if (vnCount > 0) {
int nIdx = facesNormals[i] * 3;
meshNormals[nid++] = normals[nIdx] * scale;
meshNormals[nid++] = normals[nIdx + 1] * scale;
meshNormals[nid++] = normals[nIdx + 2] * scale;
}
if (vtCount > 0) {
int uvIdx = facesTexCoords[i] * 2;
meshTexCoords[tid++] = texcoords[uvIdx];
meshTexCoords[tid++] = texcoords[uvIdx + 1];
}
int vIdx = facesVertices[i] * 3;
meshVertices[vid++] = vertices[vIdx] * scale;
meshVertices[vid++] = vertices[vIdx + 1] * scale;
meshVertices[vid++] = vertices[vIdx + 2] * scale;
}
vertexCount = fCount * 3;
// Initialize the buffers.
mPositions = ByteBuffer.allocateDirect(meshVertices.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
mPositions.put(meshVertices).position(0);
mNormals = ByteBuffer.allocateDirect(meshNormals.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
mNormals.put(meshNormals).position(0);
mTextureCoordinates = ByteBuffer.allocateDirect(meshTexCoords.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
mTextureCoordinates.put(meshTexCoords).position(0);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (is != null)
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* @param textureRes
*/
public void loadTexture(final int textureRes) {
mTextureDataHandle = Utils.loadTexture(this.context, textureRes);
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
}
}