/* * 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 static haven.GOut.checkerr; import java.awt.Color; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import javax.media.opengl.GL; import javax.media.opengl.GL2; public abstract class TexGL extends Tex { protected int id = -1; protected GL mygl = null; private Object idmon = new Object(); protected Coord tdim; protected static Map<GL, Collection<Integer>> disposed = new HashMap<GL, Collection<Integer>>(); public static boolean disableall = false; public TexGL(Coord sz) { super(sz); tdim = new Coord(nextp2(sz.x), nextp2(sz.y)); } protected abstract void fill(GOut gl); private void create(GOut g) { GL gl = g.gl; int[] buf = new int[1]; gl.glGenTextures(1, buf, 0); id = buf[0]; mygl = gl; gl.glBindTexture(GL.GL_TEXTURE_2D, id); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); fill(g); checkerr(gl); } protected Color setenv(GL2 gl) { gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); return (Color.WHITE); } Color blend(GOut g, Color amb) { Color c = g.getcolor(); Color n = new Color((c.getRed() * amb.getRed()) / 255, (c.getGreen() * amb.getGreen()) / 255, (c.getBlue() * amb.getBlue()) / 255, (c.getAlpha() * amb.getAlpha()) / 255); return (n); } public void render(GOut g, Coord c, Coord ul, Coord br, Coord sz) { GL2 gl = g.gl; synchronized (idmon) { if ((id != -1) && (mygl != gl)) { dispose(mygl, id); id = -1; } if (id < 0) create(g); g.texsel(id); } Color amb = blend(g, setenv(gl)); checkerr(gl); if (!disableall) { gl.glBegin(GL2.GL_QUADS); float l = ((float) ul.x) / ((float) tdim.x); float t = ((float) ul.y) / ((float) tdim.y); float r = ((float) br.x) / ((float) tdim.x); float b = ((float) br.y) / ((float) tdim.y); gl.glColor4f((float) amb.getRed() / 255.0f, (float) amb.getGreen() / 255.0f, (float) amb.getBlue() / 255.0f, (float) amb.getAlpha() / 255.0f); gl.glTexCoord2f(l, t); gl.glVertex3i(c.x, c.y, 0); gl.glTexCoord2f(r, t); gl.glVertex3i(c.x + sz.x, c.y, 0); gl.glTexCoord2f(r, b); gl.glVertex3i(c.x + sz.x, c.y + sz.y, 0); gl.glTexCoord2f(l, b); gl.glVertex3i(c.x, c.y + sz.y, 0); gl.glEnd(); checkerr(gl); } } private static void dispose(GL gl, int id) { Collection<Integer> dc; synchronized (disposed) { dc = disposed.get(gl); if (dc == null) { dc = new LinkedList<Integer>(); disposed.put(gl, dc); } } synchronized (dc) { dc.add(id); } } public void dispose() { synchronized (idmon) { if (id == -1) return; dispose(mygl, id); id = -1; } } protected void finalize() { dispose(); } public static void disposeall(GL gl) { Collection<Integer> dc; synchronized (disposed) { dc = disposed.get(gl); if (dc == null) return; } synchronized (dc) { if (dc.isEmpty()) return; int[] da = new int[dc.size()]; int i = 0; for (int id : dc) da[i++] = id; dc.clear(); gl.glDeleteTextures(da.length, da, 0); } } static { Console.setscmd("texdis", new Console.Command() { public void run(Console cons, String[] args) { disableall = (Integer.parseInt(args[1]) != 0); } }); } }