buffer error when loading milkshape textured model

Hi

I have managed to get the milkshape loader to load the 3d model(created in milkshape3d), and it was rendered correctly at my first attempt because i just made a simple sphere with no texture.

But when I try to use a model with a texture I get a strange error. The texture is a .bmp 128x128 size.

Heres the error: "
java.lang.IllegalArgumentException: Number of remaining buffer elements is 0, must be at least 4
at org.lwjgl.opengl.BufferChecks.checkBuffer(Unknown Source)
at org.lwjgl.opengl.BufferChecks.checkBuffer(Unknown Source)
at org.lwjgl.opengl.GL11.glMaterial(Unknown Source)
at najgl.model.ms3d.MilkshapeModel.draw(Unknown Source)
at Game.render(Unknown Source)
at Game.run(Unknown Source)
at Game.main(Unknown Source) "

I looked at the example in the najgl library to load a model in my game, and the Game.java file is based on the lwjgl example…, So because i use lwjgl 09 alpha i had to change many GL calls to GL11.GL etc… in the najgl library but everything worked until i made a model with a texture. The texture is also put at the correct location in the filesystem.

Maybe theres something i missed in the setup of lwjgl because I used the easy setup of Game.java example from lwjgl09, and the example game in najgl uses lots of gl calls that i dont understand.

Maybe Its just something with the buffers… ?

Here is the code of Game.java so you guys can take a look at what im doing.


/* 
 * Copyright (c) 2002 Light Weight Java Game Library Project 
 * 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 'Light Weight Java Game Library' 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. 
 */ 
 
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import najgl.model.Model;
import najgl.model.ms3d.MilkshapeModel;

import org.lwjgl.Sys; 
import org.lwjgl.input.Keyboard; 
import org.lwjgl.openal.AL; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.Window;
 
/** 
 * $Id: Game.java,v 1.3 2004/05/05 14:35:05 cix_foo Exp $ 
 * 
 * This is a <em>very basic</em> skeleton to init a game and run it. 
 * 
 * @author $Author: cix_foo $ 
 * @version $Revision: 1.3 $ 
 */ 
public class Game { 
  
 /** Game title */ 
 public static final String GAME_TITLE = "My Game"; 
  
 /** Desired frame time */ 
 private static final int FRAMERATE = 60; 
  
 /** Exit the game */ 
 private static boolean finished; 
  
 /** related to models */
 private static final boolean WIREFRAME = false;
 private static final boolean ANIMATED = false;
 private static String modelFilename = "data/mysphere.txt";
 private static Model model;
 
 /** My texture */
 //private static int texture;
  
 /** 
  * No constructor needed - this class is static 
  */ 
 private Game() {} 
  
 /** 
  * Application init 
  * @param args Commandline args 
  */ 
 public static void main(String[] args) { 
  try { 
   init(); 
   run(); 
  } catch (Exception e) { 
   e.printStackTrace(System.err); 
   Sys.alert(GAME_TITLE, "An error occured and the game will exit."); 
  } finally { 
   cleanup(); 
  } 
 } 
  
 /** 
  * Initialise the game 
  * @throws Exception if init fails 
  */ 
 private static void init() throws Exception { 
  // Create a fullscreen window with 1:1 orthographic 2D projection, and with 
  // mouse, keyboard, and gamepad inputs. 
  Window.create(GAME_TITLE); 
   
  // Enable vsync if we can 
  Window.setVSyncEnabled(true); 
   
  // Start up the sound system 
  AL.create();
  
  // Enable texture mapping 
  //GL11.glEnable(GL11.GL_TEXTURE_2D);
  
  // TODO: Load in your textures and models here etc.. 
  //texture = loadTexture("data/nehe.png");
  model = new MilkshapeModel(ANIMATED, WIREFRAME);
  model.load(modelFilename);
  if (WIREFRAME) {
        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
  } else {
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glShadeModel(GL11.GL_SMOOTH);
  }
  GL11.glTranslatef(100.0f, 100.0f, 0.0f);
  GL11.glScalef(5.0f,5.0f,5.0f);
 } 
  
 /**
       * Texture loading directly from LWJGL examples
       */
      /*private final static int loadTexture(String path) {
            Image image = (new javax.swing.ImageIcon(path)).getImage();

            // Exctract The Image
            BufferedImage tex = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
            Graphics2D g = (Graphics2D) tex.getGraphics();
            g.drawImage(image, null, null);
            g.dispose();

            // Flip Image
            AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
            tx.translate(0, -image.getHeight(null));
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
            tex = op.filter(tex, null);

            // Put Image In Memory
            ByteBuffer scratch = ByteBuffer.allocateDirect(4 * tex.getWidth() * tex.getHeight());

            byte data[] = (byte[]) tex.getRaster().getDataElements(0, 0, tex.getWidth(), tex.getHeight(), null);
            scratch.clear();
            scratch.put(data);
            scratch.rewind();

            // Create A IntBuffer For Image Address In Memory   
            IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
            GL11.glGenTextures(buf); // Create Texture In OpenGL   

            GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
            // Typical Texture Generation Using Data From The Image

            // Linear Filtering
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
            // Linear Filtering
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
            // Generate The Texture
            GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tex.getWidth(), tex.getHeight(), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);

            return buf.get(0); // Return Image Address In Memory
      }*/


/** 
  * Runs the game (the "main loop") 
  */ 
 private static void run() { 
  while (!finished) { 
   // Always call Window.update(), all the time 
   Window.update(); 
    
   if (Window.isCloseRequested()) { 
    // Check for O/S close requests 
    finished = true; 
   } else if (Window.isActive()) { 
    // The window is in the foreground, so we should play the game 
    logic(); 
    render(); 
    org.lwjgl.Display.sync(FRAMERATE); 
   } else { 
    // The window is not in the foreground, so we can allow other stuff to run and 
    // infrequently update 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
    } 
    logic(); 
    if (Window.isVisible() || Window.isDirty()) { 
     // Only bother rendering if the window is visible or dirty 
     render(); 
    } 
   } 
  } 
 } 
  
 /** 
  * Do any game-specific cleanup 
  */ 
 private static void cleanup() { 
  // TODO: save anything you want to disk here 
 
  // Stop the sound 
  AL.destroy(); 
   
  // Close the window 
  Window.destroy(); 
 } 
  
 /** 
  * Do all calculations, handle input, etc. 
  */ 
 private static void logic() { 
  // Example input handler: we'll check for the ESC key and finish the game instantly when it's pressed 
  if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { 
   finished = true; 
  } 
  // TODO: all your game logic goes here. 
  
 } 
  
 /** 
  * Render the current frame 
  */ 
 private static void render() { 
  GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT); 
  
  // TODO: all your rendering goes here 
  //GL11.glColor3f(30.0f,100.0f,140.0f);
   
  //GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture); // Select Our Texture
  //GL11.glRotatef(2.0f,0.0f,0.0f,1.0f);
  model.draw();
  
  
  

 } 
 
 
} 

:wink:

Must be a bug in najgl.model.ms3d.MilkshapeModel.draw(). Probably forgot to rewind the the buffer.

yes, but it works with his example, maybe something happened when i had to change som things to get it to work with lwjgl 0.9…

If anyone have a working example source of najgl+lwjgl0.9 then tell me what you did to get it to work with lwjgl0.9 :slight_smile: please :slight_smile:

You ever figure this out? I just made the appropriate .092 release adjustments, compiled and get the same buffer elemts must be 4 error.