LWJGL Forum

Programming => OpenGL => Topic started by: imnotanerd on January 13, 2011, 02:44:38

Title: Why isn't this working?
Post by: imnotanerd on January 13, 2011, 02:44:38
Ok, it is. But not how i wanted it. It just shows a black screen when it's really supposed to show a rotating cube

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

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;

  /** 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.setTitle(GAME_TITLE);
    Display.setFullscreen(fullscreen);

    // 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, 0, 0, 1.0f);
      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();
  }
}

Title: Re: Why isn't this working?
Post by: jediTofu on January 13, 2011, 03:02:32
[1]
Display.update(); & Display.sync(...) should probably be at the end of your loop cycle:
while(!finished) {
  //all other code
  Display.update(); //this also swaps back & front buffers
  Display.sync(FRAMERATE);
}

[2]
I don't see any OpenGL initialization code, such as glViewport, gluOrtho2D, glOrtho, gluPerspective, etc.
I guess you're going off of the default values?  Hopefully your rendering accounts for this.

[3]
In render, instead of glPushMatrix, you probably want this:
GL11.glMatrixMode(GL_MODELVIEW);
GL11.glLoadIdentity();
Title: Re: Why isn't this working?
Post by: imnotanerd on January 13, 2011, 04:22:12
Quote from: jediTofu on January 13, 2011, 03:02:32
[1]
Display.update(); & Display.sync(...) should probably be at the end of your loop cycle:
while(!finished) {
  //all other code
  Display.update(); //this also swaps back & front buffers
  Display.sync(FRAMERATE);
}

[2]
I don't see any OpenGL initialization code, such as glViewport, gluOrtho2D, glOrtho, gluPerspective, etc.
I guess you're going off of the default values?  Hopefully your rendering accounts for this.

[3]
In render, instead of glPushMatrix, you probably want this:
GL11.glMatrixMode(GL_MODELVIEW);
GL11.glLoadIdentity();

I did all that, and it still came up as a black screen. Here is another example of code i used to draw figures, but still shows a black screen:


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

public class game {
private boolean done = false;
private boolean fullscreen = false;
private final String windowTitle = "Lesson 1";
private boolean f1 = false;
private DisplayMode displayMode;

/**
     * Everything starts and ends here.  Takes 1 optional command line argument.
     * If fullscreen is specified on the command line then fullscreen is used,
     * otherwise windowed mode will be used.
     * @param args command line arguments
     */

public static void main(String args[]) {
boolean fullscreen = false;
if (args.length > 0) {
if (args[0].equalsIgnoreCase("fullscreen")) {
fullscreen = true;
}
}
game gamez = new game();
gamez.run(fullscreen);
}

    /**
     * Launch point
     * @param fullscreen boolean value, set to true to run in fullscreen mode
     */
public void run(boolean fullscreen) {
this.fullscreen = fullscreen;
try {
init();
while (!done) {
mainloop();
render();
Display.update();
}
cleanup();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}

   /**
     * All updating is done here.  Key and mouse polling as well as window closing and
     * custom updates, such as AI.
     */
private void mainloop() {
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
done = true;
if (Display.isCloseRequested())
done = true;
if (Keyboard.isKeyDown(Keyboard.KEY_F1)) {
f1 = true;
switchmode();
}
if (!Keyboard.isKeyDown(Keyboard.KEY_F1))
f1 = false;
}

private void switchmode() {
fullscreen = !fullscreen;
try {
Display.setFullscreen(fullscreen);
} catch (Exception e) {
e.printStackTrace();
}
}

  /**
     * For rendering all objects to the screen
     * @return boolean for success or not
     */
private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glLoadIdentity();
GL11.glTranslatef(-1.5f, 0.0f, -6.0f);
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glVertex3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
GL11.glVertex3f(1.0f, -1.0f, 0.0f);
GL11.glEnd();
GL11.glTranslatef(3.0f, 0.0f, 0.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
GL11.glVertex3f(1.0f, 1.0f, 0.0f);
GL11.glVertex3f(1.0f, -1.0f, 0.0f);
GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
GL11.glEnd();
}

   /**
     * Create a window depending on whether fullscreen is selected
     * @throws Exception Throws the Window.create() exception up the stack.
     */
private void createWindow() throws Exception {
Display.setFullscreen(fullscreen);
DisplayMode d[] = Display.getAvailableDisplayModes();
for (int i = 0; i < d.length; i++) {
if (d[i].getWidth() == 640 && d[i].getHeight() == 480 && d[i].getBitsPerPixel() == 32) {
displayMode = d[i];
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle(windowTitle);
Display.create();
}

    /**
     * Do all initilization code here.  Including Keyboard and OpenGL
     * @throws Exception Passes any exceptions up to the main loop to be handled
     */
private void init() throws Exception {
createWindow();
initGL();
}

    /**
     * Initialize OpenGL
     *
     */
private void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1.0);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_EQUAL);

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();

// calculate the apsect ratio of the window
GLU.gluPerspective(45.0f,
           (float)displayMode.getWidth() / (float)displayMode.getHeight(),
           0.1f,
           100.0f);
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
}

/**
* Cleanup all the resources
*
*/
private void cleanup() {
Display.destroy();
}
}


# Tip - In Eclipse, I included both lwjgl.jar and lwjgl_utils.jar
Title: Re: Why isn't this working?
Post by: lwjuggler on January 16, 2011, 09:57:08
Hello Imnotanerd,

I modified your code to make it work, so i added some lines wit  // ADDED at the end, and some other comments. Hope it will help you.



package utils;

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

public class game {
private boolean done = false;
private boolean fullscreen = false;
private final String windowTitle = "Lesson 1";
private boolean f1 = false;
private DisplayMode displayMode;

/**
* Everything starts and ends here. Takes 1 optional command line argument.
* If fullscreen is specified on the command line then fullscreen is used,
* otherwise windowed mode will be used.
*
* @param args
*            command line arguments
*/

public static void main(String args[]) {
boolean fullscreen = false;
if (args.length > 0) {
if (args[0].equalsIgnoreCase("fullscreen")) {
fullscreen = true;
}
}
game gamez = new game();
gamez.run(fullscreen);
}

/**
* Launch point
*
* @param fullscreen
*            boolean value, set to true to run in fullscreen mode
*/
public void run(boolean fullscreen) {
this.fullscreen = fullscreen;
try {
init();
while (!done) {
//mainloop();
render();
Display.update();
}
cleanup();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}

/**
* All updating is done here. Key and mouse polling as well as window
* closing and custom updates, such as AI.
*/
private void mainloop() {
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
done = true;
if (Display.isCloseRequested())
done = true;
if (Keyboard.isKeyDown(Keyboard.KEY_F1)) {
f1 = true;
switchmode();
}
if (!Keyboard.isKeyDown(Keyboard.KEY_F1))
f1 = false;
}

private void switchmode() {
fullscreen = !fullscreen;
try {
Display.setFullscreen(fullscreen);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* For rendering all objects to the screen
*
* @return boolean for success or not
*/
private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glLoadIdentity();
GLU.gluLookAt(0, 0, 50, 0, 0, 0, 0, 1, 0); // ADDED
GL11.glTranslatef(-1.5f, 0.0f, -6.0f);
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glVertex3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
GL11.glVertex3f(1.0f, -1.0f, 0.0f);
GL11.glEnd();
GL11.glTranslatef(3.0f, 0.0f, 0.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
GL11.glVertex3f(1.0f, 1.0f, 0.0f);
GL11.glVertex3f(1.0f, -1.0f, 0.0f);
GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
GL11.glEnd();

// IMPORTANT for further (animation)
GL11.glFlush(); // ADDED
}

/**
* Create a window depending on whether fullscreen is selected
*
* @throws Exception
*             Throws the Window.create() exception up the stack.
*/
private void createWindow() throws Exception {
Display.setFullscreen(fullscreen);
DisplayMode d[] = Display.getAvailableDisplayModes();
for (int i = 0; i < d.length; i++) {
if (d[i].getWidth() == 640 && d[i].getHeight() == 480 && d[i].getBitsPerPixel() == 32) {
displayMode = d[i];
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle(windowTitle);
Display.create();
}

/**
* Do all initilization code here. Including Keyboard and OpenGL
*
* @throws Exception
*             Passes any exceptions up to the main loop to be handled
*/
private void init() throws Exception {
createWindow();
initGL();
}

/**
* Initialize OpenGL
*
*/
private void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
//GL11.glClearDepth(1.0); // COMMENTED
GL11.glEnable(GL11.GL_DEPTH_TEST);
//GL11.glDepthFunc(GL11.GL_EQUAL); // COMMENTED

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
// NOT NECESSARY, but useful, in case you resize your window
GL11.glViewport(0, 0, 640, 480); // ADDED
// calculate the apsect ratio of the window
GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 100.0f);
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

// IMPORTANT to come back to model view
GL11.glMatrixMode(GL11.GL_MODELVIEW); // ADDED
GL11.glLoadIdentity(); // ADDED
}

/**
* Cleanup all the resources
*
*/
private void cleanup() {
Display.destroy();
}
}
Title: Re: Why isn't this working?
Post by: Matthias on January 16, 2011, 10:26:50
There is no need to call glFlush() or glFinish() when using Display.update().

Also the glViewPort is already set correct by OpenGL after creating the Display.

Why did you enable GL_TEXTURE_2D when you don't load any texture or supply vertex coordinates?
Title: Re: Why isn't this working?
Post by: lwjuggler on January 16, 2011, 12:33:10
I didn't know for glFlush() and glFinish().

But for glViewport, I put it in case the window is resized, in this case does the Display class automatically change the viewport ?

PS : in java, a class begins with an UpperCase letter ;)
Title: Re: Why isn't this working?
Post by: Matthias on January 16, 2011, 12:58:45
If you want the Display to be resizable then you need to use setParent() and put it into an java.awt.Frame and register listeners on the Canvas to handle resizing.
See TWL Theme Editor's Main.java (http://hg.l33tlabs.org/twlthemeeditor/file/9387cfd97413/src/de/matthiasmann/twlthemeeditor/Main.java#l131) for details.