Any Last Requests?

Started by princec, February 12, 2004, 09:05:33

Previous topic - Next topic

cfmdobbie

Request: org.lwjgl.LWJGLException, a subclass of java.lang.Exception; to be thrown by both Java and native code wherever a vanilla Exception is currently being thrown.

One line that exists in every single LWJGL application that should have no reason to exist anywhere in nature is "throws Exception".  Please remove the need for it!
ellomynameis Charlie Dobbie.

cfmdobbie

Question: Why is a colour depth passed to Window.create()?

I expect there's a really simple reason for it that I just haven't realised.  It looks a little odd passing in a colour depth to change display mode, then passing it in again to create the window.  What happens if I pass in different values each time?  When would I want to do just that?

I know different windows can use different palettes, but surely it's not possible to create for example a 32-bit window on a 16-bit desktop, under any operating system anywhere?
ellomynameis Charlie Dobbie.

cfmdobbie

Request: As the new "samples" behaviour is slightly off-the-wall, can we have another couple of Window.create() methods that don't require it to be passed please?

It's perfectly acceptable for LWJGL to assume 0 samples if nothing is specified, but it's not acceptable for people to have to make a decision as to how many "samples" they want just to create a window.  Allow people who care to specify it, but don't scare off or confuse those who don't know what it means.
ellomynameis Charlie Dobbie.

elias

Actually your argument about the samples parameter can be applied to most of the other arguments also. Should we create a dumbed down overloaded create that only took a width, height (+x,y and title if windowed?) and that used some default values (min 16 bit color, 16 bit depth, 0 bit stencil and 0 samples)? I've seen a few times where a user couldn't understand that the depth buffer didn't work until pointed at the min. depth argument of Window.create.

- elias

cfmdobbie

Quote from: "elias"Actually your argument about the samples parameter can be applied to most of the other arguments also.

Agreed!  I don't know how many people actually want an alpha component in their on-screen windows, but I expect it's very few.  Stencil buffers are used a lot more, but I'm sure they're still not used by the majority.

As LWJGL is intended to be used by graphics developers, I don't think it's unreasonable to request a colour depth and depth buffer precision - maybe have two variants: (width, height, bpp, depth) to allow people to get up and running without any hassle, and (width, height, bpp, depth, alpha, stencil, samples, etc) for those who want/need more control.
ellomynameis Charlie Dobbie.

cfmdobbie

Quote from: "elias"[...] that only took a width, height (+x,y and title if windowed?)

Just an observation on this line - currently you need to pass in a window title even for a full-screen window.  On one hand I think this is probably a good thing - if the system just can't go full-screen it's reasonable for LWJGL to guess at positioning the window at (0,0), but there's no sensible default for a window title.  However, on the other hand, what percentage of computers won't be able to go full-screen?  It seems a rather unlikely state of affairs, at the moment.

However, I guess the real reason for it is that it makes for a useful task-bar representation if focus moves away from the full-screen window. :?
ellomynameis Charlie Dobbie.

cfmdobbie

Mouse.destroy():

/**
	 * "Destroy" the mouse. Remember to reset the native cursor if
	 * setNativeCursor() has been called with anything else than null.
	 */
	public static void destroy() {
		assert currentCursor == null;
		if (!created)
			return;
		created = false;
		buttons = null;
		currentCursor = null;

		nDestroy();
	}


Remember to reset the native cursor.  Why force the user to do this?  This is just basic cleanup work.  If you're going to take the time to trash the VM with a failed assert, why not just do the cleanup instead?

setNativeCursor(null);



Mouse.create():

public static void create() throws Exception {
    
		assert Window.isCreated() : "Window must be created prior to creating mouse";
    
		if (!initialized) {
			initialize();
		}
		if (created) {
			return;
		}
		nCreate();
		hasWheel = nHasWheel();
		created = true;
		currentCursor = null;

		// set mouse buttons
		buttonCount = nGetButtonCount();
		buttons = new byte[buttonCount];
	}


Inconsistent.  If the window hasn't been created yet you throw an assert in debug mode and continue otherwise, but if you've already created a mouse you silently ignore any extra calls to create.

I would have thought that creating a mouse without a valid window should have the same result irregardless of whether or not asserts are enabled, while creating a mouse multiple times should be a recognised error on the part of the programmer.  Thoughts?
ellomynameis Charlie Dobbie.

princec

You are absolutely correct, we are replacing all asserts with runtime exceptions.

I am also wondering: why don't we automatically create and destroy all the devices we can get our hands on when the window is created? They cost bugger all memory or startup time and are essential to 99% of all LWJGL apps. So we might just hide create and destroy and just leave isCreated() public. What do you think of that?

I'm really in favour of simplifying the API as much as possible.

I'd also like a Window.create() that took no args at all and just created a fullscreen window at the current colour depth, 16 bit depth, 8 bits stencil if possible. I want people to be able to totally initialise LWJGL with just that call.

I don't yet see any value in a LWJGLException class. Either the call worked, or it didn't. The whole checked exception argument in Java is supposed to make more robust code but it simply makes programming more annoying and difficult without actually increasing robustness.

Cas :)

cfmdobbie

Quote from: "princec"You are absolutely correct, we are replacing all asserts with runtime exceptions.
Lovely!  Having played with asserts for a while now, I've decided that they have one purpose - internal sanity checks.  They should never be used for anything else, as such use always causes problems and confusion down the line.

However your RuntimeExceptions work, please make them consistent! ;)

QuoteSo we might just hide create and destroy and just leave isCreated() public. What do you think of that?
Sounds good!  That will also get rid of the old which object do I destroy first? problem.  If it's possible for LWJGL to handle all this, don't make the user do it.

QuoteI don't yet see any value in a LWJGLException class. Either the call worked, or it didn't. The whole checked exception argument in Java is supposed to make more robust code but it simply makes programming more annoying and difficult without actually increasing robustness.
This isn't a checked or unchecked argument - it's just removing references to "Exception".  Specific libraries should throw specific and known exceptions - even if that exception is just a single "whoops".

Being able to catch all LWJGL exceptions but leave others to propagate is very useful.  Declaring that a method "throws Exception" is just plain ugly.  Just by throwing an LWJGLException instead of an Exception, you make the example code much easier to read and understand.  And it'll only cost you a ~500 byte class.
ellomynameis Charlie Dobbie.

princec

Ok, bunch of stuff commited:

- Now there's a really easy way to start a LWJGL application:
Window.create("My 733t New Game");


- And here's a typical main loop:
while (!Window.isCloseRequested()) {
	if (Window.isMinimized()) {
		// When minimized, we don't need to do anything except sleep
		try {
			Thread.sleep(100);
		} catch (InterruptedException inte) {
		}
	} else {
		// Do "game" logic, and render
		logic();
		render();
	}

	// Do everything related to window processing
	Window.update();
}


- And here's the cleanup code:
Window.destroy();
Display.resetDisplayMode();


Regular watchers will observe the complete removal of the Window.paint() method, which I have determined is completely unnecessary, and all the controller creation, polling, buffer reading, and cleanup is done automatically for you.

The Window now even puts itself straight into 1:1 pixel aspect ratio orthographic projection mode for you when it's created.

Samples parameter is now optional.

Cas :)

blah

That is one *sexy* main loop  :lol:.

However, am I right in thinking that that is also the most advanced tutorial currently available for LWJGL development?  :roll:

Morgrog

You are sort of right :)

but I suggest you d/l the preview 0.89 available from sourceforge (www.lwjgl.org too!) and check the source code for the test programs

the openal PositionalTest.java one is pretty fun (left-center-right-left-center-right-left... and so on and so on) :D

you might also want to check Java Cool Dude's examples available in this thread. It's fun stuff :)

cfmdobbie

Request: As there's been a major change to the initialisation and destruction code, and also to the main loop, could we have an "unofficial" 0.891 release please?
ellomynameis Charlie Dobbie.

cfmdobbie

Re: LWJGLException.

Thanks guys, fantastic! :D  :D  :D
ellomynameis Charlie Dobbie.

elias

The real 0.9 is due in a week or two anyway, so that shouldn't be nescessary. 0.9 is meant to be an API review anyway.

I checked in a few of your changes too:

1. LWJGLException is used where Exceptions is used today. You can argue that we need a more finegrained exception hierarchy, but I didn't bother.
2. All asserts have been converted to appropriate runtime exceptions.
3. I added a version check to guard against jar<->dll mismatch.
4. The buffering input events now preserve the events that are not read by the application, up until the buffer is filled, instead of starting from scratch at each .read(). That fixes the problem of calling Window.update() (which calls .read()) more than once before actually reading events from the input devices.

- elias