Why is adding of the light in lwjgl so ,,dificult"?

Started by Trudko, March 08, 2007, 17:35:16

Previous topic - Next topic

Trudko

I found out on the Internet adding light by OpenGl in C++ and it looks like this:
GLfloat LightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING)
;

In lwjgl it is:
ByteBuffer temp = ByteBuffer.allocateDirect(16);
temp.order(ByteOrder.nativeOrder());
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(lightAmbient).flip());              
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(lightDiffuse).flip());            
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION,(FloatBuffer)temp.asFloatBuffer().put(lightPosition).flip());         
GL11.glEnable(GL11.GL_LIGHT1);  
GL11.glEnable(GL11.GL_LIGHTING);


What is the purpouse of this Buffers,why I need to use them ?
Why I need to create ByteBuffer and the I change it to floatBuffer?
Please help.



Fool Running

Quote
What is the purpouse of this Buffers,why I need to use them ?
The reason is that the OpenGL driver is native code (is not written in Java) so to get information from Java to that native code Java has something called NIO (Native Input Output, or something like that ;D). The way you send Java arrays to native code is by putting it in a ByteBuffer (which can be changed into a float, short, etc. buffer) which represents a native portion of memory that the driver can access. This keeps the developers from having to worry about freeing the memory, managing pointers and stuff that you have to deal with in C++, and also allows it to be garbage collected from Java.

Hope that helps ;D
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Matzon

you might want to create it as a floatbuffer initially instead of casting all the time:
FloatBuffer lightAmbient = BufferUtils.createFloatBuffer(4).put(new float[] {0.2f, 0.2f, 0.2f, 1.0f });

aldacron

Quote from: Trudko on March 08, 2007, 17:35:16
What is the purpouse of this Buffers,why I need to use them ?

Fool Running was mostly right, but I'll expand on it a bit.

The JRE maintains its own memory space that the garbage collector manages. To interface with native code, there is a special API called JNI (Java Native Interface). JNI allows you to make calls from C or C++ into Java, from Java into C or C++. LWJGL uses the JNI to interface with OpenGL and OpenAL (and other libraries).

You can pass Java arrays into native code through JNI. Doing so would make the code very similar to C. But there's a problem with that -- it's slow. Java arrays reside in the JRE's managed memory space. Depending upon the garbage collector implementation, elements in JRE memory can be shifted around at any time. If you are accessing a Java array from native code when this happens, things could blow up. So, the JNI API protects against this by either pinning the array down while it is accessed from the native side (preventing the GC from moving it) or, worse, copying it into non-moveable memory (which also means copying it back when you are finished with it in case it is modified). When you are sending a large number of variable sized arrays to native code, as we need to to with OpenGL, the performance impact can potentially be tremendous.

The NIO package (New IO, meaning it replaces the existing IO package) was created to enhance the performance of IO operations in Java. The different Buffers in the NIO API can be allocated in either JRE memory or native (direct) memory. Because they can be allocated in native memory, they can reside outside of the scope of the garbage collector. There is no concern that they will be moved around during access on the native side, so they don't need to be pinned down or copied. This means that pointers to native buffer memory can be passed directly to OpenGL. It is much more efficient than using normal Java arrays. So we always need to use native memory buffers (allocated via the *.allocateDirect() methods) with LWJGL calls, rather than JRE memory buffers (allocated with the *.allocate() methods) in order to see these benefits.

So it may seem annoying that you need to manage these buffers, or that OpenGL code with LWJGL is rather different than the C side. But in the end the benefits are worth it.

elias4444

Matzon, I like your method without casting... but don't you still have to cast it to a floatbuffer when you flip() it?

Edit: or do you just rewind() it before calling it each time?
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

Matzon

at some point you will need to flip it - but that doesn't involve any casting ?