skytomorrownow
|
 |
«
Posted
2009-08-03 19:08:01 » |
|
I am working with GL identifier ints, and have a very quick question: is there a why to pass a field/variable identifier to a function for initialization in Java? So far, this gives me errors: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ScratchPad { public static void main( String[] args ) { ScratchPad s = new ScratchPad();
int monkey = 0;
s.test( monkey );
System.out.println( monkey ); }
private void test( int ID ) { ID = 3; } } |
output = 0, instead of expected 3. I am just trying to understand why. This little mini program just illustrates the point. In a perfect world I'd like to have something like this: 1 2 3 4
| int vertexShaderID;
compileShader( vertexShaderID, GL.GL_VERTEX_SHADER, vertexShaderSource ); |
However, this only works if I have initialized vertexShaderID before passing it into the function. The sample program above encapsulates what is happening. If I don't assign the ID before calling compileShader OpenGL sends and error. I'd like the compileShader function to assign the ID with the call to gl.glCreateShader instead of doing that before the function is called. Thanks for any insights.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #1 - Posted
2009-08-03 19:13:28 » |
|
In Java, an object passed through a method is automatically passed by reference, and a primitive is passed by value, and there is no way to distinguish. The solution, therefore, is to use an Integer object instead of an actual int, or return an int and assign it.
Integer i = new Integer(5);
|
|
|
|
skytomorrownow
|
 |
«
Reply #2 - Posted
2009-08-03 19:15:02 » |
|
Sweet. Thanks demonpants! Makes total sense.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Riven
|
 |
«
Reply #3 - Posted
2009-08-03 20:40:02 » |
|
Ofcourse not. An Integer instance is immutable, so you cannot change its value. Just write your own class 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
| class Int { public int value;
public Int(value) { this.value = value; }; }
public class ScratchPad { public static void main( String[] args ) { ScratchPad s = new ScratchPad();
Int monkey = new Int(0);
s.test( monkey );
System.out.println( monkey ); }
private void test( Int ID ) { ID.value = 3; } } |
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
skytomorrownow
|
 |
«
Reply #4 - Posted
2009-08-03 20:53:30 » |
|
OK, well I did post in clueless newbies! lol. But, I get the point now: primitives are assigned, and passed by value, so I would have to have an Object with a null to pass to a function for initialization if I wanted that. I think I get it now.
Thanks both for fast replies.
|
|
|
|
Riven
|
 |
«
Reply #5 - Posted
2009-08-03 20:57:01 » |
|
No offense intended, 'ofcourse not' was a reply to DemonPants who suggested using Integer
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
Eli Delventhal
|
 |
«
Reply #6 - Posted
2009-08-03 21:26:53 » |
|
Ofcourse not. An Integer instance is immutable, so you cannot change its value.
Yes, of course you're right... you always seem to be the person who catches my mistakes. Also if you have an object and then you create a new version of it when inside your function, you're going to lose your pointer which is what you need. 1 2 3 4 5 6 7 8 9
| public void function(Object o, Object p) { o.setWhatever(value);
p = new Object(); } |
Any Object in Java is really just a pointer to an Object of that type. So if you have an Integer, it's a pointer to a wrapper class that contains an int. When you call new again, you're basically reassigning the pointer, and your old object gets removed by the garbage collector. Soooo... the advice I gave you was doubly wrong.
|
|
|
|
skytomorrownow
|
 |
«
Reply #7 - Posted
2009-08-03 21:36:40 » |
|
Thanks Riven and Demon. OK, so after looking through the OpenGL spec, I guess I am OK initializing integers for use as Program and Shader IDs to 0 since zero is reserved and will never be issued as an ID from the GL. So, I guess, the whole question was wrong! lol. Oh well, I am glad for the refresher from both of you. That's one of the funny things about JOGL is that you are thinking part C, part Java.
cheers!
|
|
|
|
cylab
|
 |
«
Reply #8 - Posted
2009-08-03 21:56:16 » |
|
Another common way of doing this is to pass an array. Since an array is an object, it is passed as reference. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ScratchPad { public static void main( String[] args ) { ScratchPad s = new ScratchPad();
int[] monkey = new int[1];
s.test( monkey );
System.out.println( monkey ); }
private void test( int[] id ) { id[0] = 3; } } |
looks ugly though. 1 2 3 4
| int vertexShaderID;
compileShader( vertexShaderID, GL.GL_VERTEX_SHADER, vertexShaderSource ); |
this is a bad example, since one would expect your function to return the ID: 1
| int vertexShaderID = compileShader( vertexShaderID, GL.GL_VERTEX_SHADER, vertexShaderSource ); |
would be better, but normally in java you would design this more OO like, e.g. with a dedicated Shader class: 1 2
| Shader shader = new Shader(GL.GL_VERTEX_SHADER, vertexShaderSource); int vertexShaderID = shader.getId(); |
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
skytomorrownow
|
 |
«
Reply #9 - Posted
2009-08-03 22:19:07 » |
|
would be better, but normally in java you would design this more OO like, e.g. with a dedicated Shader class:
I was considering doing this. I saw that there are some convenience classes in JOGL2 aimed at GLSL, similar to those we currently have for textures. Is that going to be a while before release ( couldn't find a release date )? If so, I may just get cracking on that for my project. cheers
|
|
|
|
Games published by our own members! Check 'em out!
|
|
pjt33
|
 |
«
Reply #10 - Posted
2009-08-05 07:41:40 » |
|
In Java, an object passed through a method is automatically passed by reference
No, no, no! A reference to the object is passed by value.
|
|
|
|
Ranger
|
 |
«
Reply #11 - Posted
2009-08-05 08:21:00 » |
|
Java is pass by value ... always!
Don't get confused with some languages that have the ability to clone objects. Java doesn't do that.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #12 - Posted
2009-08-05 14:55:05 » |
|
No, no, no! A reference to the object is passed by value.
I should just stop talking.
|
|
|
|
Riven
|
 |
«
Reply #13 - Posted
2009-08-05 22:03:51 » |
|
Maybe nice to clearify it a bit, for those that are puzzled by what 'passed by value' actually means.
Every argument that is passed to a method is copied.
For primitives, this is obvious: if you pass int '5', '5' is copied to another memory location, which can be read from within the invoked method.
For references, it's a bit less obvious: there is a copy, but the reference (memory location) is copied. Like:
Object a = new Object(); Object b = a; // copy of a reference a = null; // b is still refering to whatever a *was* refering to
phone.call(a /* copy of a reference */ );
class Phone { public void call(Object xyz) { // reference 'xyz' is a copy of whatever 'a' is/was refering to } }
Needless to say: the object itself is not copied.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
skytomorrownow
|
 |
«
Reply #14 - Posted
2009-08-05 22:22:24 » |
|
I had no idea it worked that way. When they mentioned pass by value for the primitives, that made sense. But, I was surprised that that held true for Objects as well.
Thanks Riven.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #15 - Posted
2009-08-06 04:44:15 » |
|
If you do want to copy an Object, you can call clone() on any Object, although it's not always implemented. clone() is a protected method, so access is restricted to classes in the same package as Object (none of yours will be), but any subclasses that implement the Cloneable interface will have overridden clone() and made it public. Anything that makes sense to be copied typically can be. 1 2 3 4 5 6 7 8 9
| Integer a = new Integer(5);
Integer b = a;
|
Integer c = (Integer) a.clone();
|
|
|
|
pjt33
|
 |
«
Reply #16 - Posted
2009-08-06 08:20:11 » |
|
Although Integer isn't the best example because it doesn't implement Cloneable. I was surprised too, but I suppose it sort-of makes sense because Integer is unmodifiable and so there's no need to clone it.
|
|
|
|
i30817
|
 |
«
Reply #17 - Posted
2009-08-06 14:24:39 » |
|
No pointers for you in java. 99% of the times you use pointers (for multiple return values) you can refactor to use single functions. The other .9% percent is when you should use a domain object to hold obviously related values. (except if you're lazy, like i am).
The .1% is for performance intensive code, where you're mostly f**ked unless you do ugly things like reusing a array parameter or globals or something.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #18 - Posted
2009-08-06 14:28:51 » |
|
Although Integer isn't the best example because it doesn't implement Cloneable. I was surprised too, but I suppose it sort-of makes sense because Integer is unmodifiable and so there's no need to clone it.
Huh, that is surprising, I should have looked it up first. I kept looking through the API just now looking for things that were Cloneable but couldn't really find any. Oh well, he gets the idea...
|
|
|
|
i30817
|
 |
«
Reply #19 - Posted
2009-08-06 14:32:31 » |
|
Cloneable is a bad idea in itself. http://www.artima.com/intv/bloch13.htmlOf course contructors can't be in interfaces, nor static methods. Static is bad too ofcourse. But i am a sinner.
|
|
|
|
Riven
|
 |
«
Reply #20 - Posted
2009-08-06 16:43:14 » |
|
The only reason I use clone is when I have to copy arrays.
byte[] data = new byte[1234]; data[13] = 14; byte[] copy = data.clone();
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
Eli Delventhal
|
 |
«
Reply #21 - Posted
2009-08-06 17:31:44 » |
|
The only reason I use clone is when I have to copy arrays.
byte[] data = new byte[1234]; data[13] = 14; byte[] copy = data.clone();
Yeah, I've used it with List's as well, but in the end that's the same basic idea. I actually didn't know you could clone an array.
|
|
|
|
pjt33
|
 |
«
Reply #22 - Posted
2009-08-07 07:50:21 » |
|
Yeah, I've used it with List's as well, but in the end that's the same basic idea. I actually didn't know you could clone an array.
The really cool bit is that since 1.5 introduced covariant return types they've been applied to most (all?) Cloneables in the standard libraries, including arrays, so Riven's example works even though it has no cast.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #23 - Posted
2009-08-07 14:54:29 » |
|
The really cool bit is that since 1.5 introduced covariant return types they've been applied to most (all?) Cloneables in the standard libraries, including arrays, so Riven's example works even though it has no cast.
That's cool. They're slowly getting out of having to typecast everything all the time territory. Those were the (1.4) days... I would have statements with like 6 parentheses next to each other.
|
|
|
|
|