Graphics library for Mercury, including OpenGL bindings, TGA image reading, and X11, Win32, and SDL2 windowing and input.
修訂 | 1d825675170ef4cc80eaf3c9b1b3b174501aae6e (tree) |
---|---|
時間 | 2023-06-30 08:39:39 |
作者 | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add Java support to core and GL components
@@ -197,24 +197,40 @@ | ||
197 | 197 | vertex(in, in, in, in) = (out), |
198 | 198 | "SaffronGeometry_CreateVertex2D"). |
199 | 199 | |
200 | +:- pragma foreign_export("C", | |
201 | + vertex(in, in, in, in) = (out), | |
202 | + "CreateVertex"). | |
203 | + | |
200 | 204 | %-----------------------------------------------------------------------------% |
201 | 205 | |
202 | 206 | :- pragma foreign_export("C", |
203 | 207 | vertex(out, out, out, out, in), |
204 | 208 | "SaffronGeometry_GetVertex2D"). |
205 | 209 | |
210 | +:- pragma foreign_export("Java", | |
211 | + vertex(out, out, out, out, in), | |
212 | + "GetVertex"). | |
213 | + | |
206 | 214 | %-----------------------------------------------------------------------------% |
207 | 215 | |
208 | 216 | :- pragma foreign_export("C", |
209 | 217 | vertex(in, in, in, in, in) = (out), |
210 | 218 | "SaffronGeometry_CreateVertex3D"). |
211 | 219 | |
220 | +:- pragma foreign_export("Java", | |
221 | + vertex(in, in, in, in, in) = (out), | |
222 | + "CreateVertex"). | |
223 | + | |
212 | 224 | %-----------------------------------------------------------------------------% |
213 | 225 | |
214 | 226 | :- pragma foreign_export("C", |
215 | 227 | vertex(out, out, out, out, out, in), |
216 | 228 | "SaffronGeometry_GetVertex3D"). |
217 | 229 | |
230 | +:- pragma foreign_export("Java", | |
231 | + vertex(out, out, out, out, out, in), | |
232 | + "GetVertex"). | |
233 | + | |
218 | 234 | %-----------------------------------------------------------------------------% |
219 | 235 | |
220 | 236 | vertex(X, Y, U, V) = vertex(mmath.vector.vector2.vector(X, Y), U, V). |
@@ -124,6 +124,19 @@ | ||
124 | 124 | #undef SAFFRON_GL_IMPL |
125 | 125 | "). |
126 | 126 | |
127 | +% Imports for the Java grade. | |
128 | +:- pragma foreign_decl("Java", " | |
129 | +import org.lwjgl.opengl.ARBVertexBufferObject; | |
130 | +import org.lwjgl.opengl.GLCapabilities; | |
131 | +import org.lwjgl.opengl.GL; | |
132 | +import org.lwjgl.opengl.GL11; // Base constants | |
133 | +import org.lwjgl.opengl.GL20; | |
134 | +import jmercury.list; | |
135 | +import jmercury.list.List_1; | |
136 | +import jmercury.maybe.Maybe_error_2; | |
137 | +import jmercury.saffron__geometry.Vertex_1; | |
138 | + "). | |
139 | + | |
127 | 140 | %-----------------------------------------------------------------------------% |
128 | 141 | |
129 | 142 | :- pragma foreign_enum("C", buffer_type/0, [ |
@@ -131,13 +144,222 @@ | ||
131 | 144 | element_array_buffer - "GL_ELEMENT_ARRAY_BUFFER" |
132 | 145 | ]). |
133 | 146 | |
147 | +:- pragma foreign_export_enum( | |
148 | + "Java", | |
149 | + buffer_type/0, | |
150 | + [prefix("BUFFER_TYPE_")|[uppercase|[]]]). | |
151 | + | |
152 | +:- pragma foreign_code("Java", " | |
153 | +public static int BufferTypeToGL(Buffer_type_0 t, boolean ARB){ | |
154 | + if(t.equals(BUFFER_TYPE_ARRAY_BUFFER)){ | |
155 | + return ARB ? | |
156 | + ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB : | |
157 | + GL20.GL_ARRAY_BUFFER; | |
158 | + } | |
159 | + else if(t.equals(BUFFER_TYPE_ELEMENT_ARRAY_BUFFER)){ | |
160 | + return ARB ? | |
161 | + ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB : | |
162 | + GL20.GL_ELEMENT_ARRAY_BUFFER; | |
163 | + } | |
164 | + else{ | |
165 | + throw new IllegalStateException(""Unknown buffer type""); | |
166 | + } | |
167 | +} | |
168 | + | |
169 | +/////////////////////////////////////////////////////////////////////////////// | |
170 | +/// \brief Base class for a Buffer context. | |
171 | +/// | |
172 | +/// This is a base class so that we can have either a context of sufficient | |
173 | +/// version to have vertex buffers, or use ARB extensions. | |
174 | +/// | |
175 | +/// This uses the bufferType method to convert from Buffer_type_0 to an int, so | |
176 | +/// that no other subclass-implemented method needs to deal with Buffer_type_0. | |
177 | +/// | |
178 | +/// Derived classes only need to implement primitive array versions of | |
179 | +/// bufferData, all mercury types and Object-ified arrays will be unwrapped | |
180 | +/// and placed into primitive arrays by the base methods. | |
181 | +public static abstract class Context{ | |
182 | + protected abstract int bufferType(Buffer_type_0 t); | |
183 | + public abstract int createBuffer(); | |
184 | + public abstract void destroyBuffer(int buffer); | |
185 | + protected abstract void bindBuffer(int buffer, int t); | |
186 | + | |
187 | + protected abstract void bufferData(int t, int[] data); | |
188 | + public void bufferData(Buffer_type_0 t, int[] data){ | |
189 | + bufferData(bufferType(t), data); | |
190 | + } | |
191 | + public void bufferData(Buffer_type_0 t, Integer[] data){ | |
192 | + int[] l_data = new int[data.length]; | |
193 | + for(int i = 0; i < data.length; i++) | |
194 | + l_data[i] = data[i].intValue(); | |
195 | + bufferData(bufferType(t), l_data); | |
196 | + } | |
197 | + public void bufferDataI(Buffer_type_0 t, List_1<Integer> data){ | |
198 | + final int length = jmercury.saffron.ListLength(data); | |
199 | + int[] l_data = new int[length]; | |
200 | + for(int i = 0; i < length; i++){ | |
201 | + l_data[i] = list.det_head(data).intValue(); | |
202 | + data = list.det_tail(data); | |
203 | + } | |
204 | + bufferData(bufferType(t), l_data); | |
205 | + } | |
206 | + | |
207 | + protected abstract void bufferData(int t, double[] data); | |
208 | + public void bufferData(Buffer_type_0 t, double[] data){ | |
209 | + bufferData(bufferType(t), data); | |
210 | + } | |
211 | + public void bufferData(Buffer_type_0 t, Double[] data){ | |
212 | + double[] l_data = new double[data.length]; | |
213 | + for(int i = 0; i < data.length; i++) | |
214 | + l_data[i] = data[i].doubleValue(); | |
215 | + bufferData(bufferType(t), l_data); | |
216 | + } | |
217 | + public void bufferDataD(Buffer_type_0 t, list.List_1<Double> data){ | |
218 | + final int length = jmercury.saffron.ListLength(data); | |
219 | + double[] l_data = new double[length]; | |
220 | + for(int i = 0; i < length; i++){ | |
221 | + l_data[i] = list.det_head(data).doubleValue(); | |
222 | + data = list.det_tail(data); | |
223 | + } | |
224 | + bufferData(bufferType(t), l_data); | |
225 | + } | |
226 | + | |
227 | + public void bufferData2( | |
228 | + Buffer_type_0 t, | |
229 | + Vertex_1<jmercury.mmath__vector__vector2.Vector_0>[] data){ | |
230 | + double[] l_data = new double[data.length * 4]; | |
231 | + int i = 0; | |
232 | + for(Vertex_1<jmercury.mmath__vector__vector2.Vector_0> vertex : data) | |
233 | + i = jmercury.saffron.WriteVertex2(l_data, vertex, i); | |
234 | + bufferData(bufferType(t), l_data); | |
235 | + } | |
236 | + | |
237 | + public void bufferData2( | |
238 | + Buffer_type_0 t, | |
239 | + List_1<Vertex_1<jmercury.mmath__vector__vector2.Vector_0>> data){ | |
240 | + final int length = jmercury.saffron.ListLength(data); | |
241 | + double[] l_data = new double[length * 4]; | |
242 | + int i = 0; | |
243 | + for(int n = 0; n < length; n++){ | |
244 | + i = jmercury.saffron.WriteVertex2(l_data, list.det_head(data), i); | |
245 | + data = list.det_tail(data); | |
246 | + } | |
247 | + bufferData(bufferType(t), l_data); | |
248 | + } | |
249 | + | |
250 | + public void bufferData3( | |
251 | + Buffer_type_0 t, | |
252 | + Vertex_1<jmercury.mmath__vector__vector3.Vector_0>[] data){ | |
253 | + double[] l_data = new double[data.length * 5]; | |
254 | + int i = 0; | |
255 | + for(Vertex_1<jmercury.mmath__vector__vector3.Vector_0> vertex : data){ | |
256 | + i = jmercury.saffron.WriteVertex3(l_data, vertex, i); | |
257 | + } | |
258 | + bufferData(bufferType(t), l_data); | |
259 | + } | |
260 | + | |
261 | + public void bufferData3( | |
262 | + Buffer_type_0 t, | |
263 | + List_1<Vertex_1<jmercury.mmath__vector__vector3.Vector_0>> data){ | |
264 | + final int length = jmercury.saffron.ListLength(data); | |
265 | + double[] l_data = new double[length * 5]; | |
266 | + int i = 0; | |
267 | + for(int n = 0; n < length; n++){ | |
268 | + i = jmercury.saffron.WriteVertex3(l_data, list.det_head(data), i); | |
269 | + data = list.det_tail(data); | |
270 | + } | |
271 | + bufferData(bufferType(t), l_data); | |
272 | + } | |
273 | + | |
274 | + public void bindBuffer(int buffer, Buffer_type_0 t){ | |
275 | + bindBuffer(buffer, bufferType(t)); | |
276 | + } | |
277 | +} | |
278 | + | |
279 | +/////////////////////////////////////////////////////////////////////////////// | |
280 | +/// \brief Implements a buffer context using core OpenGL functions. | |
281 | +public static class GL20Context extends Context{ | |
282 | + protected int bufferType(Buffer_type_0 t){ | |
283 | + if(t.equals(BUFFER_TYPE_ARRAY_BUFFER)) | |
284 | + return GL20.GL_ARRAY_BUFFER; | |
285 | + else if(t.equals(BUFFER_TYPE_ELEMENT_ARRAY_BUFFER)) | |
286 | + return GL20.GL_ELEMENT_ARRAY_BUFFER; | |
287 | + else | |
288 | + throw new IllegalStateException(""Unknown buffer type""); | |
289 | + } | |
290 | + public int createBuffer(){ | |
291 | + return GL20.glGenBuffers(); | |
292 | + } | |
293 | + public void destroyBuffer(int buffer){ | |
294 | + GL20.glDeleteBuffers(buffer); | |
295 | + } | |
296 | + protected void bindBuffer(int buffer, int t){ | |
297 | + GL20.glBindBuffer(t, buffer); | |
298 | + } | |
299 | + protected void bufferData(int t, int[] data){ | |
300 | + GL20.glBufferData(t, data, GL20.GL_STATIC_DRAW); | |
301 | + } | |
302 | + protected void bufferData(int t, double[] data){ | |
303 | + GL20.glBufferData(t, data, GL20.GL_STATIC_DRAW); | |
304 | + } | |
305 | +} | |
306 | + | |
307 | +/////////////////////////////////////////////////////////////////////////////// | |
308 | +/// \brief Implements a buffer context using GL_ARB_vertex_buffer_object | |
309 | +public static class ARBContext extends Context{ | |
310 | + protected int bufferType(Buffer_type_0 t){ | |
311 | + if(t.equals(BUFFER_TYPE_ARRAY_BUFFER)) | |
312 | + return ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB; | |
313 | + else if(t.equals(BUFFER_TYPE_ELEMENT_ARRAY_BUFFER)) | |
314 | + return ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB; | |
315 | + else | |
316 | + throw new IllegalStateException(""Unknown buffer type""); | |
317 | + } | |
318 | + public int createBuffer(){ | |
319 | + return ARBVertexBufferObject.glGenBuffersARB(); | |
320 | + } | |
321 | + public void destroyBuffer(int buffer){ | |
322 | + ARBVertexBufferObject.glDeleteBuffersARB(buffer); | |
323 | + } | |
324 | + protected void bindBuffer(int buffer, int t){ | |
325 | + ARBVertexBufferObject.glBindBufferARB(t, buffer); | |
326 | + } | |
327 | + protected void bufferData(int t, int[] data){ | |
328 | + ARBVertexBufferObject.glBufferDataARB(t, data, ARBVertexBufferObject.GL_STATIC_DRAW_ARB); | |
329 | + } | |
330 | + protected void bufferData(int t, double[] data){ | |
331 | + ARBVertexBufferObject.glBufferDataARB(t, data, ARBVertexBufferObject.GL_STATIC_DRAW_ARB); | |
332 | + } | |
333 | +} | |
334 | + | |
335 | +/////////////////////////////////////////////////////////////////////////////// | |
336 | +/// \brief Creates a shader context, using OpenGL capabilities to determine | |
337 | +/// | |
338 | +/// if a GL2.0 or an ARB context is appropriate. | |
339 | +/// May return null if no context can be created. | |
340 | +public static Context CreateContext(){ | |
341 | + final GLCapabilities caps = GL.getCapabilities(); | |
342 | + if(caps.OpenGL20){ | |
343 | + return new GL20Context(); | |
344 | + } | |
345 | + else if(caps.GL_ARB_vertex_buffer_object){ | |
346 | + return new ARBContext(); | |
347 | + } | |
348 | + else{ | |
349 | + return null; | |
350 | + } | |
351 | +} | |
352 | + "). | |
353 | + | |
134 | 354 | %-----------------------------------------------------------------------------% |
135 | 355 | |
136 | 356 | :- pragma foreign_type("C", buffer_ctx, "SAFFRON_GL_BUFFER_CTX"). |
357 | +:- pragma foreign_type("Java", buffer_ctx, "jmercury.saffron__gl__buffer.Context"). | |
137 | 358 | |
138 | 359 | %-----------------------------------------------------------------------------% |
139 | 360 | |
140 | 361 | :- pragma foreign_type("C", buffer, "GLuint"). |
362 | +:- pragma foreign_type("Java", buffer, "int"). | |
141 | 363 | |
142 | 364 | %-----------------------------------------------------------------------------% |
143 | 365 |
@@ -157,6 +379,12 @@ create_buffer_ctx_error(E) = maybe.error(E). | ||
157 | 379 | |
158 | 380 | %-----------------------------------------------------------------------------% |
159 | 381 | |
382 | +:- pragma foreign_code("Java", " | |
383 | +final public static Maybe_error_2<Context, String> create_context_error = | |
384 | + new Maybe_error_2.Error_1( | |
385 | + ""Buffers require OpenGL 2.0 or GL_ARB_vertex_buffer_objects""); | |
386 | + "). | |
387 | + | |
160 | 388 | :- pred create_buffer_ctx_internal( |
161 | 389 | gl_load_func_ctx, |
162 | 390 | maybe.maybe_error(buffer_ctx), |
@@ -181,6 +409,18 @@ create_buffer_ctx_error(E) = maybe.error(E). | ||
181 | 409 | IOo = IOi; |
182 | 410 | "). |
183 | 411 | |
412 | +:- pragma foreign_proc("Java", | |
413 | + create_buffer_ctx_internal(Ctx::in, MaybeBufferCtx::out, IOi::di, IOo::uo), | |
414 | + [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
415 | + " | |
416 | + final jmercury.saffron__gl__buffer.Context ctx = | |
417 | + jmercury.saffron__gl__buffer.CreateContext(); | |
418 | + MaybeBufferCtx = (ctx == null) ? | |
419 | + jmercury.saffron__gl__buffer.create_context_error : | |
420 | + new jmercury.maybe.Maybe_error_2.Ok_1(ctx); | |
421 | + IOo = IOi; | |
422 | + "). | |
423 | + | |
184 | 424 | %-----------------------------------------------------------------------------% |
185 | 425 | |
186 | 426 | create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- |
@@ -201,6 +441,14 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
201 | 441 | IOo = IOi; |
202 | 442 | "). |
203 | 443 | |
444 | +:- pragma foreign_proc("Java", | |
445 | + create_buffer(Ctx::in, Buffer::uo, IOi::di, IOo::uo), | |
446 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
447 | + " | |
448 | + Buffer = Ctx.createBuffer(); | |
449 | + IOo = IOi; | |
450 | + "). | |
451 | + | |
204 | 452 | %-----------------------------------------------------------------------------% |
205 | 453 | |
206 | 454 | :- pragma foreign_proc("C", |
@@ -213,6 +461,14 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
213 | 461 | IOo = IOi; |
214 | 462 | "). |
215 | 463 | |
464 | +:- pragma foreign_proc("Java", | |
465 | + destroy_buffer(Ctx::in, Buffer::in, IOi::di, IOo::uo), | |
466 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
467 | + " | |
468 | + Ctx.destroyBuffer(Buffer); | |
469 | + IOo = IOi; | |
470 | + "). | |
471 | + | |
216 | 472 | %-----------------------------------------------------------------------------% |
217 | 473 | |
218 | 474 | :- instance saffron.destroy(buffer_ctx, buffer) where [ |
@@ -230,6 +486,14 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
230 | 486 | IOo = IOi; |
231 | 487 | "). |
232 | 488 | |
489 | +:- pragma foreign_proc("Java", | |
490 | + bind_buffer(Ctx::in, Buffer::in, Type::in, IOi::di, IOo::uo), | |
491 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
492 | + " | |
493 | + Ctx.bindBuffer(Buffer, Type); | |
494 | + IOo = IOi; | |
495 | + "). | |
496 | + | |
233 | 497 | %-----------------------------------------------------------------------------% |
234 | 498 | |
235 | 499 | :- pragma foreign_proc("C", |
@@ -263,6 +527,14 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
263 | 527 | IOo = IOi; |
264 | 528 | "). |
265 | 529 | |
530 | +:- pragma foreign_proc("Java", | |
531 | + buffer_data_float_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
532 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
533 | + " | |
534 | + Ctx.bufferData(Type, T); | |
535 | + IOo = IOi; | |
536 | + "). | |
537 | + | |
266 | 538 | %-----------------------------------------------------------------------------% |
267 | 539 | |
268 | 540 | :- pragma foreign_proc("C", |
@@ -297,6 +569,14 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
297 | 569 | IOo = IOi; |
298 | 570 | "). |
299 | 571 | |
572 | +:- pragma foreign_proc("Java", | |
573 | + buffer_data_int_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
574 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
575 | + " | |
576 | + Ctx.bufferData(Type, T); | |
577 | + IOo = IOi; | |
578 | + "). | |
579 | + | |
300 | 580 | %-----------------------------------------------------------------------------% |
301 | 581 | % TODO: This should work, and is optimal when we have unboxed floats, but |
302 | 582 | % we should eventually implement a better C version for when we have boxed |
@@ -304,11 +584,31 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :- | ||
304 | 584 | buffer_data_float_list(Ctx, Type, List, !IO) :- |
305 | 585 | buffer_data_float_array(Ctx, Type, array.from_list(List), !IO). |
306 | 586 | |
587 | +% Java will always have boxed/Object-ified values in lists. | |
588 | +% Convert from that to a primitive array in one go. | |
589 | +:- pragma foreign_proc("Java", | |
590 | + buffer_data_float_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
591 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
592 | + " | |
593 | + Ctx.bufferDataD(Type, T); | |
594 | + IOo = IOi; | |
595 | + "). | |
596 | + | |
307 | 597 | %-----------------------------------------------------------------------------% |
308 | 598 | % As integers are always unboxed, this actually is optimal. |
309 | 599 | buffer_data_int_list(Ctx, Type, List, !IO) :- |
310 | 600 | buffer_data_int_array(Ctx, Type, array.from_list(List), !IO). |
311 | 601 | |
602 | +% Java will always have boxed/Object-ified values in lists. | |
603 | +% Convert from that to a primitive array in one go. | |
604 | +:- pragma foreign_proc("Java", | |
605 | + buffer_data_int_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
606 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
607 | + " | |
608 | + Ctx.bufferDataI(Type, T); | |
609 | + IOo = IOi; | |
610 | + "). | |
611 | + | |
312 | 612 | %-----------------------------------------------------------------------------% |
313 | 613 | |
314 | 614 | :- pragma foreign_proc("C", |
@@ -337,6 +637,14 @@ buffer_data_int_list(Ctx, Type, List, !IO) :- | ||
337 | 637 | IOo = IOi; |
338 | 638 | "). |
339 | 639 | |
640 | +:- pragma foreign_proc("Java", | |
641 | + buffer_data_vertex2d_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
642 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
643 | + " | |
644 | + Ctx.bufferData2(Type, (Vertex_1[])T); | |
645 | + IOo = IOi; | |
646 | + "). | |
647 | + | |
340 | 648 | :- pragma foreign_proc("C", |
341 | 649 | buffer_data_vertex2d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), |
342 | 650 | [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
@@ -369,6 +677,14 @@ buffer_data_int_list(Ctx, Type, List, !IO) :- | ||
369 | 677 | IOo = IOi; |
370 | 678 | "). |
371 | 679 | |
680 | +:- pragma foreign_proc("Java", | |
681 | + buffer_data_vertex2d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
682 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
683 | + " | |
684 | + Ctx.bufferData2(Type, T); | |
685 | + IOo = IOi; | |
686 | + "). | |
687 | + | |
372 | 688 | %-----------------------------------------------------------------------------% |
373 | 689 | |
374 | 690 | :- pragma foreign_proc("C", |
@@ -400,6 +716,14 @@ buffer_data_int_list(Ctx, Type, List, !IO) :- | ||
400 | 716 | IOo = IOi; |
401 | 717 | "). |
402 | 718 | |
719 | +:- pragma foreign_proc("Java", | |
720 | + buffer_data_vertex3d_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
721 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
722 | + " | |
723 | + Ctx.bufferData3(Type, (Vertex_1[])T); | |
724 | + IOo = IOi; | |
725 | + "). | |
726 | + | |
403 | 727 | :- pragma foreign_proc("C", |
404 | 728 | buffer_data_vertex3d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), |
405 | 729 | [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
@@ -432,3 +756,11 @@ buffer_data_int_list(Ctx, Type, List, !IO) :- | ||
432 | 756 | IOo = IOi; |
433 | 757 | "). |
434 | 758 | |
759 | +:- pragma foreign_proc("Java", | |
760 | + buffer_data_vertex3d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo), | |
761 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
762 | + " | |
763 | + Ctx.bufferData3(Type, T); | |
764 | + IOo = IOi; | |
765 | + "). | |
766 | + |
@@ -221,6 +221,39 @@ typedef char SaffronGLchar; | ||
221 | 221 | |
222 | 222 | "). |
223 | 223 | |
224 | +% Imports for the Java grade. | |
225 | +:- pragma foreign_decl("Java", " | |
226 | +import org.lwjgl.opengl.GL; | |
227 | +import org.lwjgl.opengl.GL11; // Base constants | |
228 | +import org.lwjgl.opengl.GL20; | |
229 | +import java.nio.ByteBuffer; | |
230 | +import jmercury.maybe.Maybe_1; // Used in MaybeInteger. | |
231 | + "). | |
232 | + | |
233 | +:- pragma foreign_code("Java", " | |
234 | +/////////////////////////////////////////////////////////////////////////////// | |
235 | +/// \brief Shorthand to create a maybe(int). | |
236 | +public static Maybe_1<Integer> MaybeInteger(int i, boolean b){ | |
237 | + return b ? new Maybe_1.Yes_1(new Integer(i)) : new Maybe_1.No_0(); | |
238 | +} | |
239 | + | |
240 | +public static jmercury.maybe.Maybe_1<Integer> MaybeInteger(int i){ | |
241 | + return MaybeInteger(i, i >= 0); | |
242 | +} | |
243 | +public static ByteBuffer BufferFromBitmap( | |
244 | + int w, | |
245 | + int h, | |
246 | + jmercury.runtime.MercuryBitmap bmp){ | |
247 | + if(w * h * 4 < bmp.elements.length) | |
248 | + throw new IndexOutOfBoundsException(""Bitmap is too small""); | |
249 | + final ByteBuffer buffer = ByteBuffer.allocateDirect(w * h * 4); | |
250 | + buffer.put(bmp.elements, 0, w * h * 4); | |
251 | + buffer.rewind(); | |
252 | + buffer.mark(); | |
253 | + return buffer; | |
254 | +} | |
255 | + "). | |
256 | + | |
224 | 257 | %-----------------------------------------------------------------------------% |
225 | 258 | |
226 | 259 | :- pragma foreign_enum("C", data_type/0, [ |
@@ -230,6 +263,26 @@ typedef char SaffronGLchar; | ||
230 | 263 | short - "GL_UNSIGNED_SHORT" |
231 | 264 | ]). |
232 | 265 | |
266 | +:- pragma foreign_export_enum( | |
267 | + "Java", | |
268 | + data_type/0, | |
269 | + [prefix("DATA_TYPE_")|[uppercase|[]]]). | |
270 | + | |
271 | +:- pragma foreign_code("Java", " | |
272 | +public static int DataTypeToGL(Data_type_0 t){ | |
273 | + if(t.equals(DATA_TYPE_INT)) | |
274 | + return org.lwjgl.opengl.GL11.GL_INT; | |
275 | + else if(t.equals(DATA_TYPE_FLOAT)) | |
276 | + return org.lwjgl.opengl.GL11.GL_DOUBLE; | |
277 | + else if(t.equals(DATA_TYPE_BYTE)) | |
278 | + return org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; | |
279 | + else if(t.equals(DATA_TYPE_SHORT)) | |
280 | + return org.lwjgl.opengl.GL11.GL_UNSIGNED_SHORT; | |
281 | + else | |
282 | + throw new IllegalStateException(""Unknown data type""); | |
283 | +} | |
284 | + "). | |
285 | + | |
233 | 286 | %-----------------------------------------------------------------------------% |
234 | 287 | |
235 | 288 | :- pragma foreign_enum("C", primitive_type/0, [ |
@@ -239,9 +292,30 @@ typedef char SaffronGLchar; | ||
239 | 292 | triangle_fan - "GL_TRIANGLE_FAN" |
240 | 293 | ]). |
241 | 294 | |
295 | +:- pragma foreign_export_enum( | |
296 | + "Java", | |
297 | + primitive_type/0, | |
298 | + [prefix("PRIMITIVE_TYPE_")|[uppercase|[]]]). | |
299 | + | |
300 | +:- pragma foreign_code("Java", " | |
301 | +public static int PrimitiveTypeToGL(Primitive_type_0 t){ | |
302 | + if(t.equals(PRIMITIVE_TYPE_LINE_STRIP)) | |
303 | + return org.lwjgl.opengl.GL11.GL_LINE_STRIP; | |
304 | + if(t.equals(PRIMITIVE_TYPE_LINE_LOOP)) | |
305 | + return org.lwjgl.opengl.GL11.GL_LINE_LOOP; | |
306 | + if(t.equals(PRIMITIVE_TYPE_TRIANGLE_STRIP)) | |
307 | + return org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; | |
308 | + if(t.equals(PRIMITIVE_TYPE_TRIANGLE_FAN)) | |
309 | + return org.lwjgl.opengl.GL11.GL_TRIANGLE_FAN; | |
310 | + else | |
311 | + throw new IllegalStateException(""Unknown primitive type""); | |
312 | +} | |
313 | + "). | |
314 | + | |
242 | 315 | %-----------------------------------------------------------------------------% |
243 | 316 | |
244 | 317 | :- pragma foreign_type("C", texture, "GLuint"). |
318 | +:- pragma foreign_type("Java", texture, "int"). | |
245 | 319 | |
246 | 320 | %-----------------------------------------------------------------------------% |
247 | 321 |
@@ -256,6 +330,7 @@ primitive_type(saffron.geometry.triangle_fan, saffron.gl.triangle_fan). | ||
256 | 330 | :- mode supports_extension_inner(in, uo, di, uo) is det. |
257 | 331 | |
258 | 332 | supports_extension_inner(_, bool.no, !IO). |
333 | + | |
259 | 334 | :- pragma foreign_proc("C", |
260 | 335 | supports_extension_inner(Ext::in, Supports::uo, IOi::di, IOo::uo), |
261 | 336 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
@@ -306,6 +381,13 @@ float_bytes = 8. | ||
306 | 381 | glGenTextures(1, &Tex); |
307 | 382 | "). |
308 | 383 | |
384 | +:- pragma foreign_proc("Java", create_texture(Tex::out, IOi::di, IOo::uo), | |
385 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
386 | + " | |
387 | + IOo = IOi; | |
388 | + Tex = org.lwjgl.opengl.GL11.glGenTextures(); | |
389 | + "). | |
390 | + | |
309 | 391 | %-----------------------------------------------------------------------------% |
310 | 392 | |
311 | 393 | :- pred tex_parameters(io.io::di, io.io::uo) is det. |
@@ -319,6 +401,14 @@ float_bytes = 8. | ||
319 | 401 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
320 | 402 | "). |
321 | 403 | |
404 | +:- pragma foreign_proc("Java", tex_parameters(IOi::di, IOo::uo), | |
405 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
406 | + " | |
407 | + IOo = IOi; | |
408 | + org.lwjgl.opengl.GL11.glTexParameteri(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER, org.lwjgl.opengl.GL11.GL_NEAREST); | |
409 | + org.lwjgl.opengl.GL11.glTexParameteri(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER, org.lwjgl.opengl.GL11.GL_NEAREST); | |
410 | + "). | |
411 | + | |
322 | 412 | %-----------------------------------------------------------------------------% |
323 | 413 | |
324 | 414 | :- pragma foreign_proc("C", bind_texture(Tex::in, IOi::di, IOo::uo), |
@@ -329,6 +419,13 @@ float_bytes = 8. | ||
329 | 419 | glBindTexture(GL_TEXTURE_2D, Tex); |
330 | 420 | "). |
331 | 421 | |
422 | +:- pragma foreign_proc("Java", bind_texture(Tex::in, IOi::di, IOo::uo), | |
423 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
424 | + " | |
425 | + IOo = IOi; | |
426 | + org.lwjgl.opengl.GL11.glBindTexture(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, Tex); | |
427 | + "). | |
428 | + | |
332 | 429 | %-----------------------------------------------------------------------------% |
333 | 430 | |
334 | 431 | :- pred tex_image(int::in, int::in, io.io::di, io.io::uo) is det. |
@@ -342,6 +439,22 @@ float_bytes = 8. | ||
342 | 439 | GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
343 | 440 | "). |
344 | 441 | |
442 | +:- pragma foreign_proc("Java", tex_image(W::in, H::in, IOi::di, IOo::uo), | |
443 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
444 | + " | |
445 | + IOo = IOi; | |
446 | + org.lwjgl.opengl.GL11.nglTexImage2D( | |
447 | + org.lwjgl.opengl.GL11.GL_TEXTURE_2D, | |
448 | + 0, | |
449 | + org.lwjgl.opengl.GL11.GL_RGBA, | |
450 | + W, | |
451 | + H, | |
452 | + 0, | |
453 | + org.lwjgl.opengl.GL11.GL_RGBA, | |
454 | + org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE, | |
455 | + 0); | |
456 | + "). | |
457 | + | |
345 | 458 | %-----------------------------------------------------------------------------% |
346 | 459 | |
347 | 460 | :- pred tex_image(bitmap.bitmap, int, int, io.io, io.io). |
@@ -357,12 +470,30 @@ float_bytes = 8. | ||
357 | 470 | GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, B->elements); |
358 | 471 | "). |
359 | 472 | |
473 | +:- pragma foreign_proc("Java", tex_image(B::in, W::in, H::in, IOi::di, IOo::uo), | |
474 | + [will_not_call_mercury, promise_pure, thread_safe], | |
475 | + " | |
476 | + final java.nio.ByteBuffer buffer = jmercury.saffron__gl.BufferFromBitmap(W, H, B); | |
477 | + org.lwjgl.opengl.GL11.glTexImage2D( | |
478 | + org.lwjgl.opengl.GL11.GL_TEXTURE_2D, | |
479 | + 0, | |
480 | + org.lwjgl.opengl.GL11.GL_RGBA, | |
481 | + W, | |
482 | + H, | |
483 | + 0, | |
484 | + org.lwjgl.opengl.GL11.GL_RGBA, | |
485 | + org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE, | |
486 | + buffer); | |
487 | + IOo = IOi; | |
488 | + "). | |
489 | + | |
360 | 490 | %-----------------------------------------------------------------------------% |
361 | 491 | |
362 | 492 | :- pred tex_sub_image(bitmap.bitmap, int, int, int, int, io.io, io.io). |
363 | 493 | :- mode tex_sub_image(in, in, in, in, in, di, uo) is det. |
364 | 494 | |
365 | -:- pragma foreign_proc("C", tex_sub_image(B::in, X::in, Y::in, W::in, H::in, IOi::di, IOo::uo), | |
495 | +:- pragma foreign_proc("C", | |
496 | + tex_sub_image(B::in, X::in, Y::in, W::in, H::in, IOi::di, IOo::uo), | |
366 | 497 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
367 | 498 | may_duplicate, does_not_affect_liveness], |
368 | 499 | " |
@@ -372,6 +503,24 @@ float_bytes = 8. | ||
372 | 503 | GL_TEXTURE_2D, 0, X, Y, W, H, GL_RGBA, GL_UNSIGNED_BYTE, B->elements); |
373 | 504 | "). |
374 | 505 | |
506 | +:- pragma foreign_proc("Java", | |
507 | + tex_sub_image(B::in, X::in, Y::in, W::in, H::in, IOi::di, IOo::uo), | |
508 | + [will_not_call_mercury, promise_pure, thread_safe], | |
509 | + " | |
510 | + final java.nio.ByteBuffer buffer = jmercury.saffron__gl.BufferFromBitmap(W, H, B); | |
511 | + org.lwjgl.opengl.GL11.glTexImage2D( | |
512 | + org.lwjgl.opengl.GL11.GL_TEXTURE_2D, | |
513 | + 0, | |
514 | + X, | |
515 | + Y, | |
516 | + W, | |
517 | + H, | |
518 | + org.lwjgl.opengl.GL11.GL_RGBA, | |
519 | + org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE, | |
520 | + buffer); | |
521 | + IOo = IOi; | |
522 | + "). | |
523 | + | |
375 | 524 | %-----------------------------------------------------------------------------% |
376 | 525 | |
377 | 526 | :- pred destroy_texture(texture::in, io.io::di, io.io::uo) is det. |
@@ -384,6 +533,13 @@ float_bytes = 8. | ||
384 | 533 | glDeleteTextures(1, &Tex); |
385 | 534 | "). |
386 | 535 | |
536 | +:- pragma foreign_proc("Java", destroy_texture(Tex::in, IOi::di, IOo::uo), | |
537 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
538 | + " | |
539 | + IOo = IOi; | |
540 | + org.lwjgl.opengl.GL11.glDeleteTextures(Tex); | |
541 | + "). | |
542 | + | |
387 | 543 | %-----------------------------------------------------------------------------% |
388 | 544 | |
389 | 545 | destroy_texture(_Ctx, Tex, !IO) :- |
@@ -510,6 +666,8 @@ gl_supports_extension(gl_load_func_ctx(Ctx), Ext, Supports, !IO) :- | ||
510 | 666 | :- pred version_string(version_type, string, io.io, io.io). |
511 | 667 | :- mode version_string(in, out, di, uo) is det. |
512 | 668 | |
669 | +version_string(_, "0.0", !IO). | |
670 | + | |
513 | 671 | :- pragma foreign_proc("C", |
514 | 672 | version_string(Type::in, Str::out, IOi::di, IOo::uo), |
515 | 673 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
@@ -532,9 +690,21 @@ gl_supports_extension(gl_load_func_ctx(Ctx), Ext, Supports, !IO) :- | ||
532 | 690 | |
533 | 691 | %-----------------------------------------------------------------------------% |
534 | 692 | |
693 | +:- pred opengl_version_string(string::uo, io.io::di, io.io::uo) is det. | |
694 | +opengl_version_string(Str, !IO) :- | |
695 | + version_string(gl, Str, !IO). | |
696 | + | |
697 | +:- pragma foreign_proc("Java", | |
698 | + opengl_version_string(Str::uo, IOi::di, IOo::uo), | |
699 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
700 | + " | |
701 | + IOo = IOi; | |
702 | + Str = org.lwjgl.opengl.GL11.glGetString(org.lwjgl.opengl.GL11.GL_VERSION); | |
703 | + "). | |
704 | + | |
535 | 705 | opengl_version_string(Ctx, Str, !IO) :- |
536 | 706 | saffron.make_current(Ctx, !IO), |
537 | - version_string(gl, Str, !IO). | |
707 | + opengl_version_string(Str, !IO). | |
538 | 708 | |
539 | 709 | %-----------------------------------------------------------------------------% |
540 | 710 |
@@ -543,9 +713,22 @@ opengl_version(Ctx, saffron.parse_sem_ver(Version), !IO) :- | ||
543 | 713 | |
544 | 714 | %-----------------------------------------------------------------------------% |
545 | 715 | |
716 | +:- pred shader_model_version_string(string::uo, io.io::di, io.io::uo) is det. | |
717 | +shader_model_version_string(Str, !IO) :- | |
718 | + version_string(glsl, Str, !IO). | |
719 | + | |
720 | +:- pragma foreign_proc("Java", | |
721 | + shader_model_version_string(Str::uo, IOi::di, IOo::uo), | |
722 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
723 | + " | |
724 | + IOo = IOi; | |
725 | + Str = org.lwjgl.opengl.GL20.glGetString( | |
726 | + org.lwjgl.opengl.GL20.GL_SHADING_LANGUAGE_VERSION); | |
727 | + "). | |
728 | + | |
546 | 729 | shader_model_version_string(Ctx, Str, !IO) :- |
547 | 730 | saffron.make_current(Ctx, !IO), |
548 | - version_string(glsl, Str, !IO). | |
731 | + shader_model_version_string(Str, !IO). | |
549 | 732 | |
550 | 733 | %-----------------------------------------------------------------------------% |
551 | 734 |
@@ -287,6 +287,310 @@ | ||
287 | 287 | |
288 | 288 | :- pragma foreign_import_module("C", saffron.gl). |
289 | 289 | |
290 | +% Imports for the Java grade. | |
291 | +:- pragma foreign_decl("Java", " | |
292 | +import org.lwjgl.opengl.ARBShaderObjects; | |
293 | +import org.lwjgl.opengl.ARBFragmentShader; | |
294 | +import org.lwjgl.opengl.ARBVertexShader; | |
295 | +import org.lwjgl.opengl.GLCapabilities; | |
296 | +import org.lwjgl.opengl.GL; | |
297 | +import org.lwjgl.opengl.GL11; // Base constants | |
298 | +import org.lwjgl.opengl.GL20; | |
299 | +import org.lwjgl.opengl.GL32; // Geometry shaders | |
300 | +import org.lwjgl.opengl.GLCapabilities; | |
301 | +import jmercury.maybe.Maybe_error_2; | |
302 | + "). | |
303 | + | |
304 | +:- pragma foreign_export_enum( | |
305 | + "Java", | |
306 | + shader_type/0, | |
307 | + [prefix("SHADER_TYPE_")|[uppercase|[]]]). | |
308 | + | |
309 | +:- pragma foreign_code("Java", " | |
310 | +/////////////////////////////////////////////////////////////////////////////// | |
311 | +/// \brief Base class for a Shader context. | |
312 | +/// | |
313 | +/// This is a base class so that we can have either a context of sufficient | |
314 | +/// version to have shaders, or use ARB extensions to implement shaders. | |
315 | +public static abstract class Context{ | |
316 | + public final boolean supports_geometry_shaders; | |
317 | + protected Context(boolean l_supports_geometry_shaders){ | |
318 | + supports_geometry_shaders = l_supports_geometry_shaders; | |
319 | + } | |
320 | + public abstract int createProgram(); | |
321 | + public int createShader(Shader_type_0 type){ | |
322 | + if(type.equals(SHADER_TYPE_FRAGMENT)){ | |
323 | + return createFragmentShader(); | |
324 | + } | |
325 | + else if(type.equals(SHADER_TYPE_VERTEX)){ | |
326 | + return createVertexShader(); | |
327 | + } | |
328 | + else if(type.equals(SHADER_TYPE_GEOMETRY)){ | |
329 | + if(supports_geometry_shaders) | |
330 | + return createGeometryShader(); | |
331 | + // Otherwise, fallthrough below to be unsupported rather than | |
332 | + // unknown shader type. | |
333 | + } | |
334 | + else{ | |
335 | + throw new IllegalStateException(""Unknown shader type""); | |
336 | + } | |
337 | + throw new UnsupportedOperationException(""Unsupported shader type""); | |
338 | + } | |
339 | + protected abstract int createFragmentShader(); | |
340 | + protected abstract int createVertexShader(); | |
341 | + protected int createGeometryShader(){ | |
342 | + throw new UnsupportedOperationException( | |
343 | + ""Cannot create geometry shaders""); | |
344 | + } | |
345 | + public abstract void deleteShader(int shader); | |
346 | + public abstract void deleteProgram(int program); | |
347 | + public abstract void useProgram(int program); | |
348 | + public abstract void shaderSource(int shader, String src); | |
349 | + public abstract void compileShader(int shader); | |
350 | + public abstract void linkProgram(int program); | |
351 | + public abstract void attachShader(int program, int shader); | |
352 | + public abstract boolean shaderCompileStatus(int shader); | |
353 | + public abstract boolean programLinkStatus(int program); | |
354 | + public abstract String shaderInfoLog(int shader); | |
355 | + public abstract String programInfoLog(int program); | |
356 | + public abstract int getUniformLocation(int program, String name); | |
357 | + public abstract void uniform(int location, float f1); | |
358 | + public abstract void uniform(int location, float f1, float f2); | |
359 | + public abstract void uniform(int location, float f1, float f2, float f3); | |
360 | + public abstract void uniform(int location, float f1, float f2, float f3, float f4); | |
361 | + public abstract void uniformMat3x3(int location, float[] matrix); | |
362 | + public abstract void uniformMat4x4(int location, float[] matrix); | |
363 | + public abstract void bindAttribLocation(int program, int loc, String name); | |
364 | + public abstract int getAttribLocation(int program, String name); | |
365 | + public void vertexAttribPointer(int attrib, int n, jmercury.saffron__gl.Data_type_0 t, int stride, long ptr){ | |
366 | + final int type = jmercury.saffron__gl.DataTypeToGL(t); | |
367 | + vertexAttribPointer(attrib, n, type, stride, ptr); | |
368 | + } | |
369 | + public abstract void vertexAttribPointer(int attrib, int n, int type, int stride, long ptr); | |
370 | + public void uniform(int location, double f1){ | |
371 | + uniform(location, (float)f1); | |
372 | + } | |
373 | + public void uniform(int location, double f1, double f2){ | |
374 | + uniform(location, (float)f1, (float)f2); | |
375 | + } | |
376 | + public void uniform(int location, double f1, double f2, double f3){ | |
377 | + uniform(location, (float)f1, (float)f2, (float)f3); | |
378 | + } | |
379 | + public void uniform(int location, double f1, double f2, double f3, double f4){ | |
380 | + uniform(location, (float)f1, (float)f2, (float)f3, (float)f4); | |
381 | + } | |
382 | + public void uniform(int location, Double f1){ | |
383 | + uniform(location, f1.floatValue()); | |
384 | + } | |
385 | + public void uniform(int location, Double f1, Double f2){ | |
386 | + uniform(location, f1.floatValue(), f2.floatValue()); | |
387 | + } | |
388 | + public void uniform(int location, Double f1, Double f2, Double f3){ | |
389 | + uniform(location, f1.floatValue(), f2.floatValue(), f3.floatValue()); | |
390 | + } | |
391 | + public void uniform(int location, Double f1, Double f2, Double f3, Double f4){ | |
392 | + uniform(location, f1.floatValue(), f2.floatValue(), f3.floatValue(), f4.floatValue()); | |
393 | + } | |
394 | +} | |
395 | + | |
396 | +/////////////////////////////////////////////////////////////////////////////// | |
397 | +/// Shader context that uses OpenGL core features. | |
398 | +private static class GL20Context extends Context{ | |
399 | + public GL20Context(){ | |
400 | + this(GL.getCapabilities()); | |
401 | + } | |
402 | + public GL20Context(GLCapabilities caps){ | |
403 | + super(caps.OpenGL32); | |
404 | + } | |
405 | + public int createProgram(){ | |
406 | + return GL20.glCreateProgram(); | |
407 | + } | |
408 | + protected int createFragmentShader(){ | |
409 | + return GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER); | |
410 | + } | |
411 | + protected int createVertexShader(){ | |
412 | + return GL20.glCreateShader(GL20.GL_VERTEX_SHADER); | |
413 | + } | |
414 | + protected int createGeometryShader(){ | |
415 | + return GL32.glCreateShader(GL32.GL_FRAGMENT_SHADER); | |
416 | + } | |
417 | + public void deleteShader(int shader){ | |
418 | + GL20.glDeleteShader(shader); | |
419 | + } | |
420 | + public void deleteProgram(int program){ | |
421 | + GL20.glDeleteProgram(program); | |
422 | + } | |
423 | + public void useProgram(int program){ | |
424 | + GL20.glUseProgram(program); | |
425 | + } | |
426 | + public void shaderSource(int shader, String src){ | |
427 | + GL20.glShaderSource(shader, src); | |
428 | + } | |
429 | + public void compileShader(int shader){ | |
430 | + GL20.glCompileShader(shader); | |
431 | + } | |
432 | + public void linkProgram(int program){ | |
433 | + GL20.glLinkProgram(program); | |
434 | + } | |
435 | + public void attachShader(int program, int shader){ | |
436 | + GL20.glAttachShader(program, shader); | |
437 | + } | |
438 | + public boolean shaderCompileStatus(int shader){ | |
439 | + final int status = GL20.glGetShaderi(shader, GL20.GL_COMPILE_STATUS); | |
440 | + return status == GL20.GL_TRUE; | |
441 | + } | |
442 | + public boolean programLinkStatus(int program){ | |
443 | + final int status = GL20.glGetProgrami(program, GL20.GL_LINK_STATUS); | |
444 | + return status == GL20.GL_TRUE; | |
445 | + } | |
446 | + public String shaderInfoLog(int shader){ | |
447 | + return GL20.glGetShaderInfoLog(shader); | |
448 | + } | |
449 | + public String programInfoLog(int program){ | |
450 | + return GL20.glGetProgramInfoLog(program); | |
451 | + } | |
452 | + public int getUniformLocation(int program, String name){ | |
453 | + return GL20.glGetUniformLocation(program, name); | |
454 | + } | |
455 | + public void uniform(int location, float f1){ | |
456 | + GL20.glUniform1f(location, f1); | |
457 | + } | |
458 | + public void uniform(int location, float f1, float f2){ | |
459 | + GL20.glUniform2f(location, f1, f2); | |
460 | + } | |
461 | + public void uniform(int location, float f1, float f2, float f3){ | |
462 | + GL20.glUniform3f(location, f1, f2, f3); | |
463 | + } | |
464 | + public void uniform(int location, float f1, float f2, float f3, float f4){ | |
465 | + GL20.glUniform4f(location, f1, f2, f3, f4); | |
466 | + } | |
467 | + public void uniformMat3x3(int location, float[] matrix){ | |
468 | + GL20.glUniformMatrix3fv(location, false, matrix); | |
469 | + } | |
470 | + public void uniformMat4x4(int location, float[] matrix){ | |
471 | + GL20.glUniformMatrix4fv(location, false, matrix); | |
472 | + } | |
473 | + public void bindAttribLocation(int program, int loc, String name){ | |
474 | + GL20.glBindAttribLocation(program, loc, name); | |
475 | + } | |
476 | + public int getAttribLocation(int program, String name){ | |
477 | + return GL20.glGetAttribLocation(program, name); | |
478 | + } | |
479 | + public void vertexAttribPointer(int attrib, int n, int type, int stride, long ptr){ | |
480 | + GL20.nglVertexAttribPointer(attrib, n, type, false, stride, ptr); | |
481 | + } | |
482 | +} | |
483 | + | |
484 | +/////////////////////////////////////////////////////////////////////////////// | |
485 | +// A shader context that uses ARB extensions. | |
486 | +private static class ARBContext extends Context{ | |
487 | + public ARBContext(){ | |
488 | + super(false); | |
489 | + } | |
490 | + public int createProgram(){ | |
491 | + return ARBShaderObjects.glCreateProgramObjectARB(); | |
492 | + } | |
493 | + protected int createFragmentShader(){ | |
494 | + return ARBShaderObjects.glCreateShaderObjectARB( | |
495 | + ARBFragmentShader.GL_FRAGMENT_SHADER_ARB); | |
496 | + } | |
497 | + protected int createVertexShader(){ | |
498 | + return ARBShaderObjects.glCreateShaderObjectARB( | |
499 | + ARBVertexShader.GL_VERTEX_SHADER_ARB); | |
500 | + } | |
501 | + public void deleteShader(int shader){ | |
502 | + ARBShaderObjects.glDeleteObjectARB(shader); | |
503 | + } | |
504 | + public void deleteProgram(int program){ | |
505 | + ARBShaderObjects.glDeleteObjectARB(program); | |
506 | + } | |
507 | + public void useProgram(int program){ | |
508 | + ARBShaderObjects.glUseProgramObjectARB(program); | |
509 | + } | |
510 | + public void shaderSource(int shader, String src){ | |
511 | + ARBShaderObjects.glShaderSourceARB(shader, src); | |
512 | + } | |
513 | + public void compileShader(int shader){ | |
514 | + ARBShaderObjects.glCompileShaderARB(shader); | |
515 | + } | |
516 | + public void linkProgram(int program){ | |
517 | + ARBShaderObjects.glLinkProgramARB(program); | |
518 | + } | |
519 | + public void attachShader(int program, int shader){ | |
520 | + ARBShaderObjects.glAttachObjectARB(program, shader); | |
521 | + } | |
522 | + public boolean shaderCompileStatus(int shader){ | |
523 | + final int status = ARBShaderObjects.glGetObjectParameteriARB( | |
524 | + shader, | |
525 | + ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB); | |
526 | + return status == GL11.GL_TRUE; | |
527 | + } | |
528 | + public boolean programLinkStatus(int program){ | |
529 | + final int status = ARBShaderObjects.glGetObjectParameteriARB( | |
530 | + program, | |
531 | + ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB); | |
532 | + return status == GL11.GL_TRUE; | |
533 | + } | |
534 | + public String shaderInfoLog(int shader){ | |
535 | + return ARBShaderObjects.glGetInfoLogARB(shader); | |
536 | + } | |
537 | + public String programInfoLog(int program){ | |
538 | + return ARBShaderObjects.glGetInfoLogARB(program); | |
539 | + } | |
540 | + public int getUniformLocation(int program, String name){ | |
541 | + return ARBShaderObjects.glGetUniformLocationARB(program, name); | |
542 | + } | |
543 | + public void uniform(int location, float f1){ | |
544 | + ARBShaderObjects.glUniform1fARB(location, f1); | |
545 | + } | |
546 | + public void uniform(int location, float f1, float f2){ | |
547 | + ARBShaderObjects.glUniform2fARB(location, f1, f2); | |
548 | + } | |
549 | + public void uniform(int location, float f1, float f2, float f3){ | |
550 | + ARBShaderObjects.glUniform3fARB(location, f1, f2, f3); | |
551 | + } | |
552 | + public void uniform(int location, float f1, float f2, float f3, float f4){ | |
553 | + ARBShaderObjects.glUniform4fARB(location, f1, f2, f3, f4); | |
554 | + } | |
555 | + public void uniformMat3x3(int location, float[] matrix){ | |
556 | + ARBShaderObjects.glUniformMatrix3fvARB(location, false, matrix); | |
557 | + } | |
558 | + public void uniformMat4x4(int location, float[] matrix){ | |
559 | + ARBShaderObjects.glUniformMatrix4fvARB(location, false, matrix); | |
560 | + } | |
561 | + public void bindAttribLocation(int program, int loc, String name){ | |
562 | + ARBVertexShader.glBindAttribLocationARB(program, loc, name); | |
563 | + } | |
564 | + public int getAttribLocation(int program, String name){ | |
565 | + return ARBVertexShader.glGetAttribLocationARB(program, name); | |
566 | + } | |
567 | + public void vertexAttribPointer(int attrib, int n, int type, int stride, long ptr){ | |
568 | + ARBVertexShader.nglVertexAttribPointerARB(attrib, n, type, false, stride, ptr); | |
569 | + } | |
570 | +} | |
571 | + | |
572 | +/////////////////////////////////////////////////////////////////////////////// | |
573 | +/// \brief Creates a shader context, using OpenGL capabilities to determine | |
574 | +/// | |
575 | +/// if a GL2.0 or an ARB context is appropriate. | |
576 | +/// May return null if no context can be created. | |
577 | +public static Context CreateContext(){ | |
578 | + final GLCapabilities caps = GL.getCapabilities(); | |
579 | + if(caps.OpenGL20){ | |
580 | + return new GL20Context(); | |
581 | + } | |
582 | + else if(caps.GL_ARB_shader_objects && | |
583 | + caps.GL_ARB_fragment_shader && | |
584 | + caps.GL_ARB_vertex_shader){ | |
585 | + | |
586 | + return new ARBContext(); | |
587 | + } | |
588 | + else{ | |
589 | + return null; | |
590 | + } | |
591 | +} | |
592 | + "). | |
593 | + | |
290 | 594 | % Define the native prototypes to handle shaders. |
291 | 595 | :- pragma foreign_decl("C", " |
292 | 596 | #include ""saffron.gl.shader.inc"" |
@@ -368,25 +672,32 @@ struct SaffronGL_ShaderCtx{ | ||
368 | 672 | geometry - "GL_GEOMETRY_SHADER" |
369 | 673 | ]). |
370 | 674 | |
675 | +:- pragma foreign_export_enum("Java", shader_type/0). | |
676 | + | |
371 | 677 | %-----------------------------------------------------------------------------% |
372 | 678 | |
373 | 679 | :- pragma foreign_type("C", shader_ctx, "struct SaffronGL_ShaderCtx*"). |
680 | +:- pragma foreign_type("Java", shader_ctx, "jmercury.saffron__gl__shader.Context"). | |
374 | 681 | |
375 | 682 | %-----------------------------------------------------------------------------% |
376 | 683 | |
377 | 684 | :- pragma foreign_type("C", shader_program, "GLuint"). |
685 | +:- pragma foreign_type("Java", shader_program, "int"). | |
378 | 686 | |
379 | 687 | %-----------------------------------------------------------------------------% |
380 | 688 | |
381 | 689 | :- pragma foreign_type("C", shader, "GLuint"). |
690 | +:- pragma foreign_type("Java", shader, "int"). | |
382 | 691 | |
383 | 692 | %-----------------------------------------------------------------------------% |
384 | 693 | |
385 | 694 | :- pragma foreign_type("C", uniform, "GLuint"). |
695 | +:- pragma foreign_type("Java", uniform, "int"). | |
386 | 696 | |
387 | 697 | %-----------------------------------------------------------------------------% |
388 | 698 | |
389 | 699 | :- pragma foreign_type("C", vertex_attrib, "GLuint"). |
700 | +:- pragma foreign_type("Java", vertex_attrib, "int"). | |
390 | 701 | |
391 | 702 | %-----------------------------------------------------------------------------% |
392 | 703 |
@@ -419,6 +730,12 @@ create_shader_ctx_error(E) = maybe.error(E). | ||
419 | 730 | |
420 | 731 | %-----------------------------------------------------------------------------% |
421 | 732 | |
733 | +:- pragma foreign_code("Java", " | |
734 | +final public static Maybe_error_2<Context, String> create_context_error = | |
735 | + new Maybe_error_2.Error_1(""Shaders require OpenGL 2.0 or \ | |
736 | +GL_ARB_shader_objects, GL_ARB_vertex_shader, and GL_ARB_fragment_shader""); | |
737 | + "). | |
738 | + | |
422 | 739 | :- pred create_shader_ctx_internal( |
423 | 740 | gl_load_func_ctx, |
424 | 741 | maybe.maybe_error(shader_ctx), |
@@ -458,6 +775,19 @@ create_shader_ctx_error(E) = maybe.error(E). | ||
458 | 775 | IOo = IOi; |
459 | 776 | "). |
460 | 777 | |
778 | + | |
779 | +:- pragma foreign_proc("Java", | |
780 | + create_shader_ctx_internal(Ctx::in, MaybeShaderCtx::out, IOi::di, IOo::uo), | |
781 | + [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
782 | + " | |
783 | + final jmercury.saffron__gl__shader.Context ctx = | |
784 | + jmercury.saffron__gl__shader.CreateContext(); | |
785 | + MaybeShaderCtx = (ctx == null) ? | |
786 | + jmercury.saffron__gl__shader.create_context_error : | |
787 | + new jmercury.maybe.Maybe_error_2.Ok_1(ctx); | |
788 | + IOo = IOi; | |
789 | + "). | |
790 | + | |
461 | 791 | create_shader_ctx(Ctx, MaybeShaderCtx, !IO) :- |
462 | 792 | create_shader_ctx_internal('new gl_load_func_ctx'(Ctx), MaybeShaderCtx, !IO). |
463 | 793 |
@@ -472,6 +802,14 @@ create_shader_ctx(Ctx, MaybeShaderCtx, !IO) :- | ||
472 | 802 | IOo = IOi; |
473 | 803 | "). |
474 | 804 | |
805 | +:- pragma foreign_proc("Java", | |
806 | + destroy_shader_program(Ctx::in, Program::in, IOi::di, IOo::uo), | |
807 | + [promise_pure, thread_safe, will_not_throw_exception, may_duplicate], | |
808 | + " | |
809 | + Ctx.deleteProgram(Program); | |
810 | + IOo = IOi; | |
811 | + "). | |
812 | + | |
475 | 813 | %-----------------------------------------------------------------------------% |
476 | 814 | |
477 | 815 | :- pred create_program_inner( |
@@ -484,8 +822,6 @@ create_shader_ctx(Ctx, MaybeShaderCtx, !IO) :- | ||
484 | 822 | io.io, io.io). |
485 | 823 | :- mode create_program_inner(in, in, in, uo, uo, uo, di, uo) is det. |
486 | 824 | |
487 | -%-----------------------------------------------------------------------------% | |
488 | - | |
489 | 825 | :- pragma foreign_proc("C", |
490 | 826 | create_program_inner(Ctx::in, S2::in, S1::in, Prog::uo, OK::uo, Err::uo, IOi::di, IOo::uo), |
491 | 827 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
@@ -506,6 +842,28 @@ create_shader_ctx(Ctx, MaybeShaderCtx, !IO) :- | ||
506 | 842 | IOo = IOi; |
507 | 843 | "). |
508 | 844 | |
845 | +:- pragma foreign_proc("Java", | |
846 | + create_program_inner(Ctx::in, S2::in, S1::in, Prog::uo, OK::uo, Err::uo, IOi::di, IOo::uo), | |
847 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
848 | + " | |
849 | + Prog = Ctx.createProgram(); | |
850 | + OK = jmercury.bool.NO; | |
851 | + Err = """"; | |
852 | + if(Prog == 0){ | |
853 | + Err = ""Error creating shader program""; | |
854 | + } | |
855 | + else{ | |
856 | + Ctx.attachShader(Prog, S1); | |
857 | + Ctx.attachShader(Prog, S2); | |
858 | + Ctx.linkProgram(Prog); | |
859 | + if(Ctx.programLinkStatus(Prog)) | |
860 | + OK = jmercury.bool.YES; | |
861 | + else | |
862 | + Err = Ctx.programInfoLog(Prog); | |
863 | + } | |
864 | + IOo = IOi; | |
865 | + "). | |
866 | + | |
509 | 867 | %-----------------------------------------------------------------------------% |
510 | 868 | |
511 | 869 | :- pred create_program_inner( |
@@ -538,6 +896,31 @@ create_shader_ctx(Ctx, MaybeShaderCtx, !IO) :- | ||
538 | 896 | IOo = IOi; |
539 | 897 | "). |
540 | 898 | |
899 | +:- pragma foreign_proc("Java", | |
900 | + create_program_inner(Ctx::in, Shaders::in, Prog::uo, OK::uo, Err::uo, IOi::di, IOo::uo), | |
901 | + [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
902 | + " | |
903 | + Prog = Ctx.createProgram(); | |
904 | + OK = jmercury.bool.NO; | |
905 | + Err = """"; | |
906 | + if(Prog == 0){ | |
907 | + Err = ""Error creating shader program""; | |
908 | + OK = jmercury.bool.NO; | |
909 | + } | |
910 | + else{ | |
911 | + while(!jmercury.list.is_empty(Shaders)){ | |
912 | + Ctx.attachShader(Prog, jmercury.list.det_head(Shaders)); | |
913 | + Shaders = jmercury.list.det_tail(Shaders); | |
914 | + } | |
915 | + Ctx.linkProgram(Prog); | |
916 | + if(Ctx.programLinkStatus(Prog)) | |
917 | + OK = jmercury.bool.YES; | |
918 | + else | |
919 | + Err = Ctx.programInfoLog(Prog); | |
920 | + } | |
921 | + IOo = IOi; | |
922 | + "). | |
923 | + | |
541 | 924 | %-----------------------------------------------------------------------------% |
542 | 925 | |
543 | 926 | :- pred create_program_inner_array( |
@@ -573,6 +956,28 @@ create_program_inner_array(ShaderCtx, Shaders, Program, OK, Err, !IO) :- | ||
573 | 956 | IOo = IOi; |
574 | 957 | "). |
575 | 958 | |
959 | +:- pragma foreign_proc("Java", | |
960 | + create_program_inner_array(Ctx::in, Shaders::in, Prog::uo, OK::uo, Err::uo, IOi::di, IOo::uo), | |
961 | + [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
962 | + " | |
963 | + Prog = Ctx.createProgram(); | |
964 | + OK = jmercury.bool.NO; | |
965 | + Err = """"; | |
966 | + if(Prog == 0){ | |
967 | + Err = ""Error creating shader program""; | |
968 | + } | |
969 | + else{ | |
970 | + for(int shader : Shaders) | |
971 | + Ctx.attachShader(Prog, shader); | |
972 | + Ctx.linkProgram(Prog); | |
973 | + if(Ctx.programLinkStatus(Prog)) | |
974 | + OK = jmercury.bool.YES; | |
975 | + else | |
976 | + Err = Ctx.programInfoLog(Prog); | |
977 | + } | |
978 | + IOo = IOi; | |
979 | + "). | |
980 | + | |
576 | 981 | %-----------------------------------------------------------------------------% |
577 | 982 | |
578 | 983 | create_program(ShaderCtx, S1, S2, MaybeProgram, !IO) :- |
@@ -621,15 +1026,26 @@ create_program_array(ShaderCtx, Shaders, MaybeProgram, !IO) :- | ||
621 | 1026 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
622 | 1027 | may_duplicate, does_not_affect_liveness], |
623 | 1028 | " Prog = 0; "). |
1029 | + | |
1030 | +:- pragma foreign_proc("Java", no_shader_program = (Prog::out), | |
1031 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1032 | + " Prog = 0; "). | |
624 | 1033 | :- pragma inline(no_shader_program/0). |
625 | 1034 | |
626 | 1035 | %-----------------------------------------------------------------------------% |
627 | 1036 | |
628 | -:- pragma foreign_proc("C", use_program(Ctx::in, Program::in, IOi::di, IOo::uo), | |
1037 | +:- pragma foreign_proc("C", use_program(Ctx::in, Prog::in, IOi::di, IOo::uo), | |
629 | 1038 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
630 | 1039 | tabled_for_io, may_duplicate, does_not_affect_liveness], |
631 | 1040 | " |
632 | - SAFFRON_GL_SHADERCORE_FUNC(Ctx->core, UseProgram)(Program); | |
1041 | + SAFFRON_GL_SHADERCORE_FUNC(Ctx->core, UseProgram)(Prog); | |
1042 | + IOo = IOi; | |
1043 | + "). | |
1044 | + | |
1045 | +:- pragma foreign_proc("Java", use_program(Ctx::in, Prog::in, IOi::di, IOo::uo), | |
1046 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1047 | + " | |
1048 | + Ctx.useProgram(Prog); | |
633 | 1049 | IOo = IOi; |
634 | 1050 | "). |
635 | 1051 | :- pragma inline(use_program/4). |
@@ -644,6 +1060,14 @@ create_program_array(ShaderCtx, Shaders, MaybeProgram, !IO) :- | ||
644 | 1060 | IOo = IOi; |
645 | 1061 | "). |
646 | 1062 | |
1063 | +:- pragma foreign_proc("Java", | |
1064 | + destroy_shader(Ctx::in, Shader::in, IOi::di, IOo::uo), | |
1065 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1066 | + " | |
1067 | + Ctx.deleteShader(Shader); | |
1068 | + IOo = IOi; | |
1069 | + "). | |
1070 | + | |
647 | 1071 | %-----------------------------------------------------------------------------% |
648 | 1072 | |
649 | 1073 | :- pred create_shader( |
@@ -678,6 +1102,24 @@ create_program_array(ShaderCtx, Shaders, MaybeProgram, !IO) :- | ||
678 | 1102 | IOo = IOi; |
679 | 1103 | "). |
680 | 1104 | |
1105 | +:- pragma foreign_proc("Java", | |
1106 | + create_shader(Ctx::in, Type::in, Src::in, Shader::uo, OK::uo, Err::out, IOi::di, IOo::uo), | |
1107 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1108 | + " | |
1109 | + Shader = Ctx.createShader(Type); | |
1110 | + Ctx.shaderSource(Shader, Src); | |
1111 | + Ctx.compileShader(Shader); | |
1112 | + if(Ctx.shaderCompileStatus(Shader)){ | |
1113 | + OK = jmercury.bool.NO; | |
1114 | + Err = """"; | |
1115 | + } | |
1116 | + else{ | |
1117 | + OK = jmercury.bool.YES; | |
1118 | + Err = Ctx.shaderInfoLog(Shader); | |
1119 | + } | |
1120 | + IOo = IOi; | |
1121 | + "). | |
1122 | + | |
681 | 1123 | create_shader(Ctx, Type, Src, MaybeShader, !IO) :- |
682 | 1124 | create_shader(Ctx, Type, Src, Shader, OK, Err, !IO), |
683 | 1125 | ( |
@@ -730,6 +1172,15 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
730 | 1172 | IOo = IOi; |
731 | 1173 | "). |
732 | 1174 | |
1175 | +:- pragma foreign_proc("Java", | |
1176 | + get_uniform_location(Ctx::in, Prog::in, Name::in, MaybeUniform::uo, IOi::di, IOo::uo), | |
1177 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1178 | + " | |
1179 | + int i = Ctx.getUniformLocation(Prog, Name); | |
1180 | + MaybeUniform = jmercury.saffron__gl.MaybeInteger(i); | |
1181 | + IOo = IOi; | |
1182 | + "). | |
1183 | + | |
733 | 1184 | %-----------------------------------------------------------------------------% |
734 | 1185 | |
735 | 1186 | :- pragma foreign_proc("C", |
@@ -741,6 +1192,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
741 | 1192 | IOo = IOi; |
742 | 1193 | "). |
743 | 1194 | |
1195 | +:- pragma foreign_proc("Java", | |
1196 | + uniform(Ctx::in, U::in, F1::in, IOi::di, IOo::uo), | |
1197 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1198 | + " | |
1199 | + Ctx.uniform(U, F1); | |
1200 | + IOo = IOi; | |
1201 | + "). | |
1202 | + | |
744 | 1203 | %-----------------------------------------------------------------------------% |
745 | 1204 | |
746 | 1205 | :- pragma foreign_proc("C", |
@@ -752,6 +1211,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
752 | 1211 | IOo = IOi; |
753 | 1212 | "). |
754 | 1213 | |
1214 | +:- pragma foreign_proc("Java", | |
1215 | + uniform(Ctx::in, U::in, F1::in, F2::in, IOi::di, IOo::uo), | |
1216 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1217 | + " | |
1218 | + Ctx.uniform(U, F1, F2); | |
1219 | + IOo = IOi; | |
1220 | + "). | |
1221 | + | |
755 | 1222 | %-----------------------------------------------------------------------------% |
756 | 1223 | |
757 | 1224 | :- pragma foreign_proc("C", |
@@ -763,6 +1230,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
763 | 1230 | IOo = IOi; |
764 | 1231 | "). |
765 | 1232 | |
1233 | +:- pragma foreign_proc("Java", | |
1234 | + uniform(Ctx::in, U::in, F1::in, F2::in, F3::in, IOi::di, IOo::uo), | |
1235 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1236 | + " | |
1237 | + Ctx.uniform(U, F1, F2, F3); | |
1238 | + IOo = IOi; | |
1239 | + "). | |
1240 | + | |
766 | 1241 | %-----------------------------------------------------------------------------% |
767 | 1242 | |
768 | 1243 | :- pragma foreign_proc("C", |
@@ -774,6 +1249,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
774 | 1249 | IOo = IOi; |
775 | 1250 | "). |
776 | 1251 | |
1252 | +:- pragma foreign_proc("Java", | |
1253 | + uniform(Ctx::in, U::in, F1::in, F2::in, F3::in, F4::in, IOi::di, IOo::uo), | |
1254 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1255 | + " | |
1256 | + Ctx.uniform(U, F1, F2, F3, F4); | |
1257 | + IOo = IOi; | |
1258 | + "). | |
1259 | + | |
777 | 1260 | %-----------------------------------------------------------------------------% |
778 | 1261 | |
779 | 1262 | :- pragma foreign_proc("C", |
@@ -792,6 +1275,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
792 | 1275 | IOo = IOi; |
793 | 1276 | "). |
794 | 1277 | |
1278 | +:- pragma foreign_proc("Java", | |
1279 | + uniform1(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1280 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1281 | + " | |
1282 | + Ctx.uniform(U, FV[0]); | |
1283 | + IOo = IOi; | |
1284 | + "). | |
1285 | + | |
795 | 1286 | %-----------------------------------------------------------------------------% |
796 | 1287 | |
797 | 1288 | :- pragma foreign_proc("C", |
@@ -811,6 +1302,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
811 | 1302 | IOo = IOi; |
812 | 1303 | "). |
813 | 1304 | |
1305 | +:- pragma foreign_proc("Java", | |
1306 | + uniform2(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1307 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1308 | + " | |
1309 | + Ctx.uniform(U, FV[0], FV[1]); | |
1310 | + IOo = IOi; | |
1311 | + "). | |
1312 | + | |
814 | 1313 | %-----------------------------------------------------------------------------% |
815 | 1314 | |
816 | 1315 | :- pragma foreign_proc("C", |
@@ -831,6 +1330,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
831 | 1330 | IOo = IOi; |
832 | 1331 | "). |
833 | 1332 | |
1333 | +:- pragma foreign_proc("Java", | |
1334 | + uniform3(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1335 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1336 | + " | |
1337 | + Ctx.uniform(U, FV[0], FV[1], FV[2]); | |
1338 | + IOo = IOi; | |
1339 | + "). | |
1340 | + | |
834 | 1341 | %-----------------------------------------------------------------------------% |
835 | 1342 | |
836 | 1343 | :- pragma foreign_proc("C", |
@@ -852,6 +1359,14 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
852 | 1359 | IOo = IOi; |
853 | 1360 | "). |
854 | 1361 | |
1362 | +:- pragma foreign_proc("Java", | |
1363 | + uniform4(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1364 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1365 | + " | |
1366 | + Ctx.uniform(U, FV[0], FV[1], FV[2], FV[4]); | |
1367 | + IOo = IOi; | |
1368 | + "). | |
1369 | + | |
855 | 1370 | %-----------------------------------------------------------------------------% |
856 | 1371 | |
857 | 1372 | :- pragma foreign_proc("C", |
@@ -877,6 +1392,23 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
877 | 1392 | IOo = IOi; |
878 | 1393 | "). |
879 | 1394 | |
1395 | +:- pragma foreign_proc("Java", | |
1396 | + uniform(Ctx::in, U::in, | |
1397 | + A1::in, A2::in, A3::in, | |
1398 | + B1::in, B2::in, B3::in, | |
1399 | + C1::in, C2::in, C3::in, | |
1400 | + IOi::di, IOo::uo), | |
1401 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1402 | + " | |
1403 | + float[] matrix = { | |
1404 | + (float)A1, (float)A2, (float)A3, | |
1405 | + (float)B1, (float)B2, (float)B3, | |
1406 | + (float)C1, (float)C2, (float)C3 | |
1407 | + }; | |
1408 | + Ctx.uniformMat3x3(U, matrix); | |
1409 | + IOo = IOi; | |
1410 | + "). | |
1411 | + | |
880 | 1412 | %-----------------------------------------------------------------------------% |
881 | 1413 | |
882 | 1414 | :- pragma foreign_proc("C", |
@@ -897,6 +1429,17 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
897 | 1429 | IOo = IOi; |
898 | 1430 | "). |
899 | 1431 | |
1432 | +:- pragma foreign_proc("Java", | |
1433 | + uniform3x3(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1434 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1435 | + " | |
1436 | + float[] matrix = new float[9]; | |
1437 | + for(int i = 0; i < 9; i++) | |
1438 | + matrix[i] = (float)FV[i]; | |
1439 | + Ctx.uniformMat3x3(U, matrix); | |
1440 | + IOo = IOi; | |
1441 | + "). | |
1442 | + | |
900 | 1443 | %-----------------------------------------------------------------------------% |
901 | 1444 | |
902 | 1445 | :- pragma foreign_proc("C", |
@@ -930,6 +1473,25 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
930 | 1473 | IOo = IOi; |
931 | 1474 | "). |
932 | 1475 | |
1476 | +:- pragma foreign_proc("Java", | |
1477 | + uniform(Ctx::in, U::in, | |
1478 | + A1::in, A2::in, A3::in, A4::in, | |
1479 | + B1::in, B2::in, B3::in, B4::in, | |
1480 | + C1::in, C2::in, C3::in, C4::in, | |
1481 | + D1::in, D2::in, D3::in, D4::in, | |
1482 | + IOi::di, IOo::uo), | |
1483 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1484 | + " | |
1485 | + float[] matrix = { | |
1486 | + (float)A1, (float)A2, (float)A3, (float)A4, | |
1487 | + (float)B1, (float)B2, (float)B3, (float)B4, | |
1488 | + (float)C1, (float)C2, (float)C3, (float)C4, | |
1489 | + (float)D1, (float)D2, (float)D3, (float)D4 | |
1490 | + }; | |
1491 | + Ctx.uniformMat4x4(U, matrix); | |
1492 | + IOo = IOi; | |
1493 | + "). | |
1494 | + | |
933 | 1495 | %-----------------------------------------------------------------------------% |
934 | 1496 | |
935 | 1497 | :- pragma foreign_proc("C", |
@@ -950,6 +1512,16 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
950 | 1512 | IOo = IOi; |
951 | 1513 | "). |
952 | 1514 | |
1515 | +:- pragma foreign_proc("Java", | |
1516 | + uniform4x4(Ctx::in, U::in, FV::in, IOi::di, IOo::uo), | |
1517 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1518 | + " | |
1519 | + float[] matrix = new float[16]; | |
1520 | + for(int i = 0; i < 16; i++) | |
1521 | + matrix[i] = (float)FV[i]; | |
1522 | + Ctx.uniformMat4x4(U, matrix); | |
1523 | + IOo = IOi; | |
1524 | + "). | |
953 | 1525 | |
954 | 1526 | %-----------------------------------------------------------------------------% |
955 | 1527 |
@@ -966,6 +1538,15 @@ maybe_uniform_yes(Uniform) = maybe.yes(Uniform). | ||
966 | 1538 | IOo = IOi; |
967 | 1539 | "). |
968 | 1540 | |
1541 | +:- pragma foreign_proc("Java", | |
1542 | + bind_attrib_location(Ctx::in, Program::in, Name::in, I::in, Attrib::uo, IOi::di, IOo::uo), | |
1543 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1544 | + " | |
1545 | + Ctx.bindAttribLocation(Program, I, Name); | |
1546 | + Attrib = I; | |
1547 | + IOo = IOi; | |
1548 | + "). | |
1549 | + | |
969 | 1550 | %-----------------------------------------------------------------------------% |
970 | 1551 | |
971 | 1552 | :- func maybe_vertex_attrib_no = (maybe.maybe(vertex_attrib)::uo) is det. |
@@ -994,10 +1575,19 @@ maybe_vertex_attrib_yes(Attrib) = maybe.yes(Attrib). | ||
994 | 1575 | IOo = IOi; |
995 | 1576 | "). |
996 | 1577 | |
1578 | +:- pragma foreign_proc("Java", | |
1579 | + get_attrib_location(Ctx::in, Program::in, Name::in, MaybeAttrib::uo, IOi::di, IOo::uo), | |
1580 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1581 | + " | |
1582 | + int i = Ctx.getAttribLocation(Program, Name); | |
1583 | + MaybeAttrib = jmercury.saffron__gl.MaybeInteger(i); | |
1584 | + IOo = IOi; | |
1585 | + "). | |
1586 | + | |
997 | 1587 | %-----------------------------------------------------------------------------% |
998 | 1588 | |
999 | 1589 | :- pragma foreign_proc("C", |
1000 | - vertex_attrib_pointer(Ctx::in, Attrib::in, Type::in, N::in, Stride::in, Offset::in, IOi::di, IOo::uo), | |
1590 | + vertex_attrib_pointer(Ctx::in, Attrib::in, N::in, Type::in, Stride::in, Offset::in, IOi::di, IOo::uo), | |
1001 | 1591 | [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, |
1002 | 1592 | may_duplicate, does_not_affect_liveness], |
1003 | 1593 | " |
@@ -1011,3 +1601,11 @@ maybe_vertex_attrib_yes(Attrib) = maybe.yes(Attrib). | ||
1011 | 1601 | IOo = IOi; |
1012 | 1602 | "). |
1013 | 1603 | |
1604 | +:- pragma foreign_proc("Java", | |
1605 | + vertex_attrib_pointer(Ctx::in, Attrib::in, N::in, Type::in, Stride::in, Offset::in, IOi::di, IOo::uo), | |
1606 | + [will_not_call_mercury, promise_pure, thread_safe, may_duplicate], | |
1607 | + " | |
1608 | + Ctx.vertexAttribPointer(Attrib, N, Type, Stride, Offset); | |
1609 | + IOo = IOi; | |
1610 | + "). | |
1611 | + |
@@ -239,6 +239,12 @@ | ||
239 | 239 | |
240 | 240 | %-----------------------------------------------------------------------------% |
241 | 241 | |
242 | +:- pragma foreign_decl("Java", " | |
243 | +import org.lwjgl.opengl.GL11; // The name saffron.gl2 a lie, it's really 1.1 | |
244 | + "). | |
245 | + | |
246 | +%-----------------------------------------------------------------------------% | |
247 | + | |
242 | 248 | :- pragma foreign_decl("C", " |
243 | 249 | // #define SAFFRON_GL2_DEBUG |
244 | 250 | #ifdef SAFFRON_GL2_DEBUG |
@@ -292,6 +298,10 @@ const char *Saffron_GL2_DebugError(void){ | ||
292 | 298 | saffron.draw.raise_matrix_stack_error, |
293 | 299 | "Saffron_GL2_RaiseMatrixStackError"). |
294 | 300 | |
301 | +:- pragma foreign_export("Java", | |
302 | + saffron.draw.raise_matrix_stack_error, | |
303 | + "RaiseMatrixStackError"). | |
304 | + | |
295 | 305 | %-----------------------------------------------------------------------------% |
296 | 306 | |
297 | 307 | :- pragma foreign_decl("C", |
@@ -366,6 +376,26 @@ const char *Saffron_GL2_DebugError(void){ | ||
366 | 376 | IOo = IOi; |
367 | 377 | "). |
368 | 378 | |
379 | +:- pragma foreign_proc("Java", | |
380 | + set_matrix( | |
381 | + V0::in, V1::in, V2::in, V3::in, | |
382 | + V4::in, V5::in, V6::in, V7::in, | |
383 | + V8::in, V9::in, V10::in, V11::in, | |
384 | + V12::in, V13::in, V14::in, V15::in, | |
385 | + IOi::di, IOo::uo), | |
386 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, | |
387 | + may_duplicate], | |
388 | + " | |
389 | + double[] matrix = { | |
390 | + V0, V4, V8,V12, | |
391 | + V1, V5, V9,V13, | |
392 | + V2, V6,V10,V14, | |
393 | + V3, V7,V11,V15 | |
394 | + }; | |
395 | + org.lwjgl.opengl.GL11.glLoadMatrixd(matrix); | |
396 | + IOo = IOi; | |
397 | + "). | |
398 | + | |
369 | 399 | %-----------------------------------------------------------------------------% |
370 | 400 | |
371 | 401 | :- pred transform `with_type` matrix_pred `with_inst` matrix_pred. |
@@ -401,6 +431,26 @@ const char *Saffron_GL2_DebugError(void){ | ||
401 | 431 | IOo = IOi; |
402 | 432 | "). |
403 | 433 | |
434 | +:- pragma foreign_proc("Java", | |
435 | + transform( | |
436 | + V0::in, V1::in, V2::in, V3::in, | |
437 | + V4::in, V5::in, V6::in, V7::in, | |
438 | + V8::in, V9::in, V10::in, V11::in, | |
439 | + V12::in, V13::in, V14::in, V15::in, | |
440 | + IOi::di, IOo::uo), | |
441 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, | |
442 | + may_duplicate], | |
443 | + " | |
444 | + double[] matrix = { | |
445 | + V0, V4, V8,V12, | |
446 | + V1, V5, V9,V13, | |
447 | + V2, V6,V10,V14, | |
448 | + V3, V7,V11,V15 | |
449 | + }; | |
450 | + org.lwjgl.opengl.GL11.glMultMatrixd(matrix); | |
451 | + IOo = IOi; | |
452 | + "). | |
453 | + | |
404 | 454 | %-----------------------------------------------------------------------------% |
405 | 455 | |
406 | 456 | :- pred transform(mmath.matrix.matrix::in, io.io::di, io.io::uo) is det. |
@@ -430,6 +480,13 @@ transform(Matrix, !IO) :- | ||
430 | 480 | IOo = IOi; |
431 | 481 | "). |
432 | 482 | |
483 | +:- pragma foreign_proc("Java", identity(IOi::di, IOo::uo), | |
484 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
485 | + " | |
486 | + org.lwjgl.opengl.GL11.glLoadIdentity(); | |
487 | + IOo = IOi; | |
488 | + "). | |
489 | + | |
433 | 490 | %-----------------------------------------------------------------------------% |
434 | 491 | |
435 | 492 | :- pred push_matrix(io.io::di, io.io::uo) is det. |
@@ -442,6 +499,13 @@ transform(Matrix, !IO) :- | ||
442 | 499 | IOo = IOi; |
443 | 500 | "). |
444 | 501 | |
502 | +:- pragma foreign_proc("Java", push_matrix(IOi::di, IOo::uo), | |
503 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
504 | + " | |
505 | + org.lwjgl.opengl.GL11.glPushMatrix(); | |
506 | + IOo = IOi; | |
507 | + "). | |
508 | + | |
445 | 509 | %-----------------------------------------------------------------------------% |
446 | 510 | |
447 | 511 | :- pred pop_matrix(io.io::di, io.io::uo) is det. |
@@ -455,6 +519,15 @@ transform(Matrix, !IO) :- | ||
455 | 519 | IOo = IOi; |
456 | 520 | "). |
457 | 521 | |
522 | +:- pragma foreign_proc("Java", pop_matrix(IOi::di, IOo::uo), | |
523 | + [may_call_mercury, promise_pure, thread_safe, may_duplicate], | |
524 | + " | |
525 | + org.lwjgl.opengl.GL11.glPopMatrix(); | |
526 | + if(GL11.glGetError() == org.lwjgl.opengl.GL11.GL_STACK_UNDERFLOW) | |
527 | + RaiseMatrixStackError(); | |
528 | + IOo = IOi; | |
529 | + "). | |
530 | + | |
458 | 531 | %-----------------------------------------------------------------------------% |
459 | 532 | |
460 | 533 | :- instance saffron.draw.basic_transform(context(Ctx)) |
@@ -761,6 +834,13 @@ generate_attrib_tree(Ctx, Shader, !:Tree, !IO) :- | ||
761 | 834 | IOo = IOi; |
762 | 835 | "). |
763 | 836 | |
837 | +:- pragma foreign_proc("Java", vertex(X::in, Y::in, Z::in, IOi::di, IOo::uo), | |
838 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
839 | + " | |
840 | + org.lwjgl.opengl.GL11.glVertex3d(X, Y, Z); | |
841 | + IOo = IOi; | |
842 | + "). | |
843 | + | |
764 | 844 | %-----------------------------------------------------------------------------% |
765 | 845 | |
766 | 846 | :- pred tex_coord(float::in, float::in, io.io::di, io.io::uo) is det. |
@@ -774,6 +854,13 @@ generate_attrib_tree(Ctx, Shader, !:Tree, !IO) :- | ||
774 | 854 | IOo = IOi; |
775 | 855 | "). |
776 | 856 | |
857 | +:- pragma foreign_proc("Java", tex_coord(U::in, V::in, IOi::di, IOo::uo), | |
858 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
859 | + " | |
860 | + org.lwjgl.opengl.GL11.glTexCoord2d(U, V); | |
861 | + IOo = IOi; | |
862 | + "). | |
863 | + | |
777 | 864 | %-----------------------------------------------------------------------------% |
778 | 865 | |
779 | 866 | :- pred tex_coord_i(int::in, int::in, io.io::di, io.io::uo) is det. |
@@ -787,6 +874,13 @@ generate_attrib_tree(Ctx, Shader, !:Tree, !IO) :- | ||
787 | 874 | IOo = IOi; |
788 | 875 | "). |
789 | 876 | |
877 | +:- pragma foreign_proc("Java", tex_coord_i(U::in, V::in, IOi::di, IOo::uo), | |
878 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
879 | + " | |
880 | + org.lwjgl.opengl.GL11.glTexCoord2i(U, V); | |
881 | + IOo = IOi; | |
882 | + "). | |
883 | + | |
790 | 884 | %-----------------------------------------------------------------------------% |
791 | 885 | |
792 | 886 | :- pred color(int::in, int::in, int::in, int::in, io.io::di, io.io::uo) is det. |
@@ -800,6 +894,14 @@ generate_attrib_tree(Ctx, Shader, !:Tree, !IO) :- | ||
800 | 894 | IOo = IOi; |
801 | 895 | "). |
802 | 896 | |
897 | +:- pragma foreign_proc("Java", | |
898 | + color(R::in, G::in, B::in, A::in, IOi::di, IOo::uo), | |
899 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception], | |
900 | + " | |
901 | + org.lwjgl.opengl.GL11.glColor4ub((byte)R, (byte)G, (byte)B, (byte)A); | |
902 | + IOo = IOi; | |
903 | + "). | |
904 | + | |
803 | 905 | %-----------------------------------------------------------------------------% |
804 | 906 | |
805 | 907 | :- pred color(color::in, io.io::di, io.io::uo) is det. |
@@ -849,6 +951,13 @@ draw_vertex3d(saffron.geometry.vertex(vector(X, Y, Z), U, V), C, !IO) :- | ||
849 | 951 | IOo = IOi; |
850 | 952 | "). |
851 | 953 | |
954 | +:- pragma foreign_proc("Java", begin(Type::in, IOi::di, IOo::uo), | |
955 | + [promise_pure, thread_safe, will_not_throw_exception], | |
956 | + " | |
957 | + org.lwjgl.opengl.GL11.glBegin(jmercury.saffron__gl.PrimitiveTypeToGL(Type)); | |
958 | + IOo = IOi; | |
959 | + "). | |
960 | + | |
852 | 961 | %-----------------------------------------------------------------------------% |
853 | 962 | |
854 | 963 | :- pred end(io.io::di, io.io::uo) is det. |
@@ -862,6 +971,13 @@ draw_vertex3d(saffron.geometry.vertex(vector(X, Y, Z), U, V), C, !IO) :- | ||
862 | 971 | IOo = IOi; |
863 | 972 | "). |
864 | 973 | |
974 | +:- pragma foreign_proc("Java", end(IOi::di, IOo::uo), | |
975 | + [promise_pure, thread_safe, will_not_throw_exception], | |
976 | + " | |
977 | + org.lwjgl.opengl.GL11.glEnd(); | |
978 | + IOo = IOi; | |
979 | + "). | |
980 | + | |
865 | 981 | %-----------------------------------------------------------------------------% |
866 | 982 | |
867 | 983 | :- pred draw_shape2d(shape(mmath.vector.vector2)::in, io.io::di, io.io::uo) is det. |
@@ -980,6 +1096,24 @@ draw_shape3d(Shape, !IO) :- | ||
980 | 1096 | */ |
981 | 1097 | "). |
982 | 1098 | |
1099 | +:- pragma foreign_proc("Java", init(IOi::di, IOo::uo), | |
1100 | + [promise_pure, thread_safe, will_not_throw_exception, no_sharing], | |
1101 | + " | |
1102 | + IOo = IOi; | |
1103 | + GL11.glEnable(GL11.GL_BLEND); | |
1104 | + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA); | |
1105 | + GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
1106 | + GL11.glColor4d(1.0, 1.0, 1.0, 1.0); | |
1107 | + GL11.glLineWidth(2.0f); // This is legacy for the Z2 engine (editor for Java) | |
1108 | + GL11.glEnable(GL11.GL_TEXTURE_2D); | |
1109 | + GL11.glEnable(GL11.GL_DEPTH_TEST); | |
1110 | + GL11.glLoadIdentity(); | |
1111 | + GL11.glMatrixMode(GL11.GL_PROJECTION); | |
1112 | + GL11.glLoadIdentity(); | |
1113 | + GL11.glMatrixMode(GL11.GL_MODELVIEW); | |
1114 | + GL11.glLoadIdentity(); | |
1115 | + "). | |
1116 | + | |
983 | 1117 | %-----------------------------------------------------------------------------% |
984 | 1118 | |
985 | 1119 | :- func complete_load_ctx(string, maybe.maybe_error(T)) = maybe.maybe(T). |
@@ -140,6 +140,50 @@ | ||
140 | 140 | :- use_module string. |
141 | 141 | |
142 | 142 | %-----------------------------------------------------------------------------% |
143 | +% Utilities used by Java code. | |
144 | +:- pragma foreign_decl("Java", " | |
145 | +import jmercury.list.List_1; | |
146 | +import jmercury.saffron__geometry.Vertex_1; | |
147 | + "). | |
148 | + | |
149 | +:- pragma foreign_code("Java", " | |
150 | +public static int ListLength(List_1<?> l){ | |
151 | + int i = 0; | |
152 | + while(!jmercury.list.is_empty(l)){ | |
153 | + i++; | |
154 | + l = jmercury.list.det_tail(l); | |
155 | + } | |
156 | + return i; | |
157 | +} | |
158 | +public static int WriteVector(double[] to, jmercury.mmath__vector__vector2.Vector_0 vector, int i){ | |
159 | + to[i++] = vector.x; | |
160 | + to[i++] = vector.y; | |
161 | + return i; | |
162 | +} | |
163 | +public static int WriteVector(double[] to, jmercury.mmath__vector__vector3.Vector_0 vector, int i){ | |
164 | + to[i++] = vector.x; | |
165 | + to[i++] = vector.y; | |
166 | + to[i++] = vector.z; | |
167 | + return i; | |
168 | +} | |
169 | +public static int WriteVertexUV(double[] to, Vertex_1<?> vertex, int i){ | |
170 | + to[i++] = vertex.u; | |
171 | + to[i++] = vertex.v; | |
172 | + return i; | |
173 | +} | |
174 | +public static int WriteVertex2(double[] to, Vertex_1<jmercury.mmath__vector__vector2.Vector_0> vertex, int i){ | |
175 | + i = WriteVector(to, vertex.vec, i); | |
176 | + i = WriteVertexUV(to, vertex, i); | |
177 | + return i; | |
178 | +} | |
179 | +public static int WriteVertex3(double[] to, Vertex_1<jmercury.mmath__vector__vector3.Vector_0> vertex, int i){ | |
180 | + i = WriteVector(to, vertex.vec, i); | |
181 | + i = WriteVertexUV(to, vertex, i); | |
182 | + return i; | |
183 | +} | |
184 | + "). | |
185 | + | |
186 | +%-----------------------------------------------------------------------------% | |
143 | 187 | |
144 | 188 | default_load_function(_, _, maybe.error("load_function not supported"), !IO). |
145 | 189 |