|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 7
You can assume that OpenGL and glX are multithread-safe -- i.e., they can actually support concurrent access from different threads. But that is nothing more than an assumption; the reality is implementation-dependent.
You might consider implementing the locking system that you used when accessing the drawing surface, but this time, neither OpenGL nor glX provide such a mechanism. You'll need to implement it yourself, which can prove quite complicated if you're unsure which calls need lock protection.
The best solution to solving this architectural issue is simple: OpenGL and glX functions must always be called from the same thread. In your case, they should always be called from the legacy application's main thread. It seems that you return to the initial question: how do you create an OpenGL document from Java? Well, if Java cannot call OpenGL and glX directly -- that is, synchronously -- you need a messaging mechanism. You will use that messaging mechanism to send instructions from Java to your legacy application's main thread.
One messaging mechanism that comes to mind is sockets, a classical means for communicating between processes. When the different
processes are located on the same system, you should have no concerns about communication reliability. In these cases, use
datagram sockets. They are fast, use a light protocol, and are easy to implement. You'll use datagram sockets to communicate
inside the same process but between two threads. The ActionListener Java interface acts as a socket client. It uses a socket to send messages to the legacy application thread. Listing 4 shows
how to implement the client side:
Listing 4: Socket client in Java
// File SwingMenu.java
import javax.swing.*;
import java.awt.event.*;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
class SwingMenu extends JFrame implements ActionListener {
private int outPort=9970; // Must be equal to IN_PORT in
main.c
private DatagramSocket inSocket;
private DatagramPacket createOGLWin;
private DatagramPacket animate;
private native void changeColour(int colour);
// Method to create a socket
private void initSocket() {
try {
inSocket = new DatagramSocket();
} catch (Exception exc) {
System.out.println("Unable to create a socket");
System.out.println("Error: "+exc.toString());
System.exit(99);
}
try {
InetAddress localAddr = InetAddress.getLocalHost();
String oglWinStr = new String("CreateOGLWindow");
createOGLWin = new DatagramPacket(oglWinStr.getBytes(),
oglWinStr.length(),
localAddr, outPort);
String animateStr = new String("Animate");
animate = new DatagramPacket(animateStr.getBytes(),
animateStr.length(),
localAddr, outPort);
} catch (UnknownHostException exc) {
System.out.println("Unable to get local host address");
System.out.println(exc.toString());
System.exit(99);
}
}
// Method to handle button events
public void actionPerformed(ActionEvent evt) {
String string = evt.getActionCommand();
if (string.equals("Red")) {
changeColour(1);
} else if (string.equals("Yellow")) {
changeColour(2);
} else if (string.equals("Create OpenGL window")) {
try { inSocket.send(createOGLWin); }
catch (IOException exc) {System.out.println(exc.toString()); }
} else if (string.equals("Animate")) {
try { inSocket.send(animate); }
catch (IOException exc) {System.out.println(exc.toString()); }
} else if (string.equals("Exit")) {
System.exit(0);
}
}
}
Calling the DatagramSocket() constructor without any argument creates a socket and binds it to any available port on the local host. That socket sends
datagram packets. You have to build those packets using the DatagramPacket class. Packets are sent to the local host through a specific port (the socket server binds its socket to this port).