Added support for OpenGL ES.

This commit is contained in:
Ioannis Tsakpinis 2011-05-17 16:53:57 +00:00
parent 8f6dcd3a6d
commit 40cbf3e45f
213 changed files with 19618 additions and 194 deletions

View file

@ -42,6 +42,8 @@ import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import static org.lwjgl.opengl.GL11.*;
/**
* <p/>
* An AWT rendering context.
@ -56,7 +58,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
private static final long serialVersionUID = 1L;
private static final AWTCanvasImplementation implementation;
private boolean update_context;
private boolean update_context;
private Object SYNC_LOCK = new Object();
/** The requested pixel format */
@ -69,8 +71,8 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
private final ContextAttribs attribs;
/** Context handle */
private PeerInfo peer_info;
private Context context;
private PeerInfo peer_info;
private ContextGL context;
/**
* re-entry counter for support for re-entrant
@ -105,20 +107,39 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
}
}
public void setPixelFormat(final PixelFormatLWJGL pf) throws LWJGLException {
throw new UnsupportedOperationException();
}
public PixelFormatLWJGL getPixelFormat() {
return pixel_format;
}
/** This method should only be called internally. */
public Context getContext() {
public ContextGL getContext() {
return context;
}
/** This method should only be called internally. */
public Context createSharedContext() throws LWJGLException {
public ContextGL createSharedContext() throws LWJGLException {
synchronized ( SYNC_LOCK ) {
if ( context == null ) throw new IllegalStateException("Canvas not yet displayable");
return new Context(peer_info, context.getContextAttribs(), context);
return new ContextGL(peer_info, context.getContextAttribs(), context);
}
}
public void checkGLError() {
Util.checkGLError();
}
public void initContext(final float r, final float g, final float b) {
// set background clear color
glClearColor(r, g, b, 0.0f);
// Clear window to avoid the desktop "showing through"
glClear(GL_COLOR_BUFFER_BIT);
}
/** Constructor using the default PixelFormat. */
public AWTGLCanvas() throws LWJGLException {
this(new PixelFormat());
@ -195,7 +216,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
synchronized ( SYNC_LOCK ) {
if ( context == null )
throw new IllegalStateException("Canvas not yet displayable");
Context.setSwapInterval(swap_interval);
ContextGL.setSwapInterval(swap_interval);
}
}
@ -209,7 +230,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
synchronized ( SYNC_LOCK ) {
if ( context == null )
throw new IllegalStateException("Canvas not yet displayable");
Context.swapBuffers();
ContextGL.swapBuffers();
}
}
@ -238,7 +259,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
if ( context == null )
throw new IllegalStateException("Canvas not yet displayable");
if ( context.isCurrent() )
Context.releaseCurrentContext();
context.releaseCurrent();
}
}
@ -295,7 +316,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
peer_info.lockAndGetHandle();
try {
if ( context == null ) {
this.context = new Context(peer_info, attribs, drawable != null ? ((DrawableLWJGL)drawable).getContext() : null);
this.context = new ContextGL(peer_info, attribs, drawable != null ? (ContextGL)((DrawableLWJGL)drawable).getContext() : null);
first_run = true;
}
@ -315,7 +336,7 @@ public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListe
} finally {
reentry_count--;
if ( reentry_count == 0 )
Context.releaseCurrentContext();
context.releaseCurrent();
}
} finally {
peer_info.unlock();

View file

@ -42,9 +42,9 @@ import java.util.Map;
final class CallbackUtil {
/** Context -> Long */
private static final Map<Context, Long> contextUserParamsARB = new HashMap<Context, Long>();
private static final Map<ContextGL, Long> contextUserParamsARB = new HashMap<ContextGL, Long>();
/** Context -> Long */
private static final Map<Context, Long> contextUserParamsAMD = new HashMap<Context, Long>();
private static final Map<ContextGL, Long> contextUserParamsAMD = new HashMap<ContextGL, Long>();
private CallbackUtil() {}
@ -84,8 +84,8 @@ final class CallbackUtil {
*
* @param userParam the global reference pointer
*/
private static void registerContextCallback(final long userParam, final Map<Context, Long> contextUserData) {
Context context = Context.getCurrentContext();
private static void registerContextCallback(final long userParam, final Map<ContextGL, Long> contextUserData) {
ContextGL context = ContextGL.getCurrentContext();
if ( context == null ) {
deleteGlobalRef(userParam);
throw new IllegalStateException("No context is current.");
@ -104,7 +104,7 @@ final class CallbackUtil {
*
* @param context the Context to unregister
*/
static void unregisterCallbacks(final Context context) {
static void unregisterCallbacks(final ContextGL context) {
Long userParam = contextUserParamsARB.remove(context);
if ( userParam != null )
deleteGlobalRef(userParam);

View file

@ -53,13 +53,13 @@ import static org.lwjgl.opengl.GL11.*;
* @version $Revision$
* $Id$
*/
final class Context {
final class ContextGL implements Context {
/** The platform specific implementation of context methods */
private static final ContextImplementation implementation;
/** The current Context */
private static final ThreadLocal<Context> current_context_local = new ThreadLocal<Context>();
private static final ThreadLocal<ContextGL> current_context_local = new ThreadLocal<ContextGL>();
/** Handle to the native GL rendering context */
private final ByteBuffer handle;
@ -102,13 +102,13 @@ final class Context {
return contextAttribs;
}
static Context getCurrentContext() {
static ContextGL getCurrentContext() {
return current_context_local.get();
}
/** Create a context with the specified peer info and shared context */
Context(PeerInfo peer_info, ContextAttribs attribs, Context shared_context) throws LWJGLException {
Context context_lock = shared_context != null ? shared_context : this;
ContextGL(PeerInfo peer_info, ContextAttribs attribs, ContextGL shared_context) throws LWJGLException {
ContextGL context_lock = shared_context != null ? shared_context : this;
// If shared_context is not null, synchronize on it to make sure it is not deleted
// while this context is created. Otherwise, simply synchronize on ourself to avoid NPE
synchronized ( context_lock ) {
@ -137,8 +137,8 @@ final class Context {
}
/** Release the current context (if any). After this call, no context is current. */
public static void releaseCurrentContext() throws LWJGLException {
Context current_context = getCurrentContext();
public void releaseCurrent() throws LWJGLException {
ContextGL current_context = getCurrentContext();
if ( current_context != null ) {
implementation.releaseCurrentContext();
GLContext.useContext(null);
@ -254,7 +254,7 @@ final class Context {
if ( was_current ) {
if ( GLContext.getCapabilities() != null && GLContext.getCapabilities().OpenGL11 )
error = glGetError();
releaseCurrentContext();
releaseCurrent();
}
checkDestroy();
if ( was_current && error != GL_NO_ERROR )

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengl;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.Sys;
import org.lwjgl.opengles.EGLContext;
import org.lwjgl.opengles.GLContext;
import org.lwjgl.opengles.GLES20;
import org.lwjgl.opengles.PowerManagementEventException;
import static org.lwjgl.opengles.EGL.*;
/**
* <p/>
* Context encapsulates an OpenGL ES context.
* <p/>
* <p/>
* This class is thread-safe.
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3332 $
* $Id: Context.java 3332 2010-04-20 18:21:05Z spasi $
*/
final class ContextGLES implements org.lwjgl.opengl.Context {
/** The current Context */
private static final ThreadLocal<ContextGLES> current_context_local = new ThreadLocal<ContextGLES>();
/** Handle to the native GL rendering context */
private final DrawableGLES drawable;
private final EGLContext eglContext;
private final org.lwjgl.opengles.ContextAttribs contextAttribs;
/** Whether the context has been destroyed */
private boolean destroyed;
private boolean destroy_requested;
/** The thread that has this context current, or null. */
private Thread thread;
static {
Sys.initialize();
}
public EGLContext getEGLContext() {
return eglContext;
}
org.lwjgl.opengles.ContextAttribs getContextAttribs() {
return contextAttribs;
}
static ContextGLES getCurrentContext() {
return current_context_local.get();
}
/** Create a context with the specified peer info and shared context */
ContextGLES(DrawableGLES drawable, org.lwjgl.opengles.ContextAttribs attribs, ContextGLES shared_context) throws LWJGLException {
if ( drawable == null )
throw new IllegalArgumentException();
ContextGLES context_lock = shared_context != null ? shared_context : this;
// If shared_context is not null, synchronize on it to make sure it is not deleted
// while this context is created. Otherwise, simply synchronize on ourself to avoid NPE
synchronized ( context_lock ) {
if ( shared_context != null && shared_context.destroyed )
throw new IllegalArgumentException("Shared context is destroyed");
this.drawable = drawable;
this.contextAttribs = attribs;
this.eglContext = drawable.getEGLDisplay().createContext(drawable.getEGLConfig(),
shared_context == null ? null : shared_context.eglContext,
attribs == null ? new org.lwjgl.opengles.ContextAttribs(2).getAttribList() : attribs.getAttribList());
}
}
/** Release the current context (if any). After this call, no context is current. */
public void releaseCurrent() throws LWJGLException, PowerManagementEventException {
eglReleaseCurrent(drawable.getEGLDisplay());
org.lwjgl.opengles.GLContext.useContext(null);
current_context_local.set(null);
synchronized ( this ) {
thread = null;
checkDestroy();
}
}
/** Swap the buffers on the current context. Only valid for double-buffered contexts */
public static void swapBuffers() throws LWJGLException, PowerManagementEventException {
ContextGLES current_context = getCurrentContext();
if ( current_context != null )
current_context.drawable.getEGLSurface().swapBuffers();
}
private boolean canAccess() {
return thread == null || Thread.currentThread() == thread;
}
private void checkAccess() {
if ( !canAccess() )
throw new IllegalStateException("From thread " + Thread.currentThread() + ": " + thread + " already has the context current");
}
/** Make the context current */
public synchronized void makeCurrent() throws LWJGLException, PowerManagementEventException {
checkAccess();
if ( destroyed )
throw new IllegalStateException("Context is destroyed");
thread = Thread.currentThread();
current_context_local.set(this);
eglContext.makeCurrent(drawable.getEGLSurface());
org.lwjgl.opengles.GLContext.useContext(this);
}
/** Query whether the context is current */
public synchronized boolean isCurrent() throws LWJGLException {
if ( destroyed )
throw new IllegalStateException("Context is destroyed");
return eglIsCurrentContext(eglContext);
}
private void checkDestroy() {
if ( !destroyed && destroy_requested ) {
try {
eglContext.destroy();
destroyed = true;
thread = null;
} catch (LWJGLException e) {
LWJGLUtil.log("Exception occurred while destroying context: " + e);
}
}
}
/**
* Set the buffer swap interval. This call is a best-attempt at changing
* the monitor swap interval, which is the minimum periodicity of color buffer swaps,
* measured in video frame periods, and is not guaranteed to be successful.
* <p/>
* A video frame period is the time required to display a full frame of video data.
*/
public static void setSwapInterval(int value) {
ContextGLES current_context = getCurrentContext();
if ( current_context != null ) {
try {
current_context.drawable.getEGLDisplay().setSwapInterval(value);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to set swap interval. Reason: " + e.getMessage());
}
}
}
/**
* Destroy the context. This method behaves the same as destroy() with the extra
* requirement that the context must be either current to the current thread or not
* current at all.
*/
public synchronized void forceDestroy() throws LWJGLException {
checkAccess();
destroy();
}
/**
* Request destruction of the Context. If the context is current, no context will be current after this call.
* The context is destroyed when no thread has it current.
*/
public synchronized void destroy() throws LWJGLException {
if ( destroyed )
return;
destroy_requested = true;
boolean was_current = isCurrent();
int error = GLES20.GL_NO_ERROR;
if ( was_current ) {
if ( org.lwjgl.opengles.GLContext.getCapabilities() != null && GLContext.getCapabilities().OpenGLES20 )
error = GLES20.glGetError();
try {
releaseCurrent();
} catch (PowerManagementEventException e) {
// Ignore
}
}
checkDestroy();
if ( was_current && error != GLES20.GL_NO_ERROR )
throw new OpenGLException(error);
}
public void releaseDrawable() throws LWJGLException {
}
}

View file

@ -43,10 +43,7 @@ package org.lwjgl.opengl;
* @author foo
*/
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.Sys;
import org.lwjgl.*;
import org.lwjgl.input.Controllers;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@ -62,8 +59,6 @@ import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashSet;
import static org.lwjgl.opengl.GL11.*;
public final class Display {
private static final Thread shutdown_hook = new Thread() {
@ -109,7 +104,7 @@ public final class Display {
private static int swap_interval;
/** The Drawable instance that tracks the current Display context */
private static final AbstractDrawable drawable;
private static DrawableLWJGL drawable;
private static boolean window_created;
@ -134,22 +129,6 @@ public final class Display {
LWJGLUtil.log("Initial mode: " + initial_mode);
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
drawable = new AbstractDrawable() {
public void destroy() {
synchronized ( GlobalLock.lock ) {
if ( !isCreated() )
return;
releaseDrawable();
super.destroy();
destroyWindow();
x = y = -1;
cached_icons = null;
reset();
removeShutdownHook();
}
}
};
}
@ -314,7 +293,7 @@ public final class Display {
tmp_parent.addComponentListener(component_listener);
}
DisplayMode mode = getEffectiveMode();
display_impl.createWindow(mode, tmp_parent, getWindowX(), getWindowY());
display_impl.createWindow(drawable, mode, tmp_parent, getWindowX(), getWindowY());
window_created = true;
setTitle(title);
@ -330,9 +309,9 @@ public final class Display {
private static void releaseDrawable() {
try {
Context context = drawable.context;
Context context = drawable.getContext();
if ( context != null && context.isCurrent() ) {
Context.releaseCurrentContext();
context.releaseCurrent();
context.releaseDrawable();
}
} catch (LWJGLException e) {
@ -648,8 +627,8 @@ public final class Display {
throw new IllegalStateException("Display not created");
if ( LWJGLUtil.DEBUG )
Util.checkGLError();
Context.swapBuffers();
drawable.checkGLError();
drawable.swapBuffers();
}
}
@ -851,12 +830,180 @@ public final class Display {
registerShutdownHook();
if ( isFullscreen() )
switchDisplayMode();
final DrawableGL drawable = new DrawableGL() {
public void destroy() {
synchronized ( GlobalLock.lock ) {
if ( !isCreated() )
return;
releaseDrawable();
super.destroy();
destroyWindow();
x = y = -1;
cached_icons = null;
reset();
removeShutdownHook();
}
}
};
Display.drawable = drawable;
try {
drawable.peer_info = display_impl.createPeerInfo(pixel_format);
drawable.setPixelFormat(pixel_format);
try {
createWindow();
try {
drawable.context = new Context(drawable.peer_info, attribs, shared_drawable != null ? ((AbstractDrawable)shared_drawable).getContext() : null);
drawable.context = new ContextGL(drawable.peer_info, attribs, shared_drawable != null ? ((DrawableGL)shared_drawable).getContext() : null);
try {
makeCurrentAndSetSwapInterval();
initContext();
} catch (LWJGLException e) {
drawable.destroy();
throw e;
}
} catch (LWJGLException e) {
destroyWindow();
throw e;
}
} catch (LWJGLException e) {
drawable.destroy();
throw e;
}
} catch (LWJGLException e) {
display_impl.resetDisplayMode();
throw e;
}
}
}
/**
* Create the OpenGL ES context. If isFullscreen() is true or if windowed
* context are not supported on the platform, the display mode will be switched to the mode returned by
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
* created with the given parameters, a LWJGLException will be thrown.
* <p/>
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
*
* @throws LWJGLException
*/
public static void createES() throws LWJGLException {
synchronized ( GlobalLock.lock ) {
create(new org.lwjgl.opengles.PixelFormat());
}
}
/**
* Create the OpenGL ES context with the given minimum parameters. If isFullscreen() is true or if windowed
* context are not supported on the platform, the display mode will be switched to the mode returned by
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
* created with the given parameters, a LWJGLException will be thrown.
* <p/>
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
*
* @param pixel_format Describes the minimum specifications the context must fulfill.
*
* @throws LWJGLException
*/
public static void create(org.lwjgl.opengles.PixelFormat pixel_format) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
create(pixel_format, null, null);
}
}
/**
* Create the OpenGL context with the given minimum parameters. If isFullscreen() is true or if windowed
* context are not supported on the platform, the display mode will be switched to the mode returned by
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
* created with the given parameters, a LWJGLException will be thrown.
* <p/>
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
*
* @param pixel_format Describes the minimum specifications the context must fulfill.
* @param shared_drawable The Drawable to share context with. (optional, may be null)
*
* @throws LWJGLException
*/
public static void create(org.lwjgl.opengles.PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
create(pixel_format, shared_drawable, null);
}
}
/**
* Create the OpenGL context with the given minimum parameters. If isFullscreen() is true or if windowed
* context are not supported on the platform, the display mode will be switched to the mode returned by
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
* created with the given parameters, a LWJGLException will be thrown.
* <p/>
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
*
* @param pixel_format Describes the minimum specifications the context must fulfill.
* @param attribs The ContextAttribs to use when creating the context. (optional, may be null)
*
* @throws LWJGLException
*/
public static void create(org.lwjgl.opengles.PixelFormat pixel_format, org.lwjgl.opengles.ContextAttribs attribs) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
create(pixel_format, null, attribs);
}
}
/**
* Create the OpenGL ES context with the given minimum parameters. If isFullscreen() is true or if windowed
* context are not supported on the platform, the display mode will be switched to the mode returned by
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
* created with the given parameters, a LWJGLException will be thrown.
* <p/>
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
*
* @param pixel_format Describes the minimum specifications the context must fulfill.
* @param shared_drawable The Drawable to share context with. (optional, may be null)
* @param attribs The ContextAttribs to use when creating the context. (optional, may be null)
*
* @throws LWJGLException
*/
public static void create(org.lwjgl.opengles.PixelFormat pixel_format, Drawable shared_drawable, org.lwjgl.opengles.ContextAttribs attribs) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
if ( isCreated() )
throw new IllegalStateException("Only one LWJGL context may be instantiated at any one time.");
if ( pixel_format == null )
throw new NullPointerException("pixel_format cannot be null");
removeShutdownHook();
registerShutdownHook();
if ( isFullscreen() )
switchDisplayMode();
final DrawableGLES drawable = new DrawableGLES() {
public void destroy() {
synchronized ( GlobalLock.lock ) {
if ( !isCreated() )
return;
releaseDrawable();
super.destroy();
destroyWindow();
x = y = -1;
cached_icons = null;
reset();
removeShutdownHook();
}
}
};
Display.drawable = drawable;
try {
drawable.setPixelFormat(pixel_format);
try {
createWindow();
try {
drawable.createContext(attribs, shared_drawable);
try {
makeCurrentAndSetSwapInterval();
initContext();
@ -896,7 +1043,7 @@ public final class Display {
private static void makeCurrentAndSetSwapInterval() throws LWJGLException {
makeCurrent();
try {
Util.checkGLError();
drawable.checkGLError();
} catch (OpenGLException e) {
LWJGLUtil.log("OpenGL error during context creation: " + e.getMessage());
}
@ -904,10 +1051,7 @@ public final class Display {
}
private static void initContext() {
// set background clear color
glClearColor(r, g, b, 0.0f);
// Clear window to avoid the desktop "showing through"
glClear(GL_COLOR_BUFFER_BIT);
drawable.initContext(r, g, b);
update();
}
@ -990,7 +1134,8 @@ public final class Display {
synchronized ( GlobalLock.lock ) {
swap_interval = value;
if ( isCreated() )
Context.setSwapInterval(swap_interval);
drawable.setSwapInterval(swap_interval);
}
}

View file

@ -47,7 +47,7 @@ import org.lwjgl.LWJGLException;
interface DisplayImplementation extends InputImplementation {
void createWindow(DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException;
void createWindow(DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException;
void destroyWindow();

View file

@ -4,33 +4,64 @@ import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
/**
* @author Spasi
*/
abstract class AbstractDrawable implements DrawableLWJGL {
import static org.lwjgl.opengl.GL11.*;
/** @author Spasi */
abstract class DrawableGL implements DrawableLWJGL {
/** The PixelFormat used to create the drawable. */
protected PixelFormat pixel_format;
/** Handle to the native GL rendering context */
protected PeerInfo peer_info;
/** The OpenGL Context. */
protected Context context;
protected ContextGL context;
protected AbstractDrawable() {
protected DrawableGL() {
}
public Context getContext() {
public void setPixelFormat(final PixelFormatLWJGL pf) throws LWJGLException {
this.pixel_format = (PixelFormat)pf;
this.peer_info = Display.getImplementation().createPeerInfo(pixel_format);
}
public PixelFormatLWJGL getPixelFormat() {
return pixel_format;
}
public ContextGL getContext() {
synchronized ( GlobalLock.lock ) {
return context;
}
}
public Context createSharedContext() throws LWJGLException {
public ContextGL createSharedContext() throws LWJGLException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
return new Context(peer_info, context.getContextAttribs(), context);
return new ContextGL(peer_info, context.getContextAttribs(), context);
}
}
public void checkGLError() {
Util.checkGLError();
}
public void setSwapInterval(final int swap_interval) {
ContextGL.setSwapInterval(swap_interval);
}
public void swapBuffers() throws LWJGLException {
ContextGL.swapBuffers();
}
public void initContext(final float r, final float g, final float b) {
// set background clear color
glClearColor(r, g, b, 0.0f);
// Clear window to avoid the desktop "showing through"
glClear(GL_COLOR_BUFFER_BIT);
}
public boolean isCurrent() throws LWJGLException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
@ -49,7 +80,7 @@ abstract class AbstractDrawable implements DrawableLWJGL {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
if ( context.isCurrent() )
Context.releaseCurrentContext();
context.releaseCurrent();
}
}

View file

@ -0,0 +1,211 @@
package org.lwjgl.opengl;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
import org.lwjgl.opengles.ContextAttribs;
import org.lwjgl.opengles.*;
import org.lwjgl.opengles.Util;
import static org.lwjgl.opengles.EGL.*;
import static org.lwjgl.opengles.GLES20.*;
/**
* @author Spasi
* @since 14/5/2011
*/
abstract class DrawableGLES implements DrawableLWJGL {
/** The PixelFormat used to create the EGLDisplay. */
protected org.lwjgl.opengles.PixelFormat pixel_format;
protected EGLDisplay eglDisplay;
protected EGLConfig eglConfig;
protected EGLSurface eglSurface;
/** The OpenGL Context. */
protected ContextGLES context;
/** The Drawable that shares objects with this Drawable. */
protected Drawable shared_drawable;
protected DrawableGLES() {
}
public void setPixelFormat(final PixelFormatLWJGL pf) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
this.pixel_format = (org.lwjgl.opengles.PixelFormat)pf;
}
}
public PixelFormatLWJGL getPixelFormat() {
synchronized ( GlobalLock.lock ) {
return pixel_format;
}
}
public void initialize(final long window, final long display_id, final int eglSurfaceType, final org.lwjgl.opengles.PixelFormat pf) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
if ( eglSurface != null ) {
eglSurface.destroy();
eglSurface = null;
}
if ( eglDisplay != null ) {
eglDisplay.terminate();
eglDisplay = null;
}
final EGLDisplay eglDisplay = eglGetDisplay((int)display_id);
int[] attribs = {
EGL_LEVEL, 0,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NATIVE_RENDERABLE, EGL_FALSE,
};
final EGLConfig[] configs = eglDisplay.chooseConfig(pf.getAttribBuffer(eglDisplay, eglSurfaceType, attribs), null, APIUtil.getBufferInt());
if ( configs.length == 0 )
throw new LWJGLException("No EGLConfigs found for the specified PixelFormat.");
final EGLConfig eglConfig = pf.getBestMatch(configs);
final EGLSurface eglSurface = eglDisplay.createWindowSurface(eglConfig, (int)window, null);
pf.setSurfaceAttribs(eglSurface);
this.eglDisplay = eglDisplay;
this.eglConfig = eglConfig;
this.eglSurface = eglSurface;
// This can happen when switching in and out of full-screen mode.
if ( context != null )
context.getEGLContext().setDisplay(eglDisplay);
}
}
public void createContext(final ContextAttribs attribs, final Drawable shared_drawable) throws LWJGLException {
synchronized ( GlobalLock.lock ) {
this.context = new ContextGLES(this, attribs, shared_drawable != null ? ((DrawableGLES)shared_drawable).getContext() : null);
this.shared_drawable = shared_drawable;
}
}
Drawable getSharedDrawable() {
synchronized ( GlobalLock.lock ) {
return shared_drawable;
}
}
public EGLDisplay getEGLDisplay() {
synchronized ( GlobalLock.lock ) {
return eglDisplay;
}
}
public EGLConfig getEGLConfig() {
synchronized ( GlobalLock.lock ) {
return eglConfig;
}
}
public EGLSurface getEGLSurface() {
synchronized ( GlobalLock.lock ) {
return eglSurface;
}
}
public ContextGLES getContext() {
synchronized ( GlobalLock.lock ) {
return context;
}
}
public org.lwjgl.opengl.Context createSharedContext() throws LWJGLException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
return new ContextGLES(this, context.getContextAttribs(), context);
}
}
public void checkGLError() {
Util.checkGLError();
}
public void setSwapInterval(final int swap_interval) {
ContextGLES.setSwapInterval(swap_interval);
}
public void swapBuffers() throws LWJGLException {
ContextGLES.swapBuffers();
}
public void initContext(final float r, final float g, final float b) {
// set background clear color
glClearColor(r, g, b, 0.0f);
// Clear window to avoid the desktop "showing through"
glClear(GL_COLOR_BUFFER_BIT);
}
public boolean isCurrent() throws LWJGLException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
return context.isCurrent();
}
}
public void makeCurrent() throws LWJGLException, PowerManagementEventException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
context.makeCurrent();
}
}
public void releaseContext() throws LWJGLException, PowerManagementEventException {
synchronized ( GlobalLock.lock ) {
checkDestroyed();
if ( context.isCurrent() )
context.releaseCurrent();
}
}
public void destroy() {
synchronized ( GlobalLock.lock ) {
try {
if ( context != null ) {
try {
releaseContext();
} catch (PowerManagementEventException e) {
// Ignore
}
context.forceDestroy();
context = null;
}
if ( eglSurface != null ) {
eglSurface.destroy();
eglSurface = null;
}
if ( eglDisplay != null ) {
eglDisplay.terminate();
eglDisplay = null;
}
pixel_format = null;
shared_drawable = null;
} catch (LWJGLException e) {
LWJGLUtil.log("Exception occurred while destroying Drawable: " + e);
}
}
}
protected void checkDestroyed() {
if ( context == null )
throw new IllegalStateException("The Drawable has no context available.");
}
public void setCLSharingProperties(final PointerBuffer properties) throws LWJGLException {
throw new UnsupportedOperationException();
}
}

View file

@ -3,10 +3,16 @@ package org.lwjgl.opengl;
import org.lwjgl.LWJGLException;
/**
* [INTERNAL USE ONLY]
*
* @author Spasi
*/
interface DrawableLWJGL extends Drawable {
void setPixelFormat(PixelFormatLWJGL pf) throws LWJGLException;
PixelFormatLWJGL getPixelFormat();
/**
* [INTERNAL USE ONLY] Returns the Drawable's Context.
*
@ -21,4 +27,12 @@ interface DrawableLWJGL extends Drawable {
*/
Context createSharedContext() throws LWJGLException;
}
void checkGLError();
void setSwapInterval(int swap_interval);
void swapBuffers() throws LWJGLException;
void initContext(final float r, final float g, final float b);
}

View file

@ -67,7 +67,7 @@ final class LinuxContextImplementation implements ContextImplementation {
}
public void swapBuffers() throws LWJGLException {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
if ( current_context == null )
throw new IllegalStateException("No context is current");
synchronized ( current_context ) {
@ -89,7 +89,7 @@ final class LinuxContextImplementation implements ContextImplementation {
private static native void nSwapBuffers(ByteBuffer peer_info_handle) throws LWJGLException;
public void releaseCurrentContext() throws LWJGLException {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
if ( current_context == null )
throw new IllegalStateException("No context is current");
synchronized ( current_context ) {
@ -142,7 +142,7 @@ final class LinuxContextImplementation implements ContextImplementation {
private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException;
public void setSwapInterval(int value) {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
if ( current_context == null )
throw new IllegalStateException("No context is current");
synchronized ( current_context ) {

View file

@ -50,6 +50,7 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.opengl.XRandR.Screen;
import org.lwjgl.opengles.EGL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -137,7 +138,7 @@ final class LinuxDisplay implements DisplayImplementation {
private boolean xembedded;
private boolean parent_focus;
private boolean mouseInside = true;
private LinuxKeyboard keyboard;
private LinuxMouse mouse;
@ -259,7 +260,12 @@ final class LinuxDisplay implements DisplayImplementation {
*/
static void incDisplay() throws LWJGLException {
if (display_connection_usage_count == 0) {
GLContext.loadOpenGLLibrary();
try {
// TODO: Can we know if we're on desktop or ES?
GLContext.loadOpenGLLibrary();
org.lwjgl.opengles.GLContext.loadOpenGLLibrary();
} catch (Throwable t) {
}
saved_error_handler = setErrorHandler();
display = openDisplay();
// synchronize(display, true);
@ -408,11 +414,14 @@ final class LinuxDisplay implements DisplayImplementation {
ungrabKeyboard();
}
public void createWindow(DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
public void createWindow(final DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
lockAWT();
try {
incDisplay();
try {
if ( drawable instanceof DrawableGLES )
peer_info = new LinuxDisplayPeerInfo();
ByteBuffer handle = peer_info.lockAndGetHandle();
try {
current_window_mode = getWindowMode(Display.isFullscreen());
@ -440,6 +449,9 @@ final class LinuxDisplay implements DisplayImplementation {
grab = false;
minimized = false;
dirty = true;
if ( drawable instanceof DrawableGLES )
((DrawableGLES)drawable).initialize(current_window, getDisplay(), EGL.EGL_WINDOW_BIT, (org.lwjgl.opengles.PixelFormat)drawable.getPixelFormat());
} finally {
peer_info.unlock();
}
@ -1446,4 +1458,4 @@ final class LinuxDisplay implements DisplayImplementation {
}
}
}
}

View file

@ -42,7 +42,16 @@ import org.lwjgl.LWJGLException;
* $Id$
*/
final class LinuxDisplayPeerInfo extends LinuxPeerInfo {
final boolean egl;
LinuxDisplayPeerInfo() throws LWJGLException {
egl = true;
org.lwjgl.opengles.GLContext.loadOpenGLLibrary();
}
LinuxDisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException {
egl = false;
LinuxDisplay.lockAWT();
try {
GLContext.loadOpenGLLibrary();
@ -80,9 +89,14 @@ final class LinuxDisplayPeerInfo extends LinuxPeerInfo {
public void destroy() {
super.destroy();
LinuxDisplay.lockAWT();
LinuxDisplay.decDisplay();
GLContext.unloadOpenGLLibrary();
LinuxDisplay.unlockAWT();
if ( egl )
org.lwjgl.opengles.GLContext.unloadOpenGLLibrary();
else {
LinuxDisplay.lockAWT();
LinuxDisplay.decDisplay();
GLContext.unloadOpenGLLibrary();
LinuxDisplay.unlockAWT();
}
}
}

View file

@ -55,7 +55,7 @@ final class MacOSXContextImplementation implements ContextImplementation {
private static native ByteBuffer nCreate(ByteBuffer peer_handle, IntBuffer attribs, ByteBuffer shared_context_handle) throws LWJGLException;
public void swapBuffers() throws LWJGLException {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
if ( current_context == null )
throw new IllegalStateException("No context is current");
synchronized ( current_context ) {
@ -83,7 +83,7 @@ final class MacOSXContextImplementation implements ContextImplementation {
private static native void clearDrawable(ByteBuffer handle) throws LWJGLException;
static void resetView(PeerInfo peer_info, Context context) throws LWJGLException {
static void resetView(PeerInfo peer_info, ContextGL context) throws LWJGLException {
ByteBuffer peer_handle = peer_info.lockAndGetHandle();
try {
synchronized ( context ) {
@ -117,7 +117,7 @@ final class MacOSXContextImplementation implements ContextImplementation {
private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException;
public void setSwapInterval(int value) {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
synchronized ( current_context ) {
nSetSwapInterval(current_context.getHandle(), value);
}

View file

@ -96,7 +96,7 @@ final class MacOSXDisplay implements DisplayImplementation {
}
}
public void createWindow(DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
public void createWindow(final DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
boolean fullscreen = Display.isFullscreen();
hideUI(fullscreen);
close_requested = false;
@ -272,7 +272,7 @@ final class MacOSXDisplay implements DisplayImplementation {
*
* - elias
*/
AbstractDrawable drawable = (AbstractDrawable)Display.getDrawable();
DrawableGL drawable = (DrawableGL)Display.getDrawable();
if (Display.isFullscreen() && (frame != null && frame.getCanvas().syncCanvasPainted() || should_update)) {
try {
MacOSXContextImplementation.resetView(drawable.peer_info, drawable.context);

View file

@ -48,7 +48,7 @@ import org.lwjgl.Sys;
* @version $Revision$
* $Id$
*/
public final class Pbuffer extends AbstractDrawable {
public final class Pbuffer extends DrawableGL {
/**
* Indicates that Pbuffers can be created.
*/
@ -222,7 +222,7 @@ public final class Pbuffer extends AbstractDrawable {
shared_context = ((DrawableLWJGL)shared_drawable).getContext();
else
shared_context = ((DrawableLWJGL)Display.getDrawable()).getContext(); // May be null
this.context = new Context(peer_info, attribs, shared_context);
this.context = new ContextGL(peer_info, attribs, (ContextGL)shared_context);
}
private static PeerInfo createPbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture) throws LWJGLException {

View file

@ -48,7 +48,7 @@ package org.lwjgl.opengl;
* @version $Revision$
*/
public final class PixelFormat {
public final class PixelFormat implements PixelFormatLWJGL {
/**
* The number of bits per pixel, exluding alpha.

View file

@ -0,0 +1,11 @@
package org.lwjgl.opengl;
/**
* [INTERNAL USE ONLY]
*
* @author Spasi
* @since 15/5/2011
*/
public interface PixelFormatLWJGL {
// Marker interface
}

View file

@ -44,13 +44,13 @@ import org.lwjgl.LWJGLException;
*
* @author Spasi
*/
public final class SharedDrawable extends AbstractDrawable {
public final class SharedDrawable extends DrawableGL {
public SharedDrawable(final Drawable drawable) throws LWJGLException {
this.context = ((DrawableLWJGL)drawable).createSharedContext();
this.context = (ContextGL)((DrawableLWJGL)drawable).createSharedContext();
}
public Context createSharedContext() {
public ContextGL createSharedContext() {
throw new UnsupportedOperationException();
}

View file

@ -60,7 +60,7 @@ final class WindowsContextImplementation implements ContextImplementation {
native long getHDC(ByteBuffer peer_info_handle);
public void swapBuffers() throws LWJGLException {
Context current_context = Context.getCurrentContext();
ContextGL current_context = ContextGL.getCurrentContext();
if ( current_context == null )
throw new IllegalStateException("No context is current");
synchronized ( current_context ) {

View file

@ -47,8 +47,8 @@ import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengles.EGL;
final class WindowsDisplay implements DisplayImplementation {
private static final int GAMMA_LENGTH = 256;
@ -124,7 +124,6 @@ final class WindowsDisplay implements DisplayImplementation {
private static final IntBuffer rect_buffer = BufferUtils.createIntBuffer(4);
private static final Rect rect = new Rect();
private static final Rect rect2 = new Rect();
private static WindowsDisplay current_display;
private static boolean cursor_clipped;
@ -163,7 +162,7 @@ final class WindowsDisplay implements DisplayImplementation {
current_display = this;
}
public void createWindow(DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
public void createWindow(DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException {
close_requested = false;
is_dirty = false;
isMinimized = false;
@ -181,12 +180,18 @@ final class WindowsDisplay implements DisplayImplementation {
nDestroyWindow(hwnd);
throw new LWJGLException("Failed to get dc");
}
try {
int format = WindowsPeerInfo.choosePixelFormat(getHdc(), 0, 0, peer_info.getPixelFormat(), null, true, true, false, true);
WindowsPeerInfo.setPixelFormat(getHdc(), format);
if ( drawable instanceof DrawableGL ) {
int format = WindowsPeerInfo.choosePixelFormat(getHdc(), 0, 0, (PixelFormat)drawable.getPixelFormat(), null, true, true, false, true);
WindowsPeerInfo.setPixelFormat(getHdc(), format);
} else {
peer_info = new WindowsDisplayPeerInfo(true);
((DrawableGLES)drawable).initialize(hwnd, hdc, EGL.EGL_WINDOW_BIT, (org.lwjgl.opengles.PixelFormat)drawable.getPixelFormat());
}
peer_info.initDC(getHwnd(), getHdc());
showWindow(getHwnd(), SW_SHOWDEFAULT);
if (parent == null) {
if ( parent == null ) {
setForegroundWindow(getHwnd());
setFocus(getHwnd());
}
@ -420,7 +425,7 @@ final class WindowsDisplay implements DisplayImplementation {
}
public PeerInfo createPeerInfo(PixelFormat pixel_format) throws LWJGLException {
peer_info = new WindowsDisplayPeerInfo(pixel_format);
peer_info = new WindowsDisplayPeerInfo(false);
return peer_info;
}
@ -971,4 +976,4 @@ final class WindowsDisplay implements DisplayImplementation {
return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right;
}
}
}
}

View file

@ -42,15 +42,16 @@ import org.lwjgl.LWJGLException;
* $Id$
*/
final class WindowsDisplayPeerInfo extends WindowsPeerInfo {
private final PixelFormat pixel_format;
WindowsDisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException {
this.pixel_format = pixel_format;
GLContext.loadOpenGLLibrary();
}
final boolean egl;
PixelFormat getPixelFormat() {
return pixel_format;
WindowsDisplayPeerInfo(boolean egl) throws LWJGLException {
this.egl = egl;
if ( egl)
org.lwjgl.opengles.GLContext.loadOpenGLLibrary();
else
GLContext.loadOpenGLLibrary();
}
void initDC(long hwnd, long hdc) throws LWJGLException {
@ -68,6 +69,10 @@ final class WindowsDisplayPeerInfo extends WindowsPeerInfo {
public void destroy() {
super.destroy();
GLContext.unloadOpenGLLibrary();
if ( egl )
org.lwjgl.opengles.GLContext.unloadOpenGLLibrary();
else
GLContext.unloadOpenGLLibrary();
}
}

View file

@ -0,0 +1,322 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
/** @author spasi */
final class APIUtil {
private static final int INITIAL_BUFFER_SIZE = 256;
private static final int INITIAL_LENGTHS_SIZE = 4;
private static final int BUFFERS_SIZE = 32;
private static final ThreadLocal<char[]> arrayTL = new ThreadLocal<char[]>() {
protected char[] initialValue() { return new char[INITIAL_BUFFER_SIZE]; }
};
private static final ThreadLocal<ByteBuffer> bufferTL = new ThreadLocal<ByteBuffer>() {
protected ByteBuffer initialValue() { return BufferUtils.createByteBuffer(INITIAL_BUFFER_SIZE); }
};
private static final ThreadLocal<PointerBuffer> bufferPointerTL = new ThreadLocal<PointerBuffer>() {
protected PointerBuffer initialValue() { return BufferUtils.createPointerBuffer(INITIAL_BUFFER_SIZE); }
};
private static final ThreadLocal<IntBuffer> lengthsTL = new ThreadLocal<IntBuffer>() {
protected IntBuffer initialValue() { return BufferUtils.createIntBuffer(INITIAL_LENGTHS_SIZE); }
};
private static final ThreadLocal<Buffers> buffersTL = new ThreadLocal<Buffers>() {
protected Buffers initialValue() { return new Buffers(); }
};
private APIUtil() {
}
private static char[] getArray(final int size) {
char[] array = arrayTL.get();
if ( array.length < size ) {
int sizeNew = array.length << 1;
while ( sizeNew < size )
sizeNew <<= 1;
array = new char[size];
arrayTL.set(array);
}
return array;
}
static ByteBuffer getBufferByte(final int size) {
ByteBuffer buffer = bufferTL.get();
if ( buffer.capacity() < size ) {
int sizeNew = buffer.capacity() << 1;
while ( sizeNew < size )
sizeNew <<= 1;
buffer = BufferUtils.createByteBuffer(size);
bufferTL.set(buffer);
} else
buffer.clear();
return buffer;
}
private static ByteBuffer getBufferByteOffset(final int size) {
ByteBuffer buffer = bufferTL.get();
if ( buffer.capacity() < size ) {
int sizeNew = buffer.capacity() << 1;
while ( sizeNew < size )
sizeNew <<= 1;
final ByteBuffer bufferNew = BufferUtils.createByteBuffer(size);
bufferNew.put(buffer);
bufferTL.set(buffer = bufferNew);
} else {
buffer.position(buffer.limit());
buffer.limit(buffer.capacity());
}
return buffer;
}
static PointerBuffer getBufferPointer(final int size) {
PointerBuffer buffer = bufferPointerTL.get();
if ( buffer.capacity() < size ) {
int sizeNew = buffer.capacity() << 1;
while ( sizeNew < size )
sizeNew <<= 1;
buffer = BufferUtils.createPointerBuffer(size);
bufferPointerTL.set(buffer);
} else
buffer.clear();
return buffer;
}
static ShortBuffer getBufferShort() { return buffersTL.get().shorts; }
static IntBuffer getBufferInt() { return buffersTL.get().ints; }
static FloatBuffer getBufferFloat() { return buffersTL.get().floats; }
static PointerBuffer getBufferPointer() { return buffersTL.get().pointers; }
static IntBuffer getLengths() {
return getLengths(1);
}
static IntBuffer getLengths(final int size) {
IntBuffer lengths = lengthsTL.get();
if ( lengths.capacity() < size ) {
int sizeNew = lengths.capacity();
while ( sizeNew < size )
sizeNew <<= 1;
lengths = BufferUtils.createIntBuffer(size);
lengthsTL.set(lengths);
} else
lengths.clear();
return lengths;
}
/**
* Simple ASCII encoding.
*
* @param buffer The target buffer
* @param string The source string
*/
private static ByteBuffer encode(final ByteBuffer buffer, final CharSequence string) {
for ( int i = 0; i < string.length(); i++ ) {
final char c = string.charAt(i);
if ( LWJGLUtil.DEBUG && 0x80 <= c ) // Silently ignore and map to 0x1A.
buffer.put((byte)0x1A);
else
buffer.put((byte)c);
}
return buffer;
}
/**
* Reads a byte string from the specified buffer.
*
* @param buffer
*
* @return the buffer as a String.
*/
static String getString(final ByteBuffer buffer) {
final int length = buffer.remaining();
final char[] charArray = getArray(length);
for ( int i = buffer.position(); i < buffer.limit(); i++ )
charArray[i - buffer.position()] = (char)buffer.get(i);
return new String(charArray, 0, length);
}
/**
* Returns a buffer containing the specified string as bytes.
*
* @param string
*
* @return the String as a ByteBuffer
*/
static ByteBuffer getBuffer(final CharSequence string) {
final ByteBuffer buffer = encode(getBufferByte(string.length()), string);
buffer.flip();
return buffer;
}
/**
* Returns a buffer containing the specified string as bytes, starting at the specified offset.
*
* @param string
*
* @return the String as a ByteBuffer
*/
static ByteBuffer getBuffer(final CharSequence string, final int offset) {
final ByteBuffer buffer = encode(getBufferByteOffset(offset + string.length()), string);
buffer.flip();
return buffer;
}
/**
* Returns a buffer containing the specified string as bytes, including null-termination.
*
* @param string
*
* @return the String as a ByteBuffer
*/
static ByteBuffer getBufferNT(final CharSequence string) {
final ByteBuffer buffer = encode(getBufferByte(string.length() + 1), string);
buffer.put((byte)0);
buffer.flip();
return buffer;
}
static int getTotalLength(final CharSequence[] strings) {
int length = 0;
for ( CharSequence string : strings )
length += string.length();
return length;
}
/**
* Returns a buffer containing the specified strings as bytes.
*
* @param strings
*
* @return the Strings as a ByteBuffer
*/
static ByteBuffer getBuffer(final CharSequence[] strings) {
final ByteBuffer buffer = getBufferByte(getTotalLength(strings));
for ( CharSequence string : strings )
encode(buffer, string);
buffer.flip();
return buffer;
}
/**
* Returns a buffer containing the specified strings as bytes, including null-termination.
*
* @param strings
*
* @return the Strings as a ByteBuffer
*/
static ByteBuffer getBufferNT(final CharSequence[] strings) {
final ByteBuffer buffer = getBufferByte(getTotalLength(strings) + strings.length);
for ( CharSequence string : strings ) {
encode(buffer, string);
buffer.put((byte)0);
}
buffer.flip();
return buffer;
}
/**
* Returns a buffer containing the lengths of the specified strings.
*
* @param strings
*
* @return the String lengths in an IntBuffer
*/
static IntBuffer getLengths(final CharSequence[] strings) {
IntBuffer buffer = getLengths(strings.length);
for ( CharSequence string : strings )
buffer.put(string.length());
buffer.flip();
return buffer;
}
private static class Buffers {
final ShortBuffer shorts;
final IntBuffer ints;
final FloatBuffer floats;
final PointerBuffer pointers;
Buffers() {
shorts = BufferUtils.createShortBuffer(BUFFERS_SIZE);
ints = BufferUtils.createIntBuffer(BUFFERS_SIZE);
floats = BufferUtils.createFloatBuffer(BUFFERS_SIZE);
pointers = BufferUtils.createPointerBuffer(BUFFERS_SIZE);
}
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferUtils;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/**
* This class represents the context attributes passed to EGL's eglCreateContext.
* The only attribute allowed is EGL_CONTEXT_CLIENT_VERSION and it must be 2 (LWJGL does not support GLES 1.x).
*/
public final class ContextAttribs {
private int version;
public ContextAttribs() {
this(2);
}
public ContextAttribs(final int version) {
if ( version != 2 )
throw new IllegalArgumentException("Invalid OpenGL ES version specified: " + version);
this.version = version;
}
private ContextAttribs(final ContextAttribs attribs) {
this.version = attribs.version;
}
public int getVersion() {
return version;
}
public IntBuffer getAttribList() {
int attribCount = 1;
final IntBuffer attribs = BufferUtils.createIntBuffer((attribCount * 2) + 1);
attribs.put(EGL_CONTEXT_CLIENT_VERSION).put(version);
attribs.put(EGL_NONE);
attribs.rewind();
return attribs;
}
public String toString() {
StringBuilder sb = new StringBuilder(32);
sb.append("ContextAttribs:");
sb.append(" Version=").append(version);
return sb.toString();
}
}

View file

@ -0,0 +1,922 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferChecks;
import org.lwjgl.LWJGLException;
import org.lwjgl.PointerBuffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
/** EGL wrapper class. */
public final class EGL {
/** EGL aliases */
public static final int
EGL_FALSE = 0,
EGL_TRUE = 1;
/** Out-of-band handle values */
public static final int
EGL_DEFAULT_DISPLAY = 0,
EGL_NO_CONTEXT = 0,
EGL_NO_DISPLAY = 0,
EGL_NO_SURFACE = 0;
/** Out-of-band attribute value */
public static final int EGL_DONT_CARE = -1;
/** Errors / GetError return values */
public static final int
EGL_SUCCESS = 0x3000,
EGL_NOT_INITIALIZED = 0x3001,
EGL_BAD_ACCESS = 0x3002,
EGL_BAD_ALLOC = 0x3003,
EGL_BAD_ATTRIBUTE = 0x3004,
EGL_BAD_CONFIG = 0x3005,
EGL_BAD_CONTEXT = 0x3006,
EGL_BAD_CURRENT_SURFACE = 0x3007,
EGL_BAD_DISPLAY = 0x3008,
EGL_BAD_MATCH = 0x3009,
EGL_BAD_NATIVE_PIXMAP = 0x300A,
EGL_BAD_NATIVE_WINDOW = 0x300B,
EGL_BAD_PARAMETER = 0x300C,
EGL_BAD_SURFACE = 0x300D,
EGL_CONTEXT_LOST = 0x300E; // EGL 1.1 - IMG_power_management
/** Reserved =0x300F;-=0x301F; for additional errors */
/** Config attributes */
public static final int
EGL_BUFFER_SIZE = 0x3020,
EGL_ALPHA_SIZE = 0x3021,
EGL_BLUE_SIZE = 0x3022,
EGL_GREEN_SIZE = 0x3023,
EGL_RED_SIZE = 0x3024,
EGL_DEPTH_SIZE = 0x3025,
EGL_STENCIL_SIZE = 0x3026,
EGL_CONFIG_CAVEAT = 0x3027,
EGL_CONFIG_ID = 0x3028,
EGL_LEVEL = 0x3029,
EGL_MAX_PBUFFER_HEIGHT = 0x302A,
EGL_MAX_PBUFFER_PIXELS = 0x302B,
EGL_MAX_PBUFFER_WIDTH = 0x302C,
EGL_NATIVE_RENDERABLE = 0x302D,
EGL_NATIVE_VISUAL_ID = 0x302E,
EGL_NATIVE_VISUAL_TYPE = 0x302F,
EGL_SAMPLES = 0x3031,
EGL_SAMPLE_BUFFERS = 0x3032,
EGL_SURFACE_TYPE = 0x3033,
EGL_TRANSPARENT_TYPE = 0x3034,
EGL_TRANSPARENT_BLUE_VALUE = 0x3035,
EGL_TRANSPARENT_GREEN_VALUE = 0x3036,
EGL_TRANSPARENT_RED_VALUE = 0x3037,
EGL_NONE = 0x3038, // Attrib list terminator
EGL_BIND_TO_TEXTURE_RGB = 0x3039,
EGL_BIND_TO_TEXTURE_RGBA = 0x303A,
EGL_MIN_SWAP_INTERVAL = 0x303B,
EGL_MAX_SWAP_INTERVAL = 0x303C,
EGL_LUMINANCE_SIZE = 0x303D,
EGL_ALPHA_MASK_SIZE = 0x303E,
EGL_COLOR_BUFFER_TYPE = 0x303F,
EGL_RENDERABLE_TYPE = 0x3040,
EGL_MATCH_NATIVE_PIXMAP = 0x3041, // Pseudo-attribute (not queryable)
EGL_CONFORMANT = 0x3042;
/** Reserved =0x3041;-=0x304F; for additional config attributes */
/** Config attribute values */
public static final int
EGL_SLOW_CONFIG = 0x3050, // EGL_CONFIG_CAVEAT value
EGL_NON_CONFORMANT_CONFIG = 0x3051, // EGL_CONFIG_CAVEAT value
EGL_TRANSPARENT_RGB = 0x3052, // EGL_TRANSPARENT_TYPE value
EGL_RGB_BUFFER = 0x308E, // EGL_COLOR_BUFFER_TYPE value
EGL_LUMINANCE_BUFFER = 0x308F; // EGL_COLOR_BUFFER_TYPE value
/** More config attribute values, for EGL_TEXTURE_FORMAT */
public static final int
EGL_NO_TEXTURE = 0x305C,
EGL_TEXTURE_RGB = 0x305D,
EGL_TEXTURE_RGBA = 0x305E,
EGL_TEXTURE_2D = 0x305F;
/** EGL_SURFACE_TYPE mask bits */
public static final int
EGL_PBUFFER_BIT = 0x0001,
EGL_PIXMAP_BIT = 0x0002,
EGL_WINDOW_BIT = 0x0004,
EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020,
EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040,
EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200,
EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
/** EGL_RENDERABLE_TYPE mask bits */
public static final int
EGL_OPENGL_ES_BIT = 0x0001,
EGL_OPENVG_BIT = 0x0002,
EGL_OPENGL_ES2_BIT = 0x0004,
EGL_OPENGL_BIT = 0x0008;
/** QueryString targets */
public static final int
EGL_VENDOR = 0x3053,
EGL_VERSION = 0x3054,
EGL_EXTENSIONS = 0x3055,
EGL_CLIENT_APIS = 0x308D;
/** QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
public static final int
EGL_HEIGHT = 0x3056,
EGL_WIDTH = 0x3057,
EGL_LARGEST_PBUFFER = 0x3058,
EGL_TEXTURE_FORMAT = 0x3080,
EGL_TEXTURE_TARGET = 0x3081,
EGL_MIPMAP_TEXTURE = 0x3082,
EGL_MIPMAP_LEVEL = 0x3083,
EGL_RENDER_BUFFER = 0x3086,
EGL_VG_COLORSPACE = 0x3087,
EGL_VG_ALPHA_FORMAT = 0x3088,
EGL_HORIZONTAL_RESOLUTION = 0x3090,
EGL_VERTICAL_RESOLUTION = 0x3091,
EGL_PIXEL_ASPECT_RATIO = 0x3092,
EGL_SWAP_BEHAVIOR = 0x3093,
EGL_MULTISAMPLE_RESOLVE = 0x3099;
/** EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
public static final int
EGL_BACK_BUFFER = 0x3084,
EGL_SINGLE_BUFFER = 0x3085;
/** OpenVG color spaces */
public static final int
EGL_VG_COLORSPACE_sRGB = 0x3089, // EGL_VG_COLORSPACE value
EGL_VG_COLORSPACE_LINEAR = 0x308A; // EGL_VG_COLORSPACE value
/** OpenVG alpha formats */
public static final int
EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B, // EGL_ALPHA_FORMAT value
EGL_VG_ALPHA_FORMAT_PRE = 0x308C; // EGL_ALPHA_FORMAT
/**
* Constant scale factor by which fractional display resolutions &
* aspect ratio are scaled when queried as integer values.
*/
public static final int EGL_DISPLAY_SCALING = 10000;
/** Unknown display resolution/aspect ratio */
public static final int EGL_UNKNOWN = -1;
/** Back buffer swap behaviors */
public static final int
EGL_BUFFER_PRESERVED = 0x3094, // EGL_SWAP_BEHAVIOR value
EGL_BUFFER_DESTROYED = 0x3095; // EGL_SWAP_BEHAVIOR value
/** CreatePbufferFromClientBuffer buffer types */
static final int EGL_OPENVG_IMAGE = 0x3096;
/** QueryContext targets */
public static final int EGL_CONTEXT_CLIENT_TYPE = 0x3097;
/** CreateContext attributes */
public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
/** Multisample resolution behaviors */
public static final int
EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A, // EGL_MULTISAMPLE_RESOLVE value
EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B; // EGL_MULTISAMPLE_RESOLVE value
/** BindAPI/QueryAPI targets */
public static final int
EGL_OPENGL_ES_API = 0x30A0,
EGL_OPENVG_API = 0x30A1,
EGL_OPENGL_API = 0x30A2;
/** GetCurrentSurface targets */
public static final int
EGL_DRAW = 0x3059,
EGL_READ = 0x305A;
/** WaitNative engines */
static final int EGL_CORE_NATIVE_ENGINE = 0x305B;
private EGL() {
}
public static native int eglGetError();
/**
* Obtains an EGL display from the specified native display and initializes it.
*
* @param display_id the handle to the native display.
*
* @return the EGL Display
*
* @throws org.lwjgl.LWJGLException if no display is available or an EGL error occurs
*/
public static EGLDisplay eglGetDisplay(long display_id) throws LWJGLException {
//LWJGLUtil.log("eglGetDisplay");
final long pointer = neglGetDisplay(display_id);
if ( pointer == EGL_NO_DISPLAY ) // No error is generated when this happens
throw new LWJGLException("Failed to get EGL display from native display handle: " + display_id);
return new EGLDisplay(pointer);
}
private static native long neglGetDisplay(long display_id);
/**
* Initializes the specified EGL display.
*
* @param dpy the EGL display to initialize
* @param version the EGL major and minor version will be returned in this buffer.
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglInitialize(EGLDisplay dpy, IntBuffer version) throws LWJGLException {
//LWJGLUtil.log("eglInitialize");
BufferChecks.checkBuffer(version, 2);
if ( !neglInitialize(dpy.getPointer(), version, version.position()) )
throwEGLError("Failed to initialize EGL display.");
}
private static native boolean neglInitialize(long dpy_ptr, IntBuffer version, int version_position);
/**
* Release the resources associated with the specified EGL display.
*
* @param dpy the EGL display to terminate
*/
static void eglTerminate(EGLDisplay dpy) throws LWJGLException {
//LWJGLUtil.log("eglTerminate");
if ( !neglTerminate(dpy.getPointer()) )
throwEGLError("Failed to terminate EGL display.");
}
private static native boolean neglTerminate(long dpy_ptr);
/**
* Returns a string describing some aspect of the EGL implementation running on the specified display.
*
* @param dpy the EGL display to query
* @param name the value to query
*
* @return the description
*/
public static String eglQueryString(EGLDisplay dpy, int name) {
//LWJGLUtil.log("eglQueryString");
return neglQueryString(dpy.getPointer(), name);
}
private static native String neglQueryString(long dpy, int name);
/**
* Returns the number of EGLConfigs that are available on the specified display.
*
* @param dpy the EGLDisplay
*
* @return the number of EGLConfigs available
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @see #eglGetConfigs(EGLDisplay, EGLConfig[], IntBuffer)
*/
static int eglGetConfigsNum(EGLDisplay dpy) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigsNum");
IntBuffer num_config = APIUtil.getBufferInt();
if ( !neglGetConfigs(dpy.getPointer(), null, 0, 0, num_config, num_config.position()) )
throwEGLError("Failed to get EGL configs.");
return num_config.get(0);
}
/**
* Returns the available EGLConfigs on the speficied display. The number of available EGLConfigs
* is returned in the num_config parameter. The configs array may be null. If it is null, a new
* array will be allocated, with size equal to the result of {@link #eglGetConfigsNum(EGLDisplay)} eglGetConfigsNum}.
* If it is not null, no more than {@code configs.length} EGLConfigs will be returned. If the array is bigger
* than the number of available EGLConfigs, the remaining array elements will not be affected.
*
* @param dpy the EGLDisplay
* @param configs the EGLConfigs array
* @param num_config the number of available EGLConfigs returned
*
* @return the available EGLConfigs
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLConfig[] eglGetConfigs(EGLDisplay dpy, EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigs");
BufferChecks.checkBuffer(num_config, 1);
if ( configs == null ) {
if ( !neglGetConfigs(dpy.getPointer(), null, 0, 0, num_config, num_config.position()) )
throwEGLError("Failed to get number of available EGL configs.");
configs = new EGLConfig[num_config.get(num_config.position())];
}
final PointerBuffer configs_buffer = APIUtil.getBufferPointer(configs.length);
if ( !neglGetConfigs(dpy.getPointer(), configs_buffer.getBuffer(), 0, configs.length, num_config, num_config.position()) )
throwEGLError("Failed to get EGL configs.");
final int config_size = num_config.get(num_config.position());
for ( int i = 0; i < config_size; i++ )
configs[i] = new EGLConfig(dpy, configs_buffer.get(i));
return configs;
}
private static native boolean neglGetConfigs(long dpy_ptr, ByteBuffer configs, int configs_position, int config_size, IntBuffer num_config, int num_config_position);
/**
* Returns the number of EGLConfigs that are available on the specified display and
* match the speficied list of attributes.
*
* @param dpy the EGLDisplay
* @param attrib_list the attribute list (may be null)
*
* @return the number of EGLConfigs available that satisft the attribute list
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @see #eglChooseConfig(EGLDisplay, IntBuffer, EGLConfig[], IntBuffer)
*/
static int eglChooseConfigNum(EGLDisplay dpy, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglChooseConfigNum");
checkAttribList(attrib_list);
IntBuffer num_config = APIUtil.getBufferInt();
if ( !neglChooseConfig(dpy.getPointer(), attrib_list, attrib_list == null ? 0 : attrib_list.position(), null, 0, 0, num_config, num_config.position()) )
throwEGLError("Failed to get EGL configs.");
return num_config.get(0);
}
/**
* Returns the available EGLConfigs on the speficied display that satisfy the specified list of attributes.
* The number of available EGLConfigs is returned in the num_config parameter. The configs array may be null.
* If it is null, a new array will be allocated, with size equal to the result of {@link #eglGetConfigsNum(EGLDisplay)} eglGetConfigsNum}.
* If it is not null, no more than {@code configs.length} EGLConfigs will be returned. If the array is bigger
* than the number of available EGLConfigs, the remaining array elements will not be affected.
*
* @param dpy the EGLDisplay
* @param attrib_list the attribute list (may be null)
* @param configs the EGLConfigs array
* @param num_config the number of available EGLConfigs returned
*
* @return the available EGLConfigs that satisfy the attribute list
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLConfig[] eglChooseConfig(EGLDisplay dpy, IntBuffer attrib_list, EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
//LWJGLUtil.log("eglChooseConfig");
checkAttribList(attrib_list);
BufferChecks.checkBuffer(num_config, 1);
int config_size;
if ( configs == null ) {
if ( !neglChooseConfig(dpy.getPointer(), attrib_list, attrib_list == null ? 0 : attrib_list.position(), null, 0, 0, num_config, num_config.position()) )
throwEGLError("Failed to get number of available EGL configs.");
config_size = num_config.get(num_config.position());
} else
config_size = configs.length;
//LWJGLUtil.log("config_size = " + config_size);
PointerBuffer configs_buffer = APIUtil.getBufferPointer(config_size);
if ( !neglChooseConfig(dpy.getPointer(), attrib_list, attrib_list == null ? 0 : attrib_list.position(), configs_buffer.getBuffer(), 0, config_size, num_config, num_config.position()) )
throwEGLError("Failed to choose EGL config.");
// Get the true number of configurations (the first neglChooseConfig call may return more than the second)
config_size = num_config.get(num_config.position());
if ( configs == null )
configs = new EGLConfig[config_size];
for ( int i = 0; i < config_size; i++ )
configs[i] = new EGLConfig(dpy, configs_buffer.get(i));
return configs;
}
private static native boolean neglChooseConfig(long dpy_ptr, IntBuffer attrib_list, int attrib_list_position, ByteBuffer configs, int configs_position, int config_size, IntBuffer num_config, int num_config_position);
/**
* Returns the value of an EGL config attribute.
*
* @param dpy the EGL display
* @param config the EGL config
* @param attribute the attribute
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static int eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigAttrib");
final IntBuffer value = APIUtil.getBufferInt();
if ( !neglGetConfigAttrib(dpy.getPointer(), config.getPointer(), attribute, value, value.position()) )
throwEGLError("Failed to get EGL config attribute.");
return value.get(0);
}
private static native boolean neglGetConfigAttrib(long dpy_ptr, long config_ptr, int attribute, IntBuffer value, int value_position);
/**
* Creates an on-screen rendering surface on the specified EGL display.
*
* @param dpy the EGL display
* @param config the EGL config
* @param win the native window handle
* @param attrib_list an attribute list (may be null)
*
* @return the created EGL surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, long win, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreateWindowSurface");
checkAttribList(attrib_list);
final long pointer = neglCreateWindowSurface(dpy.getPointer(), config.getPointer(), win, attrib_list, attrib_list == null ? 0 : attrib_list.position());
if ( pointer == EGL_NO_SURFACE )
throwEGLError("Failed to create EGL window surface.");
return new EGLSurface(dpy, config, pointer);
}
private static native long neglCreateWindowSurface(long dpy_ptr, long config_ptr, long win, IntBuffer attrib_list, int attrib_list_position);
/**
* Creates an off-screen rendering surface on the specified EGL display.
*
* @param dpy the EGL display
* @param config the EGL config
* @param attrib_list an attribute list (may be null)
*
* @return the created EGL surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreatePbufferSurface");
checkAttribList(attrib_list);
final long pointer = neglCreatePbufferSurface(dpy.getPointer(), config.getPointer(), attrib_list, attrib_list == null ? 0 : attrib_list.position());
if ( pointer == EGL_NO_SURFACE )
throwEGLError("Failed to create EGL pbuffer surface.");
return new EGLSurface(dpy, config, pointer);
}
private static native long neglCreatePbufferSurface(long dpy_ptr, long config_ptr, IntBuffer attrib_list, int attrib_list_position);
/*
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
*/
/**
* Sets the specified EGL surface attribute to the specified value.
*
* @param dpy the EGL display
* @param surface the EGL surface
* @param attribute the attribute
* @param value the attribute value
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value) throws LWJGLException {
//LWJGLUtil.log("eglSurfaceAttrib");
if ( !neglSurfaceAttrib(dpy.getPointer(), surface.getPointer(), attribute, value) )
throwEGLError("Failed to set surface attribute.");
}
private static native boolean neglSurfaceAttrib(long dpy_ptr, long surface_ptr, int attribute, int value);
/**
* Destroys the specified EGL surface.
*
* @param dpy the EGL display
* @param surface the EGL surface to destroy
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglDestroySurface(EGLDisplay dpy, EGLSurface surface) throws LWJGLException {
//LWJGLUtil.log("eglDestroySurface");
if ( !neglDestroySurface(dpy.getPointer(), surface.getPointer()) )
throwEGLError("Failed to destroy EGL surface.");
}
private static native boolean neglDestroySurface(long dpy_ptr, long surface_ptr);
/**
* Returns the value of the specified EGL surface attribute in the value parameter.
*
* @param dpy the EGL display
* @param surface the EGL surface
* @param attribute the surface attribute
* @param value the attribute value will be returned here
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static void eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, IntBuffer value) throws LWJGLException {
//LWJGLUtil.log("eglQuerySurface");
BufferChecks.checkBuffer(value, 1);
if ( !neglQuerySurface(dpy.getPointer(), surface.getPointer(), attribute, value, value.position()) )
throwEGLError("Failed to query surface attribute.");
}
private static native boolean neglQuerySurface(long dpy_ptr, long surface_ptr, int attribute, IntBuffer value, int value_position);
/**
* Binds the specified rendering API to the current thread.
*
* @param api the API to bind
*
* @return true if the bind was successful, false if an EGL error occurs
*/
public static native boolean eglBindAPI(int api);
/**
* Returns the current rendering API.
*
* @return the rendering API bound to the current thread
*/
public static native int eglQueryAPI();
/**
* Returns EGL to its state at thread initialization. This includes the following:<br>
* <p>
* For each client API supported by EGL, if there is a currently bound context,
* that context is released. This is equivalent to calling eglMakeCurrent
* with ctx set to EGL_NO_CONTEXT and both draw and read set to EGL_NO_SURFACE
* </p><br>
* <p>The current rendering API is reset to its value at thread initialization</p><br>
* <p>Any additional implementation-dependent per-thread state maintained by EGL
* is marked for deletion as soon as possible.</p>
*
* @return true if thread state was released successfully, false is an EGL error occurs
*/
static native boolean eglReleaseThread();
/*
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
*/
/**
* Specifies the minimum number of video frame periods per buffer swap for
* the window associated with the current context.
*
* @param dpy the EGL display
* @param interval the frame interval
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglSwapInterval(EGLDisplay dpy, int interval) throws LWJGLException {
//LWJGLUtil.log("eglSwapInterval");
if ( !neglSwapInterval(dpy.getPointer(), interval) )
throwEGLError("Failed to set swap interval.");
}
private static native boolean neglSwapInterval(long dpy_ptr, int interval);
/**
* Creates a new EGL context for the current rendering API.
*
* @param dpy the EGL display
* @param config the EGL config
* @param share_context the EGL context to share data with
* @param attrib_list the attribute list (may be null)
*
* @return the created EGL context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreateContext");
checkAttribList(attrib_list);
final long pointer = neglCreateContext(dpy.getPointer(), config.getPointer(),
share_context == null ? EGL_NO_CONTEXT : share_context.getPointer(),
attrib_list, attrib_list == null ? 0 : attrib_list.position());
if ( pointer == EGL_NO_CONTEXT )
throwEGLError("Failed to create EGL context.");
return new EGLContext(dpy, config, pointer);
}
private static native long neglCreateContext(long dpy_ptr, long config_ptr, long share_context_ptr, IntBuffer attrib_list, int attrib_list_position);
/**
* Destroys a rendering context.
*
* @param dpy the EGL display
* @param ctx the EGL context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglDestroyContext(EGLDisplay dpy, EGLContext ctx) throws LWJGLException {
//LWJGLUtil.log("eglDestroyContext");
if ( !neglDestroyContext(dpy.getPointer(), ctx.getPointer()) )
throwEGLError("Failed to destroy context.");
}
private static native boolean neglDestroyContext(long dpy_ptr, long ctx_ptr);
/**
* Binds the specified context to the current thread and to the draw and read surfaces.
*
* @param dpy the EGL display
* @param draw the draw EGL surface
* @param read the read EGL surface
* @param ctx the EGL context to make current
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @throws PowerManagementEventException if an EGL power management event occurs
*/
static void eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglMakeCurrent");
if ( !neglMakeCurrent(dpy.getPointer(),
draw == null ? EGL_NO_SURFACE : draw.getPointer(),
read == null ? EGL_NO_SURFACE : read.getPointer(),
ctx == null ? EGL_NO_CONTEXT : ctx.getPointer()) ) {
final int error = eglGetError();
if ( error == EGL_CONTEXT_LOST )
throw new PowerManagementEventException();
else
throwEGLError("Failed to change the current context.", error);
}
}
/**
* Releases the current context without assigning a new one.
*
* @param dpy the EGL display
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @throws PowerManagementEventException if an EGL power management event occurs
* @see #eglMakeCurrent(EGLDisplay, EGLSurface, EGLSurface, EGLContext)
*/
public static void eglReleaseCurrent(EGLDisplay dpy) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglReleaseCurrent");
eglMakeCurrent(dpy, null, null, null);
}
private static native boolean neglMakeCurrent(long dpy_ptr, long draw_ptr, long read_ptr, long ctx_ptr);
/**
* Returns the current EGL context for the current rendering API.
* If there is no context current, null is returned.
*
* @return the current context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLContext eglGetCurrentContext() throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentContext");
// Get current context
final long ctx = neglGetCurrentContext();
if ( ctx == EGL_NO_CONTEXT )
return null;
// Get current display
final EGLDisplay display = eglGetCurrentDisplay();
// Query context's CONFIG_ID
final IntBuffer attrib_list = APIUtil.getBufferInt();
neglQueryContext(display.getPointer(), ctx, EGL_CONFIG_ID, attrib_list, 0);
final EGLConfig config = getEGLConfig(display, attrib_list);
// Create the context handle
return new EGLContext(display, config, ctx);
}
/**
* Returns true if the specified EGL context is the current context.
* This method is faster than using {@code #eglGetCurrentContext}
* and comparing the two EGLContext objects.
*
* @param context the EGL context
*
* @return true if the EGL context is current
*
* @see #eglGetCurrentContext()
*/
public static boolean eglIsCurrentContext(EGLContext context) {
//LWJGLUtil.log("eglIsCurrentContext");
return neglGetCurrentContext() == context.getPointer();
}
private static native long neglGetCurrentContext();
/**
* Returns the EGL surfaces used for rendering by the current context.
* If there is no context current, null is returned.
*
* @param readdraw the read or draw surface
*
* @return the current surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLSurface eglGetCurrentSurface(int readdraw) throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentSurface");
final long surface = neglGetCurrentSurface(readdraw);
if ( surface == EGL_NO_SURFACE )
return null;
// Get current display
EGLDisplay display = eglGetCurrentDisplay();
// Query context's CONFIG_ID
final IntBuffer attrib_list = APIUtil.getBufferInt();
if ( !neglQuerySurface(display.getPointer(), surface, EGL_CONFIG_ID, attrib_list, 0) )
throwEGLError("Failed to query surface EGL config ID.");
final EGLConfig config = getEGLConfig(display, attrib_list);
// Create the surface handle
return new EGLSurface(display, config, surface);
}
private static native long neglGetCurrentSurface(int readdraw);
/**
* Returns the EGL display associated with the current context.
*
* @return the current display
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLDisplay eglGetCurrentDisplay() throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentDisplay");
return new EGLDisplay(neglGetCurrentDisplay());
}
private static native long neglGetCurrentDisplay();
/**
* Returns the value of the specified EGL context attribute in the value parameter.
*
* @param dpy the EGL display
* @param ctx the EGL context
* @param attribute the context attribute
* @param value the attribute value will be returned here
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static void eglQueryContext(EGLDisplay dpy, EGLContext ctx, int attribute, IntBuffer value) throws LWJGLException {
//LWJGLUtil.log("eglQueryContext");
BufferChecks.checkBuffer(value, 1);
if ( !neglQueryContext(dpy.getPointer(), ctx.getPointer(), attribute, value, value.position()) )
throwEGLError("Failed to query context attribute.");
}
private static native boolean neglQueryContext(long dpy_ptr, long ctx_ptr, int attribute, IntBuffer value, int value_position);
/**
* Prevents native rendering API functions from executing until any
* outstanding client API rendering affecting the same surface is complete.
*
* @return true if the wait was successful, false is an EGL error occurs
*/
public static native boolean eglWaitClient();
/**
* This method does the equivalent of:<br>
* <code>
* EGLenum api = eglQueryAPI();
* eglBindAPI(EGL_OPENGL_ES_API);
* eglWaitClient();
* eglBindAPI(api);
* </code>
*
* @return true if the wait was successful, false if an EGL error occurs
*/
public static native boolean eglWaitGL();
/**
* Prevents a client API command sequence from executing until any outstanding
* native rendering affecting the same surface is complete.
*
* @param engine the native rendering engine
*
* @return true if the wait was successful, false if an EGL error occurs
*/
public static native boolean eglWaitNative(int engine);
/**
* Posts the color buffer to the window.
*
* @param dpy the EGL display
* @param surface the EGL back-buffered window surface
*
* @throws org.lwjgl.LWJGLException if an EGL occurs
* @throws PowerManagementEventException if an EGL power management event occurs
*/
static void eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglSwapBuffers");
if ( !neglSwapBuffers(dpy.getPointer(), surface.getPointer()) ) {
final int error = eglGetError();
if ( error == EGL_CONTEXT_LOST )
throw new PowerManagementEventException();
else
throwEGLError("Failed to swap buffers.", error);
}
}
private static native boolean neglSwapBuffers(long dpy_ptr, long surface_ptr);
//EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
/* --------------------------------
HELPER METHODS
-------------------------------- */
static void checkAttribList(IntBuffer attrib_list) {
if ( attrib_list == null )
return;
//BufferChecks.checkDirect(attrib_list);
if ( attrib_list.remaining() % 2 != 1 )
throw new IllegalArgumentException("Invalid number of values in attribute list.");
if ( attrib_list.get(attrib_list.limit() - 1) != EGL_NONE )
throw new IllegalArgumentException("The attribute list is not terminated with EGL_NONE.");
}
private static EGLConfig getEGLConfig(final EGLDisplay dpy, final IntBuffer attrib_list) throws LWJGLException {
final int configID = attrib_list.get(0);
// -- This fails on the emulator
// Get EGL config used by the context
attrib_list.put(0, EGL_CONFIG_ID).put(1, configID).put(2, EGL_NONE);
final PointerBuffer configs_buffer = APIUtil.getBufferPointer(1);
if ( !neglChooseConfig(dpy.getPointer(), attrib_list, attrib_list.position(), configs_buffer.getBuffer(), 0, 1, attrib_list, attrib_list.position() + 3) )
throwEGLError("Failed to choose EGL config.");
return new EGLConfig(dpy, configs_buffer.get(0));
// -- Emulator workaround
/*
EGLConfig config = null;
final EGLConfig[] configs = eglGetConfigs(dpy, null, attrib_list);
final int config_size = attrib_list.get(0);
for ( int i = 0; i < config_size; i++ ) {
if ( configs[i].getConfigID() == configID ) {
config = configs[i];
break;
}
}
if ( config == null )
throwEGLError("Failed to retrieve EGL config for current context.");
return config;
//*/
}
static void throwEGLError(final String msg) throws LWJGLException {
throwEGLError(msg, eglGetError());
}
static void throwEGLError(String msg, final int error) throws LWJGLException {
if ( error != EGL_SUCCESS )
msg += " EGL error: " + Util.translateEGLErrorString(error);
throw new LWJGLException(msg);
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.PointerWrapperAbstract;
import static org.lwjgl.opengles.EGL.*;
/** EGLConfig wrapper class. */
public final class EGLConfig extends PointerWrapperAbstract {
private final EGLDisplay display;
private final int configID;
EGLConfig(final EGLDisplay display, final long pointer) throws LWJGLException {
super(pointer);
this.display = display;
this.configID = getAttribute(EGL_CONFIG_ID);
}
/**
* Returns the EGL display from which this EGL config was retrieved.
*
* @return the EGL display
*/
public EGLDisplay getDisplay() {
return display;
}
/**
* Returns the EGL_CONFIG_ID attribute of this EGLConfig.
*
* @return the EGL_CONFIG_ID
*/
public int getConfigID() {
return configID;
}
/**
* Returns the value of the specified EGL config attribute.
*
* @param attribute the attribute
*
* @return the attribute value
*/
public int getAttribute(final int attribute) throws LWJGLException {
return eglGetConfigAttrib(display, this, attribute);
}
public boolean equals(final Object obj) {
if ( obj == null || !(obj instanceof EGLConfig) )
return false;
return getPointer() == ((EGLConfig)obj).getPointer();
}
public String toString() {
final StringBuilder sb = new StringBuilder(512);
sb.append("EGLConfig (").append(configID).append(")");
sb.append("\n------------");
try {
sb.append("\nEGL_LEVEL").append(": ").append(getAttribute(EGL_LEVEL));
sb.append("\nEGL_RENDERABLE_TYPE").append(": ").append(Integer.toBinaryString(getAttribute(EGL_RENDERABLE_TYPE)));
sb.append("\nEGL_NATIVE_RENDERABLE").append(": ").append(getAttribute(EGL_NATIVE_RENDERABLE) == EGL_TRUE);
sb.append("\nEGL_SURFACE_TYPE").append(": ").append(Integer.toBinaryString(getAttribute(EGL_SURFACE_TYPE)));
} catch (LWJGLException e) {
}
final PixelFormat.Attrib[] attribEnums = PixelFormat.Attrib.values();
for ( PixelFormat.Attrib attribEnum : attribEnums ) {
if ( attribEnum.isSurfaceAttrib() )
continue;
try {
final int attrib = getAttribute(attribEnum.getEGLAttrib());
sb.append("\nEGL_").append(attribEnum.name()).append(": ").append(attrib);
} catch (LWJGLException e) {
//System.out.println("Failed to retrieve: " + attribEnum.name());
// Ignore, can happen when querying unsupported attributes (e.g. extension ones)
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.PointerWrapperAbstract;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/** EGLContext wrapper class. */
public final class EGLContext extends PointerWrapperAbstract {
private EGLDisplay display;
private final EGLConfig config;
private boolean destroyed;
EGLContext(final EGLDisplay display, final EGLConfig config, final long pointer) {
super(pointer);
if ( !display.isInitialized() )
throw new IllegalStateException("Invalid EGL display specified.");
if ( config.getDisplay() != display )
throw new IllegalStateException("Invalid EGL config specified.");
this.display = display;
this.config = config;
}
public void setDisplay(EGLDisplay display) {
this.display = display;
}
EGLDisplay getDisplay() {
return display;
}
EGLConfig getConfig() {
return config;
}
private void checkDestroyed() {
if ( destroyed )
throw new IllegalStateException("The EGL surface has been destroyed.");
}
public void destroy() throws LWJGLException {
eglDestroyContext(display, this);
destroyed = true;
}
/**
* Returns the value of the specified EGL context attribute.
*
* @param attribute the context attribute
*
* @return the attribute value
*/
int getAttribute(final int attribute) throws LWJGLException {
checkDestroyed();
IntBuffer value = APIUtil.getBufferInt();
eglQueryContext(display, this, attribute, value);
return value.get(0);
}
public void makeCurrent(final EGLSurface surface) throws LWJGLException, PowerManagementEventException {
makeCurrent(surface, surface);
}
public void makeCurrent(final EGLSurface draw, final EGLSurface read) throws LWJGLException, PowerManagementEventException {
eglMakeCurrent(display, draw, read, this);
}
public boolean equals(final Object obj) {
if ( obj == null || !(obj instanceof EGLContext) )
return false;
return getPointer() == ((EGLContext)obj).getPointer();
}
}

View file

@ -0,0 +1,216 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.PointerWrapperAbstract;
import java.nio.IntBuffer;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import static org.lwjgl.opengles.EGL.*;
/** EGLDisplay wrapper class. */
public final class EGLDisplay extends PointerWrapperAbstract {
private int majorVersion;
private int minorVersion;
private Set<String> extensions;
private boolean initialized;
EGLDisplay(final long pointer) throws LWJGLException {
super(pointer);
initialize();
/*final EGLConfig[] configs = eglGetConfigs(this, null, APIUtil.getBufferInt());
for ( EGLConfig config : configs ) {
System.out.println(config);
System.out.println("");
}*/
}
/**
* Returns the major EGL version of this EGL display.
*
* @return the major EGL version
*/
public int getMajorVersion() {
return majorVersion;
}
/**
* Returns the minor EGL version of this EGL display.
*
* @return the minor EGL version
*/
public int getMinorVersion() {
return minorVersion;
}
/**
* Returns true if the specified EGL extension is supported by this EGL display.
*
* @param eglExtension the EGL extension
*
* @return true if the extension is supported
*/
public boolean isExtensionSupported(final String eglExtension) {
checkInitialized();
if ( extensions == null ) {
extensions = new HashSet<String>(16);
final StringTokenizer tokenizer = new StringTokenizer(eglQueryString(this, EGL_EXTENSIONS));
while ( tokenizer.hasMoreTokens() )
extensions.add(tokenizer.nextToken());
}
return extensions.contains(eglExtension);
}
boolean isInitialized() {
return initialized;
}
private void initialize() throws LWJGLException {
IntBuffer version = APIUtil.getBufferInt();
eglInitialize(this, version);
majorVersion = version.get(0);
minorVersion = version.get(1);
initialized = true;
}
private void checkInitialized() {
if ( !initialized )
throw new IllegalStateException("The EGL display needs to be initialized first.");
}
/** Release the resources associated with this EGL display. */
public void terminate() throws LWJGLException {
eglTerminate(this);
majorVersion = 0;
minorVersion = 0;
initialized = false;
}
/**
* Returns a string describing some aspect of the EGL implementation running on the specified display.
*
* @param name the value to query
*
* @return the description
*/
public String query(int name) {
checkInitialized();
return eglQueryString(this, name);
}
int getConfigsNum() throws LWJGLException {
checkInitialized();
return eglGetConfigsNum(this);
}
EGLConfig[] getConfigs(EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
checkInitialized();
return eglGetConfigs(this, configs, num_config);
}
int getConfigNum(IntBuffer attrib_list) throws LWJGLException {
checkInitialized();
return eglChooseConfigNum(this, attrib_list);
}
/** Returns the available EGL configs on this display that satisfy the specified list of attributes. */
public EGLConfig[] chooseConfig(IntBuffer attrib_list, EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
checkInitialized();
return eglChooseConfig(this, attrib_list, configs, num_config);
}
/**
* Creates an on-screen rendering surface on this EGL display.
*
* @param config the EGL config
* @param window the native window handle
* @param attrib_list an attribute list (may be null)
*
* @return the EGL surface
*/
public EGLSurface createWindowSurface(EGLConfig config, int window, IntBuffer attrib_list) throws LWJGLException {
checkInitialized();
if ( config.getDisplay() != this )
throw new IllegalArgumentException("Invalid EGL config specified.");
return eglCreateWindowSurface(this, config, window, attrib_list);
}
EGLSurface createPbufferSurface(EGLConfig config, IntBuffer attrib_list) throws LWJGLException {
checkInitialized();
if ( config.getDisplay() != this )
throw new IllegalArgumentException("Invalid EGL config specified.");
return eglCreatePbufferSurface(this, config, attrib_list);
}
public EGLContext createContext(EGLConfig config, EGLContext shareContext, IntBuffer attrib_list) throws LWJGLException {
checkInitialized();
if ( config.getDisplay() != this )
throw new IllegalStateException("Invalid EGL config specified.");
if ( shareContext != null && shareContext.getDisplay() != this )
throw new IllegalStateException("Invalid shared EGL context specified.");
return eglCreateContext(this, config, shareContext, attrib_list);
}
public void setSwapInterval(final int interval) throws LWJGLException {
eglSwapInterval(this, interval);
}
public boolean equals(final Object obj) {
if ( obj == null || !(obj instanceof EGLDisplay) )
return false;
return getPointer() == ((EGLDisplay)obj).getPointer();
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.PointerWrapperAbstract;
/** EGLImageOES wrapper class. */
public final class EGLImageOES extends PointerWrapperAbstract {
public EGLImageOES(final long pointer) {
super(pointer);
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/** EGL_KHR_fence_sync wrapper class. */
public final class EGLKHRFenceSync {
/**
* Accepted by the &lt;type&gt; parameter of eglCreateSyncKHR, and returned
* in &lt;value&gt; when eglGetSyncAttribKHR is called with &lt;attribute&gt;
* EGL_SYNC_TYPE_KHR:
*/
public static final int EGL_SYNC_FENCE_KHR = 0x30F9;
/** Accepted by the &lt;attribute&gt; parameter of eglGetSyncAttribKHR: */
public static final int EGL_SYNC_TYPE_KHR = 0x30F7,
EGL_SYNC_STATUS_KHR = 0x30F1,
EGL_SYNC_CONDITION_KHR = 0x30F8;
/**
* Returned in &lt;value&gt; when eglGetSyncAttribKHR is called with
* &lt;attribute&gt; EGL_SYNC_STATUS_KHR:
*/
public static final int EGL_SIGNALED_KHR = 0x30F2,
EGL_UNSIGNALED_KHR = 0x30F3;
/**
* Returned in &lt;value&gt; when eglGetSyncAttribKHR is called with
* &lt;attribute&gt; EGL_SYNC_CONDITION_KHR:
*/
public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR = 0x30F0;
/** Accepted in the &lt;flags&gt; parameter of eglClientWaitSyncKHR: */
public static final int EGL_SYNC_FLUSH_COMMANDS_BIT_KHR = 0x0001;
/** Accepted in the &lt;timeout&gt; parameter of eglClientWaitSyncKHR: */
public static final long EGL_FOREVER_KHR = 0xFFFFFFFFFFFFFFFFl;
/** Returned by eglClientWaitSyncKHR: */
public static final int EGL_TIMEOUT_EXPIRED_KHR = 0x30F5,
EGL_CONDITION_SATISFIED_KHR = 0x30F6;
/** Returned by eglCreateSyncKHR in the event of an error: */
public static final long EGL_NO_SYNC_KHR = 0;
static {
initNativeStubs();
}
private EGLKHRFenceSync() {
}
private static native void initNativeStubs();
/**
* Creates a fence sync object for the specified EGL display and returns
* a handle to the new object.
*
* @param dpy the EGL display
* @param type the sync type
* @param attrib_list an attribute list (may be null)
*
* @return the created fence sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, int type, IntBuffer attrib_list) throws LWJGLException {
checkAttribList(attrib_list);
final long pointer = neglCreateSyncKHR(dpy.getPointer(), type, attrib_list, attrib_list == null ? 0 : attrib_list.position());
if ( pointer == EGL_NO_SYNC_KHR )
throwEGLError("Failed to create KHR fence sync object.");
return new EGLSyncKHR(pointer);
}
private static native long neglCreateSyncKHR(long dpy_ptr, int type, IntBuffer attrib_list, int attrib_list_position);
/**
* Destroys an existing sync object.
*
* @param sync the sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) throws LWJGLException {
if ( !neglDestroySyncKHR(dpy.getPointer(), sync.getPointer()) )
throwEGLError("Failed to destroy KHR fence sync object.");
}
private static native boolean neglDestroySyncKHR(long dpy_ptr, long sync_ptr);
/**
* Blocks the calling thread until the specified sync object is
* signaled, or until a specified timeout value expires.
*
* @param sync the sync object
* @param flags the block flags
* @param timeout the block timeout
*
* @return the sync object status
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, int flags, long timeout) throws LWJGLException {
final int status = neglClientWaitSyncKHR(dpy.getPointer(), sync.getPointer(), flags, timeout);
if ( status == EGL_FALSE )
throwEGLError("Failed to block on KHR fence sync object.");
return status;
}
private static native int neglClientWaitSyncKHR(long dpy_ptr, long sync_ptr, int flags, long timeout);
/**
* Returns the value of the sync object attribute.
*
* @param sync the sync object
* @param attribute the attribute to query
*
* @return the attribute value
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, int attribute) throws LWJGLException {
final IntBuffer value = APIUtil.getBufferInt();
if ( !neglGetSyncAttribKHR(dpy.getPointer(), sync.getPointer(), attribute, value, value.position()) )
throwEGLError("Failed to get KHR fence sync object attribute.");
return value.get(0);
}
private static native boolean neglGetSyncAttribKHR(long dpy_ptr, long sync_ptr, int attribute, IntBuffer value, int value_position);
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/** EGL_KHR_reusable_sync wrapper class. */
public final class EGLKHRReusableSync {
/**
* Accepted by the &lt;type&gt; parameter of eglCreateSyncKHR, and returned
* in &lt;value&gt; when eglGetSyncAttribKHR is called with &lt;attribute&gt;
* EGL_SYNC_TYPE_KHR:
*/
public static final int EGL_SYNC_REUSABLE_KHR = 0x30FA;
/** Accepted by the &lt;attribute&gt; parameter of eglGetSyncAttribKHR: */
public static final int EGL_SYNC_TYPE_KHR = 0x30F7,
EGL_SYNC_STATUS_KHR = 0x30F1;
/**
* Returned in &lt;value&gt; when eglGetSyncAttribKHR is called with
* &lt;attribute&gt; EGL_SYNC_STATUS_KHR:
*/
public static final int EGL_SIGNALED_KHR = 0x30F2,
EGL_UNSIGNALED_KHR = 0x30F3;
/** Accepted in the &lt;flags&gt; parameter of eglClientWaitSyncKHR: */
public static final int EGL_SYNC_FLUSH_COMMANDS_BIT_KHR = 0x0001;
/** Accepted in the &lt;timeout&gt; parameter of eglClientWaitSyncKHR: */
public static final long EGL_FOREVER_KHR = 0xFFFFFFFFFFFFFFFFl;
/** Returned by eglClientWaitSyncKHR: */
public static final int EGL_TIMEOUT_EXPIRED_KHR = 0x30F5,
EGL_CONDITION_SATISFIED_KHR = 0x30F6;
/** Returned by eglCreateSyncKHR in the event of an error: */
public static final long EGL_NO_SYNC_KHR = 0;
static {
initNativeStubs();
}
private EGLKHRReusableSync() {
}
private static native void initNativeStubs();
/**
* Creates a fence sync object for the specified EGL display and returns
* a handle to the new object.
*
* @param dpy the EGL display
* @param type the sync type
* @param attrib_list an attribute list (may be null)
*
* @return the created fence sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, int type, IntBuffer attrib_list) throws LWJGLException {
return EGLKHRFenceSync.eglCreateSyncKHR(dpy, type, attrib_list);
}
/**
* Destroys an existing sync object.
*
* @param sync the sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) throws LWJGLException {
EGLKHRFenceSync.eglDestroySyncKHR(dpy, sync);
}
/**
* Blocks the calling thread until the specified sync object is
* signaled, or until a specified timeout value expires.
*
* @param sync the sync object
* @param flags the block flags
* @param timeout the block timeout
*
* @return the sync object status
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, int flags, long timeout) throws LWJGLException {
return EGLKHRFenceSync.eglClientWaitSyncKHR(dpy, sync, flags, timeout);
}
/**
* Signals or unsignals the sync object by changing its status to
* the specified mode.
*
* @param sync the sync object
* @param mode the mode
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, int mode) throws LWJGLException {
if ( !neglSignalSyncKHR(dpy.getPointer(), sync.getPointer(), mode) )
throwEGLError("Failed to signal the KHR fence sync object.");
}
private static native boolean neglSignalSyncKHR(long dpy_ptr, long sync_ptr, int mode);
/**
* Returns the value of the sync object attribute.
*
* @param sync the sync object
* @param attribute the attribute to query
*
* @return the attribute value
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, int attribute) throws LWJGLException {
return EGLKHRFenceSync.eglGetSyncAttribKHR(dpy, sync, attribute);
}
}

View file

@ -0,0 +1,214 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/** EGL_NV_sync wrapper class. */
public final class EGLNVSync {
/**
* Accepted in the &lt;condition&gt; parameter of eglCreateFenceSyncNV, and
* returned in &lt;value&gt; when eglGetSyncAttribNV is called with &lt;attribute&gt;
* EGL_SYNC_CONDITION_NV:
*/
public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV = 0x30E6;
/**
* Accepted as an attribute name in the &lt;attrib_list&gt; parameter of
* eglCreateFenceSyncNV, and by the &lt;attribute&gt; parameter of
* eglGetSyncAttribNV:
*/
public static final int EGL_SYNC_STATUS_NV = 0x30E7;
/**
* Accepted as an attribute value in the &lt;attrib_list&gt; parameter of
* eglCreateFenceSyncNV for the EGL_SYNC_STATUS_NV attribute, by
* the &lt;mode&gt; parameter of eglSignalSyncNV and returned in &lt;value&gt;
* when eglGetSyncAttribNV is called with &lt;attribute&gt;
* EGL_SYNC_STATUS_NV:
*/
public static final int EGL_SIGNALED_NV = 0x30E8,
EGL_UNSIGNALED_NV = 0x30E9;
/** Accepted in the &lt;flags&gt; parameter of eglClientWaitSyncNV: */
public static final int EGL_SYNC_FLUSH_COMMANDS_BIT_NV = 0x0001;
/** Accepted in the &lt;timeout&gt; parameter of eglClientWaitSyncNV: */
public static final long EGL_FOREVER_NV = 0xFFFFFFFFFFFFFFFFL;
/** Returned by eglClientWaitSyncNV: */
public static final int EGL_ALREADY_SIGNALED_NV = 0x30EA,
EGL_TIMEOUT_EXPIRED_NV = 0x30EB,
EGL_CONDITION_SATISFIED_NV = 0x30EC;
/** Accepted in the &lt;attribute&gt; parameter of eglGetSyncAttribNV: */
public static final int EGL_SYNC_TYPE_NV = 0x30ED,
EGL_SYNC_CONDITION_NV = 0x30EE;
/**
* Returned in &lt;value&gt; when eglGetSyncAttribNV is called with
* &lt;attribute&gt; EGL_SYNC_TYPE_NV:
*/
public static final int EGL_SYNC_FENCE_NV = 0x30EF;
/** Returned by eglCreateFenceSyncNV in the event of an error: */
public static final long EGL_NO_SYNC_NV = 0;
static {
initNativeStubs();
}
private EGLNVSync() {
}
private static native void initNativeStubs();
/**
* Creates a fence sync object for the specified EGL display and returns
* a handle to the new object.
*
* @param dpy the EGL display
* @param condition the sync condition
* @param attrib_list an attribute list (may be null)
*
* @return the created fence sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static EGLSyncNV eglCreateFenceSyncNV(EGLDisplay dpy, int condition, IntBuffer attrib_list) throws LWJGLException {
checkAttribList(attrib_list);
final long pointer = neglCreateFenceSyncNV(dpy.getPointer(), condition, attrib_list, attrib_list == null ? 0 : attrib_list.position());
if ( pointer == EGL_NO_SYNC_NV )
throwEGLError("Failed to create NV fence sync object.");
return new EGLSyncNV(pointer);
}
private static native long neglCreateFenceSyncNV(long dpy_ptr, int condition, IntBuffer attrib_list, int attrib_list_position);
/**
* Destroys an existing sync object.
*
* @param sync the sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglDestroySyncNV(EGLSyncNV sync) throws LWJGLException {
if ( !neglDestroySyncNV(sync.getPointer()) )
throwEGLError("Failed to destroy NV fence sync object.");
}
private static native boolean neglDestroySyncNV(long sync_ptr);
/**
* Inserts a fence command into the command stream of the bound API's current
* context and associates it with sync object.
*
* @param sync the sync object
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglFenceNV(EGLSyncNV sync) throws LWJGLException {
if ( !neglFenceNV(sync.getPointer()) )
throwEGLError("Failed to insert NV fence command.");
}
private static native boolean neglFenceNV(long sync_ptr);
/**
* Blocks the calling thread until the specified sync object is
* signaled, or until a specified timeout value expires.
*
* @param sync the sync object
* @param flags the block flags
* @param timeout the block timeout
*
* @return the sync object status
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglClientWaitSyncNV(EGLSyncNV sync, int flags, long timeout) throws LWJGLException {
final int status = neglClientWaitSyncNV(sync.getPointer(), flags, timeout);
if ( status == EGL_FALSE )
throwEGLError("Failed to block on NV fence sync object.");
return status;
}
private static native int neglClientWaitSyncNV(long sync_ptr, int flags, long timeout);
/**
* Signals or unsignals the sync object by changing its status to
* the specified mode.
*
* @param sync the sync object
* @param mode the mode
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static void eglSignalSyncNV(EGLSyncNV sync, int mode) throws LWJGLException {
if ( !neglSignalSyncNV(sync.getPointer(), mode) )
throwEGLError("Failed to signal the NV fence sync object.");
}
private static native boolean neglSignalSyncNV(long sync_ptr, int mode);
/**
* Returns the value of the sync object attribute.
*
* @param sync the sync object
* @param attribute the attribute to query
*
* @return the attribute value
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs.
*/
public static int eglGetSyncAttribNV(EGLSyncNV sync, int attribute) throws LWJGLException {
final IntBuffer value = APIUtil.getBufferInt();
if ( !neglGetSyncAttribNV(sync.getPointer(), attribute, value, 0) )
throwEGLError("Failed to get NV fence sync object attribute.");
return value.get(0);
}
private static native boolean neglGetSyncAttribNV(long sync_ptr, int attribute, IntBuffer value, int value_position);
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.PointerWrapperAbstract;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.EGL.*;
/** EGLSurface wrapper class. */
public final class EGLSurface extends PointerWrapperAbstract {
private final EGLDisplay display;
private final EGLConfig config;
private boolean destroyed;
EGLSurface(final EGLDisplay display, final EGLConfig config, final long pointer) {
super(pointer);
if ( !display.isInitialized() )
throw new IllegalStateException("Invalid EGL display specified.");
this.display = display;
this.config = config;
}
/**
* Returns the EGL display from which this EGL surface was created.
*
* @return the EGL display
*/
public EGLDisplay getDisplay() {
return display;
}
/**
* Returns the EGL config associated with this EGL surface.
*
* @return the EGL config
*/
public EGLConfig getConfig() {
return config;
}
private void checkDestroyed() {
if ( destroyed )
throw new IllegalStateException("The EGL surface has been destroyed.");
}
/** Destroys this EGL surface. */
public void destroy() throws LWJGLException {
eglDestroySurface(display, this);
destroyed = true;
}
void setAttribute(int attribute, int value) throws LWJGLException {
checkDestroyed();
eglSurfaceAttrib(display, this, attribute, value);
}
/**
* Returns the value of the specified EGL surface attribute.
*
* @param attribute the surface attribute
*
* @return the attribute value
*/
public int getAttribute(int attribute) throws LWJGLException {
checkDestroyed();
IntBuffer value = APIUtil.getBufferInt();
eglQuerySurface(display, this, attribute, value);
return value.get(0);
}
public void swapBuffers() throws LWJGLException, PowerManagementEventException {
checkDestroyed();
eglSwapBuffers(display, this);
}
public boolean equals(final Object obj) {
if ( obj == null || !(obj instanceof EGLSurface) )
return false;
return getPointer() == ((EGLSurface)obj).getPointer();
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.PointerWrapperAbstract;
/** EGLSyncKHR wrapper class. */
public class EGLSyncKHR extends PointerWrapperAbstract {
public EGLSyncKHR(final long pointer) {
super(pointer);
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.PointerWrapperAbstract;
/** EGLSyncNV wrapper class. */
public class EGLSyncNV extends PointerWrapperAbstract {
public EGLSyncNV(final long pointer) {
super(pointer);
}
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.opengl.OpenGLException;
import java.nio.Buffer;
import static org.lwjgl.opengles.GLES20.*;
/**
* A class to check buffer boundaries in GL methods. Many GL
* methods read data from the GL into a native Buffer at its current position. If there is unsufficient space in the buffer when
* the call is made then a buffer overflow would otherwise occur and cause unexpected behaviour, a crash, or worse, a security
* risk. Therefore in those methods where GL reads data back into a buffer, we will call a bounds check method from this class
* to ensure that there is sufficient space in the buffer.
* <p/>
* Thrown by the debug build library of the LWJGL if any OpenGL operation causes an error.
*
* @author cix_foo <cix_foo@users.sourceforge.net>
* @version $Revision: 3459 $
* $Id: GLChecks.java 3459 2010-11-29 17:21:05Z spasi $
*/
class GLChecks {
/** Static methods only! */
private GLChecks() {
}
static int getBufferObjectSize(int buffer_enum) {
return glGetBufferParameter(buffer_enum, GLES20.GL_BUFFER_SIZE);
}
/** Helper method to ensure that array buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */
static void ensureArrayVBOdisabled() {
if ( LWJGLUtil.CHECKS && StateTracker.getTracker().arrayBuffer != 0 )
throw new OpenGLException("Cannot use Buffers when Array Buffer Object is enabled");
}
/** Helper method to ensure that array buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */
static void ensureArrayVBOenabled() {
if ( LWJGLUtil.CHECKS && StateTracker.getTracker().arrayBuffer == 0 )
throw new OpenGLException("Cannot use offsets when Array Buffer Object is disabled");
}
/** Helper method to ensure that element array buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */
static void ensureElementVBOdisabled() {
if ( LWJGLUtil.CHECKS && StateTracker.getTracker().elementArrayBuffer != 0 )
throw new OpenGLException("Cannot use Buffers when Element Array Buffer Object is enabled");
}
/** Helper method to ensure that element array buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */
static void ensureElementVBOenabled() {
if ( LWJGLUtil.CHECKS && StateTracker.getTracker().elementArrayBuffer == 0 )
throw new OpenGLException("Cannot use offsets when Element Array Buffer Object is disabled");
}
/**
* Calculate the storage required for an image in elements
*
* @param format The format of the image (example: GL_RGBA)
* @param type The type of the image elements (example: GL_UNSIGNED_BYTE)
* @param width The width of the image
* @param height The height of the image (1 for 1D images)
* @param depth The depth of the image (1 for 2D images)
*
* @return the size, in elements, of the image
*/
static int calculateImageStorage(Buffer buffer, int format, int type, int width, int height, int depth) {
return LWJGLUtil.CHECKS ? calculateImageStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer) : 0;
}
static int calculateTexImage1DStorage(Buffer buffer, int format, int type, int width) {
return LWJGLUtil.CHECKS ? calculateTexImage1DStorage(format, type, width) >> BufferUtils.getElementSizeExponent(buffer) : 0;
}
static int calculateTexImage2DStorage(Buffer buffer, int format, int type, int width, int height) {
return LWJGLUtil.CHECKS ? calculateTexImage2DStorage(format, type, width, height) >> BufferUtils.getElementSizeExponent(buffer) : 0;
}
static int calculateTexImage3DStorage(Buffer buffer, int format, int type, int width, int height, int depth) {
return LWJGLUtil.CHECKS ? calculateTexImage3DStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer) : 0;
}
/**
* Calculate the storage required for an image in bytes.
*
* @param format The format of the image (example: GL_RGBA)
* @param type The type of the image elements (example: GL_UNSIGNED_BYTE)
* @param width The width of the image
* @param height The height of the image (1 for 1D images)
* @param depth The depth of the image (1 for 2D images)
*
* @return the size, in bytes, of the image
*/
private static int calculateImageStorage(int format, int type, int width, int height, int depth) {
return calculateBytesPerPixel(format, type) * width * height * depth;
}
private static int calculateTexImage1DStorage(int format, int type, int width) {
return calculateBytesPerPixel(format, type) * width;
}
private static int calculateTexImage2DStorage(int format, int type, int width, int height) {
return calculateTexImage1DStorage(format, type, width) * height;
}
private static int calculateTexImage3DStorage(int format, int type, int width, int height, int depth) {
return calculateTexImage2DStorage(format, type, width, height) * depth;
}
private static int calculateBytesPerPixel(int format, int type) {
int bpe;
switch ( type ) {
case GL_UNSIGNED_BYTE:
case GL_BYTE:
bpe = 1;
break;
case GL_UNSIGNED_SHORT:
case GL_SHORT:
bpe = 2;
break;
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FLOAT:
bpe = 4;
break;
default:
// TODO: Add more types (like the GL12 types GL_UNSIGNED_INT_8_8_8_8
return 0;
// throw new IllegalArgumentException("Unknown type " + type);
}
int epp;
switch ( format ) {
case GL_LUMINANCE:
case GL_ALPHA:
epp = 1;
break;
case GL_LUMINANCE_ALPHA:
epp = 2;
break;
case GL_RGB:
epp = 3;
break;
case GL_RGBA:
epp = 4;
break;
default:
// TODO: Add more formats. Assuming 4 is too wasteful on buffer sizes where e.g. 1 is enough (like GL_DEPTH_COMPONENT)
return 0;
}
return bpe * epp;
}
}

View file

@ -0,0 +1,310 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.Sys;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import static org.lwjgl.opengles.GLES20.*;
/**
* <p/>
* Manages GL contexts. Before any rendering is done by a LWJGL system, a call should be made to GLContext.useContext() with a
* context. This will ensure that GLContext has an accurate reflection of the current context's capabilities and function
* pointers.
* <p/>
* This class is thread-safe in the sense that multiple threads can safely call all public methods. The class is also
* thread-aware in the sense that it tracks a per-thread current context (including capabilities and function pointers).
* That way, multiple threads can have multiple contexts current and render to them concurrently.
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3279 $
* $Id: GLContext.java 3279 2010-03-11 21:06:49Z spasi $
*/
public final class GLContext {
/** Maps threads to their current context's ContextCapabilities, if any */
private static final ThreadLocal<ContextCapabilities> current_capabilities = new ThreadLocal<ContextCapabilities>();
/**
* The getCapabilities() method is a potential hot spot in any LWJGL application, since
* it is needed for context capability discovery (e.g. is OpenGL 2.0 supported?), and
* for the function pointers of gl functions. However, the 'current_capabilities' ThreadLocal
* is (relatively) expensive to look up, and since most OpenGL applications use are single threaded
* rendering, the following two is an optimization for this case.
* <p/>
* ThreadLocals can be thought of as a mapping between threads and values, so the idea
* is to use a lock-less cache of mappings between threads and the current ContextCapabilities. The cache
* could be any size, but in our case, we want a single sized cache for optimal performance
* in the single threaded case.
* <p/>
* 'fast_path_cache' is the most recent ContextCapabilities (potentially null) and its owner. By
* recent I mean the last thread setting the value in setCapabilities(). When getCapabilities()
* is called, a check to see if the current is the owner of the ContextCapabilities instance in
* fast_path_cache. If so, the instance is returned, if not, some thread has since taken ownership
* of the cache entry and the slower current_capabilities ThreadLocal is queried instead.
* <p/>
* No locks are needed in get/setCapabilities, because even though fast_path_cache can be accessed
* from multiple threads at once, we are guaranteed by the JVM spec that its value is always valid.
* Furthermore, if the ownership test in getCapabilities() succeeds, the cache entry can only contain
* the correct ContextCapabilites (that is, the one from getThreadLocalCapabilites()),
* since no other thread can set the owner to anyone else than itself.
*/
private static CapabilitiesCacheEntry fast_path_cache = new CapabilitiesCacheEntry();
/**
* Simple lock-free cache of CapabilitesEntryCache to avoid allocating more than one
* cache entry per thread
*/
private static final ThreadLocal<CapabilitiesCacheEntry> thread_cache_entries = new ThreadLocal<CapabilitiesCacheEntry>();
/**
* The weak mapping from context Object instances to ContextCapabilities. Used
* to avoid recreating a ContextCapabilities every time a context is made current.
*/
private static final Map<Object, ContextCapabilities> capability_cache = new WeakHashMap<Object, ContextCapabilities>();
/** Reference count of the native opengl implementation library */
private static int gl_ref_count;
private static boolean did_auto_load;
static {
Sys.initialize();
}
/**
* Get the current capabilities instance. It contains the flags used
* to test for support of a particular extension.
*
* @return The current capabilities instance.
*/
public static ContextCapabilities getCapabilities() {
CapabilitiesCacheEntry recent_cache_entry = fast_path_cache;
// Check owner of cache entry
if ( recent_cache_entry.owner == Thread.currentThread() ) {
/* The owner ship test succeeded, so the cache must contain the current ContextCapabilities instance
* assert recent_cache_entry.capabilities == getThreadLocalCapabilities();
*/
return recent_cache_entry.capabilities;
} else // Some other thread has written to the cache since, and we fall back to the slower path
return getThreadLocalCapabilities();
}
private static ContextCapabilities getThreadLocalCapabilities() {
return current_capabilities.get();
}
/**
* Set the current capabilities instance. It contains the flags used
* to test for support of a particular extension.
*
* @return The current capabilities instance.
*/
static void setCapabilities(ContextCapabilities capabilities) {
current_capabilities.set(capabilities);
CapabilitiesCacheEntry thread_cache_entry = thread_cache_entries.get();
if ( thread_cache_entry == null ) {
thread_cache_entry = new CapabilitiesCacheEntry();
thread_cache_entries.set(thread_cache_entry);
}
thread_cache_entry.owner = Thread.currentThread();
thread_cache_entry.capabilities = capabilities;
fast_path_cache = thread_cache_entry;
}
/**
* Determine which extensions are available and returns the context profile mask. Helper method to ContextCapabilities.
*
* @param supported_extensions the Set to fill with the available extension names
*
* @return the context profile mask, will be 0 for any version < 3.2
*/
static void getSupportedExtensions(final Set<String> supported_extensions) {
// Detect OpenGL version first
final String version = glGetString(GL_VERSION);
if ( version == null )
throw new IllegalStateException("glGetString(GL_VERSION) returned null - possibly caused by missing current context.");
final String VERSION_PREFIX = "OpenGL ES ";
final StringTokenizer version_tokenizer = new StringTokenizer(version.substring(VERSION_PREFIX.length()), ". ");
int majorVersion = 0;
int minorVersion = 0;
try {
majorVersion = Integer.parseInt(version_tokenizer.nextToken());
minorVersion = Integer.parseInt(version_tokenizer.nextToken());
} catch (NumberFormatException e) {
LWJGLUtil.log("The major and/or minor OpenGL version is malformed: " + e.getMessage());
}
// ----------------------[ 2.X ]----------------------
if ( 2 <= majorVersion )
supported_extensions.add("OpenGLES20");
// Parse EXTENSIONS string
final String extensions_string = glGetString(GL_EXTENSIONS);
if ( extensions_string == null )
throw new IllegalStateException("glGetString(GL_EXTENSIONS) returned null - is there a context current?");
final StringTokenizer tokenizer = new StringTokenizer(extensions_string);
while ( tokenizer.hasMoreTokens() )
supported_extensions.add(tokenizer.nextToken());
}
/**
* Helper method to ContextCapabilities. It will try to initialize the native stubs,
* and remove the given extension name from the extension set if the initialization fails.
*/
static void initNativeStubs(final Class extension_class, Set<String> supported_extensions, String ext_name) {
//resetNativeStubs(extension_class);
if ( supported_extensions.contains(ext_name) ) {
try {
doInitNativeStubs(extension_class);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to initialize extension " + extension_class + " - exception: " + e);
supported_extensions.remove(ext_name);
}
}
}
static void doInitNativeStubs(final Class<?> extension_class) throws LWJGLException {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
Method init_stubs_method = extension_class.getDeclaredMethod("initNativeStubs");
init_stubs_method.invoke(null);
return null;
}
});
} catch (PrivilegedActionException e) {
final Throwable c = e.getCause();
if ( c instanceof InvocationTargetException )
throw new LWJGLException(c.getCause());
else
throw new LWJGLException(c);
}
}
/**
* Makes a GL context the current LWJGL context by loading GL function pointers. The context must be current before a call to
* this method! Instead it simply ensures that the current context is reflected accurately by GLContext's extension caps and
* function pointers. Use useContext(null) when no context is active. <p>If the context is the same as last time, then this is
* a no-op. <p>If the context has not been encountered before it will be fully initialized from scratch. Otherwise a cached set
* of caps and function pointers will be used. <p>The reference to the context is held in a weak reference; therefore if no
* strong reference exists to the GL context it will automatically be forgotten by the VM at an indeterminate point in the
* future, freeing up a little RAM.
*
* @param context The context object, which uniquely identifies a GL context. If context is null, the native stubs are
* unloaded.
*
* @throws org.lwjgl.LWJGLException if context non-null, and the gl library can't be loaded or the basic GL11 functions can't be loaded
*/
public static synchronized void useContext(Object context) throws LWJGLException {
if ( context == null ) {
// Moved this to the shutdown hook
ContextCapabilities.unloadAllStubs();
setCapabilities(null);
if ( did_auto_load )
unloadOpenGLLibrary();
return;
}
if ( gl_ref_count == 0 ) {
loadOpenGLLibrary();
did_auto_load = true;
}
try {
ContextCapabilities capabilities = capability_cache.get(context);
if ( capabilities == null ) {
/*
* The capabilities object registers itself as current. This behaviour is caused
* by a chicken-and-egg situation where the constructor needs to call GL functions
* as part of its capability discovery, but GL functions cannot be called before
* a capabilities object has been set.
*/
new ContextCapabilities();
capability_cache.put(context, getCapabilities());
} else
setCapabilities(capabilities);
} catch (LWJGLException e) {
if ( did_auto_load )
unloadOpenGLLibrary();
throw e;
}
}
/** If the OpenGL reference count is 0, the library is loaded. The reference count is then incremented. */
public static synchronized void loadOpenGLLibrary() throws LWJGLException {
if ( gl_ref_count == 0 )
nLoadOpenGLLibrary();
gl_ref_count++;
}
private static native void nLoadOpenGLLibrary() throws LWJGLException;
/** The OpenGL library reference count is decremented, and if it reaches 0, the library is unloaded. */
public static synchronized void unloadOpenGLLibrary() {
gl_ref_count--;
/*
* Unload the native OpenGL library unless we're on linux, since
* some drivers (NVIDIA proprietary) crash on exit when unloading the library.
*/
if ( gl_ref_count == 0 && LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_LINUX )
nUnloadOpenGLLibrary();
}
private static native void nUnloadOpenGLLibrary();
/** Native method to clear native stub bindings */
static native void resetNativeStubs(Class clazz);
private static final class CapabilitiesCacheEntry {
Thread owner;
ContextCapabilities capabilities;
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import java.nio.ByteBuffer;
/**
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3418 $
* $Id: PeerInfo.java 3418 2010-09-28 21:11:35Z spasi $
*/
abstract class PeerInfo {
private final ByteBuffer handle;
private Thread locking_thread; // Thread that has locked this PeerInfo
private int lock_count;
protected PeerInfo(ByteBuffer handle) {
this.handle = handle;
}
private void lockAndInitHandle() throws LWJGLException {
doLockAndInitHandle();
}
public final synchronized void unlock() throws LWJGLException {
if (lock_count <= 0)
throw new IllegalStateException("PeerInfo not locked!");
if (Thread.currentThread() != locking_thread)
throw new IllegalStateException("PeerInfo already locked by " + locking_thread);
lock_count--;
if (lock_count == 0) {
doUnlock();
locking_thread = null;
notify();
}
}
protected abstract void doLockAndInitHandle() throws LWJGLException;
protected abstract void doUnlock() throws LWJGLException;
public final synchronized ByteBuffer lockAndGetHandle() throws LWJGLException {
Thread this_thread = Thread.currentThread();
while (locking_thread != null && locking_thread != this_thread) {
try {
wait();
} catch (InterruptedException e) {
LWJGLUtil.log("Interrupted while waiting for PeerInfo lock: " + e);
}
}
if (lock_count == 0) {
locking_thread = this_thread;
doLockAndInitHandle();
}
lock_count++;
return getHandle();
}
final ByteBuffer getHandle() {
return handle;
}
public void destroy() {
}
}

View file

@ -0,0 +1,767 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.opengl.PixelFormatLWJGL;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.lwjgl.opengles.EGL.*;
import static org.lwjgl.opengles.NVCoverageSample.*;
import static org.lwjgl.opengles.NVDepthNonlinear.*;
import static org.lwjgl.opengles.PixelFormat.Attrib.*;
/**
* This class describes the configuration settings for an EGL surface. Instances
* of this class are used as arguments to Display.create(). The attributes specified
* in this class will be used to get EGLConfigs from an EGLDisplay. PixelFormat
* is not the best name for this class, but it matches the corresponding class
* in the official desktop LWJGL.
* <p/>
* Instances of this class are immutable. An example of the expected way to set
* the PixelFormat property values is the following:
* <code>PixelFormat pf = new PixelFormat().withDepth(24).withSamples(4);</code>
* <p/>
* Attributes that correspond to EGL extensions will be silently ignored if those
* extensions are not supported by the EGLDisplay.
*/
public final class PixelFormat implements PixelFormatLWJGL {
public static enum Attrib {
// CORE ATTRIBUTES
RED_SIZE(EGL_RED_SIZE, 0),
GREEN_SIZE(EGL_GREEN_SIZE, 0),
BLUE_SIZE(EGL_BLUE_SIZE, 0),
ALPHA_SIZE(EGL_ALPHA_SIZE, 0),
LUMINANCE_SIZE(EGL_LUMINANCE_SIZE, 0),
DEPTH_SIZE(EGL_DEPTH_SIZE, 0),
STENCIL_SIZE(EGL_STENCIL_SIZE, 0),
MIN_SWAP_INTERVAL(EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE),
MAX_SWAP_INTERVAL(EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE),
SAMPLES(EGL_SAMPLES, 0),
SAMPLE_BUFFERS(EGL_SAMPLE_BUFFERS, 0),
TRANSPARENT_TYPE(EGL_TRANSPARENT_TYPE, EGL_NONE),
TRANSPARENT_RED_VALUE(EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE),
TRANSPARENT_GREEN_VALUE(EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE),
TRANSPARENT_BLUE_VALUE(EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE),
// SURFACE ATTRIBUTES
MULTISAMPLE_RESOLVE(EGL_MULTISAMPLE_RESOLVE, EGL_MULTISAMPLE_RESOLVE_DEFAULT, true),
SWAP_BEHAVIOR(EGL_SWAP_BEHAVIOR, EGL_DONT_CARE, true),
// EXTENSION ATTRIBUTES
COVERAGE_SAMPLES_NV(EGL_COVERAGE_SAMPLES_NV, 0),
COVERAGE_BUFFERS_NV(EGL_COVERAGE_BUFFERS_NV, 0),
DEPTH_ENCODING_NONLINEAR_NV(EGL_DEPTH_ENCODING_NONLINEAR_NV, EGL_DONT_CARE);
private final int eglAttrib;
private final int defaultValue;
private final boolean surfaceAttrib;
Attrib(final int eglAttrib, final int defaultValue) {
this(eglAttrib, defaultValue, false);
}
Attrib(final int eglAttrib, final int defaultValue, final boolean surfaceAttrib) {
this.eglAttrib = eglAttrib;
this.defaultValue = defaultValue;
this.surfaceAttrib = surfaceAttrib;
}
/**
* Returns the EGL token that corresponds to this attribute.
*
* @return the EGL attribute token
*/
public int getEGLAttrib() {
return eglAttrib;
}
/**
* Returns the default value of this attribute. Attributes
* with default values will be ignored when choosing the EGLConfig.
*
* @return the default value
*/
public int getDefaultValue() {
return defaultValue;
}
public boolean isSurfaceAttrib() {
return surfaceAttrib;
}
}
private final Map<Attrib, Integer> config = new HashMap<Attrib, Integer>(16);
/**
* Creates a new PixelFormat with rgbSize = 8, alphaSize = 8 and depthSize = 16.
*
* @see #PixelFormat(int, int, int, int, int, int)
*/
public PixelFormat() {
this(8, 16, 0);
}
/**
* Creates a new PixelFormat with rgbSize = 8 and the specified
* alphaSize, depthSize and stencilSize.
*
* @param alphaSize the EGL_ALPHA_SIZE value
* @param depthSize the EGL_DEPTH_SIZE value
* @param stencilSize the EGL_STENCIL_SIZE value
*
* @see #PixelFormat(int, int, int, int, int, int)
*/
public PixelFormat(int alphaSize, int depthSize, int stencilSize) {
this(alphaSize, depthSize, stencilSize, 0);
}
/**
* Creates a new PixelFormat with rgbSize = 8 and the specified
* alphaSize, depthSize, stencilSize and samples.
*
* @param alphaSize the EGL_ALPHA_SIZE value
* @param depthSize the EGL_DEPTH_SIZE value
* @param stencilSize the EGL_STENCIL_SIZE value
* @param samples the EGL_SAMPLE_SIZE value
*
* @see #PixelFormat(int, int, int, int, int, int)
*/
public PixelFormat(int alphaSize, int depthSize, int stencilSize, int samples) {
this(8, alphaSize, 0, depthSize, stencilSize, samples);
}
/**
* Creates a new PixelFormat with the specified RGB sizes, EGL_ALPHA_SIZE,
* EGL_LUMINANCE_SIZE, EGL_DEPTH_SIZE, EGL_STENCIL_SIZE, EGL_SAMPLES.
* All values must be greater than or equal to 0. rgbSize and luminanceSize
* cannot both be greater than 0. depthSize greater than 24 and stencilSize
* greater than 8 are not recommended.
* The corresponding EGL_SAMPLE_BUFFERS value will become 0 if samples is 0,
* or 1 if samples is greater than 0.
*
* @param rgbSize the RGB sizes
* @param alphaSize the EGL_ALPHA_SIZE value
* @param luminanceSize the EGL_LUMINANCE_SIZE value
* @param depthSize the EGL_DEPTH_SIZE value
* @param stencilSize the EGL_STENCIL_SIZE value
* @param samples the EGL_SAMPLE_SIZE value
*/
public PixelFormat(int rgbSize, int alphaSize, int luminanceSize, int depthSize, int stencilSize, int samples) {
if ( rgbSize < 0 )
throw new IllegalArgumentException("Invalid RGB size specified: " + rgbSize);
if ( alphaSize < 0 )
throw new IllegalArgumentException("Invalid EGL_ALPHA_SIZE specified: " + alphaSize);
if ( luminanceSize < 0 || (0 < luminanceSize && 0 < rgbSize) )
throw new IllegalArgumentException("Invalid EGL_LUMINANCE_SIZE specified: " + luminanceSize);
if ( depthSize < 0 )
throw new IllegalArgumentException("Invalid EGL_DEPTH_SIZE specified: " + depthSize);
if ( stencilSize < 0 )
throw new IllegalArgumentException("Invalid EGL_STENCIL_SIZE specified: " + stencilSize);
if ( samples < 0 )
throw new IllegalArgumentException("Invalid EGL_SAMPLES specified: " + samples);
if ( 0 < rgbSize ) {
setAttrib(RED_SIZE, rgbSize);
setAttrib(GREEN_SIZE, rgbSize);
setAttrib(BLUE_SIZE, rgbSize);
}
setAttrib(ALPHA_SIZE, alphaSize);
setAttrib(LUMINANCE_SIZE, luminanceSize);
setAttrib(DEPTH_SIZE, depthSize);
setAttrib(STENCIL_SIZE, stencilSize);
setAttrib(SAMPLES, samples);
setAttrib(SAMPLE_BUFFERS, samples == 0 ? 0 : 1);
}
/**
* Creates a new PixelFormat that is a copy of the specified PixelFormat.
*
* @param pf the source PixelFormat
*/
private PixelFormat(final PixelFormat pf) {
config.clear();
config.putAll(pf.config);
}
/**
* Sets the value of an attribute to the current configuration.
* If the value matches the default attribute value, the
* attribute will be removed from the configuration.
*
* @param attrib the attribute
* @param value the new value
*/
private void setAttrib(final Attrib attrib, final int value) {
if ( attrib.defaultValue == value )
config.remove(attrib);
else
config.put(attrib, value);
}
/**
* Returns an IntBuffer that can be used to get/choose EGLConfigs.
* The contents of the IntBuffer will be the sum of the source
* LWJGL attributes and the user-defined attributes from this
* PixelFormat's configuration.
* <p/>
* The source LWJGL attributes should not contain the EGL_SURFACE_TYPE
* attirube, or any attributes that are handled by PixelFormat.
* <p/>
* Attributes that correspond to EGL extensions will be checked
* against the extensions supported in the specified EGLDisplay.
* Attributes that correspond to unsupported extensions will not
* be included in the final EGLConfig query.
*
* @param display the EGL display from which the EGLConfig is going to be retrieved
* @param lwjglAttribs the LWJGL attributes
*
* @return the IntBuffer
*/
public IntBuffer getAttribBuffer(final EGLDisplay display, int surfaceType, final int[] lwjglAttribs) {
// Create a copy of the configuration attributes
Set<Attrib> keys = new HashSet<Attrib>(config.keySet());
// Handle surface type bits
if ( keys.contains(MULTISAMPLE_RESOLVE) ) {
if ( display.getMajorVersion() == 1 && display.getMinorVersion() < 4 )
keys.remove(MULTISAMPLE_RESOLVE);
else if ( getAttrib(MULTISAMPLE_RESOLVE) == EGL_MULTISAMPLE_RESOLVE_BOX )
surfaceType |= EGL_MULTISAMPLE_RESOLVE_BOX_BIT;
}
if ( keys.contains(SWAP_BEHAVIOR) ) {
if ( display.getMajorVersion() == 1 && display.getMinorVersion() < 4 )
keys.remove(SWAP_BEHAVIOR);
else if ( getAttrib(SWAP_BEHAVIOR) == EGL_BUFFER_PRESERVED )
surfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
}
// Check NV_coverage_sample
if ( keys.contains(COVERAGE_BUFFERS_NV) && !display.isExtensionSupported("EGL_NV_coverage_sample") ) {
keys.remove(COVERAGE_BUFFERS_NV);
keys.remove(COVERAGE_SAMPLES_NV);
}
// Check NV_depth_nonlinear
if ( keys.contains(DEPTH_ENCODING_NONLINEAR_NV) && !display.isExtensionSupported("EGL_NV_depth_nonlinear") )
keys.remove(DEPTH_ENCODING_NONLINEAR_NV);
// Create IntBuffer and insert the attributes
final IntBuffer attribs = BufferUtils.createIntBuffer(
2 // SURFACE_TYPE
+ lwjglAttribs.length // Source LWJGL attributes
+ (keys.size() * 2) // PixelFormat attributes
+ 1 // Termination
);
attribs.put(EGL_SURFACE_TYPE).put(surfaceType);
attribs.put(lwjglAttribs);
for ( Attrib key : keys ) {
if ( !key.isSurfaceAttrib() )
attribs.put(key.eglAttrib).put(config.get(key));
}
// Finish the attribute list
attribs.put(EGL_NONE);
attribs.flip();
return attribs;
}
/**
* Returns true if the requested attribute matches the attribute in the specified EGL config.
*
* @param attrib the requested attribute
* @param config the EGL config
*
* @return true if the two attributes match
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
private boolean matches(final Attrib attrib, final EGLConfig config) throws LWJGLException {
return getAttrib(attrib) == config.getAttribute(attrib.getEGLAttrib());
}
/**
* Returns true if the requested attribute matches the attribute in the specified EGL config.
* If the requested attribute is equal to 1, then it will match with any EGL config attribute
* that is greater than 0.
*
* @param attrib the requested attribute
* @param config the EGL config
*
* @return true if the two attributes match
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
private boolean matchesNonZero(final Attrib attrib, final EGLConfig config) throws LWJGLException {
final int reqValue = getAttrib(attrib);
final int cfgValue = config.getAttribute(attrib.getEGLAttrib());
return reqValue == cfgValue || (reqValue == 1 && cfgValue > 0);
}
/**
* Returns the EGL config from the specified array that best matches this PixelFormat.
*
* @param configs the EGL configs
*
* @return the best match
*/
public EGLConfig getBestMatch(final EGLConfig[] configs) throws LWJGLException {
if ( configs == null || configs.length == 0 )
throw new IllegalArgumentException("No EGLConfigs specified.");
if ( configs.length == 1 )
return configs[0];
/*System.out.println("\nASKED FOR:");
for ( Attrib attrib : config.keySet() ) {
System.out.println("EGL_" + attrib.name() + ": " + getAttrib(attrib));
}
for ( EGLConfig config : configs ) {
if ( config == null )
continue;
System.out.println("\n----");
System.out.println(config);
}*/
for ( EGLConfig config : configs ) {
if ( config == null )
continue;
if ( !(matches(ALPHA_SIZE, config) && matchesNonZero(DEPTH_SIZE, config) && matchesNonZero(STENCIL_SIZE, config)) )
continue;
final int luminance = getAttrib(LUMINANCE_SIZE);
if ( 0 < luminance && !matches(LUMINANCE_SIZE, config) )
continue;
if ( luminance == 0 && !(matches(RED_SIZE, config) && matches(GREEN_SIZE, config) && matches(BLUE_SIZE, config)) )
continue;
if ( !(matches(SAMPLE_BUFFERS, config) && matches(SAMPLES, config)) )
continue;
// TODO: Add more? NV's Tegra SDK checks a hardcoded 5 value for COVERAGE_SAMPLES_NV (nv_main.c, line: 1823)
return config;
}
// No match found, use the one recommended by the EGL implementation.
LWJGLUtil.log("Could not find an exact EGLConfig match for the PixelFormat requested, using first returned.");
return configs[0];
}
/**
* Applies this PixelFormat's surface attributes to the specified EGL surface.
*
* @param surface the EGL surface
*/
public void setSurfaceAttribs(final EGLSurface surface) throws LWJGLException {
setSurfaceAttrib(surface, SWAP_BEHAVIOR);
setSurfaceAttrib(surface, MULTISAMPLE_RESOLVE);
}
private void setSurfaceAttrib(final EGLSurface surface, final Attrib attrib) throws LWJGLException {
final int value = getAttrib(attrib);
if ( value != attrib.getDefaultValue() )
surface.setAttribute(attrib.getEGLAttrib(), value);
}
/**
* Returns the value of the specified attribute.
*
* @param attrib the attribute to retrieve
*
* @return the attribute's value
*/
public int getAttrib(final Attrib attrib) {
final Integer value = config.get(attrib);
if ( value == null )
return attrib.defaultValue;
return value;
}
/* -----------------------------------------
CORE ATTRIBUTES
----------------------------------------- */
/**
* Returns a new PixelFormat with the specified RGB sizes.
*
* @param rgb the new EGL_RED_SIZE, EGL_GREEN_SIZE and EGL_BLUE_SIZE
*
* @return the new PixelFormat
*
* @see #withRGBSize(int, int, int)
*/
public PixelFormat withRGBSize(final int rgb) {
return withRGBSize(rgb, rgb, rgb);
}
/**
* Returns a new PixelFormat with the specified EGL_RED_SIZE, EGL_GREEN_SIZE and EGL_BLUE_SIZE.
* All 3 values must be greater than or equal to 0. If any of the 3 values is greater than 0,
* the luminanceSize will be set to 0.
*
* @param r the new EGL_RED_SIZE
* @param g the new EGL_GREEN_SIZE
* @param b the new EGL_BLUE_SIZE
*
* @return the new PixelFormat
*/
public PixelFormat withRGBSize(final int r, final int g, final int b) {
if ( r < 0 || g < 0 || b < 0 )
throw new IllegalArgumentException("Invalid RGB sizes specified: " + r + ", " + g + ", " + b);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(RED_SIZE, r);
pf.setAttrib(GREEN_SIZE, g);
pf.setAttrib(BLUE_SIZE, b);
if ( 0 < r || 0 < g || 0 < b )
pf.setAttrib(LUMINANCE_SIZE, 0);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_ALPHA_SIZE.
* The alphaSize value must be greater than or equal to 0.
*
* @param alphaSize the new EGL_ALPHA_SIZE
*
* @return the new PixelFormat
*/
public PixelFormat withAlphaSize(final int alphaSize) {
if ( alphaSize < 0 )
throw new IllegalArgumentException("Invalid EGL_ALPHA_SIZE specified: " + alphaSize);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(ALPHA_SIZE, alphaSize);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_LUMINANCE_SIZE.
* The luminanceSize value must be greater than or equal to 0. If
* luminanceSize is greater than 0, the RGB sizes will be set to 0.
*
* @param luminanceSize the new EGL_LUMINANCE_SIZE
*
* @return the new PixelFormat
*/
public PixelFormat withLuminanceSize(final int luminanceSize) {
if ( luminanceSize < 0 )
throw new IllegalArgumentException("Invalid EGL_LUMINANCE_SIZE specified: " + luminanceSize);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(LUMINANCE_SIZE, luminanceSize);
if ( 0 < luminanceSize ) {
pf.setAttrib(RED_SIZE, 0);
pf.setAttrib(GREEN_SIZE, 0);
pf.setAttrib(BLUE_SIZE, 0);
}
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_DEPTH_SIZE.
* The depthSize value must be greater than or equal to 0.
* Values greater than 24 are not recommended.
*
* @param depthSize the new EGL_DEPTH_SIZE
*
* @return the new PixelFormat
*/
public PixelFormat withDepthSize(final int depthSize) {
if ( depthSize < 0 )
throw new IllegalArgumentException("Invalid EGL_DEPTH_SIZE specified: " + depthSize);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(DEPTH_SIZE, depthSize);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_STENCIL_SIZE.
* The stencilSize value must be greater than or equal to 0.
* Values greater than 8 are not recommended.
*
* @param stencilSize the new EGL_STENCIL_SIZE
*
* @return the new PixelFormat
*/
public PixelFormat withStencilSize(final int stencilSize) {
if ( stencilSize < 0 )
throw new IllegalArgumentException("Invalid EGL_STENCIL_SIZE specified: " + stencilSize);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(STENCIL_SIZE, stencilSize);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_MIN_SWAP_INTERVAL.
* The minSwapInterval value must be between 0 and this PixelFormat's EGL_MAX_SWAP_INTERVAL.
*
* @param minSwapInterval the new EGL_MIN_SWAP_INTERVAL value
*
* @return the new PixelFormat
*/
public PixelFormat withMinSwapInterval(final int minSwapInterval) {
final int maxSwapInterval = getAttrib(MAX_SWAP_INTERVAL);
if ( minSwapInterval != EGL_DONT_CARE && (minSwapInterval < 0 || (maxSwapInterval != EGL_DONT_CARE && maxSwapInterval < minSwapInterval)) )
throw new IllegalArgumentException("Invalid EGL_MIN_SWAP_INTERVAL specified: " + minSwapInterval);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(MIN_SWAP_INTERVAL, minSwapInterval);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_MAX_SWAP_INTERVAL.
* The maxSwapInterval value must be greater than or equal to this PixelFormat's EGL_MIN_SWAP_INTERVAL.
*
* @param maxSwapInterval the new EGL_MAX_SWAP_INTERVAL value
*
* @return the new PixelFormat
*/
public PixelFormat withMaxSwapInterval(final int maxSwapInterval) {
if ( maxSwapInterval < getAttrib(MIN_SWAP_INTERVAL) )
throw new IllegalArgumentException("Invalid EGL_MAX_SWAP_INTERVAL specified: " + maxSwapInterval);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(MAX_SWAP_INTERVAL, maxSwapInterval);
return pf;
}
/**
* Returns a new PixelFormat with the specified number of EGL_SAMPLES.
* The samples value must be either 0 or greater than or equal to 2. The related
* EGL_SAMPLE_BUFFERS value will become 0 if samples is 0, or 1 if samples
* is greater than or equal to 2.
*
* @param samples the new EGL_SAMPLES value
*
* @return the new PixelFormat
*/
public PixelFormat withSamples(final int samples) {
if ( samples != 0 && samples < 2 )
throw new IllegalArgumentException("Invalid number of EGL_SAMPLES specified: " + samples);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(SAMPLES, samples);
pf.setAttrib(SAMPLE_BUFFERS, samples == 0 ? 0 : 1);
return pf;
}
private static int maxValue(final int bits) {
return (2 << bits) - 1;
}
/**
* Returns a new PixelFormat with the specified EGL_TRANSPARENT_TYPE and
* the specified transparent RGB values. The transparentType must be
* either EGL_NONE or EGL_TRANSPARENT_RGB. When it is EGL_NONE, the RGB
* values are set to zero and ignored. When it is EGL_TRANSPARENT_RGB,
* the RGB values must be between 0 and 2^rgbSize - 1.
*
* @param transparentType the new EGL_TRANSPARENT_TYPE value
* @param r the new EGL_TRANSPARENT_RED_VALUE
* @param g the new EGL_TRANSPARENT_GREEN_VALUE
* @param b the new EGL_TRANSPARENT_BLUE_VALUE
*
* @return the new PixelFormat
*/
public PixelFormat withTransparentType(final int transparentType, int r, int g, int b) {
if ( transparentType == EGL_TRANSPARENT_RGB ) {
final int redSize = getAttrib(RED_SIZE);
final int greenSize = getAttrib(GREEN_SIZE);
final int blueSize = getAttrib(BLUE_SIZE);
if ( r < 0 || (0 < redSize && maxValue(redSize) < r) )
throw new IllegalArgumentException("Invalid EGL_TRANSPARENT_RED_VALUE specified: " + r);
if ( r < 0 || (0 < greenSize && maxValue(greenSize) < g) )
throw new IllegalArgumentException("Invalid EGL_TRANSPARENT_GREEN_VALUE specified: " + g);
if ( r < 0 || (0 < blueSize && maxValue(blueSize) < b) )
throw new IllegalArgumentException("Invalid EGL_TRANSPARENT_BLUE_VALUE specified: " + b);
} else if ( transparentType != EGL_NONE )
throw new IllegalArgumentException("Invalid EGL_TRANSPARENT_TYPE specified: " + transparentType);
else
r = g = b = EGL_DONT_CARE;
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(TRANSPARENT_TYPE, transparentType);
pf.setAttrib(TRANSPARENT_RED_VALUE, r);
pf.setAttrib(TRANSPARENT_GREEN_VALUE, g);
pf.setAttrib(TRANSPARENT_BLUE_VALUE, b);
return pf;
}
/* -----------------------------------------
SURFACE ATTRIBUTES
----------------------------------------- */
/**
* Returns a new PixelFormat with the specified EGL_MULTISAMPLE_RESOLVE value.
* Valid values for multisampleResolve are EGL_MULTISAMPLE_RESOLVE_DEFAULT
* and EGL_MULTISAMPLE_RESOLVE_BOX.
* <p/>
* An IllegalStateException will be thrown if EGL_SAMPLES has not been previously defined
* to be greater than or equal to 2.
*
* @param multisampleResolve the new EGL_MULTISAMPLE_RESOLVE value
*
* @return the new PixelFormat
*/
public PixelFormat withMultisampleResolve(final int multisampleResolve) {
if ( multisampleResolve != EGL_MULTISAMPLE_RESOLVE_DEFAULT && multisampleResolve != EGL_MULTISAMPLE_RESOLVE_BOX )
throw new IllegalArgumentException("Invalid EGL_MULTISAMPLE_RESOLVE value specified: " + multisampleResolve);
if ( getAttrib(SAMPLE_BUFFERS) == 0 )
throw new IllegalStateException("An EGL_MULTISAMPLE_RESOLVE value cannot be specified unless EGL_SAMPLE_BUFFERS is 1.");
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(MULTISAMPLE_RESOLVE, multisampleResolve);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_SWAP_BEHAVIOR value.
* Valid values for swapBehavior are EGL_DONT_CARE, EGL_BUFFER_PRESERVED
* and EGL_BUFFER_DESTROYED.
*
* @param swapBehavior the new EGL_SWAP_BEHAVIOR value
*
* @return the new PixelFormat
*/
public PixelFormat withSwapBehavior(final int swapBehavior) {
switch ( swapBehavior ) {
case EGL_DONT_CARE:
case EGL_BUFFER_PRESERVED:
case EGL_BUFFER_DESTROYED:
break;
default:
throw new IllegalArgumentException("Invalid EGL_SWAP_BEHAVIOR value specified: " + swapBehavior);
}
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(SWAP_BEHAVIOR, swapBehavior);
return pf;
}
/* -----------------------------------------
EXTENSION ATTRIBUTES
----------------------------------------- */
/**
* Returns a new PixelFormat with the specified number of EGL_COVERAGE_SAMPLES_NV.
* The samples value must be greater than or equal to 0. The related
* EGL_COVERAGE_BUFFERS_NV value will become 0 if samples is 0, or 1 if samples
* is greater than 0.
*
* @param samples the new EGL_SAMPLES value
*
* @return the new PixelFormat
*/
public PixelFormat withCoverageSamplesNV(final int samples) {
if ( samples < 0 )
throw new IllegalArgumentException("Invalid number of EGL_COVERAGE_SAMPLES_NV specified: " + samples);
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(COVERAGE_SAMPLES_NV, samples);
pf.setAttrib(COVERAGE_BUFFERS_NV, samples == 0 ? 0 : 1);
return pf;
}
/**
* Returns a new PixelFormat with the specified EGL_DEPTH_ENCODING_NONLINEAR_NV.
* Valid values for depthEncoding are EGL_DONT_CARE, EGL_DEPTH_ENCODING_NONE_NV
* and EGL_DEPTH_ENCODING_NONLINEAR_NV.
*
* @param depthEncoding the new EGL_DEPTH_ENCODING_NONLINEAR_NV value
*
* @return the new PixelFormat
*/
public PixelFormat withDepthEncodingNonlinearNV(final int depthEncoding) {
switch ( depthEncoding ) {
case EGL_DONT_CARE:
case EGL_DEPTH_ENCODING_NONE_NV:
case EGL_DEPTH_ENCODING_NONLINEAR_NV:
break;
default:
throw new IllegalArgumentException("Invalid EGL_DEPTH_ENCODING_NONLINEAR_NV value specified: " + depthEncoding);
}
final PixelFormat pf = new PixelFormat(this);
pf.setAttrib(DEPTH_ENCODING_NONLINEAR_NV, depthEncoding);
return pf;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
/**
* A PowerManagementEventException exception will be thrown when a call
* to eglSwapBuffers, eglCopyBuffers or eglMakeCurrent returns EGL_FALSE
* and the EGL_ERROR generated is EGL_CONTEXT_LOST.
* <p/>
* On detection of this error, the application must destroy all contexts.
* To continue rendering the application must recreate any contexts it
* requires, and subsequently restore any client API state and objects
* it wishes to use.
* <p/>
* Note that not all implementations can be made to generate power management
* events, and developers should continue to refer to platform-specific
* documentation in this area.
*/
public class PowerManagementEventException extends RuntimeException {
static final long serialVersionUID = -1L;
public PowerManagementEventException() {
super();
}
public PowerManagementEventException(final String message) {
super(message);
}
public PowerManagementEventException(final String message, final Throwable cause) {
super(message, cause);
}
public PowerManagementEventException(final Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import java.nio.Buffer;
import static org.lwjgl.opengles.GLES20.*;
final class StateTracker {
private static StateTracker tracker = new StateTracker();
int elementArrayBuffer;
int arrayBuffer;
Buffer[] glVertexAttribPointer_buffer;
StateTracker() {
}
void init() {
glVertexAttribPointer_buffer = new Buffer[glGetInteger(GL_MAX_VERTEX_ATTRIBS)];
}
static StateTracker getTracker() {
return tracker;
}
static void bindBuffer(int target, int buffer) {
final StateTracker tracker = getTracker();
switch ( target ) {
case GL_ARRAY_BUFFER:
tracker.arrayBuffer = buffer;
break;
case GL_ELEMENT_ARRAY_BUFFER:
tracker.elementArrayBuffer = buffer;
break;
}
}
}

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.OpenGLException;
import static org.lwjgl.opengles.EGL.*;
import static org.lwjgl.opengles.GLES20.*;
/**
* Simple utility class.
*
* @author Spasi
*/
public final class Util {
private Util() {
}
/**
* Checks for OpenGL ES errors.
*
* @throws org.lwjgl.opengl.OpenGLException
* if GLES20.glGetError() returns anything else than GLES20.GL_NO_ERROR
*/
public static void checkGLError() throws OpenGLException {
int err = glGetError();
if ( err != GL_NO_ERROR )
throw new OpenGLException(err);
}
/**
* Translates a GL error code to a String describing the error.
*
* @param error_code the OpenGL ES error code
*
* @return the error description
*/
public static String translateGLErrorString(int error_code) {
switch ( error_code ) {
case GL_NO_ERROR:
return "No error";
case GL_INVALID_ENUM:
return "Invalid enum";
case GL_INVALID_VALUE:
return "Invalid value";
case GL_INVALID_OPERATION:
return "Invalid operation";
case GL_OUT_OF_MEMORY:
return "Out of memory";
default:
return null;
}
}
/**
* Checks for EGL errors.
*
* @throws org.lwjgl.LWJGLException if EGL.eglGetError() returns anything else than EGL.EGL_SUCCESS
*/
static void checkEGLError() throws LWJGLException {
int err = eglGetError();
if ( err != EGL_SUCCESS )
throw new LWJGLException(translateEGLErrorString(err));
}
/**
* Translates an EGL error code to a String describing the error.
*
* @param error_code the EGL error code
*
* @return the error description
*/
static String translateEGLErrorString(int error_code) {
switch ( error_code ) {
case EGL_NOT_INITIALIZED:
return "EGL not initialized";
case EGL_BAD_ACCESS:
return "Bad access";
case EGL_BAD_ALLOC:
return "Bad allocation";
case EGL_BAD_ATTRIBUTE:
return "Bad attribute";
case EGL_BAD_CONFIG:
return "Bad config";
case EGL_BAD_CONTEXT:
return "Bad EGL context";
case EGL_BAD_CURRENT_SURFACE:
return "Bad current EGL surface";
case EGL_BAD_DISPLAY:
return "Bad EGL display";
case EGL_BAD_MATCH:
return "Bad match";
case EGL_BAD_NATIVE_PIXMAP:
return "Bad native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "Bad native window";
case EGL_BAD_PARAMETER:
return "Bad parameter";
case EGL_BAD_SURFACE:
return "Bad EGL surface";
case EGL_CONTEXT_LOST:
return "EGL context lost";
default:
return null;
}
}
}

View file

@ -0,0 +1,327 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.test.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengles.PixelFormat;
import org.lwjgl.opengles.PowerManagementEventException;
import org.lwjgl.util.vector.Vector2f;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.GLES20.*;
import static org.lwjgl.test.opengles.util.GLMatrix.*;
/**
* Tests switching between windowed and fullscreen
*
* @author Brian Matzon <brian@matzon.dk>
* @version $Revision: 3172 $
* $Id: FullScreenWindowedTest.java 3172 2008-12-28 19:30:43Z elias_naur $
*/
public class FullScreenWindowedTest {
/** Intended deiplay mode */
private DisplayMode mode;
/** our quad moving around */
private Vector2f quadPosition;
/** our quadVelocity */
private Vector2f quadVelocity;
/** angle of quad */
private float angle;
/** degrees to rotate per frame */
private float angleRotation = 1.0f;
/** Max speed of all changable attributes */
private static final float MAX_SPEED = 20.0f;
private static int buffer_id;
private static int indices_buffer_id;
private QuadRenderer renderer;
/** Creates a FullScreenWindowedTest */
public FullScreenWindowedTest() {
}
/** Executes the test */
public void execute() {
initialize();
mainLoop();
cleanup();
Display.destroy();
}
private void switchMode() throws LWJGLException {
mode = findDisplayMode(1024, 600, Display.getDisplayMode().getBitsPerPixel());
try {
Display.setDisplayModeAndFullscreen(mode);
} catch (PowerManagementEventException e) {
e.printStackTrace();
}
}
/** Initializes the test */
private void initialize() {
try {
//find displaymode
switchMode();
// start of in windowed mode
Display.create(new PixelFormat());
glInit();
quadPosition = new Vector2f(100f, 100f);
quadVelocity = new Vector2f(1.0f, 1.0f);
renderer = new QuadRenderer();
} catch (Exception e) {
e.printStackTrace();
}
}
/** Runs the main loop of the "test" */
private void mainLoop() {
while ( !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && !Display.isCloseRequested() ) {
if ( Display.isVisible() ) {
// check keyboard input
processKeyboard();
// do "game" logic, and render it
logic();
render();
} else {
// no need to render/paint if nothing has changed (ie. window
// dragged over)
if ( Display.isDirty() ) {
render();
}
// don't waste cpu time, sleep more
try {
Thread.sleep(100);
} catch (InterruptedException inte) {
}
}
// Update window
try {
Display.update();
Display.sync(60);
} catch (PowerManagementEventException e) {
e.printStackTrace();
}
}
}
/** Performs the logic */
private void logic() {
angle += angleRotation;
if ( angle > 90.0f ) {
angle = 0.0f;
}
quadPosition.x += quadVelocity.x;
quadPosition.y += quadVelocity.y;
//check colision with vertical border border
if ( quadPosition.x + 50 >= mode.getWidth() || quadPosition.x - 50 <= 0 ) {
quadVelocity.x *= -1;
}
//check collision with horizontal border
if ( quadPosition.y + 50 >= mode.getHeight() || quadPosition.y - 50 <= 0 ) {
quadVelocity.y *= -1;
}
}
private void render() {
//clear background
glClear(GL_COLOR_BUFFER_BIT);
// draw white quad
glPushMatrix();
{
glTranslatef(quadPosition.x, quadPosition.y, 0);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
renderer.setMVPUniform();
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
}
glPopMatrix();
}
/** Processes keyboard input */
private void processKeyboard() {
//check for fullscreen key
if ( Keyboard.isKeyDown(Keyboard.KEY_F) ) {
try {
cleanup();
switchMode();
glInit();
renderer = new QuadRenderer();
} catch (Exception e) {
e.printStackTrace();
}
}
//check for window key
if ( Keyboard.isKeyDown(Keyboard.KEY_W) ) {
try {
cleanup();
mode = new DisplayMode(800, 480);
Display.setDisplayModeAndFullscreen(mode);
glInit();
renderer = new QuadRenderer();
} catch (Exception e) {
e.printStackTrace();
}
}
//check for speed changes
if ( Keyboard.isKeyDown(Keyboard.KEY_UP) ) {
quadVelocity.y += 0.1f;
}
if ( Keyboard.isKeyDown(Keyboard.KEY_DOWN) ) {
quadVelocity.y -= 0.1f;
}
if ( Keyboard.isKeyDown(Keyboard.KEY_RIGHT) ) {
quadVelocity.x += 0.1f;
}
if ( Keyboard.isKeyDown(Keyboard.KEY_LEFT) ) {
quadVelocity.x -= 0.1f;
}
if ( Keyboard.isKeyDown(Keyboard.KEY_ADD) ) {
angleRotation += 0.1f;
}
if ( Keyboard.isKeyDown(Keyboard.KEY_SUBTRACT) ) {
angleRotation -= 0.1f;
}
//throttle
if ( quadVelocity.x < -MAX_SPEED ) {
quadVelocity.x = -MAX_SPEED;
}
if ( quadVelocity.x > MAX_SPEED ) {
quadVelocity.x = MAX_SPEED;
}
if ( quadVelocity.y < -MAX_SPEED ) {
quadVelocity.y = -MAX_SPEED;
}
if ( quadVelocity.y > MAX_SPEED ) {
quadVelocity.y = MAX_SPEED;
}
if ( angleRotation < 0.0f ) {
angleRotation = 0.0f;
}
if ( angleRotation > MAX_SPEED ) {
angleRotation = MAX_SPEED;
}
}
/** Cleans up the test */
private void cleanup() {
renderer.cleanup();
IntBuffer int_buffer = BufferUtils.createIntBuffer(2);
int_buffer.put(0, buffer_id);
int_buffer.put(1, indices_buffer_id);
glDeleteBuffers(int_buffer);
}
/**
* Retrieves a displaymode, if one such is available
*
* @param width Required width
* @param height Required height
* @param bpp Minimum required bits per pixel
*
* @return
*/
private static DisplayMode findDisplayMode(int width, int height, int bpp) throws LWJGLException {
DisplayMode[] modes = Display.getAvailableDisplayModes();
for ( int i = 0; i < modes.length; i++ ) {
if ( modes[i].getWidth() == width && modes[i].getHeight() == height && modes[i].getBitsPerPixel() >= bpp && modes[i].getFrequency() <= 60 ) {
return modes[i];
}
}
return Display.getDesktopDisplayMode();
}
/** Initializes OGL */
private void glInit() {
// Go into orthographic projection mode.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, mode.getWidth(), 0, mode.getHeight(), -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, mode.getWidth(), mode.getHeight());
//set clear color to black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//sync frame (only works on windows)
Display.setVSyncEnabled(true);
final IntBuffer int_buffer = BufferUtils.createIntBuffer(2);
glGenBuffers(int_buffer);
buffer_id = int_buffer.get(0);
indices_buffer_id = int_buffer.get(1);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_id);
final FloatBuffer vertices = BufferUtils.createFloatBuffer(2 * 4);
vertices
.put(-50).put(-50)
.put(50).put(-50)
.put(-50).put(50)
.put(50).put(50);
vertices.rewind();
final IntBuffer indices = BufferUtils.createIntBuffer(4);
indices.put(0).put(1).put(2).put(3);
indices.rewind();
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
}
/** Test entry point */
public static void main(String[] args) {
System.out.println("Change between fullscreen and windowed mode, by pressing F and W respectively");
System.out.println("Move quad using arrowkeys, and change rotation using +/-");
FullScreenWindowedTest fswTest = new FullScreenWindowedTest();
fswTest.execute();
System.exit(0);
}
}

View file

@ -0,0 +1,580 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* 3-D gear wheels. Originally by Brian Paul
*/
package org.lwjgl.test.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengles.*;
import org.lwjgl.test.opengles.util.Geometry;
import org.lwjgl.test.opengles.util.ImmediateModeBuffer;
import org.lwjgl.test.opengles.util.Shader;
import org.lwjgl.test.opengles.util.ShaderProgram;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import java.lang.reflect.Field;
import java.nio.FloatBuffer;
import java.util.StringTokenizer;
import static org.lwjgl.opengles.GLES20.*;
import static org.lwjgl.test.opengles.util.GLLight.*;
import static org.lwjgl.test.opengles.util.GLMatrix.*;
import static org.lwjgl.test.opengles.util.Geometry.*;
/**
* <p>
* This is the OpenGL "standard" Gears demo, originally by Brian Paul
* </p>
*
* @author Brian Matzon <brian@matzon.dk>
* @version $Revision: 3276 $
* $Id: Gears.java 3276 2010-02-21 21:18:17Z matzon $
*/
public class Gears {
private boolean run = true;
private float view_rotx = 20.0f;
private float view_roty = 30.0f;
private float view_rotz = 0.0f;
private Gear gear1;
private Gear gear2;
private Gear gear3;
private float angle = 0.0f;
private Shader vsh;
private Shader fsh;
private ShaderProgram program;
private int LIGHT_POS;
private int MVP;
private int NM;
private int GEAR_COLOR;
private int vPosition;
private int vNormal;
private final Matrix4f p = new Matrix4f();
private final Matrix4f mv = new Matrix4f();
private final Matrix4f mvp = new Matrix4f();
private final FloatBuffer m4fBuffer = BufferUtils.createFloatBuffer(4 * 4);
private final FloatBuffer m3fBuffer = BufferUtils.createFloatBuffer(3 * 3);
public static void main(String[] args) {
new Gears().execute();
System.exit(0);
}
/**
*
*/
private void execute() {
try {
init();
} catch (LWJGLException e) {
e.printStackTrace();
System.out.println("Failed to initialize Gears.");
return;
}
System.out.println("\nGL RENDERER: " + glGetString(GL_RENDERER));
System.out.println("GL VENDOR: " + glGetString(GL_VENDOR));
System.out.println("GL VERSION: " + glGetString(GL_VERSION));
System.out.println("GL_SHADING_LANGUAGE_VERSION: " + glGetString(GL_SHADING_LANGUAGE_VERSION));
System.out.println("GL_EXTENSIONS = " + glGetString(GL_EXTENSIONS));
ContextCapabilities caps = GLContext.getCapabilities();
System.out.println();
// Check extension support
Field[] field = ContextCapabilities.class.getFields();
for ( Field f : field ) {
if ( f.getName().startsWith("GL_") ) {
try {
System.out.println(f.getName() + " - " + f.getBoolean(caps));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
System.out.println();
// Check for extensions that LWJGL does not support
final String extensions = glGetString(GL_EXTENSIONS);
final StringTokenizer tokenizer = new StringTokenizer(extensions);
while ( tokenizer.hasMoreTokens() ) {
final String ext = tokenizer.nextToken();
try {
if ( !caps.getClass().getField(ext).getBoolean(caps) )
System.out.println("-- Extension exposed but functions are missing: " + ext);
} catch (NoSuchFieldException e) {
System.out.println("-- No LWJGL support for extension: " + ext);
} catch (Exception e) {
e.printStackTrace();
}
}
loop();
destroy();
}
/**
*
*/
private void destroy() {
program.destroy();
fsh.destroy();
vsh.destroy();
gear3.destroy();
gear2.destroy();
gear1.destroy();
Display.destroy();
}
/**
*
*/
private void loop() {
long lastFrameTime = Sys.getTime();
long startTime = System.currentTimeMillis() + 5000;
long fps = 0;
while ( run ) {
if ( !Display.isVisible() )
Thread.yield();
else {
// This is the current frame time.
long frameStart = Sys.getTime();
// How many seconds passed since last frame.
final float frameTime = (float)((frameStart - lastFrameTime) / (double)Sys.getTimerResolution());
lastFrameTime = frameStart;
angle += frameTime * 120.0f;
handleInput();
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_COVERAGE_BUFFER_BIT_NV);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(-3.0f, -2.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
gear1.render();
glPopMatrix();
glPushMatrix();
glTranslatef(3.1f, -2.0f, 0.0f);
glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
gear2.render();
glPopMatrix();
glPushMatrix();
glTranslatef(-3.1f, 4.2f, 0.0f);
glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
gear3.render();
glPopMatrix();
glPopMatrix();
try {
Display.update();
//Display.sync(60);
} catch (PowerManagementEventException e) {
e.printStackTrace();
}
if ( startTime > System.currentTimeMillis() ) {
fps++;
} else {
long timeUsed = 5000 + (startTime - System.currentTimeMillis());
startTime = System.currentTimeMillis() + 5000;
System.out.println(fps + " frames in " + (timeUsed / 1000f) + " seconds = " + (fps / (timeUsed / 1000f)));
fps = 0;
}
if ( Display.isCloseRequested() )
break;
}
}
}
private void handleInput() {
if ( Keyboard.getNumKeyboardEvents() != 0 ) {
while ( Keyboard.next() ) {
if ( Keyboard.getEventKeyState() )
continue;
final int key = Keyboard.getEventKey();
switch ( key ) {
case Keyboard.KEY_ESCAPE:
run = false;
break;
}
}
}
while ( Mouse.next() ) ;
}
/**
*
*/
private void init() throws LWJGLException {
final int WIDTH = 640;
final int HEIGHT = 480;
Display.setLocation((Display.getDisplayMode().getWidth() - WIDTH) / 2,
(Display.getDisplayMode().getHeight() - HEIGHT) / 2);
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
} catch (PowerManagementEventException e) {
e.printStackTrace();
}
Display.setTitle("Gears");
Display.create(new PixelFormat());
//glCoverageMaskNV(true);
// setup ogl
glViewport(0, 0, WIDTH, HEIGHT);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
final Vector3f lp = new Vector3f(5.0f, 5.0f, 10.0f);
lp.normalise();
glLight(GL_LIGHT0, GL_POSITION, lp.getX(), lp.getY(), lp.getZ(), 0.0f);
/* make the gears */
gear1 = new Gear(gear(1.0f, 4.0f, 1.0f, 20, 0.7f), new float[] { 0.8f, 0.1f, 0.0f, 1.0f });
gear2 = new Gear(gear(0.5f, 2.0f, 2.0f, 10, 0.7f), new float[] { 0.0f, 0.8f, 0.2f, 1.0f });
gear3 = new Gear(gear(1.3f, 2.0f, 0.5f, 10, 0.7f), new float[] { 0.2f, 0.2f, 1.0f, 1.0f });
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
final float h = (float)300 / (float)300;
glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -40.0f);
vsh = new Shader(GL_VERTEX_SHADER, "uniform highp vec4 LIGHT_POS;\n" +
"uniform highp mat4 MODEL_VIEW_PROJECTION_MATRIX;\n" +
"uniform mediump mat3 NORMAL_MATRIX;\n" +
"uniform lowp vec3 GEAR_COLOR;\n" +
"attribute highp vec3 vPosition;\n" +
"attribute mediump vec3 vNormal;\n" +
"varying lowp vec3 color;\n" +
"void main(void) {\n" +
"\tgl_Position = MODEL_VIEW_PROJECTION_MATRIX * vec4(vPosition, 1.0);\n" +
"\tvec3 normal = NORMAL_MATRIX * vNormal;\n" +
"\tcolor = max(dot(normal, vec3(LIGHT_POS)), 0.0) * GEAR_COLOR + vec3(0.05);\n" +
"}");
fsh = new Shader(GL_FRAGMENT_SHADER, "varying lowp vec3 color;\n" +
"void main(void) {\n" +
"\tgl_FragColor = vec4(color, 1.0);\n" +
"}");
program = new ShaderProgram(vsh, fsh);
program.enable();
LIGHT_POS = program.getUniformLocation("LIGHT_POS");
MVP = program.getUniformLocation("MODEL_VIEW_PROJECTION_MATRIX");
NM = program.getUniformLocation("NORMAL_MATRIX");
GEAR_COLOR = program.getUniformLocation("GEAR_COLOR");
vPosition = program.getAttributeLocation("vPosition");
vNormal = program.getAttributeLocation("vNormal");
glEnableVertexAttribArray(vNormal);
glEnableVertexAttribArray(vPosition);
}
/**
* Draw a gear wheel. You'll probably want to call this function when
* building a display list since we do a lot of trig here.
*
* @param inner_radius radius of hole at center
* @param outer_radius radius at center of teeth
* @param width width of gear
* @param teeth number of teeth
* @param tooth_depth depth of tooth
*/
private static Geometry gear(float inner_radius, float outer_radius, float width, int teeth, float tooth_depth) {
int i;
float r0, r1, r2;
float angle, da;
float u, v, len;
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0f;
r2 = outer_radius + tooth_depth / 2.0f;
da = 2.0f * (float)Math.PI / teeth / 4.0f;
final Geometry gear = new Geometry();
final ImmediateModeBuffer imb = new ImmediateModeBuffer(1024);
int lastDrawIndex = 0;
//glShadeModel(GL_FLAT);
// draw front face
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, teeth * 4 + 2);
for ( i = 0; i <= teeth; i++ ) {
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
if ( i < teeth ) {
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle + 3.0f * da), r1 * sin(angle + 3.0f * da), width * 0.5f);
}
}
// draw front sides of teeth
for ( i = 0; i < teeth; i++ ) {
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, 4);
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle + 3.0f * da), r1 * sin(angle + 3.0f * da), width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r2 * cos(angle + 2.0f * da), r2 * sin(angle + 2.0f * da), width * 0.5f);
}
// draw back face
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, (teeth + 1) * 4);
for ( i = 0; i <= teeth; i++ ) {
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
}
// draw back sides of teeth
for ( i = 0; i < teeth; i++ ) {
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, 4);
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5f);
}
// draw outward faces of teeth
// OpenGL ES 2.0 note: This needs to be converted to a triangle
// list with face normals to get the flat look of the original.
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, teeth * 8 + 2);
for ( i = 0; i < teeth; i++ ) {
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(cos(angle), sin(angle), 0.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5f);
imb.glNormal3f(cos(angle), sin(angle), 0.0f);
imb.glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5f);
u = r2 * cos(angle + da) - r1 * cos(angle);
v = r2 * sin(angle + da) - r1 * sin(angle);
len = (float)Math.sqrt(u * u + v * v);
u /= len;
v /= len;
imb.glNormal3f(v, -u, 0.0f);
imb.glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5f);
imb.glNormal3f(v, -u, 0.0f);
imb.glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5f);
imb.glNormal3f(cos(angle), sin(angle), 0.0f);
imb.glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5f);
imb.glNormal3f(cos(angle), sin(angle), 0.0f);
imb.glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5f);
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
imb.glNormal3f(v, -u, 0.0f);
imb.glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5f);
imb.glNormal3f(v, -u, 0.0f);
imb.glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5f);
}
imb.glNormal3f(cos(0), sin(0), 0.0f);
imb.glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5f);
imb.glNormal3f(cos(0), sin(0), 0.0f);
imb.glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5f);
//glShadeModel(GL_SMOOTH);
// draw inside radius cylinder
lastDrawIndex += gear.addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, (teeth + 1) * 2);
for ( i = 0; i <= teeth; i++ ) {
angle = i * 2.0f * (float)Math.PI / teeth;
imb.glNormal3f(-cos(angle), -sin(angle), 0.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5f);
imb.glNormal3f(-cos(angle), -sin(angle), 0.0f);
imb.glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5f);
}
gear.update(imb.getBuffer());
return gear;
}
private class Gear {
private final Geometry geom;
private final float[] color;
Gear(final Geometry geom, final float[] color) {
this.geom = geom;
this.color = color;
}
void render() {
// Set gear color
glUniform3f(GEAR_COLOR, color[0], color[1], color[2]);
// Set Light position
setUniform4f(LIGHT_POS, GL_LIGHT0, GL_POSITION);
// Get Projection and Modelview matrices
glMatrixMode(GL_PROJECTION);
glGetMatrix(p);
glMatrixMode(GL_MODELVIEW);
glGetMatrix(mv);
// Set MVP uniform
Matrix4f.mul(p, mv, mvp);
mvp.store(m4fBuffer);
m4fBuffer.flip();
glUniformMatrix4(MVP, false, m4fBuffer);
// Set normal matrix (upper-left 3x3 of the inverse transpose MV matrix)
mv.invert();
mv.transpose();
mv.store3f(m3fBuffer);
m3fBuffer.flip();
glUniformMatrix3(NM, false, m3fBuffer);
geom.bind();
final int stride = (3 + 3) * 4;
glVertexAttribPointer(vNormal, 3, GL_FLOAT, false, stride, 0);
glVertexAttribPointer(vPosition, 3, GL_FLOAT, false, stride, 3 * 4);
geom.draw();
}
void destroy() {
geom.destroy();
}
}
}

View file

@ -0,0 +1,251 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* $Id: VBOIndexTest.java 2983 2008-04-07 18:36:09Z matzon $
*
* Simple java test program.
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 2983 $
*/
package org.lwjgl.test.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengles.GLContext;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.opengles.GLES20.*;
import static org.lwjgl.opengles.OESMapbuffer.*;
import static org.lwjgl.test.opengles.util.GLMatrix.*;
public final class MappedIndexedVBOTest {
static {
try {
//find first display mode that allows us 640*480*16
int mode = -1;
DisplayMode[] modes = Display.getAvailableDisplayModes();
for ( int i = 0; i < modes.length; i++ ) {
if ( modes[i].getWidth() == 640
&& modes[i].getHeight() == 480
&& modes[i].getBitsPerPixel() >= 16 ) {
mode = i;
break;
}
}
if ( mode != -1 ) {
//select above found displaymode
System.out.println("Setting display mode to " + modes[mode]);
Display.setDisplayMode(modes[mode]);
System.out.println("Created display.");
}
} catch (Exception e) {
System.err.println("Failed to create display due to " + e);
}
}
static {
try {
Display.createES();
System.out.println("Created OpenGL.");
if ( !GLContext.getCapabilities().GL_OES_mapbuffer ) {
System.out.println("GL_OES_mapbuffer is not supported, quitting!");
System.exit(0);
}
} catch (Exception e) {
System.err.println("Failed to create OpenGL due to " + e);
System.exit(1);
}
}
/** Is the game finished? */
private static boolean finished;
/** A rotating square! */
private static float angle;
private static int buffer_id;
private static int indices_buffer_id;
private static FloatBuffer vertices;
private static ByteBuffer mapped_buffer;
private static FloatBuffer mapped_float_buffer;
private static IntBuffer indices;
private static ByteBuffer mapped_indices_buffer;
private static IntBuffer mapped_indices_int_buffer;
private static QuadRenderer renderer;
public static void main(String[] arguments) {
try {
init();
while ( !finished ) {
Display.update();
Display.sync(30);
if ( !Display.isVisible() )
Thread.sleep(200);
else if ( Display.isCloseRequested() )
System.exit(0);
mainLoop();
render();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
cleanup();
}
System.exit(0);
}
/** All calculations are done in here */
private static void mainLoop() {
angle += 1f;
if ( angle > 360.0f )
angle = 0.0f;
if ( Mouse.getDX() != 0 || Mouse.getDY() != 0 || Mouse.getDWheel() != 0 )
System.out.println("Mouse moved " + Mouse.getDX() + " " + Mouse.getDY() + " " + Mouse.getDWheel());
for ( int i = 0; i < Mouse.getButtonCount(); i++ )
if ( Mouse.isButtonDown(i) )
System.out.println("Button " + i + " down");
if ( Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) )
finished = true;
for ( int i = 0; i < Keyboard.getNumKeyboardEvents(); i++ ) {
Keyboard.next();
if ( Keyboard.getEventKey() == Keyboard.KEY_ESCAPE && Keyboard.getEventKeyState() )
finished = true;
if ( Keyboard.getEventKey() == Keyboard.KEY_T && Keyboard.getEventKeyState() )
System.out.println("Current time: " + Sys.getTime());
}
}
/** All rendering is done in here */
private static void render() {
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(Display.getDisplayMode().getWidth() / 2, Display.getDisplayMode().getHeight() / 2, 0.0f);
glRotatef(angle, 0, 0, 1.0f);
renderer.setMVPUniform();
ByteBuffer new_mapped_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES, mapped_buffer);
if ( new_mapped_buffer != mapped_buffer ) {
mapped_buffer = new_mapped_buffer;
mapped_float_buffer = new_mapped_buffer.asFloatBuffer();
}
new_mapped_buffer = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES, mapped_indices_buffer);
if ( new_mapped_buffer != mapped_indices_buffer ) {
mapped_indices_buffer = new_mapped_buffer;
mapped_indices_int_buffer = new_mapped_buffer.asIntBuffer();
}
mapped_float_buffer.rewind();
vertices.rewind();
mapped_float_buffer.put(vertices);
mapped_indices_int_buffer.rewind();
indices.rewind();
mapped_indices_int_buffer.put(indices);
if ( glUnmapBufferOES(GL_ARRAY_BUFFER) &&
glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER) ) {
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
}
glPopMatrix();
}
/** Initialize */
private static void init() throws Exception {
System.out.println("Timer resolution: " + Sys.getTimerResolution());
// Go into orthographic projection mode.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getDisplayMode().getWidth(), 0, Display.getDisplayMode().getHeight(), -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
final IntBuffer int_buffer = BufferUtils.createIntBuffer(2);
glGenBuffers(int_buffer);
buffer_id = int_buffer.get(0);
indices_buffer_id = int_buffer.get(1);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_id);
vertices = BufferUtils.createFloatBuffer(2 * 4);
vertices
.put(-50).put(-50)
.put(50).put(-50)
.put(-50).put(50)
.put(50).put(50);
vertices.rewind();
indices = BufferUtils.createIntBuffer(4);
indices.put(0).put(1).put(2).put(3);
indices.rewind();
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * 4, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * 4, GL_STREAM_DRAW);
renderer = new QuadRenderer();
}
/** Cleanup */
private static void cleanup() {
renderer.cleanup();
IntBuffer int_buffer = BufferUtils.createIntBuffer(2);
int_buffer.put(0, buffer_id);
int_buffer.put(1, indices_buffer_id);
glDeleteBuffers(int_buffer);
Display.destroy();
}
}

View file

@ -0,0 +1,70 @@
package org.lwjgl.test.opengles;
import org.lwjgl.BufferUtils;
import org.lwjgl.test.opengles.util.Shader;
import org.lwjgl.test.opengles.util.ShaderProgram;
import org.lwjgl.util.vector.Matrix4f;
import java.nio.FloatBuffer;
import static org.lwjgl.opengles.GLES20.*;
import static org.lwjgl.test.opengles.util.GLMatrix.*;
final class QuadRenderer {
private final Shader vsh;
private final Shader fsh;
private final ShaderProgram program;
private final int uniMVP;
private final Matrix4f p = new Matrix4f();
private final Matrix4f mv = new Matrix4f();
private final Matrix4f mvp = new Matrix4f();
private final FloatBuffer m4fBuffer = BufferUtils.createFloatBuffer(4 * 4);
QuadRenderer() {
vsh = new Shader(GL_VERTEX_SHADER, "uniform highp mat4 MODEL_VIEW_PROJECTION_MATRIX;\n" +
"attribute highp vec2 vPosition;\n" +
"void main(void) {\n" +
"\tgl_Position = MODEL_VIEW_PROJECTION_MATRIX * vec4(vPosition, 0.0, 1.0);\n" +
"}");
fsh = new Shader(GL_FRAGMENT_SHADER, "void main(void) {\n" +
"\tgl_FragColor = vec4(1.0);\n" +
"}");
program = new ShaderProgram(vsh, fsh);
program.enable();
uniMVP = program.getUniformLocation("MODEL_VIEW_PROJECTION_MATRIX");
final int vPosition = program.getAttributeLocation("vPosition");
glVertexAttribPointer(vPosition, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(vPosition);
}
void setMVPUniform() {
// Get Projection and Modelview matrices
glMatrixMode(GL_PROJECTION);
glGetMatrix(p);
glMatrixMode(GL_MODELVIEW);
glGetMatrix(mv);
// Set MVP uniform
Matrix4f.mul(p, mv, mvp);
mvp.store(m4fBuffer);
m4fBuffer.flip();
glUniformMatrix4(uniMVP, false, m4fBuffer);
}
void cleanup() {
program.destroy();
fsh.destroy();
vsh.destroy();
}
}

View file

@ -0,0 +1,99 @@
package org.lwjgl.test.opengles.util;
import java.nio.*;
import static org.lwjgl.opengles.GLES20.*;
import static org.lwjgl.opengles.OESMapbuffer.*;
abstract class BufferObject implements GLObject {
protected final int ID;
protected int target;
protected int usage;
/** The BufferObject data size in bytes. */
private int size;
protected BufferObject(final int type, final int usage) {
this.ID = glGenBuffers();
this.target = type;
this.usage = usage;
}
protected BufferObject(final int type, final int usage, final Buffer buffer) {
this(type, usage);
setData(buffer);
}
protected BufferObject(final int type, final int usage, final int dataSize) {
this(type, usage);
setData(dataSize);
}
public final int getID() {
return ID;
}
public void destroy() {
glDeleteBuffers(ID);
}
public final int getTarget() {
return target;
}
public final int getUsage() {
return usage;
}
public final int getSize() {
return size;
}
public abstract void enable();
public abstract void disable();
public final void setData(final Buffer buffer) {
enable();
if ( buffer instanceof ByteBuffer ) {
glBufferData(target, (ByteBuffer)buffer, usage);
size = buffer.remaining();
} else if ( buffer instanceof ShortBuffer ) {
glBufferData(target, (ShortBuffer)buffer, usage);
size = buffer.remaining() << 1;
} else if ( buffer instanceof IntBuffer ) {
glBufferData(target, (IntBuffer)buffer, usage);
size = buffer.remaining() << 2;
} else if ( buffer instanceof FloatBuffer ) {
glBufferData(target, (FloatBuffer)buffer, usage);
size = buffer.remaining() << 2;
}
disable();
}
public final void setData(final int dataSize) {
enable();
glBufferData(target, dataSize, usage);
size = dataSize;
disable();
}
public final ByteBuffer map(final int access, final ByteBuffer oldBuffer) {
return glMapBufferOES(target, access, oldBuffer);
}
public final ByteBuffer map(final int access, final int length, final ByteBuffer oldBuffer) {
return glMapBufferOES(target, access, length, oldBuffer);
}
public final boolean unmap() {
return glUnmapBufferOES(target);
}
}

View file

@ -0,0 +1,41 @@
package org.lwjgl.test.opengles.util;
import java.nio.Buffer;
import static org.lwjgl.opengles.GLES20.*;
public final class BufferObjectArray extends BufferObject {
private static int boundBOArray;
public BufferObjectArray(final int usage) {
super(GL_ARRAY_BUFFER, usage);
}
public BufferObjectArray(final int usage, final Buffer buffer) {
super(GL_ARRAY_BUFFER, usage, buffer);
}
public BufferObjectArray(final int usage, final int dataSize) {
super(GL_ARRAY_BUFFER, usage, dataSize);
}
public void enable() {
if ( boundBOArray != ID ) {
glBindBuffer(GL_ARRAY_BUFFER, ID);
boundBOArray = ID;
}
}
public void disable() {
boArrayDisable();
}
public static void boArrayDisable() {
if ( boundBOArray != 0 ) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
boundBOArray = 0;
}
}
}

View file

@ -0,0 +1,41 @@
package org.lwjgl.test.opengles.util;
import java.nio.Buffer;
import static org.lwjgl.opengles.GLES20.*;
public final class BufferObjectElement extends BufferObject {
private static int boundBOElementArray;
public BufferObjectElement(final int usage) {
super(GL_ELEMENT_ARRAY_BUFFER, usage);
}
public BufferObjectElement(final int usage, final Buffer buffer) {
super(GL_ELEMENT_ARRAY_BUFFER, usage, buffer);
}
public BufferObjectElement(final int usage, final int dataSize) {
super(GL_ELEMENT_ARRAY_BUFFER, usage, dataSize);
}
public void enable() {
if ( boundBOElementArray != ID ) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID);
boundBOElementArray = ID;
}
}
public void disable() {
boElementArrayDisable();
}
public static void boElementArrayDisable() {
if ( boundBOElementArray != 0 ) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
boundBOElementArray = 0;
}
}
}

View file

@ -0,0 +1,165 @@
package org.lwjgl.test.opengles.util;
import static org.lwjgl.opengles.GLES20.*;
/** Emulates the light state in fixed-function OpenGL. */
public class GLLight {
public static final int GL_LIGHT0 = 0x4000;
public static final int GL_LIGHT1 = 0x4001;
public static final int GL_LIGHT2 = 0x4002;
public static final int GL_LIGHT3 = 0x4003;
public static final int GL_LIGHT4 = 0x4004;
public static final int GL_LIGHT5 = 0x4005;
public static final int GL_LIGHT6 = 0x4006;
public static final int GL_LIGHT7 = 0x4007;
public static final int GL_AMBIENT = 0x1200;
public static final int GL_DIFFUSE = 0x1201;
public static final int GL_SPECULAR = 0x1202;
public static final int GL_POSITION = 0x1203;
public static final int GL_SPOT_DIRECTION = 0x1204;
public static final int GL_SPOT_EXPONENT = 0x1205;
public static final int GL_SPOT_CUTOFF = 0x1206;
public static final int GL_CONSTANT_ATTENUATION = 0x1207;
public static final int GL_LINEAR_ATTENUATION = 0x1208;
public static final int GL_QUADRATIC_ATTENUATION = 0x1209;
private static final Light[] lights = new Light[8];
static {
for ( int i = 0; i < lights.length; i++ )
lights[i] = new Light();
System.arraycopy(new float[] { 1.0f, 1.0f, 1.0f, 1.0f }, 0, lights[0].diffuse, 0, 4);
System.arraycopy(new float[] { 1.0f, 1.0f, 1.0f, 1.0f }, 0, lights[0].specular, 0, 4);
}
private GLLight() {
}
public static void glLight(final int light, final int pname, final float v) {
if ( light < GL_LIGHT0 || GL_LIGHT7 < light )
throw new IllegalArgumentException("Invalid light specified: " + light);
final Light l = lights[light - GL_LIGHT0];
switch ( pname ) {
case GL_SPOT_EXPONENT:
l.s = v;
break;
case GL_SPOT_CUTOFF:
l.c = v;
break;
case GL_CONSTANT_ATTENUATION:
l.k0 = v;
break;
case GL_LINEAR_ATTENUATION:
l.k1 = v;
break;
case GL_QUADRATIC_ATTENUATION:
l.k2 = v;
break;
default:
throw new IllegalArgumentException("Invalid light parameter specified: " + pname);
}
}
public static void glLight(final int light, final int pname,
final float x, final float y, final float z) {
if ( light < GL_LIGHT0 || GL_LIGHT7 < light )
throw new IllegalArgumentException("Invalid light specified: " + light);
if ( pname != GL_SPOT_DIRECTION )
throw new IllegalArgumentException("Invalid light parameter specified: " + pname);
final float[] param = lights[light - GL_LIGHT0].direction;
param[0] = x;
param[1] = y;
param[2] = z;
}
private static float[] getParam4f(final int light, final int pname) {
if ( light < GL_LIGHT0 || GL_LIGHT7 < light )
throw new IllegalArgumentException("Invalid light specified: " + light);
final Light l = lights[light - GL_LIGHT0];
switch ( pname ) {
case GL_AMBIENT:
return l.ambient;
case GL_DIFFUSE:
return l.diffuse;
case GL_SPECULAR:
return l.specular;
case GL_POSITION:
return l.position;
default:
throw new IllegalArgumentException("Invalid light parameter specified: " + pname);
}
}
public static void glLight(final int light, final int pname,
final float x, final float y, final float z, final float w) {
final float[] param = getParam4f(light, pname);
param[0] = x;
param[1] = y;
param[2] = z;
param[3] = w;
}
public static void setUniform1f(final int location, final int light, final int pname) {
if ( light < GL_LIGHT0 || GL_LIGHT7 < light )
throw new IllegalArgumentException("Invalid light specified: " + light);
final Light l = lights[light - GL_LIGHT0];
switch ( pname ) {
case GL_SPOT_EXPONENT:
glUniform1f(location, l.s);
break;
case GL_SPOT_CUTOFF:
glUniform1f(location, l.c);
break;
case GL_CONSTANT_ATTENUATION:
glUniform1f(location, l.k0);
break;
case GL_LINEAR_ATTENUATION:
glUniform1f(location, l.k1);
break;
case GL_QUADRATIC_ATTENUATION:
glUniform1f(location, l.k2);
break;
default:
throw new IllegalArgumentException("Invalid light parameter specified: " + pname);
}
}
public static void setUniform3f(final int location, final int light, final int pname) {
if ( pname != GL_SPOT_DIRECTION )
throw new IllegalArgumentException("Invalid light parameter specified: " + pname);
final float[] param = lights[light - GL_LIGHT0].direction;
glUniform3f(location, param[0], param[1], param[2]);
}
public static void setUniform4f(final int location, final int light, final int pname) {
final float[] param = getParam4f(light, pname);
glUniform4f(location, param[0], param[1], param[2], param[3]);
}
private static class Light {
float[] ambient = { 0.0f, 0.0f, 0.0f, 1.0f };
float[] diffuse = { 0.0f, 0.0f, 0.0f, 1.0f };
float[] specular = { 0.0f, 0.0f, 0.0f, 1.0f };
float[] position = { 0.0f, 0.0f, 1.0f, 0.0f };
float[] direction = { 0.0f, 0.0f, -1.0f };
float s, c = 180.0f;
float k0 = 1.0f, k1, k2;
}
}

View file

@ -0,0 +1,163 @@
package org.lwjgl.test.opengles.util;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import java.util.Stack;
import static java.lang.Math.*;
/** Emulates the matrix stack in fixed-function OpenGL. */
public final class GLMatrix {
public static final int GL_MODELVIEW = 0x1700;
public static final int GL_PROJECTION = 0x1701;
private static final float PI = (float)Math.PI;
/** The model/view matrix stack. */
private static final Stack<Matrix4f> mvMatrixStack = new Stack<Matrix4f>();
/** The projection matrix stack. */
private static final Stack<Matrix4f> pMatrixStack = new Stack<Matrix4f>();
private static final Matrix4f m4f = new Matrix4f();
private static final Vector3f v3f = new Vector3f();
private static int mode = GL_MODELVIEW;
static {
mvMatrixStack.push(new Matrix4f());
pMatrixStack.push(new Matrix4f());
}
private GLMatrix() {
}
private static Stack<Matrix4f> getCurrentStack() {
switch ( mode ) {
case GL_MODELVIEW:
return mvMatrixStack;
case GL_PROJECTION:
return pMatrixStack;
default:
return null; // Cannot happen
}
}
private static Matrix4f getCurrentMatrix() {
return getCurrentStack().peek();
}
public static void glMatrixMode(final int mode) {
if ( mode != GL_MODELVIEW && mode != GL_PROJECTION )
throw new IllegalArgumentException("Invalid matrix mode specified: " + mode);
GLMatrix.mode = mode;
}
public static void glPushMatrix() {
final Stack<Matrix4f> stack = getCurrentStack();
stack.push(new Matrix4f(stack.peek()));
}
public static void glPopMatrix() {
final Stack<Matrix4f> stack = getCurrentStack();
if ( stack.size() == 1 )
throw new IllegalStateException("The last matrix in the stack cannot be popped.");
getCurrentStack().pop();
}
public static void glLoadIdentity() {
final Matrix4f m = getCurrentMatrix();
m.setIdentity();
}
public static void glLoadMatrix(final Matrix4f s) {
getCurrentMatrix().load(s);
}
public static void glMultMatrix(final Matrix4f m) {
final Matrix4f c = getCurrentMatrix();
Matrix4f.mul(c, m, c);
}
public static void glTranslatef(final float x, final float y, final float z) {
final Matrix4f m = getCurrentMatrix();
v3f.set(x, y, z);
m.translate(v3f);
}
public static void glRotatef(final float angle, final float x, final float y, final float z) {
final Matrix4f m = getCurrentMatrix();
v3f.set(x, y, z);
m.rotate((float)toRadians(angle), v3f);
}
public static void glOrtho(final float l, final float r, final float b, final float t, final float n, final float f) {
final Matrix4f m = m4f;
m.setIdentity();
m.m00 = 2.0f / (r - l);
m.m30 = -(r + l) / (r - l);
m.m11 = 2.0f / (t - b);
m.m31 = -(t + b) / (t - b);
m.m22 = -2.0f / (f - n);
m.m32 = -(f + n) / (f - n);
glMultMatrix(m);
}
public static void glFrustum(final float l, final float r, final float b, final float t, final float n, final float f) {
final Matrix4f m = m4f;
m.setIdentity();
m.m00 = 2.0f * n / (r - l);
m.m20 = (r + l) / (r - l);
m.m11 = 2.0f * n / (t - b);
m.m21 = (t + b) / (t - b);
m.m22 = -(f + n) / (f - n);
m.m32 = -(2.0f * f * n) / (f - n);
m.m23 = -1.0f;
m.m33 = 0.0f;
glMultMatrix(m);
}
public static void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
final float radians = fovy / 2.0f * PI / 180.0f;
final float deltaZ = zFar - zNear;
final float sine = (float)sin(radians);
if ( (deltaZ == 0) || (sine == 0) || (aspect == 0) ) {
return;
}
final float cotangent = (float)cos(radians) / sine;
final Matrix4f m = m4f;
m.setIdentity();
m.m00 = cotangent / aspect;
m.m11 = cotangent;
m.m22 = -(zFar + zNear) / deltaZ;
m.m23 = -1.0f;
m.m32 = -2 * zNear * zFar / deltaZ;
m.m33 = 0.0f;
glMultMatrix(m);
}
public static void glGetMatrix(final Matrix4f d) {
d.load(getCurrentMatrix());
}
}

View file

@ -0,0 +1,9 @@
package org.lwjgl.test.opengles.util;
public interface GLObject {
int getID();
void destroy();
}

View file

@ -0,0 +1,78 @@
package org.lwjgl.test.opengles.util;
import org.lwjgl.test.opengles.util.BufferObjectArray;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import static org.lwjgl.opengles.GLES20.*;
public class Geometry {
protected BufferObjectArray bo;
protected final List<DrawCommand> drawCommands = new ArrayList<DrawCommand>(4);
public Geometry() {
}
public Geometry(final FloatBuffer buffer) {
update(buffer);
}
public void update(final FloatBuffer buffer) {
if ( bo != null )
destroy();
bo = new BufferObjectArray(GL_STATIC_DRAW, buffer);
}
public void bind() {
bo.enable();
}
public void draw() {
for ( DrawCommand command : drawCommands )
command.draw();
}
public void destroy() {
bo.destroy();
bo = null;
drawCommands.clear();
}
public int addDrawCommand(final int mode, final int first, final int count) {
drawCommands.add(new DrawCommand(mode, first, count));
return count;
}
public static float sin(final float r) {
return (float)Math.sin(r);
}
public static float cos(final float r) {
return (float)Math.cos(r);
}
protected static class DrawCommand {
private int mode;
private int first;
private int count;
private DrawCommand(final int mode, final int first, final int count) {
this.mode = mode;
this.first = first;
this.count = count;
}
void draw() {
glDrawArrays(mode, first, count);
}
}
}

View file

@ -0,0 +1,58 @@
package org.lwjgl.test.opengles.util;
import org.lwjgl.BufferUtils;
import java.nio.FloatBuffer;
/**
* Utility class that emulates immediate mode vertex data submission.
* Can be used to create VBO data.
*/
public final class ImmediateModeBuffer {
private FloatBuffer buffer;
public ImmediateModeBuffer(final int startSize) {
this.buffer = BufferUtils.createFloatBuffer(startSize);
}
private void checkSize(final int count) {
while ( buffer.remaining() < count ) {
final FloatBuffer newBuffer = BufferUtils.createFloatBuffer(buffer.capacity() << 1);
buffer.flip();
newBuffer.put(buffer);
buffer = newBuffer;
}
}
public FloatBuffer getBuffer() {
buffer.flip();
return buffer;
}
public void glVertex2f(final float x, final float y) {
checkSize(2);
buffer.put(x).put(y);
}
public void glVertex3f(final float x, final float y, final float z) {
checkSize(3);
buffer.put(x).put(y).put(z);
}
public void glVertex4f(final float x, final float y, final float z, final float w) {
checkSize(4);
buffer.put(x).put(y).put(z).put(w);
}
public void glNormal3f(final float x, final float y, final float z) {
checkSize(3);
buffer.put(x).put(y).put(z);
}
public void glTexCoord2f(final float s, final float t) {
checkSize(2);
buffer.put(s).put(t);
}
}

View file

@ -0,0 +1,98 @@
package org.lwjgl.test.opengles.util;
import org.lwjgl.BufferUtils;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import static org.lwjgl.opengles.GLES20.*;
public class Shader implements GLObject {
protected static ByteBuffer fileBuffer = BufferUtils.createByteBuffer(1024 * 10);
private int type;
private int ID;
public Shader() {
}
public Shader(final int type, final CharSequence source) {
createFromSource(type, source);
}
public int getID() {
return ID;
}
public int getType() {
return type;
}
public void destroy() {
if ( ID == 0 )
throw new IllegalStateException("The shader has not been created");
glDeleteShader(ID);
ID = 0;
}
public void createFromFile(final int type, final ClassLoader loader, final String file) throws IOException {
final InputStream inputStream = loader.getResourceAsStream(file);
if ( inputStream == null )
throw new IllegalArgumentException("A shader source file could not be found: " + file);
final BufferedInputStream stream = new BufferedInputStream(inputStream);
byte character;
while ( (character = (byte)stream.read()) != -1 )
fileBuffer.put(character);
fileBuffer.flip();
stream.close();
final byte[] array = new byte[fileBuffer.remaining()];
fileBuffer.get(array);
final String source = new String(array);
fileBuffer.clear();
createFromSource(type, source);
}
public void createFromSource(final int type, final CharSequence source) {
if ( ID != 0 )
throw new IllegalStateException("The shader has already been created");
this.type = type;
this.ID = glCreateShader(type);
glShaderSource(ID, source);
glCompileShader(ID);
if ( glGetShader(ID, GL_COMPILE_STATUS) == GL_FALSE ) {
printInfoLog();
destroy();
throw new RuntimeException("A compilation error occured in a shader.");
}
}
public void printInfoLog() {
if ( ID == 0 )
throw new IllegalStateException("The shader has not been created");
final int logLength = glGetShader(ID, GL_INFO_LOG_LENGTH);
if ( logLength <= 1 )
return;
System.out.println("\nInfo Log of Shader Object: " + ID);
System.out.println("--------------------------");
System.out.println(glGetShaderInfoLog(ID, logLength));
}
}

View file

@ -0,0 +1,82 @@
package org.lwjgl.test.opengles.util;
import static org.lwjgl.opengles.GLES20.*;
public class ShaderProgram implements GLObject {
private final int ID;
public ShaderProgram(final Shader... shaders) {
this.ID = glCreateProgram();
for ( Shader shader : shaders )
glAttachShader(ID, shader.getID());
glLinkProgram(ID);
if ( glGetProgram(ID, GL_LINK_STATUS) == GL_FALSE ) {
printInfoLog();
destroy();
throw new RuntimeException("Failed to link a Shader Program: " + ID);
}
}
public void validate() {
glValidateProgram(ID);
final boolean error = glGetProgram(ID, GL_VALIDATE_STATUS) == GL_FALSE;
if ( error ) {
printInfoLog();
throw new RuntimeException("Failed to validate a Shader Program.");
}
}
public int getID() {
return ID;
}
public void destroy() {
glDeleteProgram(ID);
}
public void enable() {
glUseProgram(ID);
}
public static void disable() {
glUseProgram(0);
}
public int getUniformLocation(final String uniform) {
final int location = glGetUniformLocation(ID, uniform);
if ( location == -1 )
throw new IllegalArgumentException("Invalid uniform name specified: " + uniform);
return location;
}
public int getAttributeLocation(final String attrib) {
final int location = glGetAttribLocation(ID, attrib);
if ( location == -1 )
throw new IllegalArgumentException("Invalid attribute name specified: " + attrib);
return location;
}
private void printInfoLog() {
final int logLength = glGetProgram(ID, GL_INFO_LOG_LENGTH);
System.out.println(logLength);
if ( logLength <= 1 )
return;
System.out.println("\nInfo Log of Shader Program: " + ID);
System.out.println("-------------------");
System.out.println(glGetProgramInfoLog(ID, logLength));
System.out.println("-------------------");
}
}

View file

@ -0,0 +1,414 @@
package org.lwjgl.test.opengles.util;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import static org.lwjgl.opengles.GLES20.*;
/** VBO implementation of GLU Sphere. */
public final class Sphere {
/* QuadricNormal */
public static final int GLU_SMOOTH = 100000;
public static final int GLU_FLAT = 100001;
public static final int GLU_NONE = 100002;
/* QuadricDrawStyle */
public static final int GLU_POINT = 100010;
public static final int GLU_LINE = 100011;
public static final int GLU_FILL = 100012;
public static final int GLU_SILHOUETTE = 100013;
/* QuadricOrientation */
public static final int GLU_OUTSIDE = 100020;
public static final int GLU_INSIDE = 100021;
static final float PI = (float)Math.PI;
private int drawStyle;
private int orientation;
private boolean textureFlag;
private int normals;
private BufferObjectArray bo;
private final List<DrawCommand> drawCommands = new ArrayList<DrawCommand>(4);
public Sphere() {
this(GLU_FILL, GLU_OUTSIDE, false, GLU_SMOOTH);
}
public Sphere(final int drawStyle, final int orientation, final boolean textureFlag, final int normals) {
setDrawStyle(drawStyle);
setOrientation(orientation);
setTextureFlag(textureFlag);
setNormals(normals);
}
public Sphere(final float radius, final int slices, final int stacks) {
this();
updateGeometry(radius, slices, stacks);
}
public Sphere(final float radius, final int slices, final int stacks,
final int drawStyle, final int orientation, final boolean textureFlag, final int normals) {
this(drawStyle, orientation, textureFlag, normals);
updateGeometry(radius, slices, stacks);
}
public void updateGeometry(final float radius, final int slices, final int stacks) {
if ( bo != null )
destroy();
bo = new BufferObjectArray(GL_STATIC_DRAW, createBuffer(radius, slices, stacks));
}
public void bind() {
bo.enable();
}
public void draw() {
for ( DrawCommand command : drawCommands )
command.draw();
}
public void destroy() {
bo.destroy();
bo = null;
drawCommands.clear();
}
/**
* specifies the draw style for quadrics.
* <p/>
* The legal values are as follows:
* <p/>
* GLU.FILL: Quadrics are rendered with polygon primitives. The polygons
* are drawn in a counterclockwise fashion with respect to
* their normals (as defined with glu.quadricOrientation).
* <p/>
* GLU.LINE: Quadrics are rendered as a set of lines.
* <p/>
* GLU.SILHOUETTE: Quadrics are rendered as a set of lines, except that edges
* separating coplanar faces will not be drawn.
* <p/>
* GLU.POINT: Quadrics are rendered as a set of points.
*
* @param drawStyle The drawStyle to set
*/
public void setDrawStyle(int drawStyle) {
switch ( drawStyle ) {
case GLU_FILL:
case GLU_LINE:
case GLU_SILHOUETTE:
case GLU_POINT:
break;
default:
throw new IllegalArgumentException("Invalid draw style specified: " + drawStyle);
}
this.drawStyle = drawStyle;
}
/**
* specifies what kind of normals are desired for quadrics.
* The legal values are as follows:
* <p/>
* GLU.NONE: No normals are generated.
* <p/>
* GLU.FLAT: One normal is generated for every facet of a quadric.
* <p/>
* GLU.SMOOTH: One normal is generated for every vertex of a quadric. This
* is the default.
*
* @param normals The normals to set
*/
public void setNormals(int normals) {
switch ( normals ) {
case GLU_NONE:
case GLU_FLAT:
case GLU_SMOOTH:
break;
default:
throw new IllegalArgumentException("Invalid normal kind specified: " + normals);
}
this.normals = normals;
}
/**
* specifies what kind of orientation is desired for.
* The orientation values are as follows:
* <p/>
* GLU.OUTSIDE: Quadrics are drawn with normals pointing outward.
* <p/>
* GLU.INSIDE: Normals point inward. The default is GLU.OUTSIDE.
* <p/>
* Note that the interpretation of outward and inward depends on the quadric
* being drawn.
*
* @param orientation The orientation to set
*/
public void setOrientation(int orientation) {
if ( orientation != GLU_OUTSIDE && orientation != GLU_INSIDE )
throw new IllegalArgumentException("Invalid orientation specified: " + orientation);
this.orientation = orientation;
}
/**
* specifies if texture coordinates should be generated for
* quadrics rendered with qobj. If the value of textureCoords is true,
* then texture coordinates are generated, and if textureCoords is false,
* they are not.. The default is false.
* <p/>
* The manner in which texture coordinates are generated depends upon the
* specific quadric rendered.
*
* @param textureFlag The textureFlag to set
*/
public void setTextureFlag(boolean textureFlag) {
this.textureFlag = textureFlag;
}
/**
* Returns the drawStyle.
*
* @return int
*/
public int getDrawStyle() {
return drawStyle;
}
/**
* Returns the normals.
*
* @return int
*/
public int getNormals() {
return normals;
}
/**
* Returns the orientation.
*
* @return int
*/
public int getOrientation() {
return orientation;
}
/**
* Returns the textureFlag.
*
* @return boolean
*/
public boolean getTextureFlag() {
return textureFlag;
}
private static float sin(final float r) {
return (float)Math.sin(r);
}
private static float cos(final float r) {
return (float)Math.cos(r);
}
private int addDrawCommand(final int mode, final int first, final int count) {
drawCommands.add(new DrawCommand(mode, first, count));
return count;
}
/**
* draws a sphere of the given radius centered around the origin.
* The sphere is subdivided around the z axis into slices and along the z axis
* into stacks (similar to lines of longitude and latitude).
* <p/>
* If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then
* any normals generated point away from the center of the sphere. Otherwise,
* they point toward the center of the sphere.
* <p/>
* If texturing is turned on (with glu.quadricTexture), then texture
* coordinates are generated so that t ranges from 0.0 at z=-radius to 1.0 at
* z=radius (t increases linearly along longitudinal lines), and s ranges from
* 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75
* at the -x axis, and back to 1.0 at the +y axis.
*/
public FloatBuffer createBuffer(float radius, int slices, int stacks) {
float rho, theta;
float x, y, z;
float s, t, ds, dt;
int i, j;
final boolean normals = this.normals != GLU_NONE;
final float nsign = this.orientation == GLU_INSIDE ? -1.0f : 1.0f;
final float drho = PI / stacks;
final float dtheta = 2.0f * PI / slices;
final ImmediateModeBuffer imb = new ImmediateModeBuffer(16 * 1024); // TODO: We can calculate this to avoid re-allocs
int lastDrawIndex = 0;
if ( this.drawStyle == GLU_FILL ) {
if ( !this.textureFlag ) {
lastDrawIndex += addDrawCommand(GL_TRIANGLE_FAN, lastDrawIndex, slices + 2);
// draw +Z end as a triangle fan
imb.glNormal3f(0.0f, 0.0f, 1.0f);
imb.glVertex3f(0.0f, 0.0f, nsign * radius);
for ( j = 0; j <= slices; j++ ) {
theta = (j == slices) ? 0.0f : j * dtheta;
x = -sin(theta) * sin(drho);
y = cos(theta) * sin(drho);
z = nsign * cos(drho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
imb.glVertex3f(x * radius, y * radius, z * radius);
}
}
ds = 1.0f / slices;
dt = 1.0f / stacks;
t = 1.0f; // because loop now runs from 0
final int imin, imax;
if ( this.textureFlag ) {
imin = 0;
imax = stacks;
} else {
imin = 1;
imax = stacks - 1;
}
// draw intermediate stacks as quad strips
for ( i = imin; i < imax; i++ ) {
lastDrawIndex += addDrawCommand(GL_TRIANGLE_STRIP, lastDrawIndex, (slices + 1) * 2);
rho = i * drho;
s = 0.0f;
for ( j = 0; j <= slices; j++ ) {
theta = (j == slices) ? 0.0f : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
if ( textureFlag )
imb.glTexCoord2f(s, t);
imb.glVertex3f(x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
if ( textureFlag )
imb.glTexCoord2f(s, t - dt);
s += ds;
imb.glVertex3f(x * radius, y * radius, z * radius);
}
t -= dt;
}
if ( !this.textureFlag ) {
lastDrawIndex += addDrawCommand(GL_TRIANGLE_FAN, lastDrawIndex, slices + 2);
// draw -Z end as a triangle fan
imb.glNormal3f(0.0f, 0.0f, -1.0f);
imb.glVertex3f(0.0f, 0.0f, -radius * nsign);
rho = PI - drho;
s = 1.0f;
for ( j = slices; j >= 0; j-- ) {
theta = (j == slices) ? 0.0f : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
s -= ds;
imb.glVertex3f(x * radius, y * radius, z * radius);
}
}
} else if ( this.drawStyle == GLU_LINE || this.drawStyle == GLU_SILHOUETTE ) {
// draw stack lines
for ( i = 1; i < stacks; i++ ) { // stack line at i==stacks-1 was missing here
lastDrawIndex += addDrawCommand(GL_LINE_LOOP, lastDrawIndex, slices);
rho = i * drho;
for ( j = 0; j < slices; j++ ) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
imb.glVertex3f(x * radius, y * radius, z * radius);
}
}
// draw slice lines
for ( j = 0; j < slices; j++ ) {
lastDrawIndex += addDrawCommand(GL_LINE_STRIP, lastDrawIndex, stacks + 1);
theta = j * dtheta;
for ( i = 0; i <= stacks; i++ ) {
rho = i * drho;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
imb.glVertex3f(x * radius, y * radius, z * radius);
}
}
} else if ( this.drawStyle == GLU_POINT ) {
lastDrawIndex += addDrawCommand(GL_POINTS, lastDrawIndex, 2 + (stacks - 2) * slices);
// top and bottom-most points
if ( normals )
imb.glNormal3f(0.0f, 0.0f, nsign);
imb.glVertex3f(0.0f, 0.0f, radius);
if ( normals )
imb.glNormal3f(0.0f, 0.0f, -nsign);
imb.glVertex3f(0.0f, 0.0f, -radius);
// loop over stacks
for ( i = 1; i < stacks - 1; i++ ) {
rho = i * drho;
for ( j = 0; j < slices; j++ ) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
if ( normals )
imb.glNormal3f(x * nsign, y * nsign, z * nsign);
imb.glVertex3f(x * radius, y * radius, z * radius);
}
}
}
return imb.getBuffer();
}
private static class DrawCommand {
private int mode;
private int first;
private int count;
private DrawCommand(final int mode, final int first, final int count) {
this.mode = mode;
this.first = first;
this.count = count;
}
void draw() {
glDrawArrays(mode, first, count);
}
}
}

View file

@ -59,7 +59,8 @@ public class FieldsGenerator {
PrimitiveType.Kind field_kind = field_type_prim.getKind();
if ( field_kind != PrimitiveType.Kind.INT
&& field_kind != PrimitiveType.Kind.LONG
&& field_kind != PrimitiveType.Kind.FLOAT ) {
&& field_kind != PrimitiveType.Kind.FLOAT
&& field_kind != PrimitiveType.Kind.BYTE ) {
throw new RuntimeException("Field " + field.getSimpleName() + " is not of type 'int', 'long' or 'float'");
}
} else if ( "java.lang.String".equals(field_type.toString()) ) {
@ -85,6 +86,8 @@ public class FieldsGenerator {
field_value_string = "0x" + Long.toHexString((Long)field.getConstantValue()).toUpperCase() + 'L';
} else if ( field_value_class.equals(Float.class) ) {
field_value_string = field.getConstantValue() + "f";
} else if ( value.getClass().equals(Byte.class) ) {
field_value_string = "0x" + Integer.toHexString((Byte)field.getConstantValue()).toUpperCase();
} else if ( field_value_class.equals(String.class) ) {
field_value_string = "\"" + field.getConstantValue() + "\"";
} else {

View file

@ -209,17 +209,21 @@ public class JavaMethodsGenerator {
return false;
}
private static void printBufferObjectCheck(PrintWriter writer, BufferKind kind, Mode mode) {
private static void printBufferObjectCheck(PrintWriter writer, BufferKind kind, Mode mode, boolean context_specific) {
String bo_check_method_name = kind.toString();
writer.print("\t\t" + Utils.CHECKS_CLASS_NAME + ".ensure" + bo_check_method_name);
if (mode == Mode.BUFFEROBJECT)
writer.print("enabled");
else
writer.print("disabled");
writer.println("(caps);");
if ( context_specific )
writer.println("(caps);");
else
writer.println("();");
}
private static void printBufferObjectChecks(PrintWriter writer, MethodDeclaration method, Mode mode) {
private static void printBufferObjectChecks(PrintWriter writer, MethodDeclaration method, Mode mode, boolean context_specific) {
EnumSet<BufferKind> check_set = EnumSet.noneOf(BufferKind.class);
for (ParameterDeclaration param : method.getParameters()) {
BufferObject bo_annotation = param.getAnnotation(BufferObject.class);
@ -227,7 +231,7 @@ public class JavaMethodsGenerator {
check_set.add(bo_annotation.value());
}
for (BufferKind kind : check_set)
printBufferObjectCheck(writer, kind, mode);
printBufferObjectCheck(writer, kind, mode, context_specific);
}
private static void printMethodWithMultiType(AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, InterfaceDeclaration interface_decl, MethodDeclaration method, Map<ParameterDeclaration, TypeInfo> typeinfos_instance, Mode mode, boolean generate_error_checks, boolean context_specific) {
@ -272,9 +276,9 @@ public class JavaMethodsGenerator {
final Code code_annotation = method.getAnnotation(Code.class);
if (code_annotation != null && code_annotation.value().length() > 0)
writer.println(code_annotation.value());
printBufferObjectChecks(writer, method, mode);
printBufferObjectChecks(writer, method, mode, context_specific);
printParameterChecks(writer, method, typeinfos_instance, mode, generate_error_checks);
printParameterCaching(writer, interface_decl, method, mode);
printParameterCaching(writer, interface_decl, method, mode, context_specific);
if ( code_annotation != null && code_annotation.javaBeforeNative().length() > 0 )
writer.println(code_annotation.javaBeforeNative());
@ -526,7 +530,7 @@ public class JavaMethodsGenerator {
writer.print(param.getSimpleName());
if (check_annotation != null && check_annotation.canBeNull())
writer.print(" != null ? " + param.getSimpleName());
if ( type == PointerBuffer.class )
if ( type == PointerBuffer.class && param.getAnnotation(NativeType.class).value().endsWith("void") )
writer.print(".positionByte()");
else
writer.print(".position()");
@ -588,7 +592,7 @@ public class JavaMethodsGenerator {
return first_parameter;
}
private static void printParameterCaching(PrintWriter writer, InterfaceDeclaration interface_decl, MethodDeclaration method, Mode mode) {
private static void printParameterCaching(PrintWriter writer, InterfaceDeclaration interface_decl, MethodDeclaration method, Mode mode, boolean context_specific) {
for (ParameterDeclaration param : method.getParameters()) {
Class java_type = Utils.getJavaType(param.getType());
CachedReference cachedReference = param.getAnnotation(CachedReference.class);
@ -596,7 +600,11 @@ public class JavaMethodsGenerator {
cachedReference != null &&
(mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null) &&
param.getAnnotation(Result.class) == null) {
writer.print("\t\tif ( LWJGLUtil.CHECKS ) " + "StateTracker.getReferences(caps).");
writer.print("\t\tif ( LWJGLUtil.CHECKS ) StateTracker.");
if ( context_specific )
writer.print("getReferences(caps).");
else
writer.print("getTracker().");
if(cachedReference.name().length() > 0) {
writer.print(cachedReference.name());
} else {

View file

@ -308,7 +308,7 @@ public class NativeMethodStubsGenerator {
if (Buffer.class.isAssignableFrom(java_type) || java_type.equals(CharSequence.class) || java_type.equals(CharSequence[].class) || PointerBuffer.class.isAssignableFrom(java_type) ) {
boolean explicitly_byte_sized = java_type.equals(Buffer.class) ||
translator.getAnnotationType().equals(type_map.getVoidType()) ||
param.getAnnotation(NativeType.class) != null;
(param.getAnnotation(NativeType.class) != null && param.getAnnotation(NativeType.class).value().endsWith("void"));
if (explicitly_byte_sized)
writer.print("(((char *)");
if (method.getAnnotation(GenerateAutos.class) != null || (check_annotation != null && check_annotation.canBeNull())) {

View file

@ -94,7 +94,7 @@ public class RegisterStubsGenerator {
continue;
if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null)
signature += "I";
signature += "J";
else
signature += getTypeSignature(param.getType(), true);
}

View file

@ -0,0 +1,12 @@
package org.lwjgl.util.generator.opengl;
import org.lwjgl.util.generator.NativeType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@NativeType
@Target({ ElementType.PARAMETER, ElementType.METHOD })
public @interface EGLint64NV {
}

View file

@ -0,0 +1,12 @@
package org.lwjgl.util.generator.opengl;
import org.lwjgl.util.generator.NativeType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@NativeType
@Target({ ElementType.PARAMETER, ElementType.METHOD })
public @interface EGLuint64NV {
}

View file

@ -0,0 +1,308 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.util.generator.opengl;
import org.lwjgl.util.generator.*;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.type.InterfaceType;
/**
* Generator visitor for the context capabilities generator tool
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3334 $
* $Id: ContextCapabilitiesGenerator.java 3334 2010-04-22 23:21:48Z spasi $
*/
public class GLESCapabilitiesGenerator {
private static final String STUBS_LOADED_NAME = "loaded_stubs";
private static final String ALL_INIT_METHOD_NAME = "initAllStubs";
private static final String POINTER_INITIALIZER_POSTFIX = "_initNativeFunctionAddresses";
private static final String CACHED_EXTS_VAR_NAME = "supported_extensions";
private static final String EXTENSION_PREFIX = "GL_";
private static final String CORE_PREFIX = "Open";
public static void generateClassPrologue(PrintWriter writer, boolean context_specific, boolean generate_error_checks) {
writer.println("public class " + Utils.CONTEXT_CAPS_CLASS_NAME + " {");
writer.println("\tstatic final boolean DEBUG = " + Boolean.toString(generate_error_checks) + ";");
writer.println();
if ( !context_specific ) {
writer.println("\tprivate static boolean " + STUBS_LOADED_NAME + ";");
}
}
public static void generateInitializerPrologue(PrintWriter writer) {
writer.println("\t" + Utils.CONTEXT_CAPS_CLASS_NAME + "() throws LWJGLException {");
writer.println("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = " + ALL_INIT_METHOD_NAME + "();");
}
private static String translateFieldName(String interface_name) {
if ( interface_name.startsWith("GL") )
return CORE_PREFIX + interface_name;
else
return EXTENSION_PREFIX + interface_name;
}
public static void generateSuperClassAdds(PrintWriter writer, InterfaceDeclaration d) {
Collection<InterfaceType> super_interfaces = d.getSuperinterfaces();
if ( super_interfaces.size() > 1 )
throw new RuntimeException(d + " extends more than one other interface");
if ( super_interfaces.size() == 1 ) {
InterfaceType super_interface = super_interfaces.iterator().next();
writer.print("\t\tif (" + CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.println(translateFieldName(d.getSimpleName()) + "\"))");
writer.print("\t\t\t");
generateAddExtension(writer, super_interface.getDeclaration());
}
}
public static void generateInitializer(PrintWriter writer, InterfaceDeclaration d) {
String translated_field_name = translateFieldName(d.getSimpleName());
writer.print("\t\tthis." + translated_field_name + " = ");
writer.print(CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translated_field_name + "\")");
Collection<InterfaceType> super_interfaces = d.getSuperinterfaces();
if ( super_interfaces.size() > 1 )
throw new RuntimeException(d + " extends more than one other interface");
if ( super_interfaces.size() == 1 ) {
InterfaceType super_interface = super_interfaces.iterator().next();
writer.println();
writer.print("\t\t\t&& " + CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(super_interface.getDeclaration().getSimpleName()) + "\")");
}
Alias alias_annotation = d.getAnnotation(Alias.class);
if ( alias_annotation != null ) {
writer.println();
writer.print("\t\t\t|| " + CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(alias_annotation.value()) + "\")");
}
writer.println(";");
}
private static String getAddressesInitializerName(String class_name) {
return class_name + POINTER_INITIALIZER_POSTFIX;
}
public static void generateInitStubsPrologue(PrintWriter writer, boolean context_specific) {
writer.println("\tprivate Set<String> " + ALL_INIT_METHOD_NAME + "() throws LWJGLException {");
if ( context_specific ) {
// Load the basic pointers we need to detect OpenGL version and supported extensions.
writer.println("\t\tglGetError = GLContext.getFunctionAddress(\"glGetError\");");
writer.println("\t\tglGetString = GLContext.getFunctionAddress(\"glGetString\");");
}
// Get the supported extensions set.
writer.println("\t\tGLContext.setCapabilities(this);");
writer.println("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = new HashSet<String>(256);");
if ( !context_specific )
writer.println("\t\tGLContext.doInitNativeStubs(GLES20.class);");
writer.println("\t\tGLContext.getSupportedExtensions(" + CACHED_EXTS_VAR_NAME + ");");
if ( !context_specific ) {
writer.println("\t\tif (" + STUBS_LOADED_NAME + ")");
writer.println("\t\t\treturn " + CACHED_EXTS_VAR_NAME + ";");
} else {
writer.println("\t\tif (!" + getAddressesInitializerName("GLES20") + "())");
writer.println("\t\t\tthrow new LWJGLException(\"GL ES 2.0 not supported\");");
}
}
public static void generateInitStubsEpilogue(PrintWriter writer, boolean context_specific) {
if ( !context_specific )
writer.println("\t\t" + STUBS_LOADED_NAME + " = true;");
writer.println("\t\treturn " + CACHED_EXTS_VAR_NAME + ";");
writer.println("\t}");
}
public static void generateUnloadStubs(PrintWriter writer, InterfaceDeclaration d) {
// TODO: Remove GLES
if ( d.getMethods().size() > 0 && !d.getSimpleName().startsWith("GLES") ) {
writer.print("\t\tGLContext.resetNativeStubs(" + Utils.getSimpleClassName(d));
writer.println(".class);");
}
}
public static void generateInitStubs(PrintWriter writer, InterfaceDeclaration d, boolean context_specific) {
if ( d.getMethods().size() > 0 ) {
if ( context_specific ) {
final Alias alias_annotation = d.getAnnotation(Alias.class);
if ( d.getAnnotation(ForceInit.class) != null )
writer.println("\t\t" + CACHED_EXTS_VAR_NAME + ".add(\"" + translateFieldName(d.getSimpleName()) + "\");");
writer.print("\t\tif (");
if ( alias_annotation != null )
writer.print("(");
writer.print(CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(d.getSimpleName()) + "\")");
if ( alias_annotation != null ) {
writer.print(" || " + CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(alias_annotation.value()) + "\"))");
}
writer.print(" && !" + getAddressesInitializerName(d.getSimpleName()) + "(");
if ( d.getAnnotation(Dependent.class) != null )
writer.print("supported_extensions");
if ( alias_annotation != null ) {
writer.println(")) {");
writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \"");
writer.println(translateFieldName(alias_annotation.value()) + "\");");
} else
writer.println("))");
writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \"");
writer.println(translateFieldName(d.getSimpleName()) + "\");");
if ( alias_annotation != null )
writer.println("\t\t}");
} else {
writer.print("\t\tGLContext." + Utils.STUB_INITIALIZER_NAME + "(" + Utils.getSimpleClassName(d));
writer.println(".class, " + CACHED_EXTS_VAR_NAME + ", \"" + translateFieldName(d.getSimpleName()) + "\");");
}
}
}
private static void generateAddExtension(PrintWriter writer, InterfaceDeclaration d) {
writer.print(CACHED_EXTS_VAR_NAME + ".add(\"");
writer.println(translateFieldName(d.getSimpleName()) + "\");");
}
public static void generateAddressesInitializers(PrintWriter writer, InterfaceDeclaration d) {
Iterator<? extends MethodDeclaration> methods = d.getMethods().iterator();
if ( !methods.hasNext() )
return;
writer.print("\tprivate boolean " + getAddressesInitializerName(d.getSimpleName()) + "(");
boolean optional;
Dependent dependent = d.getAnnotation(Dependent.class);
if ( dependent != null ) {
writer.print("Set<String> supported_extensions");
}
Alias alias_annotation = d.getAnnotation(Alias.class);
boolean aliased = alias_annotation != null && alias_annotation.postfix().length() > 0;
writer.println(") {");
writer.println("\t\treturn ");
boolean first = true;
while ( methods.hasNext() ) {
MethodDeclaration method = methods.next();
if ( method.getAnnotation(Alternate.class) != null )
continue;
if ( !first )
writer.println(" &");
else
first = false;
optional = method.getAnnotation(Optional.class) != null;
dependent = method.getAnnotation(Dependent.class);
writer.print("\t\t\t(");
if ( optional )
writer.print('(');
if ( dependent != null ) {
if ( dependent.value().indexOf(',') == -1 )
writer.print("!supported_extensions.contains(\"" + dependent.value() + "\") || ");
else {
writer.print("!(false");
for ( String extension : dependent.value().split(",") )
writer.print(" || supported_extensions.contains(\"" + extension + "\")");
writer.print(") || ");
}
}
if ( dependent != null )
writer.print('(');
writer.print(Utils.getFunctionAddressName(d, method) + " = ");
PlatformDependent platform_dependent = method.getAnnotation(PlatformDependent.class);
if ( platform_dependent != null ) {
EnumSet<Platform> platform_set = EnumSet.copyOf(Arrays.asList(platform_dependent.value()));
writer.print("GLContext.getPlatformSpecificFunctionAddress(\"");
writer.print(Platform.ALL.getPrefix() + "\", ");
writer.print("new String[]{");
Iterator<Platform> platforms = platform_set.iterator();
while ( platforms.hasNext() ) {
writer.print("\"" + platforms.next().getOSPrefix() + "\"");
if ( platforms.hasNext() )
writer.print(", ");
}
writer.print("}, new String[]{");
platforms = platform_set.iterator();
while ( platforms.hasNext() ) {
writer.print("\"" + platforms.next().getPrefix() + "\"");
if ( platforms.hasNext() )
writer.print(", ");
}
writer.print("}, ");
} else if ( aliased ) {
writer.print("GLContext.getFunctionAddress(new String[] {\"" + method.getSimpleName() + "\",\"" + method.getSimpleName() + alias_annotation.postfix() + "\"})) != 0");
} else
writer.print("GLContext.getFunctionAddress(");
if ( !aliased )
writer.print("\"" + method.getSimpleName() + "\")) != 0");
if ( dependent != null )
writer.print(')');
if ( optional )
writer.print(" || true)");
}
writer.println(";");
writer.println("\t}");
writer.println();
}
public static void generateSymbolAddresses(PrintWriter writer, InterfaceDeclaration d) {
boolean first = true;
for ( final MethodDeclaration method : d.getMethods() ) {
if ( method.getAnnotation(Alternate.class) != null || method.getAnnotation(Reuse.class) != null )
continue;
if ( first ) {
writer.println("\t// " + d.getSimpleName());
first = false;
}
writer.println("\tint " + Utils.getFunctionAddressName(d, method) + ";");
}
}
public static void generateField(PrintWriter writer, InterfaceDeclaration d) {
writer.println("\tpublic final boolean " + translateFieldName(d.getSimpleName()) + ";");
}
}

View file

@ -0,0 +1,184 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.util.generator.opengl;
import org.lwjgl.util.generator.Utils;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.util.DeclarationFilter;
import static java.util.Collections.*;
/**
* Generator tool for creating the ContexCapabilities class
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3316 $
* $Id: ContextGeneratorProcessorFactory.java 3316 2010-04-09 23:57:40Z spasi $
*/
public class GLESGeneratorProcessorFactory implements AnnotationProcessorFactory, RoundCompleteListener {
private static boolean first_round = true;
// Process any set of annotations
private static final Collection<String> supportedAnnotations =
unmodifiableCollection(Arrays.asList("*"));
public Collection<String> supportedAnnotationTypes() {
return supportedAnnotations;
}
public Collection<String> supportedOptions() {
return unmodifiableCollection(Arrays.asList("-Acontextspecific", "-Ageneratechecks"));
}
public void roundComplete(RoundCompleteEvent event) {
first_round = false;
}
public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds, AnnotationProcessorEnvironment env) {
// Only process the initial types, not the generated ones
if ( first_round ) {
env.addListener(this);
return new GeneratorProcessor(env);
} else
return AnnotationProcessors.NO_OP;
}
private static class GeneratorProcessor implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
GeneratorProcessor(AnnotationProcessorEnvironment env) {
this.env = env;
}
public void process() {
Map<String, String> options = env.getOptions();
boolean generate_error_checks = options.containsKey("-Ageneratechecks");
boolean context_specific = options.containsKey("-Acontextspecific");
try {
generateContextCapabilitiesSource(context_specific, generate_error_checks);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void generateContextCapabilitiesSource(boolean context_specific, boolean generate_error_checks) throws IOException {
PrintWriter writer = env.getFiler().createTextFile(Filer.Location.SOURCE_TREE, "org.lwjgl.opengles", new File(Utils.CONTEXT_CAPS_CLASS_NAME + ".java"), null);
writer.println("/* MACHINE GENERATED FILE, DO NOT EDIT */");
writer.println();
writer.println("package org.lwjgl.opengles;");
writer.println();
writer.println("import org.lwjgl.LWJGLException;");
writer.println("import org.lwjgl.LWJGLUtil;");
writer.println("import java.util.Set;");
writer.println("import java.util.HashSet;");
writer.println();
GLESCapabilitiesGenerator.generateClassPrologue(writer, context_specific, generate_error_checks);
DeclarationFilter filter = DeclarationFilter.getFilter(InterfaceDeclaration.class);
Collection<TypeDeclaration> interface_decls = filter.filter(env.getSpecifiedTypeDeclarations());
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
if ( Utils.isFinal(interface_decl) )
GLESCapabilitiesGenerator.generateField(writer, interface_decl);
}
writer.println();
if ( context_specific ) {
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
GLESCapabilitiesGenerator.generateSymbolAddresses(writer, interface_decl);
}
writer.println();
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
GLESCapabilitiesGenerator.generateAddressesInitializers(writer, interface_decl);
}
writer.println();
}
if ( context_specific ) {
writer.println("\tprivate static void remove(Set supported_extensions, String extension) {");
writer.println("\t\tLWJGLUtil.log(extension + \" was reported as available but an entry point is missing\");");
writer.println("\t\tsupported_extensions.remove(extension);");
writer.println("\t}\n");
}
GLESCapabilitiesGenerator.generateInitStubsPrologue(writer, context_specific);
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
GLESCapabilitiesGenerator.generateSuperClassAdds(writer, interface_decl);
}
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
if ( interface_decl.getSimpleName().startsWith("GLES") )
continue;
GLESCapabilitiesGenerator.generateInitStubs(writer, interface_decl, context_specific);
}
GLESCapabilitiesGenerator.generateInitStubsEpilogue(writer, context_specific);
writer.println();
writer.println("\tstatic void unloadAllStubs() {");
if ( !context_specific ) {
writer.println("\t\tif (!loaded_stubs)");
writer.println("\t\t\treturn;");
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
GLESCapabilitiesGenerator.generateUnloadStubs(writer, interface_decl);
}
writer.println("\t\tloaded_stubs = false;");
}
writer.println("\t}");
writer.println();
GLESCapabilitiesGenerator.generateInitializerPrologue(writer);
for ( TypeDeclaration typedecl : interface_decls ) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
if ( Utils.isFinal(interface_decl) )
GLESCapabilitiesGenerator.generateInitializer(writer, interface_decl);
}
writer.println("\t}");
writer.println("}");
writer.close();
}
}
}

View file

@ -0,0 +1,287 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.util.generator.opengl;
/**
*
* OpenGL sepcific generator behaviour
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 3287 $
* $Id: GLTypeMap.java 3287 2010-03-14 23:24:40Z spasi $
*/
import org.lwjgl.util.generator.NativeTypeTranslator;
import org.lwjgl.util.generator.Signedness;
import org.lwjgl.util.generator.TypeMap;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.nio.*;
import java.util.HashMap;
import java.util.Map;
import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.type.PrimitiveType;
public class GLESTypeMap implements TypeMap {
private static final Map<Class<? extends Annotation>, PrimitiveType.Kind> native_types_to_primitive;
static {
native_types_to_primitive = new HashMap<Class<? extends Annotation>, PrimitiveType.Kind>();
native_types_to_primitive.put(GLbitfield.class, PrimitiveType.Kind.INT);
native_types_to_primitive.put(GLclampf.class, PrimitiveType.Kind.FLOAT);
native_types_to_primitive.put(GLfloat.class, PrimitiveType.Kind.FLOAT);
native_types_to_primitive.put(GLint.class, PrimitiveType.Kind.INT);
native_types_to_primitive.put(GLshort.class, PrimitiveType.Kind.SHORT);
native_types_to_primitive.put(GLsizeiptr.class, PrimitiveType.Kind.LONG);
native_types_to_primitive.put(GLuint.class, PrimitiveType.Kind.INT);
native_types_to_primitive.put(GLboolean.class, PrimitiveType.Kind.BOOLEAN);
native_types_to_primitive.put(GLchar.class, PrimitiveType.Kind.BYTE);
native_types_to_primitive.put(GLhalf.class, PrimitiveType.Kind.SHORT);
native_types_to_primitive.put(GLsizei.class, PrimitiveType.Kind.INT);
native_types_to_primitive.put(GLushort.class, PrimitiveType.Kind.SHORT);
native_types_to_primitive.put(GLbyte.class, PrimitiveType.Kind.BYTE);
native_types_to_primitive.put(GLenum.class, PrimitiveType.Kind.INT);
native_types_to_primitive.put(GLintptr.class, PrimitiveType.Kind.LONG);
native_types_to_primitive.put(GLubyte.class, PrimitiveType.Kind.BYTE);
native_types_to_primitive.put(GLvoid.class, PrimitiveType.Kind.BYTE);
native_types_to_primitive.put(EGLint64NV.class, PrimitiveType.Kind.LONG);
native_types_to_primitive.put(EGLuint64NV.class, PrimitiveType.Kind.LONG);
}
public PrimitiveType.Kind getPrimitiveTypeFromNativeType(Class<? extends Annotation> native_type) {
PrimitiveType.Kind kind = native_types_to_primitive.get(native_type);
if ( kind == null )
throw new RuntimeException("Unsupported type " + native_type);
return kind;
}
public void printCapabilitiesInit(final PrintWriter writer) {
writer.println("\t\tContextCapabilities caps = GLContext.getCapabilities();");
}
public String getCapabilities() {
return "caps";
}
public void printErrorCheckMethod(final PrintWriter writer, final MethodDeclaration method, final String tabs) {
writer.println(tabs + "Util.checkGLError();");
}
public String getRegisterNativesFunctionName() {
return "extgl_InitializeClass";
}
public Signedness getSignednessFromType(Class<? extends Annotation> type) {
if ( GLuint.class.equals(type) )
return Signedness.UNSIGNED;
else if ( GLint.class.equals(type) )
return Signedness.SIGNED;
else if ( GLushort.class.equals(type) )
return Signedness.UNSIGNED;
else if ( GLshort.class.equals(type) )
return Signedness.SIGNED;
else if ( GLubyte.class.equals(type) )
return Signedness.UNSIGNED;
else if ( GLbyte.class.equals(type) )
return Signedness.SIGNED;
else if ( EGLuint64NV.class.equals(type) )
return Signedness.UNSIGNED;
else if ( EGLint64NV.class.equals(type) )
return Signedness.SIGNED;
else
return Signedness.NONE;
}
public String translateAnnotation(Class annotation_type) {
if ( annotation_type.equals(GLuint.class) || annotation_type.equals(GLint.class) )
return "i";
else if ( annotation_type.equals(GLushort.class) || annotation_type.equals(GLshort.class) )
return "s";
else if ( annotation_type.equals(GLubyte.class) || annotation_type.equals(GLbyte.class) )
return "b";
else if ( annotation_type.equals(GLfloat.class) )
return "f";
else if ( annotation_type.equals(GLhalf.class) )
return "h";
else if ( annotation_type.equals(GLboolean.class) || annotation_type.equals(GLvoid.class) )
return "";
else if ( annotation_type.equals(EGLuint64NV.class) || annotation_type.equals(EGLint64NV.class) )
return "l";
else
throw new RuntimeException(annotation_type + " is not allowed");
}
public Class<? extends Annotation> getNativeTypeFromPrimitiveType(PrimitiveType.Kind kind) {
Class<? extends Annotation> type;
switch ( kind ) {
case INT:
type = GLint.class;
break;
case FLOAT:
type = GLfloat.class;
break;
case SHORT:
type = GLshort.class;
break;
case BYTE:
type = GLbyte.class;
break;
case BOOLEAN:
type = GLboolean.class;
break;
default:
throw new RuntimeException(kind + " is not allowed");
}
return type;
}
public Class<? extends Annotation> getVoidType() {
return GLvoid.class;
}
public Class<? extends Annotation> getStringElementType() {
return GLubyte.class;
}
public Class<? extends Annotation> getStringArrayType() {
return GLchar.class;
}
public Class<? extends Annotation> getByteBufferArrayType() {
return GLubyte.class;
}
private static Class[] getValidBufferTypes(Class type) {
if ( type.equals(IntBuffer.class) )
return new Class[] { GLbitfield.class, GLenum.class, GLint.class, GLsizei.class, GLuint.class, GLvoid.class };
else if ( type.equals(FloatBuffer.class) )
return new Class[] { GLclampf.class, GLfloat.class };
else if ( type.equals(ByteBuffer.class) )
return new Class[] { GLboolean.class, GLbyte.class, GLchar.class, GLubyte.class, GLvoid.class };
else if ( type.equals(ShortBuffer.class) )
return new Class[] { GLhalf.class, GLshort.class, GLushort.class };
else if ( type.equals(LongBuffer.class) )
return new Class[] { EGLint64NV.class, EGLuint64NV.class };
else
return new Class[] { };
}
private static Class[] getValidPrimitiveTypes(Class type) {
if ( type.equals(long.class) )
return new Class[] { GLintptr.class, GLsizeiptr.class, EGLuint64NV.class, EGLint64NV.class };
else if ( type.equals(int.class) )
return new Class[] { GLbitfield.class, GLenum.class, GLint.class, GLuint.class, GLsizei.class };
else if ( type.equals(float.class) )
return new Class[] { GLclampf.class, GLfloat.class };
else if ( type.equals(short.class) )
return new Class[] { GLhalf.class, GLshort.class, GLushort.class };
else if ( type.equals(byte.class) )
return new Class[] { GLbyte.class, GLchar.class, GLubyte.class };
else if ( type.equals(boolean.class) )
return new Class[] { GLboolean.class };
else if ( type.equals(void.class) )
return new Class[] { GLvoid.class, GLreturn.class };
else
return new Class[] { };
}
public String getTypedefPostfix() {
return "GL_APICALL ";
}
public String getFunctionPrefix() {
return "GL_APIENTRY";
}
public void printNativeIncludes(PrintWriter writer) {
writer.println("#include \"extgl.h\"");
}
public Class[] getValidAnnotationTypes(Class type) {
Class[] valid_types;
if ( Buffer.class.isAssignableFrom(type) )
valid_types = getValidBufferTypes(type);
else if ( type.isPrimitive() )
valid_types = getValidPrimitiveTypes(type);
else if ( String.class.equals(type) )
valid_types = new Class[] { GLubyte.class };
else if ( org.lwjgl.PointerWrapper.class.isAssignableFrom(type) )
valid_types = new Class[] { org.lwjgl.PointerWrapper.class };
else if ( void.class.equals(type) )
valid_types = new Class[] { GLreturn.class };
else
valid_types = new Class[] { };
return valid_types;
}
public Class<? extends Annotation> getInverseType(Class<? extends Annotation> type) {
if ( GLuint.class.equals(type) )
return GLint.class;
else if ( GLint.class.equals(type) )
return GLuint.class;
else if ( GLushort.class.equals(type) )
return GLshort.class;
else if ( GLshort.class.equals(type) )
return GLushort.class;
else if ( GLubyte.class.equals(type) )
return GLbyte.class;
else if ( GLbyte.class.equals(type) )
return GLubyte.class;
else
return null;
}
public String getAutoTypeFromAnnotation(AnnotationMirror annotation) {
Class annotation_class = NativeTypeTranslator.getClassFromType(annotation.getAnnotationType());
if ( annotation_class.equals(GLint.class) )
return "GLES20.GL_INT";
else if ( annotation_class.equals(GLbyte.class) )
return "GLES20.GL_BYTE";
else if ( annotation_class.equals(GLshort.class) )
return "GLES20.GL_SHORT";
if ( annotation_class.equals(GLuint.class) )
return "GLES20.GL_UNSIGNED_INT";
else if ( annotation_class.equals(GLubyte.class) )
return "GLES20.GL_UNSIGNED_BYTE";
else if ( annotation_class.equals(GLushort.class) )
return "GLES20.GL_UNSIGNED_SHORT";
else if ( annotation_class.equals(GLfloat.class) )
return "GLES20.GL_FLOAT";
else
return null;
}
}

View file

@ -52,6 +52,11 @@ public class Matrix4f extends Matrix implements Serializable {
setIdentity();
}
public Matrix4f(final Matrix4f src) {
super();
load(src);
}
/**
* Returns a string representation of this matrix
*/
@ -278,6 +283,23 @@ public class Matrix4f extends Matrix implements Serializable {
return this;
}
/**
* Store the rotation portion of this matrix in a float buffer. The matrix is stored in column
* major (openGL) order.
* @param buf The buffer to store this matrix in
*/
public Matrix store3f(FloatBuffer buf) {
buf.put(m00);
buf.put(m01);
buf.put(m02);
buf.put(m10);
buf.put(m11);
buf.put(m12);
buf.put(m20);
buf.put(m21);
buf.put(m22);
return this;
}
/**
* Add two matrices together and place the result in a third matrix.