package de.nameless.graphicEngine;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Date;
import java.util.Vector;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import com.sun.opengl.util.BufferUtil;
import de.nameless.gameEngine.util.DirectoryCrawler;
import de.nameless.graphicEngine.animation.NEAnimator;
import de.nameless.graphicEngine.lib.NEFireBall;
import de.nameless.graphicEngine.model.NEModelManager;
import de.nameless.graphicEngine.texture.NEMaterialManager;
//import com.sun.opengl.util.texture.*;
/**
* Der Renderer wird bei einem GLDisplay Registriert und Rendert alle im angegeben
* NEGraphicalObjectManager enthaltenen Objekte.
*/
public class Renderer implements GLEventListener{
// f�r die vorzuladenen Dateien.
public String[] preLoadMaps;
public String[] preLoadModels;
/**
* Mit der hilfe des Texturemanagers werden die Texturen gebunden und geladen.
*/
private NEMaterialManager nEMaterialManager = null;
/**
* Hier sind alle zu rendernden Grafischen objekte hinterlegt
*/
private NEGraphicalObjectManager GOJManager = null;
/**
* Hier wird der Animator gespeichert, der f�r das animieren verwendet werden soll.
*/
private NEAnimator animator = null;
/**
* Der Zeitfaktor f�r Time Based move
* Die angabe erfolgt in sec. <b> nicht </b> milisec.!
*/
public float TBM;
/**
* Aktuelle Zeit
*/
private Date now;
/**
* Aus OGL.
*/
private GLU glu = new GLU();
/**
* assoziation zum Display
*/
private GLDisplay display;
private float[] lightAmbient = {1f, 1f, 1f, 1f};
private float[] lightDiffuse = {5.0f, 5.0f, 5.0f, 1.0f};
private float[] lightPosition = {0.0f, 0.0f, 20.0f, 1.0f};
private boolean LightEnabled = true;
private boolean initialized = false;
private short selectionCounter = 0;
public Renderer() {
TBM = 0f;
now = new Date();
}
/**
* Diese metode wird kurz vor dem ersten zeichen durch das Drawable augerufen.
* Hier sollen wird OGL initialisiert
* @param gLDrawable The GLAutoDrawable object.
*/
public void init(GLAutoDrawable gLDrawable) {
final GL gl = gLDrawable.getGL();
NEModelManager.gl = gl;
//-----------------------------------------SetUp OGL-----------------------------------------------//
//gl.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0, 0, 0, 1); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations
gl.glEnable(GL.GL_TEXTURE_2D);
//gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); // Korrektes Blending
// Set up lighting
if(LightEnabled){
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, this.lightAmbient, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, this.lightDiffuse, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, this.lightPosition, 0);
gl.glEnable(GL.GL_LIGHT1);
gl.glEnable(GL.GL_LIGHTING);
}
//-----------------------------------------SetUp OGL-----------------------------------------------//
// Models vorladen und compelieren
this.preLoadModels = DirectoryCrawler.getNameOfFiles("resources/Models/", "ms3d");
NEModelManager.getInstance().preLoad(preLoadModels);
NEModelManager.getInstance().preCompileAllLoaded(gl);
// Texturen vorladen
this.preLoadMaps = DirectoryCrawler.getNameOfFiles("resources/Images/", "png,jpg");
NEMaterialManager.getInstance().preLoad(preLoadMaps);
this.initialized = true;
}
/**
* Diese metode ist einer der GLEvents auf die der Rendere h�rt.
* Alle Objekte des verbundenen NEGraphicalObjectManager werden mit hilfe des angeschlossenen
* NETextureManager gerendert.
* @param gLDrawable The GLAutoDrawable object.
*/
public void display(GLAutoDrawable gLDrawable) {
final GL gl = gLDrawable.getGL();
/* nimmt die zeit zwischen zwei aufrufen */
Date d = new Date();
TBM = (d.getTime() - now.getTime())/1000f;
now = new Date();
this.display.setTitle(GOJManager.getAll().size() + " Objekte" + " ,FPS: " + Math.round(1/TBM));
// Die animationen durchf�hren
if(animator != null){
animator.doAnimations(TBM);
}
if(selectionCounter++ >= 4){
this.selection(gl);
selectionCounter=0;
}
this.renderContent(gl);
}
public void renderContent(GL gl){
// OGL f�r das Rendern eines Frames vorbereiten
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); // Reset The View
gl.glRotatef(-45, 1, 0, 0);
gl.glInitNames();
gl.glPushName(0);
Vector<NEabstractGraphicObject> test = GOJManager.getAll();
if(nEMaterialManager != null && GOJManager != null){
for (NEabstractGraphicObject o : GOJManager.getAll()) { // alle Bekannten Objekte sich rendern lassen
if(!o.isHidden()){
//nEMaterialManager.bindObjectTexture(o);
//o.SetupGLForTextur(gl);
o.render(gl,TBM);
}
}
GOJManager.flush();
// System.out.println(GOJManager);
}else{
System.out.println("Missing Manager!");
}
}
public void selection(GL gl){
// Seclection vorbereiten -------------------------------------
// Buffer �bergeben
int selbuffsize = 512;
IntBuffer selectionBuffer = BufferUtil.newIntBuffer(selbuffsize);
gl.glSelectBuffer(selbuffsize, selectionBuffer);
// ViewPost Info holen
int[] viewPort = new int[4];
IntBuffer viewPortWrapper = IntBuffer.wrap(viewPort);
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPortWrapper);
// die gr��e des Fensters als Float einstellen
float w = Float.valueOf(viewPort[2]);
float h = Float.valueOf(viewPort[3]);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glRenderMode(GL.GL_SELECT);
gl.glPushMatrix();
gl.glLoadIdentity();
glu.gluPickMatrix(display.getMouseX(), viewPort[3]-display.getMouseY(), 1, 1, viewPortWrapper);
glu.gluPerspective(45.0f, w/h, 1f, 100.0);
renderContent(gl);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
//System.out.println(display.getMouseX() + "," + (viewPort[3]-display.getMouseY()));
int hits = gl.glRenderMode(GL.GL_RENDER);
display.setObjectsUnderMouse(this.processSelection(selectionBuffer, hits));
// Seclection vorbereiten -------------------------------------
}
private NEabstractGraphicObject[] processSelection(IntBuffer selectionBuffer, Integer hits){
NEabstractGraphicObject[] results = new NEabstractGraphicObject[hits];
//System.out.println(hits);
for(int i = 0; i < hits;i++){
//System.out.print("(" + NEabstractGraphicObject.getInstanceById( selectionBuffer.get(3+i*4)) + " " + selectionBuffer.get(3+i*4) +")");
results[hits-i-1] = NEabstractGraphicObject.getInstanceById( selectionBuffer.get(3+i*4));
}
//System.out.println();
return results;
}
/** Called when the display mode has been changed. <B>!! CURRENTLY UNIMPLEMENTED IN JOGL !!</B>
* @param gLDrawable The GLAutoDrawable object.
* @param modeChanged Indicates if the video mode has changed.
* @param deviceChanged Indicates if the video device has changed.
*/
public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
}
/**
* (Aus beispiel �bernommen f�r das Neusetzten der perspektive bei neuer fenstergr��e.)
*
* Called by the drawable during the first repaint after the component has
* been resized. The client can update the viewport and view volume of the
* window appropriately, for example by a call to
* GL.glViewport(int, int, int, int); note that for convenience the component
* has already called GL.glViewport(int, int, int, int)(x, y, width, height)
* when this method is called, so the client may not have to do anything in
* this method.
* @param gLDrawable The GLAutoDrawable object.
* @param x The X Coordinate of the viewport rectangle.
* @param y The Y coordinate of the viewport rectanble.
* @param width The new width of the window.
* @param height The new height of the window.
*/
public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
final GL gl = gLDrawable.getGL();
if (height <= 0) // avoid a divide by zero error!
height = 1;
final float h = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, h, 1f, 100.0);
//gl.glOrtho(-100.0f, 100.0f, -100.0f, 100.0f, -500.0f, 500.0f);
//gl.glScalef(20.0f, 20.0f, 20.0f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
/**
* Hier wird der gojManager gesetzt
* @param gojmanager the gojmanager to set
*/
public void setGojmanager(NEGraphicalObjectManager gojmanager) {
this.GOJManager = gojmanager;
}
/**
*
* @return der Grafische objekt manager
*/
public NEGraphicalObjectManager getGOJManager() {
return GOJManager;
}
/**
*
* @return der Texture manager
*/
public NEMaterialManager getNETextureManager() {
return nEMaterialManager;
}
/**
* hier wird der Texturmanager gesetzt
* @param textureManager
*/
public void setNETextureManager(NEMaterialManager textureManager) {
nEMaterialManager = textureManager;
}
/**
* @return the animator
*/
public NEAnimator getAnimator() {
return animator;
}
/**
* @param animator the animator to set
*/
public void setAnimator(NEAnimator animator) {
this.animator = animator;
}
/**
* @param display the display to set
*/
public void setDisplay(GLDisplay display) {
this.display = display;
}
public boolean isInit(){
return initialized;
}
}