/**
*
*/
package com.momega.spacesimulator.opengl;
import javax.media.opengl.GL2;
import com.jogamp.common.nio.Buffers;
/**
* @author martin
*
*/
public class GLLineUtils {
public static void line( GL2 gl, double x1, double y1, double x2, double y2, //coordinates of the line
double w, //width/thickness of the line in pixel
double Cr, double Cg, double Cb, //RGB color components
double Br, double Bg, double Bb, //color of background when alphablend=false,
// Br=alpha of color when alphablend=true
boolean alphablend) //use alpha blend or not
{
double t=0; double R=0; double f=w-(int)w;
double A;
if ( alphablend)
A=Br;
else
A=1.0f;
//determine parameters t,R
/* */if ( w>=0.0 && w<1.0) {
t=0.05; R=0.48+0.32*f;
if ( !alphablend) {
Cr+=0.88*(1-f);
Cg+=0.88*(1-f);
Cb+=0.88*(1-f);
if ( Cr>1.0) Cr=1.0d;
if ( Cg>1.0) Cg=1.0d;
if ( Cb>1.0) Cb=1.0d;
} else {
A*=f;
}
} else if ( w>=1.0 && w<2.0) {
t=0.05+f*0.33; R=0.768+0.312*f;
} else if ( w>=2.0 && w<3.0){
t=0.38+f*0.58; R=1.08;
} else if ( w>=3.0 && w<4.0){
t=0.96+f*0.48; R=1.08;
} else if ( w>=4.0 && w<5.0){
t=1.44+f*0.46; R=1.08;
} else if ( w>=5.0 && w<6.0){
t=1.9+f*0.6; R=1.08;
} else if ( w>=6.0){
double ff=w-6.0;
t=2.5+ff*0.50; R=1.08;
}
//printf( "w=%f, f=%f, C=%.4f\n", w,f,C);
//determine angle of the line to horizontal
double tx=0,ty=0; //core thinkness of a line
double Rx=0,Ry=0; //fading edge of a line
double cx=0,cy=0; //cap of a line
double ALW=0.01;
double dx=x2-x1;
double dy=y2-y1;
if ( Math.abs(dx) < ALW) {
//vertical
tx=t; ty=0;
Rx=R; Ry=0;
if ( w>0.0 && w<1.0)
tx*=8;
else if ( w==1.0)
tx*=10;
} else if ( Math.abs(dy) < ALW) {
//horizontal
tx=0; ty=t;
Rx=0; Ry=R;
if ( w>0.0 && w<1.0)
ty*=8;
else if ( w==1.0)
ty*=10;
} else {
if ( w < 3) { //approximate to make things even faster
double m=dy/dx;
//and calculate tx,ty,Rx,Ry
if ( m>-0.4142 && m<=0.4142) {
// -22.5< angle <= 22.5, approximate to 0 (degree)
tx=t*0.1; ty=t;
Rx=R*0.6; Ry=R;
} else if ( m>0.4142 && m<=2.4142) {
// 22.5< angle <= 67.5, approximate to 45 (degree)
tx=t*-0.7071; ty=t*0.7071;
Rx=R*-0.7071; Ry=R*0.7071;
} else if ( m>2.4142 || m<=-2.4142) {
// 67.5 < angle <=112.5, approximate to 90 (degree)
tx=t; ty=t*0.1;
Rx=R; Ry=R*0.6;
} else if ( m>-2.4142 && m<-0.4142) {
// 112.5 < angle < 157.5, approximate to 135 (degree)
tx=t*0.7071; ty=t*0.7071;
Rx=R*0.7071; Ry=R*0.7071;
} else {
// error in determining angle
//printf( "error in determining angle: m=%.4f\n",m);
}
} else { //calculate to exact
dx=y1-y2;
dy=x2-x1;
double L=Math.sqrt(dx*dx+dy*dy);
dx/=L;
dy/=L;
cx=-0.6*dy; cy=0.6*dx;
tx=t*dx; ty=t*dy;
Rx=R*dx; Ry=R*dy;
}
}
//draw the line by triangle strip
double line_vertex[]=
{
x1-tx-Rx, y1-ty-Ry, //fading edge1
x2-tx-Rx, y2-ty-Ry,
x1-tx,y1-ty, //core
x2-tx,y2-ty,
x1+tx,y1+ty,
x2+tx,y2+ty,
x1+tx+Rx, y1+ty+Ry, //fading edge2
x2+tx+Rx, y2+ty+Ry
};
gl.glVertexPointer(2, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_vertex));
if ( !alphablend) {
double line_color[]=
{
Br,Bg,Bb,
Br,Bg,Bb,
Cr,Cg,Cb,
Cr,Cg,Cb,
Cr,Cg,Cb,
Cr,Cg,Cb,
Br,Bg,Bb,
Br,Bg,Bb
};
gl.glColorPointer(3, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
} else {
double line_color[]=
{
Cr,Cg,Cb,0,
Cr,Cg,Cb,0,
Cr,Cg,Cb,A,
Cr,Cg,Cb,A,
Cr,Cg,Cb,A,
Cr,Cg,Cb,A,
Cr,Cg,Cb,0,
Cr,Cg,Cb,0
};
gl.glColorPointer(4, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
}
if ( (Math.abs(dx) < ALW || Math.abs(dy) < ALW) && w<=1.0) {
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, 6);
} else {
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, 8);
}
//cap
if ( w < 3) {
//do not draw cap
} else {
//draw cap
double line_vertex2[]=
{
x1-Rx+cx, y1-Ry+cy, //cap1
x1+Rx+cx, y1+Ry+cy,
x1-tx-Rx, y1-ty-Ry,
x1+tx+Rx, y1+ty+Ry,
x2-Rx-cx, y2-Ry-cy, //cap2
x2+Rx-cx, y2+Ry-cy,
x2-tx-Rx, y2-ty-Ry,
x2+tx+Rx, y2+ty+Ry
};
gl.glVertexPointer(2, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_vertex2));
if ( !alphablend) {
double line_color[]=
{
Br,Bg,Bb, //cap1
Br,Bg,Bb,
Cr,Cg,Cb,
Cr,Cg,Cb,
Br,Bg,Bb, //cap2
Br,Bg,Bb,
Cr,Cg,Cb,
Cr,Cg,Cb
};
gl.glColorPointer(3, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
} else {
double line_color[]=
{
Cr,Cg,Cb,0, //cap1
Cr,Cg,Cb,0,
Cr,Cg,Cb,A,
Cr,Cg,Cb,A,
Cr,Cg,Cb,0, //cap2
Cr,Cg,Cb,0,
Cr,Cg,Cb,A,
Cr,Cg,Cb,A
};
gl.glColorPointer(4, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
}
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, 4);
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 4, 4);
}
}
/*a skimmed version of line(); no color, no thickness control
* draws near-perfectly a black "hair line" of thickness 1px
* when alphablend is false, it assumes drawing on a white surface
* when alphablend is true, it draws with alpha */
public static void hair_line(GL2 gl, double x1, double y1, double x2, double y2, boolean alphablend)
{
double t=0.05; double R=0.768;
double C=0.0;
//determine angle of the line to horizontal
double tx=0,ty=0, Rx=0,Ry=0;
double ALW=0.01;
double dx=x2-x1;
double dy=y2-y1;
if ( Math.abs(dx) < ALW) {
tx=t*10; ty=0;
Rx=R; Ry=0;
} else if ( Math.abs(dy) < ALW) {
tx=0; ty=t*10;
Rx=0; Ry=R;
} else {
double m=dy/dx;
if ( m>-0.4142 && m<=0.4142) {
// -22.5< angle <= 22.5, approximate to 0 (degree)
tx=t*0.1; ty=t;
Rx=R*0.6; Ry=R;
} else if ( m>0.4142 && m<=2.4142) {
// 22.5< angle <= 67.5, approximate to 45 (degree)
tx=t*-0.7071; ty=t*0.7071;
Rx=R*-0.7071; Ry=R*0.7071;
} else if ( m>2.4142 || m<=-2.4142) {
// 67.5 < angle <=112.5, approximate to 90 (degree)
tx=t; ty=t*0.1;
Rx=R; Ry=R*0.6;
} else if ( m>-2.4142 && m<-0.4142) {
// 112.5 < angle < 157.5, approximate to 135 (degree)
tx=t*0.7071; ty=t*0.7071;
Rx=R*0.7071; Ry=R*0.7071;
}
}
//draw the line by triangle strip
double line_vertex[]=
{
x1-tx-Rx, y1-ty-Ry, //fading edge1
x2-tx-Rx, y2-ty-Ry,
x1-tx,y1-ty, //core
x2-tx,y2-ty,
x1+tx,y1+ty,
x2+tx,y2+ty,
x1+tx+Rx, y1+ty+Ry, //fading edge2
x2+tx+Rx, y2+ty+Ry
};
gl.glVertexPointer(2, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_vertex));
if ( !alphablend) {
double line_color[]=
{ 1,1,1,
1,1,1,
0,0,0,
0,0,0,
0,0,0,
0,0,0,
1,1,1,
1,1,1
};
gl.glColorPointer(3, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
} else {
double line_color[]=
{ 0,0,0,0,
0,0,0,0,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,0,
0,0,0,0
};
gl.glColorPointer(4, GL2.GL_DOUBLE, 0, Buffers.newDirectDoubleBuffer(line_color));
}
if ( (Math.abs(dx) < ALW || Math.abs(dy) < ALW)) {
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, 6);
} else {
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, 8);
}
}
// /*as a fall back to line()*/
// void line_raw( double x1, double y1, double x2, double y2,
// double w,
// double Cr, double Cg, double Cb,
// double,double,double, bool)
// {
// glLineWidth(w);
// float line_vertex[]=
// {
// x1,y1,
// x2,y2
// };
// float line_color[]=
// {
// Cr,Cg,Cb,
// Cr,Cg,Cb
// };
// glVertexPointer(2, GL_FLOAT, 0, line_vertex);
// glColorPointer(3, GL_FLOAT, 0, line_color);
// glDrawArrays(GL_LINES, 0, 2);
// }
//
}