summaryrefslogtreecommitdiff
path: root/src/powdertoyjava/OpenGLCanvasWin32.cpp
blob: 9df0a0bd3f9f83e52bc2b62bbe79048b748479ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#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