/** * Frees up the space allocated to the supplied texture * * @param t The texture to delete * @return <code>true</code> if the texture was released, <code>false</code> if it could not be * found */ public static boolean deleteTexture(Texture t) { for (GLTexture tex : textures) { if (tex.release(t)) { return true; } } return false; }
/** * Called in response to the opengl context going away, perhaps as a result of the display mode * changing */ public static void recreateTextures() { IntBuffer texNames = BufferUtils.createIntBuffer(textures.size()); for (GLTexture glt : textures) { texNames.put(glt.id); } texNames.flip(); GL11.glDeleteTextures(texNames); for (GLTexture glt : textures) { glt.recreate(); } }
/** * Loads the specified image into OpenGL. Does not specify which texture the image will reside on, * and will create new OpenGL textures as needed * * @param image the texture image * @param lonesome <code>true</code> if this texture is to be allocated in a gl texture of minimal * size, <code>false</code> for the default size * @param mipmap <code>true</code> to generate mipmaps, false otherwise * @return A {@link Texture} object, or null if it was not able to be constructed */ public static Texture buildTexture(Image image, boolean lonesome, boolean mipmap) { if (lonesome) { try { GLTexture parent = new GLTexture(image.format, image, mipmap, lonesome ? 0 : 1); textures.add(parent); Texture texture = parent.addImage(image); assert texture.getWidth() == image.getWidth(); assert texture.getHeight() == image.getHeight(); return texture; } catch (OpenGLException e) { e.printStackTrace(); return null; } } else { for (GLTexture tex : textures) { // match formats if (tex.mipmap == mipmap && tex.format == image.format) { // try to insert Texture t = tex.addImage(image); if (t != null) { // it worked! return t; } // else there was no room } } // build a new texture try { GLTexture parent = new GLTexture(image.format, null, mipmap, 1); textures.add(parent); return parent.addImage(image); } catch (OpenGLException e) { // we were not able to build the texture e.printStackTrace(); return null; } } }
/** * Regenerates any dirty mipmaps. e.g.: If there's a texture that has has data added after * creation, that data will not have made it into the lower levels. This method makes sure that it * does */ public static void regenerateMipMaps() { for (GLTexture t : textures) { t.regenerateMipmaps(); } }
public static GLTexture load(ReadableByteChannel theInputChannel) { if (theInputChannel == null) return null; GLKTXHeader myHeader = new GLKTXHeader(); myHeader.read(theInputChannel); // GLuint temp = 0; // GLuint retval = 0; // // size_t data_start, data_end; // unsigned char * data; // GLTextureTarget target = GL_NONE; if (myHeader.endianness == 0x04030201) { // No swap needed } else if (myHeader.endianness == 0x01020304) { // Swap needed myHeader.endianness = Integer.reverseBytes(myHeader.endianness); myHeader.gltype = Integer.reverseBytes(myHeader.gltype); myHeader.gltypesize = Integer.reverseBytes(myHeader.gltypesize); myHeader.glformat = Integer.reverseBytes(myHeader.glformat); myHeader.glinternalformat = Integer.reverseBytes(myHeader.glinternalformat); myHeader.glbaseinternalformat = Integer.reverseBytes(myHeader.glbaseinternalformat); myHeader.pixelwidth = Integer.reverseBytes(myHeader.pixelwidth); myHeader.pixelheight = Integer.reverseBytes(myHeader.pixelheight); myHeader.pixeldepth = Integer.reverseBytes(myHeader.pixeldepth); myHeader.arrayelements = Integer.reverseBytes(myHeader.arrayelements); myHeader.faces = Integer.reverseBytes(myHeader.faces); myHeader.miplevels = Integer.reverseBytes(myHeader.miplevels); myHeader.keypairbytes = Integer.reverseBytes(myHeader.keypairbytes); } GLTextureTarget target = null; // Guess target (texture type) if (myHeader.pixelheight == 0) { if (myHeader.arrayelements == 0) { target = GLTextureTarget.TEXTURE_1D; } else { target = GLTextureTarget.TEXTURE_1D_ARRAY; } } else if (myHeader.pixeldepth == 0) { if (myHeader.arrayelements == 0) { if (myHeader.faces == 0 || myHeader.faces == 1) { target = GLTextureTarget.TEXTURE_2D; } else { target = GLTextureTarget.TEXTURE_CUBE_MAP; } } else { if (myHeader.faces == 0) { target = GLTextureTarget.TEXTURE_2D_ARRAY; } else { target = GLTextureTarget.TEXTURE_CUBE_MAP_ARRAY; } } } else { target = GLTextureTarget.TEXTURE_3D; } if (target == null) throw new RuntimeException("Couldn't figure out target"); if (myHeader.pixelwidth == 0) throw new RuntimeException("Texture has no width???"); if (myHeader.pixelheight == 0 && myHeader.pixeldepth != 0) throw new RuntimeException("Texture has depth but no height???"); ByteBuffer data = null; if (theInputChannel instanceof FileChannel) { try { FileChannel myFileChannel = (FileChannel) theInputChannel; data = ByteBuffer.allocateDirect((int) (myFileChannel.size() - myFileChannel.position())); myFileChannel.read(data); data.rewind(); } catch (IOException e) { throw new RuntimeException(e); } } if (myHeader.miplevels == 0) { myHeader.miplevels = 1; } GLPixelDataInternalFormat myInternalFormat = GLPixelDataInternalFormat.fromGLID(myHeader.glinternalformat); GLPixelDataFormat myFormat = GLPixelDataFormat.fromGLID(myHeader.glformat); GLPixelDataType myType = GLPixelDataType.fromGLID(myHeader.gltype); CCLog.info( myInternalFormat + " ; " + myFormat + " ; " + myType + " ; " + Integer.toHexString(myHeader.glinternalformat)); GL4 gl = GLGraphics.currentGL(); GLTexture myResult = null; switch (target) { case TEXTURE_1D: GLTexture1D myTexture1D = new GLTexture1D(myHeader.miplevels, myInternalFormat, myHeader.pixelwidth); myTexture1D.texSubImage1D(0, 0, myHeader.pixelwidth, myFormat, myType, data); myResult = myTexture1D; break; case TEXTURE_2D: GLTexture2D myTexture2D = new GLTexture2D( myHeader.miplevels, myInternalFormat, myHeader.pixelwidth, myHeader.pixelheight); { int height = myHeader.pixelheight; int width = myHeader.pixelwidth; gl.glPixelStorei(GL4.GL_UNPACK_ALIGNMENT, 1); for (int i = 0; i < myHeader.miplevels; i++) { myTexture2D.texSubImage2D(i, 0, 0, width, height, myFormat, myType, data); // ptr += height * calculate_stride(h, width, 1); height >>= 1; width >>= 1; if (height <= 0) height = 1; if (width <= 0) width = 1; } } myResult = myTexture2D; break; case TEXTURE_3D: GLTexture3D myTexture3D = new GLTexture3D( myHeader.miplevels, myInternalFormat, myHeader.pixelwidth, myHeader.pixelheight, myHeader.pixeldepth); myTexture3D.texSubImage3D( 0, 0, 0, 0, myHeader.pixelwidth, myHeader.pixelheight, myHeader.pixeldepth, myFormat, myType, data); myResult = myTexture3D; break; case TEXTURE_1D_ARRAY: GLTexture1DArray myTexture1DArray = new GLTexture1DArray( myHeader.miplevels, myInternalFormat, myHeader.pixelwidth, myHeader.arrayelements); myTexture1DArray.texSubImage( 0, 0, 0, myHeader.pixelwidth, myHeader.arrayelements, myFormat, myType, data); myResult = myTexture1DArray; break; case TEXTURE_2D_ARRAY: GLTexture2DArray myTexture2DArray = new GLTexture2DArray( myHeader.miplevels, myInternalFormat, myHeader.pixelwidth, myHeader.pixelheight, myHeader.arrayelements); myTexture2DArray.texSubImage( 0, 0, 0, 0, myHeader.pixelwidth, myHeader.pixelheight, myHeader.arrayelements, myFormat, myType, data); myResult = myTexture2DArray; break; // case TEXTURE_CUBE_MAP: // glTexStorage2D(GL_TEXTURE_CUBE_MAP, myHeader.miplevels, // myHeader.glinternalformat, myHeader.pixelwidth, myHeader.pixelheight); // // glTexSubImage3D(GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, myHeader.pixelwidth, // myHeader.pixelheight, myHeader.faces, myHeader.glformat, myHeader.gltype, data); // { // int face_size = calculate_face_size(h); // for (int i = 0; i < myHeader.faces; i++) // { // glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, // myHeader.pixelwidth, myHeader.pixelheight, myHeader.glformat, myHeader.gltype, data + // face_size * i); // } // } // break; // case TEXTURE_CUBE_MAP_ARRAY: // glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, myHeader.miplevels, // myHeader.glinternalformat, myHeader.pixelwidth, myHeader.pixelheight, // myHeader.arrayelements); // glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, myHeader.pixelwidth, // myHeader.pixelheight, myHeader.faces * myHeader.arrayelements, myHeader.glformat, // myHeader.gltype, data); // break; // default: // Should never happen // goto fail_target; } if (myHeader.miplevels == 1) { myResult.generateMipMaps(); } return myResult; }
public void copyTex(GLTexture srcTex, GLTexture destTex) { float uscale = srcTex.getMaxTextureCoordS(); float vscale = srcTex.getMaxTextureCoordT(); float cx = 0.0f; float sx = +1.0f; if (destTex.isFlippedX()) { cx = 1.0f; sx = -1.0f; } float cy = 0.0f; float sy = +1.0f; if (destTex.isFlippedY()) { cy = 1.0f; sy = -1.0f; } gl.glEnable(srcTex.getTextureTarget()); gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(srcTex.getTextureTarget(), srcTex.getTextureID()); pushFramebuffer(); setFramebuffer(FBO); FBO.setDrawBuffer(destTex.getTextureTarget(), destTex.getTextureID()); saveView(); setOrthographicView(destTex.width, destTex.height); gl.glEnable(srcTex.getTextureTarget()); gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(srcTex.getTextureTarget(), srcTex.getTextureID()); gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gl.glBegin(GL.GL_QUADS); gl.glTexCoord2f((cx + sx * 0.0f) * uscale, (cy + sy * 0.0f) * vscale); gl.glVertex2f(0.0f, 0.0f); gl.glTexCoord2f((cx + sx * 1.0f) * uscale, (cy + sy * 0.0f) * vscale); gl.glVertex2f(srcTex.width, 0.0f); gl.glTexCoord2f((cx + sx * 1.0f) * uscale, (cy + sy * 1.0f) * vscale); gl.glVertex2f(srcTex.width, srcTex.height); gl.glTexCoord2f((cx + sx * 0.0f) * uscale, (cy + sy * 1.0f) * vscale); gl.glVertex2f(0.0f, srcTex.height); gl.glEnd(); gl.glBindTexture(srcTex.getTextureTarget(), 0); restoreView(); popFramebuffer(); }