private static JmeCanvasContext context;
private static Canvas canvas;
private static Application app;
private static JFrame frame;
private static Container canvasPanel1, canvasPanel2;
private static Container currentPanel;
private static JTabbedPane tabbedPane;
private static final String appClass = "jme3test.post.TestRenderToTexture";
private static void createTabs(){
tabbedPane = new JTabbedPane();
canvasPanel1 = new JPanel();
canvasPanel1.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 1", canvasPanel1);
canvasPanel2 = new JPanel();
canvasPanel2.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 2", canvasPanel2);
frame.getContentPane().add(tabbedPane);
currentPanel = canvasPanel1;
}
private static void createMenu(){
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menuTortureMethods = new JMenu("Canvas Torture Methods");
menuBar.add(menuTortureMethods);
final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas");
menuTortureMethods.add(itemRemoveCanvas);
itemRemoveCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemRemoveCanvas.getText().equals("Remove Canvas")){
currentPanel.remove(canvas);
itemRemoveCanvas.setText("Add Canvas");
}else if (itemRemoveCanvas.getText().equals("Add Canvas")){
currentPanel.add(canvas, BorderLayout.CENTER);
itemRemoveCanvas.setText("Remove Canvas");
}
}
});
final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas");
menuTortureMethods.add(itemHideCanvas);
itemHideCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemHideCanvas.getText().equals("Hide Canvas")){
canvas.setVisible(false);
itemHideCanvas.setText("Show Canvas");
}else if (itemHideCanvas.getText().equals("Show Canvas")){
canvas.setVisible(true);
itemHideCanvas.setText("Hide Canvas");
}
}
});
final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2");
menuTortureMethods.add(itemSwitchTab);
itemSwitchTab.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (itemSwitchTab.getText().equals("Switch to tab #2")){
canvasPanel1.remove(canvas);
canvasPanel2.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel2;
itemSwitchTab.setText("Switch to tab #1");
}else if (itemSwitchTab.getText().equals("Switch to tab #1")){
canvasPanel2.remove(canvas);
canvasPanel1.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel1;
itemSwitchTab.setText("Switch to tab #2");
}
}
});
JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel");
menuTortureMethods.add(itemSwitchLaf);
itemSwitchLaf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t){
t.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
});
JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)");
menuTortureMethods.add(itemSmallSize);
itemSmallSize.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Dimension preferred = frame.getPreferredSize();
frame.setPreferredSize(new Dimension(0, 0));
frame.pack();
frame.setPreferredSize(preferred);
}
});
JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas");
menuTortureMethods.add(itemKillCanvas);
itemKillCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentPanel.remove(canvas);
app.stop(true);
createCanvas(appClass);
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
}
});
JMenuItem itemExit = new JMenuItem("Exit");
menuTortureMethods.add(itemExit);
itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
frame.dispose();
app.stop();
}
});
}
private static void createFrame(){
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
app.stop();
}
});
createTabs();
createMenu();
}
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
try{
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
}
public static void startApp(){
app.startCanvas();
app.enqueue(new Callable<Void>(){
public Void call(){
if (app instanceof SimpleApplication){
SimpleApplication simpleApp = (SimpleApplication) app;
simpleApp.getFlyByCamera().setDragToRotate(true);
}
return null;
}
});
}
public static void main(String[] args){
JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
createCanvas(appClass);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
createFrame();
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I get the error "non-power-of-2 framebuffer textures are not supported by the video hardware" Is there any way the code can be changed so that non-power-of-2 textures are not required?
Like @normen mentioned, they have to be 16x16, 32x32, 64x64, 128x128, 256x256, etc… I think the limit is either 4096x4096 or 8192x8192, most likely the former.
It may actually be a general requirement by the Canvas. I haven’t looked at the code and don’t have any stack traces to go on, but it seems to me that the Canvas support would try to be conservative such that a slight resize wouldn’t crash your app later.
But like I said… I have no familiarity with that code at all.
private static JmeCanvasContext context;
private static Canvas canvas;
private static Application app;
private static JFrame frame;
private static Container canvasPanel1, canvasPanel2;
private static Container currentPanel;
private static JTabbedPane tabbedPane;
private static final String appClass = "jme3test.post.TestRenderToTexture";
private static void createTabs(){
tabbedPane = new JTabbedPane();
canvasPanel1 = new JPanel();
canvasPanel1.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 1", canvasPanel1);
canvasPanel2 = new JPanel();
canvasPanel2.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 2", canvasPanel2);
frame.getContentPane().add(tabbedPane);
currentPanel = canvasPanel1;
}
private static void createMenu(){
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menuTortureMethods = new JMenu("Canvas Torture Methods");
menuBar.add(menuTortureMethods);
final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas");
menuTortureMethods.add(itemRemoveCanvas);
itemRemoveCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemRemoveCanvas.getText().equals("Remove Canvas")){
currentPanel.remove(canvas);
itemRemoveCanvas.setText("Add Canvas");
}else if (itemRemoveCanvas.getText().equals("Add Canvas")){
currentPanel.add(canvas, BorderLayout.CENTER);
itemRemoveCanvas.setText("Remove Canvas");
}
}
});
final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas");
menuTortureMethods.add(itemHideCanvas);
itemHideCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemHideCanvas.getText().equals("Hide Canvas")){
canvas.setVisible(false);
itemHideCanvas.setText("Show Canvas");
}else if (itemHideCanvas.getText().equals("Show Canvas")){
canvas.setVisible(true);
itemHideCanvas.setText("Hide Canvas");
}
}
});
final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2");
menuTortureMethods.add(itemSwitchTab);
itemSwitchTab.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (itemSwitchTab.getText().equals("Switch to tab #2")){
canvasPanel1.remove(canvas);
canvasPanel2.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel2;
itemSwitchTab.setText("Switch to tab #1");
}else if (itemSwitchTab.getText().equals("Switch to tab #1")){
canvasPanel2.remove(canvas);
canvasPanel1.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel1;
itemSwitchTab.setText("Switch to tab #2");
}
}
});
JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel");
menuTortureMethods.add(itemSwitchLaf);
itemSwitchLaf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t){
t.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
});
JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)");
menuTortureMethods.add(itemSmallSize);
itemSmallSize.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
frame.setSize(new Dimension(0, 0));
}
});
JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas");
menuTortureMethods.add(itemKillCanvas);
itemKillCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentPanel.remove(canvas);
app.stop(true);
createCanvas(appClass);
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
}
});
JMenuItem itemExit = new JMenuItem("Exit");
menuTortureMethods.add(itemExit);
itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
frame.dispose();
app.stop();
}
});
}
private static void createFrame(){
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
app.stop();
}
});
createTabs();
createMenu();
}
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
settings.setWidth(256);
settings.setHeight(256);
try{
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(256, 256);
}
public static void startApp(){
app.startCanvas();
app.enqueue(new Callable<Void>(){
public Void call(){
if (app instanceof SimpleApplication){
SimpleApplication simpleApp = (SimpleApplication) app;
simpleApp.getFlyByCamera().setDragToRotate(true);
}
return null;
}
});
}
public static void main(String[] args){
JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
createCanvas(appClass);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
createFrame();
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
The stack trace is
Code:
INFO JmeDesktopSystem 11:49:19 AM Running on jMonkeyEngine 3.0.0 Beta
INFO Natives 11:49:19 AM Extraction Directory: C:UserschrisworkspaceGame
INFO LwjglCanvas 11:49:20 AM MAIN: Creating OGL thread.
INFO LwjglAbstractDisplay 11:49:20 AM Using LWJGL 2.8.2
INFO GLCanvas 11:49:21 AM EDT: Telling OGL to create display ..
INFO LwjglCanvas 11:49:22 AM OGL: Pbuffer has been created
WARNING LwjglRenderer 11:49:22 AM Your graphics card does not support non-power-of-2 textures. Some features might not work.
INFO LwjglRenderer 11:49:22 AM Caps: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, OpenGL20, OpenGL21, ARBprogram, GLSL100, GLSL110, GLSL120, TextureCompressionLATC]
INFO LwjglContext 11:49:22 AM Adapter: atiumdag
INFO LwjglContext 11:49:22 AM Driver Version: 7.14.10.597
INFO LwjglContext 11:49:22 AM Vendor: ATI Technologies Inc.
INFO LwjglContext 11:49:22 AM OpenGL Version: 2.1.7769 Release
INFO LwjglContext 11:49:22 AM Renderer: ATI Radeon X1200
INFO LwjglContext 11:49:22 AM GLSL Ver: 1.20
INFO LwjglTimer 11:49:22 AM Timer resolution: 1,000 ticks per second
INFO DesktopAssetManager 11:49:23 AM DesktopAssetManager created.
INFO Camera 11:49:23 AM Camera created (W: 256, H: 256)
INFO Camera 11:49:23 AM Camera created (W: 256, H: 256)
INFO LwjglAudioRenderer 11:49:24 AM AudioRenderer supports 64 channels
INFO LwjglAudioRenderer 11:49:24 AM Audio effect extension version: 1.0
INFO LwjglAudioRenderer 11:49:24 AM Audio max auxilary sends: 4
INFO MaterialDef 11:49:24 AM Loaded material definition: Unshaded
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Gui Node)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (BitmapFont) attached to this node (null)
INFO Node 11:49:24 AM Child (null) attached to this node (Statistics View)
INFO Node 11:49:24 AM Child (Statistics View) attached to this node (Gui Node)
INFO Camera 11:49:25 AM Camera created (W: 512, H: 512)
INFO Node 11:49:25 AM Child (box) attached to this node (Root Node)
INFO LwjglCanvas 11:49:25 AM OGL: Creating display ..
INFO LwjglCanvas 11:49:25 AM OGL: Waiting for canvas to become displayable..
INFO LwjglCanvas 11:49:25 AM OGL: Creating display context ..
INFO LwjglRenderer 11:49:25 AM Deleting objects and invalidating state
INFO LwjglCanvas 11:49:26 AM OGL: Display is active!
SEVERE Application 11:49:26 AM Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: non-power-of-2 framebuffer textures are not supported by the video hardware
at com.jme3.renderer.lwjgl.LwjglRenderer.updateTexImageData(LwjglRenderer.java:1878)
at com.jme3.renderer.lwjgl.LwjglRenderer.updateRenderTexture(LwjglRenderer.java:1449)
at com.jme3.renderer.lwjgl.LwjglRenderer.updateFrameBufferAttachment(LwjglRenderer.java:1472)
at com.jme3.renderer.lwjgl.LwjglRenderer.updateFrameBuffer(LwjglRenderer.java:1508)
at com.jme3.renderer.lwjgl.LwjglRenderer.setFrameBuffer(LwjglRenderer.java:1590)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1104)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1162)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:266)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:227)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
at java.lang.Thread.run(Unknown Source)
INFO LwjglRenderer 11:49:26 AM Deleting objects and invalidating state
INFO LwjglMouseInput 11:49:26 AM Mouse destroyed.
INFO LwjglKeyInput 11:49:26 AM Keyboard destroyed.
INFO LwjglAbstractDisplay 11:49:26 AM Display destroyed.
I tried setting little output statements throughout the code(one at the beginning and end of each method) and everything is being run. Running it in debug mode in eclipse shows the error in the LWJGL Renderer Thread. The if statement that throws the error is
Code:
if (img.getData(0) == null) {
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
}
and starts on line 1877 in LwjglRenderer.java. Let me know if any more information is needed, and what.
If it were an error with the renderer I would think they’d be many posts about it already. Possible, but very unlikely. I’d be willing to bet one of your image is the wrong size.