* 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
3.0
sha..rd 14 years ago
parent b6386751e4
commit 90bf137894
  1. 7
      engine/src/core/com/jme3/renderer/Caps.java
  2. 36
      engine/src/desktop/com/jme3/system/JmeSystem.java
  3. 27
      engine/src/lwjgl-ogl/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java
  4. 21
      engine/src/lwjgl-ogl/com/jme3/renderer/lwjgl/LwjglRenderer.java
  5. 20
      engine/src/tools/jme3tools/converters/MipMapGenerator.java

@ -139,7 +139,12 @@ public enum Caps {
* Supports Format.LATC for textures, this includes
* support for ATI's 3Dc texture compression.
*/
TextureCompressionLATC,
TextureCompressionLATC,
/**
* Supports Non-Power-Of-Two (NPOT) textures and framebuffers
*/
NonPowerOfTwoTextures,
/// Vertex Buffer features
MeshInstancing,

@ -37,11 +37,14 @@ import com.jme3.app.SettingsDialog.SelectionListener;
import com.jme3.asset.AssetManager;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.audio.AudioRenderer;
import com.jme3.util.JmeFormatter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;
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.Logger;
import javax.swing.SwingUtilities;
@ -318,7 +321,6 @@ public class JmeSystem {
}
AudioRenderer ar = clazz.newInstance();
// ar = new QueuedAudioRenderer(ar);
return ar;
}catch (InstantiationException ex){
logger.log(Level.SEVERE, "Failed to create context", ex);
@ -336,28 +338,28 @@ public class JmeSystem {
return;
initialized = true;
// try {
// if (!lowPermissions){
// // can only modify logging settings
// // if permissions are available
//
// JmeFormatter formatter = new JmeFormatter();
try {
if (!lowPermissions){
// can only modify logging settings
// if permissions are available
JmeFormatter formatter = new JmeFormatter();
// Handler fileHandler = new FileHandler("jme.log");
// fileHandler.setFormatter(formatter);
// Logger.getLogger("").addHandler(fileHandler);
//
// Handler consoleHandler = new ConsoleHandler();
// consoleHandler.setFormatter(formatter);
// Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
// Logger.getLogger("").addHandler(consoleHandler);
//
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
// Logger.getLogger("com.jme3").setLevel(Level.FINEST);
// }
}
// } catch (IOException ex){
// logger.log(Level.SEVERE, "I/O Error while creating log file", ex);
// } catch (SecurityException ex){
// logger.log(Level.SEVERE, "Security error in creating log file", ex);
// }
} catch (SecurityException ex){
logger.log(Level.SEVERE, "Security error in creating log file", ex);
}
logger.log(Level.INFO, "Running on {0}", getFullName());

@ -1,5 +1,6 @@
package com.jme3.renderer.lwjgl;
import com.jme3.math.FastMath;
import com.jme3.renderer.GL1Renderer;
import com.jme3.shader.Shader;
import com.jme3.shader.Shader.ShaderSource;
@ -33,6 +34,7 @@ import java.nio.IntBuffer;
import java.util.EnumSet;
import java.util.logging.Logger;
import jme3tools.converters.MipMapGenerator;
import org.lwjgl.opengl.GLContext;
import static org.lwjgl.opengl.GL11.*;
@ -47,6 +49,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
private final FloatBuffer fb16 = BufferUtils.createFloatBuffer(16);
private final RenderContext context = new RenderContext();
private final GLObjectManager objManager = new GLObjectManager();
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
private int maxTexSize;
private int maxCubeTexSize;
@ -80,13 +83,21 @@ public class LwjglGL1Renderer implements GL1Renderer {
}
public EnumSet<Caps> getCaps() {
return EnumSet.noneOf(Caps.class);
return caps;
}
public void initialize() {
//glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
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() {
@ -470,6 +481,20 @@ public class LwjglGL1Renderer implements GL1Renderer {
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) {
// No pregenerated mips available,
// generate from base level if required

@ -34,6 +34,7 @@ package com.jme3.renderer.lwjgl;
import com.jme3.light.LightList;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix4f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
@ -316,6 +317,14 @@ public class LwjglRenderer implements Renderer {
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 atdc = ctxCaps.GL_ATI_texture_compression_3dc;
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) {
List<ByteBuffer> data = img.getData();
if (data.size() != 6) {

@ -32,6 +32,7 @@
package jme3tools.converters;
import com.jme3.math.FastMath;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.plugins.AWTLoader;
@ -58,6 +59,25 @@ public class MipMapGenerator {
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){
BufferedImage original = ImageToAwt.convert(image, false, true, 0);
int width = original.getWidth();

Loading…
Cancel
Save