added sources for Slick

Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054
Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
This commit is contained in:
Song Minjae
2016-12-30 23:29:12 +09:00
parent d24b31e15d
commit 059abff814
329 changed files with 58400 additions and 7 deletions

View File

@@ -0,0 +1,228 @@
package org.newdawn.slick.opengl.pbuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.opengl.InternalTextureLoader;
import org.newdawn.slick.opengl.SlickCallable;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.util.Log;
/**
* A graphics implementation that renders to an FBO
*
* @author kevin
*/
public class FBOGraphics extends Graphics {
/** The image we're we're sort of rendering to */
private Image image;
/** The ID of the FBO in use */
private int FBO;
/** True if this context is valid */
private boolean valid = true;
/**
* Create a new graphics context around an FBO
*
* @param image The image we're rendering to
* @throws SlickException Indicates a failure to use pbuffers
*/
public FBOGraphics(Image image) throws SlickException {
super(image.getTexture().getTextureWidth(), image.getTexture().getTextureHeight());
this.image = image;
Log.debug("Creating FBO "+image.getWidth()+"x"+image.getHeight());
boolean FBOEnabled = GLContext.getCapabilities().GL_EXT_framebuffer_object;
if (!FBOEnabled) {
throw new SlickException("Your OpenGL card does not support FBO and hence can't handle the dynamic images required for this application.");
}
init();
}
/**
* Check the FBO for completeness as shown in the LWJGL tutorial
*
* @throws SlickException Indicates an incomplete FBO
*/
private void completeCheck() throws SlickException {
int framebuffer = EXTFramebufferObject.glCheckFramebufferStatusEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT);
switch ( framebuffer ) {
case EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
throw new SlickException( "FrameBuffer: " + FBO
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT exception" );
default:
throw new SlickException( "Unexpected reply from glCheckFramebufferStatusEXT: " + framebuffer);
}
}
/**
* Initialise the FBO that will be used to render to
*
* @throws SlickException
*/
private void init() throws SlickException {
IntBuffer buffer = BufferUtils.createIntBuffer(1);
EXTFramebufferObject.glGenFramebuffersEXT(buffer);
FBO = buffer.get();
// for some reason FBOs won't work on textures unless you've absolutely just
// created them.
try {
Texture tex = InternalTextureLoader.get().createTexture(image.getWidth(), image.getHeight(), image.getFilter());
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, FBO);
EXTFramebufferObject.glFramebufferTexture2DEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
GL11.GL_TEXTURE_2D, tex.getTextureID(), 0);
completeCheck();
unbind();
// Clear our destination area before using it
clear();
flush();
// keep hold of the original content
drawImage(image, 0, 0);
image.setTexture(tex);
} catch (Exception e) {
throw new SlickException("Failed to create new texture for FBO");
}
}
/**
* Bind to the FBO created
*/
private void bind() {
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, FBO);
GL11.glReadBuffer(EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT);
}
/**
* Unbind from the FBO created
*/
private void unbind() {
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
GL11.glReadBuffer(GL11.GL_BACK);
}
/**
* @see org.newdawn.slick.Graphics#disable()
*/
protected void disable() {
GL.flush();
unbind();
GL11.glPopClientAttrib();
GL11.glPopAttrib();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
SlickCallable.leaveSafeBlock();
}
/**
* @see org.newdawn.slick.Graphics#enable()
*/
protected void enable() {
if (!valid) {
throw new RuntimeException("Attempt to use a destroy()ed offscreen graphics context.");
}
SlickCallable.enterSafeBlock();
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushClientAttrib(GL11.GL_ALL_CLIENT_ATTRIB_BITS);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
bind();
initGL();
}
/**
* Initialise the GL context
*/
protected void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glViewport(0,0,screenWidth,screenHeight);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
enterOrtho();
}
/**
* Enter the orthographic mode
*/
protected void enterOrtho() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, screenWidth, 0, screenHeight, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
/**
* @see org.newdawn.slick.Graphics#destroy()
*/
public void destroy() {
super.destroy();
IntBuffer buffer = BufferUtils.createIntBuffer(1);
buffer.put(FBO);
buffer.flip();
EXTFramebufferObject.glDeleteFramebuffersEXT(buffer);
valid = false;
}
/**
* @see org.newdawn.slick.Graphics#flush()
*/
public void flush() {
super.flush();
image.flushPixelData();
}
}

View File

@@ -0,0 +1,141 @@
package org.newdawn.slick.opengl.pbuffer;
import java.util.HashMap;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.Pbuffer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log;
/**
* A factory to produce an appropriate render to texture graphics context based on current
* hardware
*
* @author kevin
*/
public class GraphicsFactory {
/** The graphics list of graphics contexts created */
private static HashMap graphics = new HashMap();
/** True if pbuffers are supported */
private static boolean pbuffer = true;
/** True if pbuffer render to texture are supported */
private static boolean pbufferRT = true;
/** True if fbo are supported */
private static boolean fbo = true;
/** True if we've initialised */
private static boolean init = false;
/**
* Initialise offscreen rendering by checking what buffers are supported
* by the card
*
* @throws SlickException Indicates no buffers are supported
*/
private static void init() throws SlickException {
init = true;
if (fbo) {
fbo = GLContext.getCapabilities().GL_EXT_framebuffer_object;
}
pbuffer = (Pbuffer.getCapabilities() & Pbuffer.PBUFFER_SUPPORTED) != 0;
pbufferRT = (Pbuffer.getCapabilities() & Pbuffer.RENDER_TEXTURE_SUPPORTED) != 0;
if (!fbo && !pbuffer && !pbufferRT) {
throw new SlickException("Your OpenGL card does not support offscreen buffers and hence can't handle the dynamic images required for this application.");
}
Log.info("Offscreen Buffers FBO="+fbo+" PBUFFER="+pbuffer+" PBUFFERRT="+pbufferRT);
}
/**
* Force FBO use on or off
*
* @param useFBO True if we should try and use FBO for offscreen images
*/
public static void setUseFBO(boolean useFBO) {
fbo = useFBO;
}
/**
* Check if we're using FBO for dynamic textures
*
* @return True if we're using FBOs
*/
public static boolean usingFBO() {
return fbo;
}
/**
* Check if we're using PBuffer for dynamic textures
*
* @return True if we're using PBuffer
*/
public static boolean usingPBuffer() {
return !fbo && pbuffer;
}
/**
* Get a graphics context for a particular image
*
* @param image The image for which to retrieve the graphics context
* @return The graphics context
* @throws SlickException Indicates it wasn't possible to create a graphics context
* given available hardware.
*/
public static Graphics getGraphicsForImage(Image image) throws SlickException {
Graphics g = (Graphics) graphics.get(image.getTexture());
if (g == null) {
g = createGraphics(image);
graphics.put(image.getTexture(), g);
}
return g;
}
/**
* Release any graphics context that is assocaited with the given image
*
* @param image The image to release
* @throws SlickException Indicates a failure to release the context
*/
public static void releaseGraphicsForImage(Image image) throws SlickException {
Graphics g = (Graphics) graphics.remove(image.getTexture());
if (g != null) {
g.destroy();
}
}
/**
* Create an underlying graphics context for the given image
*
* @param image The image we want to render to
* @return The graphics context created
* @throws SlickException
*/
private static Graphics createGraphics(Image image) throws SlickException {
init();
if (fbo) {
try {
return new FBOGraphics(image);
} catch (Exception e) {
fbo = false;
Log.warn("FBO failed in use, falling back to PBuffer");
}
}
if (pbuffer) {
if (pbufferRT) {
return new PBufferGraphics(image);
} else {
return new PBufferUniqueGraphics(image);
}
}
throw new SlickException("Failed to create offscreen buffer even though the card reports it's possible");
}
}

View File

@@ -0,0 +1,172 @@
package org.newdawn.slick.opengl.pbuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.Pbuffer;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.opengl.RenderTexture;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.opengl.SlickCallable;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureImpl;
import org.newdawn.slick.opengl.InternalTextureLoader;
import org.newdawn.slick.util.Log;
/**
* A graphics implementation that renders to a PBuffer
*
* @author kevin
*/
public class PBufferGraphics extends Graphics {
/** The pbuffer we're going to render to */
private Pbuffer pbuffer;
/** The image we're we're sort of rendering to */
private Image image;
/**
* Create a new graphics context around a pbuffer
*
* @param image The image we're rendering to
* @throws SlickException Indicates a failure to use pbuffers
*/
public PBufferGraphics(Image image) throws SlickException {
super(image.getTexture().getTextureWidth(), image.getTexture().getTextureHeight());
this.image = image;
Log.debug("Creating pbuffer(rtt) "+image.getWidth()+"x"+image.getHeight());
if ((Pbuffer.getCapabilities() & Pbuffer.PBUFFER_SUPPORTED) == 0) {
throw new SlickException("Your OpenGL card does not support PBuffers and hence can't handle the dynamic images required for this application.");
}
if ((Pbuffer.getCapabilities() & Pbuffer.RENDER_TEXTURE_SUPPORTED) == 0) {
throw new SlickException("Your OpenGL card does not support Render-To-Texture and hence can't handle the dynamic images required for this application.");
}
init();
}
/**
* Initialise the PBuffer that will be used to render to
*
* @throws SlickException
*/
private void init() throws SlickException {
try {
Texture tex = InternalTextureLoader.get().createTexture(image.getWidth(), image.getHeight(), image.getFilter());
final RenderTexture rt = new RenderTexture(false, true, false, false, RenderTexture.RENDER_TEXTURE_2D, 0);
pbuffer = new Pbuffer(screenWidth, screenHeight, new PixelFormat(8, 0, 0), rt, null);
// Initialise state of the pbuffer context.
pbuffer.makeCurrent();
initGL();
GL.glBindTexture(GL11.GL_TEXTURE_2D, tex.getTextureID());
pbuffer.releaseTexImage(Pbuffer.FRONT_LEFT_BUFFER);
image.draw(0,0);
image.setTexture(tex);
Display.makeCurrent();
} catch (Exception e) {
Log.error(e);
throw new SlickException("Failed to create PBuffer for dynamic image. OpenGL driver failure?");
}
}
/**
* @see org.newdawn.slick.Graphics#disable()
*/
protected void disable() {
GL.flush();
// Bind the texture after rendering.
GL.glBindTexture(GL11.GL_TEXTURE_2D, image.getTexture().getTextureID());
pbuffer.bindTexImage(Pbuffer.FRONT_LEFT_BUFFER);
try {
Display.makeCurrent();
} catch (LWJGLException e) {
Log.error(e);
}
SlickCallable.leaveSafeBlock();
}
/**
* @see org.newdawn.slick.Graphics#enable()
*/
protected void enable() {
SlickCallable.enterSafeBlock();
try {
if (pbuffer.isBufferLost()) {
pbuffer.destroy();
init();
}
pbuffer.makeCurrent();
} catch (Exception e) {
Log.error("Failed to recreate the PBuffer");
throw new RuntimeException(e);
}
// Put the renderer contents to the texture
GL.glBindTexture(GL11.GL_TEXTURE_2D, image.getTexture().getTextureID());
pbuffer.releaseTexImage(Pbuffer.FRONT_LEFT_BUFFER);
TextureImpl.unbind();
initGL();
}
/**
* Initialise the GL context
*/
protected void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glViewport(0,0,screenWidth,screenHeight);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
enterOrtho();
}
/**
* Enter the orthographic mode
*/
protected void enterOrtho() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, screenWidth, 0, screenHeight, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
/**
* @see org.newdawn.slick.Graphics#destroy()
*/
public void destroy() {
super.destroy();
pbuffer.destroy();
}
/**
* @see org.newdawn.slick.Graphics#flush()
*/
public void flush() {
super.flush();
image.flushPixelData();
}
}

View File

@@ -0,0 +1,167 @@
package org.newdawn.slick.opengl.pbuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.Pbuffer;
import org.lwjgl.opengl.PixelFormat;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.opengl.SlickCallable;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureImpl;
import org.newdawn.slick.opengl.InternalTextureLoader;
import org.newdawn.slick.util.Log;
/**
* A graphics implementation that renders to a PBuffer using a unique context, i.e.
* without render to texture
*
* @author kevin
*/
public class PBufferUniqueGraphics extends Graphics {
/** The pbuffer we're going to render to */
private Pbuffer pbuffer;
/** The image we're we're sort of rendering to */
private Image image;
/**
* Create a new graphics context around a pbuffer
*
* @param image The image we're rendering to
* @throws SlickException Indicates a failure to use pbuffers
*/
public PBufferUniqueGraphics(Image image) throws SlickException {
super(image.getTexture().getTextureWidth(), image.getTexture().getTextureHeight());
this.image = image;
Log.debug("Creating pbuffer(unique) "+image.getWidth()+"x"+image.getHeight());
if ((Pbuffer.getCapabilities() & Pbuffer.PBUFFER_SUPPORTED) == 0) {
throw new SlickException("Your OpenGL card does not support PBuffers and hence can't handle the dynamic images required for this application.");
}
init();
}
/**
* Initialise the PBuffer that will be used to render to
*
* @throws SlickException
*/
private void init() throws SlickException {
try {
Texture tex = InternalTextureLoader.get().createTexture(image.getWidth(), image.getHeight(), image.getFilter());
pbuffer = new Pbuffer(screenWidth, screenHeight, new PixelFormat(8, 0, 0), null, null);
// Initialise state of the pbuffer context.
pbuffer.makeCurrent();
initGL();
image.draw(0,0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex.getTextureID());
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 0, 0,
tex.getTextureWidth(),
tex.getTextureHeight(), 0);
image.setTexture(tex);
Display.makeCurrent();
} catch (Exception e) {
Log.error(e);
throw new SlickException("Failed to create PBuffer for dynamic image. OpenGL driver failure?");
}
}
/**
* @see org.newdawn.slick.Graphics#disable()
*/
protected void disable() {
// Bind the texture after rendering.
GL11.glBindTexture(GL11.GL_TEXTURE_2D, image.getTexture().getTextureID());
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 0, 0,
image.getTexture().getTextureWidth(),
image.getTexture().getTextureHeight(), 0);
try {
Display.makeCurrent();
} catch (LWJGLException e) {
Log.error(e);
}
SlickCallable.leaveSafeBlock();
}
/**
* @see org.newdawn.slick.Graphics#enable()
*/
protected void enable() {
SlickCallable.enterSafeBlock();
try {
if (pbuffer.isBufferLost()) {
pbuffer.destroy();
init();
}
pbuffer.makeCurrent();
} catch (Exception e) {
Log.error("Failed to recreate the PBuffer");
Log.error(e);
throw new RuntimeException(e);
}
// Put the renderer contents to the texture
TextureImpl.unbind();
initGL();
}
/**
* Initialise the GL context
*/
protected void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glViewport(0,0,screenWidth,screenHeight);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
enterOrtho();
}
/**
* Enter the orthographic mode
*/
protected void enterOrtho() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, screenWidth, 0, screenHeight, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
/**
* @see org.newdawn.slick.Graphics#destroy()
*/
public void destroy() {
super.destroy();
pbuffer.destroy();
}
/**
* @see org.newdawn.slick.Graphics#flush()
*/
public void flush() {
super.flush();
image.flushPixelData();
}
}