/* * This file is part of the Haven & Hearth game client. * Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and * Björn Johannessen <johannessen.bjorn@gmail.com> * * Redistribution and/or modification of this file is subject to the * terms of the GNU Lesser General Public License, version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Other parts of this source tree adhere to other copying * rights. Please see the file `COPYING' in the root directory of the * source tree for details. * * A copy the GNU Lesser General Public License is distributed along * with the source tree of which this file is a part in the file * `doc/LPGL-3'. If it is missing for any reason, please see the Free * Software Foundation's website at <http://www.fsf.org/>, or write * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ package haven; import java.util.*; import java.awt.Graphics; import java.awt.image.*; import java.io.*; import javax.imageio.ImageIO; import java.awt.color.ColorSpace; import java.nio.ByteBuffer; import javax.media.opengl.*; import haven.Defer.Future; @Resource.LayerName("tex") public class TexR extends Resource.Layer implements Resource.IDLayer<Integer> { transient private byte[] img, mask; transient private final TexL tex; private final Coord off, sz; public final int id; public TexR(Resource res, byte[] rbuf) { res.super(); Message buf = new Message(0, rbuf); this.id = buf.int16(); this.off = new Coord(buf.uint16(), buf.uint16()); this.sz = new Coord(buf.uint16(), buf.uint16()); this.tex = new Real(); int minfilter = -1, magfilter = -1; while(!buf.eom()) { int t = buf.uint8(); switch(t) { case 0: this.img = buf.bytes(buf.int32()); break; case 1: int ma = buf.uint8(); tex.mipmap(new Mipmapper[] { Mipmapper.avg, // Default Mipmapper.avg, // Specific Mipmapper.rnd, Mipmapper.cnt, Mipmapper.dav, }[ma]); break; case 2: int magf = buf.uint8(); magfilter = new int[] {GL.GL_NEAREST, GL.GL_LINEAR}[magf]; break; case 3: int minf = buf.uint8(); minfilter = new int[] {GL.GL_NEAREST, GL.GL_LINEAR, GL.GL_NEAREST_MIPMAP_NEAREST, GL.GL_NEAREST_MIPMAP_LINEAR, GL.GL_LINEAR_MIPMAP_NEAREST, GL.GL_LINEAR_MIPMAP_LINEAR, }[minf]; break; case 4: this.mask = buf.bytes(buf.int32()); break; default: throw(new Resource.LoadException("Unknown texture data part " + t + " in " + res.name, getres())); } } if(magfilter == -1) magfilter = GL.GL_LINEAR; if(minfilter == -1) minfilter = (tex.mipmap == null)?GL.GL_LINEAR:GL.GL_LINEAR_MIPMAP_LINEAR; tex.magfilter(magfilter); tex.minfilter(minfilter); } private class Real extends TexL { private Real() { super(sz); } private BufferedImage rd(byte[] data) { try { return(ImageIO.read(new ByteArrayInputStream(data))); } catch(IOException e) { throw(new RuntimeException("Invalid image data in " + getres().name, e)); } } protected BufferedImage fill() { if(mask == null) { return(rd(TexR.this.img)); } else { BufferedImage col = rd(TexR.this.img); BufferedImage mask = rd(TexR.this.mask); Coord sz = Utils.imgsz(mask); BufferedImage ret = TexI.mkbuf(sz); Graphics g = ret.createGraphics(); g.drawImage(col, 0, 0, sz.x, sz.y, null); Raster mr = mask.getRaster(); if(mr.getNumBands() != 1) throw(new RuntimeException("Invalid separated alpha data in " + getres().name)); WritableRaster rr = ret.getRaster(); for(int y = 0; y < sz.y; y++) { for(int x = 0; x < sz.x; x++) { rr.setSample(x, y, 3, mr.getSample(x, y, 0)); } } g.dispose(); return(ret); } } protected void fill(GOut g) { try { super.fill(g); } catch(Loading l) { throw(RenderList.RLoad.wrap(l)); } } public String toString() { return("TexR(" + getres().name + ", " + id + ")"); } } public TexGL tex() { return(tex); } public Integer layerid() { return(id); } public void init() {} }