I'm using a third party c++ library that uses OpenGL and I'm having problems integrating it with my Java application. More specifically, my program crashes every time I delete the opengl window. I can create the opengl window and display it fine, but when I try to delete it and clean up the resources my program crashes. I've verified that the library works as expected when running from a pure c++ context (no Java). I've also stripped out the opengl portion of the c++ library and created a small java test program to reproduce the crash.
The test program starts from Java, and calls a native method which creates a GLWindow (which is just a wrapper to house all the OpenGL code), and then deletes it. Upon delete, the crash happens with the following error message:
** glibc detected * java: free(): invalid next size (fast): 0x082492e0 **
After adding a bunch of print statements, it appears the crash is happening after the GLWindow::quit() method (see code below) has returned, but before exiting the GLWindow destructor. Any thoughts about what the problem could be would be greatly appreciated.
Here is the native method called from the Java Main, and the necessary GLWindow code called from the native method.
#include "test_Main.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include "GLWindow/GLWindow.h"
JNIEXPORT void JNICALL Java_test_Main_createGLWindow(JNIEnv *, jclass) {
blortGLWindow::GLWindow* temp_window = new blortGLWindow::GLWindow(320, 240, "Tracking");
delete temp_window;
std::cout << "**Does NOT get to this Print Statement.**" << std::endl;
}
GLWindow.cpp that contains all the openGL code:
#ifdef LINUX
#include "GLWindow/GLWindow.h"
#include <stdio.h>
#include <stdexcept>
#include <vector>
namespace blortGLWindow{
void GLWindow::init(unsigned int width, unsigned int height, const char* name){
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
dpy = XOpenDisplay(NULL);
if(dpy == NULL){
throw std::runtime_error("[GLWindow::init] Error cannot connect to X server");
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if(vi == NULL)
throw std::runtime_error("[GLWindow::init] Error no appropriate visual found");
cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
glWin = XCreateWindow(dpy, root, 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", true);
XSetWMProtocols(dpy, glWin, &wmDelete, 1);
XMapWindow(dpy, glWin);
XStoreName(dpy, glWin, name);
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
glXMakeCurrent(dpy, glWin, glc);
glXSwapBuffers(dpy, glWin);
}
void GLWindow::quit(){
glXMakeCurrent(dpy, None, NULL);
glXDestroyContext(dpy, glc);
XDestroyWindow(dpy, glWin);
XCloseDisplay(dpy);
}
GLWindow::GLWindow(unsigned int width, unsigned int height, const char* name){
init(width, height, name);
}
GLWindow::~GLWindow(){
quit();
std::cout << "Gets to this Print Statement." << std::endl;
}
void GLWindow::Activate(){
glXMakeCurrent(dpy, glWin, glc);
}
void GLWindow::Update(){
glXSwapBuffers(dpy, glWin);
}
} /* namespace */
#endif /* LINUX */