package com.momega.spacesimulator.opengl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.media.opengl.*; import static javax.media.opengl.GL.*; import static javax.media.opengl.fixedfunc.GLMatrixFunc.GL_MODELVIEW; import static javax.media.opengl.fixedfunc.GLMatrixFunc.GL_PROJECTION; /** * The abstract render used render any OPENGL objects. * * Created by martin on 4/19/14. */ public abstract class AbstractGLRenderer implements GLEventListener { private static final Logger logger = LoggerFactory.getLogger(AbstractGLRenderer.class); private boolean reshape = false; /** * The default implementation of initializing of the renderer. It creates GLU and GLUT objects * @param drawable the OPENGL canvas */ public final void init(GLAutoDrawable drawable) { logger.info("renderer initializing"); GL2 gl = drawable.getGL().getGL2(); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // set background (clear) color gl.glClearDepth(1.0f); // set clear depth value to farthest gl.glDepthMask(true); gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); gl.glDepthFunc(GL.GL_LESS); gl.glEnable(GL_DEPTH_TEST); // for textures gl.glShadeModel(GL2.GL_SMOOTH); // try setting this to GL_FLAT and see what happens. gl.glEnable(GL.GL_BLEND); gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA); gl.glEnable( GL2.GL_POLYGON_SMOOTH ); gl.glEnable( GL2.GL_POINT_SMOOTH ); gl.glEnable( GL2.GL_LINE_SMOOTH ); //gl.glAlphaFunc(GL.GL_GREATER, 0.1f); setup(drawable); logger.info("renderer initialized"); } /** * The default display method * @param drawable the OPENGL canvas */ public final void display(GLAutoDrawable drawable) { reshapeRequired(drawable); GL2 gl = drawable.getGL().getGL2(); gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // clear color and depth buffers if (isModelReady()) { // computers the scene computeScene(); // prepare gl.glLoadIdentity(); setCamera(); // computes the view object computeView(drawable); } // draw all objects draw(drawable); } protected boolean isModelReady() { return true; } /** * Prepares projection data. * @param drawable The canvas */ protected void computeView(GLAutoDrawable drawable) { // do nothing } /** * Called whenever the reshape method has to be me called * @param drawable */ protected final void reshapeRequired(GLAutoDrawable drawable) { if (reshape) { logger.debug("reshape required manually"); reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()); reshape = false; } } /** * Computes scene. The method computes the positions all the objects in the scene. */ protected abstract void computeScene(); /** * Renders the objects computed in {@link #computeScene()}. * @param drawable */ protected abstract void draw(GLAutoDrawable drawable); /** * Prepares the perspective * @param gl the OpenGL context * @param aspect the aspect */ protected abstract void setPerspective(GL2 gl, double aspect); /** * Setup the camera */ protected abstract void setCamera(); /** * Initializes the GL context * @param gl */ protected abstract void setup(GLAutoDrawable gl); /** * The default implementation of the dispose method * @param drawable the OPENGL canvas */ public final void dispose(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); dispose(gl); logger.info("renderer disposed"); } /** * Disposes the GL context * @param gl the OpenGL context */ protected void dispose(GL2 gl) { // do nothing, ready for override } /** * Whenever the window is reshaped, redefine the coordinate system and * redraw the stencil area. */ public final void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { logger.debug("reshape called {}x{}", width, height); GL2 gl = drawable.getGL().getGL2(); // get the OpenGL 2 graphics context if (height == 0) { height = 1; // prevent divide by zero } double aspect = (double) width / height; // Set the view port (display area) to cover the entire window gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL_PROJECTION); // choose projection matrix gl.glLoadIdentity(); // reset projection matrix setPerspective(gl, aspect); gl.glMatrixMode(GL_MODELVIEW); gl.glLoadIdentity(); // reset logger.debug("reshape called done"); } public void setReshape() { reshape = true; } }