* Added new renderer capability: NonPowerOfTwoTextures
* LwjglRenderer will show warnings when NPOT textures are used and the graphics card doesn't support them * LwjglGL1Renderer will scale textures to POT sizes if NPOT is not supported * Enable simple logging git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7177 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
b6386751e4
commit
90bf137894
@ -141,6 +141,11 @@ public enum Caps {
|
|||||||
*/
|
*/
|
||||||
TextureCompressionLATC,
|
TextureCompressionLATC,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports Non-Power-Of-Two (NPOT) textures and framebuffers
|
||||||
|
*/
|
||||||
|
NonPowerOfTwoTextures,
|
||||||
|
|
||||||
/// Vertex Buffer features
|
/// Vertex Buffer features
|
||||||
MeshInstancing,
|
MeshInstancing,
|
||||||
|
|
||||||
|
@ -37,11 +37,14 @@ import com.jme3.app.SettingsDialog.SelectionListener;
|
|||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.asset.DesktopAssetManager;
|
import com.jme3.asset.DesktopAssetManager;
|
||||||
import com.jme3.audio.AudioRenderer;
|
import com.jme3.audio.AudioRenderer;
|
||||||
|
import com.jme3.util.JmeFormatter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.ConsoleHandler;
|
||||||
|
import java.util.logging.Handler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@ -318,7 +321,6 @@ public class JmeSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AudioRenderer ar = clazz.newInstance();
|
AudioRenderer ar = clazz.newInstance();
|
||||||
// ar = new QueuedAudioRenderer(ar);
|
|
||||||
return ar;
|
return ar;
|
||||||
}catch (InstantiationException ex){
|
}catch (InstantiationException ex){
|
||||||
logger.log(Level.SEVERE, "Failed to create context", ex);
|
logger.log(Level.SEVERE, "Failed to create context", ex);
|
||||||
@ -336,28 +338,28 @@ public class JmeSystem {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
// try {
|
try {
|
||||||
// if (!lowPermissions){
|
if (!lowPermissions){
|
||||||
// // can only modify logging settings
|
// can only modify logging settings
|
||||||
// // if permissions are available
|
// if permissions are available
|
||||||
//
|
|
||||||
// JmeFormatter formatter = new JmeFormatter();
|
JmeFormatter formatter = new JmeFormatter();
|
||||||
// Handler fileHandler = new FileHandler("jme.log");
|
// Handler fileHandler = new FileHandler("jme.log");
|
||||||
// fileHandler.setFormatter(formatter);
|
// fileHandler.setFormatter(formatter);
|
||||||
// Logger.getLogger("").addHandler(fileHandler);
|
// Logger.getLogger("").addHandler(fileHandler);
|
||||||
//
|
|
||||||
// Handler consoleHandler = new ConsoleHandler();
|
Handler consoleHandler = new ConsoleHandler();
|
||||||
// consoleHandler.setFormatter(formatter);
|
consoleHandler.setFormatter(formatter);
|
||||||
// Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
|
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
|
||||||
// Logger.getLogger("").addHandler(consoleHandler);
|
Logger.getLogger("").addHandler(consoleHandler);
|
||||||
//
|
|
||||||
// Logger.getLogger("com.jme3").setLevel(Level.FINEST);
|
// Logger.getLogger("com.jme3").setLevel(Level.FINEST);
|
||||||
// }
|
}
|
||||||
// } catch (IOException ex){
|
// } catch (IOException ex){
|
||||||
// logger.log(Level.SEVERE, "I/O Error while creating log file", ex);
|
// logger.log(Level.SEVERE, "I/O Error while creating log file", ex);
|
||||||
// } catch (SecurityException ex){
|
} catch (SecurityException ex){
|
||||||
// logger.log(Level.SEVERE, "Security error in creating log file", ex);
|
logger.log(Level.SEVERE, "Security error in creating log file", ex);
|
||||||
// }
|
}
|
||||||
logger.log(Level.INFO, "Running on {0}", getFullName());
|
logger.log(Level.INFO, "Running on {0}", getFullName());
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jme3.renderer.lwjgl;
|
package com.jme3.renderer.lwjgl;
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.renderer.GL1Renderer;
|
import com.jme3.renderer.GL1Renderer;
|
||||||
import com.jme3.shader.Shader;
|
import com.jme3.shader.Shader;
|
||||||
import com.jme3.shader.Shader.ShaderSource;
|
import com.jme3.shader.Shader.ShaderSource;
|
||||||
@ -33,6 +34,7 @@ import java.nio.IntBuffer;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import jme3tools.converters.MipMapGenerator;
|
import jme3tools.converters.MipMapGenerator;
|
||||||
|
import org.lwjgl.opengl.GLContext;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
private final FloatBuffer fb16 = BufferUtils.createFloatBuffer(16);
|
private final FloatBuffer fb16 = BufferUtils.createFloatBuffer(16);
|
||||||
private final RenderContext context = new RenderContext();
|
private final RenderContext context = new RenderContext();
|
||||||
private final GLObjectManager objManager = new GLObjectManager();
|
private final GLObjectManager objManager = new GLObjectManager();
|
||||||
|
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
||||||
|
|
||||||
private int maxTexSize;
|
private int maxTexSize;
|
||||||
private int maxCubeTexSize;
|
private int maxCubeTexSize;
|
||||||
@ -80,13 +83,21 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public EnumSet<Caps> getCaps() {
|
public EnumSet<Caps> getCaps() {
|
||||||
return EnumSet.noneOf(Caps.class);
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
//glDisable(GL_DEPTH_TEST);
|
//glDisable(GL_DEPTH_TEST);
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||||
|
|
||||||
|
if (GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
||||||
|
caps.add(Caps.NonPowerOfTwoTextures);
|
||||||
|
}else{
|
||||||
|
logger.log(Level.WARNING, "Your graphics card does not "
|
||||||
|
+ "support non-power-of-2 textures. "
|
||||||
|
+ "Some features might not work.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetGLObjects() {
|
public void resetGLObjects() {
|
||||||
@ -470,6 +481,20 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
statistics.onTextureUse(img, true);
|
statistics.onTextureUse(img, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check sizes if graphics card doesn't support NPOT
|
||||||
|
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
||||||
|
if (img.getWidth() != 0 && img.getHeight() != 0){
|
||||||
|
if (!FastMath.isPowerOfTwo(img.getWidth())
|
||||||
|
|| !FastMath.isPowerOfTwo(img.getHeight())
|
||||||
|
|| img.getWidth() != img.getHeight()){
|
||||||
|
|
||||||
|
// Resize texture to Power-of-2 size
|
||||||
|
MipMapGenerator.resizeToPowerOf2(img);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!img.hasMipmaps() && mips) {
|
if (!img.hasMipmaps() && mips) {
|
||||||
// No pregenerated mips available,
|
// No pregenerated mips available,
|
||||||
// generate from base level if required
|
// generate from base level if required
|
||||||
|
@ -34,6 +34,7 @@ package com.jme3.renderer.lwjgl;
|
|||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
@ -316,6 +317,14 @@ public class LwjglRenderer implements Renderer {
|
|||||||
caps.add(Caps.VertexBufferArray);
|
caps.add(Caps.VertexBufferArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctxCaps.GL_ARB_texture_non_power_of_two){
|
||||||
|
caps.add(Caps.NonPowerOfTwoTextures);
|
||||||
|
}else{
|
||||||
|
logger.log(Level.WARNING, "Your graphics card does not "
|
||||||
|
+ "support non-power-of-2 textures. "
|
||||||
|
+ "Some features might not work.");
|
||||||
|
}
|
||||||
|
|
||||||
boolean latc = ctxCaps.GL_EXT_texture_compression_latc;
|
boolean latc = ctxCaps.GL_EXT_texture_compression_latc;
|
||||||
boolean atdc = ctxCaps.GL_ATI_texture_compression_3dc;
|
boolean atdc = ctxCaps.GL_ATI_texture_compression_3dc;
|
||||||
if (latc || atdc) {
|
if (latc || atdc) {
|
||||||
@ -1601,6 +1610,18 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check sizes if graphics card doesn't support NPOT
|
||||||
|
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
||||||
|
if (img.getWidth() != 0 && img.getHeight() != 0){
|
||||||
|
if (!FastMath.isPowerOfTwo(img.getWidth())
|
||||||
|
|| !FastMath.isPowerOfTwo(img.getHeight())
|
||||||
|
|| img.getWidth() != img.getHeight()){
|
||||||
|
logger.log(Level.WARNING, "Encountered NPOT texture {0}, "
|
||||||
|
+ "it might not display correctly.", img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (target == GL_TEXTURE_CUBE_MAP) {
|
if (target == GL_TEXTURE_CUBE_MAP) {
|
||||||
List<ByteBuffer> data = img.getData();
|
List<ByteBuffer> data = img.getData();
|
||||||
if (data.size() != 6) {
|
if (data.size() != 6) {
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
package jme3tools.converters;
|
package jme3tools.converters;
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import com.jme3.texture.plugins.AWTLoader;
|
import com.jme3.texture.plugins.AWTLoader;
|
||||||
@ -58,6 +59,25 @@ public class MipMapGenerator {
|
|||||||
return targetImage;
|
return targetImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void resizeToPowerOf2(Image image){
|
||||||
|
BufferedImage original = ImageToAwt.convert(image, false, true, 0);
|
||||||
|
int potWidth = FastMath.nearestPowerOfTwo(image.getWidth());
|
||||||
|
int potHeight = FastMath.nearestPowerOfTwo(image.getHeight());
|
||||||
|
int potSize = Math.max(potWidth, potHeight);
|
||||||
|
|
||||||
|
BufferedImage scaled = scaleDown(original, potSize, potSize);
|
||||||
|
|
||||||
|
AWTLoader loader = new AWTLoader();
|
||||||
|
Image output = loader.load(scaled, false);
|
||||||
|
|
||||||
|
image.setWidth(potSize);
|
||||||
|
image.setHeight(potSize);
|
||||||
|
image.setDepth(0);
|
||||||
|
image.setData(output.getData(0));
|
||||||
|
image.setFormat(output.getFormat());
|
||||||
|
image.setMipMapSizes(null);
|
||||||
|
}
|
||||||
|
|
||||||
public static void generateMipMaps(Image image){
|
public static void generateMipMaps(Image image){
|
||||||
BufferedImage original = ImageToAwt.convert(image, false, true, 0);
|
BufferedImage original = ImageToAwt.convert(image, false, true, 0);
|
||||||
int width = original.getWidth();
|
int width = original.getWidth();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user