package de.taliis.plugins.adt.jogl3D;
import java.awt.Font;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import starlight.taliis.core.chunks.ChunkNotFoundException;
import starlight.taliis.core.chunks.adt.*;
import starlight.taliis.core.files.adt;
import de.taliis.editor.fileMananger;
import de.taliis.editor.openedFile;
import de.taliis.editor.plugin.*;
import de.taliis.plugins.wowimage.blp;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.BufferUtil;
import com.sun.opengl.util.j2d.TextRenderer;
public
class Tutorial2
implements GLEventListener,
KeyListener,
MouseListener
{
Animator animator;
// for general stuff
private boolean draw = true;
private int render_mode = GL.GL_FILL;
// for our translations
private int lastX=0, lastY=0;
private float zOffset = -7.0f;
private float yRot=0f, zRot=0f, xRot=0f;
private float zBase = 0f;
public float texDetail = 8.0f;
public final static float TEX_RANGE = 62.0f/64.0f;
// display stuff
int textures[];
int textemp[][]=new int[256][4];
int alphamaps[][];
int shadow = 0;
//int animated[]= new int[4];
int tex[]= new int[4];
Plugin mpqLoader;
fileMananger fm;
// text reneder
TextRenderer renderer;
// light
// yellow diffuse : color where light hit directly the object's surface
float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
// red ambient : color applied everywhere
float[] lightAmbient = {.1f, .1f, .1f, 1.0f};
float[] lightPosition= {64*1.0f, 64*1.0f, -7.0f, 1.0f};
// adt object
adt obj;
// stupid couning value ..
int cout = 0;
//ByteBuffer buff[][]=new ByteBuffer[256][4];
public Tutorial2(adt obj,fileMananger fm, Plugin mpqLoader) {
this.obj = obj;
this.mpqLoader = mpqLoader;
this.fm = fm;
calcZBase();
}
/**
* Main loop
*/
public void display(GLAutoDrawable arg0) {
if(!draw) return;
GL gl = arg0.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); //Clear the buffers
gl.glLoadIdentity(); //Reset the view
gl.glTranslatef(0.0f, -2.0f, zOffset); //Translate the scene backwards
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, render_mode);
gl.glCullFace(GL.GL_FRONT);
gl.glEnable(GL.GL_CULL_FACE);/**/
gl.glRotatef(xRot, 1f, 0f, 0f);
gl.glRotatef(yRot, 0f, 1f, 0f);
gl.glRotatef(zRot, 0f, 0f, 1f);
// render the mechs
for(int x=0;x<16;x++){
for(int y=0;y<16;y++){
mechNoLOT(gl, x, y);
}
}
// text dispays
doTextStuff(arg0);
//TODO draw the sun
processEvents(arg0);
}
/**
* We print a lot of stuff. Here.
* @param arg0
*/
private void doTextStuff(GLAutoDrawable arg0) {
renderer.beginRendering(arg0.getWidth(), arg0.getHeight());
renderer.setColor(1f, 1f, 1f, 1f);
renderer.draw("Rotations: "+xRot+"x "+yRot+"y "+zRot+"z " , 10, 10);
renderer.endRendering();
}
/**
* Prints the default mech without
* Leve of Detail (-> 9x9 points)
*/
private void mechNoLOT(GL gl, int index_x, int index_y) {
float mul = 0.01f; // scale multiplicator
float dim = MCNK.gfxWidth * mul;
float dimc = dim / 8;
float texmul = dim;
float alphamul = texmul*0.4f;
MCNK field = obj.mcnk[index_x*16+index_y];
MCVT height = field.mcvt;
MCNR nrm = field.mcnr;
int nTextures;
// translation
float zmod = (field.getPosZ()-zBase)*mul;
float xmod = dim*index_x;
float ymod = dim*index_y;
gl.glTranslatef(xmod, ymod, zmod);
gl.glColor4f( 1f, 1f, 1f, 1f );
nTextures=obj.mcnk[index_x*16+index_y].mcly.getLength();
int nc = 0; // normal counter
/**
* Drawing the ground texture, I think it never has an alphamap
* but do I need to create strips for evry texture?
* Well I found no other way, perhaps somebody else will o.O
*/
MCLY_Entry layer_temp;
gl.glEnable(GL.GL_BLEND);
gl.glDepthMask(false);
//gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_DST_COLOR);
//gl.glEnable(GL.GL_BLEND);
gl.glAlphaFunc(GL.GL_GREATER,0.1f);
gl.glEnable(GL.GL_ALPHA_TEST);
/**
* Drawing layers with alphablending
*/
for(int i=0;i<nTextures;i++){
nc=0;
layer_temp = obj.mcnk[index_x*16+index_y].mcly.getLayer(i);
int j = layer_temp.getTextureID();
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glEnable(GL.GL_TEXTURE_2D);
if(i==0)
gl.glBindTexture(GL.GL_TEXTURE_2D, alphamaps[(index_x*16+index_y)][3]);
else
gl.glBindTexture(GL.GL_TEXTURE_2D, alphamaps[(index_x*16+index_y)][i-1]);
//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.glActiveTexture(GL.GL_TEXTURE0);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[j]);
//gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
//gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
gl.glTexEnvi(GL.GL_SRC_ALPHA, GL.GL_DST_COLOR, GL.GL_BLEND);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
// Mesh and point generation
int pc = 0;
for(int y=0; y<8; y++) {
for(int x=0; x<9; x++) {
// top point
/*gl.glNormal3f(
(float)nrm.getXNorm(nc),
(float)nrm.getYNorm(nc),
(float)nrm.getZNorm(nc)
);
nc++;/**/
gl.glVertex3f( x*dimc, y*dimc, mul*height.getValNoLOD(y, x));
gl.glMultiTexCoord2f(GL.GL_TEXTURE0,x*texmul,y*texmul);
gl.glMultiTexCoord2f(GL.GL_TEXTURE1,y*alphamul,x*alphamul);
gl.glVertex3f( x*dimc, (y+1)*dimc, mul*height.getValNoLOD(y+1, x));
gl.glMultiTexCoord2f(GL.GL_TEXTURE0,x*texmul,(y+1)*texmul);
gl.glMultiTexCoord2f(GL.GL_TEXTURE1,(y-1.5f)*alphamul,x*alphamul);
pc++;
}
}
gl.glEnd();
}
//gl.glEnable(GL.GL_DEPTH_TEST); // Enable Depth Testing
//gl.glDisable(GL.GL_BLEND);
// back translation
gl.glTranslatef(-xmod, -ymod, -zmod);
}
private void GetTextures(GL gl) throws IOException, ChunkNotFoundException {
String temp[];
int tempi=0;
tempi=obj.mtex.getLenght();
textures=new int[tempi];
TextureReader.Texture texture[] = new TextureReader.Texture[tempi];
gl.glGenTextures(tempi, textures, 0);
temp=new String[tempi];
for(int i=0;i<tempi;i++)
temp[i]=obj.mtex.getValueNo(i);
for(int i=0;i<tempi;i++){
openedFile of;
//if(mpqLoader==null) continue;
//if(!(mpqLoader instanceof PluginRequest)) continue;
PluginRequest mpql = (PluginRequest)mpqLoader;
of = mpql.requestRessource(temp[i]);
texture[i] = TextureReader.readTexture((blp) of.obj);
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[i]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
//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_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, texture[i].getWidth(), texture[i].getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, texture[i].getPixels());
System.out.println("Created Texture: "+temp[i]);
}
}
private void GetAlpha(GL gl) throws IOException{
for(int x=0; x<16; x++) {
for(int y=0; y<16; y++) {
int layers = obj.mcnk[x*16+y].mcal.getLenght();
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glGenTextures(layers, alphamaps[x*16+y], 0);
//if(layers==0) continue;
// preload data
int data[] = new int[4096];
for(int layer=0; layer<layers; layer++){
MCAL_Entry mce = obj.mcnk[x*16+y].mcal.getLayerNo(layer);
ByteBuffer buff = ByteBuffer.allocate(4096*4) ;
//buff.allocate(4096);
for(int c=0; c<4096; c++) {
// color = old color | new color>>layer*16bit
data[c] = (mce.getValue(c)&0xff);
// combined
}
for(int c=0;c<4096;c++)
buff.putInt(data[c]);
buff.position(0);
gl.glBindTexture(GL.GL_TEXTURE_2D, alphamaps[x*16+y][layer]);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0,GL.GL_ALPHA,64, 64, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);
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);
}}
}
}
/*
private void GetAlpha(GL gl) throws IOException{
for(int x=0; x<16; x++) {
for(int y=0; y<16; y++) {
ByteBuffer buff = ByteBuffer.allocate(4096*4) ;
int layers = obj.mcnk[x*16+y].mcal.getLenght();
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glGenTextures(1, alphamaps[x*16+y], 0);
//if(layers==0) continue;
// preload data
int data[] = new int[4096*4];
buff.allocate(4096*4);
for(int layer=0; layer<layers; layer++){
MCAL_Entry mce = obj.mcnk[x*16+y].mcal.getLayerNo(layer);
for(int c=0; c<4096; c++) {
// color = old color | new color>>layer*16bit
int newcolor = (mce.getValue(c)&0xff)<<(layer*8);
// combined
data[c] = data[c] | newcolor;
}
for(int c=0;c<4096;c++)
buff.putInt(data[c]);
buff.position(0);
gl.glBindTexture(GL.GL_TEXTURE_2D, alphamaps[x*16+y][0]);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0,GL.GL_RGBA,64, 64, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);
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);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
}}
}
}
*/
private void calcZBase() {
zBase = obj.mcnk[0].getPosZ();
for(int i=1; i<16*16; i++) {
zBase = (zBase + obj.mcnk[i].getPosZ()) / 2;
System.out.println(i + " v" + obj.mcnk[i].getPosZ() + " b" + zBase);
}
}
public void reshape(GLAutoDrawable glDrawable, int x, int y, int width, int height) {
final GL gl = glDrawable.getGL();
final GLU glu = new GLU();
if(height <= 0)
height = 1;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION); //Select the Projectionmatrix
gl.glLoadIdentity(); //Reset the current matrix
glu.gluPerspective(45.0f, width / height, 0.1f, 1000.0f); //set the Viewing Volume
gl.glMatrixMode(GL.GL_MODELVIEW); //select The Modelview Matrix
gl.glLoadIdentity(); //set the ModelView matrix to identity
}
public void init(GLAutoDrawable glDrawable) {
renderer = new TextRenderer(
new Font("SansSerif", Font.BOLD, 10)
);
final GL gl = glDrawable.getGL();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0); //Enable Clearing of the Depth buffer
gl.glDepthFunc(GL.GL_LEQUAL); //Type of Depth test
gl.glEnable(GL.GL_DEPTH_TEST); //Enable Depth Testing
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
// light
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, lightAmbient, 0);
//Diffuse light component
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, lightDiffuse, 0);
//Light position
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0);
//Enable the first light and the lighting mode
gl.glEnable(GL.GL_LIGHT0);
gl.glEnable(GL.GL_LIGHTING);
// material
gl.glEnable(GL.GL_COLOR_MATERIAL); // Enable Color Material
gl.glEnable(GL.GL_ALPHA);
// shading
gl.glShadeModel(GL.GL_SMOOTH);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glActiveTexture(GL.GL_TEXTURE0);
try {
GetTextures(gl);
System.out.println("Textures");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ChunkNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
alphamaps= new int[256][4];
System.out.println("Alphaarray created");
System.out.println("Starting Alpha reading");
try {
GetAlpha(gl);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Alpha loaded!");
animator = new Animator(glDrawable);
animator.start();
}
public void processEvents(GLDrawable glDrawable) {
}
public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {}
/* EVENTS */
public void keyPressed(KeyEvent ke) {
switch(ke.getKeyCode()) {
// x rotation
case KeyEvent.VK_D:
yRot += 1;
break;
case KeyEvent.VK_A:
yRot -= 1;
break;
// y rotation
case KeyEvent.VK_W:
xRot += 1;
break;
case KeyEvent.VK_S:
xRot -= 1;
break;
case KeyEvent.VK_Q:
zRot -= 1;
break;
case KeyEvent.VK_E:
zRot += 1;
break;
default:
//System.out.println("Event");
}
}
public void keyReleased(KeyEvent ke) {
switch(ke.getKeyCode()) {
//update on off
case KeyEvent.VK_ESCAPE:
draw = !draw;
break;
// fill on off
case KeyEvent.VK_F:
if(render_mode==GL.GL_FILL) render_mode = GL.GL_LINE;
else render_mode = GL.GL_FILL;
break;
default:
//System.out.println("Event");
}
}
public void keyTyped(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}