de.lessvoid.nifty.renderer.jogl.render.JoglRenderDevice Maven / Gradle / Ivy
The newest version!
package de.lessvoid.nifty.renderer.jogl.render;
import java.awt.Point;
import java.io.IOException;
import java.nio.IntBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.jogamp.common.nio.Buffers;
import com.jogamp.newt.Window;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLContext;
import de.lessvoid.nifty.render.BlendMode;
import de.lessvoid.nifty.spi.render.MouseCursor;
import de.lessvoid.nifty.spi.render.RenderDevice;
import de.lessvoid.nifty.spi.render.RenderFont;
import de.lessvoid.nifty.spi.render.RenderImage;
import de.lessvoid.nifty.spi.time.TimeProvider;
import de.lessvoid.nifty.spi.time.impl.AccurateTimeProvider;
import de.lessvoid.nifty.tools.Color;
import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
/**
* @deprecated Use {@link de.lessvoid.nifty.render.batch.BatchRenderDevice} with either
* {@link JoglBatchRenderBackendFactory#create()} or {@link JoglBatchRenderBackendCoreProfileFactory#create()}.
*/
@Deprecated
public class JoglRenderDevice implements RenderDevice {
@Nonnull
private static final Logger log = Logger.getLogger(JoglRenderDevice.class.getName());
@Nonnull
private static final IntBuffer viewportBuffer = Buffers.newDirectIntBuffer(4);
@Nonnull
private final TimeProvider timeProvider = new AccurateTimeProvider();
@Nullable // for now
private Window newtWindow;
@Nullable
private RenderFont fpsFont;
@Nullable
private BlendMode currentBlendMode = null;
@Nullable
private MouseCursor mouseCursor;
private NiftyResourceLoader resourceLoader;
// we keep track of which GL states we've already set to make sure we don't set
// the same state twice.
private boolean currentTexturing = true;
private long time;
private long frames;
private long lastFrames;
private boolean displayFPS = false;
private boolean logFPS = false;
private boolean currentClipping = false;
private int currentClippingX0 = 0;
private int currentClippingY0 = 0;
private int currentClippingX1 = 0;
private int currentClippingY1 = 0;
@Deprecated
/**
* @deprecated Replaced by {@link #JoglRenderDevice(com.jogamp.newt.Window)}
* Use of this constructor will cause some RenderDevice operations to fail.
*/
public JoglRenderDevice() {
this(null);
}
@Deprecated
/**
* @deprecated Replaced by {@link #JoglRenderDevice(com.jogamp.newt.Window,boolean)}
* Use of this constructor will cause some RenderDevice operations to fail.
* @param displayFPS display the FPS counter on the screen
*/
public JoglRenderDevice(final boolean displayFPS) {
this(null, displayFPS);
}
/**
* The standard constructor. You'll use this in production code. Using this constructor will
* configure the RenderDevice to not log FPS on System.out.
* @param newtWindow the current window handling the rendering context
*/
public JoglRenderDevice(final Window newtWindow) {
if(newtWindow == null)
log.warning("newtWindow parameter is null - some RenderDevice operations may not work properly");
this.newtWindow = newtWindow;
time = timeProvider.getMsTime();
frames = 0;
}
/**
* The development mode constructor allows to display the FPS on screen when the given flag is
* set to true. Note that setting displayFPS to false will still log the FPS on System.out every
* couple of frames.
*
* @param newtWindow the current window handling the rendering context
* @param displayFPS display the FPS counter on the screen
*/
public JoglRenderDevice(final Window newtWindow, final boolean displayFPS) {
this(newtWindow);
this.logFPS = true;
this.displayFPS = displayFPS;
if (this.displayFPS) {
fpsFont = createFont("fps.fnt");
}
}
/**
* Get Width.
*
* @return width of display mode
*/
@Override
public int getWidth() {
return getViewport().x;
}
/**
* Get Height.
*
* @return height of display mode
*/
@Override
public int getHeight() {
return getViewport().y;
}
@Nonnull
private Point getViewport() {
final GL gl = GLContext.getCurrentGL();
gl.glGetIntegerv(GL.GL_VIEWPORT, viewportBuffer);
Point dimensions = new Point(viewportBuffer.get(2), viewportBuffer.get(3));
log.fine("Viewport: " + dimensions.x + ", " + dimensions.y);
return dimensions;
}
@Override
public void beginFrame() {
log.fine("beginFrame()");
final GL gl = GLContext.getCurrentGL();
// set inital states for each frame
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
setBlendMode(BlendMode.BLEND);
gl.glEnable(GL.GL_TEXTURE_2D);
currentTexturing = true;
gl.glDisable(GL.GL_SCISSOR_TEST);
currentClipping = false;
currentClippingX0 = 0;
currentClippingY0 = 0;
currentClippingX1 = 0;
currentClippingY1 = 0;
}
@Override
public void endFrame() {
log.fine("endFrame");
frames++;
long diff = timeProvider.getMsTime() - time;
if (diff >= 1000) {
time += diff;
lastFrames = frames;
if (logFPS) {
System.out.println("fps: " + frames);
}
frames = 0;
}
if (displayFPS && fpsFont != null) {
renderFont(fpsFont, "FPS: " + String.valueOf(lastFrames), 10,
getHeight() - fpsFont.getHeight() - 10, Color.WHITE, 1.0f, 1.0f);
}
}
@Override
public void clear() {
log.fine("clear()");
final GL gl = GLContext.getCurrentGL();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
}
/**
* Create a new RenderImage.
*
* @param filename filename
* @param filterLinear linear filter the image
* @return RenderImage
*/
@Override
public RenderImage createImage(@Nonnull final String filename, final boolean filterLinear) {
return new JoglRenderImage(filename, filterLinear, resourceLoader);
}
/**
* Create a new RenderFont.
*
* @param filename filename
* @return RenderFont
*/
@Override
public RenderFont createFont(@Nonnull final String filename) {
return new JoglRenderFont(filename, this, resourceLoader);
}
/**
* Render a quad.
*
* @param x x
* @param y y
* @param width width
* @param height height
* @param color color
*/
@Override
public void renderQuad(
final int x, final int y, final int width, final int height,
@Nonnull final Color color) {
log.fine("renderQuad()");
final GL2 gl = GLContext.getCurrentGL().getGL2();
if (currentTexturing) {
gl.glDisable(GL.GL_TEXTURE_2D);
currentTexturing = false;
}
gl.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
gl.glBegin(GL2.GL_QUADS);
gl.glVertex2i(x, y);
gl.glVertex2i(x + width, y);
gl.glVertex2i(x + width, y + height);
gl.glVertex2i(x, y + height);
gl.glEnd();
}
@Override
public void renderQuad(
final int x, final int y, final int width, final int height,
@Nonnull final Color topLeft, @Nonnull final Color topRight, @Nonnull final Color bottomRight,
@Nonnull final Color bottomLeft) {
log.fine("renderQuad2()");
final GL2 gl = GLContext.getCurrentGL().getGL2();
if (currentTexturing) {
gl.glDisable(GL.GL_TEXTURE_2D);
currentTexturing = false;
}
gl.glBegin(GL2.GL_QUADS);
gl.glColor4f(topLeft.getRed(), topLeft.getGreen(), topLeft.getBlue(), topLeft.getAlpha());
gl.glVertex2i(x, y);
gl.glColor4f(topRight.getRed(), topRight.getGreen(), topRight.getBlue(),
topRight.getAlpha());
gl.glVertex2i(x + width, y);
gl.glColor4f(bottomRight.getRed(), bottomRight.getGreen(), bottomRight.getBlue(),
bottomRight.getAlpha());
gl.glVertex2i(x + width, y + height);
gl.glColor4f(bottomLeft.getRed(), bottomLeft.getGreen(), bottomLeft.getBlue(),
bottomLeft.getAlpha());
gl.glVertex2i(x, y + height);
gl.glEnd();
}
/**
* Render the image using the given Box to specify the render attributes.
*
* @param x x
* @param y y
* @param width width
* @param height height
* @param color color
* @param scale scale
*/
@Override
public void renderImage(
@Nonnull final RenderImage image, final int x, final int y, final int width,
final int height, @Nonnull final Color color, final float scale) {
log.fine("renderImage()");
final GL2 gl = GLContext.getCurrentGL().getGL2();
if (!currentTexturing) {
gl.glEnable(GL.GL_TEXTURE_2D);
currentTexturing = true;
}
gl.glPushMatrix();
gl.glTranslatef(x + width / 2, y + height / 2, 0.0f);
gl.glScalef(scale, scale, 1.0f);
gl.glTranslatef(-(x + width / 2), -(y + height / 2), 0.0f);
JoglRenderImage internalImage = (JoglRenderImage) image;
internalImage.bind();
float textureWidth = internalImage.getTextureWidth();
float textureHeight = internalImage.getTextureHeight();
float imageWidth = internalImage.getWidth();
float imageHeight = internalImage.getHeight();
float u1 = imageWidth / textureWidth;
float v1 = imageHeight / textureHeight;
gl.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex2i(x, y);
gl.glTexCoord2f(u1, 0.0f);
gl.glVertex2i(x + width, y);
gl.glTexCoord2f(u1, v1);
gl.glVertex2i(x + width, y + height);
gl.glTexCoord2f(0.0f, v1);
gl.glVertex2i(x, y + height);
gl.glEnd();
gl.glPopMatrix();
}
/**
* Render sub image.
*
* @param x x
* @param y y
* @param w w
* @param h h
* @param srcX x
* @param srcY y
* @param srcW w
* @param srcH h
* @param color color
*/
@Override
public void renderImage(
@Nonnull final RenderImage image, final int x, final int y, final int w,
final int h, final int srcX, final int srcY, final int srcW, final int srcH,
@Nonnull final Color color, final float scale, final int centerX, final int centerY) {
log.fine("renderImage2()");
final GL2 gl = GLContext.getCurrentGL().getGL2();
if (!currentTexturing) {
gl.glEnable(GL.GL_TEXTURE_2D);
currentTexturing = true;
}
gl.glPushMatrix();
gl.glTranslatef(centerX, centerY, 0.0f);
gl.glScalef(scale, scale, 1.0f);
gl.glTranslatef(-(centerX), -(centerY), 0.0f);
JoglRenderImage internalImage = (JoglRenderImage) image;
internalImage.bind();
float textureWidth = internalImage.getTextureWidth();
float textureHeight = internalImage.getTextureHeight();
float u0 = srcX / textureWidth;
float v0 = srcY / textureHeight;
float u1 = (srcX + srcW) / textureWidth;
float v1 = (srcY + srcH) / textureHeight;
gl.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2f(u0, v0);
gl.glVertex2i(x, y);
gl.glTexCoord2f(u1, v0);
gl.glVertex2i(x + w, y);
gl.glTexCoord2f(u1, v1);
gl.glVertex2i(x + w, y + h);
gl.glTexCoord2f(u0, v1);
gl.glVertex2i(x, y + h);
gl.glEnd();
gl.glPopMatrix();
}
/**
* render the text.
*/
@Override
public void renderFont(
@Nonnull final RenderFont font,
@Nonnull final String text,
final int x,
final int y,
@Nonnull final Color color,
final float fontSizeX,
final float fontSizeY) {
if (log.isLoggable(Level.FINER)) {
log.entering(
JoglRenderDevice.class.getName(),
"renderFont",
new Object[] { font, text, x, y, color, fontSizeX, fontSizeY });
}
final GL gl = GLContext.getCurrentGL();
if (!currentTexturing) {
gl.glEnable(GL.GL_TEXTURE_2D);
currentTexturing = true;
}
setBlendMode(BlendMode.BLEND);
((JoglRenderFont) font).getFont().renderWithSizeAndColor(x, y, text, fontSizeX, fontSizeY,
color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
}
/**
* Enable clipping to the given region.
*
* @param x0 x0
* @param y0 y0
* @param x1 x1
* @param y1 y1
*/
@Override
public void enableClip(final int x0, final int y0, final int x1, final int y1) {
log.fine("enableClip()");
if (currentClipping && currentClippingX0 == x0 && currentClippingY0 == y0
&& currentClippingX1 == x1 && currentClippingY1 == y1) {
return;
}
currentClipping = true;
currentClippingX0 = x0;
currentClippingY0 = y0;
currentClippingX1 = x1;
currentClippingY1 = y1;
final GL gl = GLContext.getCurrentGL();
gl.glScissor(x0, getHeight() - y1, x1 - x0, y1 - y0);
gl.glEnable(GL.GL_SCISSOR_TEST);
}
/**
* Disable Clip.
*/
@Override
public void disableClip() {
log.fine("disableClip()");
if (!currentClipping) {
return;
}
final GL gl = GLContext.getCurrentGL();
gl.glDisable(GL.GL_SCISSOR_TEST);
currentClipping = false;
currentClippingX0 = 0;
currentClippingY0 = 0;
currentClippingX1 = 0;
currentClippingY1 = 0;
}
@Override
public void setBlendMode(@Nonnull final BlendMode renderMode) {
log.fine("setBlendMode()");
if (renderMode.equals(currentBlendMode)) {
return;
}
currentBlendMode = renderMode;
final GL gl = GLContext.getCurrentGL();
if (currentBlendMode.equals(BlendMode.BLEND)) {
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
} else if (currentBlendMode.equals(BlendMode.MULIPLY)) {
gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_ZERO);
}
}
@Override
public MouseCursor createMouseCursor(@Nonnull String filename, int hotspotX, int hotspotY) throws IOException {
return new JoglMouseCursor(filename, hotspotX, hotspotY, newtWindow, resourceLoader);
}
@Override
public void enableMouseCursor(@Nonnull MouseCursor mouseCursor) {
this.mouseCursor = mouseCursor;
mouseCursor.enable();
}
@Override
public void disableMouseCursor() {
if (mouseCursor != null) {
mouseCursor.disable();
}
}
@Override
public void setResourceLoader(@Nonnull final NiftyResourceLoader niftyResourceLoader) {
this.resourceLoader = niftyResourceLoader;
}
}