/*
* 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.Comparator;
import javax.media.opengl.*;
public interface Rendered extends Drawn {
public boolean setup(RenderList r);
public static interface RComparator<T extends Rendered> {
public int compare(T a, T b, GLState.Buffer sa, GLState.Buffer sb);
}
public static final GLState.Slot<Order> order = new GLState.Slot<Order>(GLState.Slot.Type.GEOM, Order.class, HavenPanel.global);
public static abstract class Order<T extends Rendered> extends GLState {
public abstract int mainz();
public abstract RComparator<? super T> cmp();
public void apply(GOut g) {}
public void unapply(GOut g) {}
public void prep(GLState.Buffer buf) {
buf.put(order, this);
}
public static class Default extends Order<Rendered> {
private final int z;
public Default(int z) {
this.z = z;
}
public int mainz() {
return(z);
}
private RComparator<Rendered> cmp = new RComparator<Rendered>() {
public int compare(Rendered a, Rendered b, GLState.Buffer sa, GLState.Buffer sb) {
return(0);
}
};
public RComparator<Rendered> cmp() {
return(cmp);
}
}
}
public final static Order deflt = new Order.Default(0);
public final static Order first = new Order.Default(Integer.MIN_VALUE);
public final static Order last = new Order.Default(Integer.MAX_VALUE);
public final static Order postfx = new Order.Default(5000);
public final static Order postpfx = new Order.Default(5500);
public final static Order eyesort = new Order.Default(10000) {
private final RComparator<Rendered> cmp = new RComparator<Rendered>() {
public int compare(Rendered a, Rendered b, GLState.Buffer sa, GLState.Buffer sb) {
/* It would be nice to be able to cache these
* results somewhere. */
Camera ca = sa.get(PView.cam);
Location.Chain la = sa.get(PView.loc);
Matrix4f mva = ca.fin(Matrix4f.id).mul(la.fin(Matrix4f.id));
float da = (float)Math.sqrt((mva.m[12] * mva.m[12]) + (mva.m[13] * mva.m[13]) + (mva.m[14] * mva.m[14]));
Camera cb = sb.get(PView.cam);
Location.Chain lb = sb.get(PView.loc);
Matrix4f mvb = cb.fin(Matrix4f.id).mul(lb.fin(Matrix4f.id));
float db = (float)Math.sqrt((mvb.m[12] * mvb.m[12]) + (mvb.m[13] * mvb.m[13]) + (mvb.m[14] * mvb.m[14]));
if(da < db)
return(1);
else
return(-1);
}
};
public RComparator<Rendered> cmp() {
return(cmp);
}
};
public final static GLState.StandAlone skip = new GLState.StandAlone(GLState.Slot.Type.GEOM, HavenPanel.global) {
public void apply(GOut g) {}
public void unapply(GOut g) {}
};
public static class Dot implements Rendered {
public void draw(GOut g) {
GL2 gl = g.gl;
g.st.put(Light.lighting, null);
g.state(States.xray);
g.apply();
gl.glBegin(GL2.GL_POINTS);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(0.0f, 0.0f, 0.0f);
gl.glEnd();
}
public boolean setup(RenderList r) {
return(true);
}
}
public static class Axes implements Rendered {
public final float[] mid;
public Axes(java.awt.Color mid) {
this.mid = Utils.c2fa(mid);
}
public Axes() {
this(java.awt.Color.BLACK);
}
public void draw(GOut g) {
GL2 gl = g.gl;
g.st.put(Light.lighting, null);
g.state(States.xray);
g.apply();
gl.glBegin(GL.GL_LINES);
gl.glColor4fv(mid, 0);
gl.glVertex3f(0, 0, 0);
gl.glColor3f(1, 0, 0);
gl.glVertex3f(1, 0, 0);
gl.glColor4fv(mid, 0);
gl.glVertex3f(0, 0, 0);
gl.glColor3f(0, 1, 0);
gl.glVertex3f(0, 1, 0);
gl.glColor4fv(mid, 0);
gl.glVertex3f(0, 0, 0);
gl.glColor3f(0, 0, 1);
gl.glVertex3f(0, 0, 1);
gl.glEnd();
}
public boolean setup(RenderList r) {
r.state().put(States.color, null);
return(true);
}
}
public static class Line implements Rendered {
public final Coord3f end;
public Line(Coord3f end) {
this.end = end;
}
public void draw(GOut g) {
GL2 gl = g.gl;
g.apply();
gl.glBegin(GL.GL_LINES);
gl.glColor3f(1, 0, 0);
gl.glVertex3f(0, 0, 0);
gl.glColor3f(0, 1, 0);
gl.glVertex3f(end.x, end.y, end.z);
gl.glEnd();
}
public boolean setup(RenderList r) {
r.state().put(States.color, null);
r.state().put(Light.lighting, null);
return(true);
}
}
public static class Cube implements Rendered {
public void draw(GOut g) {
GL2 gl = g.gl;
g.apply();
gl.glEnable(GL2.GL_COLOR_MATERIAL);
gl.glBegin(GL2.GL_QUADS);
gl.glNormal3f(0.0f, 0.0f, 1.0f);
gl.glColor3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glColor3f(0.0f, 1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glColor3f(1.0f, 0.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glNormal3f(0.0f, 0.0f, -1.0f);
gl.glColor3f(1.0f, 1.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, -1.0f);
gl.glVertex3f(1.0f, 1.0f, -1.0f);
gl.glVertex3f(1.0f, -1.0f, -1.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glEnd();
gl.glColor3f(1.0f, 1.0f, 1.0f);
gl.glDisable(GL2.GL_COLOR_MATERIAL);
}
public boolean setup(RenderList rls) {
rls.state().put(States.color, null);
return(true);
}
}
public static class TCube implements Rendered {
public final Coord3f bn, bp;
public States.ColState sc = new States.ColState(new java.awt.Color(255, 64, 64, 128)), ec = new States.ColState(new java.awt.Color(255, 255, 255, 255));
public TCube(Coord3f bn, Coord3f bp) {
this.bn = bn;
this.bp = bp;
}
public void draw(GOut g) {
GL2 gl = g.gl;
g.state(Light.deflight);
g.state(sc);
g.apply();
gl.glEnable(GL2.GL_COLOR_MATERIAL);
gl.glBegin(gl.GL_QUADS);
gl.glNormal3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bn.z);
gl.glVertex3f(bp.x, bp.y, bn.z);
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glVertex3f(bn.x, bp.y, bn.z);
gl.glVertex3f(bn.x, bn.y, bn.z);
gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bn.z);
gl.glVertex3f(bn.x, bp.y, bn.z);
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glVertex3f(bn.x, bn.y, bn.z);
gl.glVertex3f(bp.x, bn.y, bn.z);
gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glNormal3f(0.0f, 0.0f, -1.0f);
gl.glVertex3f(bn.x, bp.y, bn.z);
gl.glVertex3f(bp.x, bp.y, bn.z);
gl.glVertex3f(bp.x, bn.y, bn.z);
gl.glVertex3f(bn.x, bn.y, bn.z);
gl.glEnd();
gl.glDisable(GL2.GL_COLOR_MATERIAL);
g.st.put(Light.lighting, null);
g.state(ec);
g.apply();
gl.glLineWidth(1.2f);
gl.glBegin(gl.GL_LINE_STRIP);
gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glEnd();
gl.glBegin(gl.GL_LINE_STRIP);
gl.glVertex3f(bn.x, bn.y, bn.z);
gl.glVertex3f(bn.x, bp.y, bn.z);
gl.glVertex3f(bp.x, bp.y, bn.z);
gl.glVertex3f(bp.x, bn.y, bn.z);
gl.glVertex3f(bn.x, bn.y, bn.z);
gl.glEnd();
gl.glBegin(gl.GL_LINES);
gl.glVertex3f(bn.x, bn.y, bn.z); gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bn.z); gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bn.z); gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glVertex3f(bn.x, bp.y, bn.z); gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glEnd();
gl.glPointSize(5);
gl.glBegin(gl.GL_POINTS);
gl.glVertex3f(bn.x, bn.y, bn.z); gl.glVertex3f(bn.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bn.y, bn.z); gl.glVertex3f(bp.x, bn.y, bp.z);
gl.glVertex3f(bp.x, bp.y, bn.z); gl.glVertex3f(bp.x, bp.y, bp.z);
gl.glVertex3f(bn.x, bp.y, bn.z); gl.glVertex3f(bn.x, bp.y, bp.z);
gl.glEnd();
}
public boolean setup(RenderList rls) {
rls.state().put(States.color, null);
rls.prepo(eyesort);
rls.prepo(States.presdepth);
return(true);
}
}
public static class ScreenQuad implements Rendered {
private static final Projection proj = new Projection(Matrix4f.id);
private static final VertexBuf.VertexArray pos = new VertexBuf.VertexArray(Utils.bufcp(new float[] {
-1, -1, 0,
1, -1, 0,
1, 1, 0,
-1, 1, 0,
}));
private static final VertexBuf.TexelArray tex = new VertexBuf.TexelArray(Utils.bufcp(new float[] {
0, 0,
1, 0,
1, 1,
0, 1,
}));
public static final GLState state = new GLState.Abstract() {
public void prep(Buffer buf) {
proj.prep(buf);
States.ndepthtest.prep(buf);
States.presdepth.prep(buf);
buf.put(PView.cam, null);
buf.put(PView.loc, null);
}
};
public void draw(GOut g) {
GL2 gl = g.gl;
g.apply();
pos.bind(g, false);
tex.bind(g, false);
gl.glDrawArrays(GL2.GL_QUADS, 0, 4);
pos.unbind(g);
tex.unbind(g);
}
public boolean setup(RenderList rls) {
rls.prepo(state);
return(true);
}
}
}