private void writeCustomImage() { try { BufferedImage image = new BufferedImage(width, outputFrames * height, BufferedImage.TYPE_INT_ARGB); IntBuffer intBuffer = scratchBuffer.asIntBuffer(); int[] argb = new int[width * height]; File path = MCPatcherUtils.getGamePath("custom_" + name + ".png"); logger.info("generating %d %s frames", outputFrames, name); for (int i = 0; i < outputFrames; i++) { renderToItems(i * (360.0 / outputFrames)); itemsFBO.read(scratchBuffer); intBuffer.position(0); for (int j = 0; j < argb.length; j++) { switch (MipmapHelper.TEX_FORMAT) { case GL12.GL_BGRA: int bgra = intBuffer.get(j); argb[j] = (bgra << 24) | ((bgra & 0xff00) << 8) | ((bgra & 0xff0000) >> 8) | (bgra >>> 24); break; default: if (i == 0 && j == 0) { logger.warning( "unhandled texture format %d, color channels may be incorrect", MipmapHelper.TEX_FORMAT); } // fall through case GL11.GL_RGBA: argb[j] = Integer.rotateRight(intBuffer.get(j), 8); break; } } image.setRGB(0, i * height, width, height, argb, 0, width); } ImageIO.write(image, "png", path); logger.info("wrote %dx%d %s", image.getWidth(), image.getHeight(), path.getPath()); } catch (Throwable e) { e.printStackTrace(); } }
private boolean render(boolean itemFrameRenderer) { if (!ok) { return false; } if (!itemFrameRenderer) { boolean changed = true; if (!keyboard.isEnabled()) { changed = false; } else if (keyboard.isKeyPressed(Keyboard.KEY_NUMPAD2)) { scaleYDelta -= STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_NUMPAD8)) { scaleYDelta += STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_NUMPAD4)) { scaleXDelta -= STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_NUMPAD6)) { scaleXDelta += STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_DOWN)) { offsetYDelta += STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_UP)) { offsetYDelta -= STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_LEFT)) { offsetXDelta -= STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_RIGHT)) { offsetXDelta += STEP; } else if (keyboard.isKeyPressed(Keyboard.KEY_MULTIPLY)) { scaleXDelta = scaleYDelta = offsetXDelta = offsetYDelta = 0.0f; } else { changed = false; } if (changed) { logger.info(""); logger.info("scaleX %+f", scaleXDelta); logger.info("scaleY %+f", scaleYDelta); logger.info("offsetX %+f", offsetXDelta); logger.info("offsetY %+f", offsetYDelta); lastAngle = ANGLE_UNSET; } if (outputFrames > 0) { writeCustomImage(); outputFrames = 0; } } double angle = getAngle(icon); if (!useScratchTexture) { // render directly to items.png if (angle != lastAngle) { renderToItems(angle); lastAngle = angle; } } else if (itemFrameRenderer) { // look in itemFrames cache first ByteBuffer buffer = itemFrames.get(angle); if (buffer == null) { logger.fine("rendering %s at angle %f for item frame", name, angle); buffer = ByteBuffer.allocateDirect(width * height * 4); renderToItems(angle); itemsFBO.read(buffer); itemFrames.put(angle, buffer); } else { itemsFBO.write(buffer); } lastItemFrameRenderer = true; } else if (lastAngle == ANGLE_UNSET) { // first time rendering - render all N copies for (FBO fbo : scratchFBO) { renderToFB(angle, fbo); } scratchFBO[0].read(scratchBuffer); itemsFBO.write(scratchBuffer); lastAngle = angle; scratchIndex = 0; } else if (lastItemFrameRenderer || angle != lastAngle) { // render to buffer i + 1 // update items.png from buffer i int nextIndex = (scratchIndex + 1) % NUM_SCRATCH_TEXTURES; if (angle != lastAngle) { renderToFB(angle, scratchFBO[nextIndex]); scratchFBO[scratchIndex].read(scratchBuffer); } itemsFBO.write(scratchBuffer); lastAngle = angle; scratchIndex = nextIndex; lastItemFrameRenderer = false; } int glError = GL11.glGetError(); if (glError != 0) { logger.severe("%s during %s update", GLU.gluErrorString(glError), name); ok = false; } return ok; }