Open-source multiplayer game server compatible with the RuneScape client
https://www.openrs2.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
5.7 KiB
259 lines
5.7 KiB
5 years ago
|
#include "jaggl_context.h"
|
||
|
#include "jaggl_opengl.h"
|
||
|
|
||
|
#include <GL/glx.h>
|
||
|
#include <jawt.h>
|
||
|
#include <jawt_md.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stddef.h>
|
||
|
|
||
|
#define JAGGL_LOCK(env) \
|
||
|
JAWT awt = { .version = JAWT_VERSION_1_4 }; \
|
||
|
bool awt_valid = JAWT_GetAWT(env, &awt); \
|
||
|
if (awt_valid) { \
|
||
|
awt.Lock(env); \
|
||
|
}
|
||
|
|
||
|
#define JAGGL_UNLOCK(env) \
|
||
|
if (awt_valid) { \
|
||
|
awt.Unlock(env); \
|
||
|
}
|
||
|
|
||
|
static Display *jaggl_display;
|
||
|
static XVisualInfo *jaggl_visual_info;
|
||
|
static VisualID jaggl_visual_id;
|
||
|
static GLXContext jaggl_context;
|
||
|
static GLXDrawable jaggl_drawable;
|
||
|
static int jaggl_alpha_bits;
|
||
|
static bool jaggl_double_buffered;
|
||
|
|
||
|
static PFNGLXSWAPINTERVALSGIPROC jaggl_glXSwapIntervalSGI;
|
||
|
|
||
|
static void jaggl_init_proc_table(void) {
|
||
|
jaggl_glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalSGI");
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_createContext(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
GLXContext current = glXGetCurrentContext();
|
||
|
if (current) {
|
||
|
glXMakeCurrent(jaggl_display, None, NULL);
|
||
|
}
|
||
|
|
||
|
if (jaggl_context) {
|
||
|
glXDestroyContext(jaggl_display, jaggl_context);
|
||
|
jaggl_context = NULL;
|
||
|
}
|
||
|
|
||
|
jaggl_context = glXCreateContext(jaggl_display, jaggl_visual_info, NULL, True);
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return jaggl_context != NULL;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_releaseContext(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
jboolean result = JNI_TRUE;
|
||
|
|
||
|
GLXContext current = glXGetCurrentContext();
|
||
|
if (current) {
|
||
|
result = (jboolean) glXMakeCurrent(jaggl_display, None, NULL);
|
||
|
}
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_destroy(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
GLXContext current = glXGetCurrentContext();
|
||
|
if (current) {
|
||
|
glXMakeCurrent(jaggl_display, None, NULL);
|
||
|
}
|
||
|
|
||
|
if (jaggl_context) {
|
||
|
glXDestroyContext(jaggl_display, jaggl_context);
|
||
|
jaggl_context = NULL;
|
||
|
}
|
||
|
|
||
|
if (jaggl_visual_info) {
|
||
|
XFree(jaggl_visual_info);
|
||
|
jaggl_visual_info = NULL;
|
||
|
}
|
||
|
|
||
|
jaggl_display = None;
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return JNI_TRUE;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_swapBuffers(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
if (jaggl_double_buffered) {
|
||
|
glXSwapBuffers(jaggl_display, jaggl_drawable);
|
||
|
} else {
|
||
|
glFlush();
|
||
|
}
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return JNI_TRUE;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jint JNICALL Java_jaggl_context_getLastError(JNIEnv *env, jclass cls) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT void JNICALL Java_jaggl_context_setSwapInterval(JNIEnv *env, jclass cls, jint interval) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
if (jaggl_glXSwapIntervalSGI) {
|
||
|
jaggl_glXSwapIntervalSGI(interval);
|
||
|
}
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jstring JNICALL Java_jaggl_context_getExtensionsString(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
const char *extensions_str = glXQueryExtensionsString(jaggl_display, jaggl_visual_info->screen);
|
||
|
jstring extensions = (*env)->NewStringUTF(env, extensions_str);
|
||
|
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return extensions;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jint JNICALL Java_jaggl_context_getAlphaBits(JNIEnv *env, jclass cls) {
|
||
|
return jaggl_alpha_bits;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_choosePixelFormat1(JNIEnv *env, jclass cls, jobject component, jint num_samples, jint alpha_bits) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
jboolean result = JNI_FALSE;
|
||
|
|
||
|
if (!awt_valid) {
|
||
|
goto awt_unlock;
|
||
|
}
|
||
|
|
||
|
JAWT_DrawingSurface *ds = awt.GetDrawingSurface(env, component);
|
||
|
if (!ds) {
|
||
|
goto awt_unlock;
|
||
|
}
|
||
|
|
||
|
jint lock_result = ds->Lock(ds);
|
||
|
if ((lock_result & JAWT_LOCK_ERROR) != 0) {
|
||
|
goto ds_free;
|
||
|
}
|
||
|
|
||
|
JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds);
|
||
|
if (!dsi) {
|
||
|
goto ds_unlock;
|
||
|
}
|
||
|
|
||
|
JAWT_X11DrawingSurfaceInfo *platformInfo = (JAWT_X11DrawingSurfaceInfo *) dsi->platformInfo;
|
||
|
if (!platformInfo) {
|
||
|
goto dsi_free;
|
||
|
}
|
||
|
|
||
|
jaggl_display = platformInfo->display;
|
||
|
jaggl_drawable = platformInfo->drawable;
|
||
|
jaggl_visual_id = platformInfo->visualID;
|
||
|
|
||
|
if (!glXQueryExtension(jaggl_display, NULL, NULL)) {
|
||
|
goto dsi_free;
|
||
|
}
|
||
|
|
||
|
XWindowAttributes window_attribs;
|
||
|
if (XGetWindowAttributes(jaggl_display, jaggl_drawable, &window_attribs)) {
|
||
|
XVisualInfo visual_info_template = { .visualid = window_attribs.visual->visualid };
|
||
|
int matches;
|
||
|
jaggl_visual_info = XGetVisualInfo(jaggl_display, VisualIDMask, &visual_info_template, &matches);
|
||
|
if (jaggl_visual_info) {
|
||
|
int value;
|
||
|
glXGetConfig(jaggl_display, jaggl_visual_info, GLX_DOUBLEBUFFER, &value);
|
||
|
jaggl_double_buffered = value;
|
||
|
|
||
|
glXGetConfig(jaggl_display, jaggl_visual_info, GLX_ALPHA_SIZE, &value);
|
||
|
jaggl_alpha_bits = value;
|
||
|
|
||
|
result = JNI_TRUE;
|
||
|
goto dsi_free;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < 2; i++) {
|
||
|
bool double_buffered = i == 0;
|
||
|
int attribs[] = {
|
||
|
GLX_RGBA,
|
||
|
GLX_RED_SIZE,
|
||
|
8,
|
||
|
GLX_GREEN_SIZE,
|
||
|
8,
|
||
|
GLX_BLUE_SIZE,
|
||
|
8,
|
||
|
GLX_ALPHA_SIZE,
|
||
|
alpha_bits,
|
||
|
GLX_DEPTH_SIZE,
|
||
|
24,
|
||
|
GLX_SAMPLE_BUFFERS,
|
||
|
num_samples ? True : False,
|
||
|
GLX_SAMPLES,
|
||
|
num_samples,
|
||
|
double_buffered ? GLX_DOUBLEBUFFER : None,
|
||
|
None
|
||
|
};
|
||
|
jaggl_visual_info = glXChooseVisual(jaggl_display, DefaultScreen(jaggl_display), attribs);
|
||
|
if (jaggl_visual_info) {
|
||
|
jaggl_double_buffered = double_buffered;
|
||
|
jaggl_alpha_bits = alpha_bits;
|
||
|
|
||
|
result = JNI_TRUE;
|
||
|
goto dsi_free;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dsi_free:
|
||
|
ds->FreeDrawingSurfaceInfo(dsi);
|
||
|
ds_unlock:
|
||
|
ds->Unlock(ds);
|
||
|
ds_free:
|
||
|
awt.FreeDrawingSurface(ds);
|
||
|
awt_unlock:
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
JNIEXPORT jboolean JNICALL Java_jaggl_context_makeCurrent1(JNIEnv *env, jclass cls) {
|
||
|
JAGGL_LOCK(env);
|
||
|
|
||
|
jboolean result = JNI_FALSE;
|
||
|
|
||
|
if (!jaggl_context) {
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
GLXContext current = glXGetCurrentContext();
|
||
|
if (jaggl_context == current) {
|
||
|
result = JNI_TRUE;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
glXMakeCurrent(jaggl_display, None, NULL);
|
||
|
|
||
|
if (!glXMakeCurrent(jaggl_display, jaggl_drawable, jaggl_context)) {
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
jaggl_init_proc_table();
|
||
|
result = JNI_TRUE;
|
||
|
|
||
|
done:
|
||
|
JAGGL_UNLOCK(env);
|
||
|
return result;
|
||
|
}
|