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:
cubes bounding volumes colliding system
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
Post a Comment