|
import java.awt.*;
|
import java.awt.event.*;
|
import java.awt.image.*;
|
import java.util.Hashtable;
|
|
import javax.media.opengl.*;
|
import javax.media.opengl.glu.GLU;
|
//import jgl.*;
|
import javax.swing.JOptionPane;
|
|
import java.awt.image.RenderedImage;
|
import java.io.*;
|
import java.util.Iterator;
|
import java.util.Locale;
|
|
import javax.imageio.IIOImage;
|
import javax.imageio.ImageIO;
|
import javax.imageio.ImageWriteParam;
|
import javax.imageio.ImageWriter;
|
import javax.imageio.ImageReadParam;
|
import javax.imageio.ImageReader;
|
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
|
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageOutputStream;
|
import javax.imageio.ImageWriteParam;
|
|
//import javax.imageio.*;
|
|
import com.sun.opengl.util.*;
|
import com.sun.opengl.util.texture.*;
|
import java.io.*;
|
import java.nio.*;
|
|
import gleem.linalg.Mat4f;
|
import javax.imageio.ImageTypeSpecifier;
|
|
class CameraPane extends GLCanvas implements iCameraPane, Runnable, GLEventListener, ActionListener, MouseWheelListener, MouseMotionListener, MouseListener, KeyListener
|
{
|
static cMaterial[] materialstack = new cMaterial[65536];
|
static boolean[] selectedstack = new boolean[65536];
|
static int materialdepth = 0;
|
|
static boolean FRUSTUM = false; // still bogus true; // frustum culling
|
|
// camera change fix
|
static boolean ABORTMODE = true;
|
static boolean ABORTED = false;
|
|
static int STEP = 1;
|
|
private static BufferedImage CreateBim(byte[] bytes, int width, int height)
|
{
|
int[] pixels = new int[bytes.length/3];
|
for (int i=pixels.length; --i>=0;)
|
{
|
int i3 = i*3;
|
pixels[i] = 0xFF;
|
pixels[i] <<= 8;
|
pixels[i] |= bytes[i3+2] & 0xFF;
|
pixels[i] <<= 8;
|
pixels[i] |= bytes[i3+1] & 0xFF;
|
pixels[i] <<= 8;
|
pixels[i] |= bytes[i3] & 0xFF;
|
}
|
/*
|
int r=0,g=0,b=0,a=0;
|
for (int i=0; i<width; i++)
|
for (int j=0; j<height; j++)
|
{
|
int index = j*width+i;
|
int p = pixels[index];
|
a = ((p>>24) & 0xFF);
|
r = ((p>>16) & 0xFF);
|
g = ((p>>8) & 0xFF);
|
b = (p & 0xFF);
|
pixels[index] = (a<<24) | (b<<16) | (g<<8) | r;
|
}
|
/**/
|
BufferedImage rendImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
|
rendImage.setRGB(0,0,width,height,pixels,width*(height-1),-width);
|
return rendImage;
|
}
|
|
/*static*/ private boolean CULLFACE = false; // true;
|
/*static*/ boolean NEAREST = false; // true;
|
/*static*/ boolean WIREFRAME = false; // true;
|
|
static boolean UVWRAP = true; // false;
|
static boolean SHADOWCULLFACE = false; // true;
|
/*static*/ int ANTIALIAS = 0;
|
static int CURRENTANTIALIAS = 0; // 1;
|
/*static*/ boolean RENDERSHADOW = true;
|
/*static*/ int RENDERPROGRAM = 2; // 0 == none, 1 == fast, 2 == normal
|
|
boolean DISPLAYTEXT = false;
|
//boolean REDUCETEXTURE = true;
|
boolean CACHETEXTURE = true;
|
boolean CLEANCACHE = false; // true;
|
boolean MIPMAP = false; // true; // never works...
|
boolean COMPRESSTEXTURE = false;
|
boolean KOMPACTTEXTURE = false; // true;
|
boolean RESIZETEXTURE = false;
|
boolean SAVETEXTURE = false;
|
int PixelThreshold = 16; // 256;
|
boolean FROZEN = false;
|
static boolean ROTATECAMERA = false;
|
//private Mat4f cameraTransform = new Mat4f();
|
//private Mat4f cameraInverseTransform = new Mat4f();
|
//private Mat4f spotlightTransform = new Mat4f();
|
//private Mat4f spotlightInverseTransform = new Mat4f();
|
static GLContext glcontext = null;
|
/*static*/ com.sun.opengl.util.texture.Texture cubemap; // Either custom or rgb
|
/*static*/ com.sun.opengl.util.texture.Texture cubemapcustom;
|
/*static*/ com.sun.opengl.util.texture.Texture cubemaprgb;
|
boolean transformMode;
|
|
boolean reverseUP = false;
|
static boolean frozen = false;
|
boolean enablebackspace = false; // patch for back buffer refresh
|
|
static boolean textureon = true;
|
static boolean LOCALTRANSFORM = false;
|
static boolean FULLSCREEN = false;
|
static boolean SUPPORT = true;
|
static boolean INERTIA = true;
|
static boolean FAST = false;
|
static boolean SLOWPOSE = false;
|
static boolean FOOTCONTACT = true;
|
|
static int tickcount = 0; // slow pose issue
|
|
static boolean BUTTONLESSWHEEL = false;
|
static boolean ZOOMBOXMODE = false;
|
static boolean BOXMODE = false;
|
static boolean IMAGEFLIP = false;
|
static boolean SMOOTHFOCUS = false;
|
static boolean SPEAKERMOCAP = true; // jan 2014 false;
|
static boolean SPEAKERCAMERA = false;
|
static boolean SPEAKERFOCUS = false;
|
static boolean REFUSEMODE = false;
|
static boolean HOLD = false;
|
static boolean TRACK = false;
|
static boolean TRACKONCE = false; // do trackon then trackoff
|
static boolean SHADOWTRACK = false;
|
static boolean OEIL = true;
|
static boolean OEILONCE = false; // do oeilon then oeiloff
|
static boolean LOOKAT = true;
|
static boolean SWITCH = true; // false;
|
static boolean HANDLES = false; // selection doesn't work!!
|
static boolean PAINTMODE = false;
|
|
static GLPbuffer selectbuffer;
|
static GLPbuffer shadowbuffer;
|
static GLPbuffer antialiasbuffer;
|
static GLPbuffer occlusionbuffer;
|
static private int SELECT_SIZE = 1024;
|
static private int TEX_SIZE = 1024;
|
static private int TEXT_WIDTH = 128;
|
static private int TEXT_HEIGHT = 64;
|
static private int SHADOW_SIZE = 2048;
|
static private int OCCLUSION_SIZE = 32;
|
static private int HISTOGRAM_SIZE = 256;
|
// Programs
|
static int[] fragmentProgram = new int[1024]; // /*shader |*/ aniso | light
|
static int[] vertexProgram = new int[4]; // pass | projection
|
static GLCapabilities defaultcaps = new GLCapabilities();
|
|
|
// OPTIONS
|
boolean Skinshader = false; // true;
|
boolean cameraLight = false;
|
boolean UVdebug = false;
|
boolean Udebug = false;
|
boolean Vdebug = false;
|
boolean NORMALdebug = false;
|
static boolean doublesided = true; // false; // reversed normals are awful for conformance
|
boolean anisotropy = true;
|
boolean softshadow = true; // slower but better false;
|
boolean opacityhalo = false; // reverse the halo effect (e.g. glass)
|
|
boolean macromode = false;
|
|
static
|
{
|
//defaultcaps.setDoubleBuffered(false);
|
defaultcaps.setAccumRedBits(16);
|
defaultcaps.setAccumGreenBits(16);
|
defaultcaps.setAccumBlueBits(16);
|
defaultcaps.setAccumAlphaBits(16);
|
}
|
|
private File defaultDirectory = javax.swing.filechooser.FileSystemView.getFileSystemView().getDefaultDirectory();
|
|
public com.sun.opengl.util.texture.Texture LoadSkybox(String name, String ext, boolean mipmap) throws GLException
|
{
|
try
|
{
|
return LoadCubemap(getClass().getClassLoader(), name, ext, mipmap);
|
} catch (IOException e)
|
{
|
System.out.println("NAME = " + name);
|
e.printStackTrace(); // throw new RuntimeException(e);
|
return null;
|
}
|
}
|
|
void SetAsGLRenderer(boolean b)
|
{
|
isRenderer = b;
|
Globals.theRenderer = this;
|
}
|
|
CameraPane(Object3D o, Camera cam, boolean withcontext)
|
{
|
super(defaultcaps, null, withcontext?glcontext:null, null);
|
|
//System.out.println("AMERICA AREA = " + (9458886 + 9210755 + 8480395 + 2736391 + 1943018 + 1289475 + 1141569 + 1069350 + 911559 + 721229 + 395886 + 377972 + 246700 + 211156 + 173985 + 141133 + 118279 + 112079 + 108523));
|
glcontext = getContext();
|
|
cameras = new Camera[2];
|
targetLookAts = new cVector[2];
|
|
SetCamera(cam, true);
|
|
// Warning: not used.
|
//SetLight(new Camera(new cVector(15, 10, -20)));
|
|
object = o;
|
|
setBackground(Color.white);
|
|
addKeyListener(this);
|
addMouseListener(this);
|
addMouseMotionListener(this);
|
addMouseWheelListener(this);
|
//System.out.println("addGLEventListener: " + this);
|
addGLEventListener(this);
|
|
// pingthread.start(); // may 2013
|
}
|
|
static boolean AntialiasingEnabled()
|
{
|
return CURRENTANTIALIAS > 0;
|
}
|
|
/// INTERFACE
|
|
public javax.media.opengl.GL GetGL0()
|
{
|
return null;
|
}
|
|
public int GenList()
|
{
|
javax.media.opengl.GL gl = GetGL();
|
return gl.glGenLists(1);
|
}
|
|
public void NewList(int id)
|
{
|
javax.media.opengl.GL gl = GetGL();
|
gl.glNewList(id, gl.GL_COMPILE); //_AND_EXECUTE);
|
}
|
|
public void CallList(int id)
|
{
|
javax.media.opengl.GL gl = GetGL();
|
gl.glCallList(id);
|
}
|
|
public void EndList()
|
{
|
javax.media.opengl.GL gl = GetGL();
|
gl.glEndList();
|
}
|
|
public boolean IsBoxMode()
|
{
|
return BOXMODE;
|
}
|
|
public boolean IsZoomBoxMode()
|
{
|
return ZOOMBOXMODE;
|
}
|
|
public void ClearDepth()
|
{
|
GetGL().glClear(GetGL().GL_DEPTH_BUFFER_BIT);
|
}
|
|
public void DepthTest(boolean depthtest)
|
{
|
if (depthtest)
|
GetGL().glDepthFunc(GL.GL_LEQUAL);
|
else
|
GetGL().glDepthFunc(GL.GL_ALWAYS);
|
}
|
|
public void DepthWrite(boolean depthwrite)
|
{
|
if (depthwrite)
|
GetGL().glDepthMask(true);
|
else
|
GetGL().glDepthMask(false);
|
}
|
|
public void BackFaceCull(boolean bfc)
|
{
|
if (bfc)
|
GetGL().glEnable(GetGL().GL_CULL_FACE);
|
else
|
GetGL().glDisable(GetGL().GL_CULL_FACE);
|
}
|
|
public boolean BackFaceCullMode()
|
{
|
return this.CULLFACE;
|
}
|
|
public boolean IsAmbientOcclusionOn()
|
{
|
return this.ambientOcclusion;
|
}
|
|
public boolean IsDebugSelection()
|
{
|
return DEBUG_SELECTION;
|
}
|
|
public boolean IsFrozen()
|
{
|
boolean selectmode = this.DrawMode() == SELECTION || this.IsDebugSelection();
|
|
return !selectmode && cameracount == 0; // != 0;
|
}
|
|
// Currently in Globals
|
public int DrawMode()
|
{
|
return Globals.DrawMode();
|
}
|
|
public Camera EyeCamera()
|
{
|
return eyeCamera;
|
}
|
|
public Camera LightCamera()
|
{
|
return lightCamera;
|
}
|
|
public Camera ManipCamera()
|
{
|
return manipCamera;
|
}
|
|
public Camera RenderCamera()
|
{
|
return renderCamera;
|
}
|
|
public Camera[] Cameras()
|
{
|
return cameras;
|
}
|
|
public void PushMaterial(Object3D obj, boolean selected)
|
{
|
CameraPane display = this;
|
javax.media.opengl.GL gl = display.GetGL();
|
cMaterial material = obj.material;
|
|
if (material != null)
|
{
|
materialstack[materialdepth] = material;
|
selectedstack[materialdepth] = selected;
|
cStatic.objectstack[materialdepth++] = obj;
|
//System.out.println("material " + material);
|
//Applet3D.tracein(this, selected);
|
//display.vector2buffer = obj.projectedVertices;
|
if (obj instanceof Camera)
|
{
|
display.options1[0] = material.shift;
|
//System.out.println("shift " + material.shift);
|
display.options1[1] = material.lightarea;
|
display.options1[2] = material.shadowbias;
|
display.options1[3] = material.aniso;
|
display.options1[4] = material.anisoV;
|
// System.out.println("display.options1[0] " + display.options1[0]);
|
// System.out.println("display.options1[1] " + display.options1[1]);
|
// System.out.println("display.options1[2] " + display.options1[2]);
|
// System.out.println("display.options1[3] " + display.options1[3]);
|
// System.out.println("display.options1[4] " + display.options1[4]);
|
display.options2[0] = material.opacity;
|
display.options2[1] = material.diffuse;
|
display.options2[2] = material.factor;
|
// System.out.println("display.options2[0] " + display.options2[0]);
|
// System.out.println("display.options2[1] " + display.options2[1]);
|
// System.out.println("display.options2[2] " + display.options2[2]);
|
|
cColor.HSBtoRGB(material.color, material.modulation, 1, display.options3);
|
// System.out.println("display.options3[0] " + display.options3[0]);
|
// System.out.println("display.options3[1] " + display.options3[1]);
|
// System.out.println("display.options3[2] " + display.options3[2]);
|
display.options4[0] = material.cameralight/0.2f;
|
display.options4[1] = material.subsurface;
|
display.options4[2] = material.sheen;
|
// System.out.println("display.options4[0] " + display.options4[0]);
|
// System.out.println("display.options4[1] " + display.options4[1]);
|
// System.out.println("display.options4[2] " + display.options4[2]);
|
|
// if (display.CURRENTANTIALIAS > 0)
|
// display.options3[3] /= 4;
|
|
/*
|
System.out.println("Focus = " + display.options1[0]);
|
System.out.println("Aperture = " + display.options1[1]);
|
System.out.println("ShadowBlur = " + display.options1[2]);
|
System.out.println("Antialiasing = " + display.options1[3]);
|
System.out.println("Fog = " + display.options2[0]);
|
System.out.println("Intensity = " + display.options2[1]);
|
System.out.println("Elevation = " + display.options2[2]);
|
/**/
|
} else
|
{
|
DrawMaterial(material, selected, obj.projectedVertices);
|
}
|
} else
|
{
|
if (selected && CameraPane.flash)
|
{
|
display.modelParams4[1] = 100;
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 4, display.modelParams4, 0);
|
}
|
}
|
}
|
|
public void PushMaterial2(Object3D obj, boolean selected)
|
{
|
CameraPane display = this;
|
cMaterial material = obj.material;
|
|
if (material != null)
|
{
|
materialstack[materialdepth] = material;
|
selectedstack[materialdepth] = selected;
|
cStatic.objectstack[materialdepth++] = obj;
|
//System.out.println("material " + material);
|
//Applet3D.tracein("selected ", selected);
|
//display.vector2buffer = obj.projectedVertices;
|
display.DrawMaterial(material, selected, obj.projectedVertices);
|
}
|
}
|
|
public void PopMaterial(Object3D obj, boolean selected)
|
{
|
CameraPane display = this;
|
javax.media.opengl.GL gl = display.GetGL();
|
cMaterial material = obj.material;
|
|
//if (parent != null && parent.GetMaterial() != null)
|
// parent.GetMaterial().Draw(display, parent.IsSelected(this));
|
if (material != null)
|
{
|
materialdepth -= 1;
|
if (materialdepth > 0)
|
{
|
//display.vector2buffer = cStatic.objectstack[materialdepth - 1].projectedVertices;
|
display.DrawMaterial(materialstack[materialdepth - 1], selectedstack[materialdepth - 1], cStatic.objectstack[materialdepth - 1].projectedVertices);
|
}
|
//Applet3D.traceout("selected ", (stackdepth>0)?selectedstack[stackdepth-1]:"???");
|
} else if (selected && CameraPane.flash && obj.GetMaterial() != null)
|
{
|
display.modelParams4[1] = obj.GetMaterial().cameralight;
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 4, display.modelParams4, 0);
|
}
|
}
|
|
public void PopMaterial2(Object3D obj)
|
{
|
CameraPane display = this;
|
cMaterial material = obj.material;
|
|
if (material != null)
|
{
|
materialdepth -= 1;
|
if (materialdepth > 0)
|
{
|
//display.vector2buffer = cStatic.objectstack[materialdepth - 1].projectedVertices;
|
display.DrawMaterial(materialstack[materialdepth - 1], selectedstack[materialdepth - 1], cStatic.objectstack[materialdepth - 1].projectedVertices);
|
}
|
//Applet3D.traceout("selected ", (stackdepth>0)?selectedstack[stackdepth-1]:"???");
|
//else
|
//material.Draw(display, false);
|
}
|
}
|
|
public void DrawFace(Object3D obj, Vertex pv, Vertex qv, Vertex rv, Face face)
|
{
|
CameraPane display = this;
|
|
if (pv.y == -10000 ||
|
qv.y == -10000 ||
|
rv.y == -10000)
|
return;
|
|
// float b = f.nbiterations & 1;
|
// float g = (f.nbiterations>>1) & 1;
|
// float r = (f.nbiterations>>2) & 1;
|
//
|
// //if (f.weight == 10000)
|
// //{
|
// // r = 1; g = b = 0;
|
// //}
|
// //else
|
// //{
|
// // assert(f.weight < 10000);
|
// r = g = b = (float)bRep.FaceWeight(f)*100;
|
// if (r<0)
|
// assert(r>=0);
|
// //}
|
|
javax.media.opengl.GL gl = display.GetGL();
|
|
boolean selectmode = display.DrawMode() == display.SELECTION || display.IsDebugSelection();
|
|
//System.out.println("p = " + pv + "; q = " + qv + "; r = " + rv);
|
if (!selectmode) // display.drawMode != display.SELECTION) // && display.drawMode != display.SHADOW) // (attributes & FILL) != 0)
|
{
|
//gl.glBegin(gl.GL_TRIANGLES);
|
boolean hasnorm = pv.norm != null && (pv.norm.x != 0 || pv.norm.y != 0 || pv.norm.z != 0)
|
// TEST LIVE NORMALS && !obj.dontselect
|
;
|
if (!hasnorm)
|
{
|
// System.out.println("Mesh normal");
|
LA.vecSub(pv/*.pos*/, qv/*.pos*/, obj.v0);
|
LA.vecSub(pv/*.pos*/, rv/*.pos*/, obj.v1);
|
LA.vecCross(obj.v0, obj.v1, obj.v2);
|
LA.vecNormalize(obj.v2);
|
|
SetGLNormal(gl, (float) obj.v2.x, (float) obj.v2.y, (float) obj.v2.z);
|
}
|
|
// P
|
float x = (float)pv.x;
|
float y = (float)pv.y;
|
float z = (float)pv.z;
|
|
if (hasnorm)
|
{
|
// if (!pv.norm.normalized())
|
// assert(pv.norm.normalized());
|
|
//System.out.println("normalp = " + pv.norm.x + ", " + pv.norm.y + ", " + pv.norm.z);
|
float nx = (float)pv.norm.x;
|
float ny = (float)pv.norm.y;
|
float nz = (float)pv.norm.z;
|
|
x += nx * obj.NORMALPUSH;
|
y += ny * obj.NORMALPUSH;
|
z += nz * obj.NORMALPUSH;
|
|
SetGLNormal(gl, nx, ny, nz);
|
}
|
gl.glColor4f(pv.AO, pv.AO, pv.AO, 1);
|
SetColor(obj, pv);
|
//gl.glColor4f(r, g, b, 1);
|
//gl.glColor4f(pv.boundary, pv.boundary, pv.boundary, 1);
|
if (obj.flipV)
|
gl.glTexCoord2f((float) pv.s, 1-(float) pv.t);
|
else
|
gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
//System.out.println("vertexp = " + pv.x + ", " + pv.y + ", " + pv.z);
|
|
gl.glVertex3f(x, y, z);
|
|
// Q
|
x = (float)qv.x;
|
y = (float)qv.y;
|
z = (float)qv.z;
|
|
// Print(pv);
|
if (hasnorm)
|
{
|
// assert(qv.norm.normalized());
|
//System.out.println("normalq = " + qv.norm.x + ", " + qv.norm.y + ", " + qv.norm.z);
|
float nx = (float)qv.norm.x;
|
float ny = (float)qv.norm.y;
|
float nz = (float)qv.norm.z;
|
|
x += nx * obj.NORMALPUSH;
|
y += ny * obj.NORMALPUSH;
|
z += nz * obj.NORMALPUSH;
|
|
SetGLNormal(gl, nx, ny, nz);
|
}
|
//System.out.println("vertexq = " + qv.s + ", " + qv.t);
|
// boolean locked = false;
|
// float eps = 0.1f;
|
// boolean wrap = CameraPane.UVWRAP; // true; // UV WRAP TEXTURE ISSUE: true = artifacts, false = nice
|
|
// int dot = 0; //*/ (int)f.dot;
|
|
// if ((dot&1) == 0)
|
// dot |= (Math.abs(qv.s - pv.s) < eps && Math.abs(qv.t - pv.t) < eps) ? 3 : 1;
|
|
// if (wrap || (dot&2) != 0) // Math.abs(qv.s - pv.s) < eps && Math.abs(qv.t - pv.t) < eps)
|
if (obj.flipV)
|
gl.glTexCoord2f((float) qv.s, 1-(float) qv.t);
|
else
|
gl.glTexCoord2f((float) qv.s, (float) qv.t);
|
// else
|
// {
|
// locked = true;
|
// gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
// }
|
gl.glColor4f(qv.AO, qv.AO, qv.AO, 1);
|
SetColor(obj, qv);
|
|
gl.glVertex3f(x, y, z);
|
//gl.glColor4f(r, g, b, 1);
|
//gl.glColor4f(qv.boundary, qv.boundary, qv.boundary, 1);
|
//System.out.println("vertexq = " + qv.x + ", " + qv.y + ", " + qv.z);
|
// Print(qv);
|
|
// R
|
x = (float)rv.x;
|
y = (float)rv.y;
|
z = (float)rv.z;
|
|
if (hasnorm)
|
{
|
// assert(rv.norm.normalized());
|
//System.out.println("normalr = " + rv.norm.x + ", " + rv.norm.y + ", " + rv.norm.z);
|
float nx = (float)rv.norm.x;
|
float ny = (float)rv.norm.y;
|
float nz = (float)rv.norm.z;
|
|
x += nx * obj.NORMALPUSH;
|
y += ny * obj.NORMALPUSH;
|
z += nz * obj.NORMALPUSH;
|
|
SetGLNormal(gl, nx, ny, nz);
|
}
|
|
// if ((dot&4) == 0)
|
// dot |= (Math.abs(rv.s - pv.s) < eps && Math.abs(rv.t - pv.t) < eps) ? 12 : 4;
|
|
// if (wrap || !locked && (dot&8) != 0)
|
if (obj.flipV)
|
gl.glTexCoord2f((float) rv.s, 1-(float) rv.t);
|
else
|
gl.glTexCoord2f((float) rv.s, (float) rv.t);
|
// else
|
// gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
|
// f.dot = dot;
|
|
gl.glColor4f(rv.AO, rv.AO, rv.AO, 1);
|
SetColor(obj, rv);
|
//gl.glColor4f(r, g, b, 1);
|
//gl.glColor4f(rv.boundary, rv.boundary, rv.boundary, 1);
|
//System.out.println("vertexr = " + rv.x + ", " + rv.y + ", " + rv.z);
|
gl.glVertex3f(x, y, z);
|
// Print(rv);
|
//gl.glEnd();
|
}
|
else
|
{
|
gl.glVertex3f((float) pv.x, (float) pv.y, (float) pv.z);
|
gl.glVertex3f((float) qv.x, (float) qv.y, (float) qv.z);
|
gl.glVertex3f((float) rv.x, (float) rv.y, (float) rv.z);
|
|
}
|
|
if (false) // (attributes & WIREFRAME) != 0)
|
{
|
gl.glDisable(gl.GL_LIGHTING);
|
|
gl.glBegin(gl.GL_LINE_LOOP);
|
gl.glVertex3d(pv./*pos.*/x, pv./*pos.*/y, pv./*pos.*/z);
|
gl.glVertex3d(qv./*pos.*/x, qv./*pos.*/y, qv./*pos.*/z);
|
gl.glVertex3d(rv./*pos.*/x, rv./*pos.*/y, rv./*pos.*/z);
|
gl.glEnd();
|
|
gl.glEnable(gl.GL_LIGHTING);
|
}
|
}
|
|
/**
|
* <code>draw</code> renders a <code>TriMesh</code> object including
|
* it's normals, colors, textures and vertices.
|
*
|
* @see Renderer#draw(TriMesh)
|
* @param tris
|
* the mesh to render.
|
*/
|
public void DrawParticles(TriMesh geo, Object3D shape, boolean selected, boolean rotate) // TriMesh tris)
|
{
|
CameraPane display = this;
|
|
float r = display.modelParams0[0];
|
float g = display.modelParams0[1];
|
float b = display.modelParams0[2];
|
float opacity = display.modelParams5[1];
|
|
//final GL gl = GLU.getCurrentGL();
|
GL gl = display.GetGL(); // getGL();
|
|
FloatBuffer vertBuf = geo.vertBuf;
|
|
int v = vertBuf.capacity();
|
|
int count = 0;
|
|
boolean cf = gl.glIsEnabled(gl.GL_CULL_FACE);
|
gl.glEnable(gl.GL_CULL_FACE);
|
// gl.glScalef(1.0f/1024,1.0f/1024,1.0f/1024);
|
for (int i=0; i<v/3; i++)
|
{
|
int index3 = i*3;
|
|
if (geo.sizeBuf.get(index3+1) == 0)
|
continue;
|
|
count++;
|
|
int index4 = i*4;
|
|
float tx = vertBuf.get(index3);
|
float ty = vertBuf.get(index3+1);
|
float tz = vertBuf.get(index3+2);
|
|
// if (tx == 0 && ty == 0 && tz == 0)
|
// continue;
|
|
gl.glMatrixMode(gl.GL_TEXTURE);
|
gl.glPushMatrix();
|
|
float[] texmat = geo.texmat;
|
texmat[12] = texmat[13] = texmat[14] = i;
|
|
gl.glMultMatrixf(texmat, 0);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glPushMatrix();
|
|
gl.glTranslatef(tx,ty,tz);
|
|
if (rotate)
|
gl.glRotatef(i, 0, 1, 0);
|
|
float size = geo.sizeBuf.get(index3) / 100;
|
gl.glScalef(size,size,size);
|
|
float cr = geo.colorBuf.get(index4);
|
float cg = geo.colorBuf.get(index4+1);
|
float cb = geo.colorBuf.get(index4+2);
|
float ca = geo.colorBuf.get(index4+3);
|
|
display.modelParams0[0] = r * cr;
|
display.modelParams0[1] = g * cg;
|
display.modelParams0[2] = b * cb;
|
|
display.modelParams5[1] = opacity * ca;
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 0, display.modelParams0, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 5, display.modelParams5, 0);
|
|
RandomNode.globalseed = (int)geo.sizeBuf.get(index3+2); // i;
|
RandomNode.globalseed2 = RandomNode.globalseed;
|
|
// gl.glColor4f(cr,cg,cb,ca);
|
// gl.glScalef(1024/16,1024/16,1024/16);
|
shape.Draw/*Node*/(display,null,selected,false); // blocked
|
// gl.glScalef(16.0f/1024,16.0f/1024,16.0f/1024);
|
//gl.glTranslatef(-tx,-ty,-tz);
|
gl.glPopMatrix();
|
|
gl.glMatrixMode(gl.GL_TEXTURE);
|
gl.glPopMatrix();
|
}
|
// gl.glScalef(1024,1024,1024);
|
if (!cf)
|
gl.glDisable(gl.GL_CULL_FACE);
|
|
display.modelParams0[0] = r;
|
display.modelParams0[1] = g;
|
display.modelParams0[2] = b;
|
|
display.modelParams5[1] = opacity;
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 0, display.modelParams0, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 5, display.modelParams5, 0);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
|
// System.err.println("total = " + v/3 + "; displayed = " + count);
|
if (true)
|
return;
|
|
//// if (!tris.predraw(this))
|
//// {
|
//// return;
|
//// }
|
//// if (Debug.stats)
|
//// {
|
//// StatCollector.addStat(StatType.STAT_TRIANGLE_COUNT, tris.getTriangleCount());
|
//// StatCollector.addStat(StatType.STAT_VERTEX_COUNT, tris.getVertexCount());
|
//// StatCollector.addStat(StatType.STAT_GEOM_COUNT, 1);
|
//// }
|
////
|
//// if (tris.getDisplayListID() != -1)
|
//// {
|
//// renderDisplayList(tris);
|
//// return;
|
//// }
|
////
|
//// if (!generatingDisplayList)
|
//// {
|
//// applyStates(tris.states, tris);
|
//// }
|
//// if (Debug.stats)
|
//// {
|
//// StatCollector.startStat(StatType.STAT_RENDER_TIMER);
|
//// }
|
//// boolean transformed = doTransforms(tris);
|
//
|
// int glMode = GL.GL_TRIANGLES;
|
// switch (getMode())
|
// {
|
// case Triangles:
|
// glMode = GL.GL_TRIANGLES;
|
// break;
|
// case Strip:
|
// glMode = GL.GL_TRIANGLE_STRIP;
|
// break;
|
// case Fan:
|
// glMode = GL.GL_TRIANGLE_FAN;
|
// break;
|
// }
|
//
|
// if (!predrawGeometry(gl))
|
// {
|
// // make sure only the necessary indices are sent through on old
|
// // cards.
|
// IntBuffer indices = this.getIndexBuffer();
|
// if (indices == null)
|
// {
|
// logger.severe("missing indices on geometry object: " + this.toString());
|
// } else
|
// {
|
// indices.rewind();
|
// indices.limit(this.getMaxIndex());
|
//
|
// gl.glDrawElements(glMode, indices.limit(), GL.GL_UNSIGNED_INT, indices); // TODO Check <count> and assumed <type> of GL_UNSIGNED_INT
|
//
|
// indices.clear();
|
// }
|
// } else
|
// {
|
// gl.glDrawElements(glMode, this.getIndexBuffer().limit(),
|
// GL.GL_UNSIGNED_INT, 0);
|
// }
|
//
|
//// postdrawGeometry(tris);
|
//// if (transformed)
|
//// {
|
//// undoTransforms(tris);
|
//// }
|
////
|
//// if (Debug.stats)
|
//// {
|
//// StatCollector.endStat(StatType.STAT_RENDER_TIMER);
|
//// }
|
//// tris.postdraw(this);
|
}
|
|
static Camera localAOcamera = new Camera();
|
static cVector from = new cVector();
|
static cVector to = new cVector();
|
|
public void PrepOcclusion(BoundaryRep br, double[][] transform)
|
{
|
CameraPane cp = this;
|
|
Camera keep = cp.RenderCamera();
|
cp.renderCamera = localAOcamera;
|
|
if (br.trimmed)
|
{
|
float[] colors = new float[br.positions.length / 3];
|
|
int i3 = 0;
|
for (int i = 0; i < br.positions.length / 3; i++, i3 += 3)
|
{
|
if (br.normals[i3] == 0 && br.normals[i3+1] == 0 && br.normals[i3+2] == 0)
|
continue;
|
|
from.set(br.positions[i3], br.positions[i3 + 1], br.positions[i3 + 2]);
|
to.set(br.positions[i3] + br.normals[i3],
|
br.positions[i3 + 1] + br.normals[i3 + 1],
|
br.positions[i3 + 2] + br.normals[i3 + 2]);
|
LA.xformPos(from, transform, from);
|
LA.xformPos(to, transform, to); // RIGID ONLY
|
localAOcamera.setAim(from, to);
|
|
CameraPane.occlusionbuffer.display();
|
|
if (CameraPane.DEBUG_OCCLUSION)
|
cp.display(); // debug
|
|
colors[i] = cp.vertexOcclusion.r;
|
//colors[i3 + 1] = cp.vertexOcclusion.g;
|
//colors[i3 + 2] = cp.vertexOcclusion.b;
|
|
if ((i % 100) == 0 && i != 0)
|
{
|
Globals.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
|
//System.out.println("Color = " + cp.vertexOcclusion.r + ", " + cp.vertexOcclusion.g + ", " + cp.vertexOcclusion.b + "; " + (int)(100.0*i/(positions.length/3)) + "% done");
|
System.out.println((int) (100.0 * i / (br.positions.length / 3)) + "% (" + i + " of " + (br.positions.length / 3) + ")");
|
}
|
}
|
|
br.colors = colors;
|
}
|
else
|
{
|
for (int i = 0; i < br.VertexCount(); i++)
|
{
|
Vertex v = br.GetVertex(i);
|
|
if (v.norm == null || v.norm.x == 0 && v.norm.y == 0 && v.norm.z == 0)
|
continue;
|
|
from.set(v.x, v.y, v.z);
|
to.set(v.x+v.norm.x, v.y+v.norm.y, v.z+v.norm.z);
|
LA.xformPos(from, transform, from);
|
LA.xformPos(to, transform, to); // RIGID ONLY
|
localAOcamera.setAim(from, to);
|
|
CameraPane.occlusionbuffer.display();
|
|
if (CameraPane.DEBUG_OCCLUSION)
|
cp.display(); // debug
|
|
v.AO = cp.vertexOcclusion.r;
|
|
if ((i % 100) == 0 && i != 0)
|
{
|
Globals.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
|
//System.out.println("Color = " + cp.vertexOcclusion.r + ", " + cp.vertexOcclusion.g + ", " + cp.vertexOcclusion.b + "; " + (int)(100.0*i/(positions.length/3)) + "% done");
|
System.out.println((int) (100.0 * i / br.VertexCount()) + "% (" + i + " of " + br.VertexCount() + ")");
|
}
|
}
|
}
|
|
//System.out.println("done.");
|
|
cp.renderCamera = keep;
|
}
|
|
void DrawPointFLow(PointFlow pointFlow, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
CameraPane display = this;
|
pointFlow.CreateHT();
|
|
float r = display.modelParams0[0];
|
float g = display.modelParams0[1];
|
float b = display.modelParams0[2];
|
float opacity = display.modelParams5[1];
|
|
//final GL gl = GLU.getCurrentGL();
|
GL gl = display.GetGL(); // getGL();
|
|
int s = pointFlow.points.size();
|
|
boolean cf = gl.glIsEnabled(gl.GL_CULL_FACE);
|
gl.glEnable(gl.GL_CULL_FACE);
|
|
for (int i=s; --i>=0;)
|
//for (int i=0; i<s; i++)
|
{
|
cVector v = pointFlow.points.get(i);
|
|
double mindist = Double.MAX_VALUE;
|
|
double size = pointFlow.minimumSize;
|
|
double distancenext = 0;
|
|
if (i > 0)
|
{
|
cVector w = pointFlow.points.get(i-1);
|
|
double dist = w.distance(v);
|
|
distancenext = dist;
|
|
if (mindist > dist)
|
{
|
mindist = dist;
|
size = mindist*pointFlow.resizefactor;
|
}
|
}
|
|
if (i < s-1)
|
{
|
cVector w = pointFlow.points.get(i+1);
|
|
double dist = w.distance(v);
|
|
if (mindist > dist)
|
{
|
mindist = dist;
|
size = mindist*pointFlow.resizefactor;
|
}
|
}
|
|
if (size < pointFlow.minimumSize)
|
size = pointFlow.minimumSize;
|
if (size > pointFlow.maximumSize)
|
size = pointFlow.maximumSize;
|
|
double tx = v.x;
|
double ty = v.y;
|
double tz = v.z;
|
|
// if (tx == 0 && ty == 0 && tz == 0)
|
// continue;
|
|
gl.glMatrixMode(gl.GL_TEXTURE);
|
gl.glPushMatrix();
|
pointFlow.texmat[12] = pointFlow.texmat[13] = pointFlow.texmat[14] = i;
|
|
gl.glMultMatrixf(pointFlow.texmat, 0);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glPushMatrix();
|
|
gl.glTranslated(tx,ty,tz);
|
|
gl.glScaled(size,size,size);
|
|
// float cr = colorBuf.get(index4);
|
// float cg = colorBuf.get(index4+1);
|
// float cb = colorBuf.get(index4+2);
|
// float ca = colorBuf.get(index4+3);
|
//
|
// display.modelParams0[0] = r * cr;
|
// display.modelParams0[1] = g * cg;
|
// display.modelParams0[2] = b * cb;
|
//
|
// display.modelParams5[1] = opacity * ca;
|
//
|
// gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 0, display.modelParams0, 0);
|
// gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 5, display.modelParams5, 0);
|
//
|
// RandomNode.globalseed = (int)sizeBuf.get(index3+2); // i;
|
// RandomNode.globalseed2 = RandomNode.globalseed;
|
//
|
//// gl.glColor4f(cr,cg,cb,ca);
|
// // gl.glScalef(1024/16,1024/16,1024/16);
|
pointFlow.geo.Draw/*Node*/(display,null,selected, blocked);
|
|
gl.glPopMatrix();
|
|
double step = size/4; //
|
|
if (i == 0 || size == 0 || distancenext > 8*size || distancenext < step)
|
continue;
|
|
int nbsteps = (int)(distancenext/step);
|
|
step = distancenext/nbsteps;
|
|
cVector next = pointFlow.points.get(i-1);
|
|
tmp.set(next);
|
tmp.sub(v);
|
tmp.normalize();
|
tmp.mul(step);
|
|
// calculate next size
|
mindist = Double.MAX_VALUE;
|
|
double nextsize = pointFlow.minimumSize;
|
|
if (i > 1)
|
{
|
cVector w = pointFlow.points.get(i-2);
|
|
double dist = w.distance(next);
|
|
if (mindist > dist)
|
{
|
mindist = dist;
|
nextsize = mindist*pointFlow.resizefactor;
|
}
|
}
|
|
double dist = v.distance(next);
|
|
if (mindist > dist)
|
{
|
mindist = dist;
|
nextsize = mindist*pointFlow.resizefactor;
|
}
|
|
if (nextsize < pointFlow.minimumSize)
|
nextsize = pointFlow.minimumSize;
|
if (nextsize > pointFlow.maximumSize)
|
nextsize = pointFlow.maximumSize;
|
//
|
|
double count = 0;
|
|
while (distancenext > 0.000000001) // step
|
{
|
gl.glPushMatrix();
|
|
gl.glTranslated(tx + tmp.x*count, ty + tmp.y*count, tz + tmp.z*count);
|
|
double K = count/nbsteps;
|
|
double intersize = K*nextsize + (1-K)*size;
|
|
gl.glScaled(intersize,intersize,intersize);
|
|
pointFlow.geo.Draw/*Node*/(display,null,selected,blocked);
|
|
count++;
|
|
distancenext -= step;
|
|
gl.glPopMatrix();
|
}
|
|
if (count != nbsteps)
|
assert(count == nbsteps);
|
|
// gl.glScalef(16.0f/1024,16.0f/1024,16.0f/1024);
|
//gl.glTranslatef(-tx,-ty,-tz);
|
|
gl.glMatrixMode(gl.GL_TEXTURE);
|
gl.glPopMatrix();
|
}
|
|
if (!cf)
|
gl.glDisable(gl.GL_CULL_FACE);
|
|
// display.modelParams0[0] = r;
|
// display.modelParams0[1] = g;
|
// display.modelParams0[2] = b;
|
//
|
// display.modelParams5[1] = opacity;
|
//
|
// gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 0, display.modelParams0, 0);
|
// gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 5, display.modelParams5, 0);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
}
|
|
public void DrawBox(cVector min, cVector max)
|
{
|
javax.media.opengl.GL gl = GetGL();
|
gl.glBegin(gl.GL_LINES);
|
|
gl.glVertex3d(min.x, min.y, min.z);
|
gl.glVertex3d(min.x, min.y, max.z);
|
gl.glVertex3d(min.x, min.y, min.z);
|
gl.glVertex3d(min.x, max.y, min.z);
|
gl.glVertex3d(min.x, min.y, min.z);
|
gl.glVertex3d(max.x, min.y, min.z);
|
|
gl.glVertex3d(max.x, max.y, max.z);
|
gl.glVertex3d(min.x, max.y, max.z);
|
gl.glVertex3d(max.x, max.y, max.z);
|
gl.glVertex3d(max.x, min.y, max.z);
|
gl.glVertex3d(max.x, max.y, max.z);
|
gl.glVertex3d(max.x, max.y, min.z);
|
|
gl.glEnd();
|
}
|
|
public void DrawGeometry(BoundaryRep bRep, boolean flipV, boolean selectmode)
|
{
|
int[] strips = bRep.getRawIndices();
|
|
javax.media.opengl.GL gl = GetGL();
|
|
// TRIANGLE STRIP ARRAY
|
if (bRep.trimmed)
|
{
|
float[] v = bRep.getRawVertices();
|
float[] n = bRep.getRawNormals();
|
float[] c = bRep.getRawColors();
|
float[] uv = bRep.getRawUVMap();
|
|
int count2 = 0;
|
int count3 = 0;
|
|
if (n.length > 0)
|
{
|
for (int i = 0; i < strips.length; i++)
|
{
|
gl.glBegin(gl.GL_TRIANGLE_STRIP);
|
|
/*
|
boolean locked = false;
|
float eps = 0.1f;
|
boolean wrap = CameraPane.UVWRAP; // true; // UV WRAP TEXTURE ISSUE: true = artifacts, false = nice
|
|
int dot = 0;
|
|
if ((dot&1) == 0)
|
dot |= (Math.abs(qv.s - pv.s) < eps && Math.abs(qv.t - pv.t) < eps) ? 3 : 1;
|
|
if (wrap || (dot&2) != 0) // Math.abs(qv.s - pv.s) < eps && Math.abs(qv.t - pv.t) < eps)
|
gl.glTexCoord2f((float) qv.s, (float) qv.t);
|
else
|
{
|
locked = true;
|
gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
}
|
//System.out.println("vertexq = " + qv.x + ", " + qv.y + ", " + qv.z);
|
gl.glVertex3f((float) qv.x, (float) qv.y, (float) qv.z);
|
if (hasnorm)
|
{
|
//System.out.println("normalr = " + rv.norm.x + ", " + rv.norm.y + ", " + rv.norm.z);
|
gl.glNormal3f((float) rv.norm.x, (float) rv.norm.y, (float) rv.norm.z);
|
}
|
|
if ((dot&4) == 0)
|
dot |= (Math.abs(rv.s - pv.s) < eps && Math.abs(rv.t - pv.t) < eps) ? 12 : 4;
|
|
if (wrap || !locked && (dot&8) != 0)
|
gl.glTexCoord2f((float) rv.s, (float) rv.t);
|
else
|
gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
|
f.dot = dot;
|
*/
|
|
if (!selectmode)
|
{
|
if (n[count3] != 0 || n[count3 + 1] != 0 || n[count3 + 2] != 0)
|
{
|
SetGLNormal(gl, n[count3], n[count3 + 1], n[count3 + 2]);
|
} else
|
{
|
SetGLNormal(gl, 0, 0, 1);
|
}
|
|
if (c != null)
|
//System.out.println("glcolor = " + c[count3] + ", " + c[count3+1] + ", " + c[count3+2]);
|
{
|
gl.glColor4f(c[count3/3], c[count3/3 /* + 1*/], c[count3/3 /* + 2*/], 1);
|
}
|
}
|
|
if (flipV)
|
gl.glTexCoord2f(uv[count2], 1-uv[count2 + 1]);
|
else
|
gl.glTexCoord2f(uv[count2], uv[count2 + 1]);
|
|
//System.out.println("vertex1 = " + v[count3] + ", " + v[count3+1] + ", " + v[count3+2]);
|
gl.glVertex3f(v[count3], v[count3 + 1], v[count3 + 2]);
|
|
count2 += 2;
|
count3 += 3;
|
if (!selectmode)
|
{
|
if (n[count3] != 0 || n[count3 + 1] != 0 || n[count3 + 2] != 0)
|
{
|
SetGLNormal(gl, n[count3], n[count3 + 1], n[count3 + 2]);
|
} else
|
{
|
SetGLNormal(gl, 0, 0, 1);
|
}
|
if (c != null)
|
{
|
gl.glColor4f(c[count3/3], c[count3/3 /* + 1*/], c[count3/3 /* + 2*/], 1);
|
}
|
}
|
|
if (flipV)
|
gl.glTexCoord2f(uv[count2], 1-uv[count2 + 1]);
|
else
|
gl.glTexCoord2f(uv[count2], uv[count2 + 1]);
|
|
//System.out.println("vertex2 = " + v[count3] + ", " + v[count3+1] + ", " + v[count3+2]);
|
gl.glVertex3f(v[count3], v[count3 + 1], v[count3 + 2]);
|
|
count2 += 2;
|
count3 += 3;
|
for (int j = 0; j < strips[i] - 2; j++)
|
{
|
//gl.glTexCoord2d(...);
|
if (!selectmode)
|
{
|
if (n[count3] != 0 || n[count3 + 1] != 0 || n[count3 + 2] != 0)
|
{
|
SetGLNormal(gl, n[count3], n[count3 + 1], n[count3 + 2]);
|
} else
|
{
|
SetGLNormal(gl, 0, 0, 1);
|
}
|
if (c != null)
|
{
|
gl.glColor4f(c[count3/3], c[count3/3 /* + 1*/], c[count3/3 /* + 2*/], 1);
|
}
|
}
|
|
if (flipV)
|
gl.glTexCoord2f(uv[count2], 1-uv[count2 + 1]);
|
else
|
gl.glTexCoord2f(uv[count2], uv[count2 + 1]);
|
|
//System.out.println("coord3 = " + uv[count2] + ", " + uv[count2+1]);
|
gl.glVertex3f(v[count3], v[count3 + 1], v[count3 + 2]);
|
|
count2 += 2;
|
count3 += 3;
|
}
|
|
gl.glEnd();
|
}
|
}
|
|
assert count3 == v.length;
|
}
|
else // !trimmed
|
{
|
int count = 0;
|
for (int i = 0; i < strips.length; i++)
|
{
|
gl.glBegin(gl.GL_TRIANGLE_STRIP);
|
|
Vertex p = bRep.GetVertex(bRep.indices[count++]);
|
Vertex q = bRep.GetVertex(bRep.indices[count++]);
|
|
drawVertex(gl, p, flipV, selectmode);
|
drawVertex(gl, q, flipV, selectmode);
|
|
for (int j = 0; j < strips[i] - 2; j++)
|
{
|
Vertex r = bRep.GetVertex(bRep.indices[count++]);
|
|
// if (j%2 == 0)
|
// drawFace(p, q, r, display, null);
|
// else
|
// drawFace(p, r, q, display, null);
|
|
// p = q;
|
// q = r;
|
drawVertex(gl, r, flipV, selectmode);
|
}
|
|
gl.glEnd();
|
}
|
}
|
}
|
|
static cSpring.Point3D temp = new cSpring.Point3D();
|
static cSpring.Point3D temp2 = new cSpring.Point3D();
|
static cSpring.Point3D temp3 = new cSpring.Point3D();
|
|
public void DrawDynamicMesh(cMesh mesh)
|
{
|
GL gl = GetGL(); // getGL();
|
|
cSpring.PhysicsController3D Phys = mesh.Phys;
|
|
gl.glDisable(gl.GL_LIGHTING);
|
|
gl.glLineWidth(1);
|
gl.glColor3f(1,1,1);
|
gl.glBegin(gl.GL_LINES);
|
double scale = 0;
|
int count = 0;
|
for (int s=0; s<Phys.allSprings.size(); s++)
|
{
|
cSpring.Spring spring = Phys.allSprings.get(s);
|
if(s == 0)
|
{
|
//System.out.println(" spring : " + spring.a.position + "; " + spring.b.position);
|
}
|
if (mesh.showsprings)
|
{
|
temp.set(spring.a.position);
|
temp.add(spring.b.position);
|
temp.mul(0.5);
|
temp2.set(spring.a.position);
|
temp2.sub(spring.b.position);
|
temp2.mul(spring.restLength/2);
|
temp.sub(temp2);
|
gl.glVertex3f((float)temp.x, (float)temp.y, (float)temp.z);
|
temp.add(temp2);
|
temp.add(temp2);
|
gl.glVertex3f((float)temp.x, (float)temp.y, (float)temp.z);
|
}
|
|
if (spring.isHandle)
|
continue;
|
|
//if (scale < spring.restLength)
|
scale += spring.restLength;
|
count++;
|
}
|
gl.glEnd();
|
|
if (count == 0)
|
scale = 0.01;
|
else
|
scale /= count * 3;
|
|
//scale = 0.25;
|
|
if (mesh.ShowInfo())
|
{
|
gl.glLineWidth(4);
|
for (int s=0; s<Phys.allNodes.size(); s++)
|
{
|
cSpring.DynamicNode node = Phys.allNodes.get(s);
|
if (node.mass == 0)
|
continue;
|
|
int i = node.springs==null?-1:node.springs.size();
|
gl.glColor3f((i>>2)&1,(i>>1)&1,i&1);
|
//temp.set(node.springForce.x, node.springForce.y, node.springForce.z);
|
//temp.normalize();
|
//gl.glColor3d((temp.x+1)/2, (temp.y+1)/2, (temp.z+1)/2);
|
gl.glBegin(gl.GL_LINES);
|
gl.glVertex3d(node.position.x, node.position.y, node.position.z);
|
//gl.glVertex3d(node.position.x + node.normal.x*scale, node.position.y + node.normal.y*scale, node.position.z + node.normal.z*scale);
|
gl.glVertex3d(node.position.x + mesh.bRep.GetVertex(s).norm.x*scale,
|
node.position.y + mesh.bRep.GetVertex(s).norm.y*scale,
|
node.position.z + mesh.bRep.GetVertex(s).norm.z*scale);
|
gl.glEnd();
|
}
|
|
gl.glLineWidth(8);
|
for (int s=0; s<Phys.allNodes.size(); s++)
|
{
|
cSpring.DynamicNode node = Phys.allNodes.get(s);
|
|
if (node.springs != null)
|
{
|
for (int i=0; i<node.springs.size(); i+=1)
|
{
|
cSpring.DynamicNode f = node.springs.get(i).GetOther(node);
|
|
int c = i+1;
|
// c = node.springs.get(i).nbcopies;
|
|
gl.glColor3f((c>>2)&1,(c>>1)&1,c&1);
|
gl.glBegin(gl.GL_LINES);
|
gl.glVertex3d(node.position.x, node.position.y, node.position.z);
|
gl.glVertex3d(f.position.x/3+node.position.x*2/3, f.position.y/3+node.position.y*2/3, f.position.z/3+node.position.z*2/3);
|
gl.glEnd();
|
}
|
}
|
}
|
|
gl.glLineWidth(1);
|
}
|
|
gl.glEnable(gl.GL_LIGHTING);
|
}
|
|
/// INTERFACE
|
|
public void StartTriangles()
|
{
|
javax.media.opengl.GL gl = GetGL();
|
gl.glBegin(gl.GL_TRIANGLES);
|
}
|
|
public void EndTriangles()
|
{
|
GetGL().glEnd();
|
}
|
|
void drawVertex(javax.media.opengl.GL gl, Vertex pv, boolean flipV, boolean selectmode)
|
{
|
if (!selectmode)
|
{
|
SetGLNormal(gl, (float) pv.norm.x, (float) pv.norm.y, (float) pv.norm.z);
|
gl.glColor4f(pv.AO, pv.AO, pv.AO, 1);
|
|
if (flipV)
|
gl.glTexCoord2f((float) pv.s, 1-(float) pv.t);
|
else
|
gl.glTexCoord2f((float) pv.s, (float) pv.t);
|
}
|
|
gl.glVertex3f((float) pv.x, (float) pv.y, (float) pv.z);
|
}
|
|
float[] colorV = new float[4];
|
|
void SetColor(Object3D obj, Vertex p0)
|
{
|
CameraPane display = this;
|
BoundaryRep bRep = obj.bRep;
|
|
if (RENDERPROGRAM == 0)
|
{
|
float r = 0;
|
if (bRep != null)
|
{
|
if (bRep.stripified)
|
{
|
r = 1;
|
}
|
}
|
float g = 0;
|
if (bRep != null)
|
{
|
if (bRep.trimmed)
|
{
|
g = 1;
|
}
|
}
|
float b = 0;
|
if (obj.support != null && obj.link2master)
|
{
|
b = 1;
|
}
|
display.GetGL().glColor3f(r*p0.AO, g*p0.AO, b*p0.AO);
|
return;
|
}
|
|
if (display.DrawMode() != CameraPane.SHADOW)
|
return;
|
|
javax.media.opengl.GL gl = display.GetGL();
|
// if (true) return;
|
// float ao = p.AO;
|
//
|
// // if (ao == 0 && !bRep.AOdone) // transient problem!
|
// // ao = 1;
|
//
|
// gl.glColor4f(ao, ao, ao, 1);
|
|
// CameraPane.selectedpoint.
|
// getAverage(cStatic.point1, true);
|
if (CameraPane.pointflow == null) // !random) // live)
|
{
|
return;
|
}
|
|
cStatic.point1.set(0,0,0);
|
LA.xformPos(cStatic.point1, CameraPane.selectedpoint.toParent, cStatic.point1);
|
|
cStatic.point1.sub(p0);
|
|
|
// if (marked && (p0.vertexlinks == null || support == null || support.bRep == null)) // no position delta?
|
// {
|
// return;
|
// }
|
|
//if (true)
|
if (cStatic.point1.dot(cStatic.point1) > 0.000001)
|
{
|
return;
|
}
|
|
if (false) // marked)
|
{
|
// debug rigging weights
|
for (int object = 0; object < p0.vertexlinks.length; object++)
|
{
|
float weight = p0.weights[object] / p0.totalweight;
|
|
// if (weight < 0.1)
|
// {
|
// assert(weight == 0);
|
// continue;
|
// }
|
|
if (p0.vertexlinks[object] == -1)
|
continue;
|
|
Vertex q = obj.support.bRep.GetVertex(p0.vertexlinks[object]);
|
|
int color = //1 << object; //
|
//p.vertexlinks.length;
|
obj.support.bRep.supports[p0.closestsupport].links[object];
|
colorV[2] += (color & 1) * weight;
|
colorV[1] += ((color & 2) >> 1) * weight;
|
colorV[0] += ((color & 4) >> 2) * weight;
|
}
|
}
|
else
|
{
|
if (obj.drawingstarted)
|
{
|
// find next point
|
if (bRep.GetVertex(0).faceindices == null)
|
{
|
bRep.InitFaceIndices();
|
}
|
|
double ymin = p0.y;
|
|
Vertex newp = p0;
|
|
for (int fii = 0; fii < p0.faceindices.length; fii++)
|
{
|
int fi = p0.faceindices[fii];
|
|
if (fi == -1)
|
break;
|
|
Face f = bRep.GetFace(fi);
|
|
Vertex p = bRep.GetVertex(f.p);
|
Vertex q = bRep.GetVertex(f.q);
|
Vertex r = bRep.GetVertex(f.r);
|
|
int swap = (int)(Math.random()*3);
|
|
// for (int s=swap; --s>=0;)
|
// {
|
// Vertex t = p;
|
// p = q;
|
// q = r;
|
// r = t;
|
// }
|
if (ymin > p.y)
|
{
|
ymin = p.y;
|
newp = p;
|
// break;
|
}
|
if (ymin > q.y)
|
{
|
ymin = q.y;
|
newp = q;
|
// break;
|
}
|
if (ymin > r.y)
|
{
|
ymin = r.y;
|
newp = r;
|
// break;
|
}
|
}
|
|
CameraPane.selectedpoint.toParent[3][0] = newp.x;
|
CameraPane.selectedpoint.toParent[3][1] = newp.y;
|
CameraPane.selectedpoint.toParent[3][2] = newp.z;
|
|
obj.drawingstarted = false;
|
|
// return;
|
}
|
|
if (false) // CameraPane.DRAW
|
{
|
p0.AO = colorV[0] = 2;
|
colorV[1] = 2;
|
colorV[2] = 2;
|
}
|
|
CameraPane.pointflow.add(p0);
|
CameraPane.pointflow.Touch();
|
}
|
|
// gl.glColor3f(colorV[0], colorV[1], colorV[2]);
|
// gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE, colorV, 0);
|
// gl.glMaterialfv(gl.GL_BACK, gl.GL_DIFFUSE, colorV, 0);
|
}
|
|
void DrawMaterial(cMaterial material, boolean selected, Object3D.cVector2[] others)
|
{
|
CameraPane display = this;
|
//new Exception().printStackTrace();
|
|
if (display.IsFrozen() && !selected || display.IsAmbientOcclusionOn()) // || display.drawMode == display.SHADOW)
|
{
|
return;
|
}
|
|
javax.media.opengl.GL gl = display.GetGL();
|
|
//Color col = Color.getHSBColor(color,modulation,1);
|
//col.getColorComponents(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), CameraPane.modelParams0);
|
if (!material.multiply)
|
{
|
display.color = material.color;
|
display.saturation = material.modulation;
|
}
|
else
|
{
|
display.color *= material.color*2;
|
display.saturation *= material.modulation*2;
|
}
|
|
cColor.HSBtoRGB(display.color, display.saturation, 1, display.modelParams0);
|
|
float[] colorV = Grafreed.colorV;
|
|
/**/
|
if (display.DrawMode() == display.DEFAULT) // && display.RENDERPROGRAM == 0)
|
{
|
colorV[0] = display.modelParams0[0] * material.diffuse;
|
colorV[1] = display.modelParams0[1] * material.diffuse;
|
colorV[2] = display.modelParams0[2] * material.diffuse;
|
colorV[3] = 1; // material.opacity;
|
|
gl.glColor4f(colorV[0], colorV[1], colorV[2], material.opacity);
|
//System.out.println("Opacity = " + opacity);
|
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE, colorV, 0);
|
//color[0] /= 2; color[1] /= 2; color[2] /= 2;
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_DIFFUSE, colorV, 0);
|
|
float amb = material.ambient;
|
if (amb < material.cameralight)
|
{
|
amb = material.cameralight;
|
}
|
colorV[0] = display.modelParams0[0] * material.diffuse * amb;
|
colorV[1] = display.modelParams0[1] * material.diffuse * amb;
|
colorV[2] = display.modelParams0[2] * material.diffuse * amb;
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_AMBIENT, colorV, 0);
|
//color[0] /= 2; color[1] /= 2; color[2] /= 2;
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_AMBIENT, colorV, 0);
|
|
/**/
|
colorV[0] = ((1 - material.metalness) + display.modelParams0[0] * material.metalness) * material.specular;
|
colorV[1] = ((1 - material.metalness) + display.modelParams0[1] * material.metalness) * material.specular;
|
colorV[2] = ((1 - material.metalness) + display.modelParams0[2] * material.metalness) * material.specular;
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_SPECULAR, colorV, 0);
|
//color[0] /= 2; color[1] /= 2; color[2] /= 2;
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_SPECULAR, colorV, 0);
|
colorV[0] = 10 / material.shininess; // 1/0.005f;
|
//System.out.println("shininess = " + colorV[0]);
|
if (colorV[0] > 128)
|
{
|
colorV[0] = 128;
|
}
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_SHININESS, colorV, 0);
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_SHININESS, colorV, 0);
|
/**/
|
}
|
/**/
|
|
//selected = false;
|
selected = selected && display.flash;
|
|
//display.modelParams0[0] = 0; // pigment.r;
|
//display.modelParams0[1] = 0; // pigment.g;
|
//display.modelParams0[2] = 0; // pigment.b;
|
if (!material.multiply)
|
{
|
display.modelParams0[3] = material.metalness;
|
display.modelParams1[0] = material.diffuse;
|
display.modelParams1[1] = material.specular;
|
display.modelParams1[2] = 1 / material.shininess;
|
display.modelParams1[3] = material.shift;
|
display.modelParams2[0] = material.ambient;
|
display.modelParams2[1] = material.lightarea;
|
//System.out.println("light area = " + lightarea);
|
display.modelParams2[2] = 1 / material.factor; // diffuseness
|
display.modelParams2[3] = material.velvet;
|
display.modelParams3[0] = material.sheen;
|
display.modelParams3[1] = material.subsurface;
|
display.modelParams3[2] = material.bump; // backlit
|
display.modelParams3[3] = material.aniso;
|
display.modelParams4[0] = material.anisoV;
|
display.modelParams4[1] = selected ? 100 : material.cameralight;
|
//System.out.println("selected = " + selected);
|
display.modelParams4[2] = material.diffuseness;
|
display.modelParams4[3] = material.shadow;
|
display.modelParams5[0] = material.texture;
|
display.modelParams5[1] = material.opacity;
|
display.modelParams5[2] = material.fakedepth;
|
display.modelParams5[3] = CameraPane.SHADOWCULLFACE ? 0f : (material.shadowbias - 0.005f) / 10;
|
}
|
else
|
{
|
display.modelParams0[3] *= material.metalness*2;
|
display.modelParams1[0] *= material.diffuse*2;
|
display.modelParams1[1] *= material.specular*2;
|
display.modelParams1[2] *= material.shininess*2;
|
display.modelParams1[3] *= material.shift*2;
|
display.modelParams2[0] *= material.ambient*2;
|
display.modelParams2[1] *= material.lightarea*2;
|
display.modelParams2[2] *= material.factor*2;
|
display.modelParams2[3] *= material.velvet*2;
|
display.modelParams3[0] *= material.sheen*2;
|
display.modelParams3[1] *= material.subsurface*2;
|
display.modelParams3[2] *= material.bump*2;
|
display.modelParams3[3] *= material.aniso*2;
|
display.modelParams4[0] *= material.anisoV*2;
|
display.modelParams4[1] *= material.cameralight*2;
|
//System.out.println("selected = " + selected);
|
display.modelParams4[2] *= material.diffuseness*2;
|
display.modelParams4[3] *= material.shadow*2;
|
display.modelParams5[0] *= material.texture*2;
|
display.modelParams5[1] *= material.opacity*2;
|
display.modelParams5[2] *= material.fakedepth*2;
|
display.modelParams5[3] *= material.shadowbias*2;
|
}
|
|
display.modelParams6[0] = 0;
|
display.modelParams6[1] = 0;
|
display.modelParams6[2] = 0;
|
display.modelParams6[3] = 0;
|
|
display.modelParams7[0] = 0;
|
display.modelParams7[1] = 1000;
|
display.modelParams7[2] = material.parallax;
|
display.modelParams7[3] = 0;
|
|
//display.modelParams6[0] = 100; // criss de bug de bump
|
|
Object3D.cVector2[] extparams = others; // display.vector2buffer;
|
if (extparams != null && extparams.length > 0 && extparams[0] != null)
|
{
|
display.modelParams6[0] = extparams[0].x / 1000.0f; // bump
|
display.modelParams6[1] = extparams[0].y / 1000.0f; // noise
|
if (extparams.length > 1)
|
{
|
display.modelParams6[2] = extparams[1].x / 1000.0f; // borderfade
|
display.modelParams6[3] = extparams[1].y / 1000.0f; // (float)Math.exp(-extparams[1].y / 1000.0f); // fog punchthrough
|
if (extparams.length > 2)
|
{
|
display.modelParams7[0] = extparams[2].x / 1000.0f; // noise power
|
float x = extparams[2].y / 1000.0f;
|
//if (x == 0)
|
// x = 1f;
|
display.modelParams7[1] = 1 / x / x / x / x / x / x / x / x / x / x / x / x / x; // (float)Math.pow(-Math.log((extparams[2].y+0.00) / 1000.0f), 1); // opacity power
|
if (extparams[2].y > 0)
|
{
|
//System.out.println("extparams[1].y = " + extparams[1].y);
|
//System.out.println("extparams[2].y = " + extparams[2].y);
|
//System.out.println("opacity power = " + display.modelParams7[1]);
|
}
|
}
|
}
|
}
|
|
//if (display.modelParams6[2] != 0)
|
/*
|
System.out.println("modelParams0[0] = " + display.modelParams0[0]);
|
System.out.println("modelParams0[1] = " + display.modelParams0[1]);
|
System.out.println("modelParams0[2] = " + display.modelParams0[2]);
|
System.out.println("modelParams0[3] = " + display.modelParams0[3]);
|
System.out.println("modelParams1[0] = " + display.modelParams1[0]);
|
System.out.println("modelParams1[1] = " + display.modelParams1[1]);
|
System.out.println("modelParams1[2] = " + display.modelParams1[2]);
|
System.out.println("modelParams1[3] = " + display.modelParams1[3]);
|
System.out.println("modelParams2[0] = " + display.modelParams2[0]);
|
System.out.println("modelParams2[1] = " + display.modelParams2[1]);
|
System.out.println("modelParams2[2] = " + display.modelParams2[2]);
|
System.out.println("modelParams2[3] = " + display.modelParams2[3]);
|
System.out.println("modelParams3[0] = " + display.modelParams3[0]);
|
System.out.println("modelParams3[1] = " + display.modelParams3[1]);
|
System.out.println("modelParams3[2] = " + display.modelParams3[2]);
|
System.out.println("modelParams3[3] = " + display.modelParams3[3]);
|
System.out.println("modelParams4[0] = " + display.modelParams4[0]);
|
System.out.println("modelParams4[1] = " + display.modelParams4[1]);
|
System.out.println("modelParams4[2] = " + display.modelParams4[2]);
|
System.out.println("modelParams4[3] = " + display.modelParams4[3]);
|
System.out.println("modelParams5[0] = " + display.modelParams5[0]);
|
System.out.println("modelParams5[1] = " + display.modelParams5[1]);
|
System.out.println("modelParams5[2] = " + display.modelParams5[2]);
|
System.out.println("modelParams5[3] = " + display.modelParams5[3]);
|
System.out.println("modelParams6[0] = " + display.modelParams6[0]);
|
System.out.println("modelParams6[1] = " + display.modelParams6[1]);
|
System.out.println("modelParams6[2] = " + display.modelParams6[2]);
|
System.out.println("modelParams6[3] = " + display.modelParams6[3]);
|
System.out.println("modelParams7[0] = " + display.modelParams7[0]);
|
System.out.println("modelParams7[1] = " + display.modelParams7[1]);
|
System.out.println("modelParams7[2] = " + display.modelParams7[2]);
|
System.out.println("modelParams7[3] = " + display.modelParams7[3]);
|
/**/
|
//assert (display.modelParams6[2] == 0);
|
|
//System.out.println("noise power = " + display.modelParams7[0]);
|
//System.out.println("shadowbias = " + shadowbias);
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 0, display.modelParams0, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 1, display.modelParams1, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 2, display.modelParams2, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 3, display.modelParams3, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 4, display.modelParams4, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 5, display.modelParams5, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 6, display.modelParams6, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 7, display.modelParams7, 0);
|
|
int mode = display.FP_SHADER;
|
|
if (material.aniso != material.anisoV || material.aniso > 0.002)
|
{
|
mode |= display.FP_ANISO;
|
}
|
|
display.EnableProgram(mode);
|
|
//System.out.println("opacity power = " + display.modelParams7[1]);
|
|
if (!material.multiply)
|
{
|
if (Globals.drawMode == CameraPane.SHADOW)
|
gl.glDepthMask(material.opacity >= 0.9 && display.modelParams7[1] > 0.1);
|
else
|
gl.glDepthMask(material.opacity >= 0.99);
|
}
|
}
|
|
int matrixdepth = 0; // 10000; // CONFLICT WITH cMESH... WARNING WARNING WARNING WARNING WARNING WARNING !!!!!!!!!!!! 0;
|
|
void MultMatrix(double[][] matrix)
|
{
|
if (matrix == null)
|
return;
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
model[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
currentGL.glMultMatrixd(model, 0);
|
}
|
|
public void PushMatrix(double[][] matrix, int count) // INTERFACE
|
{
|
matrixdepth++;
|
// GrafreeD.tracein(matrix);
|
if (matrix == null)
|
return; // Identity
|
|
//if (matrixdepth++ < MAXSTACK - 1)
|
if (matrixdepth-1 < MAXSTACK - 1)
|
{
|
currentGL.glPushMatrix();
|
}
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
model[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
while(--count>=0)
|
//MultMatrix(matrix);
|
currentGL.glMultMatrixd(model, 0);
|
}
|
|
void PushMatrix(double[][] matrix)
|
{
|
// GrafreeD.tracein(matrix);
|
PushMatrix(matrix, 1);
|
}
|
|
void PushMatrix()
|
{
|
// GrafreeD.tracein(null);
|
if (matrixdepth++ < MAXSTACK - 1)
|
{
|
currentGL.glPushMatrix();
|
}
|
|
currentGL.glLoadMatrixd(view, 0);
|
}
|
|
double[][] tmpmat = new double[4][4];
|
|
public void PopMatrix(double[][] inverse) // INTERFACE
|
{
|
--matrixdepth;
|
|
// GrafreeD.traceout(inverse);
|
if (inverse == null)
|
return; // Identity
|
|
//if (--matrixdepth < MAXSTACK - 1)
|
if (matrixdepth < MAXSTACK - 1)
|
{
|
currentGL.glPopMatrix();
|
} else
|
{
|
MultMatrix(inverse);
|
}
|
|
assert (matrixdepth >= 0);
|
}
|
|
void PopMatrix()
|
{
|
// GrafreeD.traceout(null);
|
// inverse == null??
|
if (--matrixdepth < MAXSTACK - 1)
|
{
|
currentGL.glPopMatrix();
|
}
|
else
|
assert (false);
|
|
|
assert (matrixdepth >= 0);
|
}
|
|
void PushTextureMatrix(double[][] matrix)
|
{
|
PushTextureMatrix(matrix, 1);
|
}
|
|
public void PushTextureMatrix(double[][] matrix, int count) // INTERFACE
|
{
|
currentGL.glActiveTexture(GetGL().GL_TEXTURE0);
|
|
currentGL.glMatrixMode(GetGL().GL_TEXTURE);
|
|
currentGL.glPushMatrix();
|
|
while (--count>=0)
|
MultMatrix(matrix); // Push
|
|
currentGL.glMatrixMode(GetGL().GL_MODELVIEW);
|
}
|
|
public void PopTextureMatrix(double[][] inverse) // INTERFACE
|
{
|
currentGL.glActiveTexture(GetGL().GL_TEXTURE0);
|
currentGL.glMatrixMode(GetGL().GL_TEXTURE);
|
|
currentGL.glPopMatrix();
|
//MultMatrix(inverse); // Pop
|
|
currentGL.glMatrixMode(GetGL().GL_MODELVIEW);
|
}
|
|
static String Name(int viewcode)
|
{
|
switch(viewcode)
|
{
|
case 0: return "main";
|
case 1: return "Red";
|
case 2: return "Green";
|
case 3: return "Blue";
|
case 4: return "light";
|
}
|
|
return "No name";
|
}
|
|
static int camerachangeframe;
|
|
public boolean SetCamera(Camera cam, boolean set)
|
{
|
// may 2014 if (cam == cameras[0] || cam == cameras[1])
|
// return false;
|
|
if (REFUSEMODE && Globals.isLIVE() && camerachangeframe != 0 && camerachangeframe != Globals.framecount)
|
{
|
// check for last change
|
if (Globals.framecount < camerachangeframe + 400) // 120 == 1 second
|
{
|
// refuse the camera change
|
System.err.println("Camera " + cam + " REFUSED");
|
return false;
|
}
|
}
|
|
camerachangeframe = Globals.framecount;
|
|
if (cam != null)
|
cam.hAspect = -1; // Read only
|
|
cameras[0] = cam;
|
targetLookAts[0] = new cVector(cam.lookAt);
|
for (int i = 1; i < 2; i++)
|
{
|
if (cameras[i] == null)
|
{
|
cameras[i] = new Camera(cam.viewCode);
|
}
|
|
if (set)
|
{
|
cameras[i].setAim(cam.location, cam.lookAt);
|
cameras[i].shaper_fovy = cam.shaper_fovy;
|
cameras[i].UP.set(cam.UP);
|
targetLookAts[i] = new cVector(cameras[i].lookAt);
|
}
|
}
|
cameracount = 0;
|
targetLookAt = targetLookAts[cameracount];
|
renderCamera = manipCamera = eyeCamera = cameras[cameracount/*++*/];
|
|
// Start with free camera
|
SwitchCameras(true);
|
|
pingthread.jump = true; // optional?
|
|
if (TRACKONCE)
|
{
|
//System.err.println("Oeil on");
|
TRACK = true;
|
// JUNE 2014 if (TRACK && trackedobject != null && DrawMode() == SHADOW) // && !lightMode)
|
// object.editWindow.ScreenFit(trackedobject);
|
//pingthread.StepToTarget(true);
|
}
|
|
if (OEILONCE)
|
{
|
//System.err.println("Oeil on");
|
OEIL = true;
|
if ((TRACK || SHADOWTRACK) && trackedobject != null && DrawMode() == SHADOW) // && !lightMode)
|
object.GetWindow().ScreenFit(trackedobject, SHADOWTRACK && !TRACK);
|
//pingthread.StepToTarget(true);
|
}
|
|
return true;
|
}
|
|
void SwitchCameras(boolean swap)
|
{
|
if (!lightMode)
|
{
|
cameracount++;
|
cameracount %= 2;
|
if (swap)
|
{
|
targetLookAt = targetLookAts[cameracount];
|
if (false) // cameracount == 1)
|
{
|
cameras[cameracount].setAim(manipCamera.location, manipCamera.lookAt);
|
cameras[cameracount].shaper_fovy = manipCamera.shaper_fovy;
|
cameras[cameracount].UP.set(manipCamera.UP);
|
}
|
renderCamera = manipCamera = eyeCamera = cameras[cameracount/*++*/];
|
}
|
}
|
}
|
|
void ProtectCamera()
|
{
|
/*
|
//cVector temp = new cVector();
|
//temp.set(cameras[0].location);
|
cameras[0].location.set(cameras[1].location);
|
//cameras[1].location.set(temp);
|
//temp.set(cameras[0].lookAt);
|
cameras[0].lookAt.set(cameras[1].lookAt);
|
//cameras[1].lookAt.set(temp);
|
//temp.set(targetLookAts[0]);
|
targetLookAts[0].set(targetLookAts[1]);
|
//targetLookAts[1].set(temp);
|
//float fov = cameras[0].shaper_fovy;
|
cameras[0].shaper_fovy = cameras[1].shaper_fovy;
|
//cameras[1].shaper_fovy = fov;
|
cameras[0].computeTransform();
|
//cameras[1].computeTransform();
|
*/
|
|
SwapCamera(0, 1);
|
|
//SwitchCameras();
|
}
|
|
void RevertCamera()
|
{
|
SwapCamera(1, 0);
|
|
//SwitchCameras();
|
}
|
|
void ToggleRender()
|
{
|
frozen ^= true;
|
// Weird...
|
Globals.lighttouched = true;
|
}
|
|
void ToggleDL()
|
{
|
mainDL ^= true;
|
}
|
|
void ToggleFullScreen()
|
{
|
FULLSCREEN ^= true;
|
}
|
|
void ToggleCrowd()
|
{
|
Globals.CROWD ^= true;
|
}
|
|
void ToggleLocal()
|
{
|
LOCALTRANSFORM ^= true;
|
}
|
|
public void ToggleTexture()
|
{
|
textureon ^= true;
|
}
|
|
public void ToggleLive()
|
{
|
Globals.setLIVE(Globals.isLIVE() ^ true);
|
|
System.err.println("LIVE = " + Globals.isLIVE());
|
|
if (!Globals.isLIVE()) // save sound
|
Grafreed.savesound = true; // wav.save();
|
// else
|
repaint(); // start loop // may 2013
|
}
|
|
public void ToggleSupport()
|
{
|
SUPPORT ^= true;
|
}
|
|
public void ToggleAbort()
|
{
|
ABORTMODE ^= true;
|
}
|
|
public void ToggleInertia()
|
{
|
INERTIA ^= true;
|
}
|
|
public void ToggleFast()
|
{
|
FAST ^= true;
|
}
|
|
public void ToggleSlowPose()
|
{
|
SLOWPOSE ^= true;
|
}
|
|
public void ToggleBoxMode()
|
{
|
BOXMODE ^= true;
|
}
|
|
public void ToggleZoomBoxMode()
|
{
|
ZOOMBOXMODE ^= true;
|
}
|
|
public void ToggleSmoothFocus()
|
{
|
SMOOTHFOCUS ^= true;
|
}
|
|
public void ToggleImageFlip()
|
{
|
IMAGEFLIP ^= true;
|
}
|
|
public void ToggleSpeakerMocap()
|
{
|
SPEAKERMOCAP ^= true;
|
}
|
|
public void ToggleSpeakerCamera()
|
{
|
SPEAKERCAMERA ^= true;
|
}
|
|
public void ToggleSpeakerFocus()
|
{
|
SPEAKERFOCUS ^= true;
|
}
|
|
public void ToggleFrustum()
|
{
|
FRUSTUM ^= true;
|
}
|
|
public void ToggleTrack()
|
{
|
TRACK ^= true;
|
if (TRACK)
|
{
|
if (object.selection != null &&
|
object.selection.size() > 0 &&
|
object.selection.elementAt(0) != null &&
|
!(object.selection.elementAt(0) instanceof Camera) &&
|
!(object.selection.elementAt(0) instanceof ScriptNode))
|
{
|
trackedobject = object.selection.elementAt(0);
|
repaint();
|
}
|
}
|
|
repaint();
|
}
|
|
public void ToggleTrackOnce()
|
{
|
TRACKONCE ^= true;
|
}
|
|
public void ToggleShadowTrack()
|
{
|
SHADOWTRACK ^= true;
|
repaint();
|
}
|
|
public void ToggleOeil()
|
{
|
OEIL ^= true;
|
}
|
|
public void ToggleOeilOnce()
|
{
|
OEILONCE ^= true;
|
}
|
|
void ToggleFootContact()
|
{
|
FOOTCONTACT ^= true;
|
}
|
|
void ToggleDebug()
|
{
|
Globals.DEBUG ^= true;
|
}
|
|
void ToggleLookAt()
|
{
|
LOOKAT ^= true;
|
}
|
|
void ToggleSwitch()
|
{
|
SWITCH ^= true;
|
}
|
|
void ToggleHandles()
|
{
|
HANDLES ^= true;
|
}
|
|
Object3D paintFolder;
|
|
void TogglePaint()
|
{
|
PAINTMODE ^= true;
|
paintcount = 0;
|
|
if (PAINTMODE)
|
{
|
paintFolder = GetFolder();
|
}
|
}
|
|
void SwapCamera(int a, int b)
|
{
|
//cVector temp = new cVector();
|
//temp.set(cameras[a].location);
|
cameras[a].location.set(cameras[b].location);
|
//cameras[b].location.set(temp);
|
//temp.set(cameras[a].lookAt);
|
cameras[a].lookAt.set(cameras[b].lookAt);
|
//cameras[b].lookAt.set(temp);
|
//temp.set(targetLookAts[a]);
|
cameras[a].UP.set(cameras[b].UP);
|
targetLookAts[a].set(cameras[b].lookAt); // targetLookAts[b]);
|
//targetLookAts[b].set(temp);
|
|
//float fov = cameras[a].shaper_fovy;
|
cameras[a].shaper_fovy = cameras[b].shaper_fovy;
|
//cameras[b].shaper_fovy = fov;
|
|
cameras[a].computeTransform();
|
//cameras[b].computeTransform();
|
|
//SwitchCameras();
|
}
|
|
void SetLight(Camera cam)
|
{
|
//System.out.println("PROTECTION = " + cam.hAspect);
|
//assert (cam.hAspect == 0);
|
if (cam != null)
|
cam.hAspect = 0;
|
lightCamera = cam;
|
}
|
|
private static void ApplyTransform(GL gl, Mat4f xform)
|
{
|
float[] data = new float[16];
|
xform.getColumnMajorData(data);
|
gl.glMultMatrixf(data, 0);
|
}
|
|
public void SetColumnMajorData(Mat4f mat, double[] in)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
for (int j = 0; j < 4; j++)
|
{
|
mat.set(i, j, (float) in[4 * j + i]);
|
}
|
}
|
}
|
|
static Mat4f Matrix(double[][] in)
|
{
|
Mat4f mat = new Mat4f();
|
|
for (int i = 0; i < 4; i++)
|
{
|
for (int j = 0; j < 4; j++)
|
{
|
mat.set(i, j, (float) in[i][j]);
|
}
|
}
|
|
return mat;
|
}
|
|
public void GetColumnMajorData(Mat4f mat, double[] out)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
for (int j = 0; j < 4; j++)
|
{
|
out[4 * j + i] = mat.get(i, j);
|
}
|
}
|
}
|
|
void Clear()
|
{
|
removeKeyListener(this);
|
removeMouseListener(this);
|
removeMouseMotionListener(this);
|
removeMouseWheelListener(this);
|
removeGLEventListener(this);
|
|
object = null;
|
}
|
|
GL currentGL;
|
|
public GL GetGL() // INTERFACE
|
{
|
return currentGL;
|
}
|
|
static private BufferedImage CreateBim(TextureData texturedata)
|
{
|
Grafreed.Assert(texturedata != null);
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
Buffer buffer = texturedata.getBuffer();
|
ByteBuffer bytebuf = (ByteBuffer)buffer;
|
|
byte[] bytes = bytebuf.array();
|
|
return CreateBim(bytes, width, height);
|
}
|
|
private void SetGLNormal(javax.media.opengl.GL gl, float nx, float ny, float nz)
|
{
|
gl.glNormal3f(nx, ny, nz);
|
|
if (ny > 0.9 || ny < -0.9)
|
// Ground or ceiling
|
gl.glVertexAttrib3f(4, 1, 0, 0);
|
else
|
// Walls
|
gl.glVertexAttrib3f(4, 0, 1, 0);
|
}
|
|
/**/
|
class CacheTexture
|
{
|
com.sun.opengl.util.texture.Texture texture;
|
com.sun.opengl.util.texture.TextureData texturedata;
|
|
int resolution;
|
|
CacheTexture(com.sun.opengl.util.texture.TextureData texdata, int res)
|
{
|
texture = com.sun.opengl.util.texture.TextureIO.newTexture(texdata);
|
texturedata = texdata;
|
resolution = res;
|
}
|
}
|
/**/
|
|
// TEXTURE static Texture texture;
|
static public Hashtable<cTexture, CacheTexture> texturepigment = new Hashtable<cTexture, CacheTexture>();
|
static public Hashtable<cTexture, CacheTexture> texturebump = new Hashtable<cTexture, CacheTexture>();
|
static public Hashtable<byte[], CacheTexture> bimtextures = new Hashtable<byte[], CacheTexture>();
|
static public java.util.HashSet<cTexture> usedtextures = new java.util.HashSet<cTexture>();
|
|
int pigmentdepth = 0;
|
public com.sun.opengl.util.texture.Texture[] pigmentstack = new com.sun.opengl.util.texture.Texture[65536];
|
int bumpdepth = 0;
|
public com.sun.opengl.util.texture.Texture[] bumpstack = new com.sun.opengl.util.texture.Texture[65536];
|
//public static String DEFAULT_TEXTURE = "DEFAULT_TEXTURE";
|
public static cTexture DEFAULT_TEXTURES = new cTexture("DEFAULT_TEXTURE" + ":" + "DEFAULT_TEXTURE_BUMP");
|
public static cTexture NOISE_TEXTURE = new cTexture("WHITE_NOISE:");
|
// public static cTexture IMMORTAL_TEXTURE = new cTexture("IMMORTAL");
|
|
com.sun.opengl.util.texture.TextureData GetResourceTexture(String name, boolean bump)
|
{
|
TextureData texturedata = null;
|
|
try
|
{
|
texturedata =
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream(name),
|
true,
|
GetFormat(name)); // com.sun.opengl.util.texture.TextureIO.PNG);
|
} catch (java.io.IOException e)
|
{
|
throw new javax.media.opengl.GLException(e);
|
}
|
|
if (bump)
|
texturedata = ConvertBump(texturedata, false);
|
|
// com.sun.opengl.util.texture.Texture texture =
|
// com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
|
|
//texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
//texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
|
return texturedata;
|
}
|
|
com.sun.opengl.util.texture.TextureData GetBimTexture(BufferedImage bim, boolean bump)
|
{
|
TextureData texturedata = null;
|
|
try
|
{
|
texturedata =
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
bim,
|
true);
|
} catch (Exception e)
|
{
|
throw new javax.media.opengl.GLException(e);
|
}
|
|
if (bump)
|
texturedata = ConvertBump(texturedata, false);
|
|
return texturedata;
|
}
|
|
boolean HUESMOOTH = true; // wrap around bug... true;
|
boolean SATSMOOTH = true;
|
boolean BRISMOOTH = true; // true;
|
|
int huebitshift = 2; // I
|
int satbitshift = 2; // Q
|
int bribitshift = 0; // Y
|
|
void SmoothBuffer(double smooth[], byte mask[], int length)
|
{
|
double prev = smooth[0];
|
double curr;
|
|
for (int i = 1; i < length-1; i++)
|
{
|
curr = smooth[i];
|
if (mask[i-1] == 0 && mask[i] == 0 && mask[i+1] == 0)
|
{
|
smooth[i] = prev/4 + curr/2 + smooth[i+1]/4;
|
// if (Math.abs(smooth[i] - curr) > (1<<(compressbit-1)))
|
// smooth[i] = curr;
|
}
|
prev = curr;
|
}
|
}
|
|
float[][] cutblur = { { 1,2,1 },
|
{ 2,1,2 },
|
{ 0,0,0 }, };
|
float[][] cutblur2 = { { 0,2,1 },
|
{ 0,1,2 },
|
{ 0,2,1 }, };
|
float[][] cutblur3 = { { 0,0,0 },
|
{ 2,1,2 },
|
{ 1,2,1 }, };
|
float[][] cutblur4 = { { 1,2,0 },
|
{ 2,1,0 },
|
{ 1,2,0 }, };
|
float cutweight = 9;
|
|
/*
|
float[][] cutblur = { { 1,2,0 },
|
{ 2,1,0 },
|
{ 0,0,0 }, };
|
float[][] cutblur2 = { { 0,2,1 },
|
{ 0,1,2 },
|
{ 0,0,0 }, };
|
float[][] cutblur3 = { { 0,0,0 },
|
{ 0,1,2 },
|
{ 0,2,1 }, };
|
float[][] cutblur4 = { { 0,0,0 },
|
{ 2,1,0 },
|
{ 1,2,0 }, };
|
float cutweight = 6;
|
*/
|
|
// float[][] cutblur = { { 2,1,0 },
|
// { 1,2,1 },
|
// { 0,1,2 }, };
|
// float[][] cutblur2 = { { 0,1,2 },
|
// { 1,2,1 },
|
// { 2,1,0 }, };
|
// float cutweight = 10;
|
|
//float[][] blur = { { 1,2,1 }, { 2,1,2 }, { 1,2,1 }, };
|
float[][] blur = { { 2,1,2 }, { 1,2,1 }, { 2,1,2 }, };
|
float blurweight = 14;
|
float[][] dirblur = { { 0,0,0 }, { 1,2,1 }, { 0,0,0 }, };
|
|
float[][] filter = new float[3][3];
|
|
void SmoothBuffer(short smooth[], byte mask[], boolean dir, int width, int height, int bit)
|
{
|
short temp[] = new short[smooth.length];
|
System.arraycopy(smooth, 0, temp, 0, width*height);
|
|
// short bit = 0;
|
|
//float eps = 4<<(compressbit+bit-1); // perfect match with "maskbit"
|
float eps = 2<<(maskbit+bit); // perfect match with "maskbit"
|
|
float[][] usedblur = blur;
|
|
if (dir)
|
usedblur = dirblur;
|
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
// if (smooth[j*width + i]<0)
|
// assert(smooth[j*width + i]>=0);
|
// if (smooth[j*width + i]>=256)
|
// assert(smooth[j*width + i]<256);
|
|
if (mask != null && mask[j*width + i] != 0)
|
continue;
|
|
float weight = 0;
|
|
//boolean edge = false;
|
|
//double factor = 0; // (mask[j*width + i]&0xFF)/255.0;
|
short min = 255, max =0;
|
for (int k=-1; k<=1; k++)
|
for (int l=-1; l<=1; l++)
|
{
|
/*
|
double factor2 = //Math.pow((mask[j*width + i]&0xFF)/255.0, 0.05);
|
(mask[(j+k)*width + i+l]&0xFF)/255.0;
|
if (factor < factor2)
|
factor = factor2; // mask[(j+k)*width + i+l] != 0)
|
*/
|
|
short val = smooth[(j+k)*width + i+l];
|
if (min > val)
|
min = val;
|
if (max < val)
|
max = val;
|
|
if (mask != null && mask[(j+k)*width + i+l] != 0)
|
//edge = true;
|
filter[k+1][l+1] = 0;
|
else
|
filter[k+1][l+1] = usedblur[k+1][l+1];
|
|
weight += filter[k+1][l+1];
|
}
|
|
//if (edge)
|
// continue;
|
|
// if (ZEROVALUES)
|
// if (max - min > eps)
|
// continue; // values are too far away
|
|
temp[j*width + i] = (short) (
|
filter[0][0]*smooth[(j-1)*width + i-1] + filter[0][1]*smooth[(j-1)*width + i] + filter[0][2]*smooth[(j-1)*width + i+1] +
|
filter[1][0]*smooth[j*width + i-1] + filter[1][1]*smooth[j*width + i] + filter[1][2]*smooth[j*width + i+1] +
|
filter[2][0]*smooth[(j+1)*width + i-1] + filter[2][1]*smooth[(j+1)*width + i] + filter[2][2]*smooth[(j+1)*width + i+1]
|
);
|
|
temp[j*width + i] /= weight; // 13; // 16;
|
|
// temp[j*width + i] = (short)(factor*smooth[j*width + i] + (1-factor)*temp[j*width + i]);
|
|
if (temp[j*width + i] <= 0)
|
temp[j*width + i] = 0;
|
if (temp[j*width + i] > 255)
|
temp[j*width + i] = 255;
|
}
|
}
|
|
System.arraycopy(temp, 0, smooth, 0, width*height);
|
}
|
|
void SmoothBuffer(double smooth[], int width, int height)
|
{
|
double temp[] = new double[smooth.length];
|
System.arraycopy(smooth, 0, temp, 0, width*height);
|
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
temp[j*width + i] = (double) (
|
blur[0][0]*smooth[(j-1)*width + i-1] + blur[0][1]*smooth[(j-1)*width + i] + blur[0][2]*smooth[(j-1)*width + i+1] +
|
blur[1][0]*smooth[j*width + i-1] + blur[1][1]*smooth[j*width + i] + blur[1][2]*smooth[j*width + i+1] +
|
blur[2][0]*smooth[(j+1)*width + i-1] + blur[2][1]*smooth[(j+1)*width + i] + blur[2][2]*smooth[(j+1)*width + i+1]
|
);
|
|
temp[j*width + i] /= 13; // 16;
|
}
|
}
|
|
System.arraycopy(temp, 0, smooth, 0, width*height);
|
}
|
|
void SmoothBuffer(float smooth[], int width, int height, float edges[])
|
{
|
SmoothBuffer0(smooth, width, height, edges, blur, blurweight);
|
}
|
|
float[] tempbuffer = null;
|
|
void SmoothBuffer0(float smooth[], int width, int height, float edges[], float[][] kernel, float weight)
|
{
|
if (tempbuffer == null)
|
tempbuffer = new float[smooth.length];
|
System.arraycopy(smooth, 0, tempbuffer, 0, width*height*3);
|
|
double eps = 1<<maskbit;
|
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
boolean edge = true;
|
|
if (edges != null)
|
{
|
for (int c=3; --c>=0;)
|
{
|
double min = 255, max =0;
|
for (int k=-1; k<=1; k++)
|
for (int l=-1; l<=1; l++)
|
{
|
double val = edges[((j+k)*width + i+l)*3 + c];
|
if (min > val)
|
min = val;
|
if (max < val)
|
max = val;
|
}
|
|
if (max - min <= eps)
|
edge = false; // values are close enough
|
}
|
}
|
|
if (!edge)
|
continue;
|
|
for (int k=3; --k>=0;)
|
{
|
int index = j*width + i;
|
tempbuffer[index*3 + k] = (short) (
|
kernel[0][0]*smooth[((j-1)*width + i-1)*3 + k] + kernel[0][1]*smooth[((j-1)*width + i)*3 + k] + kernel[0][2]*smooth[((j-1)*width + i+1)*3 + k] +
|
kernel[1][0]*smooth[(j*width + i-1)*3 + k] + kernel[1][1]*smooth[(j*width + i)*3 + k] + kernel[1][2]*smooth[(j*width + i+1)*3 + k] +
|
kernel[2][0]*smooth[((j+1)*width + i-1)*3 + k] + kernel[2][1]*smooth[((j+1)*width + i)*3 + k] + kernel[2][2]*smooth[((j+1)*width + i+1)*3 + k]
|
);
|
|
tempbuffer[index*3 + k] /= weight;
|
|
if (tempbuffer[index*3 + k] < 0)
|
tempbuffer[index*3 + k] = 0;
|
if (tempbuffer[index*3 + k] > 255)
|
tempbuffer[index*3 + k] = 255;
|
}
|
}
|
}
|
|
System.arraycopy(tempbuffer, 0, smooth, 0, width*height*3);
|
}
|
|
void SharpenBuffer(float input[], int width, int height, float edges[], byte[] maskorg)
|
{
|
if (tempbuffer == null)
|
tempbuffer = new float[input.length];
|
System.arraycopy(input, 0, tempbuffer, 0, width*height*3);
|
|
double eps = 1<<maskbit;
|
|
int filtersize = 2; // clampbit; // means *2 + 1 loops
|
|
for (int j = filtersize; j < height-filtersize; j++)
|
{
|
for (int i = filtersize; i < width-filtersize; i++)
|
{
|
// if (i%3 == 0 && j%3 == 0)
|
// continue;
|
|
boolean edge = true;
|
|
if (edges != null)
|
{
|
double min = 255, max =0;
|
for (int k=-1; k<=1; k++)
|
{
|
for (int l=-1; l<=1; l++)
|
{
|
int index3 = ((j+k)*width + i+l)*3;
|
|
double val = 0;
|
for (int c=3; --c>=0;)
|
{
|
val += edges[index3 + c];
|
}
|
|
val /= 3;
|
|
if (min > val)
|
min = val;
|
if (max < val)
|
max = val;
|
}
|
}
|
|
if (max - min <= eps)
|
edge = false; // values are close enough
|
}
|
else
|
{
|
if (maskorg != null)
|
{
|
edge = maskorg[(j/3)*(width/3) + i/3] != 0;
|
}
|
}
|
|
if (!edge)
|
{
|
if (COMPACT) // edge
|
{
|
int index3 = (j*width + i)*3;
|
for (int c=3; --c>=0;)
|
{
|
tempbuffer[index3 + c] = 0;
|
}
|
}
|
|
continue;
|
}
|
|
short min = 255, max =0;
|
for (int k=-filtersize; k<=filtersize; k++)
|
{
|
int index3 = ((j+k)*width + i - filtersize)*3;
|
for (int l=-filtersize; l<=filtersize; l++)
|
{
|
//int index3 = ((j+k)*width + i+l)*3;
|
|
short val = 0;
|
|
for (int c=3; --c>=0; index3++)
|
{
|
val += input[index3 /*+ c*/];
|
}
|
|
val /= 3;
|
|
if (min > val)
|
min = val;
|
if (max < val)
|
max = val;
|
}
|
}
|
|
if (min == max)
|
continue;
|
|
short val = 0;
|
|
int index3 = (j*width + i)*3;
|
|
for (int c=3; --c>=0;)
|
{
|
val += input[index3 + c];
|
}
|
|
val /= 3;
|
|
int aver = (max+min)/2;
|
|
float power = 4.0f/(1<<kompactbit); // .5;
|
float valf = val;
|
|
if (val < aver)
|
{
|
float factor = 1.0f*(aver - val)/(max-min)*2; // 0..1
|
|
//factor = Math.sqrt(factor);
|
// factor = Math.pow(factor, 1 - 1.0/(1<<4));
|
|
double importance = (max-min)/255.0f;
|
|
importance = Math.pow(importance, power);
|
|
factor *= importance;
|
|
//factor = Math.pow(factor, power*(1 - (max-min)/255));
|
|
valf = ((1-factor)*val + factor*min) / val;
|
}
|
else
|
{
|
float factor = 1.0f*(val - aver)/(max-min)*2; // 0..1
|
|
//factor = Math.sqrt(factor);
|
// factor = Math.pow(factor, 1 - 1.0/(1<<4));
|
|
double importance = (max-min)/255;
|
|
importance = Math.pow(importance, power);
|
|
factor *= importance;
|
|
//factor = Math.pow(factor, power*(1 - (max-min)/255));
|
|
valf = ((1-factor)*val + factor*max) / val;
|
}
|
|
for (int c=3; --c>=0;)
|
{
|
tempbuffer[index3 + c] *= valf;
|
|
if (tempbuffer[index3 + c] < 0)
|
tempbuffer[index3 + c] = 0;
|
if (tempbuffer[index3 + c] > 255)
|
tempbuffer[index3 + c] = 255;
|
}
|
}
|
}
|
|
System.arraycopy(tempbuffer, 0, input, 0, width*height*3);
|
}
|
|
void NormalizeBuffer(float input[], int width, int height, byte original[])
|
{
|
if (tempbuffer == null)
|
tempbuffer = new float[input.length];
|
System.arraycopy(input, 0, tempbuffer, 0, width*height*3);
|
|
for (int j = 1; j < height-1; j+=3)
|
{
|
for (int i = 1; i < width-1; i+=3)
|
{
|
// if (i%3 == 0 && j%3 == 0)
|
// continue;
|
int index = (j/3*width/3 + i/3)*3;
|
|
float target = 0;
|
for (int c=3; --c>=0;)
|
{
|
target += original[index + c]&0xFF;
|
}
|
|
target /= 3;
|
|
float average = 0;
|
|
for (int k=-1; k<=1; k++)
|
{
|
for (int l=-1; l<=1; l++)
|
{
|
int index3 = ((j+k)*width + i+l)*3;
|
|
for (int c=3; --c>=0;)
|
{
|
average += input[index3 + c];
|
}
|
}
|
}
|
|
average /= 3*9;
|
|
for (int k=-1; k<=1; k++)
|
{
|
for (int l=-1; l<=1; l++)
|
{
|
int index3 = ((j+k)*width + i+l)*3;
|
|
for (int c=3; --c>=0;)
|
{
|
tempbuffer[index3 + c] = input[index3 + c] * target/average;
|
|
if (tempbuffer[index3 + c] < 0)
|
tempbuffer[index3 + c] = 0;
|
if (tempbuffer[index3 + c] > 255)
|
tempbuffer[index3 + c] = 255;
|
}
|
}
|
}
|
}
|
}
|
|
System.arraycopy(tempbuffer, 0, input, 0, width*height*3);
|
}
|
|
static int cutcount = 0;
|
|
void CutCorners(float input[], int width, int height, float edges[])
|
{
|
switch (cutcount++%4)
|
{
|
case 0:
|
SmoothBuffer0(input, width, height, edges, // blur, blurweight);
|
cutblur, cutweight);
|
case 1:
|
SmoothBuffer0(input, width, height, edges, // blur, blurweight);
|
cutblur2, cutweight);
|
case 2:
|
SmoothBuffer0(input, width, height, edges, // blur, blurweight);
|
cutblur3, cutweight);
|
case 3:
|
SmoothBuffer0(input, width, height, edges, // blur, blurweight);
|
cutblur4, cutweight);
|
}
|
/*
|
double temp[] = new double[input.length];
|
System.arraycopy(input, 0, temp, 0, width*height*3);
|
|
double eps = 1<<maskbit;
|
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
int index01 = ((j+1)*width + i)*3;
|
|
double val01 = 0;
|
|
for (int c=3; --c>=0;)
|
{
|
val01 += input[index01 + c];
|
}
|
|
val01 /= 3;
|
|
int index10 = (j*width + i+1)*3;
|
|
double val10 = 0;
|
|
for (int c=3; --c>=0;)
|
{
|
val10 += input[index10 + c];
|
}
|
|
val10 /= 3;
|
|
int index_10 = (j*width + i-1)*3;
|
|
double val_10 = 0;
|
|
for (int c=3; --c>=0;)
|
{
|
val_10 += input[index_10 + c];
|
}
|
|
val_10 /= 3;
|
|
int index00 = (j*width + i)*3;
|
|
if (true) // Math.abs(val01 - val_10) < eps)
|
{
|
for (int c=3; --c>=0;)
|
{
|
temp[index00 + c] = temp[index00 + c]*3/4 +
|
(input[index01 + c] + input[index_10 + c])/2/4;
|
}
|
}
|
|
if (true) // Math.abs(val01 - val10) < eps)
|
{
|
for (int c=3; --c>=0;)
|
{
|
temp[index00 + c] = temp[index00 + c]*3/4 +
|
(input[index01 + c] + input[index10 + c])/2/4;
|
}
|
}
|
|
// for (int c=3; --c>=0;)
|
// {
|
// temp[index00 + c] = temp[index00 + c]*3/4 +
|
// (input[index01 + c] + input[index10 + c])/2/4;
|
// }
|
}
|
}
|
|
System.arraycopy(temp, 0, input, 0, width*height*3);
|
*/
|
}
|
|
void MarkMask(float smooth[], byte mask[], int length, int bit)
|
{
|
float prev = smooth[0];
|
float curr;
|
|
float warm = prev;
|
//float step = 1<<(Math.min(maskbit,compressbit)+bit-1);
|
float step = 1<<(maskbit+bit-1);
|
|
if (step == 0)
|
return;
|
|
for (int i = 1; i < length-1; i++)
|
{
|
smooth[i] += step;
|
|
curr = smooth[i];
|
|
float diff = curr - warm;
|
float sign;
|
|
if (diff < 0)
|
sign = -1;
|
else
|
sign = 1;
|
|
if (Math.abs(diff) > step)
|
diff = sign*step;
|
|
warm += diff;
|
|
if (Math.abs(warm - curr) > step) // (1<<compressbit))
|
{
|
mask[i-1] = mask[i] = mask[i+1] = 1;
|
warm = curr;
|
}
|
//smooth[i] = -prev + curr*2 - smooth[i+1];
|
// if (Math.abs(smooth[i] - curr) > (1<<(compressbit-1)))
|
// smooth[i] = curr;
|
//prev = curr;
|
}
|
}
|
|
byte[] tempbufferbyte = new byte[0];
|
byte[] tempbufferbyte2 = new byte[0];
|
|
void FilterMask(byte mask[], int width, int height, boolean caution)
|
{
|
// if (true)
|
// return;
|
|
if (tempbufferbyte.length != mask.length)
|
tempbufferbyte = new byte[mask.length];
|
//if (tempbufferbyte2.length != mask.length)
|
tempbufferbyte2 = new byte[mask.length];
|
System.arraycopy(mask, 0, tempbufferbyte, 0, width*height);
|
|
int neighbors = 2;
|
if (!caution)
|
neighbors = 3;
|
|
boolean atleastone = true;
|
|
while (atleastone)
|
{
|
atleastone = false;
|
|
if (caution)
|
{
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
int index = j*width + i;
|
|
tempbufferbyte2[index] = 0;
|
|
if (mask[index] == 0)
|
continue;
|
|
int nb = 0;
|
|
for (int k=-1; k<=1; k+=1)
|
{
|
for (int m=-1; m<=1; m+=1)
|
{
|
if (mask[(j+m)*width + i+k] != 0)
|
nb += 1;
|
}
|
}
|
|
if (nb >= 3) // not 2 because the pixel is in the count
|
{
|
tempbufferbyte2[index] = 1;
|
}
|
}
|
}
|
}
|
|
for (int j = 1; j < height-1; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
int index = j*width + i;
|
|
if (mask[index] == 0)
|
continue;
|
|
/*
|
int nbx = 0;
|
int nby = 0;
|
|
if (mask[j*width + i-1] != 0)
|
nbx += 1;
|
if (mask[j*width + i+1] != 0)
|
nbx += 1;
|
if (mask[(j-1)*width + i] != 0)
|
nby += 1;
|
if (mask[(j+1)*width + i] != 0)
|
nby += 1;
|
|
//if (nbx <= 1 && nby <= 1)
|
if (nbx + nby < 2)
|
*/
|
|
int nb = 0;
|
|
for (int k=-1; k<=1; k+=1)
|
{
|
for (int m=-1; m<=1; m+=1)
|
{
|
if (mask[(j+m)*width + i+k] != 0)
|
nb += 1;
|
if (tempbufferbyte2[(j+m)*width + i+k] != 0)
|
nb += 1;
|
}
|
}
|
|
if (nb < neighbors+1) // not 2 because the pixel is in the count
|
{
|
tempbufferbyte[index] = 0;
|
atleastone = true;
|
}
|
else
|
{
|
// temp[j*width + i] = (byte)(Math.pow((mask[j*width + i]&0xFF)/255.0, 1) * 255);
|
|
// if ((temp[j*width + i]&0xFF) > 252)
|
// temp[j*width + i] = (byte)255;
|
}
|
}
|
}
|
|
System.arraycopy(tempbufferbyte, 0, mask, 0, width*height);
|
}
|
}
|
|
void ClampMask(byte mask[], int width, int height, int clampbit)
|
{
|
if (tempbufferbyte.length != mask.length)
|
tempbufferbyte = new byte[mask.length];
|
System.arraycopy(mask, 0, tempbufferbyte, 0, width*height);
|
|
int maskbits = 0xFF >> clampbit;
|
maskbits <<= clampbit;
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
tempbufferbyte[j*width + i] &= maskbits;
|
}
|
}
|
|
System.arraycopy(tempbufferbyte, 0, mask, 0, width*height);
|
}
|
|
void MarkMask(short smooth[], byte mask[], int width, int height, int bit, byte channel)
|
{
|
// if (true)
|
// return;
|
|
//float step = 1<<(Math.min(maskbit,compressbit)+bit-1);
|
float step = 1<<(maskbit+bit-1);
|
if (step == 0)
|
return;
|
|
float eps = 2<<(maskbit+bit); // perfect match with "maskbit"
|
|
for (int dir=/*-*/1; dir<=1; dir+=2)
|
{
|
for (int j = 1; j < height-1; j++)
|
{
|
// int i = 0;
|
// if (dir == -1)
|
// i = width - 1;
|
|
// float prev = smooth[j*width + i];
|
// float curr;
|
|
// float warm = prev;
|
|
for (int i = 1; i < width-1; i++)
|
{
|
// i = i0;
|
// if (dir == -1)
|
// i = width - 1 - i0;
|
|
// curr = smooth[j*width + i]; // += step;
|
|
/*
|
//curr = smooth[i];
|
|
float diff = curr - warm;
|
float sign;
|
|
if (diff < 0)
|
sign = -1;
|
else
|
sign = 1;
|
|
if (Math.abs(diff) > step)
|
diff = sign*step;
|
|
warm += diff;
|
|
if (false) // Math.abs(warm - curr) > step) // (1<<compressbit))
|
{
|
mask[j*width + i-dir] |= channel;
|
mask[j*width + i] |= channel;
|
warm = curr;
|
}
|
|
short edgedist = (short)Math.abs(warm - curr);
|
// if (edgedist < 0)
|
// edgedist = 0;
|
// if (edgedist > 255)
|
// edgedist = 255;
|
|
mask[j*width + i-dir] |= edgedist;
|
mask[j*width + i] |= edgedist;
|
*/
|
|
// curvature
|
/*
|
float curvatureI = Math.abs((smooth[j*width + i+dir] - smooth[j*width + i]) -
|
(smooth[j*width + i] - smooth[j*width + i-dir]));
|
|
curvatureI *= curvatureI * smooth[j*width + i]/255;
|
|
float curvatureJ = Math.abs((smooth[(j+dir)*width + i] - smooth[j*width + i]) -
|
(smooth[j*width + i] - smooth[(j-dir)*width + i]));
|
|
curvatureJ *= curvatureJ * smooth[j*width + i]/255;
|
|
mask[j*width + i] |= (byte) ((curvatureI + curvatureJ) * step);
|
*/
|
|
short min = 255, max =0;
|
for (int k=-1; k<=1; k++)
|
for (int l=-1; l<=1; l++)
|
{
|
short val = smooth[(j+k)*width + i+l];
|
if (min > val)
|
min = val;
|
if (max < val)
|
max = val;
|
}
|
|
short dmm = (short)(max - min);
|
int count = 0;
|
while (dmm > 0)
|
{
|
dmm >>= 1;
|
count++;
|
}
|
/*
|
if (max - min <= eps)
|
continue; // values are close enough
|
|
mask[j*width + i] |= channel;
|
*/
|
count += bit;
|
if (count > 7)
|
count = 7;
|
bit = 0; // ????
|
//short maskval = (short)((1<<count)&0xF0);
|
short maskval = (short)((max - min)<<bit);
|
|
if ((mask[j*width + i]&0xFF) + maskval > 255)
|
mask[j*width + i] = (byte)255;
|
else
|
mask[j*width + i] += maskval;
|
// if (mask[j*width + i] == 0)
|
// mask[j*width + i] = 0x10;
|
//smooth[i] = -prev + curr*2 - smooth[i+1];
|
// if (Math.abs(smooth[i] - curr) > (1<<(compressbit-1)))
|
// smooth[i] = curr;
|
//prev = curr;
|
}
|
}
|
|
/*
|
for (int i = 0; i < width; i++)
|
{
|
int j = 0;
|
if (dir == -1)
|
j = height - 1;
|
|
float prev = smooth[j*width + i];
|
float curr;
|
|
float warm = prev;
|
|
for (int j0 = 1; j0 < height-1; j0++)
|
{
|
j = j0;
|
if (dir == -1)
|
j = height - 1 - j0;
|
|
curr = smooth[j*width + i]; // += step;
|
|
// float diff = curr - warm;
|
// float sign;
|
//
|
// if (diff < 0)
|
// sign = -1;
|
// else
|
// sign = 1;
|
//
|
// if (Math.abs(diff) > step)
|
// diff = sign*step;
|
//
|
// warm += diff;
|
//
|
// // if (Math.abs(warm - curr) > step) // (1<<compressbit))
|
// // {
|
// // mask[(j-dir)*width + i] = mask[j*width + i] = mask[(j+dir)*width + i] = 1;
|
// // warm = curr;
|
// // }
|
//
|
// short edgedist = (short)Math.abs(warm - curr);
|
// // if (edgedist < 0)
|
// // edgedist = 0;
|
// // if (edgedist > 255)
|
// // edgedist = 255;
|
//
|
// mask[j*width + i-dir] |= edgedist;
|
// mask[j*width + i] |= edgedist;
|
|
// curvature
|
float curvature = Math.abs((smooth[(j+dir)*width + i] - smooth[j*width + i]) -
|
(smooth[j*width + i] - smooth[(j*???newte-dir)*width + i]));
|
|
curvature *= curvature * smooth[j*width + i]/255;
|
|
mask[j*width + i] |= (byte) (curvature * step);
|
// mask[j*width + i] |= (byte) (Math.abs((smooth[(j+dir)*width + i] - smooth[j*width + i]) -
|
// (smooth[j*width + i] - smooth[(j-dir)*width + i])) * step);
|
|
//smooth[i] = -prev + curr*2 - smooth[i+1];
|
// if (Math.abs(smooth[i] - curr) > (1<<(compressbit-1)))
|
// smooth[i] = curr;
|
//prev = curr;
|
}
|
}
|
*/
|
}
|
}
|
|
/**/
|
static short[] tabledif_1 =
|
{
|
//0 /*-4*/, 1, 6, 16, 32, 64, 96, -96, -64, -32, -16, -6, -1, 4, 8, -8,
|
//0 /*-4*/, 1, 5, 20, 56, 64, 96, -96, -64, -56, -20, -5, -1, 4, 8, -8,
|
//0 /*-4*/, 1, 5, 12, 25, 56, 96, -96, -56, -25, -12, -5, -1, 4, 8, -8,
|
0 /*-4*/, 1, 6, 15, 28, 45, 66, 91, -91, -66, -45, -28, -15, -6, -1, 4, 8, -8,
|
};
|
|
static byte[] tabledif =
|
{
|
0 /*-1*/, 1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 3,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, 12, -1, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, -1, 14,
|
// 0 /*-1*/, 1, -1, -1, 13, 2/*-1*/, 2, -1, 14, -1, -1, -1, 3/*-1*/, -1, -1, -1,
|
// 3, -1, -1, -1, 3/*-1*/, -1, -1, -1, -1, 4/*-1*/, -1, -1, -1, -1, -1, -1,
|
// 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, 5/*-1*/, -1, -1, -1, -1, -1, -1, -1,
|
// 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
//
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 8, -1, -1, -1, -1, -1, -1, -1, 8/*-1*/, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 9, -1, -1, -1, -1, -1, -1, 9/*-1*/, -1, -1, -1, -1, 10/*-1*/, -1, -1, -1,
|
// 10, -1, -1, -1, 10/*-1*/, -1, -1, -1, 15, -1, 11, 11/*-1*/, 0, -1, -1, 12,
|
|
|
// 0, 1, 2, -1, 3, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1,
|
// 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
//
|
// 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
// 11, -1, -1, -1, -1, -1, -1, -1, 12, -1, -1, -1, 13, -1, 14, 15,
|
};
|
/**
|
|
static short[] tabledif_1 =
|
{
|
//-4, 1, 6, 16, 32, 64, 96, -96, -64, -32, -16, -6, -1, 4, 8, -8,
|
//0, 1, 2, 4, 8, 16, 32, 64, 128, -64, -32, -16, -8, -4, -2, -1,
|
0, 1, 3, 6, 12, 24, 48, 96, -96, -48, -24, -12, -6, -3, -1,
|
};
|
|
static byte[] tabledif =
|
{
|
0, 1, -1, 2, -1, -1, 3, -1, -1, -1, -1, -1, 4, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, 11, -1, -1, -1, -1, -1, 12, -1, -1, 13, -1, 14,
|
};
|
/**/
|
|
static Object3D lastObject;
|
|
//com.sun.opengl.util.texture.Texture
|
TextureData
|
GetFileTexture(String name, boolean bump, int resolution)
|
{
|
// if (true)
|
// return null;
|
|
TextureData texturedata = null;
|
|
for (int i=0; i<2; i++)
|
{
|
try
|
{
|
texturedata =
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
new FileInputStream(name.split("\\.tre")[0]),
|
MIPMAP,
|
GetFormat(name));
|
break;
|
} catch (java.io.FileNotFoundException e)
|
{
|
//throw new javax.media.opengl.GLException(e);
|
// System.err.println(e);
|
// return null;
|
//if (i == 2)
|
// return null;
|
//e.printStackTrace();
|
if (i == 0)
|
name = "/Users/nbriere/Textures" + name;
|
} catch (java.io.IOException e)
|
{
|
//throw new javax.media.opengl.GLException(e);
|
// System.err.println(e);
|
// return null;
|
//if (i == 2)
|
// return null;
|
// TIFF issue sept 2019
|
System.err.println("lastObject = " + lastObject);
|
e.printStackTrace();
|
name = name.split("\\.tif")[0] + ".jpg";
|
}
|
}
|
|
System.out.println("LOADING TEXTURE : " + name);
|
|
Object x = texturedata.getMipmapData(); // .getBuffer();
|
|
//
|
if (false) // compressbit > 0)
|
{
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
byte bit = (byte) (1 << clampbit);
|
for (int j = 0; j < height; j++)
|
{
|
int indexj = (j*width + width/2);
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
// bytes[index*3] = bytes[indexj*3];
|
// bytes[index*3+1] = bytes[indexj*3+1];
|
// bytes[index*3+2] = bytes[indexj*3+2];
|
bytes[index*3] &= bit;
|
bytes[index*3+1] &= bit;
|
bytes[index*3+2] &= bit;
|
}
|
}
|
}
|
|
if (name.toLowerCase().endsWith(".tre"))
|
{
|
texturedata = Uncompress(texturedata, name);
|
}
|
//else
|
|
if (name.contains("PathLMain"))
|
texturedata = texturedata;
|
|
// if (REDUCETEXTURE)
|
if (texturedata != null)
|
texturedata = ReduceTexture(texturedata, resolution);
|
|
// COMPRESSION TEST
|
if (COMPRESSTEXTURE) // || (name.toLowerCase().endsWith(".tre") && RESIZETEXTURE)) // true)
|
{
|
texturedata = CompressTexture(texturedata);
|
}
|
|
if (RESIZETEXTURE)
|
texturedata = Resize3x3(texturedata);
|
|
if (SAVETEXTURE)
|
{
|
// try
|
// {
|
// java.io.FileInputStream istream = new java.io.FileInputStream(name + ".tre");
|
// }
|
// catch (Exception e)
|
{
|
try
|
{
|
FileOutputStream ostream = new FileOutputStream(name + ".tre");
|
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
|
p.writeObject(((ByteBuffer) texturedata.getBuffer()).array());
|
p.flush();
|
|
ostream.close();
|
}
|
catch (Exception e2)
|
{
|
}
|
}
|
}
|
|
if (false)
|
{
|
// texture = CompressTexture2(name);
|
}
|
|
if (false)
|
{
|
texturedata = FFTtest(texturedata);
|
}
|
|
// // if (REDUCETEXTURE)
|
// texturedata = ReduceTexture(texturedata);
|
|
if (texturedata == null)
|
return null; // patch (for Eve)
|
|
if (bump) // !name.endsWith("NRM.jpg")
|
texturedata = ConvertBump(texturedata, name.endsWith("NRM.jpg") || name.endsWith("Normals.jpg"));
|
else
|
{
|
// if (true) // red filter
|
// texturedata = ConvertRed(texturedata);
|
// if (name.contains("forest")) // Black&white filter
|
// texturedata = ConvertBW(texturedata);
|
}
|
|
return texturedata;
|
}
|
|
/*
|
TextureData(int internalFormat, int width, int height, int border,
|
int pixelFormat, int pixelType, boolean mipmap,
|
boolean dataIsCompressed, boolean mustFlipVertically,
|
Buffer buffer, TextureData.Flusher flusher)
|
*/
|
TextureData ReduceTexture(TextureData texturedata, int resolution) // String name)
|
{
|
int pixelformat = texturedata.getPixelFormat();
|
|
int stride = 1;
|
if (pixelformat == GetGL().GL_RGB || pixelformat == GetGL().GL_BGR) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE)
|
stride = 3;
|
if (pixelformat == GetGL().GL_RGBA || pixelformat == GetGL().GL_BGRA) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE_ALPHA)
|
stride = 4;
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
// com.sun.opengl.util.texture.Texture texture = null;
|
|
// TextureData texturedata = null;
|
|
byte[] bytes = null;
|
|
try
|
{
|
// texturedata = com.sun.opengl.util.texture.TextureIO.newTextureData(new FileInputStream(name),
|
// true,
|
// GetFormat(name));
|
|
|
System.out.println("buffer = " + texturedata.getWidth() + "x" + texturedata.getHeight());
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
if (false) // debugtexture
|
{
|
//assert(imglength % 3 == 0);
|
System.out.println("#byte = " + bytes.length);
|
System.out.println("texturedata: " + texturedata);
|
System.out.println("getEstimatedMemorySize: " + texturedata.getEstimatedMemorySize());
|
System.out.println("getInternalFormat: " + texturedata.getInternalFormat());
|
System.out.println("getBorder: " + texturedata.getBorder());
|
System.out.println("getPixelFormat: " + texturedata.getPixelFormat());
|
System.out.println("getPixelType: " + texturedata.getPixelType());
|
System.out.println("getMipmap: " + texturedata.getMipmap());
|
System.out.println("isDataCompressed: " + texturedata.isDataCompressed());
|
System.out.println("getMustFlipVertically: " + texturedata.getMustFlipVertically());
|
System.out.println("getAlignment: " + texturedata.getAlignment());
|
}
|
} catch (Exception e)
|
{
|
e.printStackTrace();
|
|
Buffer buffer = ByteBuffer.allocate(texturedata.getWidth()*texturedata.getHeight()*stride);
|
|
bytes = // new byte[bytes.length];
|
((ByteBuffer) buffer).array();
|
|
int[] ints = ((IntBuffer) texturedata.getBuffer()).array();
|
|
assert(bytes.length == ints.length*4);
|
|
for (int b=0; b<ints.length; b++)
|
{
|
int inte = ints[b];
|
|
int b4 = b*4;
|
|
bytes[b4] = (byte)inte;
|
bytes[b4+1] = (byte)(inte>>>8);
|
bytes[b4+2] = (byte)(inte>>>16);
|
bytes[b4+3] = (byte)(inte>>>24);
|
}
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
texturedata.getPixelFormat(), texturedata.getPixelType(), texturedata.getMipmap(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffer, null);
|
|
//bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
// e.printStackTrace();
|
//return texturedata;
|
}
|
|
boolean square = false;
|
|
int restarget = 0;
|
|
switch (resolution)
|
{
|
case 0: restarget = 256*256; break;
|
case 1: restarget = 512*512; break;
|
case 2: restarget = 1024*1024; break;
|
case 3: restarget = 2048*2048; break;
|
case 4: restarget = 4096*4096; break;
|
case 5: restarget = 8192*8192; break;
|
}
|
|
// restarget = 512*512; // 512*512; // 2048; // 512; // 1024;
|
//
|
// if (!REDUCETEXTURE)
|
// restarget = 2048*2048; // 3072*3072; // 3072
|
|
// if (REDUCETEXTURE)
|
square = true; // (width/height < 2) && (height/width < 2); // TEXTURE COMPRESSION
|
|
if (square)
|
while (/*(width % 2) == 0 &&*/ (width*height > restarget))
|
{
|
int unzoom = 2;
|
|
System.out.println("... resized to " + (width/unzoom) + "x" + (height/unzoom));
|
|
ByteBuffer buffer = ByteBuffer.allocate((width/unzoom)*(height/unzoom)*stride);
|
|
byte[] newbytes = // new byte[bytes.length];
|
buffer.array();
|
|
//System.arraycopy(bytes,0,newbytes,0,bytes.length);
|
if (unzoom == 2)
|
ResizeDown(bytes, width, height, stride, newbytes);
|
else
|
ResizeDown3x3(bytes, width, height, stride, newbytes);
|
|
width /= unzoom;
|
height /= unzoom;
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
texturedata.getPixelFormat(), texturedata.getPixelType(), texturedata.getMipmap(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffer, null);
|
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
//assert(imglength % 3 == 0);
|
System.out.println("... #byte = " + bytes.length);
|
}
|
|
if (false) // MIPMAP)
|
{
|
int keepw = width;
|
int keeph = height;
|
|
int count = 1;
|
|
while (width%2 == 0 && height%2 == 0)
|
{
|
width /= 2; height /= 2;
|
count++;
|
}
|
|
width = keepw;
|
height = keeph;
|
|
ByteBuffer[] buffers = new ByteBuffer[count];
|
|
count = 0;
|
|
buffers[count] = ByteBuffer.allocate(bytes.length);
|
|
System.arraycopy(bytes, 0, buffers[count].array(), 0, bytes.length);
|
|
while (width%2 == 0 && height%2 == 0)
|
{
|
count++;
|
|
ByteBuffer buffer = ByteBuffer.allocate((width/2)*(height/2)*stride);
|
|
buffers[count] = buffer;
|
|
byte[] newbytes = buffer.array();
|
|
ResizeDown(bytes, width, height, stride, newbytes);
|
|
width /= 2;
|
height /= 2;
|
|
bytes = newbytes;
|
}
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
texturedata.getPixelFormat(), texturedata.getPixelType(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffers, null);
|
|
// bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
}
|
|
//System.gc();
|
return texturedata;
|
|
/*
|
//if (!name.equals("/Users/nbriere/Downloads/google/Female_Model_01/images/texture0.JPG") &&
|
// !name.equals("/Users/nbriere/Textures/tilesand.JPG"))
|
{
|
texture =
|
com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
|
texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
texturedata.flush();
|
}
|
|
System.gc();
|
|
return texture;
|
*/
|
}
|
|
void ConvertBump(byte[] origin, int width, int height, int stride, byte[] dest, boolean normalmap)
|
{
|
/*
|
float moy = 0;
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = j * width + i;
|
|
int o = origin[index*stride + 0];
|
o &= 255;
|
|
moy += o;
|
}
|
}
|
|
moy /= width * height;
|
*/
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = j * width + i;
|
|
if (normalmap)
|
{
|
cStatic.point3.y = origin[index*stride + 0]&255;
|
cStatic.point3.x = origin[index*stride + 1]&255;
|
cStatic.point3.z = origin[index*stride + 2]&255;
|
|
cStatic.point3.x -= 127;
|
cStatic.point3.y -= 127;
|
cStatic.point3.z -= 127;
|
|
cStatic.point3.normalize();
|
cStatic.point3.y -= 1;
|
//cStatic.point3.normalize();
|
|
dest[index*3 + 0] = (byte)(cStatic.point3.x * 127 + 127);
|
dest[index*3 + 1] = (byte)(cStatic.point3.y * 127 + 127);
|
dest[index*3 + 2] = (byte)(cStatic.point3.z * 127 + 127);
|
}
|
else
|
{
|
int i1 = 1;
|
int j1 = 1;
|
if (i == width-1)
|
i1 = -1;
|
if (j == height-1)
|
j1 = -1;
|
//int index00 = (j * width + i);
|
int index01 = j * width + (i+i1);
|
int index10 = (j+j1) * width + i;
|
//int index11 = ((j+1) * width + i+1);
|
|
int o = origin[index*stride + 0];
|
o &= 255;
|
int x1 = origin[index01*stride + 0];
|
x1 &= 255;
|
int y1 = origin[index10*stride + 0];
|
y1 &= 255;
|
|
float dx = x1 - o; // moy;
|
float dy = y1 - o; // moy;
|
|
cStatic.point1.set(1,dx/10,0);
|
cStatic.point1.normalize();
|
cStatic.point2.set(0,dy/10,1);
|
cStatic.point2.normalize();
|
cStatic.point3.cross(cStatic.point1,cStatic.point2);
|
cStatic.point3.normalize();
|
cStatic.point3.y -= 1;
|
//cStatic.point3.normalize();
|
|
dest[index*3 + 0] = (byte)(cStatic.point3.x * 127 + 127);
|
dest[index*3 + 1] = (byte)(cStatic.point3.y * 127 + 127);
|
dest[index*3 + 2] = (byte)(cStatic.point3.z * 127 + 127);
|
}
|
}
|
}
|
}
|
|
void ConvertRed(byte[] origin, int width, int height, int stride, byte[] dest)
|
{
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = j * width + i;
|
|
int b = origin[index*stride + 0];
|
b &= 255;
|
int g = origin[index*stride + 1];
|
g &= 255;
|
int r = origin[index*stride + 2];
|
r &= 255;
|
|
int diff = r - b;
|
|
if (diff > r - g)
|
diff = r - g;
|
|
if (diff < 0)
|
diff = 0;
|
|
float factor = diff;
|
|
factor /= r;
|
|
factor = (float)Math.sqrt(factor);
|
//factor = (float)Math.sqrt(factor);
|
|
if (factor < 0.5)
|
{
|
// avril 2014 not red enough
|
dest[index*stride + 0] = (byte)b;
|
dest[index*stride + 1] = (byte)g;
|
dest[index*stride + 2] = (byte)r;
|
continue;
|
}
|
else
|
{
|
// r = 255 - r;
|
r = (int)(factor*255 + (1-factor)*r);
|
dest[index*stride + 0] = (byte)r;
|
dest[index*stride + 1] = (byte)r;
|
dest[index*stride + 2] = (byte)r;
|
continue;
|
}
|
|
/*
|
if (r > 2*g && r > 2*b)
|
{
|
r *= 3;
|
if (r > 255)
|
r = 255;
|
g = r;
|
b = r;
|
}
|
*/
|
|
// r = (int)(factor*255 + (1-factor)*r);
|
// g = (int)(factor*255 + (1-factor)*g);
|
// b = (int)(factor*255 + (1-factor)*b);
|
//
|
// dest[index*stride + 0] = (byte)b;
|
// dest[index*stride + 1] = (byte)g;
|
// dest[index*stride + 2] = (byte)r;
|
}
|
}
|
}
|
|
void ConvertBW(byte[] origin, int width, int height, int stride, byte[] dest)
|
{
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = j * width + i;
|
|
int b = origin[index*stride + 0];
|
b &= 255;
|
int g = origin[index*stride + 1];
|
g &= 255;
|
int r = origin[index*stride + 2];
|
r &= 255;
|
|
int gray = (r+g+b)/3;
|
|
r = (int)gray;
|
g = (int)gray;
|
b = (int)gray;
|
|
dest[index*stride + 0] = (byte)b;
|
dest[index*stride + 1] = (byte)g;
|
dest[index*stride + 2] = (byte)r;
|
}
|
}
|
}
|
|
TextureData ConvertBump(TextureData texturedata, boolean normalmap) // String name)
|
{
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
int stride = 1;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGB || texturedata.getPixelFormat() == GetGL().GL_BGR) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE)
|
stride = 3;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGBA || texturedata.getPixelFormat() == GetGL().GL_BGRA) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE_ALPHA)
|
stride = 4;
|
|
Buffer buffer = ByteBuffer.allocate(width*height*3);
|
|
byte[] newbytes = // new byte[bytes.length];
|
((ByteBuffer) buffer).array();
|
|
//System.arraycopy(bytes,0,newbytes,0,bytes.length);
|
ConvertBump(bytes, width, height, stride, newbytes, normalmap);
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
GetGL().GL_RGB /*texturedata.getPixelFormat()*/, texturedata.getPixelType(), texturedata.getMipmap(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffer, null);
|
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
return texturedata;
|
}
|
|
TextureData ConvertRed(TextureData texturedata) // String name)
|
{
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
int stride = 1;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGB || texturedata.getPixelFormat() == GetGL().GL_BGR) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE)
|
stride = 3;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGBA || texturedata.getPixelFormat() == GetGL().GL_BGRA) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE_ALPHA)
|
stride = 4;
|
|
if (stride != 3)
|
return texturedata;
|
|
Buffer buffer = ByteBuffer.allocate(width*height*3);
|
|
byte[] newbytes = // new byte[bytes.length];
|
((ByteBuffer) buffer).array();
|
|
//System.arraycopy(bytes,0,newbytes,0,bytes.length);
|
ConvertRed(bytes, width, height, stride, newbytes);
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
texturedata.getPixelFormat(), texturedata.getPixelType(), texturedata.getMipmap(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffer, null);
|
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
return texturedata;
|
}
|
|
TextureData ConvertBW(TextureData texturedata)
|
{
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
int stride = 1;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGB || texturedata.getPixelFormat() == GetGL().GL_BGR) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE)
|
stride = 3;
|
if (texturedata.getPixelFormat() == GetGL().GL_RGBA || texturedata.getPixelFormat() == GetGL().GL_BGRA) // || texturedata.getPixelFormat() == GL.GL_LUMINANCE_ALPHA)
|
stride = 4;
|
|
if (stride < 3)
|
return texturedata;
|
|
Buffer buffer = ByteBuffer.allocate(width*height*stride);
|
|
byte[] newbytes = // new byte[bytes.length];
|
((ByteBuffer) buffer).array();
|
|
System.arraycopy(bytes,0,newbytes,0,bytes.length);
|
ConvertBW(bytes, width, height, stride, newbytes);
|
|
texturedata = new TextureData(texturedata.getInternalFormat(), width, height, texturedata.getBorder(),
|
texturedata.getPixelFormat(), texturedata.getPixelType(), texturedata.getMipmap(), texturedata.isDataCompressed(),
|
texturedata.getMustFlipVertically(), buffer, null);
|
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
return texturedata;
|
}
|
|
void ResizeDown(byte[] origin, int width, int height, int stride, byte[] small)
|
{
|
for (int j = 0; j < height/2; j++)
|
{
|
for (int i = 0; i < width/2; i++)
|
{
|
int index = (j * (width/2) + i);
|
|
int i0 = 2*i;
|
int j0 = 2*j;
|
|
// if (i0 >= width-1 || j0 >= height-1)
|
// continue;
|
|
int index00 = (j0 * width + i0);
|
int index01 = (j0 * width + i0+1);
|
int index10 = ((j0+1) * width + i0);
|
int index11 = ((j0+1) * width + i0+1);
|
|
try
|
{
|
for (int k = 0; k < stride; k++)
|
{
|
int o00 = origin[index00*stride + k];
|
o00 &= 255;
|
int o01 = origin[index01*stride + k];
|
o01 &= 255;
|
int o10 = origin[index10*stride + k];
|
o10 &= 255;
|
int o11 = origin[index11*stride + k];
|
o11 &= 255;
|
int val = o00 + o01 + o10 + o11;
|
val /= 4;
|
if (val < 0)
|
val = 0;
|
if (val > 255)
|
val = 255;
|
small[index*stride + k] = (byte)(val);
|
}
|
}
|
catch(Exception e)
|
{
|
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
}
|
}
|
}
|
}
|
|
void ResizeDown3x3(byte[] origin, int width, int height, int stride, byte[] small)
|
{
|
for (int j = 0; j < height/3; j++)
|
{
|
for (int i = 0; i < width/3; i++)
|
{
|
int index = (j * (width/3) + i);
|
|
int i0 = 3*i;
|
int j0 = 3*j;
|
|
// if (i0 >= width-1 || j0 >= height-1)
|
// continue;
|
|
int index00 = (j0 * width + i0);
|
int index01 = (j0 * width + i0+1);
|
int index02 = (j0 * width + i0+2);
|
int index10 = ((j0+1) * width + i0);
|
int index11 = ((j0+1) * width + i0+1);
|
int index12 = ((j0+1) * width + i0+2);
|
int index20 = ((j0+2) * width + i0);
|
int index21 = ((j0+2) * width + i0+1);
|
int index22 = ((j0+2) * width + i0+2);
|
|
try
|
{
|
for (int k = 0; k < stride; k++)
|
{
|
int o00 = origin[index00*stride + k];
|
o00 &= 255;
|
int o01 = origin[index01*stride + k];
|
o01 &= 255;
|
int o02 = origin[index02*stride + k];
|
o02 &= 255;
|
int o10 = origin[index10*stride + k];
|
o10 &= 255;
|
int o11 = origin[index11*stride + k];
|
o11 &= 255;
|
int o12 = origin[index12*stride + k];
|
o12 &= 255;
|
int o20 = origin[index20*stride + k];
|
o20 &= 255;
|
int o21 = origin[index21*stride + k];
|
o21 &= 255;
|
int o22 = origin[index22*stride + k];
|
o22 &= 255;
|
int val = o00 + o01 + o02;
|
val += o10 + o11 + o12;
|
val += o20 + o21 + o22;
|
val /= 9;
|
if (val < 0)
|
val = 0;
|
if (val > 255)
|
val = 255;
|
small[index*stride + k] = (byte)(val);
|
}
|
}
|
catch(Exception e)
|
{
|
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
}
|
}
|
}
|
}
|
|
static float[] triple = new float[3];
|
|
com.sun.opengl.util.texture.Texture CompressTexture2(String name)
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
com.sun.opengl.util.texture.Texture texture = null;
|
|
TextureData texturedata = null;
|
|
int imglength = 0;
|
int inputlength = 0;
|
|
byte[] bytes = null;
|
byte[] rgb = null;
|
byte[] hsb = null;
|
|
byte[] buffer = null;
|
|
boolean usehsb = false;
|
|
boolean oneline = false;
|
|
int width = 0;
|
int height = 0;
|
|
try
|
{
|
texturedata = com.sun.opengl.util.texture.TextureIO.newTextureData(new FileInputStream(name),
|
true,
|
GetFormat(name));
|
|
|
System.out.println("buffer = " + texturedata.getWidth() + "x" + texturedata.getHeight());
|
bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
inputlength = imglength = bytes.length;
|
//assert(imglength % 3 == 0);
|
System.out.println("#byte = " + inputlength);
|
{
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos = new java.util.zip.GZIPOutputStream(baos);
|
gzos.write(bytes);
|
gzos.finish();
|
|
System.out.println("#GZIP bytes = " + baos.toByteArray().length + " (" + (baos.toByteArray().length * 100 / (float) imglength) + "%)");
|
}
|
} catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
|
width = texturedata.getWidth();
|
height = texturedata.getHeight();
|
|
if (oneline)
|
{
|
height = 1;
|
}
|
|
inputlength = imglength = width * height * 3;
|
|
System.out.println("inputlength = " + inputlength);
|
|
/**/
|
rgb = new byte[imglength];
|
hsb = new byte[imglength];
|
|
int stride = imglength / 3;
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
for (int l = 0; l < 3; l++)
|
{
|
rgb[l * stride + index] = bytes[index * 3 + l];
|
}
|
|
float r = bytes[index*3] & 0xFF;
|
float g = bytes[index*3 + 1] & 0xFF;
|
float b = bytes[index*3 + 2] & 0xFF;
|
//if (r<0) assert(false); // r += 256;
|
//if (g<0) assert(false); // g += 256;
|
//if (b<0) assert(false); // b += 256;
|
//cColor.RGBtoHSB(r / 255, g / 255, b / 255, triple);
|
if (IQY)
|
cColor.RGBtoIQY(r / 255, g / 255, b / 255, triple);
|
else
|
cColor.RGBtoUVY(r / 255, g / 255, b / 255, triple);
|
|
//if(triple[0] < 0) triple[0] += 1;
|
//if(triple[1] < 0) triple[1] += 1;
|
//if(triple[2] < 0) triple[2] += 1;
|
//System.out.println("saturation = " + triple[1]);
|
assert (triple[0] >= 0 && triple[0] <= 1);
|
assert (triple[1] >= 0 && triple[1] <= 1);
|
assert (triple[2] >= 0 && triple[2] <= 1);
|
|
hsb[index] = (byte) (triple[0] * 255); // short
|
hsb[index + stride] = (byte) (triple[1] * 255); // short
|
hsb[index + 2 * stride] = (byte) (triple[2] * 255); // short
|
// float h = hsb[index];
|
// float s = hsb[index + stride];
|
// float v = hsb[index + 2*stride];
|
//System.out.println("h = " + h + "; s = " + s + "; v = " + v);
|
}
|
}
|
/**/
|
|
if (usehsb)
|
{
|
buffer = hsb;
|
} else
|
{
|
buffer = rgb;
|
}
|
|
float MSE = 0;
|
|
if (buffer != bytes)
|
{
|
//int stride = buffer.length / 3;
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
//for(int l=0;l<3;l++)
|
{
|
int index = (j * width + i);
|
|
float h = hsb[index] & 0xFF;
|
float s = hsb[index + stride] & 0xFF;
|
float v = hsb[index + 2 * stride] & 0xFF;
|
|
//if (h<0) assert(false); // h += 256;
|
//if (s<0) assert(false); // s += 256;
|
//if (v<0) assert(false); // v += 256;
|
//System.out.println("h = " + h + "; s = " + s + "; v = " + v);
|
//cColor.HSBtoRGB(h / 255, s / 255, v / 255, triple);
|
|
if (IQY)
|
cColor.IQYtoRGB(h / 255, s / 255, v / 255, triple);
|
else
|
cColor.UVYtoRGB(h / 255, s / 255, v / 255, triple);
|
|
/*
|
assert(triple[0] >= 0);
|
assert(triple[1] >= 0);
|
assert(triple[2] >= 0);
|
assert(triple[0] <= 1);
|
assert(triple[1] <= 1);
|
assert(triple[2] <= 1);
|
*/
|
|
float r = triple[0] * 255;
|
float g = triple[1] * 255;
|
float b = triple[2] * 255;
|
|
if (buffer == rgb)
|
{
|
r = rgb[(j * width + i)] & 0xFF;
|
g = rgb[inputlength / 3 + (j * width + i)] & 0xFF;
|
b = rgb[2 * inputlength / 3 + (j * width + i)] & 0xFF;
|
}
|
|
//if(i<width-2)
|
// index += 2;
|
float r0 = bytes[index * 3] & 0xFF;
|
float g0 = bytes[index * 3 + 1] & 0xFF;
|
float b0 = bytes[index * 3 + 2] & 0xFF;
|
//if(i<width-2)
|
// index -= 2;
|
//if (r0<0) r0 += 256;
|
//if (g0<0) g0 += 256;
|
//if (b0<0) b0 += 256;
|
|
MSE += (r0 - r) * (r0 - r);
|
MSE += (g0 - g) * (g0 - g);
|
MSE += (b0 - b) * (b0 - b);
|
|
// Debug
|
//int index2 = (j/3*width + i);
|
//bytes[index2] = (byte)h; // (triple[0]*255);
|
//bytes[index2 + stride] = (byte)s; // (triple[1]*255);
|
//bytes[index2 + 2*stride] = (byte)b; // (triple[2]*255);
|
/*
|
int cas = j/(height/128);
|
// r = h; g = s; b = v;
|
if (cas%3 == 0)
|
{
|
r = 0; g = 0; b = h;
|
}
|
else if (cas%3 == 1)
|
{
|
r = 0; g = s; b = 0;
|
}
|
else
|
{
|
r = v; g = 0; b = 0;
|
}
|
/**/
|
|
//int rs = image[index];
|
//int gs = image[index + stride];
|
//int bs = image[index + stride*2];
|
|
//if (rs < -rs) rs = -rs;
|
//if (gs < -gs) gs = -gs;
|
//if (bs < -bs) bs = -bs;
|
|
index *= 3;
|
bytes[index] = (byte) r;
|
bytes[index + 1] = (byte) g;
|
bytes[index + 2] = (byte) b;
|
}
|
}
|
}
|
}
|
|
MSE /= width * height * 3;
|
System.out.println("MSE = " + MSE);
|
System.out.println("PSNR = " + 10 * Math.log10(65536 / MSE));
|
|
texture =
|
com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
|
texturedata.flush();
|
|
return texture;
|
}
|
|
TextureData FFTtest(TextureData texturedata)
|
{
|
int imglength = 0;
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
int size2 = 1;
|
|
while (size2 < width || size2 < height)
|
{
|
size2 <<= 1;
|
}
|
|
int stride = 3; // 1
|
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
//imglength = bytes.length;
|
//assert(imglength % 3 == 0);
|
|
imglength = width*height;
|
|
System.out.println("width = " + width);
|
System.out.println("height = " + height);
|
System.out.println("size2 = " + size2);
|
System.out.println("length = " + imglength);
|
System.out.println("#byte = " + bytes.length);
|
|
int[] ints = new int[imglength];
|
double[] floats = new double[size2*size2];
|
double[] floats4x4 = new double[size2*size2];
|
|
for (int j = 0; j < size2; j++)
|
{
|
for (int i = 0; i < size2; i++)
|
{
|
int index2 = (j * size2 + i);
|
|
int val = 0;
|
int val4x4 = 0;
|
|
if (i<width && j<height)
|
{
|
int index = (j * width + i);
|
int index4x4 = ((j/4*4) * width + i/4*4);
|
int index4x401 = (((j/4+1)*4) * width + i/4*4);
|
int index4x410 = ((j/4*4) * width + (i/4+1)*4);
|
int index4x411 = (((j/4+1)*4) * width + (i/4+1)*4);
|
|
int modi = i%4;
|
int modj = j%4;
|
|
double x = modi/4.0;
|
double y = modj/4.0;
|
|
int valx = bytes[index4x4 * stride]&0xFF;
|
|
try
|
{
|
int val00 = valx;
|
int val01 = bytes[index4x401 * stride]&0xFF;
|
int val11 = bytes[index4x411 * stride]&0xFF;
|
int val10 = bytes[index4x410 * stride]&0xFF;
|
|
double valy = val00*(1-y) + val01*y;
|
double valy2 = val10*(1-y) + val11*y;
|
|
valx = (int)(valy*(1-x) + valy2*x);
|
}
|
catch (Exception e)
|
{
|
}
|
|
val4x4 |= (int)valx;
|
|
for (int k = 0; k < stride; k++)
|
{
|
val |= (bytes[index * stride + k]&0xFF)<<(k*8);
|
//val4x4 |= (bytes[index4x4 * stride + k]&0xFF)<<(k*8);
|
}
|
}
|
|
//ints[index] = val;
|
floats[index2] = val & 0xFF;
|
//Float.intBitsToFloat(val);
|
floats4x4[index2] = val4x4 & 0xFF;
|
}
|
}
|
|
double[] usedfloats = floats4x4;
|
double[] filter = new double[size2*size2];
|
|
//FFT fft = new FFT(floats, size2, size2);
|
FHT fht = new FHT(floats, size2, size2);
|
FHT fht4x4 = new FHT(floats4x4, size2, size2);
|
|
/**
|
// fft.intermediate = FreqFilter.filter(fft.intermediate, lowpass, radius);
|
|
// final Image foutput = createImage(new MemoryImageSource(width, height, fft.getPixels(), 0, width));
|
|
InverseFFT inverseFFT = new InverseFFT();
|
|
TwoDArray output = inverseFFT.transform(fft.intermediate);
|
|
// final Image invFourier = createImage(new MemoryImageSource(output.width, output.height, inverse.getPixels(output), 0, output.width));
|
|
ints = inverseFFT.getPixels(output);
|
/**/
|
|
//double[] reals;
|
|
// floats = InverseFFT.transform(fft.output).getReal();
|
|
//floats = fft.output.getReal();
|
//ints = fft.getPixels();
|
// ints = InverseFFT.toInts(reals);
|
|
boolean freqdomain = true;
|
|
try
|
{
|
fht.transform(false);
|
fht4x4.transform(false);
|
|
for (int p=0; p<size2*size2; p++)
|
{
|
// fht4x4.input[p] = fht.input[p] / fht4x4.input[p];
|
}
|
/**/
|
for (int j = 0; j < size2; j++)
|
{
|
for (int i = size2/4; i < size2; i+=size2/4)
|
{
|
double scale = 1;
|
if (i == size2/2)
|
scale = 0.5;
|
|
int index2 = (j * size2 + i);
|
|
double wave = j%(size2/2);
|
|
wave = Math.abs(wave - size2/4)/(size2/4);
|
|
wave = 1 - wave*wave;
|
|
//double line = 0.5;
|
|
for (int k=-size2/4; k<size2/4; k++)
|
{
|
double val = scale * (0.5 + wave*wave) * Math.exp(-Math.abs(k/32.0));
|
filter[index2+k] = Math.max(val,filter[index2+k]);
|
}
|
|
index2 = (i * size2 + j);
|
|
for (int k=-size2/4; k<size2/4; k++)
|
{
|
double val = scale * (0.5 + wave*wave) * Math.exp(-Math.abs(k/32.0));
|
filter[index2+k*size2] = Math.max(val,filter[index2+k*size2]);
|
}
|
// System.out.println(fht4x4.input[index2+k*size2]);
|
}
|
}
|
|
for (int k=100; --k>=0;)
|
SmoothBuffer(filter, size2,size2);
|
|
for (int j = 0; j < size2; j++)
|
{
|
for (int i = 0; i < size2; i++)
|
{
|
int index2 = (j * size2 + i);
|
|
//fht4x4.input[index2] *= (8 - filter[index2]*(4<<compressbit))/8;
|
fht4x4.input[index2] *= 1 + filter[index2]*(2<<clampbit);
|
//fht4x4.input[index2] = filter[index2]*16;
|
}
|
}
|
/**/
|
|
//FreqFilter.filterCorners(floats,size2, true, 8<<compressbit);
|
//FreqFilter.filterCenter(floats,size2, lowpass, radius);
|
|
// fht.transform(true);
|
fht4x4.transform(true); freqdomain = false;
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
int index2 = (j * size2 + i);
|
|
//int val = ints[index];
|
double valr = usedfloats[index2];
|
|
if (freqdomain)
|
{
|
// if (valr < 0)
|
// valr = -Math.log(-valr);
|
// else
|
// valr = Math.log(valr);
|
}
|
|
// if (valr < 0)
|
double valn = -valr;
|
|
if (freqdomain)
|
{
|
// if (valn < 0)
|
// valn = -Math.log(-valn);
|
// else
|
// valn = Math.log(valn);
|
}
|
|
if (valr < 0)
|
valr = 0;
|
if (valr > 255)
|
valr = 255;
|
|
if (valn < 0)
|
valn = 0;
|
if (valn > 255)
|
valn = 255;
|
|
// int val = (int)valr; // Float.floatToIntBits(floats[index2]);
|
|
// if (i<width && j<height)
|
{
|
for (int k = 0; k < stride; k++)
|
{
|
//if (k>0)
|
// bytes[index * stride + k] = 0;
|
//else
|
//bytes[index * stride + k] = (byte) (ints[index]>>>(k*8));
|
bytes[index * stride + 0/*k*/] = (byte) valn; // (val>>>(k*8));
|
bytes[index * stride + 1/*k*/] = (byte) valr;
|
bytes[index * stride + 2/*k*/] = (byte) valr;
|
}
|
}
|
}
|
}
|
|
texturedata.flush();
|
|
return texturedata;
|
}
|
|
TextureData CompressTexture(TextureData texturedata)
|
{
|
/*
|
com.sun.opengl.util.texture.Texture texture = null;
|
|
TextureData texturedata = null;
|
try
|
{
|
texturedata = com.sun.opengl.util.texture.TextureIO.newTextureData(new FileInputStream(name),
|
true,
|
GetFormat(name));
|
} catch (Exception e)
|
{
|
}
|
|
if (texturedata == null)
|
return texture;
|
*/
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
/*
|
byte[] origin = new byte[bytes.length];
|
System.arraycopy(bytes,0,origin,0,bytes.length);
|
|
for (int j = 1; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
bytes[index*3] = bytes[i*3];
|
bytes[index*3+1] = bytes[i*3];
|
bytes[index*3+2] = bytes[i*3];
|
}
|
}
|
|
origin = new byte[bytes.length];
|
System.arraycopy(bytes,0,origin,0,bytes.length);
|
|
// original FFT
|
FFT fft = FFTransform(texturedata);
|
|
double[] originFFT = new double[bytes.length];
|
// System.arraycopy(bytes,0,originFFT,0,bytes.length);
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
originFFT[index*3] = fft.output.values[i][j].real;
|
originFFT[index*3+1] = fft.output.values[i][j].real;
|
originFFT[index*3+2] = fft.output.values[i][j].real;
|
}
|
}
|
|
|
System.arraycopy(origin,0,bytes,0,bytes.length);
|
*/
|
|
Compress(texturedata);
|
|
// SHARPNESS
|
/*
|
for (int p=0; p<1; p++)
|
{
|
System.arraycopy(bytes,0,origin,0,bytes.length);
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 1; i < width-1; i++)
|
{
|
for (int k=0; k<3; k++)
|
{
|
int index = (j * width + i);
|
|
int o_1 = origin[(index-1)*3+k];
|
o_1 &= 255;
|
int o0 = origin[(index)*3+k];
|
o0 &= 255;
|
int o1 = origin[(index+1)*3+k];
|
o1 &= 255;
|
int val = -o_1/2 + 2*o0 - o1/2;
|
if (val < 0)
|
val = 0;
|
if (val > 255)
|
val = 255;
|
bytes[index*3+k] = (byte)(val);
|
}
|
}
|
}
|
}
|
*/
|
|
/*
|
for (int j = 1; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
bytes[index*3] = bytes[i*3];
|
bytes[index*3+1] = bytes[i*3];
|
bytes[index*3+2] = bytes[i*3];
|
}
|
}
|
|
// fft = FFTransform(texturedata);
|
|
double[] compressFFT = new double[bytes.length];
|
// System.arraycopy(bytes,0,compressFFT,0,bytes.length);
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
compressFFT[index*3] = fft.output.values[i][j].real;
|
compressFFT[index*3+1] = fft.output.values[i][j].real;
|
compressFFT[index*3+2] = fft.output.values[i][j].real;
|
}
|
}
|
|
/**
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
double val = 0;
|
|
if (compressFFT[i*3] == 0)
|
{
|
assert(originFFT[i*3] == 0);
|
}
|
else
|
val = originFFT[i*3]/compressFFT[i*3];
|
|
byte valb = (byte)(64*val);
|
|
bytes[index*3] = valb;
|
bytes[index*3+1] = valb;
|
bytes[index*3+2] = valb;
|
}
|
}
|
/**/
|
|
/*
|
texture =
|
com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
|
texturedata.flush();
|
|
return texture;
|
*/
|
return texturedata;
|
}
|
|
FFT FFTransform(TextureData texturedata)
|
{
|
byte[] bytes = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
int[] ints = null;
|
|
int width = texturedata.getWidth();
|
int height = texturedata.getHeight();
|
|
int stride = 3; // 3
|
|
ints = new int[bytes.length];
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
for (int l = 0; l < stride; l++)
|
{
|
ints[index] = (bytes[index * stride + l]<<24)>>>24;
|
}
|
}
|
}
|
|
FFT fft = null; // new FFT(ints, width, height);
|
|
//int[] new
|
ints = fft.getPixels();
|
//ints = InverseFFT.toPixels(InverseFFT.transform(fft.output).getMagnitude());
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
for (int l = 0; l < stride; l++)
|
{
|
bytes[index * stride + l] = (byte) ints[index];
|
}
|
}
|
}
|
|
return fft;
|
}
|
|
boolean sevenbits = false; // true;
|
boolean compress = true; // true;
|
int minlength = 64;
|
|
boolean DEBUGHSB = false;
|
boolean ZEROVALUES = false; // false;
|
boolean HUESHIFT = false; // false;
|
boolean SATSHIFT = false; // false;
|
|
boolean IQY = true; // !!! false;
|
|
boolean COMPACT = false; // true; // edge detector. always true for compression
|
|
boolean CLAMPLOW = true;
|
|
int quality = 2; // 0 == exact, 1 == nice, 2 == average, 3 == draft
|
|
boolean exact = quality == 0;
|
|
boolean usehsb = false; // false; // bug overflow
|
boolean usergb = true; // otherwise == interleaved (original)
|
|
boolean oneline = false;
|
|
byte[] CompressDIFF(short[] buffer, boolean minimal)
|
{
|
byte[] compbuf = new byte[buffer.length];
|
|
int imglength = buffer.length;
|
|
short current = 0;
|
|
int p = 0;
|
|
boolean goup = true;
|
|
for (int i = 0; i < imglength; i++)
|
{
|
byte/*short*/ dif = (byte) (buffer[i] - current);
|
|
if (!exact && dif == -128)
|
{
|
dif = -127;
|
}
|
|
short adif = dif;
|
|
if (adif < 0)
|
adif = (short) -adif;
|
|
// adif <<= kompactbit; //
|
// if (adif > 127)
|
// {
|
// adif &= 0x7F;
|
// adif |= 0x40;
|
// adif >>= kompactbit;
|
// }
|
// else
|
// {
|
// adif &= 0x7F;
|
adif >>= kompactbit;
|
// }
|
|
// if (adif > 127)
|
// assert(adif <= 127);
|
|
// byte
|
short diffval = 0;
|
|
if (false)
|
{
|
// diffval = adif;
|
if (adif > 0)
|
{
|
/*
|
short bit = 128;
|
|
while ((adif & bit) == 0)
|
{
|
bit >>= 1;
|
}
|
|
diffval = bit;
|
*/
|
|
if (adif >= 96)
|
diffval = 96;
|
else
|
if (adif >= 48)
|
diffval = 48;
|
else
|
if (adif >= 24)
|
diffval = 24;
|
else
|
if (adif >= 12)
|
diffval = 12;
|
else
|
if (adif >= 6)
|
diffval = 6;
|
else
|
if (adif >= 3)
|
diffval = 3;
|
else
|
diffval = 0; // 1;
|
|
// if (dif < 0)
|
// diffval = (short) -diffval;
|
}
|
|
// if (diffval == 24)
|
// diffval = 12;
|
// if (diffval == 6)
|
// diffval = 3;
|
// if (diffval == 1)
|
// diffval = 0;
|
|
if (diffval == 48)
|
diffval = 24;
|
if (diffval == 12)
|
diffval = 6;
|
if (diffval == 3)
|
diffval = 1;
|
|
if (diffval == -48)
|
diffval = -24;
|
if (diffval == -12)
|
diffval = -6;
|
if (diffval == -3)
|
diffval = -1;
|
|
// if (minimal)
|
// {
|
// /**
|
// if (diffval == 2)
|
// diffval = 1;
|
// if (diffval == 8)
|
// diffval = 4;
|
// if (diffval == 32)
|
// diffval = 16;
|
//
|
// if (diffval == -2)
|
// diffval = -1;
|
// if (diffval == -8)
|
// diffval = -4;
|
// if (diffval == -32)
|
// diffval = -16;
|
// /**/
|
// if (diffval == 1)
|
// diffval = 0;
|
// if (diffval == 4)
|
// diffval = 2;
|
// if (diffval == 16)
|
// diffval = 8;
|
// if (diffval == 64)
|
// diffval = 32;
|
//
|
// if (diffval == -1)
|
// diffval = 0;
|
// if (diffval == -4)
|
// diffval = -2;
|
// if (diffval == -16)
|
// diffval = -8;
|
// if (diffval == -64)
|
// diffval = -32;
|
// /**/
|
// }
|
// else
|
// {
|
// if (diffval == 1)
|
// diffval = 0;
|
// if (diffval == 4)
|
// diffval = 2;
|
// if (diffval == 16)
|
// diffval = 8;
|
// if (diffval == -1)
|
// diffval = 0;
|
// if (diffval == -4)
|
// diffval = -2;
|
// if (diffval == -16)
|
// diffval = -8;
|
// }
|
}
|
else
|
{
|
|
short bits = 0;
|
short nbbits = 0;
|
|
//if (cas % 3 >= 0) // == 2) // V
|
{
|
if ((adif & 0xE0) != 0)
|
{
|
bits = (short) 0xE0;
|
nbbits = 3;
|
} else
|
{
|
bits = (short) 0x10;
|
nbbits = 1;
|
/*
|
if ((adif&0x18) != 0)
|
{
|
bits = (short)0x18;
|
nbbits = 2;
|
}
|
else
|
{
|
bits = (short)0x04;
|
nbbits = 1;
|
}
|
/**/
|
}
|
}
|
|
diffval = dif;
|
|
if (!exact)
|
{
|
if (nbbits > 0)
|
{
|
if (dif >= 0)
|
{
|
short bit = bits;
|
|
while (bit != 0 && (bit & dif) == 0)
|
{
|
bit >>= nbbits;
|
}
|
|
diffval = (byte) (bit & dif);
|
//residu += dif & ~bit;
|
} else
|
{
|
adif = (byte) -dif;
|
|
short bit = bits;
|
|
while (bit != 0 && (bit & adif) == 0)
|
{
|
bit >>= nbbits;
|
}
|
|
diffval = (byte) -(bit & adif);
|
}
|
}
|
/**/
|
|
// remove +- 2
|
if (diffval == 2) // && ((i/(imglength/3))%3 != 0))
|
{
|
diffval = 1;
|
}
|
if (diffval == -2)
|
{
|
diffval = -1;
|
}
|
/**/
|
if (quality == 2)
|
{
|
if (diffval == 4) // && ((i/(imglength/3))%3 != 0))
|
{
|
if (dif >= 6)
|
{
|
diffval = 6;
|
} else
|
{
|
diffval = 1;
|
}
|
}
|
if (diffval == -4)
|
{
|
if (dif <= -6)
|
{
|
diffval = -6;
|
} else
|
{
|
diffval = -1;
|
}
|
}
|
if (diffval == 8)
|
{
|
diffval = 6;
|
}
|
if (diffval == -8)
|
{
|
diffval = -6;
|
}
|
/**/
|
/*
|
if (diffval == 32)
|
{
|
if (dif >= 40)
|
diffval = 40;
|
else
|
diffval = 16;
|
}
|
if (diffval == -32)
|
{
|
if (dif <= -40)
|
diffval = -40;
|
else
|
diffval = -16;
|
}
|
if (diffval == 64)
|
{
|
if (dif >= 96)
|
diffval = 96;
|
else
|
diffval = 40;
|
}
|
if (diffval == -64)
|
{
|
if (dif <= -96)
|
diffval = -96;
|
else
|
diffval = -40;
|
}
|
/**/
|
// too rare to save a lot
|
// if (diffval == 64)
|
// diffval = 32;
|
// if (diffval == -64)
|
// diffval = -32;
|
//if (diffval == 16)
|
// diffval = 6;
|
//if (diffval == -16)
|
// diffval = -6;
|
|
diffval = adif;
|
/**
|
if (adif >= 253)
|
diffval = 253;
|
else
|
if (adif >= 231)
|
diffval = 231;
|
else
|
if (adif >= 210)
|
diffval = 210;
|
else
|
if (adif >= 190)
|
diffval = 190;
|
else
|
if (adif >= 171)
|
diffval = 171;
|
else
|
if (adif >= 153)
|
diffval = 153;
|
else
|
if (adif >= 136)
|
diffval = 136;
|
else
|
/**/
|
// if (adif >= 120)
|
// diffval = 120;
|
// else
|
// if (adif >= 105)
|
// diffval = 105;
|
// else
|
if (adif >= 91)
|
diffval = 91;
|
else
|
// if (adif >= 78)
|
// diffval = 78;
|
// else
|
if (adif >= 66)
|
diffval = 66;
|
else
|
// if (adif >= 55)
|
// diffval = 55;
|
// else
|
if (adif >= 45)
|
diffval = 45;
|
else
|
// if (adif >= 36)
|
// diffval = 36;
|
// else
|
if (adif >= 28)
|
diffval = 28;
|
else
|
// if (adif >= 21)
|
// diffval = 21;
|
// else
|
if (adif >= 15)
|
diffval = 15;
|
else
|
// if (adif >= 10)
|
// diffval = 10;
|
// else
|
if (adif >= 6)
|
diffval = 6;
|
else
|
// if (adif >= 3)
|
// diffval = 3;
|
// else
|
/**
|
if (adif >= 96)
|
diffval = 96;
|
else
|
if (adif >= 56)
|
diffval = 56;
|
else
|
if (adif >= 25)
|
diffval = 25;
|
else
|
if (adif >= 12)
|
diffval = 12;
|
else
|
if (adif >= 5)
|
diffval = 5;
|
else
|
/**/
|
|
if (adif >= 1)
|
diffval = 1;
|
|
if (dif < 0)
|
diffval = (byte) -diffval;
|
|
if (diffval == 0) // && ((i/(imglength/3))%3 != 0))
|
{
|
if (goup && current < (1<<clampbit) - 1) // 127)
|
{
|
diffval = 1;
|
goup = false;
|
} else
|
{
|
if (current > 0)
|
{
|
diffval = -1;
|
goup = true;
|
} else
|
{
|
diffval = 1;
|
goup = false;
|
}
|
}
|
}
|
else
|
goup = diffval > 0;
|
}
|
}
|
}
|
//
|
// /*
|
// if ((dif&0xE0) != 0)
|
// {
|
// diffval = (short)(dif & ~0x1F);
|
// }
|
// else
|
// {
|
// if ((dif&0xE0) != 0)
|
// {
|
// diffval = (short)(dif & ~0x1F);
|
// }
|
// else
|
// {
|
//
|
// }
|
// }
|
// */
|
|
// if (diffval == 6)
|
// assert(diffval != 6);
|
|
current += diffval << kompactbit;
|
|
// current &= 0xFF;
|
if (current < 0)
|
current = 0;
|
if (current > 255)
|
current = 255;
|
|
// if (current >= 256)
|
// assert(current < 256);
|
// if (current < 0)
|
// assert(current >= 0);
|
|
compbuf[p++] = (byte)diffval;
|
}
|
|
//if (COMPACT && !exact)
|
if (true)
|
{
|
byte[] compactbuf = new byte[buffer.length/2];
|
|
int i2 = 0;
|
for (int i = 0; i < p;)
|
{
|
int dif = compbuf[i] & 0xFF;
|
|
//System.out.print("; dif = " + dif);
|
if (tabledif[dif] == -1)
|
assert (tabledif[dif] != -1);
|
//System.out.print("; dif2 = " + (image[i+1]&0xFF));
|
if (tabledif[compbuf[i + 1] & 0xFF] == -1)
|
assert (tabledif[compbuf[i + 1] & 0xFF] != -1);
|
compactbuf[i2] = (byte) ((tabledif[dif] << 4) | tabledif[compbuf[i + 1] & 0xFF]);
|
|
// invariants
|
int dif0 = compactbuf[i2];
|
short dif1 = (short) tabledif_1[(dif0>>4)&0xF];
|
short dif2 = (short) tabledif_1[dif0&0xF];
|
|
if((dif1&0xFF) != (dif&0xFF))
|
if (dif1 != dif)
|
assert(dif1 == dif);
|
if((dif2&0xFF) != (compbuf[i + 1]&0xFF))
|
if (dif2 != compbuf[i + 1])
|
assert(dif2 == compbuf[i + 1]);
|
|
i += 2;
|
i2 += 1;
|
}
|
|
compbuf = compactbuf;
|
imglength /= 2;
|
}
|
|
/**/
|
int[] counts = new int[256];
|
|
for (int i = 0; i < imglength; i++)
|
{
|
counts[compbuf[i] & 0xFF] += 1;
|
}
|
|
for (int i = 0; i < 256; i++)
|
{
|
System.out.print("" + counts[i] + ", ");
|
if (i % 16 == 15)
|
{
|
System.out.println();
|
}
|
}
|
/**/
|
|
return compbuf;
|
}
|
|
short[] UncompressDIFF(byte[] buffer)
|
{
|
short[] uncompbuf = new short[buffer.length*2];
|
|
int imglength = buffer.length;
|
|
short current = 0;
|
|
int l = 0;
|
for (int p = 0; p < imglength; p++)
|
{
|
short dif = buffer[p];
|
|
if (true) // COMPACT)
|
{
|
short dif2 = (short) tabledif_1[(dif>>4)&0xF];
|
current += dif2 << kompactbit;
|
//assert(current >= 0 && current < 256);
|
// current &= 0xFF;
|
|
if (current < 0)
|
current = 0;
|
if (current > 255)
|
current = 255;
|
uncompbuf[l++] = /*(byte)*/current;
|
dif2 = (short) tabledif_1[dif&0xF];
|
current += dif2 << kompactbit;
|
//assert(current >= 0 && current < 256);
|
//current &= 0xFF;
|
if (current < 0)
|
current = 0;
|
if (current > 255)
|
current = 255;
|
uncompbuf[l++] = /*(byte)*/current;
|
}
|
else
|
{
|
current += dif << kompactbit;
|
if (current < 0)
|
current = 0;
|
if (current > 255)
|
current = 255;
|
//current &= 0xFF;
|
//assert(current >= 0 && current < 256);
|
uncompbuf[p] = current;
|
}
|
}
|
|
return uncompbuf;
|
}
|
|
|
// not used
|
void CompressBufferDIFF(short[] buffer, short[] image, boolean minimal)
|
{
|
int imglength = buffer.length;
|
short current = 0;
|
|
//byte relax = 0;
|
//int cumul = 0;
|
|
//int current2 = 0;
|
|
//int residu = 0;
|
|
//int pixelcount = 0;
|
|
//boolean toggle = false;
|
|
boolean goup = true;
|
|
int p = 0;
|
int keepp = 0;
|
|
//boolean firsthalf = true;
|
|
int mark = -1; // index of starting 4-bit sequence
|
|
//byte error = 0;
|
for (int i = 0; i < imglength; i++)
|
{
|
// current + residu == buffer[i-1];
|
//short dif = (short) ((buffer[i] - current) & 0xFF);
|
short dif = (short) (buffer[i] - current);
|
|
// if (dif < 0)
|
// dif += 256;
|
|
// if (dif < 0)
|
// assert(dif >= 0);
|
//if (i > 0)
|
// dif = (byte) dif;
|
|
if (!exact && compress && dif == 127)
|
{
|
dif = 126;
|
} // 127 value means the next byte will
|
// contain the number of 1-bit diff values
|
|
short dif0 = dif;
|
|
int cas = i / (imglength / 3);
|
|
// if (usehsb && cas % 3 == 0) // HUE
|
// {
|
// if (dif > 63)
|
// {
|
// dif -= 128;
|
// } else if (dif < -64)
|
// {
|
// dif += 128;
|
// }
|
// }
|
|
if (!exact && dif == -128)
|
{
|
// dif = -127;
|
}
|
|
if (quality == 3)
|
{
|
if (dif > 1)
|
{
|
dif = 2;
|
} else
|
{
|
if (dif < -2)
|
{
|
dif = -2;
|
}
|
}
|
}
|
|
short adif = dif;
|
|
if (adif < 0)
|
adif = (short) -adif;
|
|
short diffval = adif;
|
|
if (adif > 0 && !exact)
|
{
|
short bit = 128;
|
|
while ((adif & bit) == 0)
|
{
|
bit >>= 1;
|
}
|
|
diffval = bit;
|
|
if (dif < 0)
|
diffval = (short) -diffval;
|
}
|
|
if (minimal)
|
{
|
/**
|
if (diffval == 2)
|
diffval = 1;
|
if (diffval == 8)
|
diffval = 4;
|
if (diffval == 32)
|
diffval = 16;
|
|
if (diffval == -2)
|
diffval = -1;
|
if (diffval == -8)
|
diffval = -4;
|
if (diffval == -32)
|
diffval = -16;
|
/**/
|
if (diffval == 1)
|
diffval = 0;
|
if (diffval == 4)
|
diffval = 2;
|
if (diffval == 16)
|
diffval = 8;
|
if (diffval == 64)
|
diffval = 32;
|
|
if (diffval == -1)
|
diffval = 0;
|
if (diffval == -4)
|
diffval = -2;
|
if (diffval == -16)
|
diffval = -8;
|
if (diffval == -64)
|
diffval = -32;
|
}
|
/**/
|
|
current += diffval;
|
|
assert(current < 256);
|
assert(current >= 0);
|
|
// if (current > 255)
|
// current -= 256;
|
|
image[p++] = diffval;
|
|
if (!exact)
|
{
|
// if (tabledif[diffval & 0xFF] == -1)
|
// {
|
// System.out.println("dif = " + dif + "; dif0 = " + dif0 + "; adif = " + adif + "; diffval = " + diffval);
|
// }
|
// assert (tabledif[diffval & 0xFF] != -1);
|
}
|
|
// Test for 4 bits compression
|
if (compress)
|
{
|
if (diffval == 1 || diffval == -1)
|
{
|
if (mark != -1)
|
{
|
int length = p - mark;
|
if (length == 255)
|
{
|
p = StopSequence(image, mark, length);
|
keepp = p;
|
mark = -1;
|
}
|
} else
|
{
|
if (!COMPACT || (p - keepp) % 2 == 1)
|
{
|
mark = p - 1;
|
}
|
}
|
} else
|
{
|
if (mark != -1)
|
{
|
int length = p - 1 - mark;
|
if (length >= minlength)
|
{
|
p = StopSequence(image, mark, length);
|
keepp = p;
|
image[p++] = diffval;
|
}
|
//else
|
// keepp = p-1;
|
|
mark = -1;
|
}
|
}
|
}
|
|
//error += diff2[i];
|
//diff2[i] = error;
|
|
/*
|
diff2[i] = (short)diff[i];
|
int d = Math.abs(current - current2);
|
current += diff[i];
|
assert(current == buffer[i]);
|
//if (current < 0)
|
// current += 256;
|
//if (current > 255)
|
// current -= 256;
|
assert(current >= 0 && current <= 255);
|
//System.out.println("diff = " + diff[i] + "; diff2 = " + diff2[i]);
|
//System.out.println("relax = " + relax);
|
cumul += d*d; // relax;
|
if (cumul > tolerance)
|
{
|
diff2[i] += relax;
|
diff[i] += relax;
|
relax = 0;
|
cumul = 0;
|
}
|
else if (diff[i] <= eps && diff[i] >= -eps)
|
{
|
relax += diff[i];
|
if (relax <= eps && relax >= -eps)
|
{
|
diff2[i] = 0;
|
diff[i] = 0;
|
}
|
else
|
{
|
diff2[i] = relax;
|
diff[i] = relax;
|
relax = 0;
|
cumul = 0;
|
}
|
}
|
current2 += diff2[i];
|
//System.out.println("diff = " + diff[i] + "; diff2 = " + diff2[i]);
|
//System.out.println("relax = " + relax);
|
//System.out.println("current = " + current + "; current2 = " + current2);
|
//if (current2 < 0) current2 = 0; // += 256;
|
//if (current2 > 255) current2 = 255; // -= 256;
|
assert(current2 >= 0 && current2 <= 255);
|
if(Math.abs(current - current2) > eps)
|
{
|
System.out.println("diff = " + diff[i] + "; diff2 = " + diff2[i]);
|
System.out.println("current = " + current + "; current2 = " + current2);
|
assert(Math.abs(current - current2) <= eps);
|
}
|
/**/
|
}
|
|
if (mark != -1)
|
{
|
assert(false);
|
int length = p - mark;
|
if (length >= minlength)
|
{
|
p = StopSequence(image, mark, length);
|
}
|
mark = -1;
|
}
|
|
System.out.println("compressed = " + p + " (" + (p * 100 / (float) imglength) + "%)");
|
|
if (COMPACT && !exact)
|
{
|
mark = 0;
|
int max = p;
|
int i2 = 0;
|
for (int i = 0; i < max;)
|
{
|
int dif = image[i] & 0xFF;
|
//System.out.print("; i = " + i);
|
if (!compress || dif != 127)
|
{
|
//System.out.print("; dif = " + dif);
|
assert (tabledif[dif] != -1);
|
//System.out.print("; dif2 = " + (image[i+1]&0xFF));
|
assert (tabledif[image[i + 1] & 0xFF] != -1);
|
image[i2 + mark] = (short) ((tabledif[dif] << 4) | tabledif[image[i + 1] & 0xFF]);
|
|
// invariants
|
int dif0 = image[i2 + mark];
|
short dif1 = (short) tabledif_1[(dif0>>4)&0xF];
|
short dif2 = (short) tabledif_1[dif0&0xF];
|
|
if((dif1&0xFF) != (dif&0xFF))
|
assert(dif1 == dif);
|
if((dif2&0xFF) != (image[i + 1]&0xFF))
|
assert(dif2 == image[i + 1]);
|
|
//? p--;
|
i += 2;
|
i2 += 1;
|
} else
|
{
|
assert ((image[i + 1] & 0xFF) >= minlength);
|
int start = i2 + mark;
|
//image[start++] = 127;
|
//image[start++] = image[i+1];
|
//int count = p - start; // ((image[i+1]&0xFF)+7)/8;
|
int nbbytes = ((image[i + 1] & 0xFF) + 7) / 8;
|
//System.out.print("; nbbytes = " + nbbytes);
|
for (int j = 0; j < nbbytes + 2; j++)
|
{
|
image[start + j] = image[i + j];
|
}
|
i += nbbytes + 2;
|
mark = start + nbbytes + 2;
|
i2 = 0;
|
}
|
}
|
|
imglength /= 2;
|
//p /= 2;
|
}
|
|
System.out.println();
|
System.out.println("compact = " + p + " (" + (p * 100 / (float) imglength) + "%)");
|
|
if (false) // compress || (compact && !exact))
|
{
|
short[] old = image;
|
image = new short[p];
|
System.arraycopy(old, 0, image, 0, p);
|
imglength = p;
|
}
|
|
int[] counts = new int[256];
|
|
for (int i = 0; i < imglength; i++)
|
{
|
counts[image[i] & 0xFF] += 1;
|
}
|
|
for (int i = 0; i < 256; i++)
|
{
|
if (i % 16 == 0)
|
{
|
System.out.println();
|
}
|
System.out.print("" + counts[i] + ", ");
|
}
|
System.out.println();
|
}
|
|
byte[] input = null;
|
short[] rgb = null;
|
short[] hsb = null; // short
|
short[] interleaved = null;
|
|
short[] hue = null;
|
short[] sat = null;
|
short[] bri = null;
|
|
//short[] diff2 = null;
|
|
short[] buffer = null; // short
|
|
short[] image = null;
|
|
byte[] CompressZIP(byte[] buf) //, boolean diff)
|
{
|
byte[] retbuf = null;
|
|
try
|
{
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos = new java.util.zip.GZIPOutputStream(baos);
|
gzos.write(buf);
|
gzos.finish();
|
|
retbuf = baos.toByteArray();
|
}
|
catch (Exception e)
|
{}
|
|
return retbuf;
|
}
|
|
byte[] Convert(short[] buf, boolean diff)
|
{
|
byte[] retbuf = new byte[buf.length];
|
|
short current = 0;
|
for (int i=0; i<buf.length; i++)
|
{
|
short clamp = buf[i];
|
|
if (clamp > 254) // for eliminating diffval == 0
|
clamp = 254;
|
if (clamp < 1)
|
clamp = 1;
|
|
retbuf[i] = (byte) (clamp - current);
|
if (diff)
|
current = clamp; // buf[i];
|
}
|
|
return retbuf;
|
}
|
|
// size of buffer image is 2w x 2h
|
void SetPixel(BufferedImage bufimage, int i2, int j2, byte[] input, int i, int j, int w, int h)
|
{
|
int p = ((h-1-j)*w + i)*3;
|
short r0 = (short)(input[p]&0xFF);
|
short g0 = (short)(input[p+1]&0xFF);
|
short b0 = (short)(input[p+2]&0xFF);
|
|
p = ((h-1-j)*w + i-1)*3;
|
short r1 = (short)(input[p]&0xFF);
|
short g1 = (short)(input[p+1]&0xFF);
|
short b1 = (short)(input[p+2]&0xFF);
|
|
p = ((h-1-(j-1))*w + i)*3;
|
short r2 = (short)(input[p]&0xFF);
|
short g2 = (short)(input[p+1]&0xFF);
|
short b2 = (short)(input[p+2]&0xFF);
|
|
p = ((h-1-j)*w + i+1)*3;
|
short r3 = (short)(input[p]&0xFF);
|
short g3 = (short)(input[p+1]&0xFF);
|
short b3 = (short)(input[p+2]&0xFF);
|
|
p = ((h-1-(j+1))*w + i)*3;
|
short r4 = (short)(input[p]&0xFF);
|
short g4 = (short)(input[p+1]&0xFF);
|
short b4 = (short)(input[p+2]&0xFF);
|
|
short r = r0;
|
short g = g0;
|
short b = b0;
|
|
int shiftbit = maskbit+5;
|
|
if ((r1>>shiftbit) == (r2>>shiftbit) && (g1>>shiftbit) == (g2>>shiftbit) && (b1>>shiftbit) == (b2>>shiftbit))
|
{
|
r = (short)((r1+r2)/2);
|
g = (short)((g1+g2)/2);
|
b = (short)((b1+b2)/2);
|
}
|
|
bufimage.setRGB(i2,j2, r << 16 | g << 8 | b);
|
|
r = r0; g = g0; b = b0;
|
|
if ((r2>>shiftbit) == (r3>>shiftbit) && (g2>>shiftbit) == (g3>>shiftbit) && (b2>>shiftbit) == (b3>>shiftbit))
|
{
|
r = (short)((r2+r3)/2);
|
g = (short)((g2+g3)/2);
|
b = (short)((b2+b3)/2);
|
}
|
|
bufimage.setRGB(i2+1,j2, r << 16 | g << 8 | b);
|
|
r = r0; g = g0; b = b0;
|
|
if ((r3>>shiftbit) == (r4>>shiftbit) && (g3>>shiftbit) == (g4>>shiftbit) && (b3>>shiftbit) == (b4>>shiftbit))
|
{
|
r = (short)((r3+r4)/2);
|
g = (short)((g3+g4)/2);
|
b = (short)((b3+b4)/2);
|
}
|
|
bufimage.setRGB(i2+1,j2+1, r << 16 | g << 8 | b);
|
|
r = r0; g = g0; b = b0;
|
|
if ((r4>>shiftbit) == (r1>>shiftbit) && (g4>>shiftbit) == (g1>>shiftbit) && (b4>>shiftbit) == (b1>>shiftbit))
|
{
|
r = (short)((r4+r1)/2);
|
g = (short)((g4+g1)/2);
|
b = (short)((b4+b1)/2);
|
}
|
|
bufimage.setRGB(i2,j2+1, r << 16 | g << 8 | b);
|
}
|
|
BufferedImage ResizeTexture(byte[] input, int w, int h)
|
{
|
System.out.println("FILTERBIT = " + clampbit);
|
System.out.println("POWERBIT = " + kompactbit);
|
System.out.println("MASKBIT = " + maskbit);
|
System.out.println("LOOPBIT = " + loopbit);
|
|
/*
|
byte[] input2x2 = new byte[w*2*h*2*3];
|
|
for (int i=0; i<w; i++)
|
{
|
for (int j=0; j<h; j++)
|
{
|
int index = j*w + i;
|
int index2x2 = 2*j*2*w + i*2;
|
|
for (int k=0; k<3; k++)
|
{
|
byte val = input[index*3+k];
|
|
input2x2[index2x2*3+k] = val;
|
input2x2[(index2x2+1)*3+k] = val;
|
input2x2[(index2x2+2*w)*3+k] = val;
|
input2x2[(index2x2+2*w+1)*3+k] = val;
|
}
|
}
|
}
|
|
BufferedImage bufimage4x4 = new BufferedImage(w*4, h*4, BufferedImage.TYPE_3BYTE_BGR);
|
|
for (int j=2*h-1; --j>=1;)
|
{
|
for (int i=2*w-1; --i>=1;)
|
{
|
SetPixel(bufimage4x4, 2*i,2*j, input2x2, i,j, 2*w, 2*h);
|
}
|
}
|
*/
|
|
int zoom = 3;
|
|
short[] input3x3 = new short[w*zoom*h*zoom*3];
|
|
for (int i=0; i<zoom*w; i++)
|
{
|
for (int j=0; j<zoom*h; j++)
|
{
|
int index = j * zoom*w + i;
|
|
int index3x300 = j/zoom * w + i/zoom;
|
int index3x301 = (j/zoom+1) * w + i/zoom;
|
int index3x310 = j/zoom * w + i/zoom+1;
|
int index3x311 = (j/zoom+1) * w + i/zoom+1;
|
|
double modi = i%zoom + 0.5;
|
double modj = j%zoom + 0.5;
|
|
double x = modi/zoom;
|
double y = modj/zoom;
|
|
//x = (Math.cos((x+1)*Math.PI) + 1) / 2;
|
//y = (Math.cos((y+1)*Math.PI) + 1) / 2;
|
|
/**
|
if (i%zoom == 0)
|
x = 0;
|
if (i%zoom == 2)
|
x = 1;
|
|
if (j%zoom == 0)
|
y = 0;
|
if (j%zoom == 2)
|
y = 1;
|
/**/
|
|
for (int k=3; --k>=0;)
|
{
|
int valx = input[index3x300*3 + k]&0xFF;
|
|
try
|
{
|
int val00 = valx;
|
int val01 = input[index3x301*3 + k]&0xFF;
|
int val11 = input[index3x311*3 + k]&0xFF;
|
int val10 = input[index3x310*3 + k]&0xFF;
|
|
double valy = val00*(1-y) + val01*y;
|
double valy2 = val10*(1-y) + val11*y;
|
|
valx = (int)(valy*(1-x) + valy2*x);
|
}
|
catch (Exception e)
|
{
|
}
|
|
int val3x3 = 0;
|
|
val3x3 |= (int)valx;
|
|
// for (int k = 0; k < 3; k++)
|
// {
|
// val |= (bytes[index * stride + k]&0xFF)<<(k*8);
|
// //val4x4 |= (bytes[index4x4 * stride + k]&0xFF)<<(k*8);
|
// }
|
|
input3x3[index*3 + k] = (short)val3x3;
|
}
|
}
|
}
|
|
float[] input3x3f = DuplicateFloat(input3x3);
|
float[] smoothed = DuplicateFloat(input3x3);
|
|
byte[] mask = GetMask(input,w,h);
|
|
tempbuffer = null;
|
|
int mbit = maskbit;
|
|
//for (int k=(1<<compressbit)-1; --k>=0;)
|
for (int k=1<<clampbit; --k>=0;)
|
{
|
// maskbit = 4;
|
CutCorners(smoothed, w*zoom,h*zoom, null); // input3x3f);
|
// SmoothBuffer(smoothed, w*zoom,h*zoom, input3x3f); // input4x4); // smoothed);
|
}
|
|
//for (int k=(1<<compressbit)-1; --k>=0;)
|
for (int k=(1<<loopbit); --k>=0;)
|
//for (int k=8; --k>=0;)
|
{
|
/** good version *
|
maskbit = ((8-zoom)-k/2); // 8 - (6-k/2);
|
// CutCorners(smoothed, w*zoom,h*zoom);
|
SharpenBuffer(smoothed, w*zoom,h*zoom, smoothed, null); // input3x3f);
|
// NormalizeBuffer(smoothed, w*zoom,h*zoom, input); // input3x3f);
|
/**/
|
SharpenBuffer(smoothed, w*zoom,h*zoom, null, mask); // input3x3f);
|
}
|
|
// maskbit = 4;
|
|
// for (int k=2; --k>=0;)
|
// CutCorners(smoothed, w*zoom,h*zoom, smoothed);
|
|
// for (int k=1; --k>=0;)
|
// SmoothBuffer(smoothed, w*zoom,h*zoom, smoothed);
|
|
maskbit = mbit;
|
|
/*
|
double[] supersmoothed = Duplicate(smoothed);
|
|
for (int s=(1<<compressbit); --s>=0;)
|
{
|
for (int pass=4; --pass>=0;)
|
SmoothBuffer(supersmoothed, w*4,h*4, input4x4f); // smoothed);
|
|
for (int i=0; i<4*w; i++)
|
{
|
for (int j=0; j<4*h; j++)
|
{
|
int index = j * 4*w + i;
|
// pixels[p] = (snapshotPixels[p] - weight * pixels[p]) / (1f - weight);
|
// float weight = 1 - 1.0f/(1<<compressbit);
|
|
for (int k=3; --k>=0;)
|
{
|
//rgb[k] = (short)((smoothed[index*3 + k] - weight * supersmoothed[index*3 + k]) / (1 - weight));
|
if (supersmoothed[index*3 + k] > 0)
|
{
|
double factor = (double)smoothed[index*3 + k] / supersmoothed[index*3 + k];
|
//double factor = Math.pow((double)smoothed[index*3 + k] / supersmoothed[index*3 + k], 1<<compressbit);
|
if (factor < 0.75)
|
factor = 0.75;
|
if (factor > 1.25)
|
factor = 1.25;
|
|
smoothed[index*3 + k] *= factor;
|
}
|
//short val4x4 = smoothed[index];
|
|
if (smoothed[index*3 + k] < 0)
|
smoothed[index*3 + k] = 0;
|
if (smoothed[index*3 + k] > 255)
|
smoothed[index*3 + k] = 255;
|
|
supersmoothed[index*3 + k] = smoothed[index*3 + k];
|
}
|
}
|
}
|
}
|
*/
|
|
short[] rgb = new short[3];
|
|
BufferedImage bufimage3x3 = new BufferedImage(w*zoom, h*zoom, BufferedImage.TYPE_3BYTE_BGR);
|
|
for (int i=0; i<zoom*w; i++)
|
{
|
for (int j=0; j<zoom*h; j++)
|
{
|
int index = j * zoom*w + i;
|
|
for (int k=3; --k>=0;)
|
{
|
//rgb[k] = (short)((smoothed[index*3 + k] - weight * supersmoothed[index*3 + k]) / (1 - weight));
|
rgb[k] = (short)smoothed[index*3 + k];
|
assert(rgb[k] >= 0);
|
assert(rgb[k] <= 255);
|
}
|
|
//short val4x4 = smoothed[index];
|
bufimage3x3.setRGB(i,zoom*h-1-j, rgb[0]<<16 | rgb[1]<<8 | rgb[2]);
|
}
|
}
|
|
|
return bufimage3x3;
|
}
|
|
short[] Duplicate(short[] input)
|
{
|
short[] output = new short[input.length];
|
|
System.arraycopy(input,0, output,0, input.length);
|
|
return output;
|
}
|
|
double[] Duplicate(double[] input)
|
{
|
double[] output = new double[input.length];
|
|
System.arraycopy(input,0, output,0, input.length);
|
|
return output;
|
}
|
|
float[] DuplicateFloat(short[] input)
|
{
|
float[] output = new float[input.length];
|
|
for (int p=input.length; --p>=0;)
|
output[p] = input[p];
|
|
return output;
|
}
|
|
TextureData Uncompress(TextureData texturedata, String name)
|
{
|
byte[] inputstring = null;
|
|
try
|
{
|
java.io.FileInputStream istream = new java.io.FileInputStream(name);
|
java.io.ObjectInputStream p = new java.io.ObjectInputStream(istream);
|
|
inputstring = (byte[]) p.readObject();
|
istream.close();
|
}
|
catch (Exception e)
|
{
|
|
}
|
|
byte[] imagebuffer = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
int length = inputstring.length;
|
|
if (inputstring.length != imagebuffer.length)
|
{
|
new Exception().printStackTrace();
|
|
if (length > imagebuffer.length)
|
length = imagebuffer.length;
|
}
|
|
System.arraycopy(inputstring, 0, imagebuffer, 0, length);
|
|
return texturedata;
|
}
|
|
TextureData Resize3x3(TextureData texturedata)
|
{
|
byte[] inputstring = ((ByteBuffer) texturedata.getBuffer()).array();
|
|
BufferedImage bufimage = ResizeTexture(inputstring, texturedata.getWidth(), texturedata.getHeight());
|
|
return new TextureData(0,0,MIPMAP,bufimage);
|
}
|
|
byte[] Resize3x3(byte[] input, int w, int h, int stride, int zoom, boolean linear)
|
{
|
byte[] output = new byte[w*zoom*h*zoom*stride];
|
|
for (int i=0; i<zoom*w; i++)
|
{
|
for (int j=0; j<zoom*h; j++)
|
{
|
int index = j * zoom*w + i;
|
|
int iz = i/zoom;
|
int jz = j/zoom;
|
|
int index3x300 = jz * w + iz;
|
int index3x301 = (jz+1) * w + iz;
|
int index3x310 = jz * w + iz+1;
|
int index3x311 = (jz+1) * w + iz+1;
|
|
double modi = i%zoom + 0.5;
|
double modj = j%zoom + 0.5;
|
|
double x = modi/zoom;
|
double y = modj/zoom;
|
|
// if (!linear)
|
// {
|
// x = y = 1;
|
// }
|
|
//x = (Math.cos((x+1)*Math.PI) + 1) / 2;
|
//y = (Math.cos((y+1)*Math.PI) + 1) / 2;
|
|
/**
|
if (i%zoom == 0)
|
x = 0;
|
if (i%zoom == 2)
|
x = 1;
|
|
if (j%zoom == 0)
|
y = 0;
|
if (j%zoom == 2)
|
y = 1;
|
/**/
|
|
for (int k=stride; --k>=0;)
|
{
|
int valx = input[index3x300*stride + k]&0xFF;
|
|
if (iz*zoom != i ||
|
jz*zoom != j)
|
valx = 0;
|
|
if (linear)
|
{
|
try
|
{
|
int val00 = valx;
|
int val01 = input[index3x301*stride + k]&0xFF;
|
int val11 = input[index3x311*stride + k]&0xFF;
|
int val10 = input[index3x310*stride + k]&0xFF;
|
|
double valy = val00*(1-y) + val01*y;
|
double valy2 = val10*(1-y) + val11*y;
|
|
valx = (int)(valy*(1-x) + valy2*x);
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
int val3x3 = 0;
|
|
val3x3 |= (int)valx;
|
|
// for (int k = 0; k < 3; k++)
|
// {
|
// val |= (bytes[index * stride + k]&0xFF)<<(k*8);
|
// //val4x4 |= (bytes[index4x4 * stride + k]&0xFF)<<(k*8);
|
// }
|
|
output[index*stride + k] = (byte)val3x3;
|
}
|
}
|
}
|
|
return output;
|
}
|
|
byte[] GetMask(byte[] input, int width, int height)
|
{
|
float[] triple = new float[3];
|
|
short[] hue = new short[input.length/3];
|
short[] sat = new short[input.length/3];
|
short[] bri = new short[input.length/3];
|
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
float r = input[index * 3] & 0xFF;
|
float g = input[index * 3 + 1] & 0xFF;
|
float b = input[index * 3 + 2] & 0xFF;
|
//if (r<0) assert(false); // r += 256;
|
//if (g<0) assert(false); // g += 256;
|
//if (b<0) assert(false); // b += 256;
|
//cColor.RGBtoHSB(r / 255, g / 255, b / 255, triple);
|
if (IQY)
|
cColor.RGBtoIQY(r / 255, g / 255, b / 255, triple);
|
else
|
cColor.RGBtoUVY(r / 255, g / 255, b / 255, triple);
|
|
//if(triple[0] < 0) triple[0] += 1;
|
//if(triple[1] < 0) triple[1] += 1;
|
//if(triple[2] < 0) triple[2] += 1;
|
//System.out.println("saturation = " + triple[1]);
|
assert (triple[0] >= 0 && triple[0] <= 1);
|
assert (triple[1] >= 0 && triple[1] <= 1);
|
assert (triple[2] >= 0 && triple[2] <= 1);
|
|
short h = (short) (triple[0] * 255);
|
short s = (short) (triple[1] * 255);
|
short v = (short) (triple[2] * 255);
|
|
hue[index] = (short)(h & 0xFF);
|
sat[index] = (short)(s & 0xFF);
|
bri[index] = (short)(v & 0xFF);
|
}
|
}
|
|
byte[] mask = new byte[width*height];
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = 0;
|
}
|
|
//if (HUESMOOTH)
|
{
|
MarkMask(hue, mask, width, height, 2/*huebitshift*/, (byte)1);
|
for (int i = 0; i < width*height; i++)
|
{
|
// mask[i] = (byte)((mask[i]&0xFF) * Math.pow(sat[i]/255.0,0.5));
|
}
|
}
|
|
// clamp mask
|
ClampMask(mask, width, height, maskbit+2);
|
|
//if (SATSMOOTH)
|
{
|
MarkMask(sat, mask, width, height, 1/*satbitshift*/, (byte)2);
|
}
|
|
//if (BRISMOOTH)
|
{
|
MarkMask(bri, mask, width, height, 0/*bribitshift*/, (byte)4);
|
}
|
|
// clamp mask
|
ClampMask(mask, width, height, maskbit+1);
|
|
for (int i = width*height; --i>=0;)
|
{
|
if (mask[i] != 0)
|
mask[i] = -1;
|
}
|
|
// remove noise
|
FilterMask(mask, width, height, true);
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = (byte)(-1 - mask[i]);
|
}
|
|
FilterMask(mask, width, height, false);
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = (byte)(-1 - mask[i]);
|
}
|
|
return mask;
|
}
|
|
void Compress(TextureData texturedata)
|
{
|
buffer = null;
|
|
java.util.Random rnd = new java.util.Random(12345);
|
|
int imglength = 0;
|
int inputlength = 0;
|
|
byte eps = 0; // (byte)(rnd.nextFloat()*16);
|
//byte tolerance = 0;
|
|
|
int width = 0;
|
int height = 0;
|
|
float[] triple = new float[3];
|
|
byte mask[] = null;
|
|
try
|
{
|
System.out.println("buffer = " + texturedata.getWidth() + "x" + texturedata.getHeight());
|
input = ((ByteBuffer) texturedata.getBuffer()).array();
|
inputlength = imglength = input.length;
|
//assert(imglength % 3 == 0);
|
System.out.println("#byte = " + inputlength);
|
{
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos = new java.util.zip.GZIPOutputStream(baos);
|
gzos.write(input);
|
gzos.finish();
|
|
System.out.println("#GZIP bytes = " + baos.toByteArray().length + " (" + (baos.toByteArray().length * 100 / (float) imglength) + "%)");
|
|
/*
|
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
java.util.zip.DeflaterOutputStream dos = new java.util.zip.DeflaterOutputStream(baos2);
|
dos.write(bytes);
|
dos.finish();
|
|
System.out.println("#DEFLATE bytes = " + baos2.toByteArray().length + " (" + (baos2.toByteArray().length * 100 / (float) imglength) + "%)");
|
*/
|
}
|
|
} catch (java.io.IOException e)
|
{
|
//throw new javax.media.opengl.GLException(e);
|
System.out.println(e);
|
}
|
|
width = texturedata.getWidth();
|
height = texturedata.getHeight();
|
|
if (oneline)
|
{
|
height = 1;
|
}
|
|
inputlength = imglength = width * height * 3;
|
|
if (imglength != input.length)
|
{
|
System.out.println("ALPHA NOT SUPPORTED");
|
return; // alpha not supported
|
}
|
|
//if (COMPACT)
|
imglength /= 2;
|
|
// System.out.println("inputlength = " + inputlength);
|
|
/**/
|
interleaved = new short[inputlength];
|
rgb = new short[inputlength];
|
hsb = new short[inputlength];
|
|
hue = new short[inputlength/3];
|
sat = new short[inputlength/3];
|
bri = new short[inputlength/3];
|
|
float minh = 255;
|
float maxh = 0;
|
float mins = 255;
|
float maxs = 0;
|
float minb = 255;
|
float maxb = 0;
|
|
int stride = inputlength / 3;
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
for (int l = 0; l < 3; l++)
|
{
|
rgb[l * stride + index] = ((short)(input[index * 3 + l] & 0xFF));
|
interleaved[index * 3 + l] = ((short)(input[index * 3 + l] & 0xFF));
|
|
// if (l > 0)
|
// rgb[l * stride + index] = interleaved[index * 3 + l] = 0;
|
}
|
|
float r = input[index * 3] & 0xFF;
|
float g = input[index * 3 + 1] & 0xFF;
|
float b = input[index * 3 + 2] & 0xFF;
|
//if (r<0) assert(false); // r += 256;
|
//if (g<0) assert(false); // g += 256;
|
//if (b<0) assert(false); // b += 256;
|
//cColor.RGBtoHSB(r / 255, g / 255, b / 255, triple);
|
if (IQY)
|
cColor.RGBtoIQY(r / 255, g / 255, b / 255, triple);
|
else
|
cColor.RGBtoUVY(r / 255, g / 255, b / 255, triple);
|
|
//if(triple[0] < 0) triple[0] += 1;
|
//if(triple[1] < 0) triple[1] += 1;
|
//if(triple[2] < 0) triple[2] += 1;
|
//System.out.println("saturation = " + triple[1]);
|
assert (triple[0] >= 0 && triple[0] <= 1);
|
assert (triple[1] >= 0 && triple[1] <= 1);
|
assert (triple[2] >= 0 && triple[2] <= 1);
|
|
short h = (short) (triple[0] * 255);
|
short s = (short) (triple[1] * 255);
|
short v = (short) (triple[2] * 255);
|
|
hsb[index] = h;
|
hsb[index + stride] = s;
|
hsb[index + 2 * stride] = v;
|
|
hue[index] = (short)(h & 0xFF);
|
sat[index] = (short)(s & 0xFF);
|
bri[index] = (short)(v & 0xFF);
|
|
if (minh > h)
|
minh = h;
|
if (maxh < h)
|
maxh = h;
|
if (mins > s)
|
mins = s;
|
if (maxs < s)
|
maxs = s;
|
if (minb > v)
|
minb = v;
|
if (maxb < v)
|
maxb = v;
|
}
|
}
|
|
mask = new byte[width*height];
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = 0;
|
}
|
|
if (HUESMOOTH)
|
{
|
MarkMask(hue, mask, width, height, 2/*huebitshift*/, (byte)1);
|
for (int i = 0; i < width*height; i++)
|
{
|
// mask[i] = (byte)((mask[i]&0xFF) * Math.pow(sat[i]/255.0,0.5));
|
}
|
}
|
|
// clamp mask
|
ClampMask(mask, width, height, maskbit+2);
|
|
if (SATSMOOTH)
|
{
|
MarkMask(sat, mask, width, height, 1/*satbitshift*/, (byte)2);
|
}
|
|
if (BRISMOOTH)
|
{
|
MarkMask(bri, mask, width, height, 0/*bribitshift*/, (byte)4);
|
}
|
|
// clamp mask
|
ClampMask(mask, width, height, maskbit+1);
|
|
for (int i = width*height; --i>=0;)
|
{
|
if (mask[i] != 0)
|
mask[i] = -1;
|
}
|
|
// remove noise
|
FilterMask(mask, width, height, true);
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = (byte)(-1 - mask[i]);
|
}
|
|
FilterMask(mask, width, height, false);
|
|
for (int i = width*height; --i>=0;)
|
{
|
mask[i] = (byte)(-1 - mask[i]);
|
}
|
|
System.out.println("HUE min = " + minh + "; max = " + maxh);
|
System.out.println("SAT min = " + mins + "; max = " + maxs);
|
System.out.println("BRI min = " + minb + "; max = " + maxb);
|
|
// Normalize layers
|
for (int i = width*height; --i>=0;)
|
{
|
int base = 1<<clampbit;
|
|
hue[i] = (short)((255-base)*(hue[i] - minh)/(maxh - minh) + base);
|
sat[i] = (short)((255-base)*(sat[i] - mins)/(maxs - mins) + base);
|
bri[i] = (short)(255*(bri[i] - minb)/(maxb - minb)); // base
|
}
|
|
/*
|
if (HUEPOW != 1)
|
for (int i = 0; i < width*height; i++)
|
{
|
hue[i] = (short) (Math.pow(hue[i]/255.0, HUEPOW) * 255);
|
}
|
|
if (SATPOW != 1)
|
for (int i = 0; i < width*height; i++)
|
{
|
//sat[i] = (short) (Math.pow(sat[i]/255.0, SATPOW) * 255);
|
sat[i] = (short) ((1 - Math.pow(1-sat[i]/255.0, SATPOW)) * 255);
|
}
|
|
if (BRIPOW != 1)
|
for (int i = 0; i < width*height; i++)
|
{
|
bri[i] = (short) ((1 - Math.pow(1-bri[i]/255.0, BRIPOW)) * 255);
|
}
|
*/
|
|
/**/
|
if (CLAMPLOW)
|
for (int j = 0; j < height; j++)
|
{
|
for (int i = 0; i < width; i++)
|
{
|
int index = (j * width + i);
|
|
int bithue = clampbit+huebitshift;
|
int bitsat = clampbit+satbitshift;
|
int bitbri = clampbit+bribitshift;
|
|
// if (compressbit<4)
|
// bithue += compressbit;
|
// else
|
// if (compressbit<7)
|
// bitsat += compressbit-3;
|
// else
|
// bitbri += compressbit-6;
|
|
short h = hue[index];
|
short s = sat[index];
|
short v = bri[index];
|
|
/*
|
int intensity = v;
|
|
if (intensity > 15)
|
{
|
int bit = 0x80;
|
|
while ((intensity&bit)==0)
|
{
|
bit >>= 1;
|
// if (HUESHIFT)
|
// bithue += 1;
|
if (SATSHIFT)
|
bitsat += 1;
|
}
|
|
int saturation = s & 0xFF;
|
|
if (saturation > 15)
|
{
|
bit = 0xC0;
|
|
while ((saturation&bit)==0)
|
{
|
bit >>= 2;
|
if (HUESHIFT)
|
bithue += 1;
|
}
|
|
if (saturation < 64)
|
mask[index] &= ~1; // hue is not trustable
|
}
|
else
|
{
|
mask[index] &= ~1; // hue is not trustable
|
if (ZEROVALUES)
|
h = 0;
|
}
|
|
if (intensity < 64)
|
{
|
mask[index] &= ~2; // sat is not trustable
|
}
|
}
|
else
|
{
|
mask[index] &= ~1; // hue is not trustable
|
mask[index] &= ~2; // so is sat
|
mask[index] &= ~4; // so is bri
|
if (ZEROVALUES)
|
{
|
h = 0;
|
s = 0;
|
v = 0;
|
}
|
}
|
*/
|
|
/**/
|
h += (short)(1<<(bithue-1));
|
if (h > 255)
|
h = 255;
|
s += (short)(1<<(bitsat-1));
|
if (s > 255)
|
s = 255;
|
v += (short)(1<<(bitbri-1));
|
if (v > 255)
|
v = 255;
|
/**/
|
//assert(hue[index]>=0);
|
//assert(sat[index]>=0);
|
//assert(bri[index]>=0);
|
hue[index] = (short)((h >> bithue)); // <<bithue);
|
sat[index] = (short)((s >> bitsat)); // <<bitsat);
|
bri[index] = (short)((v >> bitbri)); // <<bitbri);
|
/**/
|
|
// float h = hsb[index];
|
// float s = hsb[index + stride];
|
// float v = hsb[index + 2*stride];
|
//System.out.println("h = " + h + "; s = " + s + "; v = " + v);
|
}
|
}
|
|
for (int i = 0; i < width*height; i++)
|
{
|
// if (mask[i] != 0)
|
// mask[i] = (byte)255; // at least one channel is enough
|
}
|
|
/**/
|
if (usehsb)
|
{
|
buffer = hsb;
|
} // bytes
|
else
|
{
|
if (usergb)
|
buffer = rgb;
|
else
|
buffer = interleaved; // test
|
} // bytes
|
|
/**/
|
if (sevenbits)
|
{
|
for (int i = 0; i < imglength; i++)
|
{
|
short residu = 0;
|
|
// wraparound workarounds
|
short fuck = (short) (buffer[i] & 0xFF);
|
/*
|
residu += (fuck%2);
|
if(fuck/2 < 256-residu/2)
|
{
|
fuck = (short)((fuck/2) + residu/2);
|
if(residu == 2)
|
residu = 0;
|
}
|
else
|
{
|
residu = 0;
|
fuck /= 2;
|
}
|
*/
|
if (i < imglength / 3 || rnd.nextFloat() < 0.5 || fuck >= 254)
|
{
|
fuck /= 2;
|
} else
|
{
|
fuck = (short) ((fuck / 2) + fuck % 2);
|
}
|
|
buffer[i] = (byte) fuck;
|
}
|
//System.out.print(bytes[i] + " ");
|
//if(buffer[i] >= 0 && buffer[i]<=eps-1) buffer[i] = eps;
|
//if(buffer[i] <= -1 && buffer[i]>=-eps) buffer[i] = (byte)-(eps+1);
|
}
|
/**/
|
/*
|
for(int i=0;i<imglength;i++)
|
{
|
System.out.println(rgb[i]);
|
}
|
*/
|
|
/**/
|
try
|
{
|
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos2 = new java.util.zip.GZIPOutputStream(baos2);
|
byte[] rgbb = new byte[rgb.length];
|
|
for (int i=rgb.length; --i>=0;)
|
rgbb[i] = (byte)rgb[i];
|
|
gzos2.write(rgbb);
|
gzos2.finish();
|
|
System.out.println("#ZRGB bytes = " + baos2.toByteArray().length + " (" + (baos2.toByteArray().length * 100 / (float) rgb.length) + "%)");
|
/**/
|
|
ByteArrayOutputStream baos2a = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos2a = new java.util.zip.GZIPOutputStream(baos2a);
|
byte[] hsbb = new byte[hsb.length];
|
|
for (int i=hsb.length; --i>=0;)
|
hsbb[i] = (byte)hsb[i];
|
|
gzos2a.write(hsbb);
|
gzos2a.finish();
|
|
System.out.println("#ZHSB bytes = " + baos2a.toByteArray().length + " (" + (baos2a.toByteArray().length * 100 / (float) hsb.length) + "%)");
|
|
ByteArrayOutputStream baos8 = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos8 = new java.util.zip.GZIPOutputStream(baos8);
|
byte[] bits = new byte[rgb.length*2];
|
|
for (int i=rgb.length; --i>=0;)
|
{
|
for (int bit=2; --bit>=0;)
|
{
|
bits[i*2 + bit] = (byte)((rgb[i]>>(bit*4))&0xF);
|
}
|
}
|
|
gzos8.write(bits);
|
gzos8.finish();
|
|
// System.out.println("#ZRGB bits = " + baos8.toByteArray().length + " (" + (baos8.toByteArray().length * 100 / (float) rgb.length/2) + "%)");
|
/**/
|
} catch (java.io.IOException e)
|
{
|
//throw new javax.media.opengl.GLException(e);
|
System.out.println(e);
|
}
|
|
|
image = new short[inputlength];
|
//byte[] diff = new byte[imglength];
|
//short[] diff = new short[imglength];
|
|
/**/
|
short cur = 0; // buffer[0]; ??
|
for (int i = 0; i < inputlength; i++)
|
{
|
//image[i] = (byte) ((buffer[i] - cur) & 0xFF);
|
image[i] = (short) (buffer[i] - cur);
|
//diff[i] = image[i];
|
cur = buffer[i];
|
}
|
/**/
|
|
System.out.println();
|
/**/
|
try
|
{
|
ByteArrayOutputStream baos3 = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos3 = new java.util.zip.GZIPOutputStream(baos3);
|
byte[] imageb = new byte[image.length];
|
|
for (int i=image.length; --i>=0;)
|
imageb[i] = (byte)image[i];
|
|
gzos3.write(imageb);
|
gzos3.finish();
|
|
System.out.println("#ZDIFF bytes = " + baos3.toByteArray().length + " (" + (baos3.toByteArray().length * 100 / (float) image.length) + "%)");
|
System.out.println();
|
} catch (java.io.IOException e)
|
{
|
//throw new javax.media.opengl.GLException(e);
|
System.out.println(e);
|
}
|
|
//buffer = diff; // test
|
/**/
|
|
//diff2 = new short[imglength];
|
//System.arraycopy(diff,0,diff2,0,imglength);
|
|
// if (COMPACT)
|
// image = new short[imglength*2];
|
|
//CompressBufferDIFF(buffer, image);
|
|
/*
|
ByteArrayOutputStream baos4 = new ByteArrayOutputStream();
|
java.util.zip.GZIPOutputStream gzos4 = new java.util.zip.GZIPOutputStream(baos4);
|
{
|
byte[] imageb = new byte[imglength];
|
|
for (int i=imglength; --i>=0;)
|
imageb[i] = (byte)image[i];
|
|
gzos4.write(imageb);
|
}
|
gzos4.finish();
|
|
System.out.println("#ZDIFF lossy bytes = " + baos4.toByteArray().length + " (" + (baos4.toByteArray().length * 100 / (float) inputlength) + "%)");
|
*/
|
|
|
/*
|
ByteArrayOutputStream baos5 = new ByteArrayOutputStream();
|
java.util.zip.DeflaterOutputStream gzos5 = new java.util.zip.DeflaterOutputStream(baos5);
|
gzos5.write(image);
|
gzos5.finish();
|
|
System.out.println("#DEFLATE lossy bytes = " + baos5.toByteArray().length + " (" + (baos5.toByteArray().length * 100 / (float) inputlength) + "%)");
|
*/
|
|
/**
|
char[] cimage = new char[image.length/2];
|
|
for (int i=0; i<cimage.length; i++)
|
{
|
cimage[i] = (char)(image[2*i] << 8 | image[2*i+1]);
|
}
|
LZW lzw = new LZW();
|
|
int[] zimage = new int[imglength];
|
int zcount = 0;
|
|
for (int i=0; i<imglength/2; i++)
|
{
|
int rc = lzw.Encode((char)cimage[i]);
|
|
if (rc != -1)
|
{
|
zimage[zcount++] = rc;
|
}
|
}
|
|
System.out.println("Zcount = " + zcount);
|
System.out.println("Dictionary entries = " + lzw.inputDict.size());
|
|
int imgcount = 0;
|
for (int i=0; i<zcount; i++)
|
{
|
String s = lzw.Decode(zimage[i]);
|
|
for (int j=0; j<s.length(); j++)
|
assert(s.charAt(j) == cimage[imgcount+j]);
|
|
imgcount += s.length();
|
}
|
|
System.out.println("#LZW lossy bytes = " + (zcount*4) + " (" + ((zcount*4) * 100 / (float) inputlength) + "%)");
|
/* */
|
|
byte[] huecomp = null;
|
byte[] huecompZ = null;
|
byte[] satcomp = null;
|
byte[] satcompZ = null;
|
byte[] bricomp = null;
|
byte[] bricompZ = null;
|
|
try
|
{
|
huecomp = Convert(hue, true);
|
//byte[] huecomp = CompressDIFF(hue, false);
|
huecompZ = CompressZIP(huecomp);
|
System.out.println("#HUE diff = " + huecompZ.length + " (" + (huecompZ.length * 100 / (float) hue.length) + "%)");
|
|
huecomp = Convert(hue, false);
|
huecompZ = CompressZIP(huecomp);
|
System.out.println("#HUE layer = " + huecompZ.length + " (" + (huecompZ.length * 100 / (float) hue.length) + "%)");
|
|
int kompact = kompactbit;
|
kompactbit = 0;
|
huecomp = CompressDIFF(hue, false);
|
huecompZ = CompressZIP(huecomp);
|
System.out.println("#HUE compress = " + huecompZ.length + " (" + (huecompZ.length * 100 / (float) hue.length) + "%)");
|
System.out.println();
|
|
satcomp = Convert(sat, true);
|
satcompZ = CompressZIP(satcomp);
|
System.out.println("#SAT diff = " + satcompZ.length + " (" + (satcompZ.length * 100 / (float) sat.length) + "%)");
|
|
satcomp = Convert(sat, false);
|
satcompZ = CompressZIP(satcomp);
|
System.out.println("#SAT layer = " + satcompZ.length + " (" + (satcompZ.length * 100 / (float) sat.length) + "%)");
|
|
satcomp = CompressDIFF(sat, false);
|
kompactbit = kompact;
|
satcompZ = CompressZIP(satcomp);
|
System.out.println("#SAT compress = " + satcompZ.length + " (" + (satcompZ.length * 100 / (float) sat.length) + "%)");
|
System.out.println();
|
|
bricomp = Convert(bri, true);
|
bricompZ = CompressZIP(bricomp);
|
System.out.println("#BRI diff = " + bricompZ.length + " (" + (bricompZ.length * 100 / (float) bri.length) + "%)");
|
|
bricomp = Convert(bri, false);
|
bricompZ = CompressZIP(bricomp);
|
System.out.println("#BRI layer = " + bricompZ.length + " (" + (bricompZ.length * 100 / (float) bri.length) + "%)");
|
|
bricomp = CompressDIFF(bri, false);
|
bricompZ = CompressZIP(bricomp);
|
System.out.println("#BRI compress = " + bricompZ.length + " (" + (bricompZ.length * 100 / (float) bri.length) + "%)");
|
System.out.println();
|
|
byte[] maskZ = CompressZIP(mask);
|
System.out.println("#maskZ = " + maskZ.length + " (" + (maskZ.length * 100 / (float) input.length) + "%)");
|
|
int zoom = 2;
|
|
byte[] mask3x3 = Resize3x3(mask, width, height, 1, zoom, false);
|
int pixels[] = new int[mask3x3.length];
|
for (int p=mask3x3.length; --p>=0;)
|
{
|
short pixel = (short)(mask3x3[p]&0xFF);
|
pixels[p] = pixel<<24 | pixel<<16 | pixel<<8 | pixel;
|
}
|
|
BufferedImage rendImage = new BufferedImage(width*zoom, height*zoom, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
|
rendImage.setRGB(0,0,width*zoom,height*zoom, pixels, width*zoom*(height*zoom-1),-width*zoom);
|
ImageWriter writer = null;
|
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
|
if (iter.hasNext()) {
|
writer = (ImageWriter)iter.next();
|
}
|
|
|
File outfile = new File("mask.jpg");
|
float compressionQuality = 0.85f; // 9f;
|
|
try
|
{
|
ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
|
writer.setOutput(ios);
|
JPEGImageWriteParam iwparam=new JPEGImageWriteParam(Locale.getDefault());
|
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
|
iwparam.setCompressionQuality(compressionQuality);
|
writer.write(null, new IIOImage(rendImage, null, null), iwparam);
|
ios.flush();
|
writer.dispose();
|
ios.close();
|
}
|
catch(Exception e){};
|
|
byte[] mask3x3Z = CompressZIP(mask3x3);
|
System.out.println("#mask3x3Z = " + mask3x3Z.length + " (" + (mask3x3Z.length * 100 / (float) input.length/(zoom*zoom)) + "%)");
|
|
byte[] maskC = new byte[mask.length/4];
|
|
for (int p=maskC.length; --p>=0;)
|
{
|
int p4 = p*4;
|
|
short val0 = (short)(mask[p4]&0xFF);
|
switch (val0)
|
{
|
case 0x10: val0 = 0; break;
|
case 0x20: val0 = 1; break;
|
case 0x40: val0 = 2; break;
|
case 0x80: val0 = 3; break;
|
}
|
short val1 = (short)(mask[p4+1]&0xFF);
|
switch (val1)
|
{
|
case 0x10: val1 = 0; break;
|
case 0x20: val1 = 1; break;
|
case 0x40: val1 = 2; break;
|
case 0x80: val1 = 3; break;
|
}
|
short val2 = (short)(mask[p4+2]&0xFF);
|
switch (val2)
|
{
|
case 0x10: val2 = 0; break;
|
case 0x20: val2 = 1; break;
|
case 0x40: val2 = 2; break;
|
case 0x80: val2 = 3; break;
|
}
|
short val3 = (short)(mask[p4+3]&0xFF);
|
switch (val3)
|
{
|
case 0x10: val3 = 0; break;
|
case 0x20: val3 = 1; break;
|
case 0x40: val3 = 2; break;
|
case 0x80: val3 = 3; break;
|
}
|
|
maskC[p] = (byte)(val3<<6 | val2<<4 | val1<<2 | val0);
|
}
|
byte[] maskCZ = CompressZIP(maskC);
|
System.out.println("#maskCZ = " + maskCZ.length + " (" + (maskCZ.length * 100 / (float) input.length) + "%)");
|
|
if (KOMPACTTEXTURE)
|
{
|
kompact = kompactbit;
|
kompactbit = 0;
|
hue = UncompressDIFF(huecomp);
|
sat = UncompressDIFF(satcomp);
|
kompactbit = kompact;
|
bri = UncompressDIFF(bricomp);
|
}
|
}
|
catch(Exception e)
|
{
|
e.printStackTrace();
|
}
|
|
/*
|
short current = 0;
|
|
int l = 0;
|
for (int p = 0; p < imglength; p++)
|
{
|
short dif = image[p];
|
|
// if (p == 0)
|
// dif = (short) (dif & 0xFF);
|
|
if (COMPACT)
|
{
|
short dif2 = (short) tabledif_1[(dif>>4)&0xF];
|
// if (p == 0)
|
// dif2 = (short) (dif2 & 0xFF);
|
current += dif2;
|
//assert(current >= 0 && current < 256);
|
current &= 0xFF;
|
buffer[l++] = current;
|
dif2 = (short) tabledif_1[dif&0xF];
|
current += dif2;
|
//assert(current >= 0 && current < 256);
|
current &= 0xFF;
|
buffer[l++] = current;
|
}
|
else
|
{
|
// assert(dif >= 0 && dif < 256);
|
current += dif;
|
assert(current >= 0 && current < 256);
|
buffer[p] = current;
|
}
|
// if (p == 0)
|
// dif &= 0xFF;
|
// buffer[p] = (short)((current + dif)&0xFF);
|
// current = buffer[p];
|
// if (p%3 == 2)
|
// if (!(buffer[p/3*3] == buffer[p/3*3+1] && buffer[p/3*3] == buffer[p/3*3+2]))
|
// {
|
//// assert (buffer[p/3*3] == buffer[p/3*3+1] && buffer[p/3*3] == buffer[p/3*3+2]);
|
// }
|
}
|
*/
|
|
/* ????
|
int l = 0;
|
|
for (int p = 0; p < imglength;)
|
{
|
if (image[p] != 127 || !compress)
|
{
|
if (compact && !exact)
|
{
|
byte cdif = (byte)image[p++];
|
|
byte dif = tabledif_1[(cdif >> 4) & 0xF];
|
current = (byte) (current + dif);
|
if (exact)
|
{
|
assert ((byte) (buffer[l] << 1) == (byte) (current << 1));
|
}
|
buffer[l++] = current;
|
dif = tabledif_1[cdif & 0xF];
|
current = (byte) (current + dif);
|
if (exact)
|
{
|
assert ((byte) (buffer[l] << 1) == (byte) (current << 1));
|
}
|
buffer[l++] = current;
|
} else
|
{
|
current = (byte) (current + image[p++]);
|
if (exact)
|
{
|
assert ((byte) (buffer[l] << 1) == (byte) (current << 1));
|
}
|
if (false)
|
{
|
if (buffer[l] << 1 != current << 1)
|
{
|
//System.out.println("buffer[l] = " + buffer[l] + "; current = " + current);
|
assert (buffer[l] << 1 == current << 1);
|
}
|
}
|
buffer[l++] = current;
|
}
|
} else
|
{
|
p++;
|
int count = image[p++] & 0xFF;
|
//System.out.println("count = " + count + "; p = " + p);
|
//assert(count>=minlength);
|
for (int s = 0; s < count;)
|
{
|
byte difs = (byte)image[p++];
|
int c = 0;
|
while (c < 8 && s < count)
|
{
|
byte dif0 = (byte) (((difs & 0x01) << 1) + 1);
|
if ((dif0 & 0x2) != 0)
|
{
|
dif0 |= 0xFC;
|
}
|
current = (byte) (current + dif0);
|
if (exact)
|
{
|
assert ((byte) (buffer[l] << 1) == (byte) (current << 1));
|
}
|
buffer[l++] = current;
|
s++;
|
c++;
|
difs >>= 1;
|
}
|
}
|
}
|
}
|
|
if (!(l == inputlength))
|
{
|
System.out.println("l = " + l);
|
System.out.println("length = " + inputlength);
|
//assert(l == inputlength);
|
new Exception().printStackTrace();
|
}
|
*/
|
|
System.out.println("HUESMOOTH = " + HUESMOOTH);
|
System.out.println("SATSMOOTH = " + SATSMOOTH);
|
System.out.println("BRISMOOTH = " + BRISMOOTH);
|
|
System.out.println("CLAMPBIT = " + clampbit);
|
System.out.println("KOMPACTBIT = " + kompactbit);
|
System.out.println("MASKBIT = " + maskbit);
|
|
System.out.println("CLAMPLOW = " + CLAMPLOW);
|
System.out.println("ZEROVALUES = " + ZEROVALUES);
|
System.out.println("HUESHIFT = " + HUESHIFT);
|
System.out.println("SATSHIFT = " + SATSHIFT);
|
|
int bithue = clampbit+huebitshift;
|
int bitsat = clampbit+satbitshift;
|
int bitbri = clampbit+bribitshift;
|
|
for (int i = 0; i < width*height; i++)
|
{
|
hue[i] <<= bithue;
|
hue[i] = (short) (Math.pow(hue[i]/255.0, 1/HUEPOW) * 255);
|
}
|
|
|
for (int i = 0; i < width*height; i++)
|
{
|
sat[i] <<= bitsat;
|
//sat[i] = (short) (Math.pow(sat[i]/255.0, 1/SATPOW) * 255);
|
sat[i] = (short) ((1 - Math.pow(1-sat[i]/255.0, 1/SATPOW)) * 255);
|
}
|
|
for (int i = 0; i < width*height; i++)
|
{
|
bri[i] <<= bitbri;
|
bri[i] = (short) ((1 - Math.pow(1-bri[i]/255.0, 1/BRIPOW)) * 255);
|
//bri[i] = (short) (Math.pow(bri[i]/255.0, 1/BRIPOW) * 255);
|
}
|
|
float MSE = 0;
|
|
// Unnormalize layers
|
for (int i = width*height; --i>=0;)
|
{
|
int base = 1<<clampbit;
|
|
hue[i] = (short)((hue[i]-base)*(maxh - minh)/(255-base) + minh);
|
sat[i] = (short)((sat[i]-base)*(maxs - mins)/(255-base) + mins);
|
bri[i] = (short)(bri[i]/255.0*(maxb - minb) + minb);
|
//sat[i] = (short)(255*(sat[i] - mins)/(maxs - mins));
|
//bri[i] = (short)(255*(bri[i] - minb)/(maxb - minb));
|
}
|
|
// UNCOMPRESS
|
if (true) // buffer != bytes)
|
{
|
int length3 = input.length / 3;
|
|
if (HUESMOOTH)
|
{
|
for (int pass=clampbit-1; --pass>=0;) // KOMPACT effect
|
{
|
if (KOMPACTTEXTURE)
|
SmoothBuffer(hue, null/*mask*/, true, width, height, huebitshift);
|
}
|
for (int pass=1<<clampbit; --pass>=0;) // CLAMPLOW effect
|
{
|
SmoothBuffer(hue, mask, false, width, height, huebitshift);
|
}
|
for (int pass=1; --pass>=0;)
|
{
|
// SmoothBuffer(hue, null, false, width, height, 0);
|
}
|
}
|
|
if (SATSMOOTH)
|
{
|
for (int pass=clampbit-1; --pass>=0;)
|
{
|
if (KOMPACTTEXTURE)
|
SmoothBuffer(sat, null/*mask*/, true, width, height, satbitshift);
|
}
|
for (int pass=1<<clampbit; --pass>=0;)
|
{
|
SmoothBuffer(sat, mask, false, width, height, satbitshift);
|
}
|
for (int pass=1; --pass>=0;)
|
{
|
// SmoothBuffer(sat, null, false, width, height, 0);
|
}
|
}
|
|
if (BRISMOOTH)
|
{
|
for (int pass=clampbit-1; --pass>=0;)
|
{
|
if (KOMPACTTEXTURE)
|
SmoothBuffer(bri, null/*mask*/, true, width, height, bribitshift);
|
}
|
for (int pass=1<<clampbit; --pass>=0;)
|
{
|
SmoothBuffer(bri, mask, false, width, height, bribitshift);
|
}
|
for (int pass=1; --pass>=0;)
|
{
|
// SmoothBuffer(bri, null, false, width, height, 0);
|
}
|
}
|
|
if (COMPACT) // show edges
|
{
|
for (int i = 0; i < width*height; i++)
|
{
|
//hue[j * width + i] = (short) smooth[i]; // ((smooth[i] + 128)/2);
|
//if (mask[i] != 0)
|
{
|
hue[i] = 128;
|
sat[i] = 128;
|
bri[i] = (short)((mask[i]&0xFF)); // *2); // 255;
|
if (bri[i] > 255)
|
bri[i] = 255;
|
}
|
}
|
}
|
|
|
for (int j = 0; j < height; j++)
|
{
|
/*
|
int hspan = 0;
|
int hcount = 0;
|
double dh = 0;
|
|
int sspan = 0;
|
int scount = 0;
|
double ds = 0;
|
|
int bspan = 0;
|
int bcount = 0;
|
double db = 0;
|
*/
|
|
float currenth = hue[j * width];
|
float currents = sat[j * width];
|
float currentb = bri[j * width];
|
|
for (int i = 0; i < width; i++)
|
{
|
//for(int l=0;l<3;l++)
|
{
|
int index = (j * width + i);
|
|
currenth = hue[index];
|
currents = sat[index];
|
currentb = bri[index];
|
|
float h = //255;
|
currenth;
|
//hsb[index] & 0xFF;
|
float s = //255;
|
currents; ////sat[index] & 0xFF; // hsb[index + stride] & 0xFF;
|
float v = //255; // currentb;
|
currentb;
|
//bri[index] & 0xFF; // hsb[index + 2 * stride] & 0xFF;
|
//s = 0;
|
|
if (false) // !COMPACT)
|
{
|
if (h != 255 && HUESMOOTH && clampbit<5)
|
h += rnd.nextFloat()/1.5f * (1<<(clampbit+huebitshift));
|
if (s != 255 && SATSMOOTH && clampbit<5)
|
s += rnd.nextFloat()/1.5f * (1<<(clampbit+satbitshift));
|
if (v != 255 && BRISMOOTH && clampbit<5)
|
v += rnd.nextFloat()/1.5f * (1<<(clampbit+bribitshift));
|
}
|
|
/*
|
if (hcount == hspan)
|
{
|
hspan = 0;
|
while (i+hspan<width-1 && hue[index] == hue[index+hspan])
|
hspan++;
|
|
if (hspan > 16)
|
hspan = 8;
|
|
dh = hue[index+hspan] - currenth;
|
|
if (hspan > 0)
|
dh /= hspan;
|
|
// if (hspan > 16)
|
// hspan = 16;
|
|
hcount = 0;
|
//currenth = hue[index];
|
}
|
|
if (scount == sspan)
|
{
|
sspan = 0;
|
while (i+sspan<width-1 && sat[index] == sat[index+sspan])
|
sspan++;
|
|
if (sspan > 16)
|
sspan = 8;
|
|
//db = (bri[index+bspan]+currentb)/2 - currentb;
|
ds = sat[index+sspan] - currents;
|
|
// if (Math.abs(db) < (2<<(compressbit+1)))
|
// while (Math.abs(db) > (1<<(compressbit)))
|
// db /= 2;
|
|
// //if (hspan == 1)
|
// db = bri[index+--bspan] - currentb;
|
|
if (sspan > 0)
|
ds /= sspan;
|
|
// db /= 2;
|
|
scount = 0;
|
}
|
|
if (bcount == bspan)
|
{
|
bspan = 0;
|
while (i+bspan<width-1 && bri[index] == bri[index+bspan])
|
bspan++;
|
|
// if (bspan > 16)
|
// bspan = 8;
|
|
//db = (bri[index+bspan]+currentb)/2 - currentb;
|
db = bri[index+bspan] - currentb;
|
|
if (Math.abs(db) > (2<<(compressbit+1)))
|
db = 0;
|
// while (Math.abs(db) > (1<<(compressbit)))
|
// db /= 2;
|
|
// //if (hspan == 1)
|
// db = bri[index+--bspan] - currentb;
|
|
if (bspan > 0)
|
db /= bspan;
|
|
// db /= 2;
|
|
bcount = 0;
|
}
|
|
|
if (HUERND && dh != 0)
|
currenth += dh;
|
else
|
currenth = hue[index];
|
if (SATRND && ds != 0)
|
currents += ds;
|
else
|
currents = sat[index];
|
if (BRIRND && db != 0 && bspan > 0)
|
currentb += db;
|
else
|
currentb = bri[index];
|
|
hcount++;
|
scount++;
|
bcount++;
|
*/
|
|
if (sevenbits)
|
{
|
h *= 2;
|
s *= 2;
|
v *= 2;
|
}
|
|
//if (h<0) assert(false); // h += 256;
|
//if (s<0) assert(false); // s += 256;
|
//if (v<0) assert(false); // v += 256;
|
//System.out.println("h = " + h + "; s = " + s + "; v = " + v);
|
///cColor.HSBtoRGB(h / 255, s / 255, v / 255, triple);
|
if (IQY)
|
cColor.IQYtoRGB(h / 255, s / 255, v / 255, triple);
|
else
|
cColor.UVYtoRGB(h / 255, s / 255, v / 255, triple);
|
|
/*
|
assert(triple[0] >= 0);
|
assert(triple[1] >= 0);
|
assert(triple[2] >= 0);
|
assert(triple[0] <= 1);
|
assert(triple[1] <= 1);
|
assert(triple[2] <= 1);
|
*/
|
|
float r = triple[0] * 255;
|
float g = triple[1] * 255;
|
float b = triple[2] * 255;
|
|
//assert(buffer == null);
|
buffer = null;
|
|
if (buffer == rgb)
|
{
|
r = rgb[(j * width + i)] & 0xFF;
|
g = rgb[inputlength / 3 + (j * width + i)] & 0xFF;
|
b = rgb[2 * inputlength / 3 + (j * width + i)] & 0xFF;
|
if (sevenbits)
|
{
|
r *= 2;
|
g *= 2;
|
b *= 2;
|
}
|
}
|
|
if (buffer == interleaved)
|
{
|
r = interleaved[index * 3] & 0xFF;
|
g = interleaved[index * 3 + 1] & 0xFF;
|
b = interleaved[index * 3 + 2] & 0xFF;
|
if (sevenbits)
|
{
|
r *= 2;
|
g *= 2;
|
b *= 2;
|
}
|
}
|
//if(i<width-2)
|
// index += 2;
|
float r0 = input[index * 3] & 0xFF;
|
float g0 = input[index * 3 + 1] & 0xFF;
|
float b0 = input[index * 3 + 2] & 0xFF;
|
//if(i<width-2)
|
// index -= 2;
|
//if (r0<0) r0 += 256;
|
//if (g0<0) g0 += 256;
|
//if (b0<0) b0 += 256;
|
//r = input[index*3] & 0xF8;
|
//g = input[index*3 + 1] & 0xF8;
|
//b = input[index*3 + 2] & 0xF8;
|
|
MSE += (r0 - r) * (r0 - r);
|
MSE += (g0 - g) * (g0 - g);
|
MSE += (b0 - b) * (b0 - b);
|
|
// Debug
|
//int index2 = (j/3*width + i);
|
//bytes[index2] = (byte)h; // (triple[0]*255);
|
//bytes[index2 + stride] = (byte)s; // (triple[1]*255);
|
//bytes[index2 + 2*stride] = (byte)b; // (triple[2]*255);
|
/*
|
int cas = j/(height/128);
|
// r = h; g = s; b = v;
|
if (cas%3 == 0)
|
{
|
r = 0; g = 0; b = h;
|
}
|
else if (cas%3 == 1)
|
{
|
r = 0; g = s; b = 0;
|
}
|
else
|
{
|
r = v; g = 0; b = 0;
|
}
|
/**/
|
|
//int rs = image[index];
|
//int gs = image[index + stride];
|
//int bs = image[index + stride*2];
|
|
//if (rs < -rs) rs = -rs;
|
//if (gs < -gs) gs = -gs;
|
//if (bs < -bs) bs = -bs;
|
|
|
if (DEBUGHSB)
|
{
|
try
|
{
|
int index3 = (j/3 * width + i)*3;
|
|
stride = width*height/3*3;
|
|
//cColor.HSBtoRGB(h/255, 1, 1, triple);
|
if (IQY)
|
cColor.IQYtoRGB(h/255, 0.5f, 0.5f, triple);
|
else
|
cColor.UVYtoRGB(h/255, 0.5f, 1, triple);
|
input[index3] = (byte) (triple[0] * 255);
|
input[index3 + 1] = (byte) (triple[1] * 255);
|
input[index3 + 2] = (byte) (triple[2] * 255);
|
|
//cColor.HSBtoRGB(0, s/255, 1, triple);
|
if (IQY)
|
cColor.IQYtoRGB(0.5f, s/255, 0.5f, triple);
|
else
|
cColor.UVYtoRGB(0.5f, s/255, 1, triple);
|
input[index3 + length3] = (byte) (triple[0] * 255);
|
input[index3 + length3 + 1] = (byte) (triple[1] * 255);
|
input[index3 + length3 + 2] = (byte) (triple[2] * 255);
|
|
//cColor.HSBtoRGB(1, 0, v/255, triple);
|
if (IQY)
|
cColor.IQYtoRGB(0.5f, 0.5f, v/255, triple);
|
else
|
cColor.UVYtoRGB(0.5f, 0.5f, v/255, triple);
|
input[index3 + length3*2] = (byte) (triple[0] * 255);
|
input[index3 + length3*2 + 1] = (byte) (triple[1] * 255);
|
input[index3 + length3*2 + 2] = (byte) (triple[2] * 255);
|
}
|
catch (Exception e)
|
{
|
// e.printStackTrace();
|
}
|
}
|
else
|
{
|
input[index*3] = (byte) r;
|
input[index*3 + 1] = (byte) g;
|
input[index*3 + 2] = (byte) b;
|
}
|
}
|
}
|
}
|
|
//texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
//texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
}
|
|
|
MSE /= width * height * 3;
|
System.out.println("MSE = " + MSE);
|
System.out.println("PSNR = " + 10 * Math.log10(65536 / MSE));
|
}
|
|
int StopSequence(short[] image, int mark, int length)
|
{
|
// stop sequence
|
//byte a = image[mark+2];
|
//byte b = image[mark+3];
|
|
for (int s = 0; s < (length + 7) / 8; s += 1)
|
{
|
/*
|
if(s!=1)
|
{
|
byte c = image[mark+2*s];
|
byte d = 0;
|
if (2*s+1<length)
|
d = image[mark+2*s+1];
|
image[mark+2+s] = (byte)((d << 4) | (c&0x0F));
|
}
|
else
|
image[mark+2+s] = (byte)((b << 4) | (a&0x0F));
|
*/
|
|
byte a = (byte)image[mark + 8 * s];
|
byte b = 0;
|
byte c = 0;
|
byte d = 0;
|
byte e = 0;
|
byte f = 0;
|
byte g = 0;
|
byte h = 0;
|
|
if (8 * s + 1 < length)
|
{
|
b = (byte)image[mark + 8 * s + 1];
|
}
|
if (8 * s + 2 < length)
|
{
|
c = (byte)image[mark + 8 * s + 2];
|
}
|
if (8 * s + 3 < length)
|
{
|
d = (byte)image[mark + 8 * s + 3];
|
}
|
if (8 * s + 4 < length)
|
{
|
e = (byte)image[mark + 8 * s + 4];
|
}
|
if (8 * s + 5 < length)
|
{
|
f = (byte)image[mark + 8 * s + 5];
|
}
|
if (8 * s + 6 < length)
|
{
|
g = (byte)image[mark + 8 * s + 6];
|
}
|
if (8 * s + 7 < length)
|
{
|
h = (byte)image[mark + 8 * s + 7];
|
}
|
|
if (a > 0)
|
{
|
a = 0;
|
}
|
if (b > 0)
|
{
|
b = 0;
|
}
|
if (c > 0)
|
{
|
c = 0;
|
}
|
if (d > 0)
|
{
|
d = 0;
|
}
|
if (e > 0)
|
{
|
e = 0;
|
}
|
if (f > 0)
|
{
|
f = 0;
|
}
|
if (g > 0)
|
{
|
g = 0;
|
}
|
if (h > 0)
|
{
|
h = 0;
|
}
|
|
//image[mark+2+s] = (byte)(d<<6 | ((c<<4)&0x30) | ((b<<2)&0x0c) | (a&0x03));
|
image[mark + 2 + s] = (byte) (((h << 7) & 0x80) | ((g << 6) & 0x40) |
|
((f << 5) & 0x20) | ((e << 4) & 0x10) | ((d << 3) & 0x08) |
|
((c << 2) & 0x04) | ((b << 1) & 0x02) | (a & 0x01));
|
}
|
|
image[mark] = 127;
|
image[mark + 1] = (byte) length;
|
|
return mark + 2 + (length + 7) / 8;
|
}
|
|
String GetFormat(String name)
|
{
|
if (name.toLowerCase().endsWith(".jpg"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.JPG;
|
}
|
if (name.toLowerCase().endsWith(".gif"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.GIF;
|
}
|
if (name.toLowerCase().endsWith(".png"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.PNG;
|
}
|
if (name.toLowerCase().endsWith(".tga"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.TGA;
|
}
|
if (name.toLowerCase().endsWith(".tif"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.TIFF;
|
}
|
if (name.toLowerCase().endsWith(".tiff"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.TIFF;
|
}
|
if (name.toLowerCase().endsWith(".sgi"))
|
{
|
return com.sun.opengl.util.texture.TextureIO.SGI;
|
}
|
|
return null;
|
}
|
|
public void ReleaseTextures(cTexture tex) // INTERFACE
|
{
|
if (/*tex == null ||*/ ambientOcclusion ) // || !textureon)
|
{
|
return;
|
}
|
|
if (tex == null)
|
{
|
ReleaseTexture(null, true);
|
ReleaseTexture(null, false);
|
return;
|
}
|
|
String pigment = Object3D.GetPigment(tex);
|
String bump = Object3D.GetBump(tex);
|
|
//if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
{
|
// System.out.print("RELEASE +++++++++++++++ pigment = " + pigment);
|
// System.out.println("; bump = " + bump);
|
}
|
|
if (bump.equals(""))
|
{
|
bump = null;
|
}
|
if (pigment.equals(""))
|
{
|
pigment = null;
|
}
|
|
ReleaseTexture(tex, true);
|
ReleaseTexture(tex, false);
|
}
|
|
public void ReleasePigmentTexture(cTexture tex) // INTERFACE
|
{
|
if (/*tex == null ||*/ ambientOcclusion ) // || !textureon)
|
{
|
return;
|
}
|
|
if (tex == null)
|
{
|
ReleaseTexture(null, false);
|
return;
|
}
|
|
String pigment = Object3D.GetPigment(tex);
|
|
//if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
{
|
// System.out.print("RELEASE +++++++++++++++ pigment = " + pigment);
|
// System.out.println("; bump = " + bump);
|
}
|
|
if (pigment.equals(""))
|
{
|
pigment = null;
|
}
|
|
ReleaseTexture(tex, false);
|
}
|
|
public void ReleaseBumpTexture(cTexture tex) // INTERFACE
|
{
|
if (/*tex == null ||*/ ambientOcclusion ) // || !textureon)
|
{
|
return;
|
}
|
|
if (tex == null)
|
{
|
ReleaseTexture(null, true);
|
return;
|
}
|
|
String bump = Object3D.GetBump(tex);
|
|
//if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
{
|
// System.out.print("RELEASE +++++++++++++++ pigment = " + pigment);
|
// System.out.println("; bump = " + bump);
|
}
|
|
if (bump.equals(""))
|
{
|
bump = null;
|
}
|
|
ReleaseTexture(tex, true);
|
}
|
|
void ReleaseTexture(cTexture tex, boolean bump)
|
{
|
if (// DrawMode() != 0 || /*tex == null ||*/
|
ambientOcclusion ) // || !textureon)
|
{
|
return;
|
}
|
|
CacheTexture/*com.sun.opengl.util.texture.Texture*/ texture = null;
|
|
if (tex != null)
|
texture = bump ? texturebump.get(tex) : texturepigment.get(tex);
|
|
// //assert( texture != null );
|
// if (texture == null)
|
// {
|
// return;
|
// }
|
//
|
// //Applet3D.traceout(this);
|
//
|
//INTENSITY FIX:
|
// texture.disable();
|
|
if (bump)
|
{
|
bumpdepth--;
|
|
// GrafreeD.trace("POP " + tex + "(" + pigmentdepth + ")" + " : " + pigmentstack[pigmentdepth] + " vs " + texture);
|
if (bumpstack[bumpdepth] != (texture!=null?texture.texture:null))
|
{
|
// assert (bumpstack[bumpdepth] == texture);
|
}
|
|
if (bumpdepth == 0)
|
{
|
return;
|
}
|
|
if (textureon)
|
{
|
if (true) // texture != null)
|
{
|
int back = 1;
|
while (back <= bumpdepth && bumpstack[bumpdepth - back] == null)
|
back += 1;
|
|
// if (bumpstack[bumpdepth - back] != null)
|
if (bumpdepth >= back) // ????????
|
bumpstack[bumpdepth - back].bind();
|
//INTENSITY FIX: texturestack[depth-1].enable();
|
}
|
}
|
}
|
else
|
{
|
pigmentdepth--;
|
|
// GrafreeD.trace("POP " + tex + "(" + pigmentdepth + ")" + " : " + pigmentstack[pigmentdepth] + " vs " + texture);
|
if (pigmentstack[pigmentdepth] != (texture!=null?texture.texture:null))
|
{
|
// assert (pigmentstack[pigmentdepth] == texture);
|
}
|
|
if (pigmentstack[pigmentdepth] != null)
|
{
|
// System.err.println(pigmentstack[pigmentdepth]);
|
|
pigmentstack[pigmentdepth].disable();
|
// pigmentstack[pigmentdepth].dispose(); // destroy(GetGL());
|
|
// int[] free_mem = new int[2];
|
// //returns in kB, so if you want MB,divide by 1024
|
// GetGL().glGetIntegerv(GetGL().GL_TEXTURE_FREE_MEMORY_ATI,free_mem,0);
|
// //now subtract this free memory from total memory and get used memory :)
|
// //used_mem = total_mem – free_mem;
|
|
}
|
|
if (pigmentdepth == 0)
|
{
|
return;
|
}
|
|
if (textureon)
|
{
|
if (true) // texture != null)
|
{
|
int back = 1;
|
while (back <= pigmentdepth && pigmentstack[pigmentdepth - back] == null)
|
back += 1;
|
|
if (pigmentdepth >= back) // ????????
|
pigmentstack[pigmentdepth - back].bind();
|
}
|
|
// if (pigmentstack[pigmentdepth - 1] != null)
|
// pigmentstack[pigmentdepth - 1].bind();
|
//INTENSITY FIX: texturestack[depth-1].enable();
|
}
|
}
|
}
|
|
/*boolean*/ public void BindTextures(cTexture tex, int resolution) throws Exception // INTERFACE
|
{
|
// if (// DrawMode() != 0 || /*tex == null ||*/
|
// ambientOcclusion ) // || !textureon)
|
// {
|
// return; // false;
|
// }
|
//
|
// if (tex == null)
|
// {
|
// BindTexture(null,false,resolution);
|
// BindTexture(null,true,resolution);
|
// return;
|
// }
|
//
|
// String pigment = Object3D.GetPigment(tex);
|
// String bump = Object3D.GetBump(tex);
|
//
|
// usedtextures.add(pigment);
|
// usedtextures.add(bump);
|
//
|
// //if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
// {
|
// // System.out.print("BIND +++++++++++++++ pigment = " + pigment);
|
// // System.out.println("; bump = " + bump);
|
// }
|
//
|
// if (bump.equals(""))
|
// {
|
// bump = null;
|
// }
|
// if (pigment.equals(""))
|
// {
|
// pigment = null;
|
// }
|
//
|
// GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
|
// BindTexture(pigment, false, resolution);
|
// GetGL().glActiveTexture(GetGL().GL_TEXTURE2);
|
// BindTexture(bump, true, resolution);
|
// GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
|
//
|
// return; // true;
|
|
BindPigmentTexture(tex, resolution);
|
BindBumpTexture(tex, resolution);
|
}
|
|
/*boolean*/ public void BindPigmentTexture(cTexture tex, int resolution) throws Exception // INTERFACE
|
{
|
if (// DrawMode() != 0 || /*tex == null ||*/
|
ambientOcclusion ) // || !textureon)
|
{
|
return; // false;
|
}
|
|
if (tex == null)
|
{
|
BindTexture(null,false,resolution);
|
return;
|
}
|
|
String pigment = Object3D.GetPigment(tex);
|
|
usedtextures.add(tex);
|
|
//if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
{
|
// System.out.print("BIND +++++++++++++++ pigment = " + pigment);
|
// System.out.println("; bump = " + bump);
|
}
|
|
if (pigment.equals(""))
|
{
|
pigment = null;
|
}
|
|
GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
|
BindTexture(tex, false, resolution);
|
}
|
|
/*boolean*/ public void BindBumpTexture(cTexture tex, int resolution) throws Exception // INTERFACE
|
{
|
if (// DrawMode() != 0 || /*tex == null ||*/
|
ambientOcclusion ) // || !textureon)
|
{
|
return; // false;
|
}
|
|
if (tex == null)
|
{
|
BindTexture(null,true,resolution);
|
return;
|
}
|
|
String bump = Object3D.GetBump(tex);
|
|
usedtextures.add(tex);
|
|
//if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
|
{
|
// System.out.print("BIND +++++++++++++++ pigment = " + pigment);
|
// System.out.println("; bump = " + bump);
|
}
|
|
if (bump.equals(""))
|
{
|
bump = null;
|
}
|
|
GetGL().glActiveTexture(GetGL().GL_TEXTURE2);
|
BindTexture(tex, true, resolution);
|
GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
|
}
|
|
java.util.HashSet<String> missingTextures = new java.util.HashSet<String>();
|
|
private boolean FileExists(String tex)
|
{
|
if (missingTextures.contains(tex))
|
{
|
return false;
|
}
|
|
boolean fileExists = new File(tex).exists();
|
|
if (!fileExists)
|
{
|
// If file exists, the "new File()" is not executed sgain
|
missingTextures.add(tex);
|
}
|
|
return fileExists;
|
}
|
|
CacheTexture GetCacheTexture(cTexture tex, boolean bump, int resolution) throws Exception
|
{
|
CacheTexture texturecache = null;
|
|
if (tex != null)
|
{
|
String texname = bump ? Object3D.GetBump(tex) : Object3D.GetPigment(tex);
|
byte[] texdata = bump ? tex.bumpdata : tex.pigmentdata;
|
|
if (texname.equals("") && texdata == null)
|
{
|
return null;
|
}
|
|
String fallbackTextureName = defaultDirectory + "/Textures/" + texname;
|
|
// String[] split = tex.split("Textures");
|
// if (split.length > 1)
|
// texname = "/Users/nbriere/Textures" + split[split.length-1];
|
// else
|
// if (!texname.startsWith("/"))
|
// texname = "/Users/nbriere/Textures/" + texname;
|
if (!FileExists(texname) && !texname.startsWith("@"))
|
{
|
texname = fallbackTextureName;
|
}
|
|
if (CACHETEXTURE)
|
{
|
if (texdata == null)
|
texturecache = bump ? texturebump.get(tex) : texturepigment.get(tex);
|
else
|
texturecache = bimtextures.get(texdata);
|
}
|
|
if (texturecache == null || texturecache.resolution != -1 && texturecache.resolution < resolution)
|
{
|
TextureData texturedata = null;
|
|
if (texdata != null && textureon)
|
{
|
BufferedImage bim; // = new BufferedImage(bump?tex.bw:tex.pw, bump?tex.bh:tex.ph, BufferedImage.TYPE_INT_RGB);
|
|
try
|
{
|
bim = DecompressJPEG(texdata, bump?tex.bw:tex.pw, bump?tex.bh:tex.ph);
|
}
|
catch (Exception e)
|
{
|
bim = CreateBim(texdata, bump?tex.bw:tex.pw, bump?tex.bh:tex.ph);
|
}
|
|
texturecache = new CacheTexture(GetBimTexture(bim, bump), -1);
|
bimtextures.put(texdata, texturecache);
|
|
//BufferedImage bim3 = new BufferedImage(bump?tex.bw:tex.pw, bump?tex.bh:tex.ph, BufferedImage.TYPE_INT_RGB);
|
|
//Object bim2 = CreateBim(texturecache.texturedata);
|
//bim2 = bim;
|
}
|
else
|
if (texname.endsWith("DEFAULT_TEXTURE")) // ||*/ tex.equals(""))
|
{
|
assert(!bump);
|
// if (bump)
|
// {
|
// texture = textures.get(tex+"_BUMP");
|
// if (texture == null)
|
// texture = GetResourceTexture("defaultbump.png", bump);
|
// }
|
// else
|
// {
|
// texturecache = textures.get(texname); // suspicious
|
if (texturecache == null)
|
{
|
texturecache = new CacheTexture(GetResourceTexture("default.png", bump),resolution);
|
}
|
else
|
new Exception().printStackTrace();
|
// }
|
} else
|
if (texname.endsWith("DEFAULT_TEXTURE_BUMP")) // ||*/ tex.equals(""))
|
{
|
assert(bump);
|
// texturecache = textures.get(texname); // suspicious
|
if (texturecache == null)
|
texturecache = new CacheTexture(GetResourceTexture("default.png", bump),resolution);
|
else
|
new Exception().printStackTrace();
|
} else
|
{
|
//if (tex.equals("IMMORTAL"))
|
//{
|
// texture = GetResourceTexture("default.png");
|
//} else
|
//{
|
if (texname.endsWith("WHITE_NOISE"))
|
{
|
// texturecache = textures.get(texname); // suspicious
|
if (texturecache == null)
|
texturecache = new CacheTexture(GetResourceTexture("whitenoise.jpg", bump),resolution);
|
else
|
new Exception().printStackTrace();
|
} else
|
{
|
if (texname.startsWith("@") && textureon)
|
{
|
// texturecache = textures.get(texname); // suspicious
|
if (texturecache == null)
|
texturecache = new CacheTexture(GetResourceTexture(texname.substring(1), bump),resolution);
|
else
|
new Exception().printStackTrace();
|
} else
|
{
|
if (textureon)
|
{
|
String cachename = texname;
|
|
boolean processbump = bump;
|
|
if (texname.endsWith(".jpg") || texname.endsWith(".JPG"))
|
{
|
// String ext = "_highres";
|
// if (REDUCETEXTURE)
|
// ext = "_lowres";
|
String ext = "";
|
switch (resolution)
|
{
|
case 0: ext = "_lowres"; break;
|
case 1: ext = "_normalres"; break;
|
case 2: ext = "_highres"; break;
|
case 3: ext = "_veryhighres"; break;
|
case 4: ext = "_maxres"; break;
|
}
|
|
cachename = texname.substring(0, texname.length()-4)+ext+".jpg";
|
if (!FileExists(cachename))
|
cachename = texname;
|
else
|
processbump = false; // don't process bump map again
|
}
|
|
if (texname.endsWith(".png") || texname.endsWith(".PNG"))
|
{
|
// String ext = "_highres";
|
// if (REDUCETEXTURE)
|
// ext = "_lowres";
|
String ext = "";
|
switch (resolution)
|
{
|
case 0: ext = "_lowres"; break;
|
case 1: ext = "_normalres"; break;
|
case 2: ext = "_highres"; break;
|
case 3: ext = "_veryhighres"; break;
|
case 4: ext = "_maxres"; break;
|
}
|
|
cachename = texname.substring(0, texname.length()-4)+ext+".png";
|
if (!FileExists(cachename))
|
cachename = texname;
|
else
|
processbump = false; // don't process bump map again
|
}
|
|
texturedata = GetFileTexture(cachename, processbump, resolution);
|
|
|
if (texturedata == null)
|
throw new Exception();
|
|
texturecache = new CacheTexture(texturedata,resolution);
|
//texture = GetTexture(tex, bump);
|
}
|
}
|
}
|
//}
|
}
|
|
if (texdata == null && /*CACHETEXTURE &&*/ texturecache != null && textureon)
|
{
|
//return false;
|
|
// System.out.println("CACHE +++++++++++++++ TEXTURE : " + texname + " (" + texture.getEstimatedMemorySize() + ")");
|
if (texturedata != null && texname.toLowerCase().endsWith(".jpg"))
|
{
|
// String ext = "_highres";
|
// if (REDUCETEXTURE)
|
// ext = "_lowres";
|
String ext = "";
|
switch (resolution)
|
{
|
case 0: ext = "_lowres"; break;
|
case 1: ext = "_normalres"; break;
|
case 2: ext = "_highres"; break;
|
case 3: ext = "_veryhighres"; break;
|
case 4: ext = "_maxres"; break;
|
}
|
File cachefile = new File(texname.substring(0, texname.length()-4)+ext+".jpg");
|
if (!cachefile.exists())
|
{
|
//if (texturedata.getWidth() == texturedata.getHeight())
|
{
|
BufferedImage rendImage = CreateBim(texturedata);
|
|
ImageWriter writer = null;
|
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
|
if (iter.hasNext()) {
|
writer = (ImageWriter)iter.next();
|
}
|
|
float compressionQuality = 0.85f;
|
try
|
{
|
ImageOutputStream ios = ImageIO.createImageOutputStream(cachefile);
|
writer.setOutput(ios);
|
JPEGImageWriteParam iwparam=new JPEGImageWriteParam(Locale.getDefault());
|
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
|
iwparam.setCompressionQuality(compressionQuality);
|
writer.write(null, new IIOImage(rendImage, null, null), iwparam);
|
ios.flush();
|
writer.dispose();
|
ios.close();
|
}
|
catch(Exception e){};
|
}
|
}
|
}
|
|
Hashtable<cTexture, CacheTexture> textures = bump ? texturebump : texturepigment;
|
|
//System.out.println("Texture = " + tex);
|
if (textures.containsKey(tex))
|
{
|
CacheTexture thetex = textures.get(tex);
|
thetex.texture.disable();
|
thetex.texture.dispose();
|
textures.remove(tex);
|
}
|
|
//texture.texturedata = texturedata;
|
textures.put(tex, texturecache);
|
|
// newtex = true;
|
}
|
}
|
|
//Applet3D.tracein(this);
|
// assert (texture != null);
|
|
/**/
|
if (pigmentdepth > 0)
|
{
|
//INTENSITY FIX: texturestack[depth-1].disable();
|
}
|
}
|
|
return texturecache;
|
}
|
|
static void EmbedTextures(cTexture tex)
|
{
|
if (tex.pigmentdata == null)
|
{
|
//String texname = Object3D.GetPigment(tex);
|
|
CacheTexture texturecache = texturepigment.get(tex);
|
|
if (texturecache != null)
|
{
|
tex.pw = texturecache.texturedata.getWidth();
|
tex.ph = texturecache.texturedata.getHeight();
|
tex.pigmentdata = //CompressJPEG(CreateBim
|
((ByteBuffer)texturecache.texturedata.getBuffer()).array()
|
;
|
//, tex.pw, tex.ph), 0.5f);
|
}
|
}
|
|
if (tex.bumpdata == null)
|
{
|
//String texname = Object3D.GetBump(tex);
|
|
CacheTexture texturecache = texturebump.get(tex);
|
|
if (texturecache != null)
|
{
|
tex.bw = texturecache.texturedata.getWidth();
|
tex.bh = texturecache.texturedata.getHeight();
|
tex.bumpdata = //CompressJPEG(CreateBim(
|
((ByteBuffer)texturecache.texturedata.getBuffer()).array();
|
//, tex.bw, tex.bh), 0.5f);
|
}
|
}
|
}
|
|
com.sun.opengl.util.texture.Texture GetTexture(cTexture tex, boolean bump, int resolution) throws Exception
|
{
|
CacheTexture texture = GetCacheTexture(tex, bump, resolution);
|
|
if (bump)
|
{
|
// GrafreeD.trace("PUSH BUMP " + tex + "(" + bumpdepth + ")" + " : " + texture);
|
bumpstack[bumpdepth++] = texture!=null?texture.texture:null;
|
}
|
else
|
{
|
// GrafreeD.trace("PUSH PIGMENT " + tex + "(" + pigmentdepth + ")" + " : " + texture);
|
pigmentstack[pigmentdepth++] = texture!=null?texture.texture:null;
|
}
|
|
return texture!=null?texture.texture:null;
|
}
|
|
public com.sun.opengl.util.texture.TextureData GetTextureData(cTexture tex, boolean bump, int resolution) throws Exception
|
{
|
CacheTexture texture = GetCacheTexture(tex, bump, resolution);
|
|
return texture!=null?texture.texturedata:null;
|
}
|
|
boolean BindTexture(cTexture tex, boolean bump, int resolution) throws Exception
|
{
|
if (/*tex == null ||*/ ambientOcclusion ) // || !textureon)
|
{
|
return false;
|
}
|
|
//boolean newtex = false;
|
|
com.sun.opengl.util.texture.Texture texture = GetTexture(tex, bump, resolution);
|
|
if (texture == null)
|
return false;
|
/**/
|
|
if (textureon || tex.equals("DEFAULT_TEXTURE") || tex.equals("DEFAULT_TEXTURE_BUMP") || tex.equals("WHITE_NOISE")) // || tex.equals("IMMORTAL"))
|
{
|
texture.bind();
|
//INTENSITY FIX: texture.enable();
|
|
//System.out.println("TARGET = " + texture.getTarget());
|
}
|
|
|
// NEAREST
|
if (NEAREST)
|
{
|
GetGL().glTexParameteri(GetGL().GL_TEXTURE_2D, GetGL().GL_TEXTURE_MIN_FILTER, GetGL().GL_NEAREST);
|
GetGL().glTexParameteri(GetGL().GL_TEXTURE_2D, GetGL().GL_TEXTURE_MAG_FILTER, GetGL().GL_NEAREST);
|
}
|
else
|
{
|
GetGL().glTexParameteri(GetGL().GL_TEXTURE_2D, GetGL().GL_TEXTURE_MIN_FILTER, GetGL().GL_LINEAR);
|
GetGL().glTexParameteri(GetGL().GL_TEXTURE_2D, GetGL().GL_TEXTURE_MAG_FILTER, GetGL().GL_LINEAR);
|
}
|
|
texture.setTexParameteri(GetGL().GL_TEXTURE_WRAP_S, GetGL().GL_REPEAT);
|
texture.setTexParameteri(GetGL().GL_TEXTURE_WRAP_T, GetGL().GL_REPEAT);
|
|
return true; // Warning: not used.
|
}
|
|
public static byte[] CompressJPEG(BufferedImage image, float quality)
|
{
|
try
|
{
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
|
ImageWriter writer = writers.next();
|
|
ImageWriteParam param = writer.getDefaultWriteParam();
|
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
param.setCompressionQuality(quality);
|
|
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
|
writer.setOutput(ios);
|
writer.write(null, new IIOImage(image, null, null), param);
|
|
byte[] data = baos.toByteArray();
|
writer.dispose();
|
return data;
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
return null;
|
}
|
}
|
|
public static BufferedImage DecompressJPEG(byte[] image, int w, int h) throws IOException
|
{
|
ByteArrayInputStream baos = new ByteArrayInputStream(image);
|
Iterator<ImageReader> writers = ImageIO.getImageReadersByFormatName("jpg");
|
ImageReader reader = writers.next();
|
|
BufferedImage bim = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
|
ImageReadParam param = reader.getDefaultReadParam();
|
param.setDestination(bim);
|
//param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB));
|
|
ImageInputStream ios = ImageIO.createImageInputStream(baos);
|
reader.setInput(ios);
|
BufferedImage bim2 = reader.read(0, param);
|
reader.dispose();
|
|
// WritableRaster raster = bim2.getRaster();
|
// DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
|
// byte[] bytes = data.getData();
|
//
|
// int[] pixels = new int[bytes.length/3];
|
// for (int i=pixels.length; --i>=0;)
|
// {
|
// int i3 = i*3;
|
// pixels[i] = 0xFF;
|
// pixels[i] <<= 8;
|
// pixels[i] |= bytes[i3+2] & 0xFF;
|
// pixels[i] <<= 8;
|
// pixels[i] |= bytes[i3+1] & 0xFF;
|
// pixels[i] <<= 8;
|
// pixels[i] |= bytes[i3] & 0xFF;
|
// }
|
//
|
// bim.setRGB(0,0,w,h, pixels, w*(h-1),-w);
|
|
return bim;
|
}
|
|
ShadowBuffer shadowPBuf;
|
AntialiasBuffer antialiasPBuf;
|
int MAXSTACK;
|
|
public void init(GLAutoDrawable drawable)
|
{
|
timer.setRepeats(false);
|
AAtimer.setRepeats(false);
|
int[] temp = new int[1];
|
|
GL gl0 = drawable.getGL();
|
GL gl = drawable.getGL();
|
GL gl2 = getGL();
|
|
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_STACK_DEPTH, temp, 0);
|
MAXSTACK = temp[0];
|
if (Globals.DEBUG)
|
System.out.println("GL_MAX_TEXTURE_STACK_DEPTH = " + MAXSTACK);
|
gl.glGetIntegerv(GL.GL_MAX_MODELVIEW_STACK_DEPTH, temp, 0);
|
MAXSTACK = temp[0];
|
if (Globals.DEBUG)
|
System.out.println("GL_MAX_MODELVIEW_STACK_DEPTH = " + MAXSTACK);
|
|
// Use debug pipeline
|
//drawable.setGL(new DebugGL(gl)); //
|
//drawable.setGL(new TraceGL(gl, System.err)); //
|
gl = drawable.getGL(); //
|
|
GL gl3 = getGL();
|
if (Globals.DEBUG)
|
System.out.println("INIT GL IS: " + gl.getClass().getName());
|
|
|
//float pos[] = { 100, 100, 100, 0 };
|
|
//gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, pos, 0);
|
gl.glLightModeli(gl.GL_LIGHT_MODEL_TWO_SIDE, 1);
|
//if (CULLFACE)
|
// gl.glEnable(gl.GL_CULL_FACE);
|
gl.glEnable(gl.GL_LIGHT0);
|
// speed
|
//gl.glShadeModel(gl.GL_FLAT);
|
//gl.glColorMask(false, false, false, false);
|
//gl.glEnable(gl.GL_LIGHTING);
|
|
gl.glEnable(gl.GL_DEPTH_TEST);
|
|
gl.glAlphaFunc(gl.GL_GEQUAL, 0.99f);
|
|
gl.glEnable(gl.GL_NORMALIZE);
|
|
gl.setSwapInterval(1);
|
|
//gl.glDrawBuffer(gl.GL_FRONT_AND_BACK); //
|
|
/*
|
double pos[] = { 5, 5, 10, 0 };
|
double red[] = { 0.8, 0.1, 0, 1 };
|
double green[] = { 0, 0.8, 0.2, 1 };
|
double blue[] = { 0.2, 0.2, 1, 1 };
|
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, pos, 0);
|
gl.glEnable(gl.GL_CULL_FACE);
|
gl.glEnable(gl.GL_LIGHTING);
|
gl.glEnable(gl.GL_LIGHT0);
|
gl.glEnable(gl.GL_DEPTH_TEST);
|
gear1 = gl.glGenLists(1);
|
gl.glNewList(gear1, gl.GL_COMPILE);
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_AMBIENT_AND_DIFFUSE, red, 0);
|
gear(gl, 1, 4, 1, 20, 0.7f);
|
gl.glEndList();
|
gl.glEnable(gl.GL_NORMALIZE);
|
drawable.addMouseListener(this);
|
drawable.addMouseMotionListener(this);
|
*/
|
/* TEXTURE
|
try
|
{
|
texture =
|
//TextureIO.newTexture(getClass().getClassLoader().getResourceAsStream("nvlogo_spot.png"),
|
TextureIO.newTexture(getClass().getClassLoader().getResourceAsStream("image.png"),
|
true,
|
TextureIO.PNG);
|
texture.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
|
texture.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
|
} catch (IOException e)
|
{
|
throw new GLException(e);
|
}
|
*/
|
|
/*
|
int i=-1;;
|
if (textures[0] == null)
|
{
|
try
|
{
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
//getClass().getClassLoader().getResourceAsStream("image.png"),
|
new FileInputStream("/Users/nbriere/download/FairyHouse/anbaud.jpg"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("marble.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("nvlogo_spot.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("oak01b.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("skin_nor.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("4kcallisto__johnvanvliet.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("4kganymede__johnvanvliet.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("logo.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("uffizi_posy.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
textures[++i] =
|
com.sun.opengl.util.texture.TextureIO.newTexture(
|
com.sun.opengl.util.texture.TextureIO.newTextureData(
|
getClass().getClassLoader().getResourceAsStream("cubemaps/CloudyHills_posz.png"),
|
true,
|
com.sun.opengl.util.texture.TextureIO.PNG));
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
|
textures[i].setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
|
nbtex = 1; // i+1;
|
} catch (java.io.IOException e)
|
{
|
System.out.println("i = " + i);
|
throw new javax.media.opengl.GLException(e);
|
}
|
}
|
*/
|
|
//texture.bind();
|
//texture.enable();
|
|
//gl.glMatrixMode(gl.GL_TEXTURE);
|
//gl.glScaled(2,1,1);
|
|
//gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
|
|
if (cubemap == null)
|
{
|
//LoadEnvy(1);
|
}
|
|
//cubemap.enable();
|
|
if (selectbuffer == null)
|
{
|
// init pbuffer
|
GLCapabilities caps = new GLCapabilities();
|
caps.setDoubleBuffered(false);
|
|
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer())
|
{
|
UnavailableExtension("Can not create pbuffer");
|
}
|
if (selectbuffer != null)
|
{
|
selectbuffer.destroy();
|
selectbuffer = null;
|
}
|
selectbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, new DefaultGLCapabilitiesChooser(), TEX_SIZE, TEX_SIZE, drawable.getContext());
|
selectbuffer.addGLEventListener(new SelectBuffer(this));
|
}
|
|
GLContext test = drawable.getContext();
|
|
if (shadowbuffer == null)
|
{
|
// init pbuffer
|
GLCapabilities caps = new GLCapabilities();
|
caps.setDoubleBuffered(false);
|
|
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer())
|
{
|
UnavailableExtension("Can not create pbuffer");
|
}
|
if (shadowbuffer != null)
|
{
|
shadowbuffer.destroy();
|
shadowbuffer = null;
|
}
|
shadowbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, new DefaultGLCapabilitiesChooser(), SHADOW_SIZE, SHADOW_SIZE, drawable.getContext());
|
shadowbuffer.addGLEventListener(shadowPBuf = new ShadowBuffer(this));
|
}
|
|
if (antialiasbuffer == null)
|
{
|
// init pbuffer
|
GLCapabilities caps = new GLCapabilities();
|
caps.setDoubleBuffered(false);
|
|
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer())
|
{
|
UnavailableExtension("Can not create pbuffer");
|
}
|
if (antialiasbuffer != null)
|
{
|
antialiasbuffer.destroy();
|
antialiasbuffer = null;
|
}
|
antialiasbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, new DefaultGLCapabilitiesChooser(), SHADOW_SIZE, SHADOW_SIZE, drawable.getContext());
|
antialiasbuffer.addGLEventListener(antialiasPBuf = new AntialiasBuffer(this));
|
}
|
|
if (occlusionbuffer == null)
|
{
|
// init pbuffer
|
GLCapabilities caps = new GLCapabilities();
|
caps.setDoubleBuffered(false);
|
|
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer())
|
{
|
UnavailableExtension("Can not create pbuffer");
|
}
|
if (occlusionbuffer != null)
|
{
|
occlusionbuffer.destroy();
|
occlusionbuffer = null;
|
}
|
occlusionbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, new DefaultGLCapabilitiesChooser(), OCCLUSION_SIZE, OCCLUSION_SIZE, drawable.getContext());
|
occlusionbuffer.addGLEventListener(new OcclusionBuffer(this));
|
}
|
|
if (!programInitialized)
|
{
|
InitializePrograms(drawable);
|
}
|
}
|
|
void InitializePrograms(GLAutoDrawable drawable)
|
{
|
GL gl = drawable.getGL();
|
|
programInitialized = true;
|
|
//fragmentProgram[FP_SHADER] = gl.glGenLists(1);
|
//fragmentProgram[FP_SHADER | FP_ANISO] = gl.glGenLists(1);
|
|
// shadow program
|
fragmentProgram[0] = gl.glGenLists(1);
|
InitShadowProgram(gl);
|
|
for (int light = 0; light < 3; light++) // crash with 3 lights + aniso
|
{
|
int index = (light << 3); // 2);
|
fragmentProgram[FP_SHADER | index] = gl.glGenLists(1);
|
fragmentProgram[FP_SHADER | FP_ANISO | index] = gl.glGenLists(1);
|
fragmentProgram[FP_SHADER | FP_SOFTSHADOW | index] = gl.glGenLists(1);
|
fragmentProgram[FP_SHADER | FP_ANISO | FP_SOFTSHADOW | index] = gl.glGenLists(1);
|
InitFragmentProgram(gl, FP_SHADER | index);
|
InitFragmentProgram(gl, FP_SHADER | FP_ANISO | index);
|
InitFragmentProgram(gl, FP_SHADER | FP_SOFTSHADOW | index);
|
InitFragmentProgram(gl, FP_SHADER | FP_ANISO | FP_SOFTSHADOW | index);
|
/*
|
fragmentProgram[FP_SHADER | FP_LIGHT] = gl.glGenLists(1);
|
fragmentProgram[FP_SHADER | FP_ANISO | FP_LIGHT] = gl.glGenLists(1);
|
InitFragmentProgram(gl, FP_SHADER);
|
InitFragmentProgram(gl, FP_SHADER | FP_ANISO);
|
InitFragmentProgram(gl, FP_SHADER | FP_LIGHT);
|
InitFragmentProgram(gl, FP_SHADER | FP_ANISO | FP_LIGHT);
|
*/
|
}
|
vertexProgram[0] = gl.glGenLists(1);
|
vertexProgram[VP_PASS] = gl.glGenLists(1);
|
vertexProgram[VP_PASS | VP_PROJECTION] = gl.glGenLists(1);
|
InitVertexProgram(gl, 0); // , vertexProgram);
|
InitVertexProgram(gl, VP_PASS); // , vertexProgram);
|
InitVertexProgram(gl, VP_PASS | VP_PROJECTION); // , vertexProgram);
|
}
|
|
boolean printed = true; // false;
|
|
private void loadProgram(GL gl, int target, String programBuffer)
|
{
|
gl.glProgramStringARB(target, GL.GL_PROGRAM_FORMAT_ASCII_ARB,
|
programBuffer.length(), programBuffer);
|
int[] errPos = new int[1];
|
|
gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0);
|
if (errPos[0] >= 0)
|
{
|
String kind = "Program";
|
if (target == GL.GL_VERTEX_PROGRAM_ARB)
|
{
|
kind = "Vertex program";
|
} else if (target == GL.GL_FRAGMENT_PROGRAM_ARB)
|
{
|
kind = "Fragment program";
|
}
|
System.out.println(kind + " failed to load:");
|
String errMsg = gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB);
|
if (errMsg == null)
|
{
|
System.out.println("[No error message available]");
|
} else
|
{
|
System.out.println("Error message: \"" + errMsg + "\"");
|
}
|
System.out.println("Error occurred at position " + errPos[0] + " in program:");
|
int endPos = errPos[0];
|
while (endPos < programBuffer.length() && programBuffer.charAt(endPos) != '\n')
|
{
|
++endPos;
|
}
|
System.out.println(programBuffer.substring(errPos[0], endPos));
|
throw new GLException("Error loading " + kind);
|
} else
|
{
|
if (target == GetGL().GL_FRAGMENT_PROGRAM_ARB)
|
{
|
int[] isNative = new int[1];
|
/**/
|
if (!printed)
|
{
|
// printed = true;
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_LENGTH_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_LENGTH_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_FORMAT_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_FORMAT_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_BINDING_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_BINDING_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_INSTRUCTIONS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_INSTRUCTIONS_ARB = " + isNative[0]);
|
System.out.println();
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_INSTRUCTIONS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_INSTRUCTIONS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_TEMPORARIES_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_TEMPORARIES_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_TEMPORARIES_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_TEMPORARIES_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_NATIVE_TEMPORARIES_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_NATIVE_TEMPORARIES_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_NATIVE_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_NATIVE_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_ATTRIBS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_ATTRIBS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_ATTRIBS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_ATTRIBS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_NATIVE_ATTRIBS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_NATIVE_ATTRIBS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_ADDRESS_REGISTERS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_ADDRESS_REGISTERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, isNative, 0);
|
System.out.println("GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = " + isNative[0]);
|
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, isNative, 0);
|
System.out.println("GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = " + isNative[0]);
|
System.out.println();
|
}
|
/**/
|
gl.glGetProgramivARB(GetGL().GL_FRAGMENT_PROGRAM_ARB,
|
GetGL().GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, isNative, 0);
|
if (isNative[0] != 1)
|
{
|
System.out.println("WARNING: fragment program is over native resource limits");
|
Thread.dumpStack();
|
}
|
}
|
}
|
}
|
|
private void UnavailableExtension(String message)
|
{
|
JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE);
|
throw new GLException(message);
|
}
|
|
void LoadEnvy(int which)
|
{
|
assert(false);
|
|
String name;
|
String ext;
|
|
boolean mipmap = true;
|
|
switch (which)
|
{
|
case 0:
|
cubemap = null;
|
return;
|
case 1:
|
name = "cubemaps/rgb/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 2:
|
name = "cubemaps/uffizi/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 3:
|
name = "cubemaps/CloudyHills/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 4:
|
name = "cubemaps/cornell/";
|
ext = "png";
|
reverseUP = false;
|
break;
|
case 5:
|
name = "cubemaps/skycube/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 6:
|
name = "cubemaps/SaintLazarusChurch3/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 7:
|
name = "cubemaps/Sodermalmsallen/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 8:
|
name = "cubemaps/Sodermalmsallen2/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
case 9:
|
name = "cubemaps/UnionSquare/";
|
ext = "jpg";
|
reverseUP = false;
|
break;
|
default:
|
name = "cubemaps/box/";
|
ext = "png"; /*mipmap = true;*/
|
reverseUP = false;
|
break;
|
}
|
|
LoadSkybox(name, ext, mipmap);
|
}
|
|
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
|
{
|
GL gl = drawable.getGL();
|
|
//System.out.println("RESHAPE GL IS: " + gl.getClass().getName());
|
/*
|
double h = (double)height / (double)width;
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
System.err.println("GL_VENDOR: " + gl.glGetString(gl.GL_VENDOR));
|
System.err.println("GL_RENDERER: " + gl.glGetString(gl.GL_RENDERER));
|
System.err.println("GL_VERSION: " + gl.glGetString(gl.GL_VERSION));
|
gl.glLoadIdentity();
|
gl.glFrustum(-1, 1, -h, h, 5, 60);
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
gl.glTranslatef(0, 0, -40);
|
*/
|
}
|
|
static double[] view = new double[16];
|
double[] view_1 = new double[16];
|
double[] viewrot_1 = new double[16];
|
double[] lightmat = new double[16];
|
double[] lightmat_1 = new double[16];
|
static double[] tempmat = new double[16];
|
static double[] tempmat2 = new double[16];
|
static double[] model = new double[16];
|
double[] camera2light = new double[16];
|
double[] light2camera = new double[16];
|
|
//int newenvy = -1;
|
//boolean envyoff = false;
|
|
String loadedskyboxname;
|
|
cVector light0 = new cVector(0, 0, 0); // 1,3,2);
|
//float[] light0 = { 0,0,0 };
|
cVector dirlight = new cVector(0, 0, 1); // 1,3,2);
|
cVector lightposition = new cVector();
|
cVector lightcolor = new cVector(1, 1, 1);
|
static boolean programInitialized = false;
|
static boolean selectInitialized = false;
|
static boolean shadowInitialized = false;
|
static boolean antialiasInitialized = false;
|
static boolean occlusionInitialized = false;
|
boolean selection = false;
|
boolean pointselection = false;
|
///*static*/ boolean lighttouched = true;
|
boolean deselect;
|
private boolean ambientOcclusion = false;
|
static boolean flash = false;
|
/*static*/ boolean wait = false;
|
boolean displaydone = false; // after repaint() calls
|
//static boolean drawing = false;
|
// Shadowing light
|
float near_plane = 10f;
|
float far_plane = 10000000f;
|
int vertexMode, fragmentMode;
|
static boolean SPHERICAL = false;
|
final int VP_PROJECTION = 1;
|
final int VP_PASS = 2;
|
final int FP_SHADER = 1; // 1;
|
final int FP_ANISO = 2; // 2;
|
final int FP_SOFTSHADOW = 4; // 2;
|
final int FP_LIGHT = ~3; // 4;
|
|
void InitPBuffers()
|
{
|
if (!selectInitialized)
|
{
|
System.out.println("init select");
|
selectbuffer.display();
|
}
|
|
if (!shadowInitialized)
|
{
|
System.out.println("init shadow");
|
shadowbuffer.display();
|
}
|
|
if (!antialiasInitialized)
|
{
|
System.out.println("init antialias");
|
antialiasbuffer.display();
|
}
|
|
if (!occlusionInitialized)
|
{
|
System.out.println("init occlusion");
|
occlusionbuffer.display();
|
}
|
}
|
|
static int[] viewport = new int[4];
|
|
void accFrustum(javax.media.opengl.GL gl, double left, double right, double bottom,
|
double top, double near, double far, double pixdx,
|
double pixdy, double eyedx, double eyedy,
|
double focus)
|
{
|
double xwsize, ywsize;
|
double dx, dy;
|
|
gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
|
xwsize = right - left;
|
ywsize = top - bottom;
|
dx = -(pixdx * xwsize / (double) viewport[2] +
|
eyedx / focus); // *(focus - near));
|
dy = -(pixdy * ywsize / (double) viewport[3] +
|
eyedy / focus); // *(focus - near));
|
|
//dx *= 100;
|
//dy *= 100;
|
//System.out.println("dx dy = " + dx + ", " + dy);
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
gl.glFrustum(left + dx, right + dx, bottom + dy, top + dy,
|
near, far);
|
if (true) //eyedx != 0 && eyedy != 0)
|
{
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
gl.glTranslated(-eyedx, -eyedy, 0.0);
|
|
gl.glMultMatrixd(view, 0);
|
if (object.fromParent != null)
|
{
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
model[j * 4 + i] = object.fromParent[j][i];
|
}
|
}
|
|
gl.glMultMatrixd(model, 0);
|
}
|
//gl.glGetDoublev(gl.GL_PROJECTION_MATRIX, tempmat, 0);
|
//SetColumnMajorData(m, tempmat);
|
//System.out.println("MAT = " + m);
|
|
// Depth correction
|
gl.glActiveTexture(GL.GL_TEXTURE1);
|
|
//gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
gl.glTranslated(-eyedx, -eyedy, 0.0);
|
gl.glMultMatrixd(view, 0);
|
if (object.fromParent != null)
|
{
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
model[j * 4 + i] = object.fromParent[j][i];
|
}
|
}
|
|
gl.glMultMatrixd(model, 0);
|
}
|
|
eye_linear_texgen(gl);
|
texgen(gl, true);
|
gl.glPopMatrix();
|
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glLoadIdentity();
|
/**/
|
//if (!RENDERPROGRAM)
|
{
|
gl.glTranslatef(.5f, .5f, 0.5f); // ((Tweak) tweaks.get(R_COORDINATE_SCALE)).val);
|
gl.glScalef(.5f, .5f, 0.5f); // ((Tweak) tweaks.get(R_COORDINATE_BIAS)).val);
|
}
|
//double scale = 10/lightCamera.Distance(); // 0.1;
|
//gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 1, 100);
|
//glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar);
|
double scale = lightCamera.SCALE / lightCamera.Distance();
|
// PATCH FILLE AUX JEANS
|
//scale *= lightCamera.shaper_fovy / 25;
|
gl.glScaled(2 * scale, 2 * scale, -scale);
|
gl.glTranslated(0, 0, lightCamera.DECAL);
|
|
//double scale = camera.Distance() * 5; // /view.getScale();
|
//gl.glOrtho(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 0.001, 100000);
|
//scale = 1000/camera.Distance();
|
//gl.glScaled(scale,scale,scale);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
lightmat[j * 4 + i] = lightCamera.toScreen[j][i];
|
}
|
}
|
|
//lightmat[3*4 + 3] = 1;
|
|
//SetColumnMajorData(spotlightTransform, lightmat);
|
//ApplyTransform(gl, spotlightTransform);
|
gl.glMultMatrixd(lightmat, 0);
|
|
if (RENDERPROGRAM != 0)
|
{
|
gl.glPushMatrix();
|
|
gl.glMultMatrixd(view_1, 0);
|
gl.glTranslated(eyedx, eyedy, 0.0);
|
|
gl.glGetDoublev(gl.GL_TEXTURE_MATRIX, tempmat, 0);
|
|
gl.glPopMatrix();
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
camera2light[j * 4 + i] = tempmat[i * 4 + j];
|
}
|
}
|
//lightmat[j*4+i] = camera2light[j*4+i];
|
|
// jan 2013: bizarre!
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 0, camera2light, 0);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 1, camera2light, 4);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 2, camera2light, 8);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 3, camera2light, 12);
|
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
|
gl.glTranslated(-eyedx, -eyedy, 0.0);
|
gl.glMultMatrixd(view, 0);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
lightmat[j * 4 + i] = lightCamera.fromScreen[j][i];
|
}
|
}
|
|
gl.glMultMatrixd(lightmat, 0);
|
|
gl.glTranslated(0, 0, -lightCamera.DECAL);
|
|
scale = lightCamera.Distance();
|
gl.glScaled(scale / 2, scale / 2, -scale);
|
|
gl.glScalef(2, 2, 2);
|
gl.glTranslatef(-0.5f, -0.5f, -0.5f);
|
|
gl.glGetDoublev(gl.GL_TEXTURE_MATRIX, tempmat, 0);
|
|
gl.glPopMatrix();
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
light2camera[j * 4 + i] = tempmat[i * 4 + j];
|
}
|
}
|
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 10, light2camera, 0);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 11, light2camera, 4);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 12, light2camera, 8);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 13, light2camera, 12);
|
}
|
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
gl.glActiveTexture(GL.GL_TEXTURE0);
|
}
|
}
|
|
void accPerspective(javax.media.opengl.GL gl, double fovy, double aspect,
|
double near, double far, double pixdx, double pixdy,
|
double eyedx, double eyedy, double focus)
|
{
|
double fov2, left, right, bottom, top;
|
fov2 = ((fovy * Math.PI) / 180.0) / 2.0;
|
|
double angle = options1[4] * Math.PI;
|
double cosa = Math.cos(angle);
|
double sina = Math.sin(angle);
|
|
eyedy *= 1 - options1[3];
|
|
double edx = eyedx*cosa - eyedy*sina;
|
double edy = eyedx*sina + eyedy*cosa;
|
|
top = near / (Math.cos(fov2) / Math.sin(fov2));
|
bottom = -top;
|
right = top * aspect;
|
left = -right;
|
|
accFrustum(gl, left, right, bottom, top, near, far,
|
pixdx, pixdy, edx, edy, focus);
|
}
|
|
static int ACSIZE = 4; // 16;
|
static int MAXACSIZE = 256; // 1024;
|
static float[] jx8 = new float[MAXACSIZE];
|
static float[] jy8 = new float[MAXACSIZE];
|
static float[] jz8 = new float[MAXACSIZE];
|
int VPwidth, VPheight;
|
|
static
|
{
|
for (int i = 0; i < MAXACSIZE; i++)
|
{
|
jx8[i] = ((float) Math.random() - 0.5f);
|
jy8[i] = ((float) Math.random() - 0.5f);
|
jz8[i] = ((float) Math.random() - 0.5f);
|
}
|
|
jx8[0] = 0;
|
jx8[1] = 0;
|
jx8[2] = 0.5f;
|
jx8[3] = 0.5f;
|
jy8[0] = 0;
|
jy8[1] = 0.5f;
|
jy8[2] = 0;
|
jy8[3] = 0.5f;
|
}
|
|
float[] options1 = new float[]{100, 0.00001f, 20, 0, 0}; // focus, aperture, Shadow blur, aniso, anisoV
|
float[] options2 = new float[]{0, 1, 0, 0}; // fog density, intensity, elevation
|
float[] options3 = new float[]{1, 1, 1, 0}; // fog color
|
float[] options4 = new float[]{1, 0, 1, 0}; // image intensity, subsurface, lightsheen
|
|
void ResetOptions()
|
{
|
options1[0] = 100;
|
options1[1] = 0.025f;
|
options1[2] = 0.01f;
|
options1[3] = 0;
|
options1[4] = 0;
|
|
options2[0] = 0;
|
options2[1] = 0.75f;
|
options2[2] = 0;
|
options2[3] = 0;
|
|
options3[0] = 1;
|
options3[1] = 1;
|
options3[2] = 1;
|
options3[3] = 0;
|
|
options4[0] = 1;
|
options4[1] = 0;
|
options4[2] = 1;
|
options4[3] = 0;
|
}
|
|
static int imagecount = 0; // movie generation
|
|
static int jitter = 0;
|
|
boolean restartframe = false;
|
|
void displayAntiAliased(javax.media.opengl.GL gl)
|
{
|
//gl.glGetIntegerv(gl.GL_ACCUM_RED_BITS, viewport, 0);
|
//System.out.println("accum = " + viewport[0]);
|
gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
//System.out.println("viewport = " + viewport[0] + " " + viewport[1] + " " + viewport[2] + " " + viewport[3]);
|
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
// OPENGL antialiasing
|
//int jitter;
|
|
//gl.glReadBuffer(GL.GL_BACK);
|
gl.glDrawBuffer(GL.GL_BACK);
|
|
cVector loc = new cVector();
|
loc.set(lightCamera.location);
|
cVector look = new cVector();
|
look.set(lightCamera.lookAt);
|
|
cVector dir = new cVector();
|
dir.set(look);
|
dir.sub(loc);
|
double dist = dir.length();
|
|
// options3[3] /= 4;
|
|
//System.out.println("start frame");
|
gl.glClear(gl.GL_ACCUM_BUFFER_BIT);
|
for (jitter = 0; jitter < ACSIZE; jitter++) //, GrafreeD.wav.cursor += LIVE ? 735 : 0)
|
{
|
Globals.framecount++;
|
|
if (CameraPane.tickcount > 0)
|
CameraPane.tickcount--;
|
|
// GrafreeD.wav.cursor += 735; // 44100 Hz / 120 Hz * 2 (for 16 bits)
|
// restartframe = true;
|
if (options1[2] > 100 && (jitter%2==0))
|
{
|
dir.set(jx8[jitter], jy8[jitter], jz8[jitter]);
|
dir.normalize();
|
dir.mul(dist);
|
dir.add(look);
|
lightCamera.setAim(dir, look);
|
}
|
else
|
{
|
lightCamera.setAim(loc, look);
|
float factor = options1[2];
|
if (factor > 100)
|
factor /= 100;
|
lightCamera.RotatePosition(jx8[jitter] * factor, jy8[jitter] * factor);
|
}
|
|
/*
|
lightposition.set(lightCamera.location);
|
lightposition.sub(lightCamera.lookAt);
|
|
//LA.xformDir(dirlight, lightCamera.fromScreen, lightposition);
|
|
LA.xformDir(lightposition, renderCamera.toScreen, lightposition);
|
|
lightposition.normalize();
|
|
float pos[] = {(float) lightposition.x, (float) lightposition.y, (float) lightposition.z, 0};
|
|
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, pos, 0);
|
*/
|
Globals.lighttouched = true;
|
//System.err.println(" shadowbuffer: " + jitter);
|
shadowbuffer.display();
|
|
Camera parentcam = renderCamera;
|
|
if (renderCamera == cameras[0])
|
{
|
parentcam = cameras[1];
|
}
|
|
if (renderCamera == cameras[1])
|
{
|
parentcam = cameras[0];
|
}
|
|
LA.matCopy(renderCamera.toScreen, matrix);
|
|
assert (parentcam != renderCamera);
|
|
if (renderCamera != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.matConcat(matrix, parentcam.GlobalTransformInv(), matrix);
|
|
// LA.matConcat(renderCamera.toScreen, renderCamera.toParent, matrix);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
view[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
LA.matCopy(renderCamera.fromScreen, matrix);
|
|
if (renderCamera != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.matConcat(parentcam.GlobalTransform(), matrix, matrix);
|
|
// LA.matConcat(renderCamera.fromParent, renderCamera.fromScreen, matrix);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
view_1[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
for (int j = 0; j < 3; j++)
|
{
|
for (int i = 0; i < 3; i++)
|
{
|
viewrot_1[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
viewrot_1[3 * 4 + 3] = 1;
|
|
gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
double ratio = (double) viewport[2] / (double) viewport[3];
|
|
//System.out.println("viewport2 = " + viewport[0] + " " + viewport[1] + " " + viewport[2] + " " + viewport[3]);
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
|
//gl.glMatrixMode(GL.GL_TEXTURE);
|
//gl.glLoadIdentity();
|
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
|
double rati = ((double) getHeight()) / getWidth();
|
boolean yx = false;
|
|
double skyscale = 3.8; // 3.8
|
if (rati > 1)
|
{
|
gl.glOrtho(-skyscale, skyscale, -skyscale / rati, skyscale / rati, 0.001, 1000);
|
} else
|
{
|
yx = true;
|
rati = 1 / rati;
|
gl.glOrtho(-skyscale / rati, skyscale / rati, -skyscale, skyscale, 0.001, 1000);
|
}
|
|
//assert (newenvy == -1);
|
|
gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
DrawSkyBox(gl, (float)rati);
|
gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB);
|
|
boolean vr = capsLocked && !lightMode;
|
|
accPerspective(gl, renderCamera.shaper_fovy / ratio * (vr ? 1.2 : 1),
|
ratio,
|
//near_plane, far_plane,
|
renderCamera.shaper_zNear * renderCamera.Distance(), renderCamera.shaper_zFar * renderCamera.Distance(),
|
//jx8[jitter] * options1[3], jy8[jitter] * options1[3],
|
jx8[jitter], jy8[jitter],
|
jx8[(jitter + 123) % ACSIZE] * /*modelParams2[1]*/ options1[1] * renderCamera.Distance(),
|
jy8[(jitter + 123) % ACSIZE] * /*modelParams2[1]*/ options1[1] * renderCamera.Distance(),
|
options1[0]); // modelParams5[0]);
|
//System.out.println("aperture = " + modelParams2[1]);
|
//System.out.println("focus = " + modelParams5[0]);
|
////displayObjects ();
|
//object.draw(this, false);
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
//System.err.println(" DrawObject: " + jitter);
|
DrawObject(gl, jitter == ACSIZE - 1);
|
|
//gl.glFlush();
|
gl.glAccum(gl.GL_ACCUM, 1.0f / ACSIZE);
|
|
if (Globals.ANIMATION && ABORTED)
|
{
|
System.err.println(" ABORTED FRAME");
|
break;
|
}
|
/**
|
gl.glDrawBuffer(GL.GL_FRONT);
|
gl.glAccum(gl.GL_RETURN, 1);
|
gl.glDrawBuffer(GL.GL_BACK);
|
/**/
|
// gl.glFlush();
|
}
|
|
//if (ABORTED)
|
// System.err.println("aborted frame");
|
//else
|
// System.err.println("done frame");
|
|
jitter = 0;
|
// options3[3] *= 4;
|
|
gl.glAccum(gl.GL_RETURN, 1); // /options3[3]);
|
//System.out.println("boost = " + options3[3]);
|
gl.glFlush();
|
/**/
|
|
lightCamera.setAim(loc, look);
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
// save image
|
if (Globals.ANIMATION && !ABORTED)
|
{
|
VPwidth = viewport[2];
|
VPheight = viewport[3];
|
|
int offset = 0;
|
|
// patch for NULLE PART
|
int keepVPwidth = VPwidth;
|
|
//VPwidth = 1536;
|
//offset = 56;
|
|
if (savebuffersize != VPwidth * VPheight)
|
{
|
savebuffersize = VPwidth * VPheight;
|
Savebuffer = IntBuffer.allocate(savebuffersize);
|
}
|
|
/*
|
//shadowbuffer.removeGLEventListener(shadowPBuf);
|
//shadowbuffer.addGLEventListener(antialiasPBuf);
|
antialiasbuffer.display();
|
int[] pixels = bigAAbuffer.array();
|
//shadowbuffer.removeGLEventListener(antialiasPBuf);
|
//shadowbuffer.addGLEventListener(shadowPBuf);
|
/**/
|
//object.draw(this, false);
|
|
gl.glReadPixels(offset, 0, VPwidth, VPheight, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, Savebuffer);
|
int[] pixels = Savebuffer.array();
|
|
assert(pixels.length == VPwidth*VPheight);
|
|
/*
|
int r=0,g=0,b=0,a=0;
|
for (int i=0; i<width; i++)
|
for (int j=0; j<height; j++)
|
{
|
int index = j*width+i;
|
int p = pixels[index];
|
a = ((p>>24) & 0xFF);
|
r = ((p>>16) & 0xFF);
|
g = ((p>>8) & 0xFF);
|
b = (p & 0xFF);
|
pixels[index] = (a<<24) | (b<<16) | (g<<8) | r;
|
}
|
/**/
|
if (ROTATECAMERA)
|
{
|
int[] pixels2 = new int[pixels.length];
|
|
for (int j=0; j<VPheight; j++)
|
{
|
for (int i=0; i<VPwidth; i++)
|
{
|
// if (i<j)
|
// continue;
|
|
int index = j*VPwidth + i;
|
int index2 = i*VPheight + j;
|
|
pixels2[index2] = pixels[index];
|
}
|
}
|
|
System.arraycopy(pixels2, 0, pixels, 0, pixels.length);
|
}
|
|
if (IMAGEFLIP) // ^ ROTATECAMERA)
|
for (int j=0; j<VPheight; j++)
|
{
|
for (int i=0; i<VPwidth/2; i++)
|
{
|
int index = j*VPwidth + i;
|
int index2 = j*VPwidth + VPwidth-1-i;
|
|
int temp = pixels[index2];
|
pixels[index2] = pixels[index];
|
pixels[index] = temp;
|
}
|
}
|
|
BufferedImage rendImage;
|
|
if (ROTATECAMERA)
|
{
|
rendImage = new BufferedImage(VPheight/16*16, VPwidth/2*2, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
|
rendImage.setRGB(0,0,VPheight/16*16,VPwidth/2*2,pixels,VPheight*(VPwidth-1),-VPheight);
|
}
|
else
|
{
|
rendImage = new BufferedImage(VPwidth/16*16, VPheight/2*2, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
|
rendImage.setRGB(0,0,VPwidth/16*16,VPheight/2*2,pixels,VPwidth*(VPheight-1),-VPwidth);
|
}
|
ImageWriter writer = null;
|
String ext = "jpg";
|
if (Udebug || Vdebug || NORMALdebug)
|
ext = "png";
|
Iterator iter = ImageIO.getImageWritersByFormatName(ext);
|
if (iter.hasNext()) {
|
writer = (ImageWriter)iter.next();
|
}
|
|
// patch for NULLE PART
|
VPwidth = keepVPwidth;
|
|
int i = imagecount++;
|
|
// imagecount++;
|
|
String fullname = Globals.filename + (i%100000)/10000 + "" + (i%10000)/1000 + "" + (i%1000)/100 + "" + (i%100)/10 + "" + (i%10) + "." + ext;
|
|
if (!BOXMODE)
|
{
|
System.out.println("image: " + fullname + " (wav cursor=" + (Grafreed.wav.cursor / 735 / 4) + ")");
|
}
|
|
if (!BOXMODE)
|
{
|
File outfile = new File(fullname);
|
|
float compressionQuality = 0.85f;
|
|
try
|
{
|
ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
|
writer.setOutput(ios);
|
JPEGImageWriteParam iwparam=new JPEGImageWriteParam(Locale.getDefault());
|
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
|
iwparam.setCompressionQuality(compressionQuality);
|
writer.write(null, new IIOImage(rendImage, null, null), iwparam);
|
ios.flush();
|
writer.dispose();
|
ios.close();
|
}
|
catch(Exception e){};
|
}
|
}
|
else
|
{
|
if (ACSIZE > 1)
|
{
|
// System.err.println("image #" + (GrafreeD.wav.cursor / 735 / 4));
|
}
|
}
|
|
if (ABORTED)
|
{
|
System.err.println("RESET ABORT (frame)");
|
ABORTED = false;
|
}
|
else
|
Grafreed.wav.cursor += 735 * ACSIZE;
|
|
if (false)
|
{
|
VPwidth = viewport[2];
|
VPheight = viewport[3];
|
|
if (AAbuffersize != VPwidth * VPheight)
|
{
|
AAbuffersize = VPwidth * VPheight;
|
AAbuffer = IntBuffer.allocate(AAbuffersize);
|
bigAAbuffer = IntBuffer.allocate(AAbuffersize * 4);
|
}
|
|
/*
|
//shadowbuffer.removeGLEventListener(shadowPBuf);
|
//shadowbuffer.addGLEventListener(antialiasPBuf);
|
antialiasbuffer.display();
|
int[] pixels = bigAAbuffer.array();
|
//shadowbuffer.removeGLEventListener(antialiasPBuf);
|
//shadowbuffer.addGLEventListener(shadowPBuf);
|
/**/
|
DrawObject(gl);
|
//object.draw(this, false);
|
gl.glReadPixels(0, 0, VPwidth, VPheight, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, AAbuffer);
|
int[] pixels = AAbuffer.array();
|
|
/*
|
int r=0,g=0,b=0,a=0;
|
for (int i=0; i<width; i++)
|
for (int j=0; j<height; j++)
|
{
|
int index = j*width+i;
|
int p = pixels[index];
|
a = ((p>>24) & 0xFF);
|
r = ((p>>16) & 0xFF);
|
g = ((p>>8) & 0xFF);
|
b = (p & 0xFF);
|
pixels[index] = (a<<24) | (b<<16) | (g<<8) | r;
|
}
|
/**/
|
|
if (pixels4.length < pixels.length * 4)
|
{
|
pixelstmp = new short[pixels.length]; // RGBA / 2x2
|
pixels4 = new short[pixels.length * 4]; // RGBA
|
pixels16 = new short[pixels.length * 4 * 4]; // 2x2 RGBA
|
pixels64 = new short[pixels.length * 4 * 4 * 4];
|
//pixels256 = new short[pixels.length*4 * 4 * 4 * 4];
|
System.out.println("Size of buffer = " + ((pixels64.length * 2) / 1024 / 1024) + " MB");
|
}
|
|
//assert(!imageLocked);
|
if (imageLocked)
|
{
|
System.out.println("image LOCKED!!!!");
|
}
|
|
//if(active > 0)
|
// System.out.println("#activeA = " + active);
|
|
StopAntialiaser();
|
|
antialiaser = new Antialiaser();
|
//ProcessImage();
|
//if(active > 0)
|
// System.out.println("#activeB = " + active);
|
assert (active == 0);
|
imageCompleted = false;
|
antialiaser.start();
|
}
|
}
|
|
boolean imageLocked = false;
|
boolean stopAntialiaser = false;
|
boolean stopped = false;
|
boolean imageCompleted = false;
|
Antialiaser antialiaser = null;
|
static int active = 0;
|
|
void Sleep(int ms)
|
{
|
try
|
{
|
Thread.sleep(ms);
|
} catch (Exception e)
|
{
|
}
|
}
|
|
void StopAntialiaser()
|
{
|
if (antialiaser != null && antialiaser.isRunning)
|
{
|
stopAntialiaser = true;
|
while (!stopped && antialiaser.isRunning)
|
{
|
Sleep(5);
|
}
|
stopped = stopAntialiaser = false;
|
}
|
}
|
|
class Antialiaser extends Thread
|
{
|
boolean isRunning = false;
|
|
public void run()
|
{
|
active += 1;
|
isRunning = true;
|
//System.out.println(active + " START IMAGE " + stopped);
|
ProcessImage();
|
if (!stopped)
|
{
|
//System.out.println("STOP IMAGE");
|
imageLocked = true;
|
niceon = true;
|
repaint();
|
}
|
isRunning = false;
|
active -= 1;
|
}
|
}
|
|
void ProcessImage()
|
{
|
//if (ANTIALIAS > 0)
|
{
|
/*
|
Uncompact(bigAAbuffer.array(), VPwidth*2,VPheight*2, pixels4);
|
//System.out.println("AA buffer = " + (int) pixels4[0]);
|
//Antialias(antialiasbuffer.array(), VPwidth*2, VPheight*2);
|
if (ANTIALIAS > 1)
|
Antialias(VPwidth*2, VPheight*2);
|
Average(pixels4, VPwidth,VPheight, pixelstmp);
|
Compact(pixelstmp, VPwidth,VPheight, AAbuffer.array());
|
/**/
|
|
Uncompact(AAbuffer.array(), VPwidth, VPheight, pixels4);
|
if (stopped)
|
{
|
return;
|
}
|
if (ANTIALIAS > 0)
|
{
|
Antialias(VPwidth, VPheight);
|
}
|
if (stopped)
|
{
|
return;
|
}
|
Compact(pixels4, VPwidth, VPheight, AAbuffer.array());
|
if (stopped)
|
{
|
return;
|
}
|
imageCompleted = true;
|
}
|
}
|
|
short[] pixelstmp;
|
short[] pixels4 = new short[0];
|
short[] pixels16; // = new short[0];
|
short[] pixels64; // = new short[0];
|
short[] pixels256; // = new short[0];
|
int W;
|
|
void Antialias(/*int[] pixels,*/int w, int h)
|
{
|
W = w;
|
subpixcount = 0;
|
//System.out.println("PixelThreshold = " + PixelThreshold);
|
//System.out.println("param = " + (1/modelParams5[3]));
|
|
for (int i = 0; i < w; i++)
|
{
|
if (stopAntialiaser)
|
{
|
stopped = true;
|
return;
|
}
|
for (int j = 0; j < h; j++)
|
{
|
OnePixel(pixels4, i, j, w, h, pixels16);
|
}
|
}
|
|
if (ANTIALIAS > 1) // buffer too big : ANTIALIAS > 1)
|
{
|
int w2 = w * 2;
|
int h2 = h * 2;
|
|
for (int i2 = 0; i2 < w2; i2++)
|
{
|
if (stopAntialiaser)
|
{
|
stopped = true;
|
return;
|
}
|
for (int j2 = 0; j2 < h2; j2++)
|
{
|
OnePixel(pixels16, i2, j2, w2, h2, pixels64);
|
}
|
}
|
|
/*
|
if (ANTIALIAS > 2)
|
{
|
int w4 = w2*2;
|
int h4 = h2*2;
|
for (int i4=0; i4<w4; i4++)
|
for (int j4=0; j4<h4; j4++)
|
{
|
OnePixel(pixels64, i4,j4, w4,h4, pixels256);
|
}
|
Average(pixels256, w4,h4, pixels64);
|
}
|
*/
|
|
Average(pixels64, w2, h2, pixels16);
|
}
|
|
Average(pixels16, w, h, pixels4);
|
}
|
|
void Uncompact(int[] pixels, int w, int h, short[] pixels4)
|
{
|
for (int j = 0; j < h; j++)
|
{
|
int index = j * w; // +i;
|
int index4 = index * 4;
|
|
if (stopAntialiaser)
|
{
|
stopped = true;
|
return;
|
}
|
|
for (int i = 0; i < w; i++, index += 1, index4 += 4)
|
{
|
int p = pixels[index];
|
|
/*
|
short a = (short)((p>>24) & 0xFF);
|
short r = (short)((p>>16) & 0xFF);
|
short g = (short)((p>>8) & 0xFF);
|
short b = (short)(p & 0xFF);
|
*/
|
|
pixels4[index4] = (short) ((p >> 16) & 0xFF);
|
pixels4[index4 + 1] = (short) ((p >> 8) & 0xFF);
|
pixels4[index4 + 2] = (short) (p & 0xFF);
|
pixels4[index4 + 3] = (short) ((p >> 24) & 0xFF);
|
}
|
}
|
}
|
|
void Compact(short[] pixels4, int w, int h, int[] pixels)
|
{
|
for (int j = 0; j < h; j++)
|
{
|
int index = j * w; // +i;
|
int index4 = index * 4;
|
|
if (stopAntialiaser)
|
{
|
stopped = true;
|
return;
|
}
|
|
for (int i = 0; i < w; i++, index += 1, index4 += 4)
|
{
|
short r = pixels4[index4];
|
short g = pixels4[index4 + 1];
|
short b = pixels4[index4 + 2];
|
short a = 255; // pixels4[index4+3];
|
|
/*
|
r = (short)(Math.pow(r/255.0, 0.45)*255);
|
g = (short)(Math.pow(g/255.0, 0.45)*255);
|
b = (short)(Math.pow(b/255.0, 0.45)*255);
|
a = (short)(Math.pow(a/255.0, 0.45)*255);
|
*/
|
|
pixels[index] = (a << 24) | (r << 16) | (g << 8) | b;
|
}
|
}
|
}
|
|
short Gamma(short x)
|
{
|
return x;
|
/*
|
//if(x != 0)
|
// System.out.println("X = " + (int)x);
|
double f = x/255.0;
|
//f += (Math.sin(f * 2*Math.PI) * modelParams1[1]);
|
//if (f > 0 && f < modelParams1[1])
|
// f = modelParams1[1];
|
//if (f < 1 && f > (1 - modelParams1[1]))
|
// f = 1 - modelParams1[1];
|
if (f < 0.5)
|
{
|
f = Math.pow(f*2, modelParams1[1])/2;
|
}
|
else
|
{
|
f = 1 - Math.pow((1 - f)*2, modelParams1[1])/2;
|
}
|
//if(x != 0)
|
// System.out.println("F = " + (int)f);
|
return (short)(f*255);
|
*/
|
}
|
|
short Merge(short a, short b, short c, short d)
|
{
|
short med = Mediane(a, b, c, d);
|
|
int da = a - med;
|
int db = b - med;
|
int dc = c - med;
|
int dd = d - med;
|
|
boolean diff = false; // Min(a,b,c,d) != Max(a,b,c,d);
|
|
float stretch = 2; // modelParams1[1];
|
if (diff)
|
{
|
System.out.println("a = " + (int) a + "; b = " + (int) b + "; c = " + (int) c + "; d = " + (int) d);
|
}
|
a = (short) (da * stretch + med);
|
b = (short) (db * stretch + med);
|
c = (short) (dc * stretch + med);
|
d = (short) (dd * stretch + med);
|
|
if (a < 0)
|
{
|
a = 0;
|
}
|
if (b < 0)
|
{
|
b = 0;
|
}
|
if (c < 0)
|
{
|
c = 0;
|
}
|
if (d < 0)
|
{
|
d = 0;
|
}
|
if (a > 255)
|
{
|
a = 255;
|
}
|
if (b > 255)
|
{
|
b = 255;
|
}
|
if (c > 255)
|
{
|
c = 255;
|
}
|
if (d > 255)
|
{
|
d = 255;
|
}
|
|
if (diff)
|
{
|
System.out.println("A = " + (int) a + "; B = " + (int) b + "; C = " + (int) c + "; D = " + (int) d);
|
}
|
|
return Average(a, b, c, d);
|
}
|
|
short Average(short a, short b, short c, short d)
|
{
|
return (short) ((a + b + c + d) / 4);
|
}
|
|
short AntiGeo(short a, short b, short c, short d)
|
{
|
return (short) (255 - Math.sqrt(Math.sqrt((255 - a) * (255 - b) * (255 - c) * (255 - d))));
|
}
|
|
short Mediane(short a, short b, short c, short d)
|
{
|
int sum = a + b + c + d;
|
|
sum -= Min(a, b, c, d);
|
sum -= Max(a, b, c, d);
|
|
return (short) (sum / 2);
|
}
|
|
short Min(short a, short b, short c, short d)
|
{
|
short min = a;
|
|
if (min > b)
|
{
|
min = b;
|
}
|
if (min > c)
|
{
|
min = c;
|
}
|
if (min > d)
|
{
|
min = d;
|
}
|
|
return min;
|
}
|
|
short Max(short a, short b, short c, short d)
|
{
|
short max = a;
|
|
if (max < b)
|
{
|
max = b;
|
}
|
if (max < c)
|
{
|
max = c;
|
}
|
if (max < d)
|
{
|
max = d;
|
}
|
|
return max;
|
}
|
|
void Average(short[] pixels4, int w, int h, short[] pixels)
|
{
|
int w2 = w * 2;
|
for (int j = 0; j < h; j++)
|
{
|
int index = (j * w) * 4;
|
int index1 = (j * 2 * w2) * 4;
|
int index2 = index1 + 4;
|
int index3 = index2 + w2 * 4;
|
int index4 = index3 - 4;
|
|
if (stopAntialiaser)
|
{
|
stopped = true;
|
return;
|
}
|
for (int i = 0; i < w; i++, index += 4, index1 += 8, index2 += 8, index3 += 8, index4 += 8)
|
{
|
//int i2 = i*2;
|
//int j2 = j*2;
|
|
/*
|
int index = (j*w+i)*4;
|
int index1 = (j*2*w2 + i*2)*4;
|
int index2 = index1 + 4; // (j2*w2 + i2+1)*4;
|
int index3 = index2 + w2*4; // ((j2+1)*w2 + i2+1)*4;
|
int index4 = index3 - 4; // ((j2+1)*w2 + i2)*4;
|
*/
|
|
/**/
|
short r1 = Gamma(pixels4[index1]);
|
short g1 = Gamma(pixels4[index1 + 1]);
|
short b1 = Gamma(pixels4[index1 + 2]);
|
short a1 = Gamma(pixels4[index1 + 3]);
|
|
short r2 = Gamma(pixels4[index2]);
|
short g2 = Gamma(pixels4[index2 + 1]);
|
short b2 = Gamma(pixels4[index2 + 2]);
|
short a2 = Gamma(pixels4[index2 + 3]);
|
|
short r3 = Gamma(pixels4[index3]);
|
short g3 = Gamma(pixels4[index3 + 1]);
|
short b3 = Gamma(pixels4[index3 + 2]);
|
short a3 = Gamma(pixels4[index3 + 3]);
|
|
short r4 = Gamma(pixels4[index4]);
|
short g4 = Gamma(pixels4[index4 + 1]);
|
short b4 = Gamma(pixels4[index4 + 2]);
|
short a4 = Gamma(pixels4[index4 + 3]);
|
/**/
|
|
//pixels[index] = (short) ((pixels4[index1] + pixels4[index2] + pixels4[index3] + pixels4[index4]) / 4);
|
//pixels[index+1] = (short) ((pixels4[index1+1] + pixels4[index2+1] + pixels4[index3+1] + pixels4[index4+1]) / 4);
|
//pixels[index+2] = (short) ((pixels4[index1+2] + pixels4[index2+2] + pixels4[index3+2] + pixels4[index4+2]) / 4);
|
//pixels[index+3] = (short) ((pixels4[index1+3] + pixels4[index2+3] + pixels4[index3+3] + pixels4[index4+3]) / 4);
|
/**/
|
short mr = Merge(r1, r2, r3, r4); // (short) ((r1 + r2 + r3 + r4) / 4);
|
short mg = Merge(g1, g2, g3, g4); // (short) ((g1 + g2 + g3 + g4) / 4);
|
short mb = Merge(b1, b2, b3, b4); // (short) ((b1 + b2 + b3 + b4) / 4);
|
short ma = Merge(a1, a2, a3, a4); // (short) ((a1 + a2 + a3 + a4) / 4);
|
//short gr = (short) (255 - Math.sqrt(Math.sqrt((255-r1) * (255-r2) * (255-r3) * (255-r4))));
|
//short gg = (short) (255 - Math.sqrt(Math.sqrt((255-g1) * (255-g2) * (255-g3) * (255-g4))));
|
//short gb = (short) (255 - Math.sqrt(Math.sqrt((255-b1) * (255-b2) * (255-b3) * (255-b4))));
|
//short ga = (short) (255 - Math.sqrt(Math.sqrt((255-a1) * (255-a2) * (255-a3) * (255-a4))));
|
|
pixels[index] = mr > 0 ? mr : 0; // (short)((gr+mr)/2);
|
pixels[index + 1] = mg > 0 ? mg : 0; // (short)((gg+mg)/2);
|
pixels[index + 2] = mb > 0 ? mb : 0; // (short)((gb+mb)/2);
|
pixels[index + 3] = ma > 0 ? ma : 0; // (short)((ga+ma)/2);
|
/**/
|
}
|
}
|
}
|
|
boolean AreSame(short[] pixels, int i1, int i2)
|
{
|
int dr = pixels[i1] - pixels[i2];
|
int dg = pixels[i1 + 1] - pixels[i2 + 1];
|
int db = pixels[i1 + 2] - pixels[i2 + 2];
|
//int da = pixels[i1+3] - pixels[i2+3];
|
|
return dr * dr + dg * dg + db * db < PixelThreshold;
|
}
|
|
/*
|
void SetIfSame(short[] pixels, int i, int i1, int i2, short[] pixels4, int index4)
|
{
|
if(AreSame(pixels, i1,i2))
|
{
|
Set(pixels, -1, i1, pixels4, index4);
|
}
|
else
|
{
|
Set(pixels, -1, i, pixels4, index4);
|
}
|
}
|
*/
|
int subpixcount;
|
|
void Set(short[] pixels, int index, int i, short[] pixels4, int index4, boolean add)
|
{
|
if (false) // index!=-1 && !AreSame(pixels, i,index))
|
{
|
System.out.print("new subpixel count = " + ++subpixcount);
|
System.out.print("; fromi = " + ((i / 4) % W) + "; fromj = " + ((i / 4) / W));
|
System.out.print("; toi = " + ((index / 4) % W) + "; toj = " + ((index / 4) / W));
|
System.out.println("; toi4 = " + ((index4 / 4) % (W * 2)) + "; toj4 = " + ((index4 / 4) / (W * 2)));
|
}
|
|
if (false) // add)
|
{
|
pixels4[index4] += pixels[i];
|
pixels4[index4 + 1] += pixels[i + 1];
|
pixels4[index4 + 2] += pixels[i + 2];
|
pixels4[index4 + 3] += pixels[i + 3];
|
pixels4[index4] /= 2;
|
pixels4[index4 + 1] /= 2;
|
pixels4[index4 + 2] /= 2;
|
pixels4[index4 + 3] /= 2;
|
} else
|
{
|
pixels4[index4] = pixels[i];
|
pixels4[index4 + 1] = pixels[i + 1];
|
pixels4[index4 + 2] = pixels[i + 2];
|
pixels4[index4 + 3] = pixels[i + 3];
|
}
|
}
|
|
void OnePixel(short[] pixels, int i, int j, int w, int h, short[] pixels4)
|
{
|
int index = (j * w + i) * 4;
|
|
int w2 = w * 2;
|
int i2 = i * 2;
|
int j2 = j * 2;
|
|
int index1 = (j2 * w2 + i2) * 4;
|
int index2 = index1 + 4; // (j2*w2 + i2+1)*4;
|
int index3 = index2 + w2 * 4; // ((j2+1)*w2 + i2+1)*4;
|
int index4 = index3 - 4; // ((j2+1)*w2 + i2)*4;
|
|
Set(pixels, -1, index, pixels4, index1, false);
|
Set(pixels, -1, index, pixels4, index2, false);
|
Set(pixels, -1, index, pixels4, index3, false);
|
Set(pixels, -1, index, pixels4, index4, false);
|
|
if (i > 1 && i < w - 2 && j > 1 && j < h - 2)
|
{
|
int indexL = index - 4; // (j*w+i-1)*4;
|
int indexR = index + 4; // (j*w+i+1)*4;
|
int indexD = index + w * 4; // ((j+1)*w+i)*4;
|
int indexU = index - w * 4; // ((j-1)*w+i)*4;
|
|
//SetIfSame(pixels, index,indexL,indexU, pixels4, index1);
|
//SetIfSame(pixels, index,indexU,indexR, pixels4, index2);
|
//SetIfSame(pixels, index,indexR,indexD, pixels4, index3);
|
//SetIfSame(pixels, index,indexD,indexL, pixels4, index4);
|
if (AreSame(pixels, indexL, indexU))
|
{
|
Set(pixels, index, indexL, pixels4, index1, false);
|
int indexUR = indexU + 4;
|
if (AreSame(pixels, indexU, indexUR)) // && AreSame(pixels, indexU,indexUR+4))
|
{
|
Set(pixels, index, indexU, pixels4, index2, true);
|
}
|
int indexDL = indexD - 4;
|
if (AreSame(pixels, indexL, indexDL)) // && AreSame(pixels, indexL,indexDL+w*4))
|
{
|
Set(pixels, index, indexL, pixels4, index4, true);
|
}
|
}
|
if (AreSame(pixels, indexU, indexR))
|
{
|
Set(pixels, index, indexU, pixels4, index2, false);
|
int indexLU = indexU - 4;
|
if (AreSame(pixels, indexU, indexLU)) // && AreSame(pixels, indexU,indexLU-4))
|
{
|
Set(pixels, index, indexU, pixels4, index1, true);
|
}
|
int indexDR = indexD + 4;
|
if (AreSame(pixels, indexR, indexDR)) // && AreSame(pixels, indexR,indexDR+w*4))
|
{
|
Set(pixels, index, indexR, pixels4, index3, true);
|
}
|
}
|
if (AreSame(pixels, indexR, indexD))
|
{
|
Set(pixels, index, indexR, pixels4, index3, false);
|
int indexUR = indexU + 4;
|
if (AreSame(pixels, indexR, indexUR)) // && AreSame(pixels, indexR,indexUR-w*4))
|
{
|
Set(pixels, index, indexR, pixels4, index2, true);
|
}
|
int indexDL = indexD - 4;
|
if (AreSame(pixels, indexD, indexDL)) // && AreSame(pixels, indexD,indexDL-4))
|
{
|
Set(pixels, index, indexD, pixels4, index4, true);
|
}
|
}
|
if (AreSame(pixels, indexD, indexL))
|
{
|
Set(pixels, index, indexD, pixels4, index4, false);
|
int indexUL = indexU - 4;
|
if (AreSame(pixels, indexL, indexUL)) // && AreSame(pixels, indexL,indexUL-w*4))
|
{
|
Set(pixels, index, indexL, pixels4, index1, true);
|
}
|
int indexDR = indexD + 4;
|
if (AreSame(pixels, indexD, indexDR)) // && AreSame(pixels, indexD,indexDR+4))
|
{
|
Set(pixels, index, indexD, pixels4, index3, true);
|
}
|
}
|
}
|
}
|
|
boolean niceon = false;
|
javax.swing.Timer AAtimer = new javax.swing.Timer(750, this);
|
boolean currentlydrawing = false;
|
static boolean init = false;
|
|
double[][] matrix = LA.newMatrix();
|
|
// This is to refresh the UI of the material panel.
|
ObjEditor patchMaterial;
|
|
public void display(GLAutoDrawable drawable)
|
{
|
if (patchMaterial.patchMaterial)
|
{
|
patchMaterial.patchMaterial = false;
|
patchMaterial.objectTabbedPane.setSelectedIndex(1);
|
}
|
|
if (Grafreed.savesound && Grafreed.hassound)
|
{
|
Grafreed.wav.save();
|
Grafreed.savesound = false;
|
Grafreed.hassound = false;
|
}
|
// if (DEBUG_SELECTION)
|
// {
|
// if (DrawMode() != SELECTION)
|
// DrawMode() = SELECTION;
|
// }
|
|
if (!isRenderer)
|
{
|
return;
|
}
|
|
// if (TRACK)
|
// {
|
// pingthread.StepToTarget();
|
// }
|
|
// renderpass++;
|
|
if (!programInitialized)
|
{
|
InitializePrograms(drawable);
|
}
|
|
boolean keepocclusion = ambientOcclusion;
|
if (DEBUG_OCCLUSION)
|
{
|
ambientOcclusion = true;
|
}
|
|
/**/
|
if (IsFrozen() && flash)
|
{
|
flash = false;
|
return;
|
}
|
/**/
|
|
if (selection)
|
{
|
selectbuffer.display();
|
return;
|
}
|
|
boolean resetclicked = !niceon;
|
//if(!imageLocked)
|
{
|
if (false) // this == drawable)
|
{
|
System.out.println("niceon = " + niceon + "; clicked = " + clicked);
|
} // + " THIS = " + drawable);
|
//new Exception().printStackTrace();
|
|
if (!niceon)
|
{
|
clicked = false;
|
}
|
|
//ANTIALIAS = 0;
|
|
if (DrawMode() == DEFAULT) // && CURRENTANTIALIAS > 0)
|
{
|
if (niceon || Globals.isLIVE())
|
{
|
//if(active == 0)
|
// antialiaser = null;
|
ANTIALIAS = CURRENTANTIALIAS;
|
if (!macromode)
|
niceon = false; // Comment this line to get AA while drag
|
} else
|
{
|
imageLocked = false;
|
ANTIALIAS = 0;
|
//System.out.println("RESTART");
|
AAtimer.restart();
|
Globals.TIMERRUNNING = true;
|
}
|
}
|
}
|
|
/*
|
assert eyeCamera.DECAL == 12;
|
assert eyeCamera.SCALE == 1;
|
assert eyeCamera.shaper_fovy == 45.0f;
|
assert eyeCamera.shaper_zNear == 0.01f;
|
assert eyeCamera.shaper_zFar == 1E5f; // 500.0f;
|
*/
|
|
if (DrawMode() == DEFAULT)
|
{
|
if (manipCamera == lightCamera)
|
{
|
// switch (e.getKeyCode())
|
// {
|
// case DOWN_ARROW:
|
// lightCamera.DECAL /= 2;
|
// repaint();
|
// break;
|
// case UP_ARROW:
|
// lightCamera.DECAL *= 2;
|
// repaint();
|
// break;
|
// case LEFT_ARROW:
|
// lightCamera.SCALE /= 2;
|
// repaint();
|
// break;
|
// case RIGHT_ARROW:
|
// lightCamera.SCALE *= 2;
|
// repaint();
|
// break;
|
// default:
|
// break;
|
if (keys[DOWN_ARROW])
|
{
|
lightCamera.DECAL /= 2;
|
}
|
|
if (keys[UP_ARROW])
|
{
|
lightCamera.DECAL *= 2;
|
}
|
|
if (keys[LEFT_ARROW])
|
{
|
lightCamera.SCALE /= 2;
|
}
|
|
if (keys[RIGHT_ARROW])
|
{
|
lightCamera.SCALE *= 2;
|
}
|
}
|
else
|
{
|
//pingthread.mute = true;
|
|
boolean keyon = false;
|
|
if (keys[DOWN_ARROW])
|
{
|
speed = ++speedkey[DOWN_ARROW];
|
if (speed > 20)
|
speed = 20;
|
GoDown(modifiers);
|
keyon = true;
|
}
|
else
|
speedkey[DOWN_ARROW] = 0;
|
|
if (keys[UP_ARROW])
|
{
|
speed = ++speedkey[UP_ARROW];
|
if (speed > 20)
|
speed = 20;
|
GoUp(modifiers);
|
keyon = true;
|
}
|
else
|
speedkey[UP_ARROW] = 0;
|
|
if (keys[LEFT_ARROW])
|
{
|
speed = ++speedkey[LEFT_ARROW];
|
if (speed > 20)
|
speed = 20;
|
GoLeft(modifiers);
|
keyon = true;
|
}
|
else
|
speedkey[LEFT_ARROW] = 0;
|
|
if (keys[RIGHT_ARROW])
|
{
|
speed = ++speedkey[RIGHT_ARROW];
|
if (speed > 20)
|
speed = 20;
|
GoRight(modifiers);
|
keyon = true;
|
}
|
else
|
speedkey[RIGHT_ARROW] = 0;
|
|
if (keyon)
|
{
|
repaint();
|
}
|
|
//pingthread.mute = false;
|
}
|
|
currentlydrawing = true;
|
}
|
|
javax.media.opengl.GL gl = drawable.getGL();
|
|
// PATCH!!!
|
// gl.glDrawBuffer(gl.GL_FRONT_AND_BACK);
|
|
//new Exception().printStackTrace();
|
gl.glGetError();
|
|
gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
int width = viewport[2];
|
int height = viewport[3];
|
|
// if (width != 2048) System.out.println("Width = " + width + "; height = " + height); //.get(0).parent);
|
//gl.glEnable(GL.GL_TEXTURE_2D);
|
|
//if (isRenderer)
|
//assert(!init);
|
if (!init)
|
{
|
init = true;
|
// InitPBuffers();
|
init = false;
|
}
|
|
// if(Applet3D.clipboard != null)
|
// System.out.println("Clipboard = " + Applet3D.clipboard); //.get(0).parent);
|
//DrawMode() = SELECTION;
|
indexcount = 0;
|
|
if (DrawMode() == OCCLUSION)
|
{
|
Globals.drawMode = DEFAULT; // WARNING
|
ambientOcclusion = true;
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
Object3D theobject = object;
|
Object3D theparent = object.parent;
|
object.parent = null;
|
object = (Object3D)Grafreed.clone(object);
|
object.Stripify();
|
if (theobject.selection == null || theobject.selection.Size() == 0)
|
theobject.PreprocessOcclusion(this);
|
else
|
theobject.selection.PreprocessOcclusion(this);
|
object = theobject;
|
object.parent = theparent;
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
System.out.println("DONE.");
|
ambientOcclusion = false;
|
}
|
|
if (//Globals.lighttouched &&
|
DrawMode() == DEFAULT) // && !lightMode) // && !FROZEN)
|
{
|
//if (RENDERSHADOW) // ?
|
if (!IsFrozen())
|
{
|
// dec 2012
|
if (!ambientOcclusion && !(!flash && DrawMode() == DEFAULT && ANTIALIAS > 0))
|
{
|
Globals.framecount++;
|
shadowbuffer.display();
|
}
|
}
|
Globals.lighttouched = false; // ??
|
//drawing = true;
|
//lighttouched = true;
|
}
|
|
if (wait)
|
{
|
Sleep(200); // blocks everything
|
|
wait = false;
|
}
|
|
vertexMode = fragmentMode = 0;
|
|
if (ambientOcclusion || spherical)
|
//if (renderCamera != lightCamera)
|
{
|
vertexMode |= VP_PROJECTION;
|
//eyeCamera.shaper_fovy = 1;
|
}
|
|
if ((RENDERPROGRAM != 0 || ambientOcclusion || spherical) && DrawMode() == DEFAULT) // SELECTION)
|
{
|
//System.out.println("DrawMode() = " + DrawMode());
|
vertexMode |= VP_PASS;
|
//vertexMode |= VP_PROJECTION;
|
if (!ambientOcclusion)
|
{
|
fragmentMode |= FP_SHADER;
|
if (anisotropy)
|
fragmentMode |= FP_ANISO;
|
if (softshadow)
|
fragmentMode |= FP_SOFTSHADOW;
|
}
|
//fragmentMode |= FP_LIGHT; //
|
} else
|
{
|
//vertexMode |= VP_PASS;
|
//fragmentMode &= ~FP_SHADER;
|
}
|
|
//System.out.println("DISPLAY : " + drawable + " = " + RENDERSHADOW);
|
|
//drawing = true;
|
|
//spotlightInverseTransform.makeIdent(); //
|
|
currentGL = drawable.getGL();
|
|
//System.out.println("DISPLAY GL IS: " + gl); // .getClass().getName());
|
//System.out.println(" CONTEXT IS: " + drawable.getContext());
|
|
java.util.Enumeration lists = availist.keys();
|
|
if (!ambientOcclusion)
|
{
|
while (lists.hasMoreElements())
|
{
|
Object key = lists.nextElement();
|
Object obj = availist.get(key);
|
int count = ((Integer) obj).intValue();
|
|
assert(count != 0);
|
|
//System.out.println("LIST : " + key + ", " + obj);
|
|
// aout 2013 if (count == 0)
|
{
|
int thelist = ((Integer) key).intValue();
|
|
// System.err.println("Delete list = " + thelist);
|
|
gl.glDeleteLists(thelist, 1);
|
|
availist.remove(key);
|
}
|
}
|
}
|
|
//Camera cam = camera; // eyeCamera;
|
Camera cam = renderCamera; // lightMode?lightCamera:eyeCamera;
|
//Camera lightcam = new Camera(light0);
|
|
if (DrawMode() == SHADOW)
|
{
|
/*
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
glu.gluLookAt(light0.x,light0.y,light0.z, 0,0,0, 0,1,0);
|
gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, view, 0);
|
SetColumnMajorData(spotlightTransform, view);
|
spotlightInverseTransform.set(spotlightTransform);
|
spotlightInverseTransform.invertRigid();
|
GetColumnMajorData(spotlightInverseTransform, view_1);
|
gl.glPopMatrix();
|
*/
|
|
cam = lightCamera;
|
//System.out.println("------------------------------- light = " + cam);
|
} else
|
{
|
//cam = camera;
|
}
|
{
|
Camera parentcam = cam;
|
|
if (cam == cameras[0])
|
{
|
parentcam = cameras[1];
|
}
|
|
if (cam == cameras[1])
|
{
|
parentcam = cameras[0];
|
}
|
|
LA.matCopy(cam.toScreen, matrix);
|
|
// if (parentcam != renderCamera) // not a light
|
if (cam != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.matConcat(matrix, parentcam.GlobalTransformInv(), matrix);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
view[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
LA.matCopy(cam.fromScreen, matrix);
|
|
// if (parentcam != renderCamera) // not a light
|
if (cam != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.matConcat(parentcam.GlobalTransform(), matrix, matrix);
|
|
//LA.matConcat(cam.fromScreen, parentcam.fromParent, matrix);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
view_1[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
for (int j = 0; j < 3; j++)
|
{
|
for (int i = 0; i < 3; i++)
|
{
|
viewrot_1[j * 4 + i] = matrix[j][i];
|
}
|
}
|
|
//view[3*4 + 3] = 1;
|
//view_1[3*4 + 3] = 1;
|
viewrot_1[3 * 4 + 3] = 1;
|
|
//LA.matPrint(cam.toScreen);
|
//System.out.println("-------------------------------");
|
}
|
|
if ((drawable instanceof GLJPanel) &&
|
!((GLJPanel) drawable).isOpaque() &&
|
((GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent())
|
{
|
assert (false);
|
gl.glClear(gl.GL_DEPTH_BUFFER_BIT);
|
} else
|
{
|
if (DrawMode() != DEFAULT)
|
{
|
gl.glClearColor(1, 1, 1, 0);
|
} // 1);
|
else
|
{
|
if (true) // cubemap == null)
|
{
|
gl.glClearColor(1, 1, 1, 1);
|
} // 0.2f,0.3f,0.4f,1);
|
else
|
{
|
gl.glClearColor(0.f, 0.f, 0.f, 0);
|
} // 1);
|
}
|
|
if (!IsFrozen())
|
{
|
//gl.glDepthFunc(GL.GL_LESS);
|
gl.glDepthFunc(GL.GL_LEQUAL);
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
|
gl.glDepthMask(true);
|
} else
|
{
|
//gl.glDepthFunc(GL.GL_LESS); // QUAL);
|
gl.glDepthFunc(GL.GL_LEQUAL);
|
gl.glDepthMask(false);
|
}
|
}
|
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
|
double ratio = ((double) getHeight()) / getWidth();
|
boolean yx = false;
|
|
double skyscale = 3.8; // 3.8
|
if (ratio > 1)
|
{
|
gl.glOrtho(-skyscale, skyscale, -skyscale / ratio, skyscale / ratio, 0.001, 1000);
|
} else
|
{
|
yx = true;
|
ratio = 1 / ratio;
|
gl.glOrtho(-skyscale / ratio, skyscale / ratio, -skyscale, skyscale, 0.001, 1000);
|
}
|
|
// if (newenvy > -1)
|
// {
|
// LoadEnvy(newenvy);
|
// }
|
//
|
// newenvy = -1;
|
|
if (transformMode) // object.skyboxname != null && object.skyboxname.equals("cubemaps/default-skyboxes/rgb"))
|
{
|
if (cubemaprgb == null)
|
{
|
cubemaprgb = LoadSkybox("cubemaps/default-skyboxes/rgb2" + "/", "jpg", false);
|
}
|
|
cubemap = cubemaprgb;
|
}
|
else
|
{
|
if (object.skyboxname != null)
|
{
|
if (!object.skyboxname.equals(this.loadedskyboxname))
|
{
|
if (cubemap != null && cubemap != cubemaprgb)
|
cubemap.dispose();
|
cubemapcustom = LoadSkybox(object.skyboxname + "/", object.skyboxext, false);
|
loadedskyboxname = object.skyboxname;
|
}
|
}
|
else
|
{
|
cubemapcustom = null;
|
loadedskyboxname = null;
|
}
|
|
cubemap = cubemapcustom;
|
}
|
|
ratio = ((double) getWidth()) / getHeight();
|
//System.out.println("ratio = " + ratio);
|
|
boolean fast = RENDERPROGRAM == 0;
|
fast |= (mouseDown && RENDERPROGRAM == 1);
|
|
fast &= !ambientOcclusion;
|
|
if (DrawMode() == DEFAULT)
|
{
|
//gl.glEnable(gl.GL_ALPHA_TEST);
|
//gl.glActiveTexture(GL.GL_TEXTURE0);
|
|
if (!IsFrozen() && !ambientOcclusion)
|
{
|
DrawSkyBox(gl, (float)ratio);
|
}
|
|
//if (selection_view == -1)
|
//{
|
/* TEXTURE BINDING
|
texture.bind(); //
|
texture.enable();
|
*/
|
//}
|
//else
|
//{
|
//gl.glBindTexture(gl.GL_TEXTURE_2D, selection_view);
|
//gl.glEnable(gl.GL_TEXTURE_2D);
|
//}
|
|
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
|
//gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
|
//gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
|
//gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
|
//gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
|
gl.glMatrixMode(gl.GL_TEXTURE);
|
gl.glLoadIdentity();
|
//gl.glScaled(2,1,1);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
|
/**/
|
// depth compare
|
/**/
|
gl.glActiveTexture(GL.GL_TEXTURE1);
|
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
//SetColumnMajorData(cameraTransform, view);
|
//ApplyTransform(gl, cameraTransform);
|
gl.glMultMatrixd(view, 0);
|
eye_linear_texgen(gl);
|
texgen(gl, true);
|
gl.glPopMatrix();
|
/**/
|
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glLoadIdentity();
|
/**/
|
//if (!RENDERPROGRAM)
|
{
|
gl.glTranslatef(.5f, .5f, 0.5f); // ((Tweak) tweaks.get(R_COORDINATE_SCALE)).val);
|
gl.glScalef(.5f, .5f, 0.5f); // ((Tweak) tweaks.get(R_COORDINATE_BIAS)).val);
|
}
|
//double scale = 10/lightCamera.Distance(); // 0.1;
|
//gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 1, 100);
|
//glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar);
|
double scale = lightCamera.SCALE / lightCamera.Distance();
|
// PATCH FILLE AUX JEANS
|
//scale *= lightCamera.shaper_fovy / 25;
|
gl.glScaled(2 * scale, 2 * scale, -scale);
|
gl.glTranslated(0, 0, lightCamera.DECAL);
|
|
//double scale = camera.Distance() * 5; // /view.getScale();
|
//gl.glOrtho(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 0.001, 100000);
|
//scale = 1000/camera.Distance();
|
//gl.glScaled(scale,scale,scale);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
lightmat[j * 4 + i] = lightCamera.toScreen[j][i];
|
}
|
}
|
|
//lightmat[3*4 + 3] = 1;
|
|
//SetColumnMajorData(spotlightTransform, lightmat);
|
//ApplyTransform(gl, spotlightTransform);
|
gl.glMultMatrixd(lightmat, 0);
|
|
if (RENDERPROGRAM != 0)
|
{
|
gl.glPushMatrix();
|
|
gl.glMultMatrixd(view_1, 0);
|
|
gl.glGetDoublev(gl.GL_TEXTURE_MATRIX, tempmat, 0);
|
|
gl.glPopMatrix();
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
camera2light[j * 4 + i] = tempmat[i * 4 + j];
|
}
|
}
|
//lightmat[j*4+i] = camera2light[j*4+i];
|
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 0, camera2light, 0);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 1, camera2light, 4);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 2, camera2light, 8);
|
gl.glProgramEnvParameter4dvARB(gl.GL_VERTEX_PROGRAM_ARB, 3, camera2light, 12);
|
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
|
gl.glMultMatrixd(view, 0);
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
lightmat[j * 4 + i] = lightCamera.fromScreen[j][i];
|
}
|
}
|
|
gl.glMultMatrixd(lightmat, 0);
|
|
gl.glTranslated(0, 0, -lightCamera.DECAL);
|
|
scale = lightCamera.Distance();
|
gl.glScaled(scale / 2, scale / 2, -scale);
|
|
gl.glScalef(2, 2, 2);
|
gl.glTranslatef(-0.5f, -0.5f, -0.5f);
|
|
gl.glGetDoublev(gl.GL_TEXTURE_MATRIX, tempmat, 0);
|
|
gl.glPopMatrix();
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
light2camera[j * 4 + i] = tempmat[i * 4 + j];
|
}
|
}
|
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 10, light2camera, 0);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 11, light2camera, 4);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 12, light2camera, 8);
|
gl.glProgramEnvParameter4dvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 13, light2camera, 12);
|
}
|
/**/
|
|
gl.glBindTexture(GL.GL_TEXTURE_2D, light_view_depth);
|
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
|
/**/
|
|
// Bump noise
|
gl.glActiveTexture(GL.GL_TEXTURE6);
|
//gl.glBindTexture(GL.GL_TEXTURE_2D, bump_noise);
|
|
try
|
{
|
BindTexture(NOISE_TEXTURE, false, 2);
|
}
|
catch (Exception e)
|
{
|
System.err.println("FAILED: " + NOISE_TEXTURE);
|
}
|
|
|
gl.glActiveTexture(GL.GL_TEXTURE0);
|
gl.glEnable(GL.GL_TEXTURE_2D);
|
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
// We use texture matrix for view transform
|
// (UP vector for UV base)
|
//gl.glPushMatrix();
|
gl.glLoadIdentity();
|
//if(!mouseDown && RENDERPROGRAM)
|
if (true) // !fast)
|
{
|
gl.glActiveTexture(GL.GL_TEXTURE7);
|
gl.glEnable(GL.GL_TEXTURE_2D);
|
gl.glLoadIdentity();
|
gl.glMultMatrixd(view, 0);
|
gl.glActiveTexture(GL.GL_TEXTURE0);
|
gl.glEnable(GL.GL_TEXTURE_2D);
|
}
|
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
|
//gl.glEnable(gl.GL_POLYGON_SMOOTH);
|
//gl.glHint(gl.GL_POLYGON_SMOOTH_HINT, gl.GL_NICEST);
|
//gl.glEnable(gl.GL_MULTISAMPLE);
|
} else
|
{
|
//gl.glDisable(GL.GL_TEXTURE_2D);
|
gl.glDisable(gl.GL_ALPHA_TEST);
|
}
|
|
// Transparency
|
//System.out.println("BLENDING ON");
|
gl.glEnable(GL.GL_BLEND);
|
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
|
// gl.glBlendFunc(GL.GL_SRC_ALPHA_SATURATE, GL.GL_ONE);
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
|
if (DrawMode() == SHADOW || cam == lightCamera) // || (vertexMode&VP_PROJECTION) != 0)
|
{
|
//glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar);
|
double scale = lightCamera.SCALE / lightCamera.Distance();
|
// PATCH FILLE AUX JEANS
|
//scale *= lightCamera.shaper_fovy / 25;
|
gl.glScaled(2 * scale, 2 * scale, -scale);
|
gl.glTranslated(0, 0, lightCamera.DECAL);
|
//System.out.println("DECAL = " + LIGHTDECAL + "; SCALE = " + LIGHTSCALE);
|
//double scale = 10/camera.Distance(); // 0.1;
|
//gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 1, 100);
|
//System.out.println("NEAR0 = " + near_plane + "; FAR0 = " + far_plane);
|
} else
|
{
|
if (!cam.perspective || (ambientOcclusion || spherical) && SPHERICAL)
|
{
|
//double scale = 0.01*camera.getClipDistance()/camera.getDistToScreen();
|
//gl.glFrustum(-0.5*bounds.width*scale, 0.5*bounds.width*scale, -0.5*bounds.height*scale, 0.5*bounds.height*scale, minDepth, maxDepth);
|
double scale = 0.01 / cam.Distance(); // 0.1;
|
//System.out.println("NEAR = " + near_plane + "; FAR = " + far_plane);
|
//if (!ambientOcclusion)
|
//System.out.println("fovy = " + eyeCamera.shaper_fovy);
|
if (ambientOcclusion || spherical)
|
{
|
scale = 4;
|
}
|
gl.glFrustum(-0.5 * scale, 0.5 * scale, -0.5 * scale, 0.5 * scale, near_plane/*/eyeCamera.shaper_fovy*/, far_plane); // minDepth, maxDepth);
|
} else
|
{
|
//System.out.println("FOV = " + cam.shaper_fovy + "NEAR = " + cam.shaper_zNear + "; FAR = " + cam.shaper_zFar);
|
/*
|
double scale = camera.Distance() * 5; // /view.getScale();
|
//gl.glOrtho(-0.5*bounds.width*scale, 0.5*bounds.width*scale, -0.5*bounds.height*scale, 0.5*bounds.height*scale, minDepth, maxDepth);
|
if (yx)
|
gl.glFrustum(-0.5*scale/ratio, 0.5*scale/ratio, -0.5*scale, 0.5*scale, 0.001, 100000);
|
else
|
gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale/ratio, 0.5*scale/ratio, 0.001, 100000); // minDepth, maxDepth);
|
*/
|
//System.out.println("fovy = " + cam.shaper_fovy);
|
//System.out.println("ratio = " + ratio);
|
if (ambientOcclusion)
|
{
|
glu.gluPerspective(135, 1, near_plane / 1000, far_plane);
|
//gl.glOrtho(-BOOST, BOOST, -BOOST, BOOST, 0.001, 1000);
|
} else
|
{
|
boolean vr = capsLocked && !lightMode;
|
|
glu.gluPerspective(cam.shaper_fovy / ratio * (vr ? 1.2 : 1),
|
ratio, cam.shaper_zNear * cam.Distance(), cam.shaper_zFar * cam.Distance());
|
}
|
}
|
|
//double scale = 1000/camera.Distance();
|
//gl.glScaled(scale,scale,scale);
|
}
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
//gl.glPushMatrix();
|
gl.glLoadIdentity();
|
|
if (!ambientOcclusion) // DrawMode() != OCCLUSION)
|
{
|
//LA.xformPos(light0, lightCamera.fromScreen, light);
|
LA.xformDir(dirlight, lightCamera.fromScreen, lightposition);
|
|
Camera parentcam = cam;
|
|
if (cam != lightCamera)
|
// if (true) // TODO
|
{
|
if (cam == cameras[0])
|
{
|
parentcam = cameras[1];
|
}
|
|
if (cam == cameras[1])
|
{
|
parentcam = cameras[0];
|
}
|
|
|
if (parentcam == renderCamera)
|
//assert (parentcam != renderCamera);
|
//new Exception().printStackTrace();
|
System.err.println("parentcam != renderCamera");
|
|
// if (cam != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.xformDir(lightposition, parentcam.GlobalTransformInv(), lightposition); // may 2013
|
}
|
|
LA.xformDir(lightposition, cam.toScreen, lightposition);
|
|
lightposition.normalize();
|
|
//System.out.println("Light = " + lightcolor);
|
|
float pos[] = {(float) lightposition.x, (float) lightposition.y, (float) lightposition.z, 0};
|
float col[] = {(float) lightcolor.x, (float) lightcolor.y, (float) lightcolor.z, 0};
|
|
// ...
|
|
if (cameraLight)
|
{
|
light0.set(0,0,0);
|
|
if (true) // TODO
|
{
|
if (cam != lightCamera)
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.xformDir(light0, parentcam.GlobalTransform(), light0); // may 2013
|
}
|
|
LA.xformPos(light0, cam.toScreen, light0);
|
|
LA.xformPos(light0, lightCamera.fromScreen, light0);
|
//LA.xformPos(light0, cam.fromScreen, light0);
|
pos[0] = (float)light0.x;
|
pos[1] = (float)light0.y;
|
pos[2] = (float)light0.z;
|
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, pos, 0);
|
}
|
else
|
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, pos, 0);
|
gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, col, 0);
|
}
|
//gl.glTranslatef(0,0,100);
|
|
gl.glMultMatrixd(view, 0);
|
|
if (false) // object.fromParent != null)
|
{
|
double[][] matinv = object.GlobalTransform();
|
|
for (int j = 0; j < 4; j++)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
model[j * 4 + i] = matinv //object.fromParent
|
[j][i];
|
}
|
}
|
|
gl.glMultMatrixd(model, 0);
|
}
|
|
/**/
|
if (true) // DrawMode() == SELECTION) // != DEFAULT)
|
gl.glDisable(gl.GL_LIGHTING);
|
else
|
gl.glEnable(gl.GL_LIGHTING);
|
/**/
|
|
//gl.glCallList(fragmentProgram);
|
|
options2[0] /= renderCamera.Distance();
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 63, options2, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 62, options3, 0);
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, 61, options4, 0);
|
|
options2[0] *= renderCamera.Distance();
|
|
lightslot = 64;
|
|
if (!frozen && !ambientOcclusion && isRenderer && DrawMode() == DEFAULT)
|
{
|
DrawLights(object);
|
}
|
|
//fragmentMode &= FP_LIGHT; //
|
|
//System.out.println("fragmentMode = " + fragmentMode);
|
fragmentMode |= (lightslot - 64) << 2; // 1; // first bit is available for aniso
|
//System.out.println("fragmentMode = " + fragmentMode);
|
|
if (DrawMode() == DEFAULT || DrawMode() == SELECTION || IsDebugSelection())
|
{
|
/*
|
if (CULLFACE || (ambientOcclusion && OCCLUSION_CULLING))
|
{
|
gl.glEnable(gl.GL_CULL_FACE);
|
} else
|
{
|
gl.glDisable(gl.GL_CULL_FACE);
|
}
|
*/
|
if (ambientOcclusion)
|
{
|
if (OCCLUSION_CULLING)
|
{
|
gl.glEnable(gl.GL_CULL_FACE);
|
} else
|
{
|
gl.glDisable(gl.GL_CULL_FACE);
|
}
|
}
|
else
|
{
|
if (CULLFACE)
|
{
|
gl.glEnable(gl.GL_CULL_FACE);
|
} else
|
{
|
gl.glDisable(gl.GL_CULL_FACE);
|
}
|
}
|
}
|
|
if (DrawMode() == DEFAULT)
|
{
|
if (WIREFRAME && !ambientOcclusion)
|
{
|
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE);
|
} else
|
{
|
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL);
|
}
|
}
|
|
if (fragmentMode == 0)
|
fragmentMode = - - fragmentMode;
|
|
// june 2013
|
gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
|
if (!fast/*RENDERPROGRAM != 0*/ && (DrawMode() == DEFAULT || DrawMode() == SHADOW)) // && !WIREFRAME) //
|
{
|
if (vertexMode != 0) // && !fast)
|
{
|
//if (!ambientOcclusion)
|
// System.out.println("vertexMode = " + vertexMode);
|
gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vertexProgram[vertexMode]);
|
gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB);
|
}
|
|
if (!ambientOcclusion && /*fragmentMode != 0 &&*/ fragmentProgram[fragmentMode] != 0) // && !fast)
|
{
|
//if (!ambientOcclusion)
|
//System.out.println("fragmentMode = " + fragmentMode);
|
//EnableProgram(fragmentMode);
|
gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragmentProgram[fragmentMode]);
|
gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
}
|
}
|
|
if (false) //RENDERPROGRAM > 0 && DrawMode() == DEFAULT) // fast && !IsFreezed() && DrawMode() != SELECTION && !ambientOcclusion)
|
{
|
//gl.glDepthFunc(GL.GL_LEQUAL);
|
//gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
|
//gl.glDepthMask(true);
|
|
boolean texon = textureon;
|
|
gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
textureon = false;
|
|
//gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
//System.out.println("ALLO");
|
gl.glColorMask(false, false, false, false);
|
DrawObject(gl);
|
|
gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
textureon = texon;
|
|
gl.glColorMask(true, true, true, true);
|
|
gl.glDepthFunc(GL.GL_EQUAL);
|
gl.glDepthMask(false);
|
}
|
|
if (false) // DrawMode() == SHADOW)
|
{
|
//SetColumnMajorData(cameraInverseTransform, view_1);
|
//System.out.println("light = " + cameraInverseTransform);
|
}
|
|
//gl.glEnable(gl.GL_POLYGON_SMOOTH);
|
//gl.glEnable(gl.GL_BLEND);
|
//gl.glBlendFunc (gl.GL_SRC_ALPHA_SATURATE, gl.GL_ONE);
|
|
// DRAW
|
//System.out.println("object = " + object);
|
if (!frozen && !imageLocked)
|
{
|
if (!flash && !lightMode && DrawMode() == DEFAULT && ANTIALIAS > 0)
|
{
|
displayAntiAliased(gl);
|
} else
|
{
|
programcount = 0;
|
int keepmode = DrawMode();
|
// if (DEBUG_SELECTION)
|
// {
|
// DrawMode() = SELECTION;
|
// }
|
// for point selection
|
// gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, tempmat, 0);
|
// gl.glGetDoublev(gl.GL_PROJECTION_MATRIX, tempmat2, 0);
|
// gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
|
DrawObject(gl);
|
|
// jan 2013 System.err.println("RESET ABORT (display)");
|
// if (DrawMode() == DEFAULT)
|
// ABORTED = false;
|
fullreset = false;
|
Globals.drawMode = keepmode; // WARNING
|
//System.out.println("PROGRAM SWITCH " + programcount);
|
}
|
}
|
|
gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
|
if (DrawMode() == DEFAULT)
|
{
|
ReleaseTexture(NOISE_TEXTURE, false);
|
}
|
//if (DrawMode() == DEFAULT)
|
{
|
|
gl.glActiveTexture(GL.GL_TEXTURE1);
|
gl.glDisable(GL.GL_TEXTURE_2D);
|
gl.glActiveTexture(GL.GL_TEXTURE0);
|
}
|
//if (selection_view == -1)
|
// TEXTURE texture.disable();
|
//else
|
//gl.glDisable(gl.GL_TEXTURE_2D);
|
//gl.glPopMatrix();
|
if (imageCompleted && ANTIALIAS > 0 && DrawMode() == DEFAULT && cam != lightCamera && !ambientOcclusion)
|
{
|
//new Exception().printStackTrace();
|
//System.out.println("Draw image " + width + ", " + height);
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
gl.glOrtho(0, width, 0, height, -1.0, 1.0);
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
|
gl.glRasterPos2i(0, 0);
|
//if (!ambientOcclusion) // See boundary rep for debug
|
//{
|
// gl.glDrawBuffer(gl.GL_FRONT_AND_BACK);
|
// gl.glDrawPixels(OCCLUSION_SIZE, OCCLUSION_SIZE, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, occlusionsizebuffer);
|
//}
|
if (AAbuffersize != width * height)
|
{
|
AAbuffersize = width * height;
|
AAbuffer = IntBuffer.allocate(AAbuffersize);
|
} else
|
{
|
/*
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
|
if(false)
|
{
|
TextTest();
|
InvertImage(TEXT_WIDTH,TEXT_HEIGHT);
|
gl.glDrawPixels(TEXT_WIDTH,TEXT_HEIGHT, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, textbuffer);
|
}
|
//gl.glPixelZoom(8,8); // width/1024.0f,height/1024.0f);
|
gl.glDrawPixels(width, height, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, AAbuffer);
|
*/
|
}
|
}
|
//if (!ambientOcclusion)
|
{
|
// very slow
|
//gl.glFlush();
|
}
|
|
if (flash && DrawMode() == DEFAULT)
|
{
|
flash = false;
|
wait = true;
|
repaint();
|
}
|
|
//drawing = false;
|
//if(DrawMode() == DEFAULT)
|
// niceon = false;
|
if (DrawMode() == DEFAULT)
|
{
|
currentlydrawing = false;
|
}
|
|
if (resetclicked)
|
{
|
clicked = false;
|
}
|
|
ambientOcclusion = keepocclusion;
|
|
if (enablebackspace)
|
{
|
enablebackspace = false;
|
|
SwitchCameras(false);
|
repaint();
|
}
|
|
if (Globals.isLIVE() && DrawMode() == DEFAULT) // may 2013
|
repaint();
|
|
displaydone = true;
|
}
|
|
static boolean fullreset = false;
|
static boolean fromscript = false;
|
|
int lightslot;
|
int callist = -1;
|
static boolean touched = true;
|
boolean mainDL = false;
|
Object3D checker;
|
|
void DrawObject(GL gl)
|
{
|
renderpass++;
|
// System.out.println("Draw object... ");
|
STEP = 1;
|
if (FAST) // in case there is no script
|
STEP = 8;
|
|
if (CURRENTANTIALIAS == 0 || ACSIZE == 1)
|
{
|
STEP *= 4;
|
}
|
|
//object.FullInvariants();
|
|
try
|
{
|
DrawObject(gl, true);
|
}
|
catch (Exception e)
|
{
|
System.err.println("MAJOR CRASH");
|
e.printStackTrace();
|
}
|
|
if (Grafreed.RENDERME > 0)
|
Grafreed.RENDERME--; // mechante magouille
|
|
Globals.ONESTEP = false;
|
}
|
|
static boolean zoomonce = false;
|
|
static void CreateSelectedPoint()
|
{
|
if (selectedpoint == null)
|
{
|
debugpointG = new Sphere();
|
debugpointP = new Sphere();
|
debugpointC = new Sphere();
|
debugpointR = new Sphere();
|
|
selectedpoint = new Superellipsoid();
|
|
for (int i=0; i<8; i++)
|
{
|
debugpoints[i] = new Sphere();
|
}
|
}
|
}
|
|
void DrawObject(GL gl, boolean draw)
|
{
|
// To clear camera values
|
ResetOptions();
|
|
//System.out.println("DRAW OBJECT " + mouseDown);
|
// DrawMode() = SELECTION;
|
//GL gl = getGL();
|
if ((TRACK || SHADOWTRACK) || zoomonce)
|
{
|
if ((TRACK || SHADOWTRACK) && trackedobject != null && DrawMode() == SHADOW) // && !lightMode)
|
object.GetWindow().ScreenFit(trackedobject, SHADOWTRACK && !TRACK);
|
pingthread.StepToTarget(true); // true);
|
// zoomonce = false;
|
}
|
|
RandomNode.globalseed = 0;
|
RandomNode.globalseed2 = 0;
|
//RandomNode.whatevercount = 0;
|
object.ResetRandom();
|
|
if (!isRenderer)
|
{
|
return;
|
}
|
|
if (mainDL && callist == -1)
|
{
|
callist = gl.glGenLists(1);
|
}
|
|
boolean selectmode = DrawMode() == SELECTION || IsDebugSelection();
|
|
boolean active = !selectmode; // DrawMode() != SELECTION; // mouseDown;
|
|
if (!mainDL || !active || touched)
|
{
|
touched = false;
|
|
if (mainDL && active)
|
{
|
System.out.println("NEW LIST");
|
gl.glNewList(callist, GL.GL_COMPILE);
|
}
|
|
// gl.glMatrixMode(gl.GL_TEXTURE);
|
// gl.glPushMatrix();
|
// gl.glMatrixMode(gl.GL_MODELVIEW);
|
// gl.glPushMatrix();
|
|
gl.glEnable(GL.GL_DEPTH_TEST);
|
|
// nov 2013 LA.matInvert(object.GlobalTransform(), ClickInfo.matbuffer);
|
|
if (object.parent != null)
|
{
|
ClickInfo.matbuffer = object.parent.GlobalTransformInv();
|
PushMatrix(ClickInfo.matbuffer);
|
}
|
|
if (DrawMode() == 0)
|
{
|
// System.out.println("CLEAR +++++++++++++++ +++++++++++++++ +++++++++++++++ +++++++++++++++");
|
|
usedtextures.clear();
|
|
try
|
{
|
BindTextures(DEFAULT_TEXTURES, 2);
|
}
|
catch (Exception e)
|
{
|
System.err.println("FAILED: " + DEFAULT_TEXTURES);
|
}
|
}
|
//System.out.println("--> " + stackdepth);
|
// GrafreeD.traceon();
|
|
// DRAW
|
object.draw(this, /*(Composite)*/ object, false, false);
|
|
if (DrawMode() == DEFAULT)
|
{
|
if (Globals.DEBUG)
|
{
|
CreateSelectedPoint();
|
float radius = 0.05f;
|
if (selectedpoint.radius != radius)
|
{
|
// Memory crash! The display lists are not monitored in the memory activity.
|
selectedpoint.radius = radius;
|
selectedpoint.recalculate();
|
selectedpoint.material = new cMaterial();
|
selectedpoint.material.color = 0.15f; // Yellow
|
selectedpoint.material.modulation = 0.75f;
|
|
debugpointG.radius = radius;
|
debugpointG.recalculate();
|
debugpointG.material = new cMaterial();
|
debugpointG.material.color = 0.25f; // Green
|
debugpointG.material.modulation = 0.75f;
|
|
debugpointP.radius = radius;
|
debugpointP.recalculate();
|
debugpointP.material = new cMaterial();
|
debugpointP.material.color = 0.75f; // Purple
|
debugpointP.material.modulation = 0.75f;
|
|
debugpointC.radius = radius;
|
debugpointC.recalculate();
|
debugpointC.material = new cMaterial();
|
debugpointC.material.color = 0.5f; // Cyan
|
debugpointC.material.modulation = 0.75f;
|
|
debugpointR.radius = radius;
|
debugpointR.recalculate();
|
debugpointR.material = new cMaterial();
|
debugpointR.material.color = 0f; // Red
|
debugpointR.material.modulation = 0.75f;
|
|
InitPoints(radius);
|
}
|
selectedpoint.draw(this, /*(Composite)*/ null, false, false);
|
debugpointG.draw(this, /*(Composite)*/ null, false,false);
|
debugpointP.draw(this, /*(Composite)*/ null, false,false);
|
debugpointC.draw(this, /*(Composite)*/ null, false,false);
|
debugpointR.draw(this, /*(Composite)*/ null, false,false);
|
// DrawPoints(this);
|
}
|
|
// debugstuff.draw(this, /*(Composite)*/ null, false);
|
}
|
// GrafreeD.traceoff();
|
//System.out.println(stackdepth);
|
if (DrawMode() == 0)
|
{
|
ReleaseTextures(DEFAULT_TEXTURES);
|
|
if (CLEANCACHE)
|
for (java.util.Enumeration<cTexture> e = texturepigment.keys() ; e.hasMoreElements();)
|
{
|
cTexture tex = e.nextElement();
|
|
// System.out.println("Texture --------- " + tex);
|
|
if (tex.equals("WHITE_NOISE:"))
|
continue;
|
|
if (!usedtextures.contains(tex))
|
{
|
CacheTexture gettex = texturepigment.get(tex);
|
// System.out.println("DISPOSE +++++++++++++++ " + tex);
|
if (gettex != null)
|
{
|
gettex.texture.dispose();
|
texturepigment.remove(tex);
|
}
|
|
gettex = texturebump.get(tex);
|
// System.out.println("DISPOSE +++++++++++++++ " + tex);
|
if (gettex != null)
|
{
|
gettex.texture.dispose();
|
texturebump.remove(tex);
|
}
|
}
|
}
|
}
|
|
checker = null;
|
|
if (!ambientOcclusion && !IsFrozen() && DrawMode() == DEFAULT)
|
FindChecker(object);
|
|
if (checker != null && DrawMode() == DEFAULT)
|
{
|
//BindTexture(IMMORTAL_TEXTURE);
|
try
|
{
|
BindTextures(checker.GetTextures(), checker.texres);
|
}
|
catch (Exception e)
|
{
|
System.err.println("FAILED: " + checker.GetTextures());
|
}
|
// NEAREST
|
GetGL().glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); // GL.GL_LINEAR);
|
DrawChecker(gl);
|
//checker.Draw(this, null, false);
|
// ReleaseTexture(IMMORTAL_TEXTURE);
|
ReleaseTextures(checker.GetTextures());
|
}
|
|
if (object.parent != null)
|
PopMatrix(object.parent.GlobalTransformInv()); // 32 stack
|
|
// gl.glMatrixMode(gl.GL_MODELVIEW);
|
// gl.glPopMatrix();
|
// gl.glMatrixMode(gl.GL_TEXTURE);
|
// gl.glPopMatrix();
|
//gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
//gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
|
if (DISPLAYTEXT && DrawMode() == DEFAULT)
|
{
|
// Draw it once, then use the raster
|
Balloon(gl, balloon.createGraphics());
|
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
|
gl.glDisable(GL.GL_DEPTH_TEST);
|
gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
|
int i = 0;
|
for (String s : stringList)
|
{
|
cVector rp = rasterPosList.get(i++);
|
gl.glRasterPos4f((float) rp.x, (float) rp.y, (float) rp.z, 1);
|
// System.out.println("string = " + s);
|
DrawString0(s);
|
|
// // overlay
|
// gl.glRasterPos4f(-0.25f, -0f, -1, 1);
|
// DrawString0(s);
|
}
|
|
if (i > 0)
|
{
|
//System.out.println("#strings = " + i);
|
}
|
}
|
|
stringList.clear();
|
rasterPosList.clear();
|
|
if (mainDL && active)
|
{
|
gl.glEndList();
|
}
|
}
|
|
if (mainDL && active)
|
{
|
System.out.println("CALL LIST");
|
gl.glCallList(callist);
|
}
|
}
|
|
java.util.Vector<String> stringList = new java.util.Vector<String>();
|
java.util.Vector<cVector> rasterPosList = new java.util.Vector<cVector>();
|
int corner = TEXT_HEIGHT / 4;
|
int base; // = 8;
|
int shift; // = 20;
|
int fontsize = 31; // 15;
|
float bbzoom = 32; // 16
|
int[] xs = new int[3];
|
int[] ys = new int[3];
|
|
public void DrawString(Object3D obj) // String string) // INTERFACE
|
{
|
if (!DISPLAYTEXT || DrawMode() != DEFAULT)
|
{
|
return;
|
}
|
|
String string = obj.toString(); //.GetToolTip();
|
|
GL gl = GetGL();
|
|
gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, tempmat, 0);
|
|
stringList.add(string);
|
double x = tempmat[12]; // 3];
|
double y = tempmat[13]; // 3+4];
|
double z = tempmat[14]; // 3+8];
|
|
if (obj instanceof ScriptNode)
|
{
|
x = -renderCamera.shaper_fovy/120;
|
y = -renderCamera.shaper_fovy/200 / renderCamera.aspect;
|
z = -1;
|
}
|
|
rasterPosList.add(new cVector(x, y, z));
|
}
|
|
void Balloon(GL gl, Graphics2D g)
|
{
|
// for antialising geometric shapes
|
g.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
|
RenderingHints.VALUE_ANTIALIAS_ON));
|
|
//g.addRenderingHints( new RenderingHints( RenderingHints.KEY_COLOR_RENDERING,
|
// RenderingHints.VALUE_COLOR_RENDER_SPEED ));
|
//GL gl = getGL();
|
g.setBackground(new java.awt.Color(0, 0, 0, 0)); // 255));
|
g.clearRect(0, 0, TEXT_WIDTH, TEXT_HEIGHT);
|
|
base = TEXT_HEIGHT / 4 - 2;
|
shift = TEXT_WIDTH / 4;
|
|
xs[1] = 0; // TEXT_WIDTH;
|
ys[1] = TEXT_HEIGHT;
|
xs[0] = //TEXT_WIDTH -
|
shift;
|
ys[0] = TEXT_HEIGHT - base - 1;
|
xs[2] = //TEXT_WIDTH -
|
shift * 3/2;
|
ys[2] = TEXT_HEIGHT - base - 1;
|
|
//Polygon queue = new Polygon(xs,ys,3);
|
|
g.setColor(Color.WHITE);
|
g.fillRoundRect(0, 0, TEXT_WIDTH - 1, TEXT_HEIGHT/4 - base, corner * 2, corner * 2);
|
g.setColor(Color.BLACK);
|
g.drawRoundRect(0, 0, TEXT_WIDTH - 1, TEXT_HEIGHT/4 - base, corner * 2, corner * 2);
|
g.setColor(Color.WHITE);
|
g.fillPolygon(xs, ys, 3);
|
// ys[0] += 1;
|
// ys[2] += 1;
|
g.setColor(Color.BLACK);
|
g.drawPolyline(xs, ys, 3);
|
}
|
|
javax.swing.JTextArea textarea = new javax.swing.JTextArea();
|
|
void DrawString0(String text)
|
{
|
GL gl = GetGL(); // getGL();
|
Graphics2D g = textest.createGraphics();
|
|
g.setFont(new Font(g.getFont().getFontName(), 0/*Font.BOLD|Font.ITALIC*/,
|
fontsize));
|
|
double minX=0,minY=0, maxX=0,maxY=0;
|
String[] strings = text.split("\\n");
|
for (int x=0; x<strings.length; x++)
|
{
|
String string = strings[x];
|
java.awt.geom.Rectangle2D rect = g.getFont().getStringBounds(string, 0, string.length(), g.getFontRenderContext());
|
|
if (x == 0 || minX > rect.getMinX())
|
minX = rect.getMinX();
|
if (x == 0 || maxX < rect.getMaxX())
|
maxX = rect.getMaxX();
|
if (x == 0 || minY > rect.getMinY())
|
minY = rect.getMinY();
|
if (x == 0 || maxY < rect.getMaxY())
|
maxY = rect.getMaxY();
|
}
|
|
float scalex = (float) (maxX - minX);
|
float scaley = (float) (maxY - minY) * strings.length;
|
|
//System.out.println("scale = " + scale);
|
//System.out.println("scale2 = " + scale2);
|
//System.out.println("fontsize = " + fontsize);
|
|
int tw = TEXT_WIDTH;
|
int th = TEXT_HEIGHT;
|
|
float glue = 0.1f; // 2f;
|
|
double res = Math.floor(Math.log((1 + glue * 2) * scalex) / Math.log(2)) + 1;
|
|
int RES = (int) res;
|
|
res = Math.floor(Math.log((1 + glue * 2) * scaley) / Math.log(2)) + 3;
|
|
if (RES < (int) res)
|
{
|
RES = (int) res;
|
}
|
|
if (RES >= billboards.size())
|
{
|
billboards.setSize(RES + 1);
|
bbbuffers.setSize(RES + 1);
|
}
|
if (billboards.get(RES) == null)
|
{
|
int w = (int) Math.pow(2, RES);
|
int h = (int) Math.pow(2, RES - 2);
|
billboards.set(RES, new cBufferedImage(w, h, BufferedImage.TYPE_INT_ARGB));
|
bbbuffers.set(RES, IntBuffer.allocate(w * h));
|
}
|
|
textest = billboards.get(RES);
|
textbuffer = bbbuffers.get(RES);
|
|
tw = textest.getWidth();
|
th = textest.getHeight();
|
|
g = textest.createGraphics();
|
|
g.setFont(new Font(g.getFont().getFontName(), 0/*Font.BOLD|Font.ITALIC*/,
|
fontsize));
|
|
g.setBackground(new java.awt.Color(0, 0, 0, 0)); // 127));
|
g.clearRect(0, 0, tw, th);
|
/* slower...
|
g.clearRect(0, 0, corner,corner);
|
g.clearRect(TEXT_WIDTH-corner, 0, corner,corner);
|
g.clearRect(TEXT_WIDTH-corner, TEXT_HEIGHT-corner, corner,corner);
|
g.clearRect(0, TEXT_HEIGHT-corner, corner,corner);
|
*/
|
//Balloon(g);
|
|
//scale /= TEXT_WIDTH;
|
|
//float x = (float) Math.floor(fontsize/scale);
|
//scale = fontsize/x;
|
|
//scale2 /= TEXT_HEIGHT; // - base;
|
|
//if(scale > scale2)
|
// scale = scale2;
|
|
//if(scale > 1) scale = 1;
|
//if(scale2 > 1) scale2 = 1;
|
|
//
|
/*
|
scale2 /= scale;
|
scale = (float)Math.pow(2,RES-9);
|
scale2 *= scale;
|
*/
|
|
float height = (1 + glue * 2) * scaley;
|
|
g.addRenderingHints(new RenderingHints(RenderingHints.KEY_INTERPOLATION,
|
RenderingHints.VALUE_INTERPOLATION_BICUBIC));
|
g.drawImage(balloon,
|
new java.awt.geom.AffineTransform((1 + glue * 2) * scalex / TEXT_WIDTH, 0, 0, height / TEXT_HEIGHT,
|
0, th - height),
|
//AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
|
(ImageObserver) null);
|
|
//scale = 1;
|
|
// g.setFont(new Font(g.getFont().getFontName(), 0/*Font.BOLD|Font.ITALIC*/,
|
// (int)(fontsize/scale)));
|
|
g.setColor(Color.WHITE);
|
|
// for antialiasing text
|
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
//System.out.println("glue*scale = " + glue*scale);
|
|
//textarea.setSize(100,100);
|
//textarea.setText(string);
|
//textarea.paint(g);
|
for (int x=0; x<strings.length; x++)
|
{
|
String string = strings[x];
|
g.drawString(string, glue * scalex/*fontsize/3f*/, fontsize * 0.8f + glue * scaley + th - height + fontsize*x); // ((int)(fontsize/scale)));
|
}
|
|
InvertImage(tw, th);
|
|
//gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB);
|
//gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
//gl.glRasterPos4f(0,0,0,1);
|
//gl.glPixelZoom(1.5f*scale,1.5f*scale);
|
//System.out.println("RES = " + RES);
|
float zoom = (float) (1 / Math.pow(2, RES - 9));
|
//System.out.println("zoom = " + zoom);
|
//gl.glPixelZoom(zoom/fontsize,zoom/fontsize);
|
zoom = bbzoom / fontsize; // 100/scale;
|
//System.out.println("zoom = " + zoom);
|
zoom = (float) Math.pow(2, Math.floor(Math.log(zoom) / Math.log(2)));
|
//System.out.println("zoom2 = " + zoom);
|
zoom = 1; // 0.5f;
|
gl.glPixelZoom(zoom, zoom);
|
gl.glDrawPixels(tw, (int) height + 1, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, textbuffer);
|
//??? on s'en fout gl.drawString(string, tw, (int) height + 1, 1.f,1.f,1.f);
|
//gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB);
|
//gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
}
|
|
void TextTest()
|
{
|
// Text test
|
Graphics2D g = textest.createGraphics();
|
g.setBackground(new java.awt.Color(0, 0, 0, 0));
|
g.clearRect(0, 0, TEXT_WIDTH, TEXT_HEIGHT);
|
g.setColor(Color.WHITE);
|
g.fillRoundRect(0, 0, TEXT_WIDTH, TEXT_HEIGHT, 50, 50);
|
g.setColor(Color.BLACK);
|
System.out.println("Font = " + g.getFont().getName());
|
System.out.println("Name = " + g.getFont().getFontName());
|
System.out.println("Family = " + g.getFont().getFamily());
|
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
|
System.out.println("#Fonts = " + fonts.length);
|
int p = 1;
|
Font font = new Font("Courier", 0/*Font.BOLD|Font.ITALIC*/, 10);
|
String fam = "";
|
for (Font f : fonts)
|
{
|
//System.out.println("font = " + f.getFamily());
|
if (f.getFamily().equals(fam))
|
{
|
continue;
|
}
|
fam = f.getFamily();
|
g.setFont(font);
|
g.drawString(Integer.toString(p), 0, p * 10);
|
g.drawString(f.getFontName(), 100, p * 10);
|
g.setFont(new Font(f.getFontName(), 0/*Font.BOLD|Font.ITALIC*/, 10));
|
g.drawString(f.getFontName(), 20, p * 10);
|
p += 1;
|
}
|
|
System.out.println("#Families = " + p);
|
}
|
|
int[] scanline = new int[65536]; // 2048];
|
|
void InvertImage(int width, int height)
|
{
|
int[] content = textbuffer.array();
|
content = textest.getRGB(0, 0, width, height, content, 0, width);
|
|
/**/
|
for (int j = 0; j < height / 2; j++)
|
{
|
System.arraycopy(content, j * width, scanline, 0, width);
|
System.arraycopy(content, (height - 1 - j) * width, content, j * width, width);
|
System.arraycopy(scanline, 0, content, (height - 1 - j) * width, width);
|
}
|
/**/
|
}
|
|
boolean HasLights(Object3D obj)
|
{
|
if (obj instanceof Light)
|
{
|
return true;
|
}
|
|
for (int i = 0; i < obj.size(); i++)
|
{
|
Object3D child = ((Object3D /*Composite*/) obj).reserve(i);
|
if (child == null)
|
continue;
|
boolean haslights = HasLights(child);
|
((Object3D /*Composite*/) obj).release(i);
|
if (haslights)
|
{
|
return true;
|
}
|
}
|
|
return false;
|
}
|
|
void DrawLights(Object3D obj)
|
{
|
DrawLights(obj, new cTreePath(obj));
|
}
|
|
void DrawLights(Object3D obj, cTreePath tp)
|
{
|
if (obj.hide || obj.count <= 0 || IsFrozen() || !HasLights(obj))
|
{
|
return;
|
}
|
|
if (obj instanceof Light)
|
{
|
//new Exception().printStackTrace();
|
//obj.Draw(this, false);
|
javax.media.opengl.GL gl = GetGL();
|
|
cVector light = new cVector();
|
|
obj.bRep.Average(light);
|
|
//obj.TransformToWorld(light, light);
|
for (int i = tp.size(); --i >= 0;)
|
{
|
//for (int count = tp.get(i).GetTransformCount(); --count>=0;)
|
LA.xformPos(light, tp.get(i).GlobalTransformInv(), light);
|
}
|
|
|
//System.out.println("Light = " + light);
|
Camera parentcam = renderCamera;
|
|
if (renderCamera == cameras[0])
|
{
|
parentcam = cameras[1];
|
}
|
|
if (renderCamera == cameras[1])
|
{
|
parentcam = cameras[0];
|
}
|
|
//for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.xformPos(light, parentcam.GlobalTransform(), light); // may 2013
|
|
LA.xformPos(light, renderCamera.toScreen, light);
|
|
//System.out.println("Light2 = " + light);
|
|
cMaterial material = obj.GetMaterial();
|
|
lightParams[0] = (float) light.x;
|
lightParams[1] = (float) light.y;
|
lightParams[2] = (float) light.z;
|
lightParams[3] = (float) material.lightarea; // light area
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, lightslot, lightParams, 0);
|
|
cColor.HSBtoRGB(material.color, material.modulation, 1, lightParams);
|
|
lightParams[0] *= material.diffuse;
|
lightParams[1] *= material.diffuse;
|
lightParams[2] *= material.diffuse;
|
lightParams[3] = (float) material.lightarea; // light area
|
|
gl.glProgramEnvParameter4fvARB(gl.GL_FRAGMENT_PROGRAM_ARB, lightslot + 1, lightParams, 0);
|
|
lightslot += 2;
|
|
return;
|
}
|
|
//for (Object3D child : obj)
|
for (int i = 0; i < obj.size(); i++)
|
{
|
Object3D child = ((Object3D) obj).reserve(i);
|
if (child == null)
|
continue;
|
DrawLights(child, new cTreePath(tp, child));
|
((Object3D) obj).release(i);
|
}
|
}
|
|
void FindChecker(Object3D obj)
|
{
|
if (obj.count <= 0)
|
{
|
return;
|
}
|
|
if (obj instanceof Checker)
|
{
|
checker = obj;
|
|
return;
|
}
|
|
for (int i = 0; i < obj.size(); i++)
|
{
|
Object3D child = ((Object3D /*Composite*/) obj).reserve(i);
|
if (child == null)
|
continue;
|
FindChecker(child);
|
((Object3D /*Composite*/) obj).release(i);
|
}
|
}
|
|
int currentMode = -1;
|
int programcount = 0;
|
|
void EnableProgram(int fragmentMode)
|
{
|
//new Exception().printStackTrace();
|
if (fragmentMode != currentMode)
|
{
|
programcount++;
|
//javax.media.opengl.GL gl = GetGL();
|
//gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragmentProgram[fragmentMode]);
|
currentMode = fragmentMode;
|
}
|
}
|
|
float[] lightParams = new float[]{0, 0, 0, 0};
|
|
private void InitFragmentProgram(GL gl, int mode) //, int displayListID)
|
{
|
int[] tmpInt = new int[1];
|
gl.glGenProgramsARB(1, tmpInt, 0);
|
fragmentProgram[mode] = tmpInt[0];
|
gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragmentProgram[mode]);
|
|
//gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 127, lightParams, 0);
|
|
String programmin =
|
// Min shader
|
"!!ARBfp1.0\n" +
|
"PARAM zero12t = { 0.0, 1.0, 2, 1.25 };" +
|
"PARAM pow_2 = { 0.5, 0.25, 0.125, 0.0 };" +
|
"PARAM pow2 = { 2, 4, 8, 0.0 };" +
|
"PARAM one = { 1.0, 1.0, 1.0, 1.0 };" +
|
"PARAM eps = { 0.001, 0.001, 0.001, 1.0 };" +
|
"PARAM infinity = { 100000000, 100000000, 100000000, 1.0 };" +
|
"PARAM light2cam0 = program.env[10];" +
|
"PARAM light2cam1 = program.env[11];" +
|
"PARAM light2cam2 = program.env[12];" +
|
"TEMP temp;" +
|
"TEMP light;" +
|
"TEMP ndotl;" +
|
"TEMP normal;" +
|
"TEMP depth;" +
|
"TEMP eye;" +
|
"TEMP pos;" +
|
|
"MAD normal, fragment.color, zero12t.z, -zero12t.y;" +
|
Normalize("normal") +
|
"MOV light, state.light[0].position;" +
|
"DP3 ndotl.x, light, normal;" +
|
"MAX ndotl.x, ndotl.x, zero12t.x;" +
|
|
// shadow
|
"MOV pos, fragment.texcoord[1];" +
|
"MOV temp, pos;" +
|
ShadowTextureFetch("depth", "temp", "1") +
|
//"TEX depth, fragment.texcoord[1], texture[1], 2D;" +
|
"SLT ndotl.z, fragment.texcoord[1].z, depth.z;" +
|
|
// No shadow when out of frustum
|
//"SGE temp.y, depth.z, zero123.y;" +
|
//"LRP temp.x, temp.y, zero123.y, temp.x;" +
|
|
"MUL ndotl.x, ndotl.x, ndotl.z;" + // Shadow
|
|
// Backlit
|
"MOV pos.w, zero12t.y;" + // one
|
"DP4 eye.x, pos, light2cam0;" +
|
"DP4 eye.y, pos, light2cam1;" +
|
"DP4 eye.z, pos, light2cam2;" +
|
Normalize("eye") +
|
|
"DP3 ndotl.y, -eye, normal;" +
|
//"MUL ndotl.y, ndotl.y, pow2.x;" +
|
"POW ndotl.y, ndotl.y, pow2.x;" + // backlit
|
"SUB ndotl.y, zero12t.y, ndotl.y;" + // 1 - y
|
//"POW ndotl.y, ndotl.y, pow2.z;" + // backlit
|
//"SUB ndotl.y, zero123.y, ndotl.y;" +
|
//"MUL ndotl.y, ndotl.y, pow2.z;" +
|
"ADD ndotl.y, ndotl.y, one.x;" +
|
"MUL ndotl.y, ndotl.y, pow_2.x;" +
|
|
//"MAX ndotl.x, ndotl.x, ndotl.y;" + // Ambient
|
//"MAX ndotl.x, ndotl.x, pow2.y;" + // Ambient
|
|
// Pigment
|
"TEX temp, fragment.texcoord[0], texture[0], 2D;" +
|
"LRP temp, zero12t.w, temp, one;" + // texture proportion
|
"MUL temp, temp, zero12t.w;" + // Times x
|
|
//"MUL temp, temp, ndotl.y;" +
|
"MAD ndotl.x, pow_2.xxxx, ndotl.yyyy, ndotl.x;" +
|
|
"MUL temp, temp, ndotl.x;" + // lambert
|
|
"MOV temp.w, zero12t.y;" + // reset alpha
|
"MOV result.color, temp;" +
|
"END";
|
|
String programmax =
|
"!!ARBfp1.0\n" +
|
|
//"OPTION ARB_fragment_program_shadow;" +
|
"PARAM light2cam0 = program.env[10];" +
|
"PARAM light2cam1 = program.env[11];" +
|
"PARAM light2cam2 = program.env[12];" +
|
//"PARAM light2cam3 = program.env[13];" +
|
"TEMP temp;" +
|
"TEMP temp2;" +
|
"TEMP temp3;" +
|
"PARAM one = { 1.0, 1.0, 1.0, 1.0 };" +
|
// "PARAM almostone = { 0.99, 0.99, 0.99, 1.0 };" +
|
"TEMP pos;" +
|
"MOV temp, fragment.texcoord[1];" +
|
"MOV temp.w, one.x;" +
|
"DP4 pos.x, temp, light2cam0;" +
|
"DP4 pos.y, temp, light2cam1;" +
|
"DP4 pos.z, temp, light2cam2;" +
|
//"KIL -pos.z;" +
|
|
"PARAM params0 = program.env[0];" + // pigment RGB, metalness
|
"PARAM params1 = program.env[1];" + // diffuse, specular, shininess, shift
|
"PARAM params2 = program.env[2];" + // ambient, lightarea, diffuseness, velvet
|
"PARAM params3 = program.env[3];" + // sheen, subsurface, backlit /*was bump*/, anisoU
|
"PARAM params4 = program.env[4];" + // anisoV, cameralight, selfshadow, shadow
|
"PARAM params5 = program.env[5];" + // texture, opacity, fakedepth, shadowbias
|
"PARAM params6 = program.env[6];" + // bump, noise, borderfade, fog punchthrough
|
"PARAM params7 = program.env[7];" + // noise power, opacity power, parallax
|
"PARAM options0 = program.env[63];" + // fog density, intensity, elevation
|
"PARAM options1 = program.env[62];" + // fog rgb color
|
"PARAM options2 = program.env[61];" + // image intensity, subsurface, lightsheen
|
"PARAM pointlight = program.env[127];" + // ...
|
"PARAM zero = { 0.0, 0.0, 0.0, 0.0 };" +
|
"PARAM halfhalf = { 0.25, 0.25, 0.25, 1.0 };" +
|
"PARAM half = { 0.5, 0.5, 0.5, 1.0 };" +
|
"PARAM threequarter = { 0.75, 0.75, 0.75, 1.0 };" +
|
"PARAM two = { 2.0, 2.0, 2.0, 1.0 };" +
|
"PARAM ten = { 10, 10, 10, 1.0 };" +
|
"PARAM one3rd = { 0.5, 0.33333333333, 0.333333333, 1.0 };" +
|
"PARAM slope = { -0.666666666, -1, 0.333333333, 1.0 };" +
|
"PARAM one10th = { 0.1, 0.1, 0.1, 1.0 };" +
|
"PARAM one100 = { 100.0, 100.0, 100.0, 1.0 };" +
|
"PARAM one100th = { 0.01, 0.01, 0.01, 1.0 };" +
|
"PARAM one64th = { 0.25, 0.015625, 0.015625, 1.0 };" +
|
//"PARAM one256th = { 0.00390625, 0.00390625, 0.00390625, 1.0 };" +
|
"PARAM lightarea = { 0.075, 0.0, 0.0, 1.0 };" +
|
"PARAM X = { 1.0, 0.0, 0.0, 1.0 };" +
|
"PARAM Y = { 0.01, 1.0, 0.01, 1.0 };" +
|
"PARAM Z = { 0.0, 0.0, 1.0, 1.0 };" +
|
//"PARAM red = { 0.7, 0.1, 0.2, 1.0 };" +
|
"PARAM eps = { 0.001, 0.001, 0.001, 1.0 };" +
|
"PARAM eps2 = { 0.01, 0.01, 0.01, 1.0 };" +
|
"PARAM shadoweps = { 0.07, 0.07, 0.5, 1.0 };" +
|
"PARAM lodbias = { 10,10,10,10 };" + // 20, -2, -20, 1.0 };" +
|
"PARAM infinity = { 100000000, 100000000, 100000000, 1.0 };" +
|
"PARAM one2048th = { 0.00048828125, 0.00048828125, 0.00048828125, 1.0 };" +
|
"PARAM ninetenth = { 0.9, 0.9, 0.9, 1.0 };" +
|
"PARAM almostone = { 0.999, 0.999, 0.999, 1.0 };" +
|
"PARAM c256 = { 256, 256, 256, 1.0 };" +
|
"PARAM c256i = { 0.00390625, 0.00390625, 0.00390625, 1.0 };" +
|
//
|
//"PARAM four = { 4.0, 4.0, 4.0, 1.0 };" +
|
"TEMP pigment;" +
|
"TEMP texSamp;" +
|
"TEMP texSamp0;" +
|
"TEMP bump;" +
|
"TEMP bump0;" +
|
"TEMP bumpmap;" +
|
"TEMP buffer;" +
|
"TEMP depth;" +
|
"TEMP depth0;" +
|
"TEMP depth1;" +
|
"TEMP depth2;" +
|
"TEMP depth3;" +
|
"TEMP floor;" +
|
"TEMP frac;" +
|
"TEMP eye;" +
|
"TEMP normal0;" + // for shadowbias
|
"TEMP normal;" +
|
"TEMP ndotl;" +
|
"TEMP normald;" + // biased lighting normal
|
"TEMP normals;" + // biased lighting normal
|
"TEMP UP;" +
|
"TEMP U;" +
|
"TEMP V;" +
|
"TEMP light;" +
|
"TEMP lightd;" +
|
"TEMP lights;" +
|
"TEMP dist2;" +
|
"TEMP H;" +
|
"TEMP shadow;" +
|
"TEMP alpha;" +
|
"TEMP occlusion;" +
|
"TEMP R0;" +
|
"TEMP R1;" +
|
"TEMP R2;" +
|
"TEMP R3;" +
|
"TEMP min;" +
|
"TEMP max;" +
|
"TEMP average;" +
|
"TEMP saturation;" +
|
"TEMP keep1;" +
|
"TEMP keep2;" +
|
"TEMP keep3;" +
|
"TEMP out;" +
|
"TEMP final;" +
|
"TEMP debug;" +
|
"TEMP mapgrid;" +
|
"TEMP WSPOS;" +
|
"TEMP WSNORM;" +
|
"TEMP noise1;" +
|
"TEMP noise2;" +
|
"TEMP noise3;" +
|
"TEMP shininess;" +
|
"\n" +
|
"MOV texSamp, one;" +
|
|
"MOV mapgrid.x, one2048th.x;" +
|
"MOV temp, fragment.texcoord[1];" +
|
/*
|
"TEX depth, temp, texture[1], 2D;" + // SHADOW2D;" +
|
"SUB depth.x, fragment.texcoord[1].z, depth.z;" +
|
"SGE depth.y, depth.x, zero.x;" +
|
"SUB depth.x, one.x, depth.x;" +
|
"MUL shadow.x, depth.x, depth.y;" +
|
"SUB shadow.x, one.x, shadow.x;" +
|
//"RCP shadow.x, shadow.x;" +
|
"MUL mapgrid.x, mapgrid.x, shadow.x;" +
|
"MUL mapgrid.x, mapgrid.x, params5.w;" +
|
/**/
|
"RCP temp.w, mapgrid.x;" +
|
"MUL temp, temp, temp.w;" +
|
"FLR floor, temp;" +
|
"SUB frac, temp, floor;" +
|
"MUL temp, floor, mapgrid.x;" +
|
//"TEX depth0, temp, texture[1], 2D;" +
|
(((mode & FP_SOFTSHADOW) == 0) ? "" :
|
ShadowTextureFetch("depth0", "temp", "1") +
|
"") +
|
"ADD temp.x, temp.x, mapgrid.x;" +
|
//"TEX depth1, temp, texture[1], 2D;" +
|
(((mode & FP_SOFTSHADOW) == 0) ? "" :
|
ShadowTextureFetch("depth1", "temp", "1") +
|
"") +
|
"ADD temp.y, temp.y, mapgrid.x;" +
|
//"TEX depth2, temp, texture[1], 2D;" +
|
ShadowTextureFetch("depth2", "temp", "1") +
|
"SUB temp.x, temp.x, mapgrid.x;" +
|
//"TEX depth3, temp, texture[1], 2D;" +
|
(((mode & FP_SOFTSHADOW) == 0) ? "" :
|
ShadowTextureFetch("depth3", "temp", "1") +
|
"") +
|
//"MUL texSamp0, texSamp0, state.material.front.diffuse;" +
|
//"MOV params, material;" +
|
//"MOV params.x, shininess.x;" +
|
//"MOV params.y, lightarea.x;" +
|
//"TEX texSamp1, fragment.texcoord[1], texture[1], 2D;" +
|
//"TEX texSamp2, fragment.texcoord[2], texture[2], 2D;" +
|
//"TEX texSamp3, fragment.texcoord[3], texture[3], 2D;" +
|
//"SUB spare0, texSamp0, texSamp1;" +
|
//"MUL spare0, spare0, four;" +
|
//"SUB spare1, texSamp3, texSamp2;" +
|
//"MUL spare1, spare1, four;" +
|
//"MUL spare0, spare0, redMask;" +
|
//"MAD spare0, greenMask, spare1, spare0;" +
|
//"MUL_SAT spare2, spare0, spare0;" +
|
//"SUB spare2, one, spare2;" +
|
//"DP3 spare1, spare2, const0;" +
|
//"ADD spare0, spare0, const1;" +
|
//"MAD result.color, const2, spare1, spare0;" +
|
"MOV normal, fragment.color;" +
|
"MUL normal, normal, two;" +
|
"SUB normal, normal, one;" +
|
"MOV normal0, normal;" +
|
/* NEW */ Normalize("normal0") +
|
|
// BUMP MAP
|
"MOV temp, fragment.texcoord[0];" + // UV
|
"MOV temp.w, lodbias.y;" +
|
//"TXB bumpmap, temp, texture[2], 2D;" +
|
"TEX bumpmap, temp, texture[2], 2D;" + // bumpmap texture (not noise)
|
// may 2013
|
"MOV bumpmap.z, zero.x;" +
|
|
"MUL bumpmap, bumpmap, two;" +
|
"SUB bumpmap, bumpmap, one;" +
|
// /* NEW */ Normalize("bumpmap") +
|
"MUL bumpmap, params6.xxxx, bumpmap;" +
|
// Test non-uniform shininess
|
"MAX shininess, bumpmap, -bumpmap;" +
|
"MOV shininess, one;" +
|
//"RCP shininess.z, shininess.z;" +
|
//"MOV bumpmap, zero;" +
|
"SUB normal, normal, bumpmap;" +
|
|
/**/ Normalize("normal") +
|
|
"MUL shininess, shininess, params1;" +
|
|
// Occlusion
|
/*
|
"MOV temp.x, fragment.color.w;" +
|
//"MUL temp.x, temp.x, one256th.x;" +
|
"FLR temp.y, temp.x;" +
|
"SUB occlusion.x, temp.x, temp.y;" +
|
"MUL temp.y, temp.y, one256th.x;" +
|
"FLR temp.z, temp.y;" +
|
"SUB occlusion.y, temp.y, temp.z;" +
|
"MUL occlusion.z, temp.z, one256th.x;" +
|
*/
|
"MOV occlusion, fragment.texcoord[2];" +
|
//"RSQ temp, temp.x;" +
|
//"MUL normal, normal, temp;" +
|
//"MUL texSamp, texSamp, two;" +
|
//"MUL temp, temp, texSamp;" +
|
//"MOV temp.y, fragment.texcoord[3];" +
|
//"MOV temp.z, fragment.texcoord[2];" +
|
//"ADD temp, temp, one;" +
|
//"MUL temp, temp, half;" +
|
//"MOV result.depth, texSamp.x;" +
|
//"RCP temp.w, temp.w;" +
|
//"MUL temp.z, temp.z, temp.w;" +
|
|
//"MUL texSamp.x, texSamp.x, half;" +
|
//"MUL texSamp.x, texSamp.x, half;" +
|
//"MUL texSamp.x, texSamp.x, half;" +
|
//"MUL texSamp.x, texSamp.x, half;" +
|
//"ADD temp.z, texSamp.x, temp.z;" + // fragment.texcoord[0].x;" +
|
//"MOV result.depth, temp.z;" + // fragment.texcoord[0].x;" +
|
//"MOV result.color, texSamp;" + // fragment.texcoord[0];" +
|
|
//"DP3 temp.x,state.matrix.modelview.invtrans.row[0],normal;" +
|
//"DP3 temp.y,state.matrix.modelview.invtrans.row[1],normal;" +
|
//"DP3 temp.z,state.matrix.modelview.invtrans.row[2],normal;" +
|
//"MOV normal, temp;" +
|
|
/*
|
"MOV temp, fragment.texcoord[1];" +
|
"MOV temp.w, one.x;" +
|
"DP4 pos.x, temp, light2cam0;" +
|
"DP4 pos.y, temp, light2cam1;" +
|
"DP4 pos.z, temp, light2cam2;" +
|
"KIL -pos.z;" +
|
*/
|
//"DP4 pos.w, temp, light2cam3;" +
|
"MOV pos.w, one.x;" +
|
"MOV eye, -pos;" +
|
//"MOV eye, Z;" +
|
Normalize("eye") +
|
|
// world space
|
// "DP4 WSPOS.x,state.matrix.texture[7].inverse.row[0],pos;" +
|
// "DP4 WSPOS.y,state.matrix.texture[7].inverse.row[1],pos;" +
|
// "DP4 WSPOS.z,state.matrix.texture[7].inverse.row[2],pos;" +
|
// "DP3 WSNORM.x,state.matrix.texture[7].inverse.row[0],normal;" +
|
// "DP3 WSNORM.y,state.matrix.texture[7].inverse.row[1],normal;" +
|
// "DP3 WSNORM.z,state.matrix.texture[7].inverse.row[2],normal;" +
|
/*
|
// object space
|
"DP4 temp.x,state.matrix.modelview.inverse.row[0],pos;" +
|
"DP4 temp.y,state.matrix.modelview.inverse.row[1],pos;" +
|
*/
|
"MOV temp, fragment.texcoord[0];" +
|
//"DP3 temp.z, normal, eye;" +
|
//"MUL temp.w, lodbias.x, temp.z;" + //
|
"MOV temp.w, lodbias.z;" + // y;" +
|
//"TXB texSamp, temp, texture[0], 2D;" +
|
"TEX texSamp, temp, texture[0], 2D;" +
|
//??? "SUB alpha.a, texSamp.a, eps.x;" + // y;" +
|
"POW texSamp.a, texSamp.a, params6.w;" + // fog punch through shortcut
|
// mar 2013 ??? "KIL alpha.a;" +
|
"MOV alpha, texSamp.aaaa;" + // y;" +
|
"KIL alpha.a;" + // not sure with parallax mapping
|
/*
|
"MUL temp.xy, temp, two;" +
|
"TXB bump, temp, texture[0], 2D;" +
|
//"MUL bump, bump, half;" +
|
"MUL temp.xy, temp, two;" +
|
"TXB bump0, temp, texture[0], 2D;" +
|
"ADD bump, bump, bump0;" +
|
//"MUL bump, bump, half;" +
|
"MUL temp.xy, temp, two;" +
|
"TXB bump0, temp, texture[0], 2D;" +
|
"ADD bump, bump, bump0;" +
|
//"MUL bump, bump, half;" +
|
"MUL temp.xy, temp, two;" +
|
"TXB bump0, temp, texture[0], 2D;" +
|
"ADD bump, bump, bump0;" +
|
//"MUL bump, bump, half;" +
|
"MUL temp.xy, temp, two;" +
|
"TXB bump0, temp, texture[0], 2D;" +
|
"ADD bump, bump, bump0;" +
|
//"MUL bump, bump, half;" +
|
"MUL temp.xy, temp, two;" +
|
"TXB bump0, temp, texture[0], 2D;" +
|
"ADD bump, bump, bump0;" +
|
"MUL temp.xy, temp, one64th;" +
|
*/
|
/*
|
"MOV temp.w, lodbias.x;" + //
|
"TXB texSamp0, temp, texture[0], 2D;" +
|
*/
|
//"MOV bump, texSamp;" + //
|
//"MOV bump0, texSamp0;" + //
|
|
// noise power
|
"MUL temp, temp, params6.yyyy;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
//"TXB bump0, temp, texture[6], 2D;" +
|
"TEX bump0, temp, texture[6], 2D;" +
|
/*
|
"MOV temp.x, WSPOS.x;" +
|
"MOV temp.y, WSPOS.y;" +
|
"MUL temp, temp, params6.yyyy;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
"TXB noise1, temp, texture[6], 2D;" +
|
"MAX temp.z, WSNORM.z, -WSNORM.z;" +
|
"MUL noise1, noise1, temp.z;" +
|
"MUL noise1, noise1, temp.z;" +
|
//"MOV noise1, one;" +
|
"MOV temp.x, WSPOS.y;" +
|
"MOV temp.y, WSPOS.z;" +
|
"MUL temp, temp, params6.yyyy;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
"TXB noise2, temp, texture[6], 2D;" +
|
"MAX temp.z, WSNORM.x, -WSNORM.x;" +
|
"MUL noise2, noise2, temp.z;" +
|
"MUL noise2, noise2, temp.z;" +
|
//"MOV noise2, zero;" +
|
"MOV temp.x, WSPOS.z;" +
|
"MOV temp.y, WSPOS.x;" +
|
"MUL temp, temp, params6.yyyy;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
"TXB noise3, temp, texture[6], 2D;" +
|
"MAX temp.z, WSNORM.y, -WSNORM.y;" +
|
"MUL noise3, noise3, temp.z;" +
|
"MUL noise3, noise3, temp.z;" +
|
//"MOV noise3, zero;" +
|
// "LRP bump0, bump0.x, noise1, noise2;" +
|
"MOV bump0, noise1;" +
|
"ADD bump0, bump0, noise2;" +
|
"ADD bump0, bump0, noise3;" +
|
/**/
|
//"MUL bump, bump, half;" +
|
"SUB bump, bump0, half;" +
|
"MUL temp, temp, params7.xxxx;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
//"TXB bump0, temp, texture[6], 2D;" +
|
"TEX bump0, temp, texture[6], 2D;" +
|
"SUB bump0, bump0, half;" +
|
"ADD bump, bump, bump0;" +
|
"MUL temp, temp, params7.xxxx;" +
|
"MOV temp.w, lodbias.z;" + // highest res
|
//"TXB bump0, temp, texture[6], 2D;" +
|
"TEX bump0, temp, texture[6], 2D;" +
|
"SUB bump0, bump0, half;" +
|
"ADD bump, bump, bump0;" +
|
|
// double-sided
|
/**/
|
(doublesided?"DP3 temp.z, normal, eye;" +
|
"SGE temp.x, temp.z, eps.x;" +
|
"SUB temp.x, temp.x, one.x;" +
|
"MUL temp.x, temp.x, two.x;" +
|
"ADD temp.x, temp.x, one.x;" +
|
"MUL normal, normal, temp.xxxx;":""
|
) +
|
/**/
|
|
"MOV temp, fragment.texcoord[4];" +
|
|
// UV base
|
//"DP3 UP.x,state.matrix.modelview.row[0],Y;" +
|
//"DP3 UP.y,state.matrix.modelview.row[1],Y;" +
|
//"DP3 UP.z,state.matrix.modelview.row[2],Y;" +
|
"DP3 UP.x,state.matrix.texture[7].row[0],temp;" +
|
"DP3 UP.y,state.matrix.texture[7].row[1],temp;" +
|
"DP3 UP.z,state.matrix.texture[7].row[2],temp;" +
|
Normalize("UP") +
|
|
"XPD V, normal, UP;" +
|
Normalize("V") +
|
"XPD U, V, normal;" +
|
Normalize("U") +
|
|
"MOV temp, fragment.texcoord[0];" +
|
|
// "MAD normal, -temp.x, U, normal;" +
|
// "MAD normal, -temp.y, V, normal;" +
|
// Normalize("normal") +
|
|
//// "MAX normal.z, eps.x, normal.z;" +
|
// Normalize("normal") +
|
"MOV normald, normal;" +
|
"MOV normals, normal;" +
|
|
// parallax mapping
|
|
"DP3 temp2.x, V, eye;" +
|
"DP3 temp2.y, U, eye;" +
|
"DP3 temp2.z, normal, eye;" +
|
"RCP temp2.z, temp2.z;" +
|
|
"DP3 temp2.w, texSamp, texSamp;" + // Height
|
"RSQ temp2.w, temp2.w;" +
|
"RCP temp2.w, temp2.w;" +
|
|
"SUB temp2.w, temp2.w, half;" +
|
// "SGE temp.x, temp2.w, eps.x;" +
|
// "MUL temp2.w, temp2.w, temp.x;" +
|
|
// "MOV texSamp, U;" +
|
|
"MUL temp2.z, temp2.z, temp2.w;" +
|
"MUL temp2.z, temp2.z, params7.z;" + // parallax
|
|
"MUL temp2, temp2, temp2.z;" +
|
|
"SUB temp, temp, temp2;" +
|
|
"TEX temp, temp, texture[0], 2D;" +
|
"POW temp.a, temp.a, params6.w;" + // punch through
|
|
"ADD texSamp, temp, texSamp;" +
|
"MUL texSamp.xyz, half, texSamp;" +
|
|
"MOV alpha, texSamp.aaaa;" +
|
|
// parallax mapping
|
|
"MOV temp.x, texSamp.a;" +
|
"LRP texSamp, params5.x, texSamp, one;" + // texture proportion
|
//"LRP texSamp0, params5.x, texSamp0, one;" +
|
"MOV texSamp.a, temp.x;" +
|
|
//"MOV temp, fragment.texcoord[0];" +
|
//
|
//"DP3 temp.z, U, eye;" +
|
//"DP3 temp.w, V, eye;" +
|
//
|
//"DP3 temp.z, normal, eye;" +
|
//
|
////"DP3 temp.z, normal, eye;" +
|
////"MUL temp.w, lodbias.x, temp.z;" + //
|
//"MOV temp.w, lodbias.z;" + // y;" +
|
////"TXB texSamp, temp, texture[0], 2D;" +
|
//"TEX texSamp, temp, texture[0], 2D;" +
|
////??? "SUB alpha.a, texSamp.a, eps.x;" + // y;" +
|
//"POW texSamp.a, texSamp.a, params6.w;" + // fog punch through shortcut
|
//// mar 2013 ??? "KIL alpha.a;" +
|
//"MOV alpha, texSamp.aaaa;" + // y;" +
|
//"KIL alpha.a;" +
|
|
// bump map
|
/*
|
"MOV temp.x, texSamp.x;" +
|
"POW temp.x, temp.x, R1.x;" +
|
"POW temp.y, normal2.y, temp.x;" +
|
"POW temp.z, -normal2.y, temp.x;" +
|
"CMP normal2.y, normal2.y, -temp.z, temp.y;" +
|
Normalize("normal2") +
|
*/
|
/* good ?
|
//"SUB R1, bump, bump0;" +
|
"MOV R1, bump;" +
|
"MUL R1, params2.yyyy, R1;" +
|
"MUL R2, R1, normals;" +
|
"ADD temp, V, R2;" +
|
"XPD normals, U, temp;" +
|
"MAX normals.z, eps.x, normals.z;" +
|
Normalize("normals") +
|
"MUL R2, R1, normald;" +
|
"ADD temp, V, R2;" +
|
"XPD normald, U, temp;" +
|
"MAX normald.z, eps.x, normald.z;" +
|
Normalize("normald") +
|
*/
|
"MOV bump0, bump;" +
|
"MUL bump0, params6.wwww, bump0;" + // fog punch-through shortcut
|
"MUL bump, params6.xxxx, bump;" +
|
|
"MUL temp, bump.xxxx, normals;" +
|
"ADD R1, U, temp;" +
|
//Normalize("R1") +
|
"MUL temp, bump.yyyy, normals;" +
|
"ADD R2, V, temp;" +
|
//Normalize("R2") +
|
"XPD normals, R1, R2;" +
|
Normalize("normals") +
|
"DP3 temp.x, normals, eye;" +
|
//"MAX normals.z, eps.x, normals.z;" +
|
"MIN temp.x, -eps2.x, temp.x;" +
|
"MUL temp, eye, temp.xxxx;" +
|
"SUB normals, normals, temp;" +
|
Normalize("normals") +
|
"MOV normald, normals;" + //
|
//"DP3 temp.x, normals, eye;" +
|
//"MOV texSamp.xyz, -temp.x;" + // //
|
|
// SILHOUETTE TEST
|
// "DP3 temp.z, normald, eye;" +
|
// "KIL temp.z;" +
|
|
//
|
/**
|
// Test non-uniform shininess
|
"MAX shininess.z, bump0.x, -bump0.x;" + // roughness
|
"POW shininess.z, shininess.z, two.z;" +
|
"MIN shininess.z, shininess.z, one10th.x;" +
|
"RCP shininess.z, shininess.z;" +
|
//"MOV shininess, one;" +
|
//"MOV bumpmap, zero;" +
|
"MUL shininess, shininess, params1;" +
|
|
"MOV normald, normal;" +
|
"MOV normals, normal;" +
|
/**/
|
|
"MOV light, state.light[0].position;" +
|
//"DP3 temp.x,state.matrix.projection.row[0],light;" +
|
//"DP3 temp.y,state.matrix.projection.row[1],light;" +
|
//"DP3 temp.z,state.matrix.projection.row[2],light;" +
|
//"MOV light, temp;" +
|
//Normalize("light") +
|
|
//"MOV debug, light;" +
|
|
"DP3 ndotl.x, light, normal0;" +
|
//"DP3 temp.z, light, normal;" +
|
/*
|
"SLT temp.x, temp.z, one100th.x;" +
|
"SLT temp.y, fragment.texcoord[1].z, depth.z;" +
|
"MAX shadow.x, temp.x, temp.y;" +
|
"MAX shadow.x, shadow.x, params4.w;" +
|
*/
|
// SHADOW
|
// Used for backfacing shadow culling
|
"MOV lightd, light;" +
|
"MOV temp, normal;" +
|
"MUL temp, params3.y, temp;" + // subsurface
|
"ADD lightd, lightd, temp;" +
|
Normalize("lightd") +
|
Shadow("depth2", "shadow") +
|
//"MUL texSamp, texSamp, fragment.texcoord[0];" +
|
//"MOV texSamp.z, zero.z;" +
|
|
(((mode & FP_SOFTSHADOW) == 0) ? "" :
|
"MUL shadow.x, shadow.x, frac.x;" +
|
"MUL shadow.x, shadow.x, frac.y;" +
|
"SUB frac.x, one.x, frac.x;" +
|
Shadow("depth3", "buffer") +
|
"MUL buffer.x, buffer.x, frac.x;" +
|
"MAD shadow.x, buffer.x, frac.y, shadow.x;" +
|
"SUB frac.y, one.y, frac.y;" +
|
Shadow("depth0", "buffer") +
|
"MUL buffer.x, buffer.x, frac.x;" +
|
"MAD shadow.x, buffer.x, frac.y, shadow.x;" +
|
"SUB frac.x, one.x, frac.x;" +
|
Shadow("depth1", "buffer") +
|
"MUL buffer.x, buffer.x, frac.x;" +
|
"MAD shadow.x, buffer.x, frac.y, shadow.x;" +
|
"") +
|
|
// display shadow only (fakedepth == 0)
|
"SUB temp.x, half.x, shadow.x;" +
|
"MOV temp.y, -params5.z;" + // params6.x;" +
|
"SLT temp.z, temp.y, -c256i.x;" +
|
"SUB temp.y, one.x, temp.z;" +
|
"MUL temp.x, temp.x, temp.y;" +
|
"KIL temp.x;" +
|
|
"MUL pigment, params0, texSamp;" +
|
//"MUL pigment, pigment, state.light[0].diffuse;" +
|
|
"MOV light.w, one.x;" +
|
"MOV shadow.w, one.x;" + // light area
|
Light(mode) +
|
"MUL out, out, state.light[0].diffuse;" +
|
"MOV final, out;" +
|
(((mode & FP_LIGHT) == 0) ? "" : LoopLights(mode) +
|
/*
|
"SUB light, pointlight, pos;" + // eye;" +
|
"DP3 dist2.x, light, light;" +
|
"RCP dist2.x, dist2.x;" +
|
Normalize("light") +
|
"MOV shadow.x, one.x;" +
|
"MOV shadow.y, one.x;" + // zero.x;" +
|
Light(mode) +
|
"MUL out, out, dist2.x;" +
|
"MUL out, out, pointlight.wwww;" +
|
"ADD final, final,out;" + //?
|
*/
|
/*
|
//
|
"MOV light, eye;" +
|
"MOV shadow.x, one.x;" +
|
"MOV shadow.y, zero.x;" +
|
Light(mode) +
|
"MUL out, params4.yyyy, out;" +
|
"ADD final, final,out;" + //?
|
/**/
|
"") +
|
// Saturation for skin
|
// /**/
|
// "DP3 temp.x, final,one;" +
|
// "MUL R2, one3rd.xxxx,temp.xxxx;" +
|
// "SUB temp, final,R2;" +
|
// // using light angle
|
//// "DP3 ndotl.x, normald,light;" +
|
//// //"SLT ndotl.y, ndotl.x, zero.x;" +
|
//// "MAX ndotl.y, ndotl.x, -ndotl.x;" +
|
//// "MUL ndotl.y, ndotl.y, ndotl.y;" +
|
// // using light intensity
|
// "MOV ndotl.y, R2.x;" +
|
// "MAD R1.x, ndotl.y,slope.y,one.x;" +
|
// "MUL temp, R1.xxxx,temp;" +
|
// "ADD final, temp,R2;" +
|
// /**/
|
// Global light
|
//
|
"MOV temp2.w, occlusion.w;" +
|
|
/* use least saturated pigment value (ndotl == 1) *
|
"DP3 temp.x, pigment,one;" +
|
"MUL R2, one3rd.xxxx,temp.xxxx;" +
|
"SUB temp, pigment,R2;" +
|
"ADD R1.x, slope.y,one.x;" +
|
"MUL temp, R1.xxxx,temp;" +
|
"ADD pigment, temp,R2;" +
|
/**/
|
|
"MUL occlusion, occlusion, pigment;" +
|
"DP3 temp.z, normald, eye;" +
|
"MUL temp.x, temp.z, half.x;" +
|
//"MUL temp.x, temp.x, temp.x;" +
|
"SUB temp.x, one.x, temp.x;" +
|
//"RSQ temp.x, temp.x;" +
|
//"RCP temp.x, temp.x;" +
|
"POW temp.x, temp.x, params3.z;" + // backlit
|
// "sky" fade
|
"DP3 temp.y, normald, UP;" +
|
/**/
|
"MUL R1, -temp.z, normald;" +
|
"MUL R1, R1, two;" +
|
"SUB R1, -eye, R1;" +
|
"DP3 temp.w, R1, UP;" +
|
"SUB temp, one, temp;" +
|
"MUL temp.y, temp.y, temp.w;" +
|
"SUB temp, one, temp;" +
|
/**/
|
"MAD temp.y, half.x, temp.y, one.x;" +
|
// Y fading:
|
//"MUL temp.x, temp.x, temp.y;" +
|
// "back" fade
|
/*
|
//"DP3 temp.y, normal, light;" +
|
"MOV temp.y, -ndotl.x;" +
|
"MAD temp.y, half.x, temp.y, one.x;" +
|
"MUL temp.x, temp.x, temp.y;" +
|
*/
|
//"MAX temp.x, temp.x, half.x;" +
|
"MUL occlusion, occlusion, params4.yyyy;" + // intensity
|
"MUL occlusion, occlusion, temp.xxxx;" + // global light
|
"ADD final, final,occlusion;" +
|
//"MAX final, final,occlusion;" +
|
|
"MUL R2, params2.xxxx, pigment;" +
|
"MUL R2, R2, temp.xxxx;" +
|
"MAX final, final, R2;" + // ambient
|
|
// skin?
|
// Saturation for skin
|
/**/
|
(Skinshader?
|
"DP3 average.x, final,one;" +
|
"MUL average, one3rd.xxxx,average.xxxx;" +
|
|
"MIN min.x, final.x,final.y;" +
|
"MIN min.x, min.x,final.z;" +
|
|
"MAX max.x, final.x,final.y;" +
|
"MAX max.x, max.x,final.z;" +
|
"MOV max, max.xxxx;" +
|
|
"SUB saturation, max, final;" +
|
|
"ADD temp.x, max.x, one10th.x;" +
|
"RCP temp.x, temp.x;" +
|
"MUL temp.x, temp.x, half.x;" +
|
"MUL saturation, saturation, temp.xxxx;" +
|
|
"DP3 ndotl.x, normald, light;" +
|
"MAX ndotl.x, ndotl.x, -ndotl.x;" +
|
|
"SUB temp.x, one.x, ndotl.x;" +
|
// Tuning for default skin
|
//"ADD temp.x, temp.x, options2.z;" + // lightsheen
|
"MAD temp.x, options2.z, half.y, temp.x;" + // lightsheen
|
"ADD temp.y, one.y, options2.y;" + // subsurface
|
"MUL temp.x, temp.x, temp.y;" +
|
|
"MUL saturation, saturation, temp.xxxx;" +
|
"SUB_SAT temp, max, saturation;" +
|
/**
|
"DP3 temp.x, final,one;" +
|
"MUL R2, one3rd.xxxx,temp.xxxx;" +
|
"SUB temp, final, R2;" +
|
|
// using light angle
|
"DP3 ndotl.x, normald,light;" +
|
//"SLT ndotl.y, ndotl.x, zero.x;" +
|
"MAX ndotl.y, ndotl.x, -ndotl.x;" +
|
"SUB ndotl.y, one.y, ndotl.y;" +
|
"MUL ndotl.y, ndotl.y, ndotl.y;" +
|
// "MUL ndotl.y, ndotl.y, ndotl.y;" +
|
"MUL ndotl.y, ndotl.y, one3rd.y;" +
|
// "MAD temp.x, R2.y, ndotl.y, temp.x;" + // red shift (skin)
|
// using light intensity
|
"MOV ndotl.z, R2.x;" +
|
"MUL ndotl.z, ndotl.z, ndotl.z;" + // tuning...
|
// june 2014
|
"MAD R1.x, ndotl.z,slope.y,one.x;" +
|
// "SUB ndotl.x, one.x, ndotl.x;" +
|
// "MAD R1.x, ndotl.x,-slope.y,one.x;" +
|
|
"MUL temp, R1.xxxx,temp;" +
|
"ADD temp, temp,R2;" +
|
|
//"MUL R2.y, shadow.x,R2.y;" + // avril 2014
|
|
"MAD temp.x, R2.y, ndotl.y, temp.x;" + // red shift (skin)
|
/**/
|
|
// "ADD final, R2,temp;" +
|
"MOV final, temp;"
|
:""
|
) +
|
/**/
|
|
//"RCP temp.x, params5.y;" +
|
//"MUL final, final, temp.xxxx;" + // Pre-multiply alpha
|
|
/*MOON*/
|
"MOV occlusion, final;" +
|
/**/
|
/* FOG */
|
"DP3 temp.x, pos,pos;" +
|
"RSQ temp.x, temp.x;" +
|
"RCP temp.x, temp.x;" +
|
"MUL temp.x, -options0.x,temp.x;" + // density
|
//"MUL temp.x, params6.w,temp.x;" + // punch through
|
// DP3
|
"DP4 temp.z, state.matrix.texture[7].inverse.row[1],pos;" +
|
// test clip plane
|
// "SUB temp.y,one.x,params3.x;" +
|
// "MUL temp.y,temp.z,temp.y;" +
|
// "KIL temp.y;" +
|
"MUL temp.y, -options0.z,temp.z;" + // elevation
|
"EX2 temp.y, temp.y;" +
|
"MUL temp.x, temp.x,temp.y;" +
|
"EX2 temp.x, temp.x;" +
|
"MUL final, final,temp.xxxx;" +
|
"SUB temp.x, one.x,temp.x;" +
|
"MUL temp.x, options0.y,temp.x;" + // intensity
|
"MUL temp, options1,temp.xxxx;" +
|
"ADD final, final,temp;" +
|
/**/
|
"MOV final.a, one.x;" +
|
/* vertical alpha (B&W patch). temp.z is the altitude
|
"DP4 temp.z, state.matrix.texture[7].inverse.row[1],pos;" +
|
//"DP3 temp.z, pos, UP;" +
|
"MAX temp.z, temp.z, eps.z;" +
|
//"POW temp.z, temp.z, params7.y;" +
|
"POW temp.z, temp.z, params6.w;" +
|
//"EX2 temp.x, -temp.z;" +
|
"POW temp.x, params7.y, -temp.z;" +
|
"SUB temp.x, one.x, temp.x;" +
|
"MUL final.a, final.a,temp.x;" +
|
/**/
|
/* halo... */
|
"DP3 temp.x, eye, normald;" +
|
(opacityhalo?
|
"SUB temp.x, one.x, temp.x;":"") + // reverse opacity power
|
// "SUB R1.x, one.x, temp.x;" +
|
// "LRP temp.x, params6.w, temp.x, R1.x;" +
|
// nov 2013
|
"RCP temp.y, params7.y;" +
|
"POW temp.x, temp.x, temp.y;" +
|
"MUL final.a, final.a,temp.x;" +
|
|
/* border fade */
|
"SUB temp, fragment.texcoord[3], half;" + // [0]
|
"MAX temp, temp, -temp;" +
|
"MUL_SAT temp, temp, two;" +
|
"MUL temp, temp, almostone;" +
|
"RCP R1.x, params6.z;" +
|
/* square */
|
"POW temp.x, temp.x, R1.x;" +
|
"POW temp.y, temp.y, R1.x;" +
|
"SUB temp, one, temp;" +
|
"MUL temp, temp, temp;" +
|
"MUL temp.x, temp.x, temp.y;" +
|
/**/
|
/* circle
|
"MOV temp.z, zero.x;" +
|
"DP3 temp.z, temp, temp;" +
|
"RSQ temp.z, temp.z;" +
|
"RCP temp.z, temp.z;" +
|
"POW temp.x, temp.z, R1.x;" +
|
"SUB temp.x, one.x, temp.x;" +
|
/**/
|
/* MOON patch
|
//"DP3 temp.y, occlusion,occlusion;" +
|
"DP3 temp.y, light,normal;" +
|
"MAX temp.y, zero.x,temp.y;" +
|
"RSQ temp.y, temp.y;" +
|
"RCP temp.y, temp.y;" +
|
"MUL final.a, final.a,temp.y;" +
|
/**/
|
// HDR
|
"MOV temp.z, final.a;" +
|
"MUL final, final,options2.x;" +
|
"MOV final.a, temp.z;" +
|
/**/
|
|
"MUL final.a, final.a,temp.x;" +
|
/**/
|
//"MOV final.a, params5.y;" +
|
"MUL final.a, final.a,params5.y;" +
|
"MUL final.a, final.a,temp2.w;" +
|
"MUL final.a, final.a,alpha.x;" +
|
"MOV temp.a, final.a;" +
|
"RCP temp.x, final.a;" +
|
/**/ //
|
// "MUL final, final, temp.xxxx;" + // Pre-multiply alpha
|
"MOV final.a, temp.a;" +
|
|
// (UVdebug?"MOV final.x, fragment.texcoord[0].x;" +
|
// "MOV final.y, fragment.texcoord[0].y;" +
|
// "MOV final.z, zero.x;" +
|
// "MOV final.a, one.w;":""
|
// ) +
|
(Udebug?//"MOV final.x, fragment.texcoord[0].x;" +
|
"MUL final.y, fragment.texcoord[0].x, c256;" +
|
"FLR final.x, final.y;" +
|
"SUB final.y, final.y, final.x;" +
|
"MUL final.x, final.x, c256i;" +
|
"MOV final.z, zero.x;" +
|
"MOV final.a, one.w;":""
|
) +
|
(Vdebug?//"MOV final.x, fragment.texcoord[0].y;" +
|
"MUL final.y, fragment.texcoord[0].y, c256;" +
|
"FLR final.x, final.y;" +
|
"SUB final.y, final.y, final.x;" +
|
"MUL final.x, final.x, c256i;" +
|
"MOV final.z, zero.x;" +
|
"MOV final.a, one.w;":""
|
) +
|
/*
|
(NORMALdebug?"MOV final.x, normal.x;" +
|
"MOV final.y, normal.y;" +
|
"MOV final.z, normal.z;" +
|
"MOV final.a, one.w;":""
|
) +
|
*/
|
(NORMALdebug?"SUB final.x, one.x, final.x;" +
|
"SUB final.y, one.x, final.y;" +
|
"SUB final.z, one.x, final.z;" +
|
"MOV final.a, final.a;":""
|
) +
|
// "MOV final, bumpmap;" +
|
"MOV result.color, final;" +
|
//"MOV result.color, fragment.color.zzzz;" +
|
//"MOV result.color.x, zero.x;" + // depth.x;" +
|
//"MOV result.color.y, fragment.color.z;" +
|
//"MOV result.color.z, zero.x;" +
|
// "MOV result.color, fragment.color;" + // mars 2014
|
// aout 2013
|
// "MOV temp.x, fragment.position.z;" + //
|
// "TEX bump0, fragment.position, texture[6], 2D;" +
|
// "MUL bump0.x, one10th.x,bump0.x;" +
|
// "ADD result.depth.z, temp.x, bump0.x;" +
|
|
// july 2014: test occlusion bias. works.
|
// "MUL temp.x, params6.w, one100th.x;" + //
|
// "MUL temp.x, temp.x, one100th.x;" + //
|
// "SUB result.depth.z, fragment.position.z, temp.x;" +
|
|
"\n" +
|
"END\n";
|
|
//if (!once)
|
{
|
//System.out.println(program.split(";").length);
|
//once = true;
|
}
|
|
String program = programmax;
|
|
if (Globals.MINSHADER)
|
{
|
program = programmin;
|
}
|
|
if (Globals.DEBUG)
|
{
|
System.out.print("Program #" + mode + "; instructions = " + program.split(";").length + "; length = " + program.length());
|
System.out.println(" - " + (mode >> 3) + " lights; " + ((mode & 2) == 2 ? "anisoUV " : "") + ((mode & 4) == 4 ? "SoftShadow " : ""));
|
}
|
|
loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program);
|
|
//gl.glNewList(displayListID, GL.GL_COMPILE);
|
//gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg);
|
//gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
//gl.glEndList();
|
}
|
|
static boolean once = false;
|
|
private void InitShadowProgram(GL gl) //, int displayListID)
|
{
|
int[] tmpInt = new int[1];
|
gl.glGenProgramsARB(1, tmpInt, 0);
|
fragmentProgram[0] = tmpInt[0];
|
gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragmentProgram[0]);
|
|
//gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 127, lightParams, 0);
|
|
String program =
|
"!!ARBfp1.0\n" +
|
"PARAM lodbias = { 0,0,0,0 };" + // 20, -2, -20, 1.0 };" +
|
"PARAM zero = { 0.0, 0.0, 0.0, 0.0 };" +
|
"PARAM half = { 0.5, 0.5, 0.5, 0.5 };" +
|
"PARAM one = { 1.0, 1.0, 1.0, 1.0 };" +
|
"TEMP temp;" +
|
"TEMP texSamp;" +
|
|
"MOV temp, fragment.texcoord[0];" +
|
"MOV temp.w, lodbias.z;" + // y;" +
|
"TEX texSamp, temp, texture[0], 2D;" +
|
// "POW texSamp.a, texSamp.a, params6.w;" + // fog punch through shortcut
|
"SUB temp.x, texSamp.a, half.x;" +
|
"KIL temp.x;" +
|
|
// "SLT temp.x, texSamp.a, half.x;" +
|
// "MAX temp.x, fragment.position.z, temp.x;" +
|
|
// "MOV temp.x, fragment.position.z;" + //
|
//
|
// "MOV result.color, one;" +
|
// "MOV result.depth.z, temp.x;" +
|
|
"\n" +
|
"END\n";
|
|
if (Globals.DEBUG)
|
System.out.println("Program shadow #" + 0 + "; length = " + program.length());
|
loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program);
|
|
//gl.glNewList(displayListID, GL.GL_COMPILE);
|
//gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg);
|
//gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB);
|
//gl.glEndList();
|
}
|
|
String LoopLights(int mode)
|
{
|
//System.out.println("loop lights = " + mode);
|
String out = "";
|
|
int nb = mode >> 3; // 2;
|
|
for (int i = 0; i < nb; i++)
|
{
|
int index = (i * 2 + 64);
|
//System.out.println("Light #" + index);
|
out +=
|
"SUB light, program.env[" + index + "], pos;" + // eye;" +
|
//"DP3 dist2.x, light, light;" +
|
//"RCP dist2.x, dist2.x;" +
|
Normalize("light") + // keeps the distance in light.w
|
//"MOV temp3, shadow;" +
|
//"MOV shadow.x, one.x;" +
|
//"MOV shadow.y, one.x;" + // zero.x;" +
|
"MOV shadow, one;" + // z and w are not used (x=diff, y=spec)
|
"MOV shadow.w, program.env[" + index + "].w;" + // light area
|
Light(mode) +
|
//"MOV shadow, temp3;" +
|
|
//"MUL out, out, dist2.x;" +
|
// SQUARED DISTANCE (moved)
|
// "MUL out, out, light.w;" +
|
// "MUL out, out, light.w;" +
|
//"MUL out, out, program.env[" + (index+1) + "];" +
|
//"ADD final, final,out;";
|
"MAD final, out, program.env[" + (index + 1) + "], final;";
|
}
|
|
return out;
|
}
|
|
// Also does frustum culling
|
String ShadowTextureFetch(String dest, String src, String unit)
|
{
|
return "TEX " + dest + ", " + src + ", texture[" + unit + "], 2D;" +
|
"SGE " + src + ".w, " + src + ".x, eps.x;" +
|
"SGE " + src + ".z, " + src + ".y, eps.x;" +
|
"SLT " + dest + ".x, " + src + ".x, one.x;" +
|
"SLT " + dest + ".y, " + src + ".y, one.x;" +
|
"MUL " + src + ".w, " + src + ".z, " + src + ".w;" +
|
"MUL " + src + ".w, " + dest + ".x, " + src + ".w;" +
|
"MUL " + src + ".w, " + dest + ".y, " + src + ".w;" +
|
//"SWZ buffer, temp, w,w,w,w;";
|
//"MUL " + dest + ".z, " + dest + ".z, " + src + ".w;" +
|
"SUB " + src + ".z, " + "one.x, " + src + ".w;" +
|
//"MUL " + src + ".z, " + src + ".z, infinity.x;" +
|
//"ADD " + dest + ".z, " + dest + ".z, " + src + ".z;";
|
//"MAD " + dest + ".z, " + src + ".z, infinity.x," + dest + ".z;";
|
|
//?? "LRP " + dest + ".z, " + src + ".w," + dest + ".z, infinity.x;";
|
"LRP " + dest + ".z, " + src + ".z, infinity.x," + dest + ".z;";
|
}
|
|
String Shadow(String depth, String shadow)
|
{
|
return "MAX temp.x, ndotl.x, one64th.x;" +
|
"MIN temp.x, temp.x, ninetenth.x;" +
|
/**/
|
// Sine
|
"MUL temp.y, temp.x, temp.x;" +
|
//"MAX temp.y, temp.y, one10th.x;" +
|
"SUB temp.y, one.x, temp.y;" +
|
"RSQ temp.y, temp.y;" +
|
"MUL temp.x, temp.x, temp.y;" +
|
"RCP temp.x, temp.x;" +
|
//"MOV temp.x, one.x;" +
|
//"MAD temp.x, temp.x, mapgrid.x, params5.w;" + // Shadow bias
|
"MUL temp.x, temp.x, params5.w;" + // Shadow bias
|
//"MUL temp.x, temp.x, mapgrid.x;" +
|
|
"ADD " + depth + ".z, " + depth + ".z, temp.x;" +
|
//"SUB " + depth + ".z, " + depth + ".z, temp.x;" + // back face shadowing!
|
|
// Compare fragment depth in light space with shadowmap.
|
"SUB temp.x, fragment.texcoord[1].z, " + depth + ".z;" +
|
"SGE temp.y, temp.x, zero.x;" +
|
"SUB " + shadow + ".y, one.x, temp.y;" + // Specular is fully occluded
|
|
// Reverse comparison
|
"SUB temp.x, one.x, temp.x;" +
|
"MUL " + shadow + ".x, temp.x, temp.y;" +
|
"SUB " + shadow + ".x, one.x, " + shadow + ".x;" + // diffuse
|
"POW " + shadow + ".x, " + shadow + ".x, params5.z;" + // fake depth
|
|
"SLT " + shadow + ".z, fragment.texcoord[1].z, " + depth + ".z;" +
|
"SUB temp.z, one.x, " + shadow + ".z;" +
|
"SUB temp.x, one.x, " + depth + ".z;" +
|
"MUL temp.z, temp.z, temp.x;" +
|
"SUB temp.z, one.x, temp.z;" +
|
"MUL " + shadow + ".x, " + shadow + ".x, temp.z;" + // ???
|
"POW " + shadow + ".x, " + shadow + ".x, params4.w;" + // shadow
|
|
// No shadow for backface
|
"DP3 temp.x, normal, lightd;" +
|
"SLT temp.x, temp.x, zero.x;" + // shadoweps
|
"LRP " + shadow + ", temp.x, one, " + shadow + ";" +
|
|
// No shadow when out of frustum
|
"SGE temp.x, " + depth + ".z, one.z;" +
|
"LRP " + shadow + ", temp.x, one, " + shadow + ";" +
|
"";
|
}
|
|
String Light(int mode)
|
{
|
//System.out.println("Light mode = " + mode);
|
return "MOV lightd, light;" +
|
"MOV lights, light;" +
|
// Subsurface
|
/*
|
"MOV temp, light;" +
|
"MUL temp, params3.y, temp;" +
|
"ADD normal, normal, temp;" +
|
Normalize("normal") +
|
*/
|
"MOV temp, normald;" +
|
"MUL temp, params3.y, temp;" + // subsurface
|
"ADD lightd, lightd, temp;" +
|
//"MAD temp, params3.y, temp, lightd;" + // subsurface
|
// ?? Normalize("lightd") +
|
|
// H vector
|
"ADD H, lights, eye;" +
|
Normalize("H") +
|
"MOV keep1, normald;" +
|
"MOV keep2, normals;" +
|
"MOV keep3, lightd;" +
|
Aniso("temp", "U", "params3.w") +
|
"MOV out, temp;" +
|
"MOV normald, keep1;" +
|
"MOV normals, keep2;" +
|
"MOV lightd, keep3;" +
|
((mode & FP_ANISO) == 0 ? "" : Aniso("temp", "V", "params4.x") +
|
//"MOV debug, normald;" + //
|
|
"MOV normald, keep1;" +
|
"MOV normals, keep2;" +
|
"MOV lightd, keep3;" +
|
"ADD out, out,temp;" +
|
"MUL out, out,half.xxxx;" +
|
"") +
|
"";
|
}
|
|
String Aniso(String dest, String U, String factor)
|
{
|
return /**/ // Anisotropic
|
// Diffuse
|
"DP3 R1.x, " + U + ", light;" +
|
"MUL R1.x, " + factor + ", R1.x;" +
|
//"MUL R1, -R1.xxxx, " + U + ";" +
|
//"ADD lightd, lightd, R1;" +
|
"MAD lightd, -R1.xxxx, " + U + ", lightd;" +
|
Normalize("lightd") +
|
//"ADD lights, lights, R1;" +
|
//Normalize("lightd") +
|
|
//"DP3 R1.x, temp, lights;" +
|
//"MUL R1, -R1.xxxx, temp;" +
|
//"ADD lights, lights, R1;" +
|
//Normalize("lights") +
|
|
/**/
|
// Specular
|
"XPD R2, " + U + ", H;" +
|
"DP3 R1.x, R2, normals;" +
|
"MUL R1.x, " + factor + ", R1.x;" +
|
//"MUL R1, -R1.xxxx, R2;" +
|
//"ADD normals, normals, R1;" +
|
"MAD normals, -R1.xxxx, R2, normals;" +
|
Normalize("normals") +
|
/**/
|
// grazing angle normal (sheen)
|
"DP3 R1.x, lightd, normal;" +
|
"MAX R1.x, zero.x, R1.x;" +
|
"MOV temp.x, params3.x;" +
|
"POW temp.x, temp.x, R1.x;" +
|
"DP3 temp.y, normald, eye;" +
|
"MAX temp.y, temp.y, eps.x;" +
|
"POW temp.z, temp.y, temp.x;" +
|
"SUB temp.z, temp.z, temp.y;" +
|
//"MUL R1, temp.z, eye;" +
|
//"ADD normald, normald, R1;" +
|
"MAD normald, temp.z, eye, normald;" +
|
Normalize("normald") +
|
// Shading
|
"DP3 R1.x, lightd, normald;" +
|
"DP3 R1.y, H, normals;" +
|
"DP3 R1.w, light, normal;" +
|
/*
|
//"MOV R1.z, params.x;" +
|
"MOV R1.z, texSamp.x;" +
|
"MUL R1.z, R1.z, R1.z;" +
|
"MUL R1.z, R1.z, R1.z;" +
|
//"MUL R1.z, R1.z, params.x;" +
|
//"ADD R1.z, R1.z, eps.x;" +
|
//"MOV R1.z, params1.z;" +
|
//"MOV R1.w, params2.y;" +
|
*/
|
Model("R2", "R1") +
|
"DP3 R1.x, lightd, normal;" +
|
"CMP R2.x, R1.x, zero.x, R2.x;" +
|
"MUL R2, R2, shadow;" +
|
/*
|
"MAX R3, R2.xxxx, params2.xxxx;" + // ambient
|
"MUL temp, pigment, R3;" +
|
*/
|
"MUL temp, pigment, R2.xxxx;" +
|
"MUL temp, params1.xxxx, temp;" + // diffuse
|
|
// arctan fall-off factor
|
"MUL temp.w, shadow.w, light.w;" + // lightarea / distance
|
"MIN temp.w, one.x, temp.w;" + // atan(x) ~= x - x^3/3
|
"MUL R1.x, temp.w, temp.w;" +
|
"MUL R1.x, R1.x, temp.w;" +
|
"MAD R1.x, R1.x, -one3rd.z, temp.w;" +
|
|
"MUL temp, temp, R1.xxxx;" + // atan fall-off
|
// "MUL temp, temp, light.w;" + // / distance
|
// //"MUL temp, temp, light.w;" + // / distance squared
|
|
"DP3 R1.x, lights, normal;" +
|
"CMP R3, R1.x, zero.xxxx, R2.yyyy;" +
|
"MAX R3, zero, R3;" +
|
"MUL R0, pigment, pigment.wwww;" + // metalness
|
"SUB R2, one, pigment.wwww;" +
|
"ADD R0, R2, R0;" +
|
"MUL R3, R0, R3;" +
|
"RCP temp.w, params5.y;" +
|
"MUL R3, R3, temp.wwww;" + // Pre-multiply alpha (twice)
|
|
"MAD temp, R3, params1.yyyy, temp;" + // specular + diffuse
|
//"MUL temp, temp, state.light[0].diffuse;" +
|
"\n";
|
}
|
|
float color,saturation; // patch for multiply
|
/*static*/ float[] modelParams0 = new float[]{0, 0, 0, 0}; // pigment RGB, metalness
|
/*static*/ float[] modelParams1 = new float[]{0, 0, 0, 0}; // diffuse, specular, shininess, shift
|
/*static*/ float[] modelParams2 = new float[]{0, 0, 0, 0}; // ambient, lightarea, diffuseness, velvet
|
/*static*/ float[] modelParams3 = new float[]{0, 0, 0, 0}; // sheen, subsurface, backlit /* was bump*/, anisoU
|
/*static*/ float[] modelParams4 = new float[]{0, 0, 0, 0}; // anisoV, cameralight, selfshadow, shadow
|
/*static*/ float[] modelParams5 = new float[]{0, 0, 0, 0}; // texture, opacity, fakedepth, shadowbias
|
/*static*/ float[] modelParams6 = new float[]{0, 0, 0, 0}; // bump, noise, borderfade, fog punchthrough
|
/*static*/ float[] modelParams7 = new float[]{0, 0, 0, 0}; // noise power, opacity power, parallax
|
|
//Object3D.cVector2[] vector2buffer;
|
|
// IN : ndotl, ndoth, xxx, NdotL //, snininess, lightarea
|
// OUT : diff, spec
|
String Model(String dest, String src)
|
{
|
return //"MOV " + dest + "," + src + ";" +
|
//"RCP " + src + ".w," + src + ".w;" +
|
//"LIT " + dest + "," + dest + ";" +
|
//"MOV " + dest + "," + dest + ".yzxw;";
|
/**/ "MAX " + dest + ".x," + src + ".w," + "zero.x;" +
|
// shininess = shininess/pow(edotn,velvet)
|
/**/
|
"DP3 " + dest + ".z," + "normals," + "eye;" +
|
"MAX " + dest + ".w," + dest + ".z," + "eps.x;" +
|
//"MOV " + dest + ".w," + "normal.z;" +
|
// "MUL " + dest + ".z," + "params2.w," + dest + ".x;" + // PRETTY HEURISTIC FOR VELVET
|
// "MUL " + dest + ".z," + dest + ".z," + dest + ".x;" +
|
|
"MOV " + dest + ".z," + "params2.w;" + // EXACT
|
"POW " + dest + ".w," + dest + ".w," + dest + ".z;" +
|
"RCP " + dest + ".w," + dest + ".w;" +
|
//"RSQ " + dest + ".w," + dest + ".w;" +
|
"MUL " + src + ".z," + "shininess.z," + dest + ".w;" +
|
//"MUL " + src + ".z," + "texSamp.x," + src + ".z;" + //
|
/**/
|
//"MOV " + src + ".z," + "params1.z;" +
|
|
// ndotl
|
"MAX " + dest + ".x," + src + ".x," + "zero.x;" +
|
//-------------------
|
// DIFFUSE
|
|
/**/
|
// diff = ndotl + (1-ndotl)*ndotl^(shininess*factor/ndotl)
|
//"MUL " + dest + ".w," + src + ".z," + "params2.z;" +
|
"MUL " + dest + ".w," + "params2.z," + dest + ".w;" +
|
"POW " + dest + ".z," + dest + ".x," + "params4.z;" +
|
"RCP " + dest + ".z," + dest + ".z;" +
|
"MUL " + dest + ".w," + dest + ".z," + dest + ".w;" +
|
"MAX " + dest + ".w," + dest + ".w," + "one10th.x;" +
|
"POW " + dest + ".w," + dest + ".x," + dest + ".w;" +
|
"SUB " + dest + ".z," + "one.x," + dest + ".x;" +
|
//"MUL " + dest + ".z," + dest + ".z," + dest + ".w;" +
|
//"ADD " + dest + ".x," + dest + ".x," + dest + ".z;" +
|
"MAD " + dest + ".x," + dest + ".z," + dest + ".w," + dest + ".x;" +
|
/**/
|
/*
|
// diff = ndotl + sqrt(1-ndotl*ndotl)*ndotl^(shininess*factor)
|
"MUL " + dest + ".w," + src + ".z," + "params2.z;" +
|
"MAX " + dest + ".w," + dest + ".w," + "one10th.x;" +
|
"POW " + dest + ".w," + dest + ".x," + dest + ".w;" +
|
"MUL " + dest + ".z," + dest + ".x," + dest + ".x;" +
|
"SUB " + dest + ".z," + "one.x," + dest + ".z;" +
|
"RSQ " + dest + ".z," + dest + ".z;" +
|
"RCP " + dest + ".z," + dest + ".z;" +
|
"MUL " + dest + ".z," + dest + ".z," + dest + ".w;" +
|
"ADD " + dest + ".x," + dest + ".x," + dest + ".z;" +
|
/**/
|
//"MAX " + dest + ".x," + src + ".x," + "zero.x;" +
|
|
/*
|
"MAX " + dest + ".x," + src + ".x," + "eps.x;" +
|
//"SUB " + dest + ".x," + "one.x," + dest + ".x;" +
|
// tan = Math.pow(Math.sqrt(1-ndotl*ndotl) / ndotl / lightarea, 1/shininess);
|
"MAD " + dest + ".z," + dest + ".x," + dest + ".x," + "-one.x;" +
|
"RSQ " + dest + ".z, -" + dest + ".z;" +
|
"MUL " + dest + ".x," + dest + ".x," + src + ".w;" +
|
"MUL " + dest + ".x," + dest + ".z," + dest + ".x;" +
|
"RCP " + dest + ".x," + dest + ".x;" +
|
"RCP " + dest + ".z," + src + ".z;" +
|
"POW " + dest + ".x," + dest + ".x," + dest + ".z;" +
|
"SUB " + dest + ".x," + "one.x," + dest + ".x;" +
|
// diff = Math.exp(-tan * tan / 2);
|
"MUL " + dest + ".x," + dest + ".x," + dest + ".x;" +
|
"MUL " + dest + ".x," + dest + ".x," + "-half.x;" +
|
"POW " + dest + ".x," + "E.x," + dest + ".x;" +
|
// diff = (1-ndotl)*diff + ndotl
|
"MAX " + dest + ".z," + src + ".x," + "eps.x;" +
|
"SUB " + dest + ".z," + "one.x," + dest + ".z;" +
|
"MUL " + dest + ".x," + dest + ".x," + dest + ".z;" +
|
"SUB " + dest + ".z," + "one.x," + dest + ".z;" +
|
"ADD " + dest + ".x," + dest + ".z," + dest + ".x;" +
|
*/
|
//-------------------
|
// SPECULAR
|
|
// ndoth = Math.sqrt((ndoth + 1) / 2);
|
//"ADD " + dest + ".y," + src + ".y," + "one.x;" +
|
//"MUL " + dest + ".y," + dest + ".y," + "half.x;" +
|
//"RSQ " + dest + ".y," + dest + ".y;" +
|
//"RCP " + dest + ".y," + dest + ".y;" +
|
"MAX " + dest + ".y," + src + ".y," + "eps.x;" +
|
// ndoth = 1 - (ndoth - 1/p)
|
"RCP " + dest + ".z," + "params1.w;" +
|
"SUB " + dest + ".z," + dest + ".y," + dest + ".z;" +
|
"SUB " + dest + ".z," + "one.x," + dest + ".z;" +
|
"MUL " + dest + ".y," + dest + ".y," + "params1.w;" +
|
"CMP " + dest + ".y," + dest + ".z," + dest + ".y," + dest + ".z;" +
|
// tan = Math.pow(Math.sqrt(1-ndoth*ndoth) / ndoth / lightarea, shininess);
|
"MAD " + dest + ".z," + dest + ".y," + dest + ".y," + "-one.x;" +
|
"RSQ " + dest + ".z, -" + dest + ".z;" +
|
"MUL " + dest + ".y," + dest + ".y," + "params2.y;" +
|
"MUL " + dest + ".z," + dest + ".z," + dest + ".y;" +
|
"RCP " + dest + ".z," + dest + ".z;" +
|
//"RCP " + dest + ".y," + src + ".z;" +
|
"POW " + dest + ".z," + dest + ".z," + src + ".z;" +
|
// spec = pow(2, -tan * tan / 2);
|
"MUL " + dest + ".z," + dest + ".z," + dest + ".z;" +
|
"MUL " + dest + ".z," + dest + ".z," + "-half.x;" +
|
"POW " + dest + ".y," + "two.x," + dest + ".z;" +
|
// shadow = 2 * ndoth * ndotl / edoth;
|
// if (shadow < geo) geo = shadow;
|
"MUL " + dest + ".w," + src + ".w," + src + ".y;" +
|
"MUL " + dest + ".w," + dest + ".w," + "two.x;" +
|
"DP3 " + dest + ".z," + "H," + "eye;" +
|
//"MOV " + dest + ".z," + "H.z;" +
|
//"MAX " + dest + ".z," + "eps.x," + "H.z;" +
|
"RCP " + dest + ".z," + dest + ".z;" +
|
"MUL " + dest + ".w," + dest + ".w," + dest + ".z;" +
|
"MIN " + dest + ".w," + dest + ".w," + "one.x;" +
|
// geo = 1 - sqrt(1 - geo)
|
"SUB " + dest + ".w," + "one.x," + dest + ".w;" +
|
"MUL " + dest + ".w," + dest + ".w," + dest + ".w;" +
|
//"MUL " + dest + ".w," + dest + ".w," + dest + ".w;" +
|
//"RCP " + dest + ".w," + dest + ".w;" +
|
"SUB " + dest + ".w," + "one.x," + dest + ".w;" +
|
// spec * geo
|
"MUL " + dest + ".y," + dest + ".y," + dest + ".w;" +
|
// TEST
|
"DP3 " + dest + ".z," + "normals," + "eye;" +
|
"MAX " + dest + ".w," + dest + ".z," + "shadoweps.z;" +
|
"RCP " + dest + ".w," + dest + ".w;" +
|
"MUL " + dest + ".y," + dest + ".y," + dest + ".w;";
|
/**/
|
}
|
|
String Normalize(String v)
|
{
|
String t = v;
|
return "DP3 " + t + ".w," + v + "," + v + ";" +
|
"RSQ " + t + ".w," + t + ".w;" +
|
"MUL " + v + ".xyz," + v + "," + t + ".w;" /* +
|
"MOV " + v + ".w," + "one.x;"*/;
|
}
|
|
private void InitVertexProgram(GL gl, int mode) // , int displayListID)
|
{
|
int[] tmpInt = new int[1];
|
gl.glGenProgramsARB(1, tmpInt, 0);
|
vertexProgram[mode] = tmpInt[0];
|
gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vertexProgram[mode]);
|
|
String programBuffer =
|
"!!ARBvp1.0\n" +
|
"# Parameters\n" +
|
"PARAM cam2light0 = program.env[0];" +
|
"PARAM cam2light1 = program.env[1];" +
|
"PARAM cam2light2 = program.env[2];" +
|
"PARAM cam2light3 = program.env[3];" +
|
//"PARAM mvp[4] = { state.matrix.mvp }; # modelview projection matrix\n" +
|
"PARAM mv[4] = { state.matrix.modelview }; # modelview projection matrix\n" +
|
"PARAM p[4] = { state.matrix.projection }; # modelview projection matrix\n" +
|
"PARAM zero = { 0.0, 0.0, 0.0, 1.0 };" +
|
"PARAM half = { 0.5, 0.5, 0.5, 1.0 };" +
|
"PARAM one = { 1.0, 1.0, 1.0, 1.0 };" +
|
"PARAM two = { 2.0, 2.0, 2.0, 1.0 };" +
|
"PARAM third = { 0.33333333333, 0.33333333333, 0.33333333333, 1.0 };" +
|
//"PARAM v256 = { 256.0, 256.0, 256.0, 1.0 };" +
|
"PARAM scale = { 2, 0.5, 0.5, 1.0 };" +
|
"TEMP ipos;" +
|
"TEMP temp;" +
|
"TEMP temp2;" +
|
"TEMP depth;" +
|
"\n" +
|
//"# Addresses\n" +
|
//"ADDRESS addr;" +
|
//"\n" +
|
"# Per vertex inputs\n" +
|
"ATTRIB iPos = vertex.position; #position\n" +
|
"\n" +
|
"# Outputs\n" +
|
"OUTPUT oPos = result.position; #position\n" +
|
"\n" +
|
"# Transform vertex-position to clip-space\n" +
|
"MOV ipos, iPos;" +
|
"MOV ipos.w, one.x;" +
|
"DP4 temp.x, ipos, mv[0];" +
|
"DP4 temp.y, ipos, mv[1];" +
|
"DP4 temp.z, ipos, mv[2];" +
|
"DP4 temp.w, ipos, mv[3];" +
|
(SPHERICAL && (mode & VP_PROJECTION) != 0 ? // spherical projection
|
"DP3 depth.x, temp, temp;" +
|
"RSQ depth.x, depth.x;" +
|
//"MUL depth.y, scale.x, depth.x;" +
|
"MUL temp.x, temp.x, depth.x;" +
|
"MUL temp.y, temp.y, depth.x;" +
|
//"CMP depth.z, temp.z, -depth.x, depth.x;" +
|
"SLT depth.z, temp.z, zero.x;" +
|
//"MUL depth.z, depth.z, two.x;" +
|
//"SUB depth.z, depth.z, one.x;" +
|
"RCP depth.x, depth.x;" +
|
"MUL depth.x, depth.x, -depth.z;" +
|
"MOV temp.z, zero.x;" +
|
"DP3 depth.z, temp, temp;" +
|
"SUB depth.z, one.x, depth.z;" +
|
"RSQ depth.z, depth.z;" +
|
"RCP depth.z, depth.z;" +
|
"MUL depth.x, depth.x, depth.z;" +
|
"MUL temp.x, temp.x, scale.x;" +
|
"MUL temp.y, temp.y, scale.x;" +
|
"MOV temp.z, depth.x;" +
|
//"SUB temp.z, temp.z, half.x;" +
|
"MOV temp.w, one.x;"
|
: "") +
|
/**/
|
"MOV temp2, temp;" +
|
"DP4 temp.x, temp2, p[0];" +
|
"DP4 temp.y, temp2, p[1];" +
|
"DP4 temp.z, temp2, p[2];" +
|
"DP4 temp.w, temp2, p[3];" /**/ //)
|
+
|
"MOV oPos, temp;" +
|
"DP4 temp.x,state.matrix.texture[0].inverse.row[0],vertex.texcoord;" +
|
"DP4 temp.y,state.matrix.texture[0].inverse.row[1],vertex.texcoord;" +
|
"DP4 temp.z,state.matrix.texture[0].inverse.row[2],vertex.texcoord;" +
|
//"MOV result.texcoord, vertex.fogcoord;" +
|
"MOV result.texcoord, temp;" +
|
// border fade
|
"MOV result.texcoord[3], vertex.texcoord;" +
|
((mode & VP_PASS) != 0 ? // light distance
|
"DP4 temp.x, ipos, mv[0];" +
|
"DP4 temp.y, ipos, mv[1];" +
|
"DP4 temp.z, ipos, mv[2];" +
|
"DP4 temp.w, ipos, mv[3];" +
|
//"MOV temp.w, one.x;" +
|
"DP4 depth.x, temp, cam2light0;" +
|
"DP4 depth.y, temp, cam2light1;" +
|
"DP4 depth.z, temp, cam2light2;" +
|
/**/
|
"DP4 depth.w, temp, cam2light3;" +
|
"RCP depth.w, depth.w;" +
|
"MUL depth.z, depth.z, depth.w;" +
|
"MUL depth.y, depth.y, depth.w;" +
|
"MUL depth.x, depth.x, depth.w;" +
|
/**/
|
/*
|
"MUL depth.x, depth.x, half.x;" +
|
"MUL depth.y, depth.y, half.x;" +
|
"MUL depth.z, depth.z, half.x;" +
|
"ADD depth.x, depth.x, half.x;" +
|
"ADD depth.y, depth.y, half.x;" +
|
"ADD depth.z, depth.z, half.x;" +
|
/**/
|
"MOV result.texcoord[1], depth;" +
|
"MOV result.texcoord[2], vertex.color;" +
|
"MOV temp, vertex.normal;" +
|
//"MOV temp, vertex.position;" +
|
/**/
|
Normalize("temp") +
|
"DP3 temp.x,state.matrix.modelview.invtrans.row[0],vertex.normal;" +
|
"DP3 temp.y,state.matrix.modelview.invtrans.row[1],vertex.normal;" +
|
"DP3 temp.z,state.matrix.modelview.invtrans.row[2],vertex.normal;" +
|
Normalize("temp") +
|
"ADD temp, temp, one;" +
|
"MUL temp, temp, half;" +
|
/**/
|
//"TEX temp, vertex.texcoord, texture[0], 2D;" +
|
//"ADD oPos, vertex.normal;" +
|
//"MOV temp, vertex.normal;" +
|
|
//"ADD temp.z, temp.z, one;" +
|
|
"MOV result.texcoord[4], vertex.attrib[4];" + // U dir
|
|
"MOV result.color, temp;" // Normal
|
: "MOV result.color, vertex.color;") +
|
((mode & VP_PROJECTION) != 0 ? "MOV result.color, zero;"
|
: "") +
|
/*
|
"ADD temp.x, vertex.color.x, vertex.color.y;" +
|
"ADD temp.x, temp.x, vertex.color.z;" +
|
"MUL temp.x, temp.x, third.x;" +
|
"MOV result.color.w, temp.x;" +
|
/**/
|
// Vertex colors
|
/* doesn't work!
|
"MOV temp.z, vertex.color.z;" +
|
"MUL temp.z, temp.z, v256.x;" +
|
"FLR temp.x, temp.z;" +
|
"MOV temp.z, vertex.color.y;" +
|
"MUL temp.z, temp.z, v256.x;" +
|
"FLR temp.y, temp.z;" +
|
"MUL temp.x, temp.x, v256.x;" +
|
"ADD temp.x, temp.x, temp.y;" +
|
"ADD temp.x, temp.x, vertex.color.x;" +
|
//"MUL temp.x, temp.x, v255.x;" +
|
"MOV result.color.w, temp.x;" +
|
*/
|
//"MOV result.color, vertex.color;" + //
|
|
"\n" +
|
"END\n";
|
|
// set up constants (not currently used in the vertex program, though)
|
|
//float[] rCVConsts = new float[] { 0, 0.5f, 1.0f, 2.0f };
|
//gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_CONSTS_1, rCVConsts, 0);
|
|
loadProgram(gl, GL.GL_VERTEX_PROGRAM_ARB, programBuffer);
|
}
|
|
private double mDistribution0(double ndoth, float pDiffuseness, float pShininess)
|
{
|
ndoth = Math.sqrt((ndoth + 1) / 2);
|
|
/**/
|
double shiny = pShininess; // Math.pow(3, 4*pShininess - 2);
|
double diff = 0.1; // Math.pow(6, 4*pDiffuseness - 2);
|
|
double ltan = Math.pow(Math.sqrt(1 - ndoth * ndoth) / ndoth / diff, shiny);
|
|
double dist = Math.exp(-ltan * ltan / 2);
|
|
double lweight = 1; // Math.pow(ndoth, 1);
|
|
return dist * lweight + (1 - lweight);
|
/**/
|
|
// Beckmann
|
//double ltan = Math.sqrt(1-cos*cos) / cos;
|
//return Math.exp(-ltan * ltan * pShininess) * pShininess / (4 * cos * cos * cos * cos);
|
}
|
|
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
|
{
|
GL gl = drawable.getGL();
|
|
System.out.println("DISPLAYCHANGED GL IS: " + gl.getClass().getName());
|
}
|
static java.util.Hashtable<Integer, Integer> availist = new java.util.Hashtable<Integer, Integer>();
|
|
static public void RemoveList(int list)
|
{
|
if (list == -1 || list == 0 /*serial issue*/)
|
{
|
return;
|
}
|
|
//System.out.println("Remove list : " + list); new Exception().printStackTrace();
|
Integer key = new Integer(list);
|
// Object obj;
|
// if ((obj = availist.get(key)) == null)
|
// {
|
// System.out.println("ASSERT FAILED: RemoveList");
|
// // new Exception().printStackTrace();
|
// return;
|
// }
|
//
|
// int val = ((Integer) obj).intValue();
|
|
// System.err.println("To be deleted: " + list);
|
|
availist.put(key, key); // new Integer(val - 1));
|
}
|
|
static public void AddDuplicate(int list)
|
{
|
if (list == -1)
|
{
|
return;
|
}
|
|
Integer key = new Integer(list);
|
Object obj = availist.get(key);
|
if (obj == null)
|
{
|
availist.put(key, key); // new Integer(1));
|
} else
|
{
|
int val = ((Integer) obj).intValue();
|
|
availist.put(key, new Integer(val + 1));
|
}
|
}
|
|
///////////////////////
|
static class Size
|
{
|
|
int w, h;
|
|
public int hashCode()
|
{
|
return (w * 31) ^ (h * 17);
|
}
|
|
public boolean equals(Object o)
|
{
|
Size size = (Size) o;
|
return size.w == w && size.h == h;
|
}
|
}
|
|
Size sizetest = new Size();
|
Hashtable imageTable = new Hashtable();
|
|
public void mouseClicked(MouseEvent e)
|
{
|
System.out.println("mouseClicked: " + e);
|
}
|
|
public void mousePressed(MouseEvent e)
|
{
|
//System.out.println("mousePressed: " + e);
|
clickStart(e.getX(), e.getY(), e.getModifiers(), e.getModifiersEx());
|
}
|
|
static long prevtime = 0;
|
|
javax.swing.Timer wheeltimer = new javax.swing.Timer(750, this);
|
boolean keepboxmode;
|
boolean keepsupport;
|
|
public void mouseWheelMoved(MouseWheelEvent e)
|
// Invoked when the mouse wheel is rotated.
|
{
|
// LIVE = waslive; // hmmm
|
// TENTATIVE POUR DEALER AVEC LA CRISS DE SOURIS
|
long curtime = System.currentTimeMillis();
|
|
if (prevtime == 0)
|
prevtime = curtime;
|
|
long Dtime = (curtime - prevtime);
|
|
prevtime = curtime;
|
|
float ratio = (float)e.getUnitsToScroll()/Dtime;
|
|
//System.err.println("Dtime = " + Dtime + "; units = " + e.getUnitsToScroll() + "; ratio (units/ms) = " + ratio);
|
|
if (BUTTONLESSWHEEL)
|
if (Math.abs(ratio) < 0.1 || Math.abs(Dtime) == 0) // < 30)
|
{
|
return;
|
}
|
|
//boolean capsLocked = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
|
|
boolean vr = capsLocked && !lightMode;
|
|
// TIMER
|
if (ZOOMBOXMODE && !wheeltimer.isRunning() && e.getModifiersEx() == 0 && !vr) // VR
|
{
|
keepboxmode = BOXMODE;
|
keepsupport = SUPPORT;
|
|
BOXMODE = true;
|
SUPPORT = false;
|
|
wheeltimer.restart();
|
}
|
|
//System.out.println("getScrollType: " + e.getScrollType());
|
//System.out.println("getScrollAmount: " + e.getScrollAmount());
|
//System.out.println("getWheelRotation: " + e.getWheelRotation());
|
//System.out.println("getUnitsToScroll: " + e.getUnitsToScroll());
|
//clickStart(e.getX(), e.getY(), e.getModifiersEx());
|
int keepm = MODIFIERS;
|
int x = X;
|
int y = Y;
|
int keepmode = mouseMode;
|
int px = prevX;
|
int py = prevY;
|
int ax = anchorX;
|
int ay = anchorY;
|
MODIFIERS &= ~COMMAND;
|
mouseMode = 0; // autorepeat
|
tmp.set(targetLookAt);
|
tmp.sub(manipCamera.lookAt);
|
if (manipCamera.hAspect == 0)
|
{
|
manipCamera.lookAt.add(tmp);
|
manipCamera.location.add(tmp);
|
manipCamera.computeTransform();
|
}
|
// int mode = WHEEL;
|
// if (e.metaDown())
|
// {
|
// mode |= META;
|
//}
|
|
SetMouseMode(e.getModifiers(), WHEEL | e.getModifiersEx());
|
drag(anchorX, anchorY + e.getUnitsToScroll()*8, 0, 0);
|
anchorX = ax;
|
anchorY = ay;
|
prevX = px;
|
prevY = py;
|
MODIFIERS = keepm;
|
X = x;
|
Y = y;
|
mouseMode = keepmode;
|
}
|
|
int selectX, selectY;
|
boolean clicked = false;
|
boolean hold = false;
|
boolean forcetranslate = false;
|
boolean mouseDown = false;
|
|
public void actionPerformed(ActionEvent evt)
|
{
|
if (evt.getSource() == wheeltimer)
|
{
|
if (!CameraPane.movingcamera)
|
{
|
BOXMODE = keepboxmode;
|
SUPPORT = keepsupport;
|
wheeltimer.stop();
|
repaint();
|
}
|
else
|
wheeltimer.restart();
|
}
|
else
|
if (evt.getSource() == AAtimer)
|
{
|
Globals.TIMERRUNNING = false;
|
if (mouseDown)
|
{
|
//new Exception().printStackTrace();
|
} else
|
{
|
//System.out.println("STOP UP " + clicked + " " + niceon + " " + hold + " " + evt.getSource());
|
if (!clicked)
|
{
|
niceon = true;
|
clicked = false;
|
if (CURRENTANTIALIAS == 0)
|
{
|
//System.out.println("WRONG TIMER: clicked = " + clicked + " niceon = " + niceon + " hold = " + hold + " " + evt.getSource());
|
} else
|
{
|
repaint();
|
}
|
}
|
}
|
} else
|
{
|
assert(evt.getSource() == timer);
|
// LIVE = waslive;
|
// wasliveok = true;
|
// waslive = false;
|
|
// May 2019 Forget it:
|
if (true)
|
return;
|
|
// source == timer
|
if (mouseDown)
|
{
|
//System.out.println("STOP DOWN");
|
if (!clicked)
|
{
|
return;
|
}
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
hold = true;
|
//clicked = false;
|
} else
|
{
|
}
|
}
|
}
|
|
static boolean waslive = false;
|
boolean wasliveok = true;
|
|
public void repaint() // may 2014 () // 2()
|
{
|
if (isRenderer)
|
{
|
// new Exception().printStackTrace();
|
// ObjEditor.tweenManager.update(1f / 60f);
|
|
// fev 2014???
|
if ((TRACK || SHADOWTRACK) && trackedobject != null) // && DrawMode() == SHADOW) // && !lightMode)
|
object.GetWindow().ScreenFit(trackedobject, SHADOWTRACK && !TRACK);
|
pingthread.StepToTarget(true); // true);
|
}
|
// if (!LIVE)
|
super.repaint();
|
}
|
|
javax.swing.Timer timer = new javax.swing.Timer(350, this);
|
|
void clickStart(int x, int y, int modifiers, int modifiersex)
|
{
|
if (!wasliveok)
|
return;
|
|
AAtimer.restart(); //
|
Globals.TIMERRUNNING = true;
|
|
// waslive = LIVE;
|
// LIVE = false;
|
// wasliveok = false;
|
|
//System.out.println("clickStart = " + mouseMode);
|
MODIFIERS = 0;
|
mouseDown = true;
|
// touched = true; // main DL
|
if (isRenderer)
|
{
|
SetMouseMode(modifiers, modifiersex);
|
}
|
|
selectX = anchorX = x;
|
selectY = anchorY = y;
|
|
//long time = System.currentTimeMillis();
|
//System.out.println("Delay time = " + (time - time0));
|
//time0 = time;
|
|
clicked = true;
|
hold = false;
|
|
if (((modifiersex & ~1024) & ~0) == 0) // Single or multiple selection
|
// june 2013 means CTRL_CLICK: if (((modifiers & ~1024) & ~128) == 0) // Single or multiple selection
|
{
|
// System.out.println("RESTART II " + modifiers);
|
//timer.setDelay(IsFrozen()?0:350);
|
// timer.setDelay(((modifiers & ~128) == 0)?0:350);
|
timer.restart();
|
}
|
|
if (isRenderer || mouseMode != 0)
|
{
|
marqX = x;
|
marqY = y;
|
if (drag)
|
{
|
drag = false;
|
// assert (false);
|
repaint();
|
}
|
} else
|
{
|
locked = true;
|
drag = false;
|
//System.out.println("Mouse DOWN");
|
editObj = false;
|
//ClickInfo info = new ClickInfo();
|
object.clickInfo.bounds.setBounds(0, 0, (int) (getBounds().width * zoom), (int) (getBounds().height * zoom));
|
object.clickInfo.pane = this;
|
object.clickInfo.camera = renderCamera;
|
object.clickInfo.x = x;
|
object.clickInfo.y = y;
|
object.clickInfo.modifiers = modifiersex;
|
editObj = object.doEditClick(//info,
|
0);
|
if (!editObj)
|
{
|
hasMarquee = true;
|
firstime = true;
|
marqX = startX = x;
|
marqY = startY = y;
|
marqW = marqH = 0;
|
}
|
}
|
}
|
|
static boolean movingcamera = false;
|
|
public void mouseDragged(MouseEvent e)
|
{
|
Globals.MOUSEDRAGGED = true;
|
|
//System.out.println("mouseDragged: " + e);
|
if (isRenderer)
|
movingcamera = true;
|
|
//if (drawing)
|
//return;
|
if ((e.getModifiersEx() & CTRL) != 0 ||
|
(e.getModifiersEx() & COMMAND) != 0) // || IsFrozen())
|
{
|
//System.out.println("mouseDragged: " + e);
|
clickEnd(e.getX(), e.getY(), e.getModifiersEx());
|
}
|
else
|
drag(e.getX(), e.getY(), e.getModifiers(), e.getModifiersEx());
|
|
//try { Thread.sleep(1); } catch (Exception ex) {}
|
}
|
|
cVector[] targetLookAts;
|
cVector[] lightLookAts;
|
cVector targetLookAt; // = new cVector();
|
cVector lightLookAt = new cVector(); // june 2014
|
cVector tmp = new cVector();
|
cVector tmp2 = new cVector();
|
boolean isMoving;
|
|
public cVector TargetLookAt()
|
{
|
return targetLookAt;
|
}
|
|
class PingThread extends Thread
|
{
|
boolean jump;
|
|
boolean mute;
|
|
// void JumpToTarget()
|
// {
|
// StepToTarget(true);
|
// }
|
|
void StepToTarget()
|
{
|
StepToTarget(jump);
|
jump = false; // only once
|
}
|
|
// only one thread!? synchronized
|
void StepToTarget(boolean jump)
|
{
|
if (mute)
|
return;
|
|
tmp.set(targetLookAt);
|
tmp.sub(manipCamera.lookAt); // june 2014
|
|
Camera parentcam = manipCamera;
|
|
if (manipCamera == cameras[0])
|
{
|
parentcam = cameras[1];
|
}
|
|
if (manipCamera == cameras[1])
|
{
|
parentcam = cameras[0];
|
}
|
|
|
//assert (parentcam != manipCamera);
|
if (parentcam == manipCamera) // probably the light
|
return;
|
|
// june 2014
|
// for (int count = parentcam.GetTransformCount(); --count>=0;)
|
// LA.xformPos(tmp, parentcam.toParent, tmp);
|
|
// tmp.sub(manipCamera.lookAt);
|
|
//System.out.println("V = " + tmp);
|
if (true) // !TRACK)
|
{
|
isMoving = true;
|
double step = 0.05; // .01; // 5; // 0.25;
|
|
if (FAST)
|
jump = true; // step = 1;
|
|
if (tmp.dot(tmp) > 1) // may 2014. far away: jump to target
|
{
|
jump = true; // step = 1;
|
}
|
|
if (OEILONCE && OEIL)
|
{
|
jump = true; // step = 1;
|
}
|
|
if (TRACKONCE && TRACK)
|
{
|
jump = true; // step = 1;
|
}
|
|
double factor = 1;
|
|
if (jump || !SMOOTHFOCUS || (MODIFIERS & COMMAND) == COMMAND)
|
// Jump to target because continuous drag
|
// will reset the point
|
{
|
step = 1;
|
}
|
else
|
{
|
if (CameraPane.AntialiasingEnabled())
|
factor = 1.0/CameraPane.ACSIZE;
|
}
|
|
double step2 = 0; // ?? Math.exp(-tmp.length() * 10);
|
|
step *= factor;
|
step2 *= factor;
|
|
if (tmp.dot(tmp) < 0.00001)
|
{
|
zoomonce = false;
|
}
|
|
tmp.mul(step > step2 ? step : step2);
|
}
|
else
|
{
|
if (!OEIL)
|
{
|
tmp2.set(manipCamera.lookAt);
|
tmp2.sub(manipCamera.location);
|
|
double distance = tmp2.length();
|
|
tmp.set(targetLookAt);
|
tmp.sub(manipCamera.location);
|
|
tmp.normalize();
|
tmp.mul(distance);
|
tmp.add(manipCamera.location);
|
tmp.sub(manipCamera.lookAt);
|
}
|
}
|
|
if (manipCamera.hAspect == 0)
|
{
|
if (LOOKAT)
|
manipCamera.lookAt.add(tmp);
|
if (OEIL && !capsLocked)
|
manipCamera.location.add(tmp);
|
|
{
|
// fev 2014 : track light too
|
if (/*TRACK &&*/ SHADOWTRACK && (jitter == 0)) // || TRACKONCE))
|
{
|
tmp.set(lightLookAt);
|
tmp.sub(lightCamera.lookAt);
|
//System.out.println(lightCamera + " ---------- Light " + tmp.length2());
|
lightCamera.lookAt.add(tmp);
|
lightCamera.location.add(tmp);
|
lightCamera.computeTransform();
|
}
|
}
|
if (tmp.x != 0 || tmp.y != 0 || tmp.z != 0)
|
{
|
manipCamera.computeTransform();
|
}
|
}
|
// ?????? mouseDown = true;
|
//System.out.println("---------------- ---------- Paint " + tmp.length2());
|
if (lightMode)
|
{
|
Globals.lighttouched = true;
|
}
|
|
if (OEILONCE && OEIL)
|
{
|
//System.err.println("Oeil off");
|
OEIL = false;
|
}
|
if (TRACKONCE && TRACK)
|
{
|
//System.err.println("Track off");
|
TRACK = false;
|
}
|
}
|
|
public void run()
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
for (;;)
|
{
|
try
|
{
|
sleep(1);; // 0); // 20);
|
} catch (Exception e)
|
{
|
}
|
;
|
if (currentlydrawing)
|
{
|
continue;
|
}
|
if (isRenderer)
|
{
|
tmp.set(targetLookAt);
|
tmp.sub(manipCamera.lookAt);
|
|
boolean alreadypainted = false;
|
|
if (tmp.length2() > 1E-6)
|
{
|
if (!TRACK)
|
{
|
ABORTED = true; // warning: script nodes are not notified
|
System.err.println("SET ABORTED (ping) ");
|
StepToTarget();
|
repaint();
|
alreadypainted = true;
|
}
|
}
|
// ???
|
else
|
{
|
if (isMoving)
|
{
|
//System.out.println("---------------- ---------- STOP!!");
|
mouseDown = false;
|
if (lightMode)
|
{
|
Globals.lighttouched = true;
|
}
|
repaint();
|
alreadypainted = true;
|
}
|
isMoving = false;
|
} //??
|
|
if (Globals.isLIVE() && !alreadypainted)
|
{
|
// FOR DEBUG BREAKPOINT USING PAUSE: while (true)
|
repaint();
|
}
|
//?? }
|
}
|
if (isRenderer && //(mode != 0 || mouseDown) &&
|
(MODIFIERS & COMMAND) == COMMAND)
|
{
|
if (lightMode)
|
{
|
Globals.lighttouched = true;
|
}
|
drag(X, (mouseMode != 0) ? Y : anchorY, 0, MODIFIERS);
|
}
|
//else
|
}
|
}
|
}
|
|
PingThread pingthread = new PingThread();
|
int delta = 1;
|
int speed = 1;
|
boolean autorepeat = false;
|
|
void GoDown(int mod)
|
{
|
MODIFIERS |= COMMAND;
|
boolean isVR = (mouseMode&VR)!=0;
|
/**/
|
if((mod&SHIFT) == SHIFT)
|
{
|
// if (isVR)
|
// manipCamera.RotateInterest(0, speed);
|
// else
|
manipCamera.Translate(0, -speed*delta, getWidth());
|
}
|
else
|
{
|
if (isVR)
|
manipCamera.BackForth(0, -speed*delta, isVR?1000:0); // getWidth());
|
else
|
manipCamera.RotatePosition(0, -speed);
|
}
|
|
/**/
|
// if ((mod & SHIFT) == SHIFT)
|
// {
|
// mouseMode = mouseMode; // VR??
|
// } else
|
// {
|
// mouseMode |= BACKFORTH;
|
// }
|
|
targetLookAt.set(manipCamera.lookAt);
|
|
//prevX = X = anchorX;
|
prevY = Y = anchorY - (int) (renderCamera.Distance());
|
}
|
|
void GoUp(int mod)
|
{
|
MODIFIERS |= COMMAND;
|
/**/
|
boolean isVR = (mouseMode&VR)!=0;
|
|
if((mod&SHIFT) == SHIFT)
|
{
|
// if (isVR)
|
// manipCamera.RotateInterest(0, -speed);
|
// else
|
manipCamera.Translate(0, speed*delta, getWidth());
|
}
|
else
|
{
|
if (isVR)
|
manipCamera.BackForth(0, speed*delta, isVR?1000:0); // getWidth());
|
else
|
manipCamera.RotatePosition(0, speed);
|
}
|
|
/**/
|
// if ((mod & SHIFT) == SHIFT)
|
// {
|
// mouseMode = mouseMode;
|
// } else
|
// {
|
// mouseMode |= BACKFORTH;
|
// }
|
|
targetLookAt.set(manipCamera.lookAt);
|
|
//prevX = X = anchorX;
|
prevY = Y = anchorY + (int) (renderCamera.Distance());
|
}
|
|
void GoLeft(int mod)
|
{
|
MODIFIERS |= COMMAND;
|
/**/
|
if((mod&SHIFT) == SHIFT)
|
manipCamera.Translate(speed*delta, 0, getWidth());
|
else
|
{
|
if ((mouseMode&VR)!=0)
|
manipCamera.RotateInterest(-speed, 0);
|
else
|
manipCamera.RotatePosition(speed, 0);
|
}
|
|
/**/
|
// if ((mod & SHIFT) == SHIFT)
|
// {
|
// mouseMode = mouseMode;
|
// } else
|
// {
|
// mouseMode |= ROTATE;
|
// } // TRANSLATE;
|
|
//System.err.println("lookAt = " + manipCamera.lookAt);
|
//System.err.println("location = " + manipCamera.location);
|
|
targetLookAt.set(manipCamera.lookAt);
|
|
prevX = X = anchorX - 10; // (int)(10*renderCamera.Distance());
|
prevY = Y = anchorY;
|
}
|
|
void GoRight(int mod)
|
{
|
MODIFIERS |= COMMAND;
|
/**/
|
if((mod&SHIFT) == SHIFT)
|
manipCamera.Translate(-speed*delta, 0, getWidth());
|
else
|
{
|
if ((mouseMode&VR)!=0)
|
manipCamera.RotateInterest(speed, 0);
|
else
|
manipCamera.RotatePosition(-speed, 0);
|
}
|
|
/**/
|
// if ((mod & SHIFT) == SHIFT)
|
// {
|
// mouseMode = mouseMode;
|
// } else
|
// {
|
// mouseMode |= ROTATE;
|
// } // TRANSLATE;
|
|
targetLookAt.set(manipCamera.lookAt);
|
|
prevX = X = anchorX + 10; // (int)(10*renderCamera.Distance());
|
prevY = Y = anchorY;
|
}
|
|
// Ping thread
|
int MODIFIERS;
|
int X, Y;
|
boolean SX, SY;
|
|
void drag(int x, int y, int modifiers, int modifiersex)
|
{
|
if (IsFrozen())
|
{
|
return;
|
}
|
|
drag = true; // NEW
|
|
boolean continuous = (modifiersex & COMMAND) == COMMAND;
|
|
X = x;
|
Y = y;
|
// floating state for animation
|
MODIFIERS = modifiersex;
|
modifiersex &= ~1024;
|
if (false) // modifiers != 0)
|
{
|
//new Exception().printStackTrace();
|
System.out.println("mouseDragged: " + modifiersex);
|
System.out.println("SHIFT = " + SHIFT);
|
System.out.println("CONTROL = " + COMMAND);
|
System.out.println("META = " + META);
|
}
|
clicked = false;
|
timer.stop();
|
StopAntialiaser();
|
if (!isRenderer && mouseMode == 0)
|
{
|
if (editObj)
|
{
|
drag = true;
|
//ClickInfo info = new ClickInfo();
|
object.clickInfo.bounds.setBounds(0, 0,
|
(int) (getBounds().width * zoom), (int) (getBounds().height * zoom));
|
object.clickInfo.pane = this;
|
object.clickInfo.camera = renderCamera;
|
object.clickInfo.x = x;
|
object.clickInfo.y = y;
|
object //.GetWindow().copy
|
.doEditDrag(//info,
|
(modifiers & MouseEvent.BUTTON3_MASK) != 0);
|
} else
|
{
|
if (x < startX)
|
{
|
marqX = x;
|
marqW = startX - x;
|
} else
|
{
|
marqX = startX;
|
marqW = x - startX;
|
}
|
if (y < startY)
|
{
|
marqY = y;
|
marqH = startY - y;
|
} else
|
{
|
marqY = startY;
|
marqH = y - startY;
|
}
|
}
|
|
//repaint();
|
} else
|
//if (mode > 0 || isRenderer)
|
{
|
//System.out.println("processMouseMotionEvent: " + mode);
|
|
if (hold)
|
{
|
hold = false;
|
forcetranslate = true;
|
//long time = System.currentTimeMillis();
|
//System.out.println("Click time = " + (time - time0));
|
//time0 = time;
|
//if (time - time0 > 250)
|
mouseMode |= TRANSLATE;
|
}
|
|
float dx = x - anchorX;
|
float dy = y - anchorY;
|
|
if (continuous)
|
{
|
dx /= 10;
|
if (mouseMode != 0)
|
{
|
dy /= 10;
|
}
|
|
if (x != prevX)
|
{
|
boolean sx = (x > prevX);
|
if (sx ^ SX)
|
{
|
anchorX = x; //dx = -dx; // 0
|
}
|
prevX = x;
|
SX = sx;
|
}
|
if (y != prevY)
|
{
|
boolean sy = (y > prevY);
|
if (sy ^ SY)
|
{
|
anchorY = y; //dy = -dy; // 0
|
}
|
prevY = y;
|
SY = sy;
|
}
|
}
|
|
if (mouseMode == 0 || (mouseMode & ROTATE) != 0)
|
{
|
// manipCamera.RotateInterest(dx, dy);
|
manipCamera.RotatePosition(dx, dy);
|
}
|
//else
|
{
|
if ((mouseMode & ZOOM) != 0)
|
{
|
//if ((mouseMode & BACKFORTH) != 0)
|
if ((mouseMode & VR) != 0)
|
manipCamera.BackForth(dx, dy, getWidth());
|
else
|
manipCamera.BackForth(dx, dy, 0);
|
}
|
if ((mouseMode & BACKFORTH) != 0)
|
{
|
if (manipCamera != lightCamera)
|
{
|
manipCamera.BackForth(dx, dy, getWidth());
|
} else
|
{
|
lightcolor.mul(Math.pow(1.1, -dy));
|
}
|
}
|
if ((mouseMode & TRANSLATE) != 0)
|
{
|
manipCamera.Translate(dx, dy, getWidth());
|
}
|
else
|
if ((mouseMode & ZOOM) == 0 && (mouseMode & VR) != 0)
|
{
|
manipCamera.RotateInterest(dx, dy);
|
}
|
}
|
|
targetLookAt.set(manipCamera.lookAt);
|
|
if (manipCamera == lightCamera)
|
{
|
Globals.lighttouched = true;
|
}
|
/*
|
switch (mode)
|
{
|
case ROTATE: camera.RotatePosition(dx, dy); break;
|
case BACKFORTH: camera.BackForth(dx, dy); break;
|
case TRANSLATE: camera.Translate(dx, dy, getWidth()); break;
|
case VR: camera.RotateInterest(dx, dy); break;
|
default: break;
|
}
|
*/
|
|
if (!continuous)
|
{
|
anchorX = x;
|
anchorY = y;
|
} else if (mouseMode == 0)
|
{
|
anchorY = y;
|
}
|
|
//repaint();
|
}
|
|
if (isRenderer)
|
{
|
repaint();
|
} else
|
{
|
//System.out.println("OBJECT = " + object);
|
//?? object.applySelf();
|
object.refreshEditWindow();
|
}
|
}
|
|
// ClickInfo clickInfo = new ClickInfo();
|
|
public void mouseMoved(MouseEvent e)
|
{
|
//object.editWindow.frame.
|
setCursor(Cursor.getDefaultCursor());
|
|
//System.out.println("mouseMoved: " + e);
|
if (isRenderer)
|
return;
|
|
// Mouse cursor feedback
|
object.clickInfo.x = e.getX();
|
object.clickInfo.y = e.getY();
|
object.clickInfo.modifiers = e.getModifiersEx();
|
object.clickInfo.bounds.setBounds(0, 0, (int) (getBounds().width * zoom), (int) (getBounds().height * zoom));
|
object.clickInfo.pane = this;
|
object.clickInfo.camera = renderCamera;
|
if (!isRenderer)
|
{
|
//ObjEditor editWindow = object.editWindow;
|
//Object3D copy = editWindow.copy;
|
if (object.doEditClick(//clickInfo,
|
0))
|
{
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
} else
|
{
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
}
|
}
|
}
|
|
public void mouseReleased(MouseEvent e)
|
{
|
Globals.MOUSEDRAGGED = false;
|
|
movingcamera = false;
|
X = 0; // getBounds().width/2;
|
Y = 0; // getBounds().height/2;
|
//System.out.println("mouseReleased: " + e);
|
clickEnd(e.getX(), e.getY(), e.getModifiersEx());
|
}
|
|
void clickEnd(int x, int y, int modifiers)
|
{
|
clickEnd(x, y, modifiers, false);
|
}
|
|
void clickEnd(int x, int y, int modifiers, boolean timeout)
|
{
|
// System.out.println("clickEnd: " + modifiers);
|
|
// LIVE = waslive;
|
// wasliveok = true;
|
// waslive = false;
|
|
timeout |= hold || forcetranslate;
|
|
boolean control = ((modifiers & CTRL) != 0); // june 2013: for point selection
|
boolean command = ((modifiers & COMMAND) != 0); // june 2013: for multiple selection
|
|
// No delay if (control || command || IsFrozen())
|
timeout = true;
|
// ?? May 2019 else
|
// timer.setDelay((modifiers & 128) != 0?0:350);
|
mouseDown = false;
|
if (!control && !command) // june 2013
|
timer.restart(); // ???
|
hold = false;
|
//clicked = false;
|
forcetranslate = false;
|
// if (!control) // june 2013
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
int dx = x - selectX;
|
int dy = y - selectY;
|
|
if ((dx * dx + dy * dy <= 2 || control || command) && isRenderer && timeout)
|
{
|
marqX = x;
|
marqY = y;
|
|
selection = true;
|
|
if (control)
|
pointselection = true;
|
|
if (modifiers != 0)
|
{
|
// System.out.println("modifiers = " + modifiers);
|
}
|
deselect = (modifiers == 0); // || control;
|
//if (control)
|
//{
|
// selectX = x;
|
// selectY = y;
|
//}
|
drag = false;
|
// System.out.println("select... = " + modifiers);
|
display();
|
//repaint();
|
return;
|
}
|
|
if (isRenderer || mouseMode != 0)
|
{
|
marqX = x;
|
marqY = y;
|
if (drag)
|
{
|
drag = false;
|
repaint();
|
}
|
} else
|
{
|
long time = System.currentTimeMillis();
|
//System.out.println("Click time = " + (time - time0));
|
time0 = time;
|
locked = false;
|
drag = false;
|
|
if (editObj)
|
{
|
object.refreshEditWindow();
|
//?? object.applySelf();
|
} else
|
{
|
hasMarquee = false;
|
/* No selection in small views
|
ClickInfo info = new ClickInfo();
|
info.bounds.setBounds(0, 0,
|
(int)(getBounds().width*zoom),
|
(int)(getBounds().height*zoom));
|
info.pane = this;
|
info.camera = renderCamera;
|
if (marqW == 0 && marqH == 0)
|
{
|
marqX -= 16; marqY -= 16;
|
marqW = 32; marqH = 32;
|
}
|
System.out.println("X = " + marqX + ", Y = " + marqY + "; W = " + marqW + ", H = " + marqH);
|
Rectangle r = new Rectangle(marqX, marqY, marqW, marqH);
|
object.doSelection(info, r, 0);
|
*/
|
repaint();
|
}
|
}
|
}
|
|
public void mouseEntered(MouseEvent e)
|
{
|
System.out.println("mouseEntered: " + e);
|
}
|
|
public void mouseExited(MouseEvent e)
|
{
|
System.out.println("mouseExited: " + e);
|
}
|
|
public void keyTyped(KeyEvent e)
|
{
|
System.out.println("keyTyped: " + e);
|
}
|
|
public void keyPressed(KeyEvent e)
|
{
|
System.out.println("keyPressed: " + e);
|
}
|
|
public void keyReleased(KeyEvent e)
|
{
|
System.out.println("keyReleased: " + e);
|
}
|
|
void SetMouseMode(int modifiers, int modifiersex)
|
{
|
//System.out.println("SetMouseMode = " + modifiers);
|
//modifiers &= ~1024;
|
//System.out.println("SetMode0 = " + modifiers);
|
if (!autorepeat)
|
{
|
mouseMode = 0;
|
} // (modifiers == 0) ? ROTATE : 0;
|
//if (modifiers == 0) // || (modifiers == (1024 | CONTROL)))
|
// return;
|
//System.out.println("SetMode = " + modifiers);
|
if ((modifiersex & WHEEL) == WHEEL)
|
{
|
mouseMode |= ZOOM;
|
}
|
|
//boolean capsLocked = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
|
boolean vr = capsLocked && !lightMode;
|
|
if (vr) // || (modifiers & META) == META)
|
{
|
mouseMode |= VR; // BACKFORTH;
|
}
|
if ((modifiersex & CTRLCLICK) == CTRLCLICK)
|
{
|
mouseMode |= SELECT;
|
}
|
if ((modifiersex & COMMAND) == COMMAND)
|
{
|
mouseMode |= SELECT;
|
}
|
if (//(modifiersex & SHIFT) == SHIFT ||
|
forcetranslate || (modifiers & MouseEvent.BUTTON3_MASK) != 0)
|
{
|
mouseMode &= ~VR;
|
mouseMode |= TRANSLATE;
|
}
|
// if ((modifiers & SHIFT_META) == SHIFT_META)
|
// {
|
// mouseMode /*|*/= VR;
|
// }
|
/*
|
switch (modifiers)
|
{
|
case CONTROL: mode = BACKFORTH; break;
|
case SHIFT: mode = TRANSLATE; break;
|
case SHIFT_CONTROL: mode = VR; break;
|
default: mode = ROTATE; break;
|
}
|
*/
|
}
|
|
void keyPressed(int key, int modifiers)
|
{
|
//if(!isRenderer)
|
// return;
|
|
//System.out.println("key = " + (char)key + " (" + key + ")");
|
|
if (isRenderer) //
|
{
|
SetMouseMode(0, modifiers);
|
}
|
|
Globals.theRenderer.keyPressed(key);
|
}
|
|
int kompactbit = 4; // power bit
|
int clampbit = 1; // filter bit
|
int maskbit = 4;
|
int loopbit = 2;
|
|
float HUEPOW = 1;
|
float SATPOW = 1; // 2; // 0.5f;
|
float BRIPOW = 1; // 0.5f; // 0.5f;
|
|
static BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
|
// Create a new blank cursor.
|
static Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
|
cursorImg, new Point(0, 0), "blank cursor");
|
|
public void keyPressed(int key)
|
{
|
// Set the blank cursor to the JFrame.
|
//object.editWindow.frame.
|
setCursor(blankCursor);
|
|
if (key >= '0' && key <= '5')
|
clampbit = (key-'0');
|
|
if (key >= '6' && key <= '9')
|
maskbit = (key-'5');
|
|
switch (key)
|
{
|
/*
|
case 'V' :
|
case 'v' : Simplex.SOLID ^= true; object.retile(true); repaint(); break;
|
case 'S' :
|
case 's' : Simplex.SURFACE ^= true; object.retile(true); repaint(); break;
|
case 'B' :
|
case 'b' : Simplex.BOUNDARY ^= true; object.retile(true); repaint(); break;
|
*/
|
case 'h':
|
opacityhalo ^= true; programInitialized = false;
|
repaint();
|
break;
|
case 'H':
|
HUESMOOTH ^= true;
|
break;
|
case 'F':
|
// BoundaryRep.remove3valence = true;
|
doublesided ^= true; programInitialized = false;
|
System.out.println("Double sided = " + doublesided);
|
repaint();
|
break;
|
case 'x':
|
anisotropy ^= true; programInitialized = false;
|
repaint();
|
break;
|
case 'S':
|
SATSMOOTH ^= true;
|
softshadow ^= true; programInitialized = false;
|
repaint();
|
break;
|
// case 'R':
|
// REDUCETEXTURE ^= true;
|
// //textures.clear();
|
// //repaint();
|
// break;
|
case 'T':
|
CACHETEXTURE ^= true;
|
texturepigment.clear();
|
texturebump.clear();
|
// repaint();
|
break;
|
case 'Y':
|
COMPRESSTEXTURE ^= true;
|
//textures.clear();
|
break;
|
case 'K':
|
KOMPACTTEXTURE ^= true;
|
//textures.clear();
|
// break;
|
//case 'P': // Texture Projection macros
|
// SAVETEXTURE ^= true;
|
macromode = true;
|
Udebug = Vdebug = NORMALdebug = false; programInitialized = false;
|
Udebug = true;
|
paint(graphics);
|
|
Udebug = Vdebug = NORMALdebug = false; programInitialized = false;
|
Vdebug = true;
|
paint(graphics);
|
|
Udebug = Vdebug = NORMALdebug = false; programInitialized = false;
|
NORMALdebug = true;
|
paint(graphics);
|
|
// show texture selection
|
IncDepth();
|
Udebug = Vdebug = NORMALdebug = false; programInitialized = false;
|
paint(graphics);
|
DecDepth();
|
macromode = false;
|
break;
|
case 't':
|
DISPLAYTEXT ^= true;
|
repaint();
|
break;
|
case 'A':
|
case 'a':
|
CURRENTANTIALIAS = ((CURRENTANTIALIAS != 0) ? 0 : 1);
|
System.out.println("Antialias ACSIZE = " + ACSIZE);
|
System.out.println("CURRENTANTIALIAS = " + CURRENTANTIALIAS);
|
repaint();
|
break;
|
case 'd':
|
loopbit += 2;
|
case 's':
|
if (loopbit > 0)
|
loopbit -= 1;
|
CURRENTANTIALIAS = ((CURRENTANTIALIAS != 0) ? ((CURRENTANTIALIAS != 2) ? 2 : 1) : 0);
|
if (key == 's' && ACSIZE > 1)
|
{
|
ACSIZE /= 4;
|
}
|
if (key == 'd' && ACSIZE < MAXACSIZE)
|
{
|
ACSIZE *= 4;
|
}
|
//ACSIZE *= (key=='s')?0.25:4;
|
System.out.println("Antialias = " + ACSIZE);
|
if (AntialiasingEnabled())
|
{
|
repaint();
|
}
|
break;
|
case 'B':
|
BRISMOOTH ^= true;
|
SHADOWCULLFACE ^= true;
|
Globals.lighttouched = true;
|
repaint();
|
break;
|
case 'b':
|
CULLFACE ^= true;
|
repaint();
|
break;
|
case 'n':
|
NEAREST ^= true;
|
repaint();
|
break;
|
case 'U' : MIPMAP ^= true;
|
repaint();
|
break;
|
case 'E' : COMPACT ^= true;
|
repaint();
|
break;
|
case 'W' : // Wide Window (fullscreen)
|
//DEBUGHSB ^= true;
|
ObjEditor.theFrame.ToggleFullScreen();
|
repaint();
|
break;
|
case 'u' : Udebug ^= true; Vdebug = false; NORMALdebug = false; programInitialized = false; repaint(); break;
|
case 'v' : Vdebug ^= true; Udebug = false; NORMALdebug = false; programInitialized = false; repaint(); break;
|
case 'N' : NORMALdebug ^= true; Udebug = false; Vdebug = false; programInitialized = false; repaint(); break;
|
//case 'u' : UVWRAP ^= true; /*object.Toggle(object.WIREFRAME);*/ repaint(); break;
|
case 'w' : WIREFRAME ^= true; /*object.Toggle(object.WIREFRAME);*/ repaint(); break;
|
/*
|
case 'F' :
|
case 'f' : object.Toggle(object.FILL); repaint(); break;
|
case 'C' :
|
case 'c' : object.Toggle(object.BACKFACE); repaint(); break;
|
*/
|
case 'c': cameraLight ^= true;
|
repaint();
|
break;
|
case 'C':
|
ResetCentroid(); // for 3ds models
|
repaint();
|
break;
|
case 'V':
|
RevertCamera();
|
repaint();
|
break;
|
//case 'l':
|
case 'L':
|
if (lightMode)
|
{
|
lightMode = false;
|
renderCamera = eyeCamera;
|
manipCamera = eyeCamera;
|
} else
|
{
|
if (renderCamera == eyeCamera)
|
{
|
manipCamera = (manipCamera == lightCamera) ? eyeCamera : lightCamera;
|
} else
|
{
|
manipCamera = renderCamera = eyeCamera;
|
}
|
}
|
targetLookAt.set(manipCamera.lookAt);
|
repaint();
|
break;
|
case 'P': // p':
|
// c'est quoi ca au juste? spherical ^= true;
|
Skinshader ^= true; programInitialized = false;
|
repaint();
|
break;
|
case 'D':
|
DEBUG_OCCLUSION ^= true;
|
repaint();
|
break;
|
case 'm':
|
{
|
//PrintMemory();
|
ToggleImageFlip();
|
break;
|
}
|
case 'M':
|
DEBUG_SELECTION ^= true;
|
repaint();
|
break;
|
case 'Q':
|
// OCCLUSIONBOOST *= 2;
|
// ZEROVALUES ^= true;
|
IQY ^= true;
|
repaint();
|
System.out.println("OCCLUSION BOOST = " + OCCLUSIONBOOST);
|
break;
|
case 'q':
|
// OCCLUSIONBOOST /= 2;
|
HUESHIFT ^= true;
|
// SATSHIFT ^= true;
|
repaint();
|
System.out.println("OCCLUSION BOOST = " + OCCLUSIONBOOST);
|
break;
|
case 'r':
|
ROTATECAMERA ^= true;
|
renderCamera.computeTransform();
|
repaint();
|
break;
|
case 'O':
|
// Too dangerous. Use menu. Globals.drawMode = OCCLUSION; // WARNING
|
//repaint();
|
//break;
|
case 'o':
|
OCCLUSION_CULLING ^= true;
|
System.out.println("OCCLUSION CULLING = " + OCCLUSION_CULLING);
|
break;
|
//case '0': envyoff ^= true; repaint(); break;
|
case '1':
|
case '2':
|
case '3':
|
case '4':
|
case '5':
|
case '6':
|
case '7':
|
case '8':
|
case '9':
|
if (true) // envyoff)
|
{
|
BGcolor = (key - '1')/8.f;
|
}
|
else
|
{
|
//newenvy = Character.getNumericValue(key);
|
}
|
repaint();
|
break;
|
case '!':
|
manipCamera.UP.x = 0;
|
manipCamera.UP.y = 0;
|
manipCamera.UP.z = 1;
|
manipCamera.computeTransform();
|
repaint();
|
break;
|
case '@':
|
manipCamera.UP.x = 0;
|
manipCamera.UP.y = 1;
|
manipCamera.UP.z = 0;
|
manipCamera.computeTransform();
|
repaint();
|
break;
|
case '#':
|
manipCamera.UP.x = 0;
|
manipCamera.UP.y = 1;
|
manipCamera.UP.z = 1;
|
manipCamera.computeTransform();
|
repaint();
|
break;
|
case '$':
|
manipCamera.UP.x = 1;
|
manipCamera.UP.y = 0;
|
manipCamera.UP.z = 0;
|
manipCamera.computeTransform();
|
repaint();
|
break;
|
case '%':
|
manipCamera.UP.x = 1;
|
manipCamera.UP.y = 0;
|
manipCamera.UP.z = 1;
|
manipCamera.computeTransform();
|
repaint();
|
break;
|
case '^':
|
// manipCamera.UP.x = 1;
|
// manipCamera.UP.y = 1;
|
// manipCamera.UP.z = 0;
|
// manipCamera.computeTransform();
|
// repaint();
|
kompactbit = 0;
|
break;
|
case '&':
|
// manipCamera.UP.x = 1;
|
// manipCamera.UP.y = 1;
|
// manipCamera.UP.z = 1;
|
// manipCamera.computeTransform();
|
// repaint();
|
kompactbit = 1;
|
break;
|
case '*':
|
kompactbit = 2;
|
break;
|
case '(':
|
kompactbit = 3;
|
break;
|
case ')':
|
kompactbit = 4;
|
break;
|
case '_':
|
kompactbit = 5;
|
break;
|
// case '+':
|
// kompactbit = 6;
|
// break;
|
case ' ':
|
capsLocked ^= true;
|
repaint();
|
break;
|
case 'l':
|
lightMode ^= true;
|
if (lightMode)
|
{
|
keepshadow = Globals.RENDERSHADOW;
|
Globals.RENDERSHADOW = false;
|
}
|
else
|
{
|
Globals.RENDERSHADOW = keepshadow;
|
}
|
|
Globals.lighttouched = true;
|
manipCamera = renderCamera = lightMode ? lightCamera : eyeCamera;
|
targetLookAt.set(manipCamera.lookAt);
|
repaint();
|
break;
|
//case '`' :
|
case ESC:
|
if (FULLSCREEN)
|
object.editWindow.ToggleFullScreen();
|
break;
|
case 'p':
|
RENDERPROGRAM += 1;
|
RENDERPROGRAM %= 3;
|
|
repaint();
|
break;
|
case 'Z':
|
//RESIZETEXTURE ^= true;
|
//break;
|
case 'z':
|
Globals.RENDERSHADOW ^= true;
|
Globals.lighttouched = true;
|
repaint();
|
break;
|
//case UP:
|
//case LEFT: SelectParent(); break;
|
//case DOWN:
|
//case RIGHT: SelectChildren(); break;
|
case 'G':
|
CLEANCACHE ^= true;
|
break;
|
case 'g':
|
System.out.println("Memory (F/T/M) : " + Runtime.getRuntime().freeMemory() + "/" + Runtime.getRuntime().totalMemory() + "/" + Runtime.getRuntime().maxMemory());
|
System.gc();
|
System.out.println("GC Memory (F/T/M) : " + Runtime.getRuntime().freeMemory() + "/" + Runtime.getRuntime().totalMemory() + "/" + Runtime.getRuntime().maxMemory());
|
break;
|
case 'i':
|
ResetTransform(2); // -1);
|
break;
|
case 'I':
|
CLAMPLOW ^= true;
|
ResetTransform(1);
|
break;
|
case 'f':
|
FlipTransform();
|
break;
|
case ENTER:
|
// object.editWindow.ScreenFit(); // Edit();
|
ToggleLive();
|
break;
|
case DELETE:
|
ClearSelection();
|
break;
|
case '+':
|
|
/*
|
//fontsize += 1;
|
bbzoom *= 2;
|
repaint();
|
break;
|
case '_':
|
//if(fontsize > 1) fontsize -= 1;
|
if (bbzoom > 1)
|
{
|
bbzoom /= 2;
|
}
|
repaint();
|
break;
|
*/
|
case '=':
|
IncDepth();
|
//fontsize += 1;
|
object.GetWindow().refreshContents(true);
|
maskbit = 6;
|
break;
|
case '-': //if (PixelThreshold>1) PixelThreshold /= 2;
|
DecDepth();
|
maskbit = 5;
|
//if(fontsize > 1) fontsize -= 1;
|
// if (object.editWindow == null)
|
// new Exception().printStackTrace();
|
// else
|
object.GetWindow().refreshContents(true);
|
break;
|
case '{':
|
manipCamera.shaper_fovy /= 1.1;
|
System.out.println("FOV = " + manipCamera.shaper_fovy);
|
repaint();
|
break;
|
case '}':
|
manipCamera.shaper_fovy *= 1.1;
|
System.out.println("FOV = " + manipCamera.shaper_fovy);
|
repaint();
|
break;
|
case '[':
|
manipCamera.shaper_fovy /= 1.01;
|
if (false) //manipCamera.hAspect == 0)
|
{
|
double x = Math.tan(manipCamera.shaper_fovy * Math.PI / 180 / 2);
|
x /= 1.1;
|
manipCamera.shaper_fovy = (float) (Math.atan(x) * 180 / Math.PI * 2);
|
cStatic.point1.set(manipCamera.lookAt);
|
cStatic.point1.sub(manipCamera.location);
|
cStatic.point1.mul(0.1);
|
manipCamera.location.sub(cStatic.point1);
|
manipCamera.computeTransform();
|
}
|
repaint();
|
break;
|
case ']':
|
//manipCamera.shaper_fovy += (180 - manipCamera.shaper_fovy)*0.1;
|
manipCamera.shaper_fovy *= 1.01;
|
if (false) //manipCamera.hAspect == 0)
|
{
|
double x = Math.tan(manipCamera.shaper_fovy * Math.PI / 180 / 2);
|
x *= 1.1;
|
manipCamera.shaper_fovy = (float) (Math.atan(x) * 180 / Math.PI * 2);
|
cStatic.point1.set(manipCamera.lookAt);
|
cStatic.point1.sub(manipCamera.location);
|
cStatic.point1.mul(0.0909090909);
|
manipCamera.location.add(cStatic.point1);
|
manipCamera.computeTransform();
|
}
|
repaint();
|
break;
|
case BACKSPACE:
|
enablebackspace = true;
|
|
// SwitchCameras(false);
|
repaint();
|
break;
|
|
default:
|
break;
|
}
|
//System.out.println("shaper_fovy = " + manipCamera.shaper_fovy);
|
}
|
|
static double OCCLUSIONBOOST = 1; // 0.5;
|
|
void keyReleased(int key, int modifiers)
|
{
|
//mode = ROTATE;
|
if ((MODIFIERS & COMMAND) == 0) // VR??
|
{
|
SetMouseMode(0, modifiers);
|
}
|
}
|
|
boolean keys[] = new boolean[256];
|
int speedkey[] = new int[256];
|
int modifiers = 0;
|
|
public void processKeyEvent(KeyEvent e)
|
{
|
switch (e.getID())
|
{
|
case KeyEvent.KEY_PRESSED:
|
keys[e.getKeyCode()] = true;
|
modifiers = e.getModifiersEx();
|
keyPressed(e.getKeyChar(), modifiers);
|
//Globals.theRenderer.keyPressed(e.getKeyChar());
|
repaint();
|
break;
|
// if (!autorepeat)
|
// {
|
// //System.out.println("processKeyEvent: " + KeyEvent.getKeyText(e.getKeyCode()));
|
// keyPressed(e.getKeyChar(), e.getModifiersEx());
|
// }
|
// if (manipCamera == lightCamera)
|
// {
|
// switch (e.getKeyCode())
|
// {
|
// case DOWN_ARROW:
|
// lightCamera.DECAL /= 2;
|
// repaint();
|
// break;
|
// case UP_ARROW:
|
// lightCamera.DECAL *= 2;
|
// repaint();
|
// break;
|
// case LEFT_ARROW:
|
// lightCamera.SCALE /= 2;
|
// repaint();
|
// break;
|
// case RIGHT_ARROW:
|
// lightCamera.SCALE *= 2;
|
// repaint();
|
// break;
|
// default:
|
// break;
|
// }
|
//
|
// System.out.println("DECAL = " + lightCamera.DECAL + "; SCALE = " + lightCamera.SCALE);
|
// } else
|
// {
|
// if (true) // !autorepeat)
|
// {
|
// boolean reset = true;
|
//
|
// switch (e.getKeyCode())
|
// {
|
// case DOWN_ARROW:
|
// GoDown(e.getModifiersEx());
|
// repaint();
|
// break;
|
// case UP_ARROW:
|
// GoUp(e.getModifiersEx());
|
// repaint();
|
// break;
|
// case LEFT_ARROW:
|
// GoLeft(e.getModifiersEx());
|
// repaint();
|
// break;
|
// case RIGHT_ARROW:
|
// GoRight(e.getModifiersEx());
|
// repaint();
|
// break;
|
// default:
|
// reset = false;
|
// break;
|
// }
|
//
|
// if (reset)
|
// {
|
// autorepeat = true;
|
//
|
// targetLookAt.set(manipCamera.lookAt);
|
// }
|
// }
|
// }
|
// break;
|
// case KeyEvent.KEY_TYPED:
|
// break;
|
case KeyEvent.KEY_RELEASED:
|
keys[e.getKeyCode()] = false;
|
modifiers = e.getModifiersEx();
|
keyReleased(e.getKeyChar(), e.getModifiersEx());
|
repaint();
|
break;
|
// {
|
// switch (e.getKeyCode())
|
// {
|
// case DOWN_ARROW:
|
// case UP_ARROW:
|
// case LEFT_ARROW:
|
// case RIGHT_ARROW:
|
// MODIFIERS &= ~COMMAND;
|
// autorepeat = false;
|
// break;
|
// default:
|
// break;
|
// }
|
// keyReleased(e.getKeyChar(), e.getModifiersEx());
|
// break;
|
// }
|
default:
|
break;
|
}
|
|
//System.out.println("mode = " + mode);
|
}
|
|
protected void processMouseEvent(MouseEvent e)
|
{
|
//System.out.println("processMouseEvent: " + e);
|
|
//if (!isRenderer)
|
//{
|
if (e.getID() == MouseEvent.MOUSE_PRESSED)
|
{
|
mousePressed(e);
|
} else if (e.getID() == MouseEvent.MOUSE_RELEASED)
|
{
|
mouseReleased(e);
|
}
|
//}
|
|
/*
|
if (isRenderer)
|
{
|
marqX = e.getX();
|
marqY = e.getY();
|
if (drag)
|
{
|
drag = false;
|
repaint();
|
}
|
}
|
*/
|
}
|
|
protected void processMouseMotionEvent(MouseEvent e)
|
{
|
//System.out.println("processMouseMotionEvent: " + mouseMode + " " + e.getModifiers() + " " + e.getModifiersEx() + " " + e.getButton());
|
//if (e.getButton() == MouseEvent.NOBUTTON && (mouseMode & SELECT) == 0)
|
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) == 0 && (e.getModifiers() & MouseEvent.BUTTON3_MASK) == 0 && (mouseMode & SELECT) == 0)
|
{
|
mouseMoved(e);
|
} else
|
{
|
mouseDragged(e);
|
}
|
}
|
|
void Edit()
|
{
|
/*
|
System.out.println("edit " + object);
|
//if (object instanceof CSG)
|
{
|
Composite group = (Composite) object;
|
for (int i=0; i<group.selectees.size(); i++)
|
{
|
Object3D elem = (Object3D)group.selectees.elementAt(i);
|
System.out.println("open " + elem);
|
elem.openEditWindow(object.editWindow);
|
}
|
}
|
*/
|
|
object.GetWindow().EditSelection(false);
|
}
|
|
void SelectParent()
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
Composite group = (Composite) object;
|
java.util.Vector selectees = new java.util.Vector(group.selection);
|
boolean first = true;
|
for (int i = 0; i < selectees.size(); i++)
|
{
|
Object3D elem = (Object3D) selectees.elementAt(i);
|
if (/*i == selectees.size() - 1 &&*/elem != group && elem.parent != null)
|
{
|
//selectees.remove(i);
|
System.out.println("select parent of " + elem);
|
group.GetWindow().Select(elem.parent.GetTreePath(), first, true);
|
} else
|
{
|
group.GetWindow().Select(elem.GetTreePath(), first, true);
|
}
|
|
first = false;
|
}
|
}
|
|
void SelectChildren()
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
/*
|
Composite group = (Composite) object;
|
java.util.Vector selectees = group.selectees;
|
int last = selectees.size() - 1;
|
Object3D elem = (Object3D)selectees.elementAt(last);
|
if (elem instanceof Composite)
|
{
|
System.out.println("select children of " + elem);
|
group = (Composite) elem;
|
selectees.remove(last);
|
for (int i=0; i<group.children.size(); i++)
|
{
|
elem = (Object3D)group.children.elementAt(i);
|
object.editWindow.Select(elem, false);
|
}
|
}
|
*/
|
Composite group = (Composite) object;
|
java.util.Vector selectees = new java.util.Vector(group.selection);
|
boolean first = true;
|
for (int i = 0; i < selectees.size(); i++)
|
{
|
Object3D elem = (Object3D) selectees.elementAt(i);
|
if (/*i == selectees.size() - 1 &&*/elem instanceof Composite)
|
{
|
group = (Composite) elem;
|
//selectees.remove(i);
|
System.out.println("select children of " + elem);
|
for (int j = 0; j < group.children.size(); j++)
|
{
|
elem = (Object3D) group.children.elementAt(j);
|
object.GetWindow().Select(elem.GetTreePath(), first, true);
|
first = false;
|
}
|
} else
|
{
|
object.GetWindow().Select(elem.GetTreePath(), first, true);
|
}
|
|
first = false;
|
}
|
}
|
|
void ClearSelection()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.GetWindow().loadClipboard(true); // ClearSelection(false);
|
}
|
|
void ResetTransform(int mask)
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.GetWindow().ResetTransform(mask);
|
}
|
|
void FlipTransform()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.GetWindow().FlipTransform();
|
// group.editWindow.ReduceMesh(true);
|
}
|
|
void PrintMemory()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.GetWindow().PrintMemory();
|
// group.editWindow.ReduceMesh(true);
|
}
|
|
void ResetCentroid()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.GetWindow().ResetCentroid();
|
}
|
|
void IncDepth()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.IncDepth();
|
}
|
|
void DecDepth()
|
{
|
//Composite group = (Composite) object;
|
Object3D group = object;
|
group.DecDepth();
|
}
|
|
Image CreateImage(int w, int h)
|
{
|
sizetest.w = w;
|
sizetest.h = h;
|
Image image = (Image) imageTable.get(sizetest);
|
if (image == null)
|
{
|
image = createImage(w, h);
|
Size size = new Size();
|
size.w = w;
|
size.h = h;
|
imageTable.put(size, image);
|
}
|
|
return image;
|
}
|
//static public int[] allXs = new int[10000];
|
//static public int[] allYs = new int[10000];
|
//static public int allCount = 0;
|
//static int[] Xs = new int[3];
|
//static int[] Ys = new int[3];
|
static public int Xmin = 10000, Ymin = 10000, Xmax = -10000, Ymax = -10000; // grrr
|
/*static*/ Color linecolorX = new Color(128, 80, 80);
|
/*static*/ Color linecolorY = new Color(80, 128, 80);
|
/*static*/ Color linecolorZ = new Color(80, 80, 128);
|
Color linecolor;
|
Graphics graphics;
|
Thread draw;
|
|
static int renderpass = 0;
|
|
public void paint(Graphics g)
|
{
|
graphics = g; // jan 2014
|
|
if (isRenderer)
|
{
|
// renderpass++;
|
super.paint(g);
|
} else
|
{
|
paintIt(g); // june 2013
|
|
// if (draw != null)
|
// {
|
// draw.stop();
|
// }
|
// graphics = g;
|
// draw = new Thread(this);
|
// //draw.start();
|
// draw.run();
|
}
|
}
|
|
public void run()
|
{
|
paintIt(graphics);
|
}
|
|
public void paintIt(Graphics g)
|
{
|
//System.out.println("PAINT " + isRenderer);
|
|
int width = getBounds().width;
|
int height = getBounds().height;
|
//Image img = CreateImage(width, height);
|
//System.out.println("width = " + width + "; height = " + height + "\n");
|
|
Graphics gr = g; // img.getGraphics();
|
|
if (!hasMarquee)
|
{
|
if (Xmin < Xmax) // !locked)
|
{
|
gr.setColor(Color.darkGray);
|
if (locked)
|
{
|
gr.fillRect(Xmin - 4, Ymin - 4, Xmax - Xmin + 8, Ymax - Ymin + 8);
|
//gr.fillRect(Xmin, Ymin, Xmax-Xmin, Ymax-Ymin);
|
Xmin = 10000;
|
Ymin = 10000;
|
Xmax = -10000;
|
Ymax = -10000;
|
} else
|
{
|
gr.fillRect(0, 0, width, height);
|
}
|
} else
|
{
|
gr.setColor(Color.darkGray);
|
gr.fillRect(0, 0, width, height);
|
// erase previous rendering (weird look)
|
/*
|
gr.setColor(Color.darkGray);
|
for (int i=0; i<allCount;)
|
{
|
Xs[0] = allXs[i]; Ys[0] = allYs[i++];
|
Xs[1] = allXs[i]; Ys[1] = allYs[i++];
|
Xs[2] = allXs[i]; Ys[2] = allYs[i++];
|
gr.drawPolyline(Xs, Ys, 3);
|
}
|
allCount = 0;
|
*/
|
}
|
}
|
|
if (!isRenderer && !hasMarquee)
|
{
|
gr.setColor(linecolor);
|
int gridSize = (int) (64 / manipCamera.Distance());
|
|
if (gridSize == 0)
|
{
|
gridSize = 1;
|
}
|
|
for (int foo = (height / 2) % gridSize; foo < height; foo += gridSize)
|
{
|
if (foo == height / 2)
|
{
|
gr.fillRect(0, foo - 1, width, 3);
|
} else
|
{
|
gr.drawLine(0, foo, width, foo);
|
}
|
}
|
|
for (int foo = (width / 2) % gridSize; foo < width; foo += gridSize)
|
{
|
if (foo == width / 2)
|
{
|
gr.fillRect(foo - 1, 0, 3, height);
|
} else
|
{
|
gr.drawLine(foo, 0, foo, height);
|
}
|
}
|
|
}
|
if (object != null && !hasMarquee)
|
{
|
if (object.clickInfo == null)
|
object.clickInfo = new ClickInfo();
|
ClickInfo info = object.clickInfo;
|
//ClickInfo info = new ClickInfo();
|
info.bounds.setBounds(0, 0, (int) (width * zoom), (int) (height * zoom));
|
|
if (isRenderer)
|
{
|
object.clickInfo.flags++;
|
double frameAspect = (double) width / (double) height;
|
if (frameAspect > renderCamera.aspect)
|
{
|
int desired = (int) ((double) height * renderCamera.aspect);
|
object.clickInfo.bounds.width -= width - desired;
|
object.clickInfo.bounds.x += (width - desired) / 2;
|
} else
|
{
|
int desired = (int) ((double) width / renderCamera.aspect);
|
object.clickInfo.bounds.height -= height - desired;
|
object.clickInfo.bounds.y += (height - desired) / 2;
|
}
|
}
|
|
object.clickInfo.g = gr;
|
object.clickInfo.camera = renderCamera;
|
/*
|
// Memory intensive (brep.verticescopy)
|
if (!(object instanceof Composite))
|
object.draw(info, 0, false); // SLOW :
|
*/
|
if (!isRenderer) // && drag)
|
{
|
Grafreed.Assert(object != null);
|
Grafreed.Assert(object.selection != null);
|
if (object.selection.Size() > 0)
|
{
|
int hitSomething = object.selection.get(0).hitSomething;
|
|
object.clickInfo.DX = 0;
|
object.clickInfo.DY = 0;
|
object.clickInfo.W = 1;
|
if (hitSomething == Object3D.hitCenter)
|
{
|
info.DX = X;
|
if (X != 0)
|
info.DX -= info.bounds.width/2;
|
|
info.DY = Y;
|
if (Y != 0)
|
info.DY -= info.bounds.height/2;
|
}
|
|
object.drawEditHandles(//info,
|
0);
|
|
if (drag && (X != 0 || Y != 0))
|
{
|
switch (hitSomething)
|
{
|
case Object3D.hitCenter: gr.setColor(Color.white);
|
gr.drawLine(X, Y, info.bounds.width/2, info.bounds.height/2);
|
break;
|
case Object3D.hitRotate: gr.setColor(Color.yellow);
|
gr.drawLine(X, Y, info.bounds.width/2, info.bounds.height/2);
|
break;
|
case Object3D.hitScale: gr.setColor(Color.cyan);
|
gr.drawLine(X, Y, info.bounds.width/2, info.bounds.height/2);
|
break;
|
}
|
|
}
|
}
|
}
|
}
|
|
if (isRenderer)
|
{
|
//gr.setColor(Color.black);
|
//gr.drawRect(info.bounds.x - 1, info.bounds.y - 1, info.bounds.width + 1, info.bounds.height + 1);
|
//gr.drawRect(info.bounds.x - 2, info.bounds.y - 2, info.bounds.width + 3, info.bounds.height + 3);
|
}
|
|
if (hasMarquee)
|
{
|
gr.setXORMode(Color.white);
|
gr.setColor(Color.white);
|
if (!firstime)
|
{
|
gr.drawRect(prevmarqX, prevmarqY, prevmarqW, prevmarqH);
|
}
|
gr.drawRect(marqX, marqY, marqW, marqH);
|
prevmarqX = marqX;
|
prevmarqY = marqY;
|
prevmarqW = marqW;
|
prevmarqH = marqH;
|
firstime = false;
|
} else
|
{
|
gr.setXORMode(Color.black);
|
}
|
|
//if (g != gr) g.drawImage(img, 0, 0, width, height, null);
|
}
|
|
// To avoid clear.
|
public void update(Graphics g)
|
{
|
paint(g);
|
}
|
|
public void InitNewPos(Event evt, int x, int y)
|
{
|
startX = x;
|
startY = y;
|
boolean ctrl = (evt.modifiers & 0x2) != 0;
|
boolean shift = (evt.modifiers & 0x1) != 0;
|
if (ctrl && shift)
|
{
|
doWhat = 4;
|
} else if (ctrl)
|
{
|
doWhat = 3;
|
} else if (shift)
|
{
|
doWhat = 2;
|
} else
|
{
|
doWhat = 1;
|
}
|
LA.vecSub(renderCamera.location, renderCamera.lookAt, startView);
|
startDistance = LA.vecLen(startView);
|
LA.vecNormalize(startView);
|
startFLen = renderCamera.focalLength;
|
if (startView.z > 1)
|
{
|
startView.z = 1;
|
}
|
if (startView.z < -1)
|
{
|
startView.z = -1;
|
}
|
initPhi = (double) Math.acos(startView.z);
|
double sinx = (double) Math.sin(initPhi);
|
double cosx;
|
if (Math.abs(sinx) < 1E-05)
|
{
|
cosx = 1;
|
sinx = 0;
|
} else
|
{
|
cosx = startView.x / sinx;
|
sinx = startView.y / sinx;
|
}
|
if (cosx > 1)
|
{
|
cosx = 1;
|
}
|
if (cosx < -1)
|
{
|
cosx = -1;
|
}
|
initTheta = sinx <= 0 ? (double) (-Math.acos(cosx)) : (double) Math.acos(cosx);
|
if (startY <= 0)
|
{
|
startX = 1;
|
}
|
if (startY >= getBounds().height)
|
{
|
startY = getBounds().height - 1;
|
}
|
switch (doWhat)
|
{
|
case 1: // '\001'
|
case 2: // '\002'
|
topScale = (Math.PI - initPhi) / (double) startY;
|
bottomScale = initPhi / (double) (getBounds().height - startY);
|
break;
|
|
case 3: // '\003'
|
topScale = (startDistance - 10) / (double) startY;
|
bottomScale = (1000 - startDistance) / (double) (getBounds().height - startY);
|
break;
|
|
case 4: // '\004'
|
topScale = (startFLen - 10) / (double) startY;
|
bottomScale = (0.1 - startFLen) / (double) (getBounds().height - startY);
|
break;
|
}
|
hScale = 6.283185 / (double) getBounds().width;
|
}
|
|
public boolean mouseDown(Event evt, int x, int y)
|
{
|
System.out.println("mouseDown: " + evt);
|
System.exit(0);
|
/*
|
locked = true;
|
drag = false;
|
//System.out.println("Mouse DOWN");
|
editObj = false;
|
if (isRenderer)
|
{
|
InitNewPos(evt, x, y);
|
}
|
else if (object != null)
|
{
|
ClickInfo info = new ClickInfo();
|
info.bounds.setBounds(0, 0,
|
(int)(getBounds().width*zoom), (int)(getBounds().height*zoom));
|
info.pane = this;
|
info.camera = camera;
|
info.x = x;
|
info.y = y;
|
info.modifiers = evt.modifiers;
|
editObj = object.doEditClick(info, 0);
|
if (!editObj)
|
{
|
hasMarquee = true;
|
firstime = true;
|
marqX = startX = x;
|
marqY = startY = y;
|
marqW = marqH = 0;
|
}
|
}
|
*/
|
int modifiers = 0;
|
if (evt.controlDown() || evt.metaDown())
|
{
|
modifiers |= META;
|
}
|
if (evt.shiftDown())
|
{
|
modifiers |= SHIFT;
|
}
|
if (modifiers != 0)
|
{
|
keyPressed(0, modifiers);
|
}
|
// clickStart(x, y, modifiers);
|
return true;
|
}
|
|
public boolean mouseDrag(Event evt, int x, int y)
|
{
|
//System.out.println("mouseDrag: " + evt);
|
/*
|
drag = true;
|
//System.out.println("Mouse DRAG");
|
if (isRenderer)
|
{
|
if (y >= getBounds().height)
|
y = getBounds().height - 1;
|
if (y <= 0)
|
y = 1;
|
switch (doWhat)
|
{
|
default:
|
break;
|
case 1: // '\001'
|
case 2: // '\002'
|
double dTheta;
|
if (doWhat == 2)
|
dTheta = (double)(x - startX) * hScale * 0.9;
|
else
|
dTheta = (double)(startX - x) * hScale;
|
double dPhi;
|
if (doWhat == 2)
|
dPhi = (double)(y - startY) * 0.9 * (y >= startY ? bottomScale : topScale);
|
else
|
dPhi = (double)(startY - y) * (y >= startY ? bottomScale : topScale);
|
double sinx = (double)Math.sin(initPhi + dPhi);
|
newView.x = sinx * (double)Math.cos(initTheta + dTheta);
|
newView.y = sinx * (double)Math.sin(initTheta + dTheta);
|
newView.z = (double)Math.cos(initPhi + dPhi);
|
//for (int i=0; i < 3; i++)
|
newView.mulEq(startDistance);
|
if (doWhat == 1)
|
{
|
LA.vecAdd(newView, camera.lookAt, newView);
|
camera.setLocation(newView);
|
} else
|
{
|
LA.vecSub(camera.location, newView, newView);
|
camera.setFocus(newView);
|
}
|
break;
|
case 3: // '\003'
|
double dDist = (double)(y - startY) * (y >= startY ? bottomScale : topScale);
|
for (int i=0; i < 3; i++)
|
newView.set(i, startView.get(i) * (startDistance - dDist));
|
LA.vecAdd(camera.lookAt, newView, newView);
|
camera.setLocation(newView);
|
break;
|
case 4: // '\004'
|
double dFL = (double)(y - startY) * (y >= startY ? bottomScale : topScale);
|
camera.focalLength = startFLen + dFL;
|
break;
|
}
|
repaint();
|
InitNewPos(evt, x, y);
|
}
|
else if (editObj)
|
{
|
ClickInfo info = new ClickInfo();
|
info.bounds.setBounds(0, 0, getBounds().width, getBounds().height);
|
info.pane = this;
|
info.camera = camera;
|
info.x = x;
|
info.y = y;
|
object.doEditDrag(info);
|
}
|
else
|
{
|
if (x < startX)
|
{
|
marqX = x;
|
marqW = startX - x;
|
} else
|
{
|
marqX = startX;
|
marqW = x - startX;
|
}
|
if (y < startY)
|
{
|
marqY = y;
|
marqH = startY - y;
|
} else
|
{
|
marqY = startY;
|
marqH = y - startY;
|
}
|
repaint();
|
//info.pane.repaint();
|
}
|
*/
|
int modifiers = 0;
|
//if (evt.controlDown() || evt.metaDown())
|
if (evt.metaDown())
|
{
|
modifiers |= META;
|
}
|
if (evt.controlDown())
|
{
|
modifiers |= COMMAND;
|
}
|
if (evt.shiftDown())
|
{
|
modifiers |= SHIFT;
|
}
|
if (modifiers != 0)
|
{
|
keyPressed(0, modifiers);
|
} else
|
{
|
keyReleased(0, 0);
|
}
|
drag(x, y, 0, modifiers);
|
return true;
|
}
|
|
public boolean mouseUp(Event evt, int x, int y)
|
{
|
System.out.println("mouseUp: " + evt);
|
/*
|
locked = false;
|
if (isRenderer)
|
{
|
marqX = x;
|
marqY = y;
|
if (drag)
|
{
|
drag = false;
|
repaint();
|
return true;
|
}
|
}
|
//System.out.println("Mouse UP");
|
drag = false;
|
if (editObj)
|
{
|
//object.refreshEditWindow();
|
object.applySelf();
|
return true;
|
} else
|
{
|
hasMarquee = false;
|
ClickInfo info = new ClickInfo();
|
info.bounds.setBounds(0, 0, getBounds().width, getBounds().height);
|
info.pane = this;
|
info.camera = camera;
|
if (marqW == 0 && marqH == 0)
|
{
|
marqX -= 16; marqY -= 16;
|
marqW = 32; marqH = 32;
|
}
|
System.out.println("X = " + marqX + ", Y = " + marqY + "; W = " + marqW + ", H = " + marqH);
|
Rectangle r = new Rectangle(marqX, marqY, marqW, marqH);
|
object.doSelection(info, r, 0);
|
repaint();
|
return true;
|
}
|
*/
|
|
int modifiers = 0;
|
//if (evt.controlDown() || evt.metaDown())
|
if (evt.metaDown())
|
{
|
modifiers |= META;
|
}
|
if (evt.controlDown())
|
{
|
modifiers |= COMMAND;
|
}
|
if (evt.shiftDown())
|
{
|
modifiers |= SHIFT;
|
}
|
clickEnd(x, y, modifiers);
|
if (modifiers != 0)
|
{
|
keyReleased(0, modifiers);
|
}
|
return true;
|
}
|
|
public boolean keyDown(Event evt, int key)
|
{
|
System.out.println("keyDown: " + evt);
|
int modifiers = 0;
|
//if (evt.controlDown() || evt.metaDown())
|
if (evt.metaDown())
|
{
|
modifiers |= META;
|
}
|
if (evt.controlDown())
|
{
|
modifiers |= COMMAND;
|
}
|
if (evt.shiftDown())
|
{
|
modifiers |= SHIFT;
|
}
|
keyPressed(key, modifiers);
|
return true;
|
}
|
|
public boolean keyUp(Event evt, int key)
|
{
|
int modifiers = 0;
|
//if (evt.controlDown() || evt.metaDown())
|
if (evt.metaDown())
|
{
|
modifiers |= META;
|
}
|
if (evt.controlDown())
|
{
|
modifiers |= COMMAND;
|
}
|
if (evt.shiftDown())
|
{
|
modifiers |= SHIFT;
|
}
|
keyReleased(key, modifiers);
|
return true;
|
}
|
/**/
|
/*static*/ Dimension aMin = new Dimension(128, 128);
|
/*static*/ Dimension aPref = new Dimension(256, 256);
|
/*static*/ Dimension aMax = new Dimension(1024, 1024);
|
|
public Dimension getMinimumSize()
|
{
|
return aMin;
|
}
|
|
public Dimension getPreferredSize()
|
{
|
return aPref;
|
}
|
|
public Dimension getMaximumSize()
|
{
|
return aMax;
|
}
|
/**/
|
Object3D object;
|
static Object3D trackedobject;
|
Camera renderCamera; // Light or Eye (or Occlusion)
|
/*static*/ Camera manipCamera; // Light or Eye. Can be Light when Eye, not Eye when Light
|
/*static*/ Camera eyeCamera;
|
/*static*/ Camera lightCamera;
|
int cameracount;
|
Camera[] cameras;
|
boolean isRenderer;
|
boolean hasMarquee;
|
boolean locked;
|
static boolean drag;
|
int marqX, marqY, marqW, marqH;
|
int prevmarqX, prevmarqY, prevmarqW, prevmarqH;
|
private static final int kChangePos = 1;
|
private static final int kChangeFocus = 2;
|
private static final int kChangeDist = 3;
|
private static final int kChangeFLen = 4;
|
static final int WHEEL = InputEvent.ALT_GRAPH_DOWN_MASK;
|
static final int SHIFT = InputEvent.SHIFT_DOWN_MASK;
|
static final int BUTTON1 = InputEvent.BUTTON1_DOWN_MASK;
|
static final int META = InputEvent.ALT_DOWN_MASK; // means "OPTION"
|
static final int CTRL = InputEvent.CTRL_DOWN_MASK;
|
static final int CTRLCLICK = CTRL | BUTTON1;
|
static final int COMMAND = InputEvent.META_DOWN_MASK; // 256; // ALT?? InputEvent.CTRL_DOWN_MASK;
|
//static final int SHIFT_CONTROL = SHIFT | COMMAND;
|
static final int SHIFT_META = SHIFT | META;
|
static final int ESC = KeyEvent.VK_ESCAPE;
|
static final int TAB = KeyEvent.VK_TAB;
|
static final int BACKSPACE = KeyEvent.VK_BACK_SPACE;
|
static final int ENTER = KeyEvent.VK_ENTER;
|
static final int DELETE = KeyEvent.VK_DELETE;
|
static final int DOWN_ARROW = KeyEvent.VK_DOWN;
|
static final int UP_ARROW = KeyEvent.VK_UP;
|
static final int LEFT_ARROW = KeyEvent.VK_LEFT;
|
static final int RIGHT_ARROW = KeyEvent.VK_RIGHT;
|
//static final int TAB = KeyEvent.VK_TAB;
|
static final int UP = KeyEvent.VK_UP;
|
static final int DOWN = KeyEvent.VK_DOWN;
|
static final int LEFT = KeyEvent.VK_LEFT;
|
static final int RIGHT = KeyEvent.VK_RIGHT;
|
private static final int ROTATE = 1;
|
private static final int BACKFORTH = 2;
|
private static final int TRANSLATE = 4;
|
private static final int ZOOM = 8;
|
private static final int VR = 16;
|
private static final int SELECT = 32;
|
int mouseMode = 0; // ROTATE;
|
int anchorX, anchorY;
|
int prevX, prevY;
|
double zoom = 1;
|
long time0;
|
private /*static*/ int doWhat;
|
private /*static*/ int startX;
|
private /*static*/ int startY;
|
private /*static*/ cVector startView = new cVector();
|
private /*static*/ double startDistance;
|
private /*static*/ double startFLen;
|
private /*static*/ double initPhi;
|
private /*static*/ double initTheta;
|
private /*static*/ double topScale;
|
private /*static*/ double bottomScale;
|
private /*static*/ double hScale;
|
private /*static*/ boolean editObj;
|
private /*static*/ boolean firstime;
|
private /*static*/ cVector newView = new cVector();
|
private static final String[] suffixes = {"posx", "negx", "posy", "negy", "posz", "negz"};
|
private static final String[] suffixes2 = {"east", "west", "top", "bottom", "north", "south"};
|
private static final String[] suffixes3 = {"ft", "bk", "up", "dn", "rt", "lf"};
|
private static final int[] targets = {GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
};
|
|
public static com.sun.opengl.util.texture.Texture LoadCubemap(ClassLoader scope, String basename, String suffix, boolean mipmapped) throws IOException, GLException
|
{
|
com.sun.opengl.util.texture.Texture cubemap = TextureIO.newTexture(GL.GL_TEXTURE_CUBE_MAP);
|
|
int usedsuf = 0;
|
|
for (int i = 0; i < suffixes.length; i++)
|
{
|
String[] suffixe = suffixes;
|
String[] fallback = suffixes2;
|
String[] fallfallback = suffixes3;
|
|
for (int c=usedsuf; --c>=0;)
|
{
|
// String[] temp = suffixe;
|
// suffixe = fallback;
|
// fallback = fallfallback;
|
// fallfallback = temp;
|
}
|
|
String resourceName = basename + suffixe[i] + "." + suffix;
|
TextureData data;
|
|
try
|
{
|
data = TextureIO.newTextureData(scope.getResourceAsStream(resourceName),
|
mipmapped,
|
FileUtil.getFileSuffix(resourceName));
|
}
|
catch (Exception e)
|
{
|
try
|
{
|
resourceName = basename + fallback[i] + "." + suffix;
|
data = TextureIO.newTextureData(scope.getResourceAsStream(resourceName),
|
mipmapped,
|
FileUtil.getFileSuffix(resourceName));
|
}
|
catch (Exception e2)
|
{
|
resourceName = basename + fallfallback[i] + "." + suffix;
|
data = TextureIO.newTextureData(scope.getResourceAsStream(resourceName),
|
mipmapped,
|
FileUtil.getFileSuffix(resourceName));
|
}
|
}
|
|
//System.out.println("Target = " + targets[i]);
|
cubemap.updateImage(data, targets[i]);
|
}
|
|
return cubemap;
|
}
|
|
int bigsphere = -1;
|
|
float BGcolor = 0.5f;
|
|
float ambientLight[] = {1f, 1f, 1f, 1.0f};
|
|
private void DrawSkyBox(GL gl, float ratio)
|
{
|
if (//envyoff ||
|
WIREFRAME ||
|
cubemap == null)
|
{
|
gl.glClearColor(BGcolor, BGcolor, BGcolor, 1);
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
|
return;
|
}
|
|
if (WIREFRAME)
|
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL);
|
|
gl.glDisable(gl.GL_CULL_FACE);
|
|
// Compensates for ExaminerViewer's modification of modelview matrix
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
gl.glScalef(1,ratio,1);
|
|
// colorV[0] = 2;
|
// colorV[1] = 2;
|
// colorV[2] = 2;
|
// colorV[3] = 1;
|
// gl.glDisable(gl.GL_COLOR_MATERIAL);
|
// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, colorV, 0);
|
//
|
// gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, ambientLight, 0);
|
|
//gl.glActiveTexture(GL.GL_TEXTURE1);
|
//gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
|
|
//gl.glActiveTexture(GL.GL_TEXTURE0);
|
cubemap.bind();
|
cubemap.enable();
|
|
// This is a workaround for a driver bug on Mac OS X where the
|
// normals are not being sent down to the hardware in
|
// GL_NORMAL_MAP texgen mode. Temporarily enabling lighting
|
// causes the normals to be sent down. Thanks to Ken Dyke.
|
//gl.glEnable(GL.GL_LIGHTING);
|
gl.glDisable(GL.GL_LIGHTING);
|
|
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
|
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
|
gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
|
|
gl.glEnable(GL.GL_TEXTURE_GEN_S);
|
gl.glEnable(GL.GL_TEXTURE_GEN_T);
|
gl.glEnable(GL.GL_TEXTURE_GEN_R);
|
|
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
|
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
if (reverseUP)
|
{
|
gl.glScalef(1.0f, -1.0f, 1.0f);
|
}
|
gl.glScalef(-1.0f, 1.0f, 1.0f);
|
gl.glMultMatrixd(viewrot_1, 0);
|
gl.glTranslatef(0, 0, 0.5f); // (float)lightCamera.Distance()); // 0.5f);
|
//viewer.updateInverseRotation(gl);
|
|
gl.glDisable(GL.GL_DEPTH_TEST);
|
/*
|
gl.glColor4f(1,1,1,1);
|
gl.glEnable(GL.GL_LIGHTING);
|
gl.glDisable(GL.GL_BLEND);
|
float[] colorV = Applet3D.colorV;
|
colorV[0] = 1;
|
colorV[1] = 1;
|
colorV[2] = 1;
|
colorV[3] = 1;
|
gl.glColor4f(colorV[0], colorV[1], colorV[2], 1);
|
//System.out.println("Opacity = " + opacity);
|
gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, colorV, 0);
|
*/
|
|
if (bigsphere == -1)
|
{
|
bigsphere = gl.glGenLists(1);
|
|
gl.glNewList(bigsphere, gl.GL_COMPILE);
|
glut.glutSolidSphere(5.0, 60, 40);
|
gl.glEndList();
|
}
|
gl.glCallList(bigsphere);
|
gl.glEnable(GL.GL_DEPTH_TEST);
|
|
//gl.glDisable(GL.GL_LIGHTING);
|
|
gl.glPopMatrix();
|
//gl.glMatrixMode(GL.GL_MODELVIEW);
|
|
gl.glDisable(GL.GL_TEXTURE_GEN_S);
|
gl.glDisable(GL.GL_TEXTURE_GEN_T);
|
gl.glDisable(GL.GL_TEXTURE_GEN_R);
|
|
cubemap.disable();
|
//cubemap.dispose();
|
|
if (CULLFACE)
|
{
|
gl.glEnable(gl.GL_CULL_FACE);
|
} // ABC
|
|
if (WIREFRAME)
|
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE);
|
}
|
|
private void DrawChecker(GL gl)
|
{
|
/*
|
Object3D.materialstack[Object3D.stackdepth] = checker.material;
|
Object3D.selectedstack[Object3D.stackdepth] = false;
|
cStatic.objectstack[Object3D.stackdepth++] = checker;
|
//System.out.println("material " + material);
|
//Applet3D.tracein(this, selected);
|
vector2buffer = checker.projectedVertices;
|
|
checker.GetMaterial().Draw(this, false); // true);
|
|
Object3D.stackdepth -= 1;
|
if (Object3D.stackdepth > 0)
|
{
|
vector2buffer = cStatic.objectstack[Object3D.stackdepth - 1].projectedVertices;
|
Object3D.materialstack[Object3D.stackdepth - 1].Draw(this, Object3D.selectedstack[Object3D.stackdepth - 1]);
|
}
|
*/
|
|
// Compensates for ExaminerViewer's modification of modelview matrix
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
gl.glPushAttrib(GL.GL_ALL_ATTRIB_BITS);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
//PushMatrix(checker.toParent);
|
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
gl.glTranslatef(0.5f, 0.5f, 0.5f);
|
gl.glScalef(0.5f, 0.5f, 0.5f);
|
PushTextureMatrix(checker.fromParent);
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glScalef(2f, 2f, 2f);
|
gl.glTranslatef(-0.5f, -0.5f, -0.5f);
|
|
gl.glMatrixMode(GL.GL_PROJECTION);
|
gl.glPushMatrix();
|
gl.glLoadIdentity();
|
|
if (reverseUP)
|
{
|
gl.glScalef(1.0f, -1.0f, 1.0f);
|
}
|
|
SetGLNormal(gl, 0.0f, 0.0f, 1.0f);
|
|
float step = 2; // 0.1666f; //0.25f;
|
float stepv = 2; // step * 1652 / 998;
|
|
int i0 = 0;
|
/*
|
gl.glBegin(GL.GL_QUADS);
|
for (float i = -2; i < 2; i += step, i0 += 1)
|
{
|
int j0 = 0;
|
for (float j = -2; j < 2; j += stepv, j0 += 1)
|
{
|
if (((i0 ^ j0) & 1) != 0)// &&
|
//(i0 != 15 || j0 != 6))
|
{
|
// continue;
|
}
|
|
//float u = (i+1)/2;
|
//float v = (j+1)/2;
|
gl.glTexCoord2f((i + 1) / 2, (j + 1) / 2); // (1,0) // (i+1+step)/2,(j+1)/2);
|
gl.glVertex3f(i, j, -0.5f);
|
|
gl.glTexCoord2f((i + 1 + step) / 2, (j + 1) / 2); // (1,1) // (i+1+step)/2,(j+1+step)/2);
|
gl.glVertex3f(i + step, j, -0.5f);
|
|
gl.glTexCoord2f((i + 1 + step) / 2, (j + 1 + stepv) / 2); // (0,1) //(i+1)/2,(j+1+step)/2);
|
gl.glVertex3f(i + step, j + stepv, -0.5f);
|
|
gl.glTexCoord2f((i + 1) / 2, (j + 1 + stepv) / 2); // (0,0) //(i+1)/2,(j+1)/2);
|
gl.glVertex3f(i, j + stepv, -0.5f);
|
}
|
}
|
gl.glEnd();
|
|
/**/
|
//checker.GetMaterial().opacity = 1.1f;
|
////checker.GetMaterial().ambient = 0.99f;
|
materialstack[materialdepth] = checker.material;
|
selectedstack[materialdepth] = false;
|
cStatic.objectstack[materialdepth++] = checker;
|
//System.out.println("material " + material);
|
//Applet3D.tracein(this, selected);
|
//vector2buffer = checker.projectedVertices;
|
|
//checker.GetMaterial().Draw(this, false); // true);
|
DrawMaterial(checker.GetMaterial(), false, checker.projectedVertices); // true);
|
|
materialdepth -= 1;
|
if (materialdepth > 0)
|
{
|
//vector2buffer = cStatic.objectstack[materialdepth - 1].projectedVertices;
|
DrawMaterial(materialstack[materialdepth - 1], selectedstack[materialdepth - 1], cStatic.objectstack[materialdepth - 1].projectedVertices);
|
}
|
//checker.GetMaterial().opacity = 1f;
|
////checker.GetMaterial().ambient = 1f;
|
|
gl.glDepthMask(false);
|
gl.glBegin(GL.GL_QUADS);
|
i0 = 0;
|
for (float i = -2; i < 2; i += step, i0 += 1)
|
{
|
int j0 = 0;
|
for (float j = -2; j < 2; j += stepv, j0 += 1)
|
{
|
if ((i0 != 15 || j0 != 6) &&
|
(i0 != 8 || j0 != 7))
|
{
|
//continue;
|
}
|
|
//float u = (i+1)/2;
|
//float v = (j+1)/2;
|
if (checker.flipV)
|
gl.glTexCoord2f((i + 1) / 2, 1 - (j + 1) / 2);
|
else
|
gl.glTexCoord2f((i + 1) / 2, (j + 1) / 2); // (1,0) // (i+1+step)/2,(j+1)/2);
|
gl.glVertex3f(i, j, -0.5f);
|
|
if (checker.flipV)
|
gl.glTexCoord2f((i + 1 + step) / 2, 1 - (j + 1) / 2); // (1,1) // (i+1+step)/2,(j+1+step)/2);
|
else
|
gl.glTexCoord2f((i + 1 + step) / 2, (j + 1) / 2); // (1,1) // (i+1+step)/2,(j+1+step)/2);
|
gl.glVertex3f(i + step, j, -0.5f);
|
|
if (checker.flipV)
|
gl.glTexCoord2f((i + 1 + step) / 2, 1 - (j + 1 + stepv) / 2); // (0,1) //(i+1)/2,(j+1+step)/2);
|
else
|
gl.glTexCoord2f((i + 1 + step) / 2, (j + 1 + stepv) / 2); // (0,1) //(i+1)/2,(j+1+step)/2);
|
gl.glVertex3f(i + step, j + stepv, -0.5f);
|
|
if (checker.flipV)
|
gl.glTexCoord2f((i + 1) / 2, 1 - (j + 1 + stepv) / 2); // (0,0) //(i+1)/2,(j+1)/2);
|
else
|
gl.glTexCoord2f((i + 1) / 2, (j + 1 + stepv) / 2); // (0,0) //(i+1)/2,(j+1)/2);
|
gl.glVertex3f(i, j + stepv, -0.5f);
|
}
|
}
|
gl.glEnd();
|
/**/
|
gl.glDepthMask(true);
|
|
gl.glMatrixMode(GL.GL_PROJECTION);
|
gl.glPopMatrix();
|
gl.glMatrixMode(GL.GL_MODELVIEW);
|
//PopMatrix(null); // checker.toParent); // null);
|
gl.glPopMatrix();
|
PopTextureMatrix(checker.toParent);
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
gl.glPopMatrix();
|
gl.glPopAttrib();
|
gl.glEnable(GL.GL_LIGHTING);
|
}
|
|
static double Trunk(double f)
|
{
|
return (int) (f * 1000) / 1000.0;
|
}
|
|
static int paintcount = 0;
|
|
static void PrintFromTos(Object3D path)
|
{
|
for (int i=0; i<path.size(); i++)
|
{
|
if (i == 0)
|
{
|
System.out.println("; gotox " + path.name + " " + Trunk(path.get(i).toParent[3][0]));
|
System.out.println("; gotoy " + path.name + " " + Trunk(path.get(i).toParent[3][1]));
|
System.out.println("; gotoz " + path.name + " " + Trunk(path.get(i).toParent[3][2]));
|
continue;
|
}
|
|
System.out.println("; fromto " + path.name + " " + Trunk(path.get(i-1).toParent[3][0]) + " " + Trunk(path.get(i-1).toParent[3][1]) + " " + Trunk(path.get(i-1).toParent[3][2]) + " " +
|
Trunk(path.get(i).toParent[3][0]) + " " + Trunk(path.get(i).toParent[3][1]) + " " + Trunk(path.get(i).toParent[3][2]));
|
}
|
}
|
|
private Object3D GetFolder()
|
{
|
Object3D folder = object.GetWindow().copy;
|
if (object.GetWindow().copy.selection.Size() > 0)
|
folder = object.GetWindow().copy.selection.elementAt(0);
|
return folder;
|
}
|
|
class SelectBuffer implements GLEventListener
|
{
|
|
GLEventListener parent = null;
|
|
SelectBuffer(GLEventListener p)
|
{
|
parent = p;
|
}
|
|
public void init(GLAutoDrawable drawable)
|
{
|
//new Exception().printStackTrace();
|
System.out.println("select buffer init");
|
// Use debug pipeline
|
//drawable.setGL(new DebugGL(drawable.getGL()));
|
|
GL gl = drawable.getGL();
|
|
/*
|
if (CULLFACE)
|
gl.glEnable(gl.GL_CULL_FACE); // ABC
|
else
|
gl.glDisable(gl.GL_CULL_FACE); // ABC
|
*/
|
gl.glEnable(gl.GL_DEPTH_TEST);
|
|
/*
|
int[] depth_bits = new int[1];
|
gl.glGetIntegerv(GL.GL_DEPTH_BITS, depth_bits, 0);
|
depth_format = GL.GL_DEPTH_COMPONENT24_ARB;
|
if (depth_bits[0] == 16)
|
depth_format = GL.GL_DEPTH_COMPONENT16_ARB;
|
*/
|
|
/*
|
selection_view = GenTexture(gl);
|
gl.glBindTexture(GL.GL_TEXTURE_2D, selection_view);
|
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, TEX_SIZE, TEX_SIZE, 0,
|
GL.GL_RGB, GL.GL_UNSIGNED_INT, null);
|
//set_light_view_texture_parameters(gl);
|
*/
|
|
selectInitialized = true;
|
}
|
|
/*
|
private int GenTexture(GL gl)
|
{
|
int[] tmp = new int[1];
|
gl.glGenTextures(1, tmp, 0);
|
return tmp[0];
|
}
|
*/
|
public void display(GLAutoDrawable drawable)
|
{
|
if (!selection)
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
return;
|
}
|
|
selection = false;
|
|
//System.out.println("pbuffer display = " + fullyInitialized);
|
//fullyInitialized = true;
|
GL gl = drawable.getGL();
|
|
//gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
|
//gl.glPolygonOffset(((Tweak) tweaks.get(POLYGON_OFFSET_SCALE)).val,
|
//((Tweak) tweaks.get(POLYGON_OFFSET_BIAS)).val);
|
//gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
|
|
//render_scene_from_light_view(gl, drawable, 0, 0);
|
|
//gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
|
|
if (PAINTMODE)
|
{
|
if (object.GetWindow().copy.selection.Size() > 0)
|
{
|
Object3D paintobj = object.GetWindow().copy.selection.elementAt(0);
|
|
// Make what you paint not selectable.
|
paintobj.ResetSelectable();
|
}
|
}
|
|
//int tmp = selection_view;
|
//selection_view = -1;
|
int temp = DrawMode();
|
Globals.drawMode = SELECTION; // WARNING
|
indexcount = 0;
|
parent.display(drawable);
|
//selection_view = tmp;
|
//if (temp == SELECTION)
|
// temp = DEFAULT; // patch for selection debug
|
Globals.drawMode = temp; // WARNING
|
|
if (PAINTMODE)
|
{
|
if (object.GetWindow().copy.selection.Size() > 0)
|
{
|
Object3D paintobj = object.GetWindow().copy.selection.elementAt(0);
|
|
// Revert.
|
paintobj.RestoreSelectable();
|
}
|
}
|
|
//gl.glBindTexture(GL.GL_TEXTURE_2D, selection_view);
|
|
// trying different ways of getting the depth info over
|
//gl.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, TEX_SIZE, TEX_SIZE);
|
//gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB /*depth_format*/, TEX_SIZE, TEX_SIZE, 0,
|
//GL.GL_RGB, GL.GL_UNSIGNED_BYTE, buffer);
|
// GL_DEPTH_COMPONENT
|
|
// SINGLE POINT
|
gl.glReadPixels(0, 0, SELECT_SIZE, SELECT_SIZE, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, pointselectsizebuffer);
|
|
float[] depths = pointselectsizebuffer.array();
|
|
/*
|
System.out.println("#pixels = " + pixels.length);
|
for (int i=0; i<10; i++)
|
{
|
System.out.print(pixels[i] + ", ");
|
}
|
System.out.println();
|
/**/
|
|
int x = marqX;
|
int y = marqY;
|
|
x = x * TEX_SIZE / getWidth();
|
y = (getHeight() - 1 - y) * TEX_SIZE / getHeight();
|
|
float depth = depths[y * TEX_SIZE + x];
|
|
if (pointselection && (mouseMode & SELECT) == SELECT && depth != 0 && depth != 1)
|
{
|
pointselection = false;
|
|
gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, tempmat, 0);
|
gl.glGetDoublev(gl.GL_PROJECTION_MATRIX, tempmat2, 0);
|
gl.glGetIntegerv(gl.GL_VIEWPORT, viewport, 0);
|
|
// System.err.println("tempmat = " + tempmat[0] + " " + tempmat[1] + " " + tempmat[2] + " " + tempmat[3]);
|
// System.err.println("tempmat = " + tempmat[4] + " " + tempmat[5] + " " + tempmat[6] + " " + tempmat[7]);
|
// System.err.println("tempmat = " + tempmat[8] + " " + tempmat[9] + " " + tempmat[10] + " " + tempmat[11]);
|
// System.err.println("tempmat = " + tempmat[12] + " " + tempmat[13] + " " + tempmat[14] + " " + tempmat[15]);
|
//
|
// System.err.println("view = " + view[0] + " " + view[1] + " " + view[2] + " " + view[3]);
|
// System.err.println("view = " + view[4] + " " + view[5] + " " + view[6] + " " + view[7]);
|
// System.err.println("view = " + view[8] + " " + view[9] + " " + view[10] + " " + view[11]);
|
// System.err.println("view = " + view[12] + " " + view[13] + " " + view[14] + " " + view[15]);
|
|
CreateSelectedPoint();
|
|
// Will fit the mesh !!!
|
selectedpoint.toParent[0][0] = 0.0001;
|
selectedpoint.toParent[1][1] = 0.0001;
|
selectedpoint.toParent[2][2] = 0.0001;
|
|
glu.gluUnProject(x,y,depth,view,0,tempmat2,0,viewport,0,selectedpoint.toParent[3],0);
|
|
// if (object.selection != null && object.selection.Size() > 0)
|
// {
|
// for (Object3D sel : object.selection)
|
// {
|
// if (sel instanceof Mocap)
|
// {
|
// Mocap mocap = (Mocap) sel;
|
//
|
// mocap.goalx = selectedpoint.toParent[3][0];
|
// mocap.goalz = selectedpoint.toParent[3][2];
|
// }
|
// }
|
// }
|
// System.err.print("marq = " + marqX + " " + marqY);
|
// System.err.println("; depth = " + depth);
|
// System.err.println("X = " + x + " " + y);
|
// System.err.println("viewport = [" + viewport[0] + " " + viewport[1] + " " + viewport[2] + " " + viewport[3] + "]");
|
if (!movingcamera)
|
{
|
if (true) // object.selection.Size() == 0)
|
{
|
System.err.println("selected point = " + Trunk(selectedpoint.toParent[3][0]) + " " + Trunk(selectedpoint.toParent[3][1]) + " " + Trunk(selectedpoint.toParent[3][2]));
|
previousselectedpoint = null;
|
}
|
else
|
{
|
String sel = object.selection.get(0).GetPath().toString().split("/", 3)[2];
|
if (previousselectedpoint == null)
|
{
|
System.out.println("; gotox " + sel + " " + Trunk(selectedpoint.toParent[3][0]));
|
System.out.println("; gotoy " + sel + " " + Trunk(selectedpoint.toParent[3][1]));
|
System.out.println("; gotoz " + sel + " " + Trunk(selectedpoint.toParent[3][2]));
|
// System.out.println("; goalx " + sel + " " + selectedpoint.toParent[3][0]);
|
// System.out.println("; goaly " + sel + " " + selectedpoint.toParent[3][1]);
|
// System.out.println("; goalz " + sel + " " + selectedpoint.toParent[3][2]);
|
}
|
else
|
{
|
System.out.println("; fromto " + sel + " " + Trunk(previousselectedpoint.toParent[3][0]) + " " + Trunk(previousselectedpoint.toParent[3][2]) + " " + Trunk(selectedpoint.toParent[3][0]) + " " + Trunk(selectedpoint.toParent[3][2]));
|
}
|
|
previousselectedpoint = (Sphere) Grafreed.clone(selectedpoint);
|
}
|
}
|
|
if (!movingcamera && !PAINTMODE)
|
object.GetWindow().ScreenFitPoint(); // fev 2014
|
|
if (PAINTMODE) // && Grafreed.clipboard.size() == 1) // object.editWindow.copy.selection.Size() > 0)
|
{
|
//Object3D paintobj; // = Grafreed.clipboard.get(0); // object.editWindow.copy.selection.elementAt(0);
|
|
if (object.GetWindow().copy.selection.Size() > 0)
|
{
|
Object3D paintobj = object.GetWindow().copy.selection.elementAt(0);
|
|
Object3D inst = new Object3D("inst" + paintcount++);
|
|
inst.CreateMaterial(); // use a void leaf to select instances
|
|
inst.add(paintobj); // link
|
|
object.GetWindow().SnapObject(inst);
|
|
Object3D folder = paintFolder; // GetFolder();
|
|
folder.add(inst);
|
|
object.GetWindow().ResetModel();
|
object.GetWindow().refreshContents();
|
}
|
}
|
else
|
paintcount = 0;
|
|
return; // june 2013
|
}
|
|
// OBJECT
|
gl.glReadPixels(0, 0, SELECT_SIZE, SELECT_SIZE, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, selectsizebuffer);
|
|
int[] pixels = selectsizebuffer.array();
|
|
/*
|
System.out.println("#pixels = " + pixels.length);
|
for (int i=0; i<10; i++)
|
{
|
System.out.print(pixels[i] + ", ");
|
}
|
System.out.println();
|
/**/
|
|
x = marqX;
|
y = marqY;
|
|
x = x * TEX_SIZE / getWidth();
|
y = (getHeight() - 1 - y) * TEX_SIZE / getHeight();
|
|
int color = pixels[y * TEX_SIZE + x] & (16777215 / 2);
|
|
if (color != 0)
|
{
|
//assert objects[color] != null;
|
|
// System.out.println("indexcount = " + indexcount);
|
//System.out.println("color = " + color);
|
//System.out.println("objects[color] = " + objects[color]);
|
//objects[color].Select();
|
indexcount = 0;
|
ObjEditor window = object.GetWindow();
|
if (window != null && deselect)
|
{
|
window.Select(null, deselect, true);
|
}
|
object.Select(color, deselect);
|
}
|
|
pixels[y * TEX_SIZE + x] = -1;
|
|
Object src = pixels;
|
Object dest = ((DataBufferInt) bufimage.getRaster().getDataBuffer()).getData();
|
int srcIncr = TEX_SIZE;
|
int destIncr = bufimage.getWidth();
|
|
int srcPos = 0;
|
int destPos = (bufimage.getHeight() - 1) * destIncr;
|
for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr)
|
{
|
//System.out.println("arraycopy(" + src + ", " + srcPos + ", " + dest + ", " + destPos + ", " + destIncr + ")");
|
System.arraycopy(src, srcPos, dest, destPos, destIncr);
|
}
|
|
//texture = TextureIO.newTexture(new TextureData(0,0, false, image));
|
|
// TEXTURE texture.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
|
// TEXTURE texture.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
|
}
|
|
// Unused routines
|
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
|
{
|
}
|
|
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
|
{
|
}
|
}
|
private int light_view_depth;
|
//private int bump_noise;
|
//private int occlusionmap;
|
int depth_format;
|
|
class ShadowBuffer implements GLEventListener
|
{
|
|
GLEventListener parent = null;
|
|
ShadowBuffer(GLEventListener p)
|
{
|
parent = p;
|
}
|
|
public void init(GLAutoDrawable drawable)
|
{
|
if (Globals.DEBUG)
|
System.out.println("shadow buffer init");
|
|
GL gl = drawable.getGL();
|
|
gl.glEnable(GL.GL_DEPTH_TEST);
|
//gl.glDepthFunc(gl.GL_LEQUAL);
|
gl.glClearDepth(1);
|
//gl.glEnable(GL.GL_NORMALIZE);
|
// speed
|
gl.glShadeModel(gl.GL_FLAT);
|
gl.glColorMask(false, false, false, false);
|
//gl.glDisable(gl.GL_LIGHTING);
|
gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST);
|
|
int[] depth_bits = new int[1];
|
gl.glGetIntegerv(GL.GL_DEPTH_BITS, depth_bits, 0);
|
|
if (depth_bits[0] == 16)
|
{
|
depth_format = GL.GL_DEPTH_COMPONENT16_ARB;
|
} else
|
{
|
depth_format = GL.GL_DEPTH_COMPONENT24_ARB;
|
}
|
|
light_view_depth = GenTexture(gl);
|
gl.glBindTexture(GL.GL_TEXTURE_2D, light_view_depth);
|
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, depth_format, SHADOW_SIZE, SHADOW_SIZE, 0,
|
GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, null);
|
set_light_view_texture_parameters(gl);
|
|
shadowInitialized = true;
|
}
|
|
public void display(GLAutoDrawable drawable)
|
{
|
restartframe = true;
|
|
GL gl = drawable.getGL();
|
|
if (SHADOWCULLFACE)
|
{
|
gl.glEnable(gl.GL_CULL_FACE); // ABC
|
gl.glCullFace(gl.GL_FRONT);
|
} else
|
{
|
gl.glDisable(gl.GL_CULL_FACE);
|
}
|
|
if (!Globals.RENDERSHADOW)
|
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
|
// SB gl.glPolygonOffset(2.5f, 10);
|
// SB gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
|
|
//gl.glShadeModel(gl.GL_FLAT);
|
//gl.glColorMask(false, false, false, false);
|
|
//render_scene_from_light_view(gl, drawable, 0, 0);
|
if (Globals.RENDERSHADOW && Globals.lighttouched && (!movingcamera || !Globals.FREEZEONMOVE)) // && !parent.IsFreezed())
|
{
|
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
|
int temp = DrawMode();
|
Globals.drawMode = SHADOW; // WARNING
|
parent.display(drawable);
|
Globals.drawMode = temp; // WARNING
|
}
|
|
gl.glCullFace(gl.GL_BACK);
|
if (!CULLFACE)
|
{
|
gl.glDisable(gl.GL_CULL_FACE);
|
} // ABC
|
|
// SB gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
|
|
gl.glBindTexture(GL.GL_TEXTURE_2D, light_view_depth);
|
|
// trying different ways of getting the depth info over
|
gl.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_SIZE, SHADOW_SIZE);
|
|
gl.glFlush();
|
//gl.glShadeModel(gl.GL_SMOOTH);
|
//gl.glColorMask(true, true, true, true);
|
|
// debug
|
/*
|
//gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, depth_format, TEX_SIZE, TEX_SIZE, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, buffer);
|
gl.glReadPixels(0, 0, TEX_SIZE, TEX_SIZE, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, buffer);
|
//gl.glReadPixels(0, 0, TEX_SIZE, TEX_SIZE, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
int[] pixels = buffer.array();
|
Object src = pixels;
|
Object dest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
int srcIncr = TEX_SIZE;
|
int destIncr = image.getWidth();
|
int srcPos = 0;
|
int destPos = (image.getHeight() - 1) * destIncr;
|
for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr)
|
{
|
//System.out.println("arraycopy(" + src + ", " + srcPos + ", " + dest + ", " + destPos + ", " + destIncr + ")");
|
System.arraycopy(src, srcPos, dest, destPos, destIncr);
|
}
|
texture = TextureIO.newTexture(new TextureData(0,0, false, image));
|
/**/
|
}
|
|
// Unused routines
|
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
|
{
|
}
|
|
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
|
{
|
}
|
}
|
|
class AntialiasBuffer implements GLEventListener
|
{
|
CameraPane parent = null;
|
|
AntialiasBuffer(CameraPane p)
|
{
|
parent = p;
|
}
|
|
public void init(GLAutoDrawable drawable)
|
{
|
System.out.println("antialias buffer init");
|
//antialiasInitialized = true;
|
antialiasInitialized = true;
|
}
|
|
public void display(GLAutoDrawable drawable)
|
{
|
GL gl = drawable.getGL();
|
|
//gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
|
int keep = ANTIALIAS;
|
ANTIALIAS = 0;
|
gl.glEnable(gl.GL_DEPTH_TEST);
|
parent.display(drawable);
|
//parent.object.draw(parent, false);
|
ANTIALIAS = keep;
|
|
gl.glFlush();
|
gl.glReadPixels(0, 0, VPwidth * 2, VPheight * 2, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, bigAAbuffer);
|
gl.glFlush();
|
}
|
|
// Unused routines
|
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
|
{
|
}
|
|
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
|
{
|
}
|
}
|
|
static int stackdepth = 0;
|
|
//static
|
class OcclusionBuffer implements GLEventListener
|
{
|
|
CameraPane parent = null;
|
|
OcclusionBuffer(GLEventListener p)
|
{
|
parent = (CameraPane) p;
|
}
|
|
public void init(GLAutoDrawable drawable)
|
{
|
System.out.println("occlusion buffer init");
|
|
GL gl = drawable.getGL();
|
|
gl.glLightModeli(gl.GL_LIGHT_MODEL_TWO_SIDE, 1);
|
//if (CULLFACE)
|
// gl.glEnable(gl.GL_CULL_FACE);
|
gl.glEnable(gl.GL_LIGHT0);
|
gl.glEnable(gl.GL_LIGHTING);
|
gl.glEnable(gl.GL_DEPTH_TEST);
|
gl.glEnable(gl.GL_NORMALIZE);
|
|
/*
|
occlusionmap = GenTexture(gl);
|
gl.glBindTexture(GL.GL_TEXTURE_2D, occlusionmap);
|
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, OCCLUSION_SIZE, OCCLUSION_SIZE, 0,
|
GL.GL_RGB, GL.GL_UNSIGNED_INT, null);
|
*/
|
|
//gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
|
//gl.glHistogram(GL.GL_HISTOGRAM, HISTOGRAM_SIZE, GL.GL_RGB, false);
|
//gl.glEnable(GL.GL_HISTOGRAM);
|
|
occlusionInitialized = true;
|
}
|
|
cVector ray = new cVector();
|
|
public void display(GLAutoDrawable drawable)
|
{
|
stackdepth++;
|
GL gl = drawable.getGL();
|
|
//gl.glEnable(gl.GL_CULL_FACE);
|
//gl.glCullFace(gl.GL_BACK);
|
|
//drawMode = DEFAULT;
|
//float keep = parent.renderCamera.shaper_fovy;
|
//parent.renderCamera.shaper_fovy = 170;
|
parent.display(drawable);
|
//parent.renderCamera.shaper_fovy = keep;
|
//drawMode = OCCLUSION;
|
|
/*
|
gl.glBindTexture(GL.GL_TEXTURE_2D, occlusionmap);
|
// trying different ways of getting the depth info over
|
gl.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, OCCLUSION_SIZE, OCCLUSION_SIZE);
|
*/
|
|
gl.glFlush();
|
|
/**/
|
gl.glReadPixels(0, 0, OCCLUSION_SIZE, OCCLUSION_SIZE, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, occlusiondepthbuffer);
|
|
float[] depths = occlusiondepthbuffer.array();
|
|
gl.glReadPixels(0, 0, OCCLUSION_SIZE, OCCLUSION_SIZE, GL.GL_BGRA, GL.GL_UNSIGNED_INT_8_8_8_8_REV, occlusioncolorbuffer);
|
|
int[] pixels = selectsizebuffer.array();
|
|
double r = 0, g = 0, b = 0;
|
|
double count = 0;
|
|
gl.glGetDoublev(gl.GL_PROJECTION_MATRIX, tempmat2, 0);
|
|
float mindepth = 1;
|
|
double FACTOR = 1;
|
|
for (int i = 0; i < depths.length; i++)
|
{
|
int x = i / OCCLUSION_SIZE - OCCLUSION_SIZE / 2;
|
int y = i % OCCLUSION_SIZE - OCCLUSION_SIZE / 2;
|
|
double u = (double) x / (OCCLUSION_SIZE / 2);
|
double v = (double) y / (OCCLUSION_SIZE / 2);
|
|
//double sin2 = 4.0 * (x * x + y * y) / OCCLUSION_SIZE / OCCLUSION_SIZE;
|
double sin2 = u * u + v * v;
|
|
//if (x * x + y * y > OCCLUSION_SIZE * OCCLUSION_SIZE / 4)
|
if (sin2 >= 1)
|
{
|
continue;
|
}
|
|
int newindex = i;
|
|
double stretch = 10;
|
|
u *= stretch;
|
v *= stretch;
|
|
// point is (u,v,1)
|
ray.x = u;
|
ray.y = v;
|
ray.z = 1;
|
|
ray.normalize();
|
|
u = ray.x;
|
v = ray.y;
|
|
// double cos = Math.sqrt(1 - sin2);
|
// double sin = Math.sqrt(sin2);
|
//
|
// //double test = Math.atan2(Math.sqrt(sin2), cos) / (Math.PI / 2);
|
// double factor = sin / cos * OCCLUSIONBOOST; // Math.pow(sin,BOOST); // 1 - cos; // Math.atan2(BOOST, cos) / (Math.PI / 2);
|
//
|
// if (factor > 1)
|
// {
|
// factor = 1;
|
// }
|
//
|
// assert (factor >= 0);
|
// //assert(factor <= 1);
|
//
|
// if (sin == 0)
|
// {
|
// sin = 1;
|
// }
|
//
|
// u *= factor / sin;
|
// v *= factor / sin;
|
|
// //x = (int)(u * (OCCLUSION_SIZE/2 - 1) + 0.5) + OCCLUSION_SIZE/2;
|
// //y = (int)(v * (OCCLUSION_SIZE/2 - 1) + 0.5) + OCCLUSION_SIZE/2;
|
// x = (int) Math.floor(u * (OCCLUSION_SIZE / 2 - 1));
|
// y = (int) Math.floor(v * (OCCLUSION_SIZE / 2 - 1));
|
//
|
// //double modu = u * (OCCLUSION_SIZE/2 - 1) - x;
|
// //double modv = v * (OCCLUSION_SIZE/2 - 1) - y;
|
//
|
// x += OCCLUSION_SIZE / 2;
|
// y += OCCLUSION_SIZE / 2;
|
|
/*
|
assert (x>=0);
|
assert (y>=0);
|
if (x >= OCCLUSION_SIZE - 1)
|
x -= 1;
|
if (y >= OCCLUSION_SIZE - 1)
|
y -= 1;
|
*/
|
|
if (!CameraPane.SPHERICAL)
|
{
|
// newindex = x * OCCLUSION_SIZE + y;
|
}
|
|
double scale = ray.z; // 1; // cos
|
|
float depth = depths[newindex];
|
|
/*
|
int newindex2 = (x + 1) * OCCLUSION_SIZE + y;
|
int newindex3 = (x + 1) * OCCLUSION_SIZE + (y+1);
|
int newindex4 = x * OCCLUSION_SIZE + (y+1);
|
scale = (1 - modu) * (1 - modv);
|
r += ((p >> 16) & 0xFF) * scale / 255;
|
g += ((p >> 8) & 0xFF) * scale / 255;
|
b += (p & 0xFF) * scale / 255;
|
p = pixels[newindex2];
|
scale = modu * (1 - modv);
|
r += ((p >> 16) & 0xFF) * scale / 255;
|
g += ((p >> 8) & 0xFF) * scale / 255;
|
b += (p & 0xFF) * scale / 255;
|
p = pixels[newindex3];
|
scale = modu * modv;
|
r += ((p >> 16) & 0xFF) * scale / 255;
|
g += ((p >> 8) & 0xFF) * scale / 255;
|
b += (p & 0xFF) * scale / 255;
|
p = pixels[newindex4];
|
scale = (1 - modu) * modv;
|
*/
|
|
//r += ((p >> 16) & 0xFF) * scale / 255;
|
//g += ((p >> 8) & 0xFF) * scale / 255;
|
//b += (p & 0xFF) * scale / 255;
|
|
if (mindepth > depth)
|
{
|
mindepth = depth;
|
}
|
|
double z_eye = tempmat2[3*4 + 2] / (depth * -2.0 + 1.0 - tempmat2[2*4 + 2]);
|
|
double factor = 1 - Math.exp(-z_eye * z_eye / FACTOR);
|
|
r += factor * scale;
|
g += factor * scale;
|
b += factor * scale;
|
|
count += scale;
|
}
|
|
// if (r != 0 || g != 0 || b != 0)
|
// assert(false);
|
|
double scale = 1.0 / count; // (pixels.length);
|
parent.vertexOcclusion.Set(r * scale, g * scale, b * scale);
|
/**/
|
|
/*
|
gl.glResetHistogram(GL.GL_HISTOGRAM);
|
gl.glReadBuffer(GL.GL_FRONT);
|
gl.glDrawBuffer(GL.GL_FRONT);
|
gl.glMatrixMode(gl.GL_PROJECTION);
|
gl.glLoadIdentity();
|
gl.glOrtho(0, 256, 0, 10000, -1.0, 1.0);
|
gl.glMatrixMode(gl.GL_MODELVIEW);
|
gl.glLoadIdentity();
|
gl.glRasterPos2i(1,1);
|
gl.glCopyPixels(0, 0, OCCLUSION_SIZE, OCCLUSION_SIZE, GL.GL_COLOR);
|
gl.glGetHistogram(GL.GL_HISTOGRAM, true, GL.GL_RGB, GL.GL_FLOAT, histogram);
|
double r=0, g=0, b=0;
|
int i3 = 0;
|
for (int i=0; i<HISTOGRAM_SIZE; i++, i3+=3)
|
{
|
r += histogram.get(i3)*i;
|
g += histogram.get(i3+1)*i;
|
b += histogram.get(i3+2)*i;
|
}
|
double scale = 1.0/HISTOGRAM_SIZE/HISTOGRAM_SIZE; // /65536;
|
vertexOcclusion.Set(r*scale,g*scale,b*scale);
|
/**/
|
|
gl.glFlush();
|
|
stackdepth--;
|
|
//System.err.println("depth = " + stackdepth);
|
// DEBUG
|
/*
|
Object src = pixels;
|
Object dest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
int srcIncr = TEX_SIZE;
|
int destIncr = image.getWidth();
|
int srcPos = 0;
|
int destPos = (image.getHeight() - 1) * destIncr;
|
for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr)
|
{
|
//System.out.println("arraycopy(" + src + ", " + srcPos + ", " + dest + ", " + destPos + ", " + destIncr + ")");
|
System.arraycopy(src, srcPos, dest, destPos, destIncr);
|
}
|
texture = TextureIO.newTexture(new TextureData(0,0, false, image));
|
/**/
|
}
|
|
// Unused routines
|
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
|
{
|
}
|
|
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
|
{
|
}
|
}
|
|
private int GenTexture(GL gl)
|
{
|
int[] tmp = new int[1];
|
gl.glGenTextures(1, tmp, 0);
|
return tmp[0];
|
}
|
|
private void set_light_view_texture_parameters(GL gl)
|
{
|
gl.glBindTexture(GL.GL_TEXTURE_2D, light_view_depth);
|
if (NEAREST)
|
{
|
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); // GL_LINEAR);
|
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); // GL.GL_LINEAR);
|
}
|
else
|
{
|
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
|
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
|
}
|
// gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
|
// gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
|
// gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_MODE_ARB, GL.GL_COMPARE_R_TO_TEXTURE_ARB);
|
// gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_FUNC_ARB, GL.GL_LEQUAL);
|
// gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_DEPTH_TEXTURE_MODE_ARB, GL.GL_INTENSITY);
|
}
|
|
static GLU glu = new GLU();
|
GLUT glut = new GLUT();
|
|
|
public boolean spherical = false;
|
static boolean DEBUG_OCCLUSION = false;
|
static boolean DEBUG_SELECTION = false;
|
boolean OCCLUSION_CULLING = false; //true;
|
public boolean lightMode = false;
|
|
private boolean keepshadow;
|
|
public boolean capsLocked = false; // VR
|
|
static public int indexcount = 0;
|
/*static*/ cColor vertexOcclusion = new cColor();
|
//private int selection_view = -1;
|
int savebuffersize = 0;
|
int AAbuffersize = 0;
|
|
//double[] selectedpoint = new double[3];
|
static Superellipsoid selectedpoint;
|
static Sphere previousselectedpoint = null;
|
static Sphere debugpointG;
|
static Sphere debugpointP;
|
static Sphere debugpointC;
|
static Sphere debugpointR;
|
|
static Sphere debugpoints[] = new Sphere[8];
|
|
static void InitPoints(float radius)
|
{
|
for (int i=0; i<8; i++)
|
{
|
debugpoints[i].radius = radius;
|
debugpoints[i].recalculate();
|
debugpoints[i].material = new cMaterial();
|
|
cColor.RGBtoHSB(i&1, (i&2)>>1, (i&4)>>2, triple);
|
|
debugpoints[i].material.color = triple[0];
|
debugpoints[i].material.modulation = 1f;
|
if (i == 0)
|
debugpoints[i].material.diffuse = 0;
|
if (i == 7)
|
debugpoints[i].material.modulation = 0;
|
}
|
}
|
|
static void DrawPoints(iCameraPane cpane)
|
{
|
for (int i=0; i<8; i++) // first and last are red
|
{
|
LA.matInvert(debugpoints[i].toParent, debugpoints[i].fromParent);
|
debugpoints[i].draw(cpane, null, false, false);
|
cpane.PushMatrix(debugpoints[i].ToParent(), debugpoints[i].GetTransformCount());
|
cpane.DrawString(debugpoints[i]); //.name);
|
cpane.PopMatrix(debugpoints[i].FromParent());
|
}
|
}
|
|
static Object3D debugstuff = new Object3D();
|
static PointFlow pointflow;
|
|
static IntBuffer Savebuffer;
|
static IntBuffer AAbuffer; // = IntBuffer.allocate(MAX_SIZE*MAX_SIZE);
|
static IntBuffer bigAAbuffer;
|
static java.nio.FloatBuffer histogram = BufferUtil.newFloatBuffer(HISTOGRAM_SIZE * 3);
|
//static IntBuffer texturesizebuffer = IntBuffer.allocate(TEX_SIZE * TEX_SIZE);
|
static IntBuffer selectsizebuffer = IntBuffer.allocate(SELECT_SIZE * SELECT_SIZE);
|
static java.nio.FloatBuffer pointselectsizebuffer = java.nio.FloatBuffer.allocate(SELECT_SIZE * SELECT_SIZE);
|
//static IntBuffer occlusionsizebuffer = IntBuffer.allocate(OCCLUSION_SIZE * OCCLUSION_SIZE);
|
static java.nio.FloatBuffer occlusiondepthbuffer = java.nio.FloatBuffer.allocate(OCCLUSION_SIZE * OCCLUSION_SIZE);
|
|
static IntBuffer occlusioncolorbuffer = IntBuffer.allocate(OCCLUSION_SIZE * OCCLUSION_SIZE);
|
|
static BufferedImage bufimage = new BufferedImage(TEX_SIZE, TEX_SIZE, BufferedImage.TYPE_INT_RGB);
|
static BufferedImage textest = new cBufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
static java.util.Vector<BufferedImage> billboards = new java.util.Vector<BufferedImage>();
|
static java.util.Vector<IntBuffer> bbbuffers = new java.util.Vector<IntBuffer>();
|
static BufferedImage balloon = new cBufferedImage(TEXT_WIDTH*8, TEXT_HEIGHT*8, BufferedImage.TYPE_INT_ARGB);
|
static IntBuffer textbuffer = null; // IntBuffer.allocate(TEXT_WIDTH*8*8 * TEXT_HEIGHT);
|
// Depth buffer format
|
//private int depth_format;
|
|
public void NextIndex()
|
{
|
indexcount+=16;
|
GetGL().glColor3d(((indexcount >>> 16) & 255) / 255.0, ((indexcount >>> 8) & 255) / 255.0, ((indexcount) & 255) / 255.0);
|
//objects[indexcount] = o;
|
//System.out.println("indexcount = " + indexcount);
|
}
|
|
static public boolean Match(int count)
|
{
|
indexcount+=16;
|
//System.out.println("indexcount = " + indexcount + " vs " + count);
|
//new Exception().printStackTrace();
|
return count == indexcount;
|
}
|
//static Object3D[] objects = new Object3D[256*256*16];
|
Mat4f m = new Mat4f();
|
|
private void eye_linear_texgen(GL gl)
|
{
|
m.makeIdent();
|
//gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, tempmat, 0);
|
//SetColumnMajorData(m, tempmat);
|
|
set_texgen_planes(gl, GL.GL_EYE_PLANE, m);
|
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
|
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
|
gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
|
gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
|
}
|
float[] row = new float[4];
|
int[] coord = {GL.GL_S, GL.GL_T, GL.GL_R, GL.GL_Q};
|
|
private void set_texgen_planes(GL gl, int plane_type, Mat4f m)
|
{
|
for (int i = 0; i < 4; i++)
|
{
|
getRow(m, i, row);
|
gl.glTexGenfv(coord[i], plane_type, row, 0);
|
}
|
}
|
|
private static void getRow(Mat4f m, int row, float[] out)
|
{
|
out[0] = m.get(row, 0);
|
out[1] = m.get(row, 1);
|
out[2] = m.get(row, 2);
|
out[3] = m.get(row, 3);
|
}
|
|
private void texgen(GL gl, boolean enable)
|
{
|
if (enable)
|
{
|
gl.glEnable(GL.GL_TEXTURE_GEN_S);
|
gl.glEnable(GL.GL_TEXTURE_GEN_T);
|
gl.glEnable(GL.GL_TEXTURE_GEN_R);
|
gl.glEnable(GL.GL_TEXTURE_GEN_Q);
|
} else
|
{
|
gl.glDisable(GL.GL_TEXTURE_GEN_S);
|
gl.glDisable(GL.GL_TEXTURE_GEN_T);
|
gl.glDisable(GL.GL_TEXTURE_GEN_R);
|
gl.glDisable(GL.GL_TEXTURE_GEN_Q);
|
}
|
}
|
}
|