All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.badlogic.gdx.backends.jogamp.JoglGraphicsBase Maven / Gradle / Ivy

There is a newer version: 1.9.9
Show newest version
/*******************************************************************************
 * Copyright 2015 See AUTHORS file.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.backends.jogamp;

import com.badlogic.gdx.Application;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.backends.jogamp.audio.OpenALAudio;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.glutils.GLVersion;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;

public abstract class JoglGraphicsBase implements Graphics, GLEventListener {
	static GLVersion glVersion;
	static int major, minor;

	ApplicationListener listener = null;
	boolean created = false;
	String extensions;
	volatile boolean isContinuous = true;
	volatile boolean requestRendering = false;
	volatile boolean cancelRendering = false;
	GLAutoDrawable canvas;
	Animator animator;
	long frameStart = System.nanoTime();
	long lastFrameTime = System.nanoTime();
	float deltaTime = 0;
	int fps;
	int frames;
	boolean paused = true, disposed = false;
	JoglApplicationConfiguration config;

	long frameId = -1;
	GL20 gl20;
	GL30 gl30;


	void initialize (ApplicationListener listener, JoglApplicationConfiguration config) {
		if (listener == null) throw new GdxRuntimeException("RenderListener must not be null");
		this.listener = listener;
		this.config = config;

		GLCapabilities caps;
		if(config.useGL30){
			caps = new GLCapabilities(GLProfile.getMaxProgrammable(true));
		} else {
			// GL20 uses glDrawElements and glVertexAttribPointer
			// passing buffers, these functions are removed in
			// OpenGL core only contexts.
			// libgdx shaders are currently only GLES2 and GL2
			// compatible.
			// try to allocate an GL2 or GLES2 context.
			// core only contexts are not supported for GL20.
			try {
				caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
			} catch (GLException e) {
				caps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
			}
		}

		caps.setRedBits(config.r);
		caps.setGreenBits(config.g);
		caps.setBlueBits(config.b);
		caps.setAlphaBits(config.a);
		caps.setDepthBits(config.depth);
		caps.setStencilBits(config.stencil);
		caps.setNumSamples(config.samples);
		caps.setSampleBuffers(config.samples > 0);
		caps.setDoubleBuffered(true);

		canvas = createCanvas(caps);

		//canvas.setBackground(Color.BLACK);
		canvas.addGLEventListener(this);
	}

	protected abstract GLAutoDrawable createCanvas(final GLCapabilities caps);

	GLAutoDrawable getCanvas () {
		return canvas;
	}

	void create () {
		disposed = false;
		frameStart = System.nanoTime();
		lastFrameTime = frameStart;
		deltaTime = 0;
		animator = new Animator(canvas);
		animator.start();
	}

	void pause () {
		cancelRendering = true;
		synchronized (this) {
			paused = true;
		}
		// stop here if not yet fully initialized
		if (!created) return;
		animator.stop();
		if (!canvas.getContext().isCurrent()) {
		    canvas.getContext().makeCurrent();
		}
		listener.pause();
	}

	void resume () {
		paused = false;
		cancelRendering = false;
		if (!created) return;
		if (!canvas.getContext().isCurrent()) {
	    canvas.getContext().makeCurrent();
	  }
		listener.resume();
		frameStart = System.nanoTime();
		lastFrameTime = frameStart;
		deltaTime = 0;
		animator.resume();
		animator.setRunAsFastAsPossible(true);
		animator.start();
	}

	@Override
	public void init (GLAutoDrawable drawable) {
		initializeGLInstances(drawable);
		initGLVersion();
		setVSync(config.vSyncEnabled);

		if (!created) {
			listener.create();
			synchronized (this) {
				paused = false;
			}
			created = true;
		}
	}

	@Override
	public void reshape (GLAutoDrawable drawable, int x, int y, int width, int height) {
		listener.resize(width, height);
	}

	@Override
	public void display (GLAutoDrawable arg0) {
		synchronized (this) {
			if (!paused) {
				final boolean shouldRender = ((JoglApplicationBase)Gdx.app).executeRunnables() | shouldRender();
				if (shouldRender && !cancelRendering) {
					updateTime();
					((JoglInput) (Gdx.input)).processEvents();
					frameId++;
					listener.render();
					if (Gdx.audio != null) {
					    ((OpenALAudio) Gdx.audio).update();
					}
				}
			}
		}
	}

	void destroy () {
		if (!canvas.getContext().isCurrent()) {
		    canvas.getContext().makeCurrent();
		}

		pause();
		// prevent animator from touching the dying drawable context
		animator.remove(canvas);
		disposed = true;
		listener.dispose();
		canvas.destroy();
	}

	@Override
	public void setVSync (boolean vsync) {
		if (vsync)
			canvas.getGL().setSwapInterval(1);
		else
			canvas.getGL().setSwapInterval(0);
	}

	@Override
	public void dispose(GLAutoDrawable drawable) {
		setContinuousRendering(true);
		created = false;
	}

	@Override
	public boolean supportsExtension (String extension) {
		if (extensions == null) extensions = Gdx.gl.glGetString(GL20.GL_EXTENSIONS);
		return extensions.contains(extension);
	}

	@Override
	public void setContinuousRendering (boolean isContinuous) {
		this.isContinuous = isContinuous;
	}

	@Override
	public boolean isContinuousRendering () {
		return isContinuous;
	}

	@Override
	public void requestRendering () {
		synchronized (this) {
			requestRendering = true;
		}
	}

	public boolean shouldRender () {
		synchronized (this) {
			boolean rq = requestRendering;
			requestRendering = false;
			return rq || isContinuous /*|| isDirty()*/;
		}
	}

	@Override
	public BufferFormat getBufferFormat () {
		GLCapabilitiesImmutable caps = canvas.getChosenGLCapabilities();
		return new BufferFormat(caps.getRedBits(), caps.getGreenBits(), caps.getBlueBits(), caps.getAlphaBits(),
			caps.getDepthBits(), caps.getStencilBits(), caps.getNumSamples(), false);
	}

	void initializeGLInstances (GLAutoDrawable drawable) {
		major = drawable.getGL().getContext().getGLVersionNumber().getMajor();
		minor = drawable.getGL().getContext().getGLVersionNumber().getMinor();

		if (config.useGL30 && major >= 3) {
			gl30 = new JoglGL30();
			gl20 = gl30;
		} else {
			gl20 = new JoglGL20();
		}

		Gdx.gl = gl20;
		Gdx.gl20 = gl20;
		Gdx.gl30 = gl30;

		if (major <= 1)
			throw new GdxRuntimeException("OpenGL 2.0 or higher with the FBO extension is required. OpenGL version: " + major + "." + minor);
		if (major == 2 && !drawable.getGL().isGLES2Compatible()) {
			if (!supportsExtension("GL_EXT_framebuffer_object") && !supportsExtension("GL_ARB_framebuffer_object")) {
				final String vendor = drawable.getGL().glGetString(GL.GL_VENDOR);
				final String renderer = drawable.getGL().glGetString(GL.GL_RENDERER);
				final String version = drawable.getGL().glGetString(GL.GL_VERSION);
				final String glInfo = vendor + "\n" + renderer + "\n" + version;
				throw new GdxRuntimeException("OpenGL 2.0 or higher with the FBO extension is required. OpenGL version: " + major + "." + minor
					+ ", FBO extension: false" + (glInfo.isEmpty() ? "" : ("\n" + glInfo)));
			}
		}
	}

	@Override
	public float getPpiX () {
		return config.getScreenResolution();
	}

	@Override
	public float getPpiY () {
		return config.getScreenResolution();
	}

	@Override
	public float getPpcX () {
		return (config.getScreenResolution() / 2.54f);
	}

	@Override
	public float getPpcY () {
		return (config.getScreenResolution() / 2.54f);
	}

	@Override
	public float getDensity () {
		return (config.getScreenResolution() / 160f);
	}

	@Override
	public DisplayMode[] getDisplayModes () {
		return config.getDisplayModes();
	}

	void updateTime () {
		deltaTime = (System.nanoTime() - lastFrameTime) / 1000000000.0f;
		lastFrameTime = System.nanoTime();

		if (System.nanoTime() - frameStart > 1000000000) {
			fps = frames;
			frames = 0;
			frameStart = System.nanoTime();
		}
		frames++;
	}

	@Override
	public float getDeltaTime () {
		return deltaTime;
	}

	@Override
	public float getRawDeltaTime () {
		return deltaTime;
	}

	@Override
	public int getFramesPerSecond () {
		return fps;
	}

	@Override
	public GL20 getGL20 () {
		return gl20;
	}

	@Override
	public void setGL20 (GL20 gl20) {
		this.gl20 = gl20;
		if (gl30 == null) {
			Gdx.gl = gl20;
			Gdx.gl20 = gl20;
		}
	}

	@Override
	public GL30 getGL30 () {
		return gl30;
	}

	@Override
	public void setGL30 (GL30 gl30) {
		this.gl30 = gl30;
		if (gl30 != null) {
			this.gl20 = gl30;

			Gdx.gl = gl20;
			Gdx.gl20 = gl20;
			Gdx.gl30 = gl30;
		}
	}

	@Override
	public boolean isGL30Available () {
		return gl30 != null;
	}

	@Override
	public GraphicsType getType () {
		// TODO Change to JoGL when (if) it is available
		return GraphicsType.LWJGL;
	}

	@Override
	public long getFrameId() {
		return frameId;
	}

	@Override
	public int getBackBufferWidth() {
		return getWidth();
	}

	@Override
	public int getBackBufferHeight() {
		return getHeight ();
	}

	@Override
	public DisplayMode getDisplayMode() {
		return getDisplayMode(getMonitor());
	}

	@Override
	public GLVersion getGLVersion () {
		return glVersion;
	}

	private static void initGLVersion () {
		String versionString = GLContext.getCurrent().getGLVersionNumber().toString();
		String vendorString = GLContext.getCurrentGL().glGetString(GL.GL_VENDOR);
		String rendererString = GLContext.getCurrentGL().glGetString(GL.GL_RENDERER);
		glVersion = new GLVersion(Application.ApplicationType.Desktop, versionString, vendorString, rendererString);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy