Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  SPGL question  (Read 3053 times)
0 Members and 1 Guest are viewing this topic.
Offline bedelf

Junior Member




Are you suggesting coconuts migrate?


« Posted 2003-05-16 04:44:18 »

Is there a particular reason Resources needs a thread? I've never really had to allocate/deallocate memory for anything so this is the only thing I have to look at when I go to make my own.
Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #1 - Posted 2003-05-16 11:37:41 »

It doesn't need a thread, but it does make sure you're in the correct thread before you try and allocate anything natively. If no thread is specified for a particular resource it'll just immediately allocate or deallocate something.

The best example (and its raison d'etre) is allocating resources in GL. An instance of GL is only valid in the thread that created it, unless you switch contexts but that's a bit beyond the scope of LWJGL's requirements so we've hidden it away to make life simpler. So if you try to create a texture in another thread, what it does is queue the creation request in the GL thread and then waits for it to complete. This allows you to use background threads for asynchronously loading resources whilst in the main thread you can still keep a display running showing a progress bar or somesuch.

Cas Smiley

Offline bedelf

Junior Member




Are you suggesting coconuts migrate?


« Reply #2 - Posted 2003-05-16 12:34:15 »

So what your saying is, your a sexy, sexy man?

Thanks, I forgot about the whole GL-in-one-thread thing.

Edit: I'm still lost in your god damn code though. Tongue
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ap_kelly

Junior Member




Java rocks!


« Reply #3 - Posted 2003-05-17 05:28:35 »

I've not heard about this GL in a single thread bit before, where can I find more info?

I tried to put my printScreen logic into a seperate thread in order to avoid a hit on my FPS, which worked, unfortunately I got a blank screenshot, I'm guessing the gl.readPixels isn't working in my new thread, are there any work arounds for this? I did try passing in GL as a parameter to my method incase that made a difference, but it didn't.

Any ideas would be appreciated.

Andy.

Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #4 - Posted 2003-05-17 10:23:13 »

The short answer is no, there's no easy workaround without a load of hassle. So just do it in the main thread.

It's a well known fact about all implementations of GL (or Direct3D for that matter) that if you try doing things in the wrong thread your results are at best unpredictable.

The reason is that there is only one hardware device in your machine, and that device is in a particular state at any given instant. A thread maintains a thread-local copy of this state so it knows what commands to send the device when it tries to do something. No other threads will have access to this state. If you want to do GL commands in another thread, you have to load the state from hardware or synchronize it with whatever might be the master copy into that thread before you can start tweaking it. This is a concession to performance; if you had two threads trying to render two different things at the same time the hardware would have to constantly swap the state back and forth between the two threads  as they alternately grabbed control of it.

So we've just removed the feature from LWJGL altogether because it's too complicated and error prone. Just use the main thread to do GL commands.

Cas Smiley

Offline ap_kelly

Junior Member




Java rocks!


« Reply #5 - Posted 2003-05-18 21:06:47 »

Now this may be heading offtopic, but I'll ask here anyway.

I'm thinking of loading my world peice by peice as required in order to save memory, so I came up with the idea of splitting my world into sectors and only loading 9 at a time, the current one, and the 8 surrounding ones. If you leave your current sector I load in the extra ones in a seperate Thread to avoid any slowdown to the game. How would this work with GL only working in a single Thread, I'm guessing I'd have to load my extra sectors in the background and use some sort of notifier to let the main Thread know that they ready to be uploaded to the grahpics card, would you agree?

Edit: Reading through the earlier part of this thread, I may have a  look at GLTexture in the spgl stuff to see if that has the answer about background loading).

I'm also working on a simple widget set, buttons, labels etc for creating my menu system and preference screens. When I write the text onto the screen the backgrounds are black, do I need to setup an alpha channel in my png in order to make them transparent or is it a setting when I load/render my font that does this?

Thanks,

Andy.

Offline darcone

Junior Member




Size matters


« Reply #6 - Posted 2003-05-19 04:26:44 »

Ill take the freedom to answer this one Smiley

If you want to optimise your game then there are a few tricks you can try. If it is a 2D game you can try what I have implemented in my game:

1) Quad trees. Do a search on these, gamedev.net has a nice tutorial iirc and it is basically the "sectors" thing you mentioned but in a clever way. Using this you can implement Culling and smarter collision detection (instead of checking for collisions against all the objects in the world, you can check it only against the objects in range, even without doing sphere bounding first).

2) For the background, if you have a simple texture as the main background, ie a grass texture, you can create a quad that is just big enough to be visible on the screen, and instead of moving the quad (the background) when moving over it, you can move/animate the texture coordinates. This should save you some performance also as it means things you dont see would not be drawn (culling).

Hope this helps.
Offline ap_kelly

Junior Member




Java rocks!


« Reply #7 - Posted 2003-05-19 05:02:08 »

Thanks for the info, but it's not quite what I was after, I'll try to clarify...

The sector idea I'm tring to come up with is there because I want a huge world, I mean massive in every direction. So I'd use the quad tree idea but on a smaller part of my world, that would be the 9 sectors that I mentioned. When you move into a new sector I'd update the quad tree to remove the old sectors and add in the new ones. So what technique would I use to load the sectors in the background (with any new textures they require) if the GL context is single threaded?

The second point about my backgrounds, I was refering to the background of my texture that I use for my fonts, the background is black but I want it to be transparent when I render the font. Does this mean I have to set something up in the png, or is it a setting when I render the font?

Thanks,

Andy.

Offline darcone

Junior Member




Size matters


« Reply #8 - Posted 2003-05-19 07:49:36 »

It is something you have to remember when you create the png (create alpha channel etc), when you load the texture AND when you render it.
And the Quad tree, I don´t think you really got the idea. You only move objects in the quad tree when they change their position, you dont update the quad tree every frame. So the quad tree would optimally represent your whole world.
Offline ap_kelly

Junior Member




Java rocks!


« Reply #9 - Posted 2003-05-19 08:26:09 »

The world I hope to represent is going to be huge, I mean like global! I realise you don't change the quad tree every frame, what I'm proposing is to only change it when the player enters a new sector. The quad tree is then only containing the current 9 sectors (each one about 2km x 2km in size)  of information, not the 3000 sectors which make up the whole world.

I was wondering what techniques are available for loading in parts of the level during the execution of the game, especially since GL is single threaded and I may have to load in new textures...when the player moves from desert to forrest.

Andy.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2003-05-19 08:41:46 »

What you're talking about is not a GL rendering problem but a scenegraph manipulation problem.

All GL is for is drawing, nothing more. It doesn't know about worlds, only triangles and textures.

To load in your adjacent sectors you will certainly be better off using a separate thread for each sector to be loaded. Your main scenegraph view has a list of the loaded sectors, to which access is synchronized. When you request of the world that it loads a sector, it will immediately insert a blank sector in this list (synchronized of course), and start a thread to load the sector.

The sector's contents must be synchronized and waited upon. If you ask for the contents of a sector, because you are going to draw it, you must synchronize on it from the main thread and wait until it is loaded. The game will simply stop whilst this occurs, and there's very little you can do about it because it means otherwise you'd draw an empty void.

You will of course need to build a quadtree of the sector after it's loaded - unless you actually store your world as chunks of quadtree. This would be nice on a multiprocessor system but in a single processor system you're going to experience juddering because quadtree creation is processor intensive and it'll get in the way of the rendering.

I was thinking about using this technique for Multiple Injury but I discovered I could fit a massive looking world into 256x256. (Then I canned the whole project because it was too ambitious Wink )

Ah, and if you need to load a texture in, it can of course be loaded into Java heap space in the sector loading thread. However, the moment it's needed by GL, you'll have to get the GL rendering thread to upload it and wait() on that to happen.

Cas Smiley

Offline darcone

Junior Member




Size matters


« Reply #11 - Posted 2003-05-19 14:16:35 »

Multiple injury - some new game project of yours that I have missed princec? Smiley
Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #12 - Posted 2003-05-19 19:12:07 »

Nah, it was an old one, now living in a cupboard under the stairs. Online multiplayer kind of thing.

When we've got a million quid stashed away we'll start developing it again.

Cas Smiley

Offline bedelf

Junior Member




Are you suggesting coconuts migrate?


« Reply #13 - Posted 2003-05-20 01:11:36 »

Hmm. How is get() in Resources blocking when something was added but is waiting to be created? All I see it doing is calling allocate again.

What am I missing here?
Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #14 - Posted 2003-05-20 10:22:47 »

When you create an instance of SPGL "GL", it registers its class with Resources as being the allocator for things that say they use GL.

A GLTexture for example says "I use GL.class" when asked what allocator it is.

When asked to create(gl), the Resources finds out the thread that should be doing the allocation by asking the GL instance what thread it was constructed with. If it's the same as the current thread it just goes ahead; otherwise it waits() on being notifyed() by the allocator.

Now, the only way to get things to happen in this way is that in your main loop you call Resources.manage(), which takes care of queued requests to create stuff. I think that's what you're missing.

Your main loop needs to look something like this: (and this is largely the same for all LWJGL apps so take heed)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
public static void main(String[] args) {

      // Ensure that we reset the display mode. TODO: move this into LWJGL
     Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                  org.lwjgl.Display.resetDisplayMode();
            }
      });

      // Set up display, create gl etc.
     init();

      while (!finished) {

            // Perform OS specific windowing functions here:
           gl.tick();

            if (gl.isMinimized()) {
                  if (gl.isDirty())
                        gl.paint();
                  Thread.sleep(200);
                  continue;
            } else if (gl.isCloseRequested()) {
                  finished = true;
            }

            AbsMouse.poll();

            long then = Sys.getTime();

            // First do all your thinkin'
           doGameLogic();

            // Then do all your drawin'
           gl.clear(GL.COLOR_BUFFER_BIT);
            Interface.render();

            // Finally take care of queued requests in other threads
           Resources.manage();

            // Now let's start thinking about controlling the framerate
           if (GL.WGL_EXT_swap_control) {
                  long now = Sys.getTime();
                  frameTime = (float)(now - then) / (float)Sys.getTimerResolution();
            } else
                  frameTime = 0.0f;

            // Paint the display (swap buffers, clear dirty flag)
           gl.paint();

            float elapsed = 0.0f;
            do {
                  long now = Sys.getTime();
                  elapsed = (float)(now - then) / (float)Sys.getTimerResolution();
                  if (frameTime == 0.0f)
                        frameTime = elapsed;
                  if (elapsed < options.getFrameTime())
                        Thread.sleep((int)((options.getFrameTime() - elapsed) * 1000.0f));
            } while (elapsed < options.getFrameTime());


      }
}


Cas :)

Offline psiegel

Junior Member




Adamant about gaming.


« Reply #15 - Posted 2003-05-20 10:46:18 »

If I might interject a quick question here.  I don't mean to hijack this thread, but it hardly seemed worth it's own thread.  

Where exactly is SPGL?  I keep hearing about it, but I've never seen a download link.

Paul

Paul Siegel
Adamant Games, Inc.
http://www.adamantgames.com
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #16 - Posted 2003-05-20 11:04:28 »

here ya go:
www.sf.net/projects/spgl

it's Cas's dump of (some of the) classes he uses in developing his commercial game Alien Flux.

Offline bedelf

Junior Member




Are you suggesting coconuts migrate?


« Reply #17 - Posted 2003-05-20 19:14:16 »

No I understood most/all of that already. But what I didn't realize was in Resources.put()/get(), resourceMap != allocated.. looking at other peoples code is hard :/

So, what is going on here, when do you Resources.put()/get() and when are you just calling create(), or did you mean for the them to just be 2 different ways of allocating res?

In mine I just have it setup so that you have to call a create() type blocking method on the resource.
Offline princec

JGO Kernel


Medals: 364
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #18 - Posted 2003-05-20 19:39:38 »

Resources.put() just stuffs something in, uncreated, with a name attached to it so you can subsequently get() it. A call to get() automatically calls the appropriate create() with the correct allocator.

If you want to explicitly create resources, construct them as normal and just call create(...) with the correct allocator. For GenericResources the allocator can just be null, meaning there's nothing special going on that requires threads to get looked at.

Don't forget to destroy() stuff when you want it cleaned up properly. There's no corresponding method in Resources. If you subsequently get() it again it will be re-created just as before.

Cas Smiley

Offline bedelf

Junior Member




Are you suggesting coconuts migrate?


« Reply #19 - Posted 2003-05-20 20:06:38 »

Thanks for taking a moment. Smiley That's probably a good idea and I'll go ahead and put that in my crap too. sigh. Tongue
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (12 views)
2014-08-28 18:26:30

CopyableCougar4 (24 views)
2014-08-22 19:31:30

atombrot (37 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (29 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (28 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!