The-Powder-Toy/src/powdertoyjava/OpenGLCanvasWin32.cpp

170 lines
4.3 KiB
C++

#if defined(USE_JNI) && defined(WIN32)
#include "OpenGLCanvasWin32.h"
static jfieldID ctxID = NULL;
int defaultPixelFormat(PIXELFORMATDESCRIPTOR* pfd)
{
::ZeroMemory( pfd, sizeof( PIXELFORMATDESCRIPTOR ) );
pfd->nSize = sizeof( PIXELFORMATDESCRIPTOR );
pfd->nVersion = 1;
pfd->dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd->iPixelType = PFD_TYPE_RGBA;
pfd->cColorBits = 24;
pfd->cDepthBits = 16;
pfd->iLayerType = PFD_MAIN_PLANE;
return 0;
}
HGLRC ensureContext(JAWT_Win32DrawingSurfaceInfo* dsi_win, HGLRC hRC) {
if (!hRC) {
int iFormat;
PIXELFORMATDESCRIPTOR pfd;
defaultPixelFormat(&pfd);
iFormat = ChoosePixelFormat( dsi_win->hdc, &pfd );
SetPixelFormat( dsi_win->hdc, iFormat, &pfd );
hRC = wglCreateContext( dsi_win->hdc );
}
if (1 && wglGetCurrentDC() != dsi_win->hdc) {
wglMakeCurrent( dsi_win->hdc, hRC );
}
return hRC;
}
ContextInfo* getContext(JNIEnv *env, jobject canvas)
{
ContextInfo *ci;
if (!ctxID) {
jclass cls = env->GetObjectClass(canvas);
ctxID = env->GetFieldID(cls, "openGLContext", "J");
}
ci = (ContextInfo *)(long)(env->GetLongField(canvas, ctxID));
if (!ci) {
ci = (ContextInfo *)calloc(sizeof(ContextInfo), 1);
ci->awt = (JAWT *)calloc(sizeof(JAWT), 1);
env->SetLongField(canvas, ctxID, (jlong)(long)ci);
}
return ci;
}
void freeContext(JNIEnv *env, jobject canvas, ContextInfo* ci)
{
if (ci) {
free(ci->awt);
free(ci);
env->SetLongField(canvas, ctxID, 0L);
}
}
JNIEXPORT jboolean JNICALL Java_OpenGLCanvas_beginOpenGL(JNIEnv *env, jobject canvas)
{
jint lock;
ContextInfo *ci = getContext(env, canvas);
// Get the drawing surface. This can be safely cached -- not in win32
// Anything below the DS (DSI, contexts, etc)
// can possibly change/go away and should not be cached.
ci->ds = ci->awt->GetDrawingSurface(env, canvas);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
assert(ci->ds != NULL);
// Lock the drawing surface
// You must lock EACH TIME before drawing
lock = ci->ds->Lock(ci->ds);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
assert((lock & JAWT_LOCK_ERROR) == 0);
// Get the drawing surface info
ci->dsi = ci->ds->GetDrawingSurfaceInfo(ci->ds);
// Check DrawingSurfaceInfo. This can be NULL on Mac OS X
// if the windowing system is not ready
if (ci->dsi != NULL) {
// Get the platform-specific drawing info
// We will use this to get at Cocoa and CoreGraphics
// See <JavaVM/jawt_md.h>
ci->dsi_win = (JAWT_Win32DrawingSurfaceInfo*)ci->dsi->platformInfo;
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
// Get the corresponding peer from the caller canvas
ci->hRC = ensureContext(ci->dsi_win, ci->hRC);
return JNI_TRUE;
}
return JNI_FALSE;
}
JNIEXPORT void JNICALL Java_OpenGLCanvas_endOpenGL(JNIEnv *env, jobject canvas)
{
ContextInfo *ci = getContext(env, canvas);
SwapBuffers( ci->dsi_win->hdc );
// Free the DrawingSurfaceInfo
ci->ds->FreeDrawingSurfaceInfo(ci->dsi);
if (env->ExceptionOccurred()){
env->ExceptionDescribe();
}
// Unlock the drawing surface
// You must unlock EACH TIME when done drawing
ci->ds->Unlock(ci->ds);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
// Free the drawing surface (if not caching it)
ci->awt->FreeDrawingSurface(ci->ds);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
}
JNIEXPORT void JNICALL Java_OpenGLCanvas_updateOpenGL(JNIEnv *env, jobject canvas)
{
ContextInfo *ci = getContext(env, canvas);
wglMakeCurrent( ci->dsi_win->hdc, ci->hRC );
}
JNIEXPORT void JNICALL Java_OpenGLCanvas_allocOpenGL(JNIEnv *env, jobject canvas)
{
ContextInfo *ci = getContext(env, canvas);
jboolean result = JNI_FALSE;
// get the AWT
ci->awt->version = JAWT_VERSION_1_4;
result = JAWT_GetAWT(env, ci->awt);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
assert(result != JNI_FALSE);
}
JNIEXPORT void JNICALL Java_OpenGLCanvas_releaseOpenGL(JNIEnv *env, jobject canvas)
{
ContextInfo *ci = getContext(env, canvas);
if (ci->hRC) {
wglDeleteContext(ci->hRC);
}
freeContext(env, canvas, ci);
}
#endif