LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: guillaumesmo on September 07, 2007, 20:32:50

Title: Problem rendering objects
Post by: guillaumesmo on September 07, 2007, 20:32:50
Hello everybody,

I've just made a small application, using LWJGL. I have added the OBJ loader of elias4444 to load objets in my 3D world. But the objets have a problem to load:

(http://www.livedj.be/documents/test.jpg)

Like you can see, the plane is not shown correctly.

How can I fix that ?

P.S.: Originally the plane was very very little inside the screen, so I have had to add a glScalef(10f,10f,10f) to be able to see it in an acceptable size.
Title: Re: Problem rendering objects
Post by: elias4444 on September 07, 2007, 21:31:31
There's several possible things that could be wrong there (one of which is my old code  :P ).

I would recommend trying it with culling turned off first though. It's possible that the normals are messed up with the object. Or, at least, that's what it kinda looks like.
Title: Re: Problem rendering objects
Post by: elias4444 on September 07, 2007, 22:33:45
I went ahead and updated my texturetester demo (includes source for OBJ loader and TrueType Font Renderer). Thought the updated code might help you out a bit too.

www.tommytwisters.com/texturetester.jar (http://www.tommytwisters.com/texturetester.jar)
Title: Re: Problem rendering objects
Post by: elias4444 on September 07, 2007, 22:52:34
I also went ahead and posted a webstartable version of the texture tester at:

www.tommytwisters.com/texture/texture.jnlp (http://www.tommytwisters.com/texture/texture.jnlp)

I figure, that way you can run it and see how your OBJ file loads up in another application.
Title: Re: Problem rendering objects
Post by: guillaumesmo on September 08, 2007, 20:24:53
Thank you for your application.

I'll paste my code here, could you take a look and tell me what's going wrong?

import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;

import java.io.BufferedReader;
import java.io.FileReader;

/**
* Basic game
*
* @author Name <email>
* @version 1.0
*/
public class Main {

  /** 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;

  /** Angle of rotating square */
  private static float angle;

  /**
   * Application init
   * @param args Commandline args
   */
  public static void main(String[] args) {
    boolean fullscreen = (args.length == 1 && args[0].equals("-fullscreen"));

    try {
      init(fullscreen);
      run();
    } catch (Exception e) {
      e.printStackTrace(System.err);
      Sys.alert(GAME_TITLE, "An error occured and the game will exit.");
    } finally {
      cleanup();
    }
    System.exit(0);
  }

  /**
   * Initialise the game
   * @throws Exception if init fails
   */
  private static void init(boolean fullscreen) throws Exception {
    // Create a fullscreen window with 1:1 orthographic 2D projection (default)
    Display.setFullscreen(fullscreen);
   
    Display.setTitle(GAME_TITLE);

    // Enable vsync if we can (due to how OpenGL works, it cannot be guarenteed to always work)
    Display.setVSyncEnabled(true);

    // Create default display of 640x480
    Display.create();
   
  }

  /**
   * Runs the game (the "main loop")
   */
  private static void run() {

    while (!finished) {
      // Always call Window.update(), all the time - it does some behind the
      // scenes work, and also displays the rendered output
      Display.update();

      // Check for close requests
      if (Display.isCloseRequested()) {
finished = true;
      }

      // The window is in the foreground, so we should play the game
      else if (Display.isActive()) {
        logic();
        render();
        Display.sync(FRAMERATE);
      }

      // The window is not in the foreground, so we can allow other stuff to run and
      // infrequently update
      else {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        logic();

// Only bother rendering if the window is visible or dirty
        if (Display.isVisible() || Display.isDirty()) {
          render();
        }
      }
    }
  }

  /**
   * Do any game-specific cleanup
   */
  private static void cleanup() {
    // Close the window
    Display.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;
    }

    // Rotate the square
    angle += 2.0f % 360;
  }
 
    /**
   * Render the current frame
   */
  private static void render() {
    // clear the screen
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);

    // center square according to screen size
    GL11.glPushMatrix();
    GL11.glTranslatef(Display.getDisplayMode().getWidth() / 2, Display.getDisplayMode().getHeight() / 2, 0.0f);

      // rotate square according to angle
      GL11.glRotatef(angle, 0f, 0f, 1.0f);

      // render the square
      GL11.glBegin(GL11.GL_QUADS);
        GL11.glVertex2i(-50, -50);
        GL11.glVertex2i(50, -50);
        GL11.glVertex2i(50, 50);
        GL11.glVertex2i(-50, 50);
      GL11.glEnd();

    GL11.glPopMatrix();
   
    GL11.glPushMatrix();
    GL11.glTranslatef(Display.getDisplayMode().getWidth() / 3, Display.getDisplayMode().getHeight() / 3, -5f);
    GL11.glRotatef(angle, 0, 1f, 0);
    GL11.glScalef(10f,10f,10f);
    try{
        FileReader fr = new FileReader("C:/java/obj/p51_mustang.obj");
        BufferedReader br = new BufferedReader(fr);
        Object3D letest = new Object3D(br,false);
        letest.opengldraw();
    } catch (Exception e) {
      e.printStackTrace(System.err);
      Sys.alert(GAME_TITLE, "Une erreur est survenue durant le chargement");
    }
    GL11.glPopMatrix();
   
  }
 
}


Thank you!
Title: Re: Problem rendering objects
Post by: guillaumesmo on September 09, 2007, 08:43:25
P.S.:

I've just implemented your new code into my application but I'm still having the same problem.
And, I can't see the plane in your Texture Tester.
Title: Re: Problem rendering objects
Post by: bobjob on September 09, 2007, 11:55:50
iv had problems like this when:

* culling was enabled.
* the model or ".obj" has not been triangulated.
* texture is not to the power of 2 (eg 32, 64, 128, 256...)
* or texture has alpha channels and alpha blending is enabled.
Title: Re: Problem rendering objects
Post by: elias4444 on September 09, 2007, 15:34:42
Have you tried loading a different OBJ file? I'm really thinking it may be the object itself.
Title: Re: Problem rendering objects
Post by: guillaumesmo on September 09, 2007, 16:41:50
Yes, I tried with objects that work in your application too.
Title: Re: Problem rendering objects
Post by: elias4444 on September 10, 2007, 03:14:02
Ok, I looked at your code, and I found a couple of things. One, you're loading the OBJ file every frame. You should preload it, and then just call the opengldraw() command in your render loop. Also, you should call Display.update() AFTER you've rendered everything in the loop. As it stands now, you update the display, only to clear it again in the same loop. You may be gettings drawing artifacts.

Try those things, and see what happens.
Title: Re: Problem rendering objects
Post by: guillaumesmo on September 10, 2007, 20:04:30
OK,

The FPS is now way faster (thanks)

But I'm still having the problem with the plane (and other objects)
Title: Re: Problem rendering objects
Post by: elias4444 on September 10, 2007, 22:30:14
Ok, lets work on your openGL init function:

You'll want to add some of these:


GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_NORMALIZE);
// Setup translucency
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_DITHER);

GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glEnable(GL11.GL_DEPTH_TEST);



This will enable materials, transparency, and setup depth testing and things.  Place it after your Display.create() call. Try it out, and let me know.
Title: Re: Problem rendering objects
Post by: guillaumesmo on September 12, 2007, 13:49:53
After adding your lines in the init method everyting disappreared.

After some searching, I have commented the line "GL11.glEnable(GL11.GL_DEPTH_TEST);", but now, I still have the same problem as in my very first post ...

May be you should try my code on your own computer, update it their, try what you can, and then say me if you found something.

Thank you very much
Title: Re: Problem rendering objects
Post by: elias4444 on September 13, 2007, 04:06:41
Here you go:

Issue was that you hadn't setup anything for depth, so 2D images would work fine, but not 3D. I also added the init functions you'd need for transparency and things.


import java.io.BufferedReader;
import java.io.FileReader;

import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import tools.Object3D;

/**
* Basic game
*
* @author Name <email>
* @version 1.0
*/
public class Main {

/** Game title */
public static final String GAME_TITLE = "My Game";

/** Exit the game */
private static boolean finished;

/** Angle of rotating square */
private static float angle;

/** The Object to Draw */
private Object3D letest;

/**
* Application init
* @param args Commandline args
*/
public static void main(String[] args) {
boolean fullscreen = (args.length == 1 && args[0].equals("-fullscreen"));

Main app = new Main();

try {
app.init(fullscreen);
app.run();
} catch (Exception e) {
e.printStackTrace(System.err);
Sys.alert(GAME_TITLE, "An error occured and the game will exit.");
} finally {
app.cleanup();
}
System.exit(0);
}

/**
* Initialise the game
* @throws Exception if init fails
*/
private void init(boolean fullscreen) throws Exception {
// Create a fullscreen window with 1:1 orthographic 2D projection (default)
Display.setFullscreen(fullscreen);

Display.setTitle(GAME_TITLE);

// Enable vsync if we can (due to how OpenGL works, it cannot be guarenteed to always work)
Display.setVSyncEnabled(true);

Display.setDisplayMode(new DisplayMode(640,480));

// Create default display of 640x480
Display.create();

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_NORMALIZE);
// Setup translucency
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_DITHER);

GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1.0);
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing

// OpenGL uses a backwards x,y coordinate system, so use GL_BACK for culling
GL11.glCullFace(GL11.GL_BACK);
GL11.glEnable(GL11.GL_CULL_FACE);

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity(); // reset projection matrix
GL11.glViewport(0,0,640,480);
GL11.glOrtho(-640/2,640/2,-480/2,480/2, -100f, 10000f);
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
GL11.glLoadIdentity();


try{
FileReader fr = new FileReader("C:/java/obj/p51_mustang.obj");
BufferedReader br = new BufferedReader(fr);
letest = new Object3D(br,false,"C:/java/obj/");
} catch (Exception e) {
e.printStackTrace(System.err);
Sys.alert(GAME_TITLE, "Une erreur est survenue durant le chargement");
}


}

/**
* Runs the game (the "main loop")
*/
private void run() {

while (!finished) {

// Check for close requests
if (Display.isCloseRequested()) {
finished = true;
}

// The window is in the foreground, so we should play the game
else if (Display.isActive()) {
logic();
render();
}

// The window is not in the foreground, so we can allow other stuff to run and
// infrequently update
else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
logic();

// Only bother rendering if the window is visible or dirty
if (Display.isVisible() || Display.isDirty()) {
render();
}
}
}
}

/**
* Do any game-specific cleanup
*/
private void cleanup() {
// Close the window
Display.destroy();
}

/**
* Do all calculations, handle input, etc.
*/
private 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;
}

// Rotate the square
angle += 2.0f % 360;
}

/**
* Render the current frame
*/
private void render() {
// clear the screen
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
GL11.glLoadIdentity();

// center square according to screen size
GL11.glPushMatrix();
//GL11.glTranslatef(Display.getDisplayMode().getWidth() / 2, Display.getDisplayMode().getHeight() / 2, 0.0f);
GL11.glTranslatef(0, 0, 0);

// rotate square according to angle
GL11.glRotatef(angle, 0f, 0f, 1.0f);

// render the square
GL11.glColor4f(1, 1, 1, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(-50, -50);
GL11.glVertex2i(50, -50);
GL11.glVertex2i(50, 50);
GL11.glVertex2i(-50, 50);
GL11.glEnd();

GL11.glPopMatrix();

GL11.glPushMatrix();
GL11.glTranslatef(-100f,-100f,0);
GL11.glRotatef(angle, 0, 1f, 0);
GL11.glScalef(10f,10f,10f);
letest.opengldraw();
GL11.glPopMatrix();

// Always call Window.update(), all the time - it does some behind the
// scenes work, and also displays the rendered output
Display.update();


}

}


Title: Re: Problem rendering objects
Post by: guillaumesmo on September 17, 2007, 21:02:22
Thank you very much!

It works on my PC too ;)

Indeed, I took the code on the wiki for rendering a square. I thought it would work for 3D too.

It was a bit confusing because there is no 3D example on the whole lwjgl.org website :(

But thanks,
you really helped me!