Conflicts: jme3-core/src/main/java/com/jme3/material/RenderState.java jme3-core/src/main/java/com/jme3/renderer/opengl/GL.javacleanup_build_scripts
commit
cb61e760ce
@ -1,136 +0,0 @@ |
|||||||
package com.jme3.asset; |
|
||||||
|
|
||||||
import android.graphics.Bitmap; |
|
||||||
import android.graphics.BitmapFactory; |
|
||||||
import android.graphics.Matrix; |
|
||||||
import com.jme3.math.ColorRGBA; |
|
||||||
import com.jme3.texture.Image; |
|
||||||
import com.jme3.texture.Image.Format; |
|
||||||
import com.jme3.texture.image.ImageRaster; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* <code>AndroidImageInfo</code> is set in a jME3 image via the {@link Image#setEfficentData(java.lang.Object) } |
|
||||||
* method to retrieve a {@link Bitmap} when it is needed by the renderer. |
|
||||||
* User code may extend <code>AndroidImageInfo</code> and provide their own implementation of the |
|
||||||
* {@link AndroidImageInfo#loadBitmap()} method to acquire a bitmap by their own means. |
|
||||||
* |
|
||||||
* @author Kirill Vainer |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public class AndroidImageInfo extends ImageRaster { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName()); |
|
||||||
|
|
||||||
protected AssetInfo assetInfo; |
|
||||||
protected Bitmap bitmap; |
|
||||||
protected Format format; |
|
||||||
|
|
||||||
public AndroidImageInfo(AssetInfo assetInfo) { |
|
||||||
this.assetInfo = assetInfo; |
|
||||||
} |
|
||||||
|
|
||||||
public Bitmap getBitmap(){ |
|
||||||
if (bitmap == null || bitmap.isRecycled()){ |
|
||||||
try { |
|
||||||
loadBitmap(); |
|
||||||
} catch (IOException ex) { |
|
||||||
// If called first inside AssetManager, the error will propagate
|
|
||||||
// correctly. Assuming that if the first calls succeeds
|
|
||||||
// then subsequent calls will as well.
|
|
||||||
throw new AssetLoadException("Failed to load image " + assetInfo.getKey(), ex); |
|
||||||
} |
|
||||||
} |
|
||||||
return bitmap; |
|
||||||
} |
|
||||||
|
|
||||||
public void notifyBitmapUploaded() { |
|
||||||
// Default function is to recycle the bitmap.
|
|
||||||
if (bitmap != null && !bitmap.isRecycled()) { |
|
||||||
bitmap.recycle(); |
|
||||||
bitmap = null; |
|
||||||
logger.log(Level.FINE, "Bitmap was deleted. "); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public Format getFormat(){ |
|
||||||
return format; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getWidth() { |
|
||||||
return getBitmap().getWidth(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getHeight() { |
|
||||||
return getBitmap().getHeight(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setPixel(int x, int y, ColorRGBA color) { |
|
||||||
getBitmap().setPixel(x, y, color.asIntARGB()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ColorRGBA getPixel(int x, int y, ColorRGBA store) { |
|
||||||
if (store == null) { |
|
||||||
store = new ColorRGBA(); |
|
||||||
} |
|
||||||
store.fromIntARGB(getBitmap().getPixel(x, y)); |
|
||||||
return store; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Loads the bitmap directly from the asset info, possibly updating |
|
||||||
* or creating the image object. |
|
||||||
*/ |
|
||||||
protected void loadBitmap() throws IOException{ |
|
||||||
InputStream in = null; |
|
||||||
try { |
|
||||||
in = assetInfo.openStream(); |
|
||||||
bitmap = BitmapFactory.decodeStream(in); |
|
||||||
if (bitmap == null) { |
|
||||||
throw new IOException("Failed to load image: " + assetInfo.getKey().getName()); |
|
||||||
} |
|
||||||
} finally { |
|
||||||
if (in != null) { |
|
||||||
in.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
switch (bitmap.getConfig()) { |
|
||||||
case ALPHA_8: |
|
||||||
format = Image.Format.Alpha8; |
|
||||||
break; |
|
||||||
case ARGB_8888: |
|
||||||
format = Image.Format.RGBA8; |
|
||||||
break; |
|
||||||
case RGB_565: |
|
||||||
format = Image.Format.RGB565; |
|
||||||
break; |
|
||||||
default: |
|
||||||
// This should still work as long
|
|
||||||
// as renderer doesn't check format
|
|
||||||
// but just loads bitmap directly.
|
|
||||||
format = null; |
|
||||||
} |
|
||||||
|
|
||||||
TextureKey texKey = (TextureKey) assetInfo.getKey(); |
|
||||||
if (texKey.isFlipY()) { |
|
||||||
// Flip the image, then delete the old one.
|
|
||||||
Matrix flipMat = new Matrix(); |
|
||||||
flipMat.preScale(1.0f, -1.0f); |
|
||||||
Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false); |
|
||||||
bitmap.recycle(); |
|
||||||
bitmap = newBitmap; |
|
||||||
|
|
||||||
if (bitmap == null) { |
|
||||||
throw new IOException("Failed to flip image: " + texKey); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,533 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.audio.android; |
|
||||||
|
|
||||||
import android.app.Activity; |
|
||||||
import android.content.Context; |
|
||||||
import android.content.res.AssetFileDescriptor; |
|
||||||
import android.content.res.AssetManager; |
|
||||||
import android.media.AudioManager; |
|
||||||
import android.media.MediaPlayer; |
|
||||||
import android.media.SoundPool; |
|
||||||
import com.jme3.asset.AssetKey; |
|
||||||
import com.jme3.audio.*; |
|
||||||
import com.jme3.audio.AudioSource.Status; |
|
||||||
import com.jme3.audio.openal.ALAudioRenderer; |
|
||||||
import com.jme3.math.FastMath; |
|
||||||
import com.jme3.math.Vector3f; |
|
||||||
import java.io.IOException; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* This class is the android implementation for {@link AudioRenderer} |
|
||||||
* |
|
||||||
* @author larynx |
|
||||||
* @author plan_rich |
|
||||||
* |
|
||||||
* @deprecated No longer supported due to too many limitations. |
|
||||||
* Please use the generic {@link ALAudioRenderer} instead. |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public class AndroidMediaPlayerAudioRenderer implements AudioRenderer, |
|
||||||
SoundPool.OnLoadCompleteListener, MediaPlayer.OnCompletionListener { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidMediaPlayerAudioRenderer.class.getName()); |
|
||||||
private final static int MAX_NUM_CHANNELS = 16; |
|
||||||
private final HashMap<AudioSource, MediaPlayer> musicPlaying = new HashMap<AudioSource, MediaPlayer>(); |
|
||||||
private SoundPool soundPool = null; |
|
||||||
private final Vector3f listenerPosition = new Vector3f(); |
|
||||||
// For temp use
|
|
||||||
private final Vector3f distanceVector = new Vector3f(); |
|
||||||
private final AssetManager assetManager; |
|
||||||
private HashMap<Integer, AudioSource> soundpoolStillLoading = new HashMap<Integer, AudioSource>(); |
|
||||||
private Listener listener; |
|
||||||
private boolean audioDisabled = false; |
|
||||||
private final AudioManager manager; |
|
||||||
|
|
||||||
public AndroidMediaPlayerAudioRenderer(Activity context) { |
|
||||||
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); |
|
||||||
context.setVolumeControlStream(AudioManager.STREAM_MUSIC); |
|
||||||
assetManager = context.getAssets(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void initialize() { |
|
||||||
soundPool = new SoundPool(MAX_NUM_CHANNELS, AudioManager.STREAM_MUSIC, |
|
||||||
0); |
|
||||||
soundPool.setOnLoadCompleteListener(this); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void updateSourceParam(AudioSource src, AudioParam param) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (src.getChannel() < 0) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
switch (param) { |
|
||||||
case Position: |
|
||||||
if (!src.isPositional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
Vector3f pos = src.getPosition(); |
|
||||||
break; |
|
||||||
case Velocity: |
|
||||||
if (!src.isPositional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
Vector3f vel = src.getVelocity(); |
|
||||||
break; |
|
||||||
case MaxDistance: |
|
||||||
if (!src.isPositional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RefDistance: |
|
||||||
if (!src.isPositional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
break; |
|
||||||
case ReverbFilter: |
|
||||||
if (!src.isPositional() || !src.isReverbEnabled()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
break; |
|
||||||
case ReverbEnabled: |
|
||||||
if (!src.isPositional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (src.isReverbEnabled()) { |
|
||||||
updateSourceParam(src, AudioParam.ReverbFilter); |
|
||||||
} |
|
||||||
break; |
|
||||||
case IsPositional: |
|
||||||
break; |
|
||||||
case Direction: |
|
||||||
if (!src.isDirectional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
Vector3f dir = src.getDirection(); |
|
||||||
break; |
|
||||||
case InnerAngle: |
|
||||||
if (!src.isDirectional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
break; |
|
||||||
case OuterAngle: |
|
||||||
if (!src.isDirectional()) { |
|
||||||
return; |
|
||||||
} |
|
||||||
break; |
|
||||||
case IsDirectional: |
|
||||||
if (src.isDirectional()) { |
|
||||||
updateSourceParam(src, AudioParam.Direction); |
|
||||||
updateSourceParam(src, AudioParam.InnerAngle); |
|
||||||
updateSourceParam(src, AudioParam.OuterAngle); |
|
||||||
} else { |
|
||||||
} |
|
||||||
break; |
|
||||||
case DryFilter: |
|
||||||
if (src.getDryFilter() != null) { |
|
||||||
Filter f = src.getDryFilter(); |
|
||||||
if (f.isUpdateNeeded()) { |
|
||||||
// updateFilter(f);
|
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
case Looping: |
|
||||||
if (src.isLooping()) { |
|
||||||
} |
|
||||||
break; |
|
||||||
case Volume: |
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
if (mp != null) { |
|
||||||
mp.setVolume(src.getVolume(), src.getVolume()); |
|
||||||
} else { |
|
||||||
soundPool.setVolume(src.getChannel(), src.getVolume(), |
|
||||||
src.getVolume()); |
|
||||||
} |
|
||||||
|
|
||||||
break; |
|
||||||
case Pitch: |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void updateListenerParam(Listener listener, ListenerParam param) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
switch (param) { |
|
||||||
case Position: |
|
||||||
listenerPosition.set(listener.getLocation()); |
|
||||||
break; |
|
||||||
case Rotation: |
|
||||||
Vector3f dir = listener.getDirection(); |
|
||||||
Vector3f up = listener.getUp(); |
|
||||||
|
|
||||||
break; |
|
||||||
case Velocity: |
|
||||||
Vector3f vel = listener.getVelocity(); |
|
||||||
|
|
||||||
break; |
|
||||||
case Volume: |
|
||||||
// alListenerf(AL_GAIN, listener.getVolume());
|
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void update(float tpf) { |
|
||||||
float distance; |
|
||||||
float volume; |
|
||||||
|
|
||||||
// Loop over all mediaplayers
|
|
||||||
for (AudioSource src : musicPlaying.keySet()) { |
|
||||||
|
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
|
|
||||||
// Calc the distance to the listener
|
|
||||||
distanceVector.set(listenerPosition); |
|
||||||
distanceVector.subtractLocal(src.getPosition()); |
|
||||||
distance = FastMath.abs(distanceVector.length()); |
|
||||||
|
|
||||||
if (distance < src.getRefDistance()) { |
|
||||||
distance = src.getRefDistance(); |
|
||||||
} |
|
||||||
if (distance > src.getMaxDistance()) { |
|
||||||
distance = src.getMaxDistance(); |
|
||||||
} |
|
||||||
volume = src.getRefDistance() / distance; |
|
||||||
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData(); |
|
||||||
|
|
||||||
if (FastMath.abs(audioData.getCurrentVolume() - volume) > FastMath.FLT_EPSILON) { |
|
||||||
// Left / Right channel get the same volume by now, only
|
|
||||||
// positional
|
|
||||||
mp.setVolume(volume, volume); |
|
||||||
|
|
||||||
audioData.setCurrentVolume(volume); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void setListener(Listener listener) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (this.listener != null) { |
|
||||||
// previous listener no longer associated with current
|
|
||||||
// renderer
|
|
||||||
this.listener.setRenderer(null); |
|
||||||
} |
|
||||||
|
|
||||||
this.listener = listener; |
|
||||||
this.listener.setRenderer(this); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void cleanup() { |
|
||||||
// Cleanup sound pool
|
|
||||||
if (soundPool != null) { |
|
||||||
soundPool.release(); |
|
||||||
soundPool = null; |
|
||||||
} |
|
||||||
|
|
||||||
// Cleanup media player
|
|
||||||
for (AudioSource src : musicPlaying.keySet()) { |
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
{ |
|
||||||
mp.stop(); |
|
||||||
mp.release(); |
|
||||||
src.setStatus(Status.Stopped); |
|
||||||
} |
|
||||||
} |
|
||||||
musicPlaying.clear(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onCompletion(MediaPlayer mp) { |
|
||||||
if (mp.isPlaying()) { |
|
||||||
mp.seekTo(0); |
|
||||||
mp.stop(); |
|
||||||
} |
|
||||||
// XXX: This has bad performance -> maybe change overall structure of
|
|
||||||
// mediaplayer in this audiorenderer?
|
|
||||||
for (AudioSource src : musicPlaying.keySet()) { |
|
||||||
if (musicPlaying.get(src) == mp) { |
|
||||||
src.setStatus(Status.Stopped); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Plays using the {@link SoundPool} of Android. Due to hard limitation of |
|
||||||
* the SoundPool: After playing more instances of the sound you only have |
|
||||||
* the channel of the last played instance. |
|
||||||
* |
|
||||||
* It is not possible to get information about the state of the soundpool of |
|
||||||
* a specific streamid, so removing is not possilbe -> noone knows when |
|
||||||
* sound finished. |
|
||||||
*/ |
|
||||||
public void playSourceInstance(AudioSource src) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData(); |
|
||||||
|
|
||||||
if (!(audioData.getAssetKey() instanceof AudioKey)) { |
|
||||||
throw new IllegalArgumentException("Asset is not a AudioKey"); |
|
||||||
} |
|
||||||
|
|
||||||
AudioKey assetKey = (AudioKey) audioData.getAssetKey(); |
|
||||||
|
|
||||||
try { |
|
||||||
|
|
||||||
if (audioData.getId() < 0) { // found something to load
|
|
||||||
int soundId = soundPool.load( |
|
||||||
assetManager.openFd(assetKey.getName()), 1); |
|
||||||
audioData.setId(soundId); |
|
||||||
} |
|
||||||
|
|
||||||
int channel = soundPool.play(audioData.getId(), 1f, 1f, 1, 0, 1f); |
|
||||||
|
|
||||||
if (channel == 0) { |
|
||||||
soundpoolStillLoading.put(audioData.getId(), src); |
|
||||||
} else { |
|
||||||
if (src.getStatus() != Status.Stopped) { |
|
||||||
soundPool.stop(channel); |
|
||||||
src.setStatus(Status.Stopped); |
|
||||||
} |
|
||||||
src.setChannel(channel); // receive a channel at the last
|
|
||||||
setSourceParams(src); |
|
||||||
// playing at least
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
} catch (IOException e) { |
|
||||||
logger.log(Level.SEVERE, |
|
||||||
"Failed to load sound " + assetKey.getName(), e); |
|
||||||
audioData.setId(-1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { |
|
||||||
AudioSource src = soundpoolStillLoading.remove(sampleId); |
|
||||||
|
|
||||||
if (src == null) { |
|
||||||
logger.warning("Something went terribly wrong! onLoadComplete" |
|
||||||
+ " had sampleId which was not in the HashMap of loading items"); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
AudioData audioData = src.getAudioData(); |
|
||||||
|
|
||||||
// load was successfull
|
|
||||||
if (status == 0) { |
|
||||||
int channelIndex; |
|
||||||
channelIndex = soundPool.play(audioData.getId(), 1f, 1f, 1, 0, 1f); |
|
||||||
src.setChannel(channelIndex); |
|
||||||
setSourceParams(src); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void playSource(AudioSource src) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData(); |
|
||||||
|
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
if (mp == null) { |
|
||||||
mp = new MediaPlayer(); |
|
||||||
mp.setOnCompletionListener(this); |
|
||||||
mp.setAudioStreamType(AudioManager.STREAM_MUSIC); |
|
||||||
} |
|
||||||
|
|
||||||
try { |
|
||||||
if (src.getStatus() == Status.Stopped) { |
|
||||||
mp.reset(); |
|
||||||
AssetKey<?> key = audioData.getAssetKey(); |
|
||||||
|
|
||||||
AssetFileDescriptor afd = assetManager.openFd(key.getName()); // assetKey.getName()
|
|
||||||
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), |
|
||||||
afd.getLength()); |
|
||||||
mp.prepare(); |
|
||||||
setSourceParams(src, mp); |
|
||||||
src.setChannel(0); |
|
||||||
src.setStatus(Status.Playing); |
|
||||||
musicPlaying.put(src, mp); |
|
||||||
mp.start(); |
|
||||||
} else { |
|
||||||
mp.start(); |
|
||||||
} |
|
||||||
} catch (IllegalStateException e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} catch (Exception e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void setSourceParams(AudioSource src, MediaPlayer mp) { |
|
||||||
mp.setLooping(src.isLooping()); |
|
||||||
mp.setVolume(src.getVolume(), src.getVolume()); |
|
||||||
//src.getDryFilter();
|
|
||||||
} |
|
||||||
|
|
||||||
private void setSourceParams(AudioSource src) { |
|
||||||
soundPool.setLoop(src.getChannel(), src.isLooping() ? -1 : 0); |
|
||||||
soundPool.setVolume(src.getChannel(), src.getVolume(), src.getVolume()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Pause the current playing sounds. Both from the {@link SoundPool} and the |
|
||||||
* active {@link MediaPlayer}s |
|
||||||
*/ |
|
||||||
public void pauseAll() { |
|
||||||
if (soundPool != null) { |
|
||||||
soundPool.autoPause(); |
|
||||||
for (MediaPlayer mp : musicPlaying.values()) { |
|
||||||
if(mp.isPlaying()){ |
|
||||||
mp.pause(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Resume all paused sounds. |
|
||||||
*/ |
|
||||||
public void resumeAll() { |
|
||||||
if (soundPool != null) { |
|
||||||
soundPool.autoResume(); |
|
||||||
for (MediaPlayer mp : musicPlaying.values()) { |
|
||||||
mp.start(); //no resume -> api says call start to resume
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void pauseSource(AudioSource src) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
if (mp != null) { |
|
||||||
mp.pause(); |
|
||||||
src.setStatus(Status.Paused); |
|
||||||
} else { |
|
||||||
int channel = src.getChannel(); |
|
||||||
if (channel != -1) { |
|
||||||
soundPool.pause(channel); // is not very likley to make
|
|
||||||
} // something useful :)
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void stopSource(AudioSource src) { |
|
||||||
if (audioDisabled) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
// can be stream or buffer -> so try to get mediaplayer
|
|
||||||
// if there is non try to stop soundpool
|
|
||||||
MediaPlayer mp = musicPlaying.get(src); |
|
||||||
if (mp != null) { |
|
||||||
mp.stop(); |
|
||||||
mp.reset(); |
|
||||||
src.setStatus(Status.Stopped); |
|
||||||
} else { |
|
||||||
int channel = src.getChannel(); |
|
||||||
if (channel != -1) { |
|
||||||
soundPool.pause(channel); // is not very likley to make
|
|
||||||
// something useful :)
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void deleteAudioData(AudioData ad) { |
|
||||||
|
|
||||||
for (AudioSource src : musicPlaying.keySet()) { |
|
||||||
if (src.getAudioData() == ad) { |
|
||||||
MediaPlayer mp = musicPlaying.remove(src); |
|
||||||
mp.stop(); |
|
||||||
mp.release(); |
|
||||||
src.setStatus(Status.Stopped); |
|
||||||
src.setChannel(-1); |
|
||||||
ad.setId(-1); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (ad.getId() > 0) { |
|
||||||
soundPool.unload(ad.getId()); |
|
||||||
ad.setId(-1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setEnvironment(Environment env) { |
|
||||||
// not yet supported
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void deleteFilter(Filter filter) { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public float getSourcePlaybackTime(AudioSource src) { |
|
||||||
throw new UnsupportedOperationException("Not supported yet."); |
|
||||||
} |
|
||||||
} |
|
@ -1,591 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2015 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.renderer.android; |
|
||||||
|
|
||||||
import android.graphics.Bitmap; |
|
||||||
import android.opengl.ETC1; |
|
||||||
import android.opengl.ETC1Util.ETC1Texture; |
|
||||||
import android.opengl.GLES20; |
|
||||||
import android.opengl.GLUtils; |
|
||||||
import com.jme3.asset.AndroidImageInfo; |
|
||||||
import com.jme3.renderer.RendererException; |
|
||||||
import com.jme3.texture.Image; |
|
||||||
import com.jme3.texture.Image.Format; |
|
||||||
import com.jme3.util.BufferUtils; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* @deprecated Should not be used anymore. Use {@link GLRenderer} instead. |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public class TextureUtil { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(TextureUtil.class.getName()); |
|
||||||
//TODO Make this configurable through appSettings
|
|
||||||
public static boolean ENABLE_COMPRESSION = true; |
|
||||||
private static boolean NPOT = false; |
|
||||||
private static boolean ETC1support = false; |
|
||||||
private static boolean DXT1 = false; |
|
||||||
private static boolean DEPTH24_STENCIL8 = false; |
|
||||||
private static boolean DEPTH_TEXTURE = false; |
|
||||||
private static boolean RGBA8 = false; |
|
||||||
|
|
||||||
// Same constant used by both GL_ARM_rgba8 and GL_OES_rgb8_rgba8.
|
|
||||||
private static final int GL_RGBA8 = 0x8058; |
|
||||||
|
|
||||||
private static final int GL_DXT1 = 0x83F0; |
|
||||||
private static final int GL_DXT1A = 0x83F1; |
|
||||||
|
|
||||||
private static final int GL_DEPTH_STENCIL_OES = 0x84F9; |
|
||||||
private static final int GL_UNSIGNED_INT_24_8_OES = 0x84FA; |
|
||||||
private static final int GL_DEPTH24_STENCIL8_OES = 0x88F0; |
|
||||||
|
|
||||||
public static void loadTextureFeatures(String extensionString) { |
|
||||||
ETC1support = extensionString.contains("GL_OES_compressed_ETC1_RGB8_texture"); |
|
||||||
DEPTH24_STENCIL8 = extensionString.contains("GL_OES_packed_depth_stencil"); |
|
||||||
NPOT = extensionString.contains("GL_IMG_texture_npot") |
|
||||||
|| extensionString.contains("GL_OES_texture_npot") |
|
||||||
|| extensionString.contains("GL_NV_texture_npot_2D_mipmap"); |
|
||||||
|
|
||||||
DXT1 = extensionString.contains("GL_EXT_texture_compression_dxt1"); |
|
||||||
DEPTH_TEXTURE = extensionString.contains("GL_OES_depth_texture"); |
|
||||||
|
|
||||||
RGBA8 = extensionString.contains("GL_ARM_rgba8") || |
|
||||||
extensionString.contains("GL_OES_rgb8_rgba8"); |
|
||||||
|
|
||||||
logger.log(Level.FINE, "Supports ETC1? {0}", ETC1support); |
|
||||||
logger.log(Level.FINE, "Supports DEPTH24_STENCIL8? {0}", DEPTH24_STENCIL8); |
|
||||||
logger.log(Level.FINE, "Supports NPOT? {0}", NPOT); |
|
||||||
logger.log(Level.FINE, "Supports DXT1? {0}", DXT1); |
|
||||||
logger.log(Level.FINE, "Supports DEPTH_TEXTURE? {0}", DEPTH_TEXTURE); |
|
||||||
logger.log(Level.FINE, "Supports RGBA8? {0}", RGBA8); |
|
||||||
} |
|
||||||
|
|
||||||
private static void buildMipmap(Bitmap bitmap, boolean compress) { |
|
||||||
int level = 0; |
|
||||||
int height = bitmap.getHeight(); |
|
||||||
int width = bitmap.getWidth(); |
|
||||||
|
|
||||||
logger.log(Level.FINEST, " - Generating mipmaps for bitmap using SOFTWARE"); |
|
||||||
|
|
||||||
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); |
|
||||||
|
|
||||||
while (height >= 1 || width >= 1) { |
|
||||||
//First of all, generate the texture from our bitmap and set it to the according level
|
|
||||||
if (compress) { |
|
||||||
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) with compression.", new Object[]{level, width, height}); |
|
||||||
uploadBitmapAsCompressed(GLES20.GL_TEXTURE_2D, level, bitmap, false, 0, 0); |
|
||||||
} else { |
|
||||||
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) directly.", new Object[]{level, width, height}); |
|
||||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, level, bitmap, 0); |
|
||||||
} |
|
||||||
|
|
||||||
if (height == 1 || width == 1) { |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
//Increase the mipmap level
|
|
||||||
height /= 2; |
|
||||||
width /= 2; |
|
||||||
Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); |
|
||||||
|
|
||||||
// Recycle any bitmaps created as a result of scaling the bitmap.
|
|
||||||
// Do not recycle the original image (mipmap level 0)
|
|
||||||
if (level != 0) { |
|
||||||
bitmap.recycle(); |
|
||||||
} |
|
||||||
|
|
||||||
bitmap = bitmap2; |
|
||||||
|
|
||||||
level++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static void uploadBitmapAsCompressed(int target, int level, Bitmap bitmap, boolean subTexture, int x, int y) { |
|
||||||
if (bitmap.hasAlpha()) { |
|
||||||
logger.log(Level.FINEST, " - Uploading bitmap directly. Cannot compress as alpha present."); |
|
||||||
if (subTexture) { |
|
||||||
GLUtils.texSubImage2D(target, level, x, y, bitmap); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} else { |
|
||||||
GLUtils.texImage2D(target, level, bitmap, 0); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} |
|
||||||
} else { |
|
||||||
// Convert to RGB565
|
|
||||||
int bytesPerPixel = 2; |
|
||||||
Bitmap rgb565 = bitmap.copy(Bitmap.Config.RGB_565, true); |
|
||||||
|
|
||||||
// Put texture data into ByteBuffer
|
|
||||||
ByteBuffer inputImage = BufferUtils.createByteBuffer(bitmap.getRowBytes() * bitmap.getHeight()); |
|
||||||
rgb565.copyPixelsToBuffer(inputImage); |
|
||||||
inputImage.position(0); |
|
||||||
|
|
||||||
// Delete the copied RGB565 image
|
|
||||||
rgb565.recycle(); |
|
||||||
|
|
||||||
// Encode the image into the output bytebuffer
|
|
||||||
int encodedImageSize = ETC1.getEncodedDataSize(bitmap.getWidth(), bitmap.getHeight()); |
|
||||||
ByteBuffer compressedImage = BufferUtils.createByteBuffer(encodedImageSize); |
|
||||||
ETC1.encodeImage(inputImage, bitmap.getWidth(), |
|
||||||
bitmap.getHeight(), |
|
||||||
bytesPerPixel, |
|
||||||
bytesPerPixel * bitmap.getWidth(), |
|
||||||
compressedImage); |
|
||||||
|
|
||||||
// Delete the input image buffer
|
|
||||||
BufferUtils.destroyDirectBuffer(inputImage); |
|
||||||
|
|
||||||
// Create an ETC1Texture from the compressed image data
|
|
||||||
ETC1Texture etc1tex = new ETC1Texture(bitmap.getWidth(), bitmap.getHeight(), compressedImage); |
|
||||||
|
|
||||||
// Upload the ETC1Texture
|
|
||||||
if (bytesPerPixel == 2) { |
|
||||||
int oldSize = (bitmap.getRowBytes() * bitmap.getHeight()); |
|
||||||
int newSize = compressedImage.capacity(); |
|
||||||
logger.log(Level.FINEST, " - Uploading compressed image to GL, oldSize = {0}, newSize = {1}, ratio = {2}", new Object[]{oldSize, newSize, (float) oldSize / newSize}); |
|
||||||
if (subTexture) { |
|
||||||
GLES20.glCompressedTexSubImage2D(target, |
|
||||||
level, |
|
||||||
x, y, |
|
||||||
bitmap.getWidth(), |
|
||||||
bitmap.getHeight(), |
|
||||||
ETC1.ETC1_RGB8_OES, |
|
||||||
etc1tex.getData().capacity(), |
|
||||||
etc1tex.getData()); |
|
||||||
|
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} else { |
|
||||||
GLES20.glCompressedTexImage2D(target, |
|
||||||
level, |
|
||||||
ETC1.ETC1_RGB8_OES, |
|
||||||
bitmap.getWidth(), |
|
||||||
bitmap.getHeight(), |
|
||||||
0, |
|
||||||
etc1tex.getData().capacity(), |
|
||||||
etc1tex.getData()); |
|
||||||
|
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} |
|
||||||
|
|
||||||
// ETC1Util.loadTexture(target, level, 0, GLES20.GL_RGB,
|
|
||||||
// GLES20.GL_UNSIGNED_SHORT_5_6_5, etc1Texture);
|
|
||||||
// } else if (bytesPerPixel == 3) {
|
|
||||||
// ETC1Util.loadTexture(target, level, 0, GLES20.GL_RGB,
|
|
||||||
// GLES20.GL_UNSIGNED_BYTE, etc1Texture);
|
|
||||||
} |
|
||||||
|
|
||||||
BufferUtils.destroyDirectBuffer(compressedImage); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* <code>uploadTextureBitmap</code> uploads a native android bitmap |
|
||||||
*/ |
|
||||||
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips) { |
|
||||||
uploadTextureBitmap(target, bitmap, needMips, false, 0, 0); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* <code>uploadTextureBitmap</code> uploads a native android bitmap |
|
||||||
*/ |
|
||||||
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips, boolean subTexture, int x, int y) { |
|
||||||
boolean recycleBitmap = false; |
|
||||||
//TODO, maybe this should raise an exception when NPOT is not supported
|
|
||||||
|
|
||||||
boolean willCompress = ENABLE_COMPRESSION && ETC1support && !bitmap.hasAlpha(); |
|
||||||
if (needMips && willCompress) { |
|
||||||
// Image is compressed and mipmaps are desired, generate them
|
|
||||||
// using software.
|
|
||||||
buildMipmap(bitmap, willCompress); |
|
||||||
} else { |
|
||||||
if (willCompress) { |
|
||||||
// Image is compressed but mipmaps are not desired, upload directly.
|
|
||||||
logger.log(Level.FINEST, " - Uploading compressed bitmap. Mipmaps are not generated."); |
|
||||||
uploadBitmapAsCompressed(target, 0, bitmap, subTexture, x, y); |
|
||||||
|
|
||||||
} else { |
|
||||||
// Image is not compressed, mipmaps may or may not be desired.
|
|
||||||
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}", |
|
||||||
(needMips |
|
||||||
? " Mipmaps will be generated in HARDWARE" |
|
||||||
: " Mipmaps are not generated.")); |
|
||||||
if (subTexture) { |
|
||||||
System.err.println("x : " + x + " y :" + y + " , " + bitmap.getWidth() + "/" + bitmap.getHeight()); |
|
||||||
GLUtils.texSubImage2D(target, 0, x, y, bitmap); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} else { |
|
||||||
GLUtils.texImage2D(target, 0, bitmap, 0); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} |
|
||||||
|
|
||||||
if (needMips) { |
|
||||||
// No pregenerated mips available,
|
|
||||||
// generate from base level if required
|
|
||||||
GLES20.glGenerateMipmap(target); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (recycleBitmap) { |
|
||||||
bitmap.recycle(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void uploadTextureAny(Image img, int target, int index, boolean needMips) { |
|
||||||
if (img.getEfficentData() instanceof AndroidImageInfo) { |
|
||||||
logger.log(Level.FINEST, " === Uploading image {0}. Using BITMAP PATH === ", img); |
|
||||||
// If image was loaded from asset manager, use fast path
|
|
||||||
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData(); |
|
||||||
uploadTextureBitmap(target, imageInfo.getBitmap(), needMips); |
|
||||||
} else { |
|
||||||
logger.log(Level.FINEST, " === Uploading image {0}. Using BUFFER PATH === ", img); |
|
||||||
boolean wantGeneratedMips = needMips && !img.hasMipmaps(); |
|
||||||
if (wantGeneratedMips && img.getFormat().isCompressed()) { |
|
||||||
logger.log(Level.WARNING, "Generating mipmaps is only" |
|
||||||
+ " supported for Bitmap based or non-compressed images!"); |
|
||||||
} |
|
||||||
|
|
||||||
// Upload using slower path
|
|
||||||
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}", |
|
||||||
(wantGeneratedMips |
|
||||||
? " Mipmaps will be generated in HARDWARE" |
|
||||||
: " Mipmaps are not generated.")); |
|
||||||
|
|
||||||
uploadTexture(img, target, index); |
|
||||||
|
|
||||||
// Image was uploaded using slower path, since it is not compressed,
|
|
||||||
// then compress it
|
|
||||||
if (wantGeneratedMips) { |
|
||||||
// No pregenerated mips available,
|
|
||||||
// generate from base level if required
|
|
||||||
GLES20.glGenerateMipmap(target); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static void unsupportedFormat(Format fmt) { |
|
||||||
throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware."); |
|
||||||
} |
|
||||||
|
|
||||||
public static AndroidGLImageFormat getImageFormat(Format fmt, boolean forRenderBuffer) |
|
||||||
throws UnsupportedOperationException { |
|
||||||
AndroidGLImageFormat imageFormat = new AndroidGLImageFormat(); |
|
||||||
switch (fmt) { |
|
||||||
case Depth32: |
|
||||||
case Depth32F: |
|
||||||
throw new UnsupportedOperationException("The image format '" |
|
||||||
+ fmt + "' is not supported by OpenGL ES 2.0 specification."); |
|
||||||
case Alpha8: |
|
||||||
imageFormat.format = GLES20.GL_ALPHA; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
// Highest precision alpha supported by vanilla OGLES2
|
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Luminance8: |
|
||||||
imageFormat.format = GLES20.GL_LUMINANCE; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
// Highest precision luminance supported by vanilla OGLES2
|
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Luminance8Alpha8: |
|
||||||
imageFormat.format = GLES20.GL_LUMINANCE_ALPHA; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RGB565: |
|
||||||
imageFormat.format = GLES20.GL_RGB; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5; |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; |
|
||||||
break; |
|
||||||
case RGB5A1: |
|
||||||
imageFormat.format = GLES20.GL_RGBA; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1; |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB5_A1; |
|
||||||
break; |
|
||||||
case RGB8: |
|
||||||
imageFormat.format = GLES20.GL_RGB; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
// Fallback: Use RGB565 if RGBA8 is not available.
|
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; |
|
||||||
} |
|
||||||
break; |
|
||||||
case BGR8: |
|
||||||
imageFormat.format = GLES20.GL_RGB; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RGBA8: |
|
||||||
imageFormat.format = GLES20.GL_RGBA; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
if (RGBA8) { |
|
||||||
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
|
||||||
} else { |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Depth: |
|
||||||
case Depth16: |
|
||||||
if (!DEPTH_TEXTURE && !forRenderBuffer) { |
|
||||||
unsupportedFormat(fmt); |
|
||||||
} |
|
||||||
imageFormat.format = GLES20.GL_DEPTH_COMPONENT; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT; |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_DEPTH_COMPONENT16; |
|
||||||
break; |
|
||||||
case Depth24: |
|
||||||
case Depth24Stencil8: |
|
||||||
if (!DEPTH_TEXTURE) { |
|
||||||
unsupportedFormat(fmt); |
|
||||||
} |
|
||||||
if (DEPTH24_STENCIL8) { |
|
||||||
// NEW: True Depth24 + Stencil8 format.
|
|
||||||
imageFormat.format = GL_DEPTH_STENCIL_OES; |
|
||||||
imageFormat.dataType = GL_UNSIGNED_INT_24_8_OES; |
|
||||||
imageFormat.renderBufferStorageFormat = GL_DEPTH24_STENCIL8_OES; |
|
||||||
} else { |
|
||||||
// Vanilla OGLES2, only Depth16 available.
|
|
||||||
imageFormat.format = GLES20.GL_DEPTH_COMPONENT; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT; |
|
||||||
imageFormat.renderBufferStorageFormat = GLES20.GL_DEPTH_COMPONENT16; |
|
||||||
} |
|
||||||
break; |
|
||||||
case DXT1: |
|
||||||
if (!DXT1) { |
|
||||||
unsupportedFormat(fmt); |
|
||||||
} |
|
||||||
imageFormat.format = GL_DXT1; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
imageFormat.compress = true; |
|
||||||
break; |
|
||||||
case DXT1A: |
|
||||||
if (!DXT1) { |
|
||||||
unsupportedFormat(fmt); |
|
||||||
} |
|
||||||
imageFormat.format = GL_DXT1A; |
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; |
|
||||||
imageFormat.compress = true; |
|
||||||
break; |
|
||||||
default: |
|
||||||
throw new UnsupportedOperationException("Unrecognized format: " + fmt); |
|
||||||
} |
|
||||||
return imageFormat; |
|
||||||
} |
|
||||||
|
|
||||||
public static class AndroidGLImageFormat { |
|
||||||
|
|
||||||
boolean compress = false; |
|
||||||
int format = -1; |
|
||||||
int renderBufferStorageFormat = -1; |
|
||||||
int dataType = -1; |
|
||||||
} |
|
||||||
|
|
||||||
private static void uploadTexture(Image img, |
|
||||||
int target, |
|
||||||
int index) { |
|
||||||
|
|
||||||
if (img.getEfficentData() instanceof AndroidImageInfo) { |
|
||||||
throw new RendererException("This image uses efficient data. " |
|
||||||
+ "Use uploadTextureBitmap instead."); |
|
||||||
} |
|
||||||
|
|
||||||
// Otherwise upload image directly.
|
|
||||||
// Prefer to only use power of 2 textures here to avoid errors.
|
|
||||||
Image.Format fmt = img.getFormat(); |
|
||||||
ByteBuffer data; |
|
||||||
if (index >= 0 || img.getData() != null && img.getData().size() > 0) { |
|
||||||
data = img.getData(index); |
|
||||||
} else { |
|
||||||
data = null; |
|
||||||
} |
|
||||||
|
|
||||||
int width = img.getWidth(); |
|
||||||
int height = img.getHeight(); |
|
||||||
|
|
||||||
if (!NPOT && img.isNPOT()) { |
|
||||||
// Check if texture is POT
|
|
||||||
throw new RendererException("Non-power-of-2 textures " |
|
||||||
+ "are not supported by the video hardware " |
|
||||||
+ "and no scaling path available for image: " + img); |
|
||||||
} |
|
||||||
AndroidGLImageFormat imageFormat = getImageFormat(fmt, false); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); |
|
||||||
} |
|
||||||
|
|
||||||
int[] mipSizes = img.getMipMapSizes(); |
|
||||||
int pos = 0; |
|
||||||
if (mipSizes == null) { |
|
||||||
if (data != null) { |
|
||||||
mipSizes = new int[]{data.capacity()}; |
|
||||||
} else { |
|
||||||
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < mipSizes.length; i++) { |
|
||||||
int mipWidth = Math.max(1, width >> i); |
|
||||||
int mipHeight = Math.max(1, height >> i); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
data.position(pos); |
|
||||||
data.limit(pos + mipSizes[i]); |
|
||||||
} |
|
||||||
|
|
||||||
if (imageFormat.compress && data != null) { |
|
||||||
GLES20.glCompressedTexImage2D(target, |
|
||||||
i, |
|
||||||
imageFormat.format, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
0, |
|
||||||
data.remaining(), |
|
||||||
data); |
|
||||||
} else { |
|
||||||
GLES20.glTexImage2D(target, |
|
||||||
i, |
|
||||||
imageFormat.format, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
0, |
|
||||||
imageFormat.format, |
|
||||||
imageFormat.dataType, |
|
||||||
data); |
|
||||||
} |
|
||||||
|
|
||||||
pos += mipSizes[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Update the texture currently bound to target at with data from the given |
|
||||||
* Image at position x and y. The parameter index is used as the zoffset in |
|
||||||
* case a 3d texture or texture 2d array is being updated. |
|
||||||
* |
|
||||||
* @param image Image with the source data (this data will be put into the |
|
||||||
* texture) |
|
||||||
* @param target the target texture |
|
||||||
* @param index the mipmap level to update |
|
||||||
* @param x the x position where to put the image in the texture |
|
||||||
* @param y the y position where to put the image in the texture |
|
||||||
*/ |
|
||||||
public static void uploadSubTexture( |
|
||||||
Image img, |
|
||||||
int target, |
|
||||||
int index, |
|
||||||
int x, |
|
||||||
int y) { |
|
||||||
if (img.getEfficentData() instanceof AndroidImageInfo) { |
|
||||||
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData(); |
|
||||||
uploadTextureBitmap(target, imageInfo.getBitmap(), true, true, x, y); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
// Otherwise upload image directly.
|
|
||||||
// Prefer to only use power of 2 textures here to avoid errors.
|
|
||||||
Image.Format fmt = img.getFormat(); |
|
||||||
ByteBuffer data; |
|
||||||
if (index >= 0 || img.getData() != null && img.getData().size() > 0) { |
|
||||||
data = img.getData(index); |
|
||||||
} else { |
|
||||||
data = null; |
|
||||||
} |
|
||||||
|
|
||||||
int width = img.getWidth(); |
|
||||||
int height = img.getHeight(); |
|
||||||
|
|
||||||
if (!NPOT && img.isNPOT()) { |
|
||||||
// Check if texture is POT
|
|
||||||
throw new RendererException("Non-power-of-2 textures " |
|
||||||
+ "are not supported by the video hardware " |
|
||||||
+ "and no scaling path available for image: " + img); |
|
||||||
} |
|
||||||
AndroidGLImageFormat imageFormat = getImageFormat(fmt, false); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); |
|
||||||
} |
|
||||||
|
|
||||||
int[] mipSizes = img.getMipMapSizes(); |
|
||||||
int pos = 0; |
|
||||||
if (mipSizes == null) { |
|
||||||
if (data != null) { |
|
||||||
mipSizes = new int[]{data.capacity()}; |
|
||||||
} else { |
|
||||||
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < mipSizes.length; i++) { |
|
||||||
int mipWidth = Math.max(1, width >> i); |
|
||||||
int mipHeight = Math.max(1, height >> i); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
data.position(pos); |
|
||||||
data.limit(pos + mipSizes[i]); |
|
||||||
} |
|
||||||
|
|
||||||
if (imageFormat.compress && data != null) { |
|
||||||
GLES20.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, data.remaining(), data); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} else { |
|
||||||
GLES20.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, imageFormat.dataType, data); |
|
||||||
RendererUtil.checkGLError(); |
|
||||||
} |
|
||||||
|
|
||||||
pos += mipSizes[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
package com.jme3.texture.plugins; |
|
||||||
|
|
||||||
import android.graphics.Bitmap; |
|
||||||
import com.jme3.asset.AndroidImageInfo; |
|
||||||
import com.jme3.asset.AssetInfo; |
|
||||||
import com.jme3.asset.AssetLoader; |
|
||||||
import com.jme3.texture.Image; |
|
||||||
import com.jme3.texture.image.ColorSpace; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
@Deprecated |
|
||||||
public class AndroidImageLoader implements AssetLoader { |
|
||||||
|
|
||||||
public Object load(AssetInfo info) throws IOException { |
|
||||||
AndroidImageInfo imageInfo = new AndroidImageInfo(info); |
|
||||||
Bitmap bitmap = imageInfo.getBitmap(); |
|
||||||
|
|
||||||
Image image = new Image(imageInfo.getFormat(), bitmap.getWidth(), bitmap.getHeight(), null, ColorSpace.sRGB); |
|
||||||
|
|
||||||
image.setEfficentData(imageInfo); |
|
||||||
return image; |
|
||||||
} |
|
||||||
} |
|
@ -1,44 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.animation; |
|
||||||
|
|
||||||
/** |
|
||||||
* @deprecated use Animation instead with tracks of selected type (ie. BoneTrack, SpatialTrack, MeshTrack) |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public final class BoneAnimation extends Animation { |
|
||||||
|
|
||||||
@Deprecated |
|
||||||
public BoneAnimation(String name, float length) { |
|
||||||
super(name, length); |
|
||||||
} |
|
||||||
} |
|
@ -1,42 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.animation; |
|
||||||
|
|
||||||
/** |
|
||||||
* @deprecated use Animation instead with tracks of selected type (ie. BoneTrack, SpatialTrack, MeshTrack) |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public class SpatialAnimation extends Animation { |
|
||||||
public SpatialAnimation(String name, float length) { |
|
||||||
super(name, length); |
|
||||||
} |
|
||||||
} |
|
@ -1,76 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.effect; |
|
||||||
|
|
||||||
import com.jme3.renderer.Camera; |
|
||||||
import java.util.Comparator; |
|
||||||
|
|
||||||
@Deprecated |
|
||||||
class ParticleComparator implements Comparator<Particle> { |
|
||||||
|
|
||||||
private Camera cam; |
|
||||||
|
|
||||||
public void setCamera(Camera cam){ |
|
||||||
this.cam = cam; |
|
||||||
} |
|
||||||
|
|
||||||
public int compare(Particle p1, Particle p2) { |
|
||||||
return 0; // unused
|
|
||||||
/* |
|
||||||
if (p1.life <= 0 || p2.life <= 0) |
|
||||||
return 0; |
|
||||||
|
|
||||||
// if (p1.life <= 0)
|
|
||||||
// return 1;
|
|
||||||
// else if (p2.life <= 0)
|
|
||||||
// return -1;
|
|
||||||
|
|
||||||
float d1 = p1.distToCam, d2 = p2.distToCam; |
|
||||||
|
|
||||||
if (d1 == -1){ |
|
||||||
d1 = cam.distanceToNearPlane(p1.position); |
|
||||||
p1.distToCam = d1; |
|
||||||
} |
|
||||||
if (d2 == -1){ |
|
||||||
d2 = cam.distanceToNearPlane(p2.position); |
|
||||||
p2.distToCam = d2; |
|
||||||
} |
|
||||||
|
|
||||||
if (d1 < d2) |
|
||||||
return 1; |
|
||||||
else if (d1 > d2) |
|
||||||
return -1; |
|
||||||
else |
|
||||||
return 0; |
|
||||||
*/ |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,6 @@ |
|||||||
|
MaterialDef Test Material { |
||||||
|
Technique Test { |
||||||
|
VertexShader GLSL100 : test.vert |
||||||
|
FragmentShader GLSL100 : test.frag |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
MaterialDef Test Material { |
||||||
|
Technique A { |
||||||
|
} |
||||||
|
Technique B { |
||||||
|
VertexShader GLSL100 : test.vert |
||||||
|
FragmentShader GLSL100 : test.frag |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
MaterialDef Test Material { |
||||||
|
Technique Test { |
||||||
|
VertexShader GLSL150 : test150.vert |
||||||
|
FragmentShader GLSL150 : test150.frag |
||||||
|
} |
||||||
|
Technique Test { |
||||||
|
VertexShader GLSL100 : test.vert |
||||||
|
FragmentShader GLSL100 : test.frag |
||||||
|
} |
||||||
|
} |
@ -1,359 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.system; |
|
||||||
|
|
||||||
import java.io.*; |
|
||||||
import java.net.MalformedURLException; |
|
||||||
import java.net.URL; |
|
||||||
import java.net.URLConnection; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* Helper class for extracting the natives (dll, so) from the jars. |
|
||||||
* This class should only be used internally. |
|
||||||
* |
|
||||||
* @deprecated Use {@link NativeLibraryLoader} instead. |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public final class Natives { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Natives.class.getName()); |
|
||||||
private static final byte[] buf = new byte[1024 * 100]; |
|
||||||
private static File extractionDirOverride = null; |
|
||||||
private static File extractionDir = null; |
|
||||||
|
|
||||||
public static void setExtractionDir(String name) { |
|
||||||
extractionDirOverride = new File(name).getAbsoluteFile(); |
|
||||||
} |
|
||||||
|
|
||||||
public static File getExtractionDir() { |
|
||||||
if (extractionDirOverride != null) { |
|
||||||
return extractionDirOverride; |
|
||||||
} |
|
||||||
if (extractionDir == null) { |
|
||||||
File workingFolder = new File("").getAbsoluteFile(); |
|
||||||
if (!workingFolder.canWrite()) { |
|
||||||
setStorageExtractionDir(); |
|
||||||
} else { |
|
||||||
try { |
|
||||||
File file = new File(workingFolder.getAbsolutePath() + File.separator + ".jmetestwrite"); |
|
||||||
file.createNewFile(); |
|
||||||
file.delete(); |
|
||||||
extractionDir = workingFolder; |
|
||||||
} catch (Exception e) { |
|
||||||
setStorageExtractionDir(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return extractionDir; |
|
||||||
} |
|
||||||
|
|
||||||
private static void setStorageExtractionDir() { |
|
||||||
logger.log(Level.WARNING, "Working directory is not writable. Using home directory instead."); |
|
||||||
extractionDir = new File(JmeSystem.getStorageFolder(), |
|
||||||
"natives_" + Integer.toHexString(computeNativesHash())); |
|
||||||
if (!extractionDir.exists()) { |
|
||||||
extractionDir.mkdir(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static int computeNativesHash() { |
|
||||||
URLConnection conn = null; |
|
||||||
try { |
|
||||||
String classpath = System.getProperty("java.class.path"); |
|
||||||
URL url = Thread.currentThread().getContextClassLoader().getResource("com/jme3/system/Natives.class"); |
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(url.toString()); |
|
||||||
if (sb.indexOf("jar:") == 0) { |
|
||||||
sb.delete(0, 4); |
|
||||||
sb.delete(sb.indexOf("!"), sb.length()); |
|
||||||
sb.delete(sb.lastIndexOf("/") + 1, sb.length()); |
|
||||||
} |
|
||||||
try { |
|
||||||
url = new URL(sb.toString()); |
|
||||||
} catch (MalformedURLException ex) { |
|
||||||
throw new UnsupportedOperationException(ex); |
|
||||||
} |
|
||||||
|
|
||||||
conn = url.openConnection(); |
|
||||||
int hash = classpath.hashCode() ^ (int) conn.getLastModified(); |
|
||||||
return hash; |
|
||||||
} catch (IOException ex) { |
|
||||||
throw new UnsupportedOperationException(ex); |
|
||||||
} finally { |
|
||||||
if (conn != null) { |
|
||||||
try { |
|
||||||
conn.getInputStream().close(); |
|
||||||
conn.getOutputStream().close(); |
|
||||||
} catch (IOException ex) { } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void extractNativeLib(String sysName, String name) throws IOException { |
|
||||||
extractNativeLib(sysName, name, false, true); |
|
||||||
} |
|
||||||
|
|
||||||
public static void extractNativeLib(String sysName, String name, boolean load) throws IOException { |
|
||||||
extractNativeLib(sysName, name, load, true); |
|
||||||
} |
|
||||||
|
|
||||||
public static void extractNativeLib(String sysName, String name, boolean load, boolean warning) throws IOException { |
|
||||||
String fullname; |
|
||||||
String path; |
|
||||||
//XXX: hack to allow specifying the extension via supplying an extension in the name (e.g. "blah.dylib")
|
|
||||||
// this is needed on osx where the openal.dylib always needs to be extracted as dylib
|
|
||||||
// and never as jnilib, even if that is the platform JNI lib suffix (OpenAL is no JNI library)
|
|
||||||
if(!name.contains(".")){ |
|
||||||
// automatic name mapping
|
|
||||||
fullname = System.mapLibraryName(name); |
|
||||||
path = "native/" + sysName + "/" + fullname; |
|
||||||
//XXX: Hack to extract jnilib to dylib on OSX Java 1.7+
|
|
||||||
// This assumes all jni libs for osx are stored as "jnilib" in the jar file.
|
|
||||||
// It will be extracted with the name required for the platform.
|
|
||||||
// At a later stage this should probably inverted so that dylib is the default name.
|
|
||||||
if(sysName.equals("macosx")){ |
|
||||||
path = path.replaceAll("dylib","jnilib"); |
|
||||||
} |
|
||||||
} else{ |
|
||||||
fullname = name; |
|
||||||
path = "native/" + sysName + "/" + fullname; |
|
||||||
} |
|
||||||
|
|
||||||
URL url = Thread.currentThread().getContextClassLoader().getResource(path); |
|
||||||
|
|
||||||
// Also check for binaries that are not packed in folders by jme team, e.g. maven artifacts
|
|
||||||
if(url == null){ |
|
||||||
path = fullname; |
|
||||||
if(sysName.equals("macosx") && !name.contains(".")){ |
|
||||||
path = path.replaceAll("dylib","jnilib"); |
|
||||||
} |
|
||||||
url = Thread.currentThread().getContextClassLoader().getResource(path); |
|
||||||
} |
|
||||||
|
|
||||||
if(url == null){ |
|
||||||
if (!warning) { |
|
||||||
logger.log(Level.WARNING, "Cannot locate native library in classpath: {0}/{1}", |
|
||||||
new String[]{sysName, fullname}); |
|
||||||
} |
|
||||||
// Still try loading the library without a filename, maybe it is
|
|
||||||
// accessible otherwise
|
|
||||||
try{ |
|
||||||
System.loadLibrary(name); |
|
||||||
} catch(UnsatisfiedLinkError e){ |
|
||||||
if (!warning) { |
|
||||||
logger.log(Level.WARNING, "Cannot load native library: {0}/{1}", |
|
||||||
new String[]{sysName, fullname}); |
|
||||||
} |
|
||||||
} |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
URLConnection conn = url.openConnection(); |
|
||||||
InputStream in = conn.getInputStream(); |
|
||||||
File targetFile = new File(getExtractionDir(), fullname); |
|
||||||
OutputStream out = null; |
|
||||||
try { |
|
||||||
if (targetFile.exists()) { |
|
||||||
// OK, compare last modified date of this file to
|
|
||||||
// file in jar
|
|
||||||
long targetLastModified = targetFile.lastModified(); |
|
||||||
long sourceLastModified = conn.getLastModified(); |
|
||||||
|
|
||||||
// Allow ~1 second range for OSes that only support low precision
|
|
||||||
if (targetLastModified + 1000 > sourceLastModified) { |
|
||||||
logger.log(Level.FINE, "Not copying library {0}. Latest already extracted.", fullname); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
out = new FileOutputStream(targetFile); |
|
||||||
int len; |
|
||||||
while ((len = in.read(buf)) > 0) { |
|
||||||
out.write(buf, 0, len); |
|
||||||
} |
|
||||||
in.close(); |
|
||||||
in = null; |
|
||||||
out.close(); |
|
||||||
out = null; |
|
||||||
|
|
||||||
// NOTE: On OSes that support "Date Created" property,
|
|
||||||
// this will cause the last modified date to be lower than
|
|
||||||
// date created which makes no sense
|
|
||||||
targetFile.setLastModified(conn.getLastModified()); |
|
||||||
} catch (FileNotFoundException ex) { |
|
||||||
if (ex.getMessage().contains("used by another process")) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
throw ex; |
|
||||||
} finally { |
|
||||||
if (load) { |
|
||||||
System.load(targetFile.getAbsolutePath()); |
|
||||||
} |
|
||||||
if(in != null){ |
|
||||||
in.close(); |
|
||||||
} |
|
||||||
if(out != null){ |
|
||||||
out.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
logger.log(Level.FINE, "Copied {0} to {1}", new Object[]{fullname, targetFile}); |
|
||||||
} |
|
||||||
|
|
||||||
protected static boolean isUsingNativeBullet() { |
|
||||||
try { |
|
||||||
Class clazz = Class.forName("com.jme3.bullet.util.NativeMeshUtil"); |
|
||||||
return clazz != null; |
|
||||||
} catch (ClassNotFoundException ex) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void extractNativeLibs(Platform platform, AppSettings settings) throws IOException { |
|
||||||
if (true) { |
|
||||||
throw new UnsupportedEncodingException("Now, why would you EVER want to do that?"); |
|
||||||
} |
|
||||||
|
|
||||||
String renderer = settings.getRenderer(); |
|
||||||
String audioRenderer = settings.getAudioRenderer(); |
|
||||||
boolean needLWJGL = false; |
|
||||||
boolean needOAL = false; |
|
||||||
boolean needJInput = false; |
|
||||||
boolean needNativeBullet = isUsingNativeBullet(); |
|
||||||
|
|
||||||
if (renderer != null) { |
|
||||||
if (renderer.startsWith("LWJGL")) { |
|
||||||
needLWJGL = true; |
|
||||||
} |
|
||||||
} |
|
||||||
if (audioRenderer != null) { |
|
||||||
if (audioRenderer.equals("LWJGL")) { |
|
||||||
needLWJGL = true; |
|
||||||
needOAL = true; |
|
||||||
} |
|
||||||
} |
|
||||||
needJInput = settings.useJoysticks(); |
|
||||||
|
|
||||||
String libraryPath = getExtractionDir().toString(); |
|
||||||
if (needLWJGL) { |
|
||||||
logger.log(Level.INFO, "Extraction Directory: {0}", getExtractionDir().toString()); |
|
||||||
|
|
||||||
// LWJGL supports this feature where
|
|
||||||
// it can load libraries from this path.
|
|
||||||
System.setProperty("org.lwjgl.librarypath", libraryPath); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
// AND Luckily enough JInput supports the same feature.
|
|
||||||
System.setProperty("net.java.games.input.librarypath", libraryPath); |
|
||||||
} |
|
||||||
|
|
||||||
switch (platform) { |
|
||||||
case Windows64: |
|
||||||
if (needLWJGL) { |
|
||||||
extractNativeLib("windows", "lwjgl64"); |
|
||||||
} |
|
||||||
if (needOAL) { |
|
||||||
extractNativeLib("windows", "OpenAL64", true, false); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
extractNativeLib("windows", "jinput-dx8_64"); |
|
||||||
extractNativeLib("windows", "jinput-raw_64"); |
|
||||||
} |
|
||||||
if (needNativeBullet) { |
|
||||||
extractNativeLib("windows", "bulletjme64", true, false); |
|
||||||
} |
|
||||||
break; |
|
||||||
case Windows32: |
|
||||||
if (needLWJGL) { |
|
||||||
extractNativeLib("windows", "lwjgl"); |
|
||||||
} |
|
||||||
if (needOAL) { |
|
||||||
extractNativeLib("windows", "OpenAL32", true, false); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
extractNativeLib("windows", "jinput-dx8"); |
|
||||||
extractNativeLib("windows", "jinput-raw"); |
|
||||||
} |
|
||||||
if (needNativeBullet) { |
|
||||||
extractNativeLib("windows", "bulletjme", true, false); |
|
||||||
} |
|
||||||
break; |
|
||||||
case Linux64: |
|
||||||
if (needLWJGL) { |
|
||||||
extractNativeLib("linux", "lwjgl64"); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
extractNativeLib("linux", "jinput-linux64"); |
|
||||||
} |
|
||||||
if (needOAL) { |
|
||||||
extractNativeLib("linux", "openal64"); |
|
||||||
} |
|
||||||
if (needNativeBullet) { |
|
||||||
extractNativeLib("linux", "bulletjme64", true, false); |
|
||||||
} |
|
||||||
break; |
|
||||||
case Linux32: |
|
||||||
if (needLWJGL) { |
|
||||||
extractNativeLib("linux", "lwjgl"); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
extractNativeLib("linux", "jinput-linux"); |
|
||||||
} |
|
||||||
if (needOAL) { |
|
||||||
extractNativeLib("linux", "openal"); |
|
||||||
} |
|
||||||
if (needNativeBullet) { |
|
||||||
extractNativeLib("linux", "bulletjme", true, false); |
|
||||||
} |
|
||||||
break; |
|
||||||
case MacOSX_PPC32: |
|
||||||
case MacOSX32: |
|
||||||
case MacOSX_PPC64: |
|
||||||
case MacOSX64: |
|
||||||
if (needLWJGL) { |
|
||||||
extractNativeLib("macosx", "lwjgl"); |
|
||||||
} |
|
||||||
if (needOAL){ |
|
||||||
extractNativeLib("macosx", "openal.dylib"); |
|
||||||
} |
|
||||||
if (needJInput) { |
|
||||||
extractNativeLib("macosx", "jinput-osx"); |
|
||||||
} |
|
||||||
if (needNativeBullet) { |
|
||||||
extractNativeLib("macosx", "bulletjme", true, false); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.terrain.geomipmap.lodcalc; |
|
||||||
|
|
||||||
import com.jme3.export.Savable; |
|
||||||
import com.jme3.terrain.geomipmap.TerrainPatch; |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates LOD Calculator objects for the terrain patches. |
|
||||||
* |
|
||||||
* @author Brent Owens |
|
||||||
* @deprecated phasing this out |
|
||||||
*/ |
|
||||||
public interface LodCalculatorFactory extends Savable, Cloneable { |
|
||||||
|
|
||||||
public LodCalculator createCalculator(); |
|
||||||
public LodCalculator createCalculator(TerrainPatch terrainPatch); |
|
||||||
|
|
||||||
public LodCalculatorFactory clone(); |
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.terrain.geomipmap.lodcalc; |
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule; |
|
||||||
import com.jme3.export.JmeExporter; |
|
||||||
import com.jme3.export.JmeImporter; |
|
||||||
import com.jme3.export.OutputCapsule; |
|
||||||
import com.jme3.terrain.geomipmap.TerrainPatch; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author bowens |
|
||||||
* @deprecated phasing out |
|
||||||
*/ |
|
||||||
public class LodDistanceCalculatorFactory implements LodCalculatorFactory { |
|
||||||
|
|
||||||
private float lodThresholdSize = 2.7f; |
|
||||||
private LodThreshold lodThreshold = null; |
|
||||||
|
|
||||||
|
|
||||||
public LodDistanceCalculatorFactory() { |
|
||||||
} |
|
||||||
|
|
||||||
public LodDistanceCalculatorFactory(LodThreshold lodThreshold) { |
|
||||||
this.lodThreshold = lodThreshold; |
|
||||||
} |
|
||||||
|
|
||||||
public LodCalculator createCalculator() { |
|
||||||
return new DistanceLodCalculator(); |
|
||||||
} |
|
||||||
|
|
||||||
public LodCalculator createCalculator(TerrainPatch terrainPatch) { |
|
||||||
return new DistanceLodCalculator(); |
|
||||||
} |
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException { |
|
||||||
OutputCapsule c = ex.getCapsule(this); |
|
||||||
c.write(lodThreshold, "lodThreshold", null); |
|
||||||
c.write(lodThresholdSize, "lodThresholdSize", 2); |
|
||||||
} |
|
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException { |
|
||||||
InputCapsule c = im.getCapsule(this); |
|
||||||
lodThresholdSize = c.readFloat("lodThresholdSize", 2); |
|
||||||
lodThreshold = (LodThreshold) c.readSavable("lodThreshold", null); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public LodDistanceCalculatorFactory clone() { |
|
||||||
LodDistanceCalculatorFactory clone = new LodDistanceCalculatorFactory(); |
|
||||||
clone.lodThreshold = lodThreshold.clone(); |
|
||||||
clone.lodThresholdSize = lodThresholdSize; |
|
||||||
return clone; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,80 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
|
||||||
* 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 'jMonkeyEngine' 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 com.jme3.terrain.geomipmap.lodcalc; |
|
||||||
|
|
||||||
import com.jme3.export.JmeExporter; |
|
||||||
import com.jme3.export.JmeImporter; |
|
||||||
import com.jme3.renderer.Camera; |
|
||||||
import com.jme3.terrain.geomipmap.TerrainPatch; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
/** |
|
||||||
* TODO: Make it work with multiple cameras |
|
||||||
* TODO: Fix the cracks when the lod differences are greater than 1 |
|
||||||
* for two adjacent blocks. |
|
||||||
* @deprecated phasing out |
|
||||||
*/ |
|
||||||
public class LodPerspectiveCalculatorFactory implements LodCalculatorFactory { |
|
||||||
|
|
||||||
private Camera cam; |
|
||||||
private float pixelError; |
|
||||||
|
|
||||||
public LodPerspectiveCalculatorFactory(Camera cam, float pixelError){ |
|
||||||
this.cam = cam; |
|
||||||
this.pixelError = pixelError; |
|
||||||
} |
|
||||||
|
|
||||||
public LodCalculator createCalculator() { |
|
||||||
return new PerspectiveLodCalculator(cam, pixelError); |
|
||||||
} |
|
||||||
|
|
||||||
public LodCalculator createCalculator(TerrainPatch terrainPatch) { |
|
||||||
PerspectiveLodCalculator p = new PerspectiveLodCalculator(cam, pixelError); |
|
||||||
return p; |
|
||||||
} |
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException { |
|
||||||
} |
|
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public LodCalculatorFactory clone() { |
|
||||||
try { |
|
||||||
return (LodCalculatorFactory) super.clone(); |
|
||||||
} catch (CloneNotSupportedException ex) { |
|
||||||
throw new AssertionError(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue