Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (429)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (468)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  RFE/Discussion : glCompressedTexImage2D  (Read 4516 times)
0 Members and 1 Guest are viewing this topic.
Offline Rob Nugent

Junior Member




May contain nuts


« Posted 2005-01-21 14:22:51 »

Hi All,

I'm making substantial use of S3 Texture compression and mipmapping. I can most efficiently obtain my texture data in a single byte array where the data for each of my mipmap levels appears sequentially in this byte array.

E.G. Typically this means that I have byte[10936] where

*) the first 8192 bytes are for mipmap level 1
*) the next 2048 bytes are for mipmap level 2
*) the next 512 bytes are for mipmap level 3
*) the next 128 bytes are for mipmap level 4
*) the next 32 bytes are for mipmap level 5
*) the next 8 bytes are for mipmap level 6
*) the next 8 (sic) bytes are for mipmap level 7
*) the next 8 (sic) bytes are for mipmap level 8

Now I have to give each of these mimap levels to JOGL via a call to:

1  
void       glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, int imageSize, byte[] data)


Now this method seems a bit perverse to me: I can specify whatever length of data I like (imageSize), but I have to supply it at the *front* of a byte array.

It also seems to have lost some of the spirit/intent of the wrappered C function which takes a pointer to the data and the length of the data, and so can be used to access data of arbitrary length in any arbitrary location.

What I'd like is a version of glCompressedTexImage2D that takes a byte array, length and *start offset* into that byte array.

Now I know that I can convert my single byte array into 8 smaller byte arrays, but this is a highly performance critical section of code (I'm using a *lot* of textures and can't preload them) and the extra CPU overhead and in particular the GC cost of the extra byte arrays is causing me problems.

Maybe I'm missing something here, and if so I'd be grateful if someone can point out any error, otherwise I'd welcome a discussion on this subject - I suspect that there are a number of other JOGL methods that suffer for the same issues.

Rob
Offline tom
« Reply #1 - Posted 2005-01-21 15:08:44 »

Use the version that takes a Buffer instead of a byte[]. Remember it must be a direct buffer. When you wan't to use a part of the buffer you slice it and give it to glCompressedTexImage2D. I'll also bet that using a buffer is faster than an array.

Offline Rob Nugent

Junior Member




May contain nuts


« Reply #2 - Posted 2005-01-21 16:49:49 »

Tom,

Thanks for the reply.

Quote
Use the version that takes a Buffer instead of a byte[]...


I don't happen to believe that using Buffers is appropriate for my application (due to amongst others things, page alignment issues with direct buffers that have bitten me badly in the past) , but to get into a discussion of Buffer vs. byte[] misses the point of what I'd like to discuss in this thread.

If I *were* using a Buffer I'd like to be able to call a variant of glCompressedTexImage2D and specify an arbitrary *sub-section* of that Buffer in exactly the same way that I want to be able to specify an subsection of a byte[].

Yes, I can slice() up a Buffer but this is an exactly analogous issue to being forced to carve up my byte[] into 8 smaller ones - the overhead *may* be less but I'm still being forced to jump through hoops by the JOGL API when a variant of glCompressedTexImage2D that took a subsection (offset/length) of a byte[]  (or indeed of a Buffer) would save me that trouble.

I consider it a deficiency of the JOGL API that it doesn't have these methods, and what I'd like to discuss in this thread is whether anyone agrees with me, and whether this is an appropriate case for an RFE.

Rob
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tom
« Reply #3 - Posted 2005-01-21 17:42:20 »

I think LWJGL got it right. Only buffers, and it uses the position and limit to specify wich part to use. I'm against arrays because the data has to be copied anyway. Wich removes it from the c api.

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #4 - Posted 2005-01-24 20:20:59 »

This is a matter of style. The GlueGen tool which autogenerates the JOGL binding attempts to use simple Java idioms for C constructs. For example, a C char** seen in a function signature is exposed to Java as a String[] and all necessary conversion is done under the hood. The New I/O direct buffer variant gives you the flexibility to slice up your data. I think the rest of the API would become too confusing if every outgoing array argument also had an offset.

The API is already too cluttered as it stands. For this reason we're discussing removing mappings like boolean[] -> void* and char[] -> void* in a future release.
Offline Rob Nugent

Junior Member




May contain nuts


« Reply #5 - Posted 2005-01-25 08:25:00 »

Ken,

I can't agree that this is simply a matter of 'style' - it is one of coherent API design and one of performance.

I am not in a position where using the (direct) Buffer variants of certain methods (including glCompressedTexImage2D and glDataBufferARB) provides me *any* benefit whatsoever, and they do cause me substantial drawbacks. If you think that this statement is contentious please say so, and I'd be happy to start another thread to explain in more detail - but direct Buffers are not a panacea for all applications.

I am therefore making substantial use of the variant of glCompressedTexImage2D discussed that takes a byte[] and also of glDataBufferARB that takes a float[].

Both of these methods also require an argument that specifies the size of the data supplied, but in each case the data can only begin at the start of the supplied array.

If the size argument in each case had been omitted and the length determined from the length of the array I could understand an argument from an API clarity point of view, but this would still leave the overhead of sometimes having to supply data to JOGL in an inconvenient format and e.g. incurring the cost of copying the data an extra time to supply a separate byte[] for each level of a mipmap.

The array and sub-range design pattern ( [], offset, length ) is common throughout other Java APIs. I don't see how using this pattern could be deemed 'confusing'.

What I do think is confusing is the scheme we have currently where arbitrary length data can be supplied but only starting at the *beginning* of an array, and also where data is supplied as one primitive type, but its length has to be supplied as a number of bytes. These are patterns I've *never* seen in another Java API. From my code:

1  
2  
3  
4  
5  
6  
float[] fa = tsa.getInterleavedFloatArray();
gl.glBufferDataARB(
 GL.GL_ARRAY_BUFFER_ARB,
 fa.length *BufferUtils.SIZEOF_FLOAT,
 fa,
 GL.GL_STATIC_DRAW_ARB);


So it's perfectly possible to supply, say, three and three-quarters floats worth of data. (It took me a *long* time to work out the length had to be in bytes rather than the number of floats).

To my mind, one of the biggest problems with JOGL is that many of the methods take arguments seemingly based on what it's easy to generate from gluegen, rather than what a programmer would want or need. I understand the reasons why this is currently the case, but it makes it very hard to program JOGL effectively unless you also have a good working knowledge of 'C', and the lack of meaningful javadoc that explains each argument doesn't help this problem.

I'm pleased to hear about the proposed removal of the (redundant) mappings such as  boolean[] -> void* and char[] -> void* which, in some cases,  I've never been able to see why anyone would ever want to call.

I'd be happy, by the way, if JSR231/JOGL *replaced* the (remaining) array,length methods with array,offset,length methods if you want to avoid cluttering the API with extra methods. In fact I'd *prefer* this, as I really do think that the array,length paradigm is utterly stupid as an API.

I hope the above doesn't come over as too much of a rant :-) These are real problems I've encountered and the changes I'm proposing would make JOGL more logical and easier and natural for a *Java* programmer to use.

Rob
Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #6 - Posted 2005-01-25 13:46:08 »

So, er, use LWJGL then, if it's that important.

Cas Smiley

Offline Rob Nugent

Junior Member




May contain nuts


« Reply #7 - Posted 2005-01-25 14:20:59 »

Quote
So, er, use LWJGL then, if it's that important.


Cas - the last time I looked, LWJGL only supported versions of glBufferDataARB and glCompressedTexImage2D which took Buffers, and as I've already explained Buffers cause problems for my particular app. Has this changed ? I seem to remember reading something on the LWJGL website saying that use of Buffer-only methods was one of the LWJGL design philosophies.

Rob
Offline Spasi
« Reply #8 - Posted 2005-01-25 14:32:50 »

The problem you have seems to be performance related. Since JOGL will copy your array(s) to buffers anyway (with or withour this RFE), I can't see why doing it yourself (probably more efficiently, since you can cache and reuse buffers as needed) will affect performance.

Besides, reading textures from disk and putting them in buffers (and then directly to GL) is more efficient with NIO.
Offline Rob Nugent

Junior Member




May contain nuts


« Reply #9 - Posted 2005-01-25 15:15:17 »

Spasi,

Quote
Since JOGL will copy your array(s) to buffers anyway...


I don't think it does. The native code for glCompressedTexImage2D just calls GetPrimitiveArrayCritical to get a pointer to the array data and then invokes the C function with this pointer.

Quote
Besides, reading textures from disk and putting them in buffers (and then directly to GL) is more efficient with NIO.


My textures (Around 330,000 of them) currently reside in a number of JAR files and are brought in via a ClassLoader.  As far as I can tell there isn't currently a way to get hold of a Channel derived from a file in a JAR and hence get the image data directly into a Buffer. If I could, I agree that I could use a bunch of recyclable Buffers along with the necessary derived slices (to specify the subranges of each mipmap level's data). Cracking open the JARs however seems to lead to even worse performance - I think probably because of the indvidual operating system file open-read-close overhead.

This however is getting off my intended point for this thread - JOGL seems to agree that versions of methods that take byte[], float[] etc are a valid thing to want to use, but don't supply a versions that take a subrange of such an array, and this would be very helpful regardless of whether there is a way of jumping through hoops to use a slightly friendlier JOGL method such as Buffers in any particular case.

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

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2005-01-25 17:19:56 »

If the JOGL team add offset & length to every method taking an array the API will double in size :/ That's the problem for them, it'll just bloat and bloat as they keep adding convenience methods all over the place. And if not every method then which ones and why?

LWJGL takes Buffers and you can simply set the position() and limit() to specify the range in the buffer you're actually talking about. This is more or less what you're after, and it's guaranteed safe by the NIO APIs.

One optimisation I have done in the past is load everything related into a HUGE buffer in one go and then split() that buffer up. That way you get very fast loading times. Or, at least, as fast as you can get with .jar resources. You may find that writing out jar resources to a temporary local cache and then memmapping them might work too.

Cas Smiley

Offline Rob Nugent

Junior Member




May contain nuts


« Reply #11 - Posted 2005-01-26 07:15:47 »

Cas,

As I said above, I'd be happy if JSR231 simply *replaced* the current byte[],length methods etc with byte[],offset,length methods - I think it was a mistake that this wasn't done in the first place as there really is no justification for having to specify the length of data in an array when that data can *only* start of the beginning of the array, which is what we have at the moment.

I believe that the only reason that the JOGL API is this way is because it was easier to generate methods of this signature with gluegen. I would have been more sympathetic if the current API simply took a byte[] of the relevant length, but it doesn't.

Your suggestion about having a very large buffer and subdividing it is reasonable, but it is experience with this very technique that has lead to some of my anitipathy towards buffers for *this* appllication (note that I'm *not* trying to make general points here, and I know that there are plenty of cases where buffers work well for people and I wouldn't suggest otherwise).

Much of my problem in this area stems from using buffers for my vertex, normal, texcoords data rather than for textures. Here's what happened:

1) My app is running fin on Win2K in 256MB of RAM
2) I move it to a SunBlade 2000 running Solaris 9 with a 1GB and the app uses all the available memory and swap space and had to be rebooted to recover.

Each object in my scene was using a direct byte buffer for vertex data. Unfortunately it turns out that direct buffers are page aligned on Solaris (and Linux, not sure about Win32) and so allocations of small direct buffers use a page size's worth of memory.

In my apps, each object in the scene owns its own vertex data, so there were lots of small (i.e. a fraction of the page size) direct byte buffers and the extra memory overhead on Solaris caused the problem.

Now, I'm not aware of this page alignment issue being documented anywhere other than in the following bug:

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

Note that I didn't raise this bug, someone else did who hit the same issue.

This more or less forces me to use your suggested technique with buffers i.e. that of allocating one or more large buffers and slicing that buffer whenever an object wants storage for vertices. etc.

This is fine for most apps, but for 2 of my apps, the 3D model doesn't fit into main RAM, and as the sub slices of the big buffers are 'allocated' and 'freed' as objects are added and removed from my model the buffers end up fragmented and only partially used and the burden on the RAM goes up.

If I wanted to implement malloc() and free() style routines for low-level memory management, I wouldn't have chosen Java as a programming language :-)

The other issue with Buffers for my apps is that I want efficient access to the vertex data to do things like collision detection, picking etc. With the vertex data in a direct Buffer access to it is very inefficient. If you can afford to duplicate the vertex data, this problem doesn't occur, but if  you are RAM constrained, you can't do that.

Finally, Buffers do *not* give me any meaningful speed advantage - I'm using static draw VBOs and the vertex data gets whacked down to the card exactly once using glBufferDataARB with the vertex, normal, tcoord data specified in an interleaved float[] array and the rendering is hellishly fast.

Rob
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #12 - Posted 2005-01-26 21:53:30 »

Rob:

You're right that the current JOGL API signatures are in a form convenient for GlueGen to produce from the corresponding C APIs.

I agree with you that to be more like other Java APIs that array arguments in JOGL should have an "offset" parameter immediately following the array. However, there is a problem in doing so. There are many places in the OpenGL APIs where the "size" or "length" of the data needs to be passed down as well. Currently we know nothing about the semantics of these values and perform no translation when passing them down to C, so these lengths are all specified in bytes as in the OpenGL specification. However, everywhere in the Java APIs, array offsets are expressed in "number of elements of the array". If we trivially added an array offset argument, and it were expressed in array elements rather than bytes, it would conflict with the byte-sized length arguments specified elsewhere in the OpenGL API and cause confusion. If we added enough information to GlueGen so it accepted all lengths for OpenGL APIs in terms of element sizes rather than bytes, the API would diverge very significantly from the C API. One of the concrete goals of JOGL and JSR-231 is to map to the underlying C API in a transparent manner to avoid confusing programmers coming to Java from C.

Another option would be to add a byte offset argument wherever the JOGL APIs accept primitive arrays. This would at least match the OpenGL APIs, but would force the application programmer to know the element size of Java arrays. This is already necessary in some cases for direct buffers, though; see the BufferUtils.SIZEOF_ constants and their uses in the JOGL demos. There are problems with this approach too. It would be easy to cause a crash on some platforms by feeding in a byte offset that isn't a multiple of the array element size. It also doesn't match Java style exactly. However, it is at least consistent with the OpenGL style of apecifying lengths in terms of bytes.

What  do you think about these possible approaches?

Direct buffer usage, at least FloatBuffer and other types, should be very fast wth HotSpot. ByteBuffer is currently more of a problem (fixes for this problem are coming), but if you cast your direct ByteBuffers to MappedByteBuffer you should see very high speed with those buffer types as well. I would think that you could store your data in a large FloatBuffer and still get efficient access for collision detection and other purposes. Take a look at the source code for the Grand Canyon demo (an update of that demo to use JOGL rather than GL4Java is presently underway); it performs collision detection against the ground, the data for which is contained in a direct ShortBuffer (16-bit ground heights).

I agree that the issue of direct buffer alignment on certain OSs is nasty. I added (Sun-internal) comments to bug 4820023. If memory consumption for small direct buffers were more reasonable, would it be easier for you to use them in your application?
Offline Rob Nugent

Junior Member




May contain nuts


« Reply #13 - Posted 2005-01-27 07:06:52 »

Ken,

Many thanks for the comprehensive reply.

Before I reply in detail on the offset/length issue, can you give me some examples of the 'byte-sized length arguments specified elsewhere in the OpenGL API' with which you are concerned that moving to a number-of-elements approach would conflict.

I don't feel that I understand this concern properly and had got half way through typing a lengthy reply before I realize that this might be the crux of the matter, and I should understand it more fully.

[EDIT] Surely there's nobody suggesting that 'all length parameters in JOGL must be in bytes' ? [/EDIT]

Thanks for you comments on Buffers - there are some interesting things there, and I might start another thread to discuss them - From the start I've *tried* to keep this thread focused on the [],length,offset API design issue which I think is independent of any application's ability to  use buffers or not.

[EDIT:] thread is here:

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl;action=display;num=1106820725;start=0#0

Rob
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #14 - Posted 2005-01-27 21:49:54 »

Quote
Before I reply in detail on the offset/length issue, can you give me some examples of the 'byte-sized length arguments specified elsewhere in the OpenGL API' with which you are concerned that moving to a number-of-elements approach would conflict.


The 'stride' argument to glVertexPointer and (several) similar functions; the 'size' argument to the glCompressedTexImage functions; the 'size' argument to the glBufferData functions; the 'len' argument to glProgramStringARB; the 'stride' argument to glReplacementCodePointerSUN; the 'length' argument to glVertexArrayRangeNV; the 'ustride' and 'vstride' arguments to glMapControlPointsNV and others; and the 'size' and 'stride' arguments to glNewObjectBufferATI and similar functions. There may be others.

After going through the headers, I'm actually surprised how few instances of this construct there are given the size of the OpenGL API. There are definitely instances where lengths are given in terms of the number of elements in an array, not in bytes (see, for example, glFeedbackBuffer); this occurs where the array is strongly typed, e.g. GLfloat* or GLint*.

I learned a fair bit by going through these examples. I now think that it wouldn't be as confusing as I thought to supply array offset arguments. However, this would affect the JOGL API fairly drastically; there are a _lot_ of routines that take pointers as arguments. I can also think of some APIs where providing the offset doesn't make much sense, such as those taking C strings, which are converted to take Java Strings by GlueGen; these would require special casing. In fact, I wonder whether we should provide array offset arguments on a case-by-case basis; the compressed texture routines are a clear case where they should be present, and I can think of others where it would be convenient but not essential.

What do you all think? Is this something that should be brought up in the JSR 231/239 expert groups? At this point I think it should at least be discussed. Please post and provide examples where this would help if you can. Rob, thanks for raising the issue and providing your concrete example.
Offline Rob Nugent

Junior Member




May contain nuts


« Reply #15 - Posted 2005-01-28 08:28:42 »

Ken,

First a disclaimer - I really like JOGL and think this is a great opportunity for the JSR231 experts group to clean up one of few big things that are wrong, so I hope the following doesn't come across as negative comment.

I think that the issue here is actually very simple. Let me come at this a little tangentially:

Java is a more strongly typed language than C, and many features of the language/runtime are designed explictly to prevent the programmer doing the sort of 'stupid' things that are easy in C.

Let's initially consder arrays: arrays in Java are arrays of some primitive or some Object. All the array sematics in every API in the java.* and javax.* hierarchy are based on indexes and 'number of elements' - the length of a float[] is returned in number-or-elements and not bytes. Those APIs that take array subranges work the same way.

Other Java APIs are similar- e.g. If you want a substring of a String the API is based on indexing, and not on byte-offset.

This is fundamental to the way Java works.

Now let's look at Buffers. From the Javadoc from java.nio.Buffer:

Quote

A buffer is a linear, finite sequence of elements of a specific primitive type. Aside from its content, the essential properties of a buffer are its capacity, limit, and position:
A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.
A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.
A buffer's position is the index of the next element to be read or written. A buffer's position is never negative and is never greater than its limit.


So Buffers work in the same way. e.g. The limit, position of FloatBuffer is an element index not a byte offset. The capacity of a FloatBuffer is the number of elements it contains not its size in bytes. If I invoke get(7) on a FloatBuffer it returns the float at index 7, and does not attempt to access a float from byte offset 7 (thus protecting me from unaligned accesses etc).

So, everything in Java is consistent - numbers of elements, and index numbers of elements - everywhere, arrays, Buffers, Strings.

Except JOGL.

I therefore suggest that JOGL should move to a similar scheme. Yes - it's incompatible with the current API, but the current API is just plain wrong - e.g. The current ability to pass 17 bytes worth of floats (whatever that might mean) to JOGL on glBufferDataARB called with a float[] and length.

The perception that somehow all lengths on the JOGL API should be in bytes in order to be helpful to C programmers porting applications is horribly mistaken - those programmers are going to have to cope with the Java way of doing things and having, say, to call glDataBufferARB with a float[] and a length-in-bytes is just horribly confusing for anyone including a C 'newbie', given that they'll probably have just called System.arraycopy() or some other method that deals in indexes to populate the very same array that they are passing to JOGL.

I was a professional C programmer for 5 years for IBM, and have worked in product development in Java since late 1995 (including 3 years at Sun), and I have to say that it's currently almost impossible to program to the current JOGL APIs to any degree of sophistication without knowing both languages. It took me a long time to work out that glBufferDataARB(..,float[], length,...) took a length in bytes as it just didn't match my expectation as a Java programmer. Also the code doesn't crash, it just give the wrong rendering results. I also find BufferUtils.bufferOffset unspeakable.

The current JOGL style does not help C newbies - it'll simply serve to confuse them further. (They'll be too busy wondering where the preprocessor went anyhow :-) ). The current style is positively broken for any experienced Java programmer.

Note also, that a C programmer sticking to byte[] and ByteBuffer can consider the offset and lengths to be byte offsets etc if he/she wishes, although I suggest that they just need to get out of the C mindset when coding Java.

So, my proposals:

1) Methods that take (or that need to be enhanced to take) subranges of arrays should take the offset and length in the traditional Java way (not byte offsets). e.g.

glBufferDataARB(...,float[], offset, length,...)

I can't see a need for more than one method like this for each array type, (float[] etc) by the way, as the above is flexible and fast. If you want to have a version that just takes a float[] and no offset or length, but just uses the whole contents of the array, that's fine, and is consistent with the Java style, but might be considered to be cluttering the API. The current version that take float[] and length but no offset is pointless and should be removed. (I am more than happy with the idea of only adding methods that take subranges where a need is identified, provided that 'bloat' is not used as a counter-argument once a need is identified).

2) Methods that take Buffers should have a way of specifying subranges also where a need is identified. I quite like the LWJGL style, which uses the Buffer's position and limit to specify the subrange, although I think that stylistically the following would also be acceptable:

glBufferDataARB(..., FloatBuffer, offset, length) where the offset and length are in the Java style, i.e. Indexes not byte offsets. As an illustration of how a Java programmer would think about this is that logically the implementation of this method is going to call get(i) on the FloatBuffer where i goes from offset to (offset + length - 1) to access the data, all nice and consistent. I don't have a strong opinion about which of these two is preferable.

[aside]
The current JOGL implementation defines these methods as taking Buffer, rather than a number of methods that take FloatBuffer, ByteBuffer etc as per LWJGL. I think that the latter style is preferable as it reinforces the message about the contents of the Buffer concerned being of the given type. I suspect that we have the current setup due to the desire to avoid API 'bloat' - a concern which I think is being given too much priority - methods should be present wherever logical and necessary and helpful.
[/aside]


These changes are plainly incompatible with the current behaviour of JOGL. However the current behaviour is a critical issue, that MUST be addressed by JSR231 and the expert group. We are lead to believe that the package names will be changing anyhow, so that'll be the time to sort things out.

The JOGL APIs that currently take a spurious length but no offset should be removed and replaced either with a version that takes length/offset where appropriate or with a version that takes no length or offset (e.g. Remove the size from glProgramStringARB)

I think that the methods you mentioned in your post should all fall to the above logic i.e. they should work in the manner consistent with the parameters supplied in the normal Java way of working, be that parameter a String, array, or Buffer. I'm unfamilar with a couple of them such as glMapControlPointsNV but suspect they'll fall out consistently as well.

A final comment: I've ever only come across one other Java API (A com.ibm.* API which I hesitate to identify further) that made the sort of 'mistakes' that we currently see in JOGL API. Whenever referred to in our office it was derided as 'that API written by C programmers'. I hope that the JSR231 experts group can avoid the same mistake.

Rob
Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #16 - Posted 2005-01-28 10:13:20 »

Damn it why don't the sodding JSR group just take LWJGL as their base starting point??? I just can't believe the whole API has been ignored despite, it seems, getting everything completely right.

Cas Smiley

Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #17 - Posted 2005-01-28 11:09:59 »

NIH  Huh

Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #18 - Posted 2005-01-28 14:47:01 »

Yeah, maybe I'm just trolling anyway.

Cas Smiley

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #19 - Posted 2005-01-28 17:41:06 »

LWJGL does not handle multiple OpenGL contexts on multiple threads due to its use of a global function pointer table for OpenGL entry points. Am I wrong about this?

If I'm correct, a complete rearchitecture of LWJGL would be necessary in order to support multiple windows correctly. The first thing that would have to change is LWJGL's use of static methods to represent OpenGL entry points. Look at GLEW (http://glew.sourceforge.net/) and their multithreading support; they have per-context function tables, and since they don't represent the GL in an object-oriented fashion they have to do a lookup in thread-local storage per function call.

I don't think there is a case of NIH here. Cas was invited (by me) to join the 231 expert group but so far has contributed only a couple of emails to the discussion.
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #20 - Posted 2005-01-28 20:19:17 »

Quote
I therefore suggest that JOGL should move to a similar scheme.


Rob: thanks for your detailed post. I agree that in many cases an array offset should be able to be supplied. I am sure this is going to come up in the JSR 231/239 expert groups, and I'll point the EG to this thread so they can see the ongoing discussion.

I also agree that LWJGL's use of the position of direct buffers to indicate a pointer in to the buffer is a good idea. It avoids the need to slice() the buffers and is an analogue to providing the offset for arrays.

The expert groups (and me personally as well) are not concerned with maintaining backward compatibility to the existing JOGL APIs. The JSR 231/239 APIs will look different in some fundamental ways and the switch to those APIs a good time to make large changes like these.
Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #21 - Posted 2005-01-28 21:21:23 »

I'm just watching JSR231 with interest but have little useful to contribute. Some of the participants don't appear to do very much OpenGL coding though.
LWJGL is fully able to work with multiple contexts and multiple threads. In fact, we could implement JOGL in terms of LWJGL.

Cas Smiley

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #22 - Posted 2005-01-28 22:45:25 »

Quote
LWJGL is fully able to work with multiple contexts and multiple threads.


Can multiple OpenGL contexts be current simultaneously on multiple threads in LWJGL? To be more precise, if you have OpenGL contexts ctxA and ctxB and threads A and B, can thread A have ctxA current at the same time that thread B has ctxB current?
Offline elias

Senior Member





« Reply #23 - Posted 2005-01-29 06:27:34 »

No, LWJGL can't handle multiple contexts from multiple threads at the same time. However, I hope that other parts of the LWJGL design will be seriously considered in the JSR (the way we handle Buffer position() and limit() and the way we allow (checked) int offsets into VBO/PBOs being two good ideas in my opinion)

- elias

Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #24 - Posted 2005-01-29 10:34:30 »

...LWJGL can't handle it directly, but then, neither can OpenGL hardware. To use LWJGL in multiple threads with multiple contexts, you synchronize on the GLContext class. As only one thread can actually render with OpenGL at any time this is the most efficient manner of using it. Trying to do otherwise results in absolutely appalling performance.

Cas Smiley

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #25 - Posted 2005-01-29 22:44:25 »

Quote
No, LWJGL can't handle multiple contexts from multiple threads at the same time. However, I hope that other parts of the LWJGL design will be seriously considered in the JSR (the way we handle Buffer position() and limit() and the way we allow (checked) int offsets into VBO/PBOs being two good ideas in my opinion)


I agree that there are many good ideas in LWJGL and the use of Buffers' limit() and position() is one in particular that we didn't think of when originally designing JOGL that are going to come up again in the expert group. The problem I see with passing offsets down into VBO-related methods is that the OpenGL binding then has to know what methods are affected by the VBO specification and provide alternative entry points, which doesn't seem maintainable to me. There are a lot of gl*Pointer entry points hidden in various extensions.

Are there other elements of LWJGL's design that you think we should consider? Hiding of most of the GL_INT / GL_FLOAT data types going down to OpenGL? Others?
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #26 - Posted 2005-01-29 22:47:37 »

Quote
...LWJGL can't handle it directly, but then, neither can OpenGL hardware. To use LWJGL in multiple threads with multiple contexts, you synchronize on the GLContext class. As only one thread can actually render with OpenGL at any time this is the most efficient manner of using it. Trying to do otherwise results in absolutely appalling performance.


I won't argue with you about the performance issue, at least on most consumer cards; higher-end hardware, in particular that which supports multiple graphics cards, usually performs better. However, the OpenGL specification allows multiple threads to perform OpenGL rendering to multiple contexts simultaneously, so for generality the JSR-231 and 239 specifications must support this, even if it's discouraged in general use.
Offline elias

Senior Member





« Reply #27 - Posted 2005-01-29 23:02:03 »

Not everyone agrees on this, but I particularly like the way we split up OpenGL into separate classes, one for each "extensions: GL11, GL12, ARBVertexBufferObject and so on.

Also, but LWJGL _never_ allocates objects in normal OpenGL operation (buffer swapping and calling OpenGL functions), to ensure as smooth animation as possible. I'm not sure the JOGL policy in this, but it sure is a nice property.

- elias

Online princec

JGO Kernel


Medals: 285
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #28 - Posted 2005-01-30 12:31:46 »

I do wonder that you might be overcomplicating JOGL in an attempt to please everybody and ending pleasing nobody Sad How many systems out there are your bog standard 1-or-2 CPU, single consumer class 3D card on an AGP bus, single monitor system versus oddball workstations with multiple graphics cards? I'd say the ratio was something like 99.9999% and to make the entire API cater for the 0.00001% of uses at the expense of a ton of complexity is a bit baffling. After all most of the rest of the Java APIs are a big concession to lowest common denominators, or hacked together slightly inefficiently Wink

Cas Smiley

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #29 - Posted 2005-01-30 14:55:54 »

Quote
Not everyone agrees on this, but I particularly like the way we split up OpenGL into separate classes, one for each "extensions: GL11, GL12, ARBVertexBufferObject and so on.


I like this too. We've considered doing at least the GL11, GL12, etc. split in the expert group; I don't know whether we reached a firm decision on it. There's something I don't understand about the splitting of the extensions in to different classes, though. Frequently an extension will accept not only the tokens it defines, but also many other GL_ constants from either the core or another extension, as a parameter to a certain function. How do you organize the extension classes in this case? As one example, I see you've cleverly made e.g. ARBVertexBufferObject and ARBPixelBufferObject extend ARBBufferObject; do you have other examples of this?

Is all of the LWJGL OpenGL interface code handwritten, or do you have any tools that help automate the process?

Quote
Also, but LWJGL _never_ allocates objects in normal OpenGL operation (buffer swapping and calling OpenGL functions), to ensure as smooth animation as possible. I'm not sure the JOGL policy in this, but it sure is a nice property.


JOGL does allocate a few objects during makeCurrent() and free() due to the structure of the glue code that GlueGen makes for the JAWT. It doesn't allocate anything during the calling of OpenGL routines. One of the members of the expert group, Alex Radeski, has done some profiling of the code and was/is trying to eliminate these object allocations.
Pages: [1] 2
  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.

theagentd (6 views)
2014-04-24 23:00:44

xsi3rr4x (83 views)
2014-04-15 18:08:23

BurntPizza (75 views)
2014-04-15 03:46:01

UprightPath (86 views)
2014-04-14 17:39:50

UprightPath (69 views)
2014-04-14 17:35:47

Porlus (86 views)
2014-04-14 15:48:38

tom_mai78101 (109 views)
2014-04-10 04:04:31

BurntPizza (169 views)
2014-04-08 23:06:04

tom_mai78101 (265 views)
2014-04-05 13:34:39

trollwarrior1 (217 views)
2014-04-04 12:06:45
Escape Analysis
by Roquen
2014-04-25 10:38:58

Escape Analysis
by Roquen
2014-04-25 10:22:13

List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51
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!