java - Loading Texture in Android OpenglEs 2.0 result in no color at all -


i had working method before, saw there not optimized. trying upload textures rgb_565 or argb_4_4_4_4 color scheme, using 3 bytes first , 4 last one. in fact if use rgb_565 needing 2 bytes (5+6+5 bits), same second. did modifications it's not working, , sure forgot or did bad.

you can find old code commented out in function if wish compare. appreciated.

this code:

/// //  load texture inputstream // private int loadtexture(inputstream is) {     int[] textureid = new int[1];     bitmap reversedbitmap, bitmap;      bitmapfactory.options opts = new bitmapfactory.options();     opts.inpreferredconfig = bitmap.config.rgb_565;     reversedbitmap = bitmapfactory.decodestream(is, null, opts);     //reversedbitmap = bitmapfactory.decodestream(is);      if (reversedbitmap == null) {         throw new runtimeexception("texture.loadtexture: depuracion");     }      int width = reversedbitmap.getwidth();     int height = reversedbitmap.getheight();      matrix flip = new matrix();     flip.postscale(1f, -1f);     bitmap = bitmap.createbitmap(reversedbitmap, 0, 0, width, height, flip, true);      reversedbitmap.recycle();      // int bitmapformat = bitmap.getconfig() == bitmap.config.argb_8888 ? gles20.gl_rgba : gles20.gl_rgb;      int bitmapformat = bitmap.getconfig() == bitmap.config.argb_4444 ? gles20.gl_rgba4 : gles20.gl_rgb565;      byte[] buffer = null;     /*     if (bitmapformat == gles20.gl_rgb) {         buffer = new byte[width * height * 3];     } else if (bitmapformat == gles20.gl_rgba) {         buffer = new byte[width * height * 4];     }     */     if (bitmapformat == gles20.gl_rgb565) {         buffer = new byte[width * height * 2];     } else if (bitmapformat == gles20.gl_rgba4) {         buffer = new byte[width * height * 2];     }      int[] pixelarray;     pixelarray = new int[width * height];     bitmap.getpixels(pixelarray, 0, width, 0, 0, width, height);      (int y = 0; y < height; y++) {          (int x = 0; x < width; x++) { /*             int pixel = pixelarray[x + y * width];              if (bitmapformat == gles20.gl_rgb) {                 buffer[(y * width + x) * 3 + 0] = (byte) ((pixel >> 16) & 0xff);                 buffer[(y * width + x) * 3 + 1] = (byte) ((pixel >> 8) & 0xff);                 buffer[(y * width + x) * 3 + 2] = (byte) ((pixel >> 0) & 0xff);             } else if (bitmapformat == gles20.gl_rgba) {                 buffer[(y * width + x) * 4 + 0] = (byte) ((pixel >> 16) & 0xff);                 buffer[(y * width + x) * 4 + 1] = (byte) ((pixel >> 8) & 0xff);                 buffer[(y * width + x) * 4 + 2] = (byte) ((pixel >> 0) & 0xff);                  // alpha channel                 buffer[(y * width + x) * 4 + 3] = (byte) ((pixel >> 24) & 0xff);             } */             int pixel = pixelarray[x + y * width];              if (bitmapformat == gles20.gl_rgb565) {                 /*                 buffer[(y * width + x) * 3 + 0] = (byte) ((pixel >> 11) & 0x1f); // color rojo empieza en el bit 11 y se debe hacer , logico con 1f pues ocupa 5 caracteres                 buffer[(y * width + x) * 3 + 1] = (byte) ((pixel >> 5) & 0x3f);                 buffer[(y * width + x) * 3 + 2] = (byte) ((pixel >> 0) & 0x1f);                 */                 byte red = (byte) ((pixel >> 11) & 0x1f);                 byte green = (byte) ((pixel >> 5) & 0x3f);                 byte blue = (byte) ((pixel >> 0) & 0x1f);                  // desplazamos red tres dígitos la izquierda que es lo que queda libre del byte al ser red de 5 bits                 byte first_byte = (byte) (red << 3);                 // desplazamos tres bits la derecha y aplicamos la máscara con , lógico                 byte auxiliar_green_first_byte = (byte) ((green >> 3) & 0x7); // máscara 7 => 0000000111                 // ya podemos calcular el primer byte                 first_byte = (byte) (first_byte | auxiliar_green_first_byte);                 // creamos un nuevo auxiliar para manejar la parte baja de green                 // desplazamos la parte baja de green cinco bits y hacemos un , lógico con la máscara e0 para dejar hueco blue                 byte auxiliar_green_second_byte = (byte) ((green << 5) & 0xe0); // máscara e0 => 11100000                 // ya podemos calcular el segundo byte = auxiliar_green_second_byte | blue;                 byte second_byte = (byte) (auxiliar_green_second_byte | blue);                  // almacenamos los resultados del pixel                 buffer[(y * width + x) * 2 + 0] = first_byte;                 buffer[(y * width + x) * 2 + 1] = second_byte;               } else if (bitmapformat == gles20.gl_rgba4) {                 /*                 buffer[(y * width + x) * 4 + 0] = (byte) ((pixel >> 16) & 0xff);                 buffer[(y * width + x) * 4 + 1] = (byte) ((pixel >> 8) & 0xff);                 buffer[(y * width + x) * 4 + 2] = (byte) ((pixel >> 0) & 0xff);                  // alpha channel                 buffer[(y * width + x) * 4 + 3] = (byte) ((pixel >> 24) & 0xff);                 */                 byte red = (byte) ((pixel >> 8) & 0xf);                 byte green = (byte) ((pixel >> 4) & 0xf);                 byte blue = (byte) ((pixel >> 0) & 0xf);                  byte alpha = (byte) ((pixel >> 12) & 0xf);                  // movemos red 4 bits la izquierda y aplicamos máscara 11110000                 byte first_byte = (byte) ((red << 4) & 0xf0);                  // tras haber desplazado red procedemos calcular definitivamente fist_byte con red or green                 first_byte = (byte) (first_byte | green); // green ya está desplazado en los 4 últimos bits, no hace falta manipularlo                  // movemos blue 4 bits la izquierda y aplicamos máscara 11110000                 byte second_byte = (byte) ((blue << 4) & 0xf0);                 // tras haber desplazado blue procedemos calcular definitivamente second byte con la operación nuevo blue or logico alpha                 second_byte = (byte) (second_byte | alpha); // alpha ya está desplazado en los 4 últimos bits, no hace falta manipularlo                  buffer[(y * width + x) * 2 + 0] = first_byte;                 buffer[(y * width + x) * 2 + 1] = second_byte;             }         }       }     bytebuffer bytebuffer = null;     /*     if (bitmapformat == gles20.gl_rgb) { // 3 bytes, 1 por canal         bytebuffer = bytebuffer.allocatedirect(width * height * 3);     } else if (bitmapformat == gles20.gl_rgba4) { // 4 bytes, 1 por canal         bytebuffer = bytebuffer.allocatedirect(width * height * 4);     }     */     if (bitmapformat == gles20.gl_rgb565) { // 3 bytes, 1 por canal         bytebuffer = bytebuffer.allocatedirect(width * height * 2);     } else if (bitmapformat == gles20.gl_rgba4) { // 4 bytes, 1 por canal         bytebuffer = bytebuffer.allocatedirect(width * height * 2);     }     bytebuffer.put(buffer).position(0);      gles20.glgentextures(1, textureid, 0);      this.m_textureid = textureid[0];      bind();      setfilters(this.m_minifyfilter, this.m_magnifyfilter);     // gles20.gltexparameteri ( gles20.gl_texture_2d, gles20.gl_texture_min_filter, gles20.gl_linear );     // gles20.gltexparameteri ( gles20.gl_texture_2d, gles20.gl_texture_mag_filter, gles20.gl_linear );     gles20.gltexparameteri(gles20.gl_texture_2d, gles20.gl_texture_wrap_s, gles20.gl_repeat);     gles20.gltexparameteri(gles20.gl_texture_2d, gles20.gl_texture_wrap_t, gles20.gl_repeat);       /*      gles20.glteximage2d(gles20.gl_texture_2d, 0, bitmapformat, width, height, 0,                 bitmapformat, gles20.gl_unsigned_byte, bytebuffer);      */      if (bitmapformat == gles20.gl_rgb565) {         gles20.glteximage2d(gles20.gl_texture_2d, 0, bitmapformat, width, height, 0,                 bitmapformat, gles20.gl_unsigned_short_5_6_5, bytebuffer);     } else if (bitmapformat == gles20.gl_rgba4) {         gles20.glteximage2d(gles20.gl_texture_2d, 0, bitmapformat, width, height, 0,                 bitmapformat, gles20.gl_unsigned_short_4_4_4_4, bytebuffer);     }      // this.textureid = textureid[0];     pixelarray = null; // para que el recolector libere el tamaño del array de la imagen en memoria      if ((m_minifyfilter == gles20.gl_linear_mipmap_linear) ||             (m_minifyfilter == gles20.gl_linear_mipmap_nearest) ||             (m_minifyfilter == gles20.gl_nearest_mipmap_linear) ||             (m_minifyfilter == gles20.gl_nearest_mipmap_nearest)) {          gles20.glgeneratemipmap(gles20.gl_texture_2d);     }      unbind();     bitmap.recycle();     try {         is.close();     } catch (ioexception e) {         log.e("texture.loadtexture: ", " error closing inputstream");     }     return textureid[0]; } 

edit 1:

i´m editing because see poor result converting rgb888 texture rgb565 one. followed method suggested @samgak, looks work ok color distorted. i´m uploading 2 captures, first 1 rgb888 , looks well, should do. second 1 conversion distorsion. normal in kind of transformation? if is, have keep texture in full rgb888 format

well drawn frame: enter image description here

cubes bounding volumes colliding system

enter image description here

solved. problem was getting bytebuffer in wrong byte order (endianless/big endian) , swapping first , second byte @samgak suggested.

gles20.gl_rgb565 , gles20.gl_rgba4 not valid values pass glteximage2d:

internalformat specifies internal format of texture. must 1 of following symbolic constants: gl_alpha, gl_luminance, gl_luminance_alpha, gl_rgb, gl_rgba.

when uploading rgb 565 texture using glteximage2d, should pass gles20.gl_rgb format , internalformat, , gles20.gl_unsigned_short_5_6_5 type. likewise rgba 4444 texture, pass gles20.gl_rgba , gles20.gl_unsigned_short_4_4_4_4

e.g:

gles20.glteximage2d(gles20.gl_texture_2d, 0, gles20.gl_rgb, width, height, 0,     gles20.gl_rgb, gles20.gl_unsigned_short_5_6_5, bytebuffer); 

and

gles20.glteximage2d(gles20.gl_texture_2d, 0, gles20.gl_rgba, width, height, 0,     gles20.gl_rgba, gles20.gl_unsigned_short_4_4_4_4, bytebuffer); 

gles20.gl_rgb565 , gles20.gl_rgba4 used specifying internal format of render buffer in calls glrenderbufferstorage


Comments

Popular posts from this blog

java - Andrioid studio start fail: Fatal error initializing 'null' -

android - Gradle sync Error:Configuration with name 'default' not found -

StringGrid issue in Delphi XE8 firemonkey mobile app -