Target = Linux + Windows : LWJGL or JOGL ?

Greetings, all. I’ve been out of circulation for several months but am trying to get going again here. I have worked thru a few of the tutorials ( need to revist a few though ) and am ready to start a basic game that I hope to build up in layers until it’s something interresting.

I’ve been a Linux advocate for many years and live as much of my e-life as possible behind X. However, I know M$ will continue to have the dominant share of target audiences for years to come. SO…I really want to be able to support both ( Mac support would be good, but not as critical to me at this time…personal reasons :stuck_out_tongue: ). I have been trying to catch back up on the last few months of topics here but haven’t found much meat on a specific issue that’s outstanding in my planning right now. Basically, if I want to support Linux & Windows in full screen mode ( with safe Alt-tab to other apps and back ), is either JOGL or LWJGL a better choice considering both OS targets?

The game itself is a mostly-strategic game along the lines of Master of Orion, etc. As such it is pretty much “flat” screens and I’m not trying to push pixles to their limits. I do hope to use a 3d space map with the ability to zoom in and out, but that’s not in the first-phase of release. It is starting off as two player + computer AI but I hope to expand it to up to a larger human player base in the mid-development time frame ( continued to be turn-based though with each player submitting thier turn’s orders to the server for processing and results sent back ). Likewise, I may want to expand the game to have a semi-3d space combat ( ships generally stay flat but player can swing the camera around and perform some zooming ) but again that’s candy that’s going to wait until I have a functional and fun game ( and may depend heavily on how I want multi-players to interract ).

I know this is a touchy subject that can easily kick off religious wars and I don’t want to go down that route. It’s just that right now I’m leaning to JOGL since I’ve had a little more reading experience with it and am “getting it” a little better right now, but if one is seriuosly better than the other for technical reasons I would appreciate the heads-up before I invest too much time.

advTHANKSance! :slight_smile:

-Lawrence

I think both support Linux as a first class platform.

If you use JOGL you’ll also want to use JInput and JOAL. All support WIndows, Linux and Mac :slight_smile:

If you use LWJGL I believe it has its own input and audio API, and it supports all 3 paltforms, so either way your covered.

What Jeff said.
However there is one technical reason - which may or may not be relevant for you - Jogl cannot do proper fullscreen on Linux, and (though not entirely sure about that) it cant do it completely reliable on Windows either.
But if you’re doing Windowed mode, that isn’t an issue.

Thanks for the pointers. “True” full screen on Linux may be an issue later, so I’ll have to do some early tests to see what I can do with an undecorated window. Depending on how well I can keep that reflecting the theme of the game it may make my decision for me. At least now I have a better direction to focus the little bit of free time I have. :wink:

-Lawrence

May I ask what your reasons are not to support Mac as of yet?
I found that it was basically effortless to get my emulator working on Mac using LWJGL. Chances are that if you include the mac binaries, it will ‘just work’.

Yep, it will just work… I’ve never even seen Ultratron running on a Mac!

I’d use whichever API suits your coding style better as they are functionally identical. LWJGL in most cases simplifies things for the common case of writing games though.

Cas :slight_smile:

I’m actually not planning on “excluding” Mac, but I just don’t have access or any experience with them ( since Apple days ). Since this is just hobby level for me for a while at least I plan on getting things the way I want on the platforms I can personally test. Once I pull in external testers I’ll try to find people w/ Mac to participate but it would really be based on who helps out and what kind of problems turn up.

Sorry…didn’t mean to give the impression I’m anti-Mac. I USED to be in the 80s, but those days are long gone. :stuck_out_tongue:

-L

Hmm.

Im not sure how much difference there is in fullscreen, honestly.

If you tell Java to create a FullScreen undecorated window it will look exactly the same as any other full screen display and I don’t believe there is any performance penalty.

I’ve done this with Java3D, though not with JOGL, for JNWN at times and its been just fine.

JK

Yes, but will it actually switch modes? AFAIK, java fullscreen support is limited to the current display mode, which is likely to be higher than what you want (if you have a resource-hungry game, you’d like to run it at 800x600 or 1024x768 on mediocre machines).

Note: I’m aware of the fact that java 6 has fixed this issue, but then we can take the details; like the fact that LWJGL can alt-tab out of fullscreen modes on supported window managers, while the java implementation can’t.

  • elias

Totally false.

You can use the DeviceContext to chnage display modes at will.

See this tutorial by Mike Martak

http://java.sun.com/docs/books/tutorial/extra/fullscreen/[quote]
[/quote]

I may be missing the point, but it’s never looked teh same in linux, and last time I checked, there was no way to change the resolution at all in linux with the JVM (but then, I dont actively use 1.5, so forgive me for foolishness if 1.5 has finally fixed this bug)

The API hooks are certainly there… Ill go grab one of Mike’s old tests and run it on my linux box to see what it does :slight_smile:

Okay, I decided its abotu time i starte dputting soime simple HUD stuff in JWNW so Im just going to use that as a test base.

Im going to try to use Dave Yazel’s J3D HUD stuff.

It may take me a week or so to put the mode setting dialog in. After ist in il ltest it on Linux and see what it does :slight_smile:

[/quote]
Check your facts:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4661156

The API is there alright, but it is reported as not supported (isDisplayChangeSupported() returns false). It is marked as fixed in mustang, as I said.

  • elias

So from the limited info I’ve posted about my basic needs it really boils down to LWJGL is the only option for true full-screen-exclusive mode under Linux. With JOGL the best I could do would be a “full-screen” undecorated window which is at the mercy of the user having their display set to the same as my game wants to use. If they are higher or lower then it will not look right and may, in fact, cause problems.

I thought I could live with the JOGL limitation, but the more I’m thinking about it the more I’m afraid to go down that path too far and find that full-screen really is as important to the visual of the game as I think it will be.

Follow-up question: Are there any concerns or gotcha’s in LWJGL’s behaviour under Linux?

-Lawrence

Thats falls into the rumor category. I do not believe it is true as the API celarly allows you to chnage mode.

I havent had a chance to test it yet but if thats going to be the deciding poitn for you I suggest you test it. Write a simple full-screen exclusive mode program that opens a window and tries to chnage the settings.

JK

Okay, because I HATE rumors I did the tests myself on SUSE 1.3.

The full screen display mode stuff as near as I can see is total nonsense.

JOGL uses AWT.

AWT goes fullscreen and sets the display mode just fine. Here’s the test code:


/*
  test @(#)DisplayModeTest.java	1.4 01/07/17
  @bug 4189326
  @summary Tests changing display mode
  @author martak@eng: area=FullScreen
  @ignore This test enters full-screen mode, if available, and should not
  be run as an applet or as part of the test harness.
*/

/**
 * This test generates a table of all available display modes, enters
 * full-screen mode, if available, and allows you to change the display mode.
 * The application should look fine under each enumerated display mode.
 * On UNIX, only a single display mode should be available, and on Microsoft
 * Windows, display modes should depend on direct draw availability and the
 * type of graphics card.
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

class DisplayModeModel extends DefaultTableModel {
    private DisplayMode[] modes;

    public DisplayModeModel(DisplayMode[] modes) {
        this.modes = modes;
    }

    public DisplayMode getDisplayMode(int r) {
        return modes[r];
    }

    public String getColumnName(int c) {
        return DisplayModeTest.COLUMN_NAMES[c];
    }

    public int getColumnCount() {
        return DisplayModeTest.COLUMN_WIDTHS.length;
    }

    public boolean isCellEditable(int r, int c) {
        return false;
    }

    public int getRowCount() {
        if (modes == null) {
            return 0;
        }
        return modes.length;
    }

    public Object getValueAt(int rowIndex, int colIndex) {
        DisplayMode dm = modes[rowIndex];
        switch (colIndex) {
            case DisplayModeTest.INDEX_WIDTH :
                return Integer.toString(dm.getWidth());
            case DisplayModeTest.INDEX_HEIGHT :
                return Integer.toString(dm.getHeight());
            case DisplayModeTest.INDEX_BITDEPTH : {
                int bitDepth = dm.getBitDepth();
                String ret;
                if (bitDepth == DisplayMode.BIT_DEPTH_MULTI) {
                    ret = "Multi";
                } else {
                    ret = Integer.toString(bitDepth);
                }
                return ret;
            }
            case DisplayModeTest.INDEX_REFRESHRATE : {
                int refreshRate = dm.getRefreshRate();
                String ret;
                if (refreshRate == DisplayMode.REFRESH_RATE_UNKNOWN) {
                    ret = "Unknown";
                } else {
                    ret = Integer.toString(refreshRate);
                }
                return ret;
            }
        }
        throw new ArrayIndexOutOfBoundsException("Invalid column value");
    }

}

public class DisplayModeTest extends JFrame implements ActionListener,
    ListSelectionListener {

    private boolean waiting = false;
    private GraphicsDevice device;
    private DisplayMode originalDM;
    private JButton exit = new JButton("Exit");
    private JButton changeDM = new JButton("Set Display");
    private JLabel currentDM = new JLabel();
    private JTable dmList = new JTable();
    private JScrollPane dmPane = new JScrollPane(dmList);
    private boolean isFullScreen = false;

    public static final int INDEX_WIDTH = 0;
    public static final int INDEX_HEIGHT = 1;
    public static final int INDEX_BITDEPTH = 2;
    public static final int INDEX_REFRESHRATE = 3;

    public static final int[] COLUMN_WIDTHS = new int[] {
        100, 100, 100, 100
    };
    public static final String[] COLUMN_NAMES = new String[] {
        "Width", "Height", "Bit Depth", "Refresh Rate"
    };

    public DisplayModeTest(GraphicsDevice device) {
        super(device.getDefaultConfiguration());
        this.device = device;
        setTitle("Display Mode Test");
        originalDM = device.getDisplayMode();
        setDMLabel(originalDM);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Make sure a DM is always selected in the list
        exit.addActionListener(this);
        changeDM.addActionListener(this);
        changeDM.setEnabled(device.isDisplayChangeSupported());
    }

    public void actionPerformed(ActionEvent ev) {
        Object source = ev.getSource();
        if (source == exit) {
            device.setDisplayMode(originalDM);
            System.exit(0);
        } else { // if (source == changeDM)
            int index = dmList.getSelectionModel().getAnchorSelectionIndex();
            if (index >= 0) {
                DisplayModeModel model = (DisplayModeModel)dmList.getModel();
                DisplayMode dm = model.getDisplayMode(index);
                device.setDisplayMode(dm);
                setDMLabel(dm);
                setSize(new Dimension(dm.getWidth(), dm.getHeight()));
                validate();
            }
        }
    }

    public void valueChanged(ListSelectionEvent ev) {
        changeDM.setEnabled(device.isDisplayChangeSupported());
    }

    private void initComponents(Container c) {
        setContentPane(c);
        c.setLayout(new BorderLayout());
        // Current DM
        JPanel currentPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        c.add(currentPanel, BorderLayout.NORTH);
        JLabel current = new JLabel("Current Display Mode : ");
        currentPanel.add(current);
        currentPanel.add(currentDM);
        // Display Modes
        JPanel modesPanel = new JPanel(new GridLayout(1, 2));
        c.add(modesPanel, BorderLayout.CENTER);
        // List of display modes
        for (int i = 0; i < COLUMN_WIDTHS.length; i++) {
            TableColumn col = new TableColumn(i, COLUMN_WIDTHS[i]);
            col.setIdentifier(COLUMN_NAMES[i]);
            col.setHeaderValue(COLUMN_NAMES[i]);
            dmList.addColumn(col);
        }
        dmList.getSelectionModel().setSelectionMode(
            ListSelectionModel.SINGLE_SELECTION);
        dmList.getSelectionModel().addListSelectionListener(this);
        modesPanel.add(dmPane);
        // Controls
        JPanel controlsPanelA = new JPanel(new BorderLayout());
        modesPanel.add(controlsPanelA);
        JPanel controlsPanelB = new JPanel(new GridLayout(2, 1));
        controlsPanelA.add(controlsPanelB, BorderLayout.NORTH);
        // Exit
        JPanel exitPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        controlsPanelB.add(exitPanel);
        exitPanel.add(exit);
        // Change DM
        JPanel changeDMPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        controlsPanelB.add(changeDMPanel);
        changeDMPanel.add(changeDM);
        controlsPanelA.add(new JPanel(), BorderLayout.CENTER);
    }

    public void setVisible(boolean isVis) {
        super.setVisible(isVis);
        if (isVis) {
            dmList.setModel(new DisplayModeModel(device.getDisplayModes()));
        }
    }

    public void setDMLabel(DisplayMode newMode) {
        int bitDepth = newMode.getBitDepth();
        int refreshRate = newMode.getRefreshRate();
        String bd, rr;
        if (bitDepth == DisplayMode.BIT_DEPTH_MULTI) {
            bd = "Multi";
        } else {
            bd = Integer.toString(bitDepth);
        }
        if (refreshRate == DisplayMode.REFRESH_RATE_UNKNOWN) {
            rr = "Unknown";
        } else {
            rr = Integer.toString(refreshRate);
        }
        currentDM.setText(
            COLUMN_NAMES[INDEX_WIDTH] + ": " + newMode.getWidth() + " "
            + COLUMN_NAMES[INDEX_HEIGHT] + ": " + newMode.getHeight() + " "
            + COLUMN_NAMES[INDEX_BITDEPTH] + ": " + bd + " "
            + COLUMN_NAMES[INDEX_REFRESHRATE] + ": " + rr
            );
    }

    public void begin() {
        isFullScreen = device.isFullScreenSupported();
        setUndecorated(isFullScreen);
        setResizable(!isFullScreen);
        if (isFullScreen) {
            // Full-screen mode
            device.setFullScreenWindow(this);
            validate();
        } else {
            // Windowed mode
            pack();
            setVisible(true);
        }
    }

    public static void main(String[] args) {
        GraphicsEnvironment env = GraphicsEnvironment.
            getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = env.getScreenDevices();
        // REMIND : Multi-monitor full-screen mode not yet supported
        for (int i = 0; i < 1 /* devices.length */; i++) {
            DisplayModeTest test = new DisplayModeTest(devices[i]);
            test.initComponents(test.getContentPane());
            test.begin();
        }
    }
}

I don’t believe that LWJGL handles this significantly differently then AWT/JOGL. At the end fo teh day both must go through X to get to OGL.

You are a true prince among coders, Jeff. :smiley: Thanks for taking some of your time to help clearing some fud. I’m trying to get my head above water with some work issues right now but will duplicate your test with my own environments as soon as I can.

-Lawrence

Thanks, but the code actually is Mike Martak’s, not mine.

I started to write a test, went to Mike’s excellent tutorial to remind myself of a few things and found it was already written for me in his examples ;D

As an interesting side note, this may have bene the start of the rumor, from Mike’s comments:


 * On UNIX, only a single display mode should be available, 

He was almost certainly referring to Solaris. This has to do with the weird ass way Solaris does X.
(On older Solaris boxes, believe it or not, display mode is set per-pixel. This allows cool things like different windows in different modes on the same screen but really complicates the whole issue.)