Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Rockhopper

Members
  • Posts

    3
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Rockhopper's Achievements

Tree Puncher

Tree Puncher (2/8)

0

Reputation

  1. But while I've got you here, @V0idWa1k3r, any ideas how I could get this working on blocks like signs and beds? The sprite being retrieved for those blocks is the purple/black missing texture pattern. Clearly retrieving their top quad isn't the way to go.
  2. Thank you @V0idWa1k3r! That was just the tip I needed to get this working. I found another post of yours elsewhere on the forum and ended up combining it with the advice here to come up with // Temporarily replace the frame buffer to write sprite data. int width = sprite.getIconWidth(); int height = sprite.getIconHeight(); Framebuffer currentFrame = Minecraft.getMinecraft().getFramebuffer(); Framebuffer spriteFrame = new Framebuffer(width, height, true); spriteFrame.bindFramebuffer(true); GlStateManager.clearColor(0, 0, 0, 1); GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT); // Draw the actual block texture. GlStateManager.pushMatrix(); float xScale = ((1.0f * Minecraft.getMinecraft().displayWidth) / (1.0f * Minecraft.getMinecraft().displayHeight)); GlStateManager.scale(xScale, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); Minecraft.getMinecraft().ingameGUI.drawTexturedModalRect(0, 0, sprite, 256, 256); GlStateManager.popMatrix(); // Allocate a buffer for GL to dump pixels into. IntBuffer pixels = BufferUtils.createIntBuffer(width * height); GlStateManager.bindTexture(spriteFrame.framebufferTexture); // Dump the pixels onto the IntBuffer. Note that the pixel format is BGRA and // the pixel type is 8 bits per color. GlStateManager.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixels); // Allocate the array to hold pixel values. int[] pixelValues = new int[width * height]; pixels.get(pixelValues); TextureUtil.processPixelValues(pixelValues, width, height); which seems to be working great. Just in case it helps anyone else down the road, here's what I use to retrieve the sprite. // If a block is liquid, get its texture from the fluid registry. if (block instanceof IFluidBlock || block instanceof BlockLiquid) { Fluid fluid = FluidRegistry.lookupFluidForBlock(block); ResourceLocation fluidTexture = fluid.getStill(); sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(fluidTexture.toString()); // Retrieve the top quad of the solid block. } else { IBakedModel bakedModel = Minecraft.getMinecraft().getBlockRendererDispatcher() .getBlockModelShapes().getModelForState(blockState); List<BakedQuad> quadList = bakedModel.getQuads(blockState, EnumFacing.UP, 0L); sprite = quadList.isEmpty() ? bakedModel.getParticleTexture() : quadList.get(0).getSprite(); }
  3. Hello everyone, I've been getting some good support in the Discord about this recently, but still haven't been able to resolve my problems. I figured I'd create a post here now that the forums are back online. What I'm trying to do: when a player types a command, I want to export an average pixel color value for the top surface of all blocks. What I've managed to do so far is to obtain the TextureAtlasSprite that I believe corresponds to the top surface of every block in the game. I cannot for the life of me figure out how to read the actual pixel values of this sprite though. Here's what I have so far: // Flag for whether the player has executed a color map generation request. public static boolean MAPPING = false; @SubscribeEvent public static void onTickingPlayer(PlayerTickEvent event) { if (MAPPING) { MAPPING = false; EntityPlayer sender = event.player; sender.sendMessage(new TextComponentString(TextFormatting.GREEN + "Exporting all block textures...")); // Find the texture of each block. for (Block block : ForgeRegistries.BLOCKS) { for (IBlockState blockState : block.getBlockState().getValidStates()) { // Filter to test on just cobble for now. if (blockState.toString().equals("minecraft:cobblestone")) { // Retrieve the top quad of the block. System.out.println(blockState.toString()); IBakedModel bakedModel = Minecraft.getMinecraft().getBlockRendererDispatcher() .getBlockModelShapes().getModelForState(blockState); List<BakedQuad> quadList = bakedModel.getQuads(blockState, EnumFacing.UP, 0L); TextureAtlasSprite sprite = quadList.isEmpty() ? bakedModel.getParticleTexture() : quadList.get(0).getSprite(); if (sprite == null) { System.out.println("null"); // If the sprite exists, parse its pixel information. } else { int width = sprite.getIconWidth(); int height = sprite.getIconHeight(); int bytesPerPixel = 4; ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * bytesPerPixel); Minecraft.getMinecraft().getTextureManager() .bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GL11.glReadPixels(sprite.getOriginX(), sprite.getOriginY(), width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels); // Debug print an image of the single block. int r = 0, g = 0, b = 0; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int i = (x + (width * y)) * bytesPerPixel; r = pixels.get(i) & 0xFF; g = pixels.get(i + 1) & 0xFF; b = pixels.get(i + 2) & 0xFF; image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b); } } File file = new File("test_cobblestone.png"); String format = "png"; try { ImageIO.write(image, format, file); } catch (IOException e) { e.printStackTrace(); } // Debug print the atlas. int atlasSize = 112; ByteBuffer atlasPixels = BufferUtils.createByteBuffer(atlasSize * atlasSize * 4); Minecraft.getMinecraft().getTextureManager() .bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GL11.glReadPixels(0, 0, atlasSize, atlasSize, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, atlasPixels); BufferedImage atlasImage = new BufferedImage(atlasSize, atlasSize, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < atlasSize; x++) { for (int y = 0; y < atlasSize; y++) { int i = (x + (atlasSize * y)) * bytesPerPixel; int atlasR = atlasPixels.get(i) & 0xFF; int atlasG = atlasPixels.get(i + 1) & 0xFF; int atlasB = atlasPixels.get(i + 2) & 0xFF; atlasImage.setRGB(x, atlasSize - (y + 1), (0xFF << 24) | (atlasR << 16) | (atlasG << 8) | atlasB); } } File atlasFile = new File("test_atlas.png"); String atlasFormat = "png"; try { ImageIO.write(atlasImage, atlasFormat, atlasFile); } catch (IOException e) { e.printStackTrace(); } } } } } } } What I was trying to do with this code above is print out as debug two images, "test_cobblestone.png" and "test_atlas.png" which I would expect to correspond to the 16x16 area of the texture atlas for the cobblestone surface and to a larger 112x112 snapshot of the texture atlas, respectively. What I find instead is that they correspond to effectively partial screenshots of my current view when running the command! I've attached them to this post for reference. I put this code into a tick handler just in case it was somehow being broken when attempting to execute immediately off of the command. What it seems to me is going on is an error somewhere in this part of my code: int width = sprite.getIconWidth(); int height = sprite.getIconHeight(); int bytesPerPixel = 4; ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * bytesPerPixel); Minecraft.getMinecraft().getTextureManager() .bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GL11.glReadPixels(sprite.getOriginX(), sprite.getOriginY(), width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels); It looks like "GL11.glReadPixels" is reading my screen and not the texture atlas. Any and all help here would be appreciated. I know that I can maybe achieve the same goal by reading the textures from disk, but really want to better understand how I can actually read textures from the block texture atlas. Thank you!
×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.