• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javaandroidc++linuxc#windowsobjective-ccocoaqtpython誰得phprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Graphics library for Mercury, including OpenGL bindings, TGA image reading, and X11, Win32, and SDL2 windowing and input.


コミットメタ情報

リビジョン26403b7ea308694b661777edacfef806d318d7a3 (tree)
日時2022-03-14 14:08:38
作者AlaskanEmily <emily@alas...>
コミッターAlaskanEmily

ログメッセージ

Add OpenGL buffer function bindings

変更サマリ

差分

--- a/saffron.geometry.m
+++ b/saffron.geometry.m
@@ -36,6 +36,15 @@
3636 :- mode vertex(muo, muo, muo, muo) = (mdi) is det.
3737 :- mode vertex(in, in, in, in) = (in) is semidet. % Implied.
3838
39+:- pred vertex(float, float, float, float, vertex2d).
40+:- mode vertex(in, in, in, in, out) is det.
41+:- mode vertex(di, di, di, di, uo) is det.
42+:- mode vertex(mdi, mdi, mdi, mdi, muo) is det.
43+:- mode vertex(out, out, out, out, in) is det.
44+:- mode vertex(uo, uo, uo, uo, di) is det.
45+:- mode vertex(muo, muo, muo, muo, mdi) is det.
46+:- mode vertex(in, in, in, in, in) is semidet. % Implied.
47+
3948 %-----------------------------------------------------------------------------%
4049 % This is intended to be used as if it was a functor for vertex, to construct
4150 % or destructure the vector so that the vector's fields appear directly in the
@@ -49,6 +58,15 @@
4958 :- mode vertex(muo, muo, muo, muo, muo) = (mdi) is det.
5059 :- mode vertex(in, in, in, in, in) = (in) is semidet. % Implied.
5160
61+:- pred vertex(float, float, float, float, float, vertex3d).
62+:- mode vertex(in, in, in, in, in, out) is det.
63+:- mode vertex(di, di, di, di, di, uo) is det.
64+:- mode vertex(mdi, mdi, mdi, mdi, mdi, muo) is det.
65+:- mode vertex(out, out, out, out, out, in) is det.
66+:- mode vertex(uo, uo, uo, uo, uo, di) is det.
67+:- mode vertex(muo, muo, muo, muo, muo, mdi) is det.
68+:- mode vertex(in, in, in, in, in, in) is semidet. % Implied.
69+
5270 %-----------------------------------------------------------------------------%
5371
5472 :- type primitive_type --->
@@ -174,11 +192,37 @@
174192
175193 %-----------------------------------------------------------------------------%
176194
195+:- pragma foreign_export("C",
196+ vertex(in, in, in, in) = (out),
197+ "SaffronGeometry_CreateVertex2D").
198+
199+%-----------------------------------------------------------------------------%
200+
201+:- pragma foreign_export("C",
202+ vertex(out, out, out, out, in),
203+ "SaffronGeometry_GetVertex2D").
204+
205+%-----------------------------------------------------------------------------%
206+
207+:- pragma foreign_export("C",
208+ vertex(in, in, in, in, in) = (out),
209+ "SaffronGeometry_CreateVertex3D").
210+
211+%-----------------------------------------------------------------------------%
212+
213+:- pragma foreign_export("C",
214+ vertex(out, out, out, out, out, in),
215+ "SaffronGeometry_GetVertex3D").
216+
217+%-----------------------------------------------------------------------------%
218+
177219 vertex(X, Y, U, V) = vertex(vector.vector2.vector(X, Y), U, V).
220+vertex(X, Y, U, V, vertex(vector.vector2.vector(X, Y), U, V)).
178221
179222 %-----------------------------------------------------------------------------%
180223
181224 vertex(X, Y, Z, U, V) = vertex(vector.vector3.vector(X, Y, Z), U, V).
225+vertex(X, Y, Z, U, V, vertex(vector.vector3.vector(X, Y, Z), U, V)).
182226
183227 %-----------------------------------------------------------------------------%
184228
--- a/saffron.gl.buffer.m
+++ b/saffron.gl.buffer.m
@@ -19,6 +19,11 @@
1919 :- interface.
2020 %=============================================================================%
2121
22+:- use_module array.
23+:- use_module list.
24+
25+:- use_module saffron.geometry.
26+
2227 %-----------------------------------------------------------------------------%
2328 % The function pointers to let us create buffers.
2429 :- type buffer_ctx.
@@ -39,11 +44,68 @@
3944 <= saffron.gl.context(Ctx).
4045 :- mode create_buffer_ctx(in, out, di, uo) is det.
4146
47+%-----------------------------------------------------------------------------%
48+
49+:- pred destroy_buffer(buffer_ctx::in, buffer::in, io.io::di, io.io::uo) is det.
50+
51+%-----------------------------------------------------------------------------%
52+
53+:- pred create_buffer(buffer_ctx::in, buffer::uo, io.io::di, io.io::uo) is det.
54+
55+%-----------------------------------------------------------------------------%
56+
57+:- instance saffron.destroy(buffer_ctx, buffer).
58+
59+%-----------------------------------------------------------------------------%
60+
61+:- pred bind_buffer(buffer_ctx, buffer, buffer_type, io.io, io.io).
62+:- mode bind_buffer(in, in, in, di, uo) is det.
63+
64+%-----------------------------------------------------------------------------%
65+
66+:- type buffer_data(T) == (pred(buffer_ctx, buffer_type, T, io.io, io.io)).
67+:- inst buffer_data == (pred(in, in, in, di, uo) is det).
68+
69+:- pred buffer_data_float_array
70+ `with_type` buffer_data(array.array(float))
71+ `with_inst` buffer_data.
72+
73+:- pred buffer_data_float_list
74+ `with_type` buffer_data(list.list(float))
75+ `with_inst` buffer_data.
76+
77+:- pred buffer_data_int_array
78+ `with_type` buffer_data(array.array(int))
79+ `with_inst` buffer_data.
80+
81+:- pred buffer_data_int_list
82+ `with_type` buffer_data(list.list(int))
83+ `with_inst` buffer_data.
84+
85+:- pred buffer_data_vertex2d_array
86+ `with_type` buffer_data(array.array(saffron.geometry.vertex2d))
87+ `with_inst` buffer_data.
88+
89+:- pred buffer_data_vertex2d_list
90+ `with_type` buffer_data(list.list(saffron.geometry.vertex2d))
91+ `with_inst` buffer_data.
92+
93+:- pred buffer_data_vertex3d_array
94+ `with_type` buffer_data(array.array(saffron.geometry.vertex3d))
95+ `with_inst` buffer_data.
96+
97+:- pred buffer_data_vertex3d_list
98+ `with_type` buffer_data(list.list(saffron.geometry.vertex3d))
99+ `with_inst` buffer_data.
100+
42101 %=============================================================================%
43102 :- implementation.
44103 %=============================================================================%
45104
46-:- use_module array.
105+:- use_module vector.
106+:- use_module vector.vector2.
107+:- use_module vector.vector3.
108+
47109 :- pragma foreign_import_module("C", saffron.gl).
48110
49111 % Define the native prototypes to handle buffers.
@@ -256,7 +318,6 @@ saffron_gl_create_buffer_ctx_internal:
256318 IOo = IOi;
257319 ").
258320
259-
260321 %-----------------------------------------------------------------------------%
261322
262323 create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :-
@@ -283,4 +344,235 @@ create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :-
283344 LoadFuncCtx = 'new gl_load_func_ctx'(Ctx),
284345 create_buffer_ctx_internal(LoadFuncCtx, Old, MaybeBufferCtx, !IO).
285346
347+%-----------------------------------------------------------------------------%
348+
349+:- pragma foreign_proc("C",
350+ create_buffer(Ctx::in, Buffer::uo, IOi::di, IOo::uo),
351+ [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
352+ tabled_for_io, may_duplicate, does_not_affect_liveness],
353+ "
354+ GLuint b;
355+ SAFFRON_GL_BUFFER_FUNC(Ctx, GenBuffers)(1, &b);
356+ Buffer = b;
357+ IOo = IOi;
358+ ").
359+
360+%-----------------------------------------------------------------------------%
361+
362+:- pragma foreign_proc("C",
363+ destroy_buffer(Ctx::in, Buffer::in, IOi::di, IOo::uo),
364+ [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
365+ tabled_for_io, may_duplicate, does_not_affect_liveness],
366+ "
367+ GLuint b = Buffer;
368+ SAFFRON_GL_BUFFER_FUNC(Ctx, DeleteBuffers)(1, &b);
369+ IOo = IOi;
370+ ").
371+
372+%-----------------------------------------------------------------------------%
373+
374+:- instance saffron.destroy(buffer_ctx, buffer) where [
375+ pred(saffron.destroy/4) is saffron.gl.buffer.destroy_buffer
376+].
377+
378+%-----------------------------------------------------------------------------%
379+
380+:- pragma foreign_proc("C",
381+ bind_buffer(Ctx::in, Buffer::in, Type::in, IOi::di, IOo::uo),
382+ [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
383+ may_duplicate, does_not_affect_liveness],
384+ "
385+ SAFFRON_GL_BUFFER_FUNC(Ctx, BindBuffer)(Type, Buffer);
386+ IOo = IOi;
387+ ").
388+
389+%-----------------------------------------------------------------------------%
390+
391+:- pragma foreign_proc("C",
392+ buffer_data_float_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
393+ [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
394+ may_duplicate, does_not_affect_liveness],
395+ "
396+ const MR_Integer len = T->size;
397+ MR_Float *array;
398+#ifdef MR_UNBOXED_FLOAT
399+ array = (void*)(T->elements);
400+#else
401+ MR_Integer i;
402+
403+ /* Attempt to avoid allocations if necessary. */
404+ MR_Float small_array[32];
405+ const int do_alloc = (len >= sizeof(small_array) / sizeof(MR_Float));
406+ array = (do_alloc) ? MR_malloc(sizeof(MR_Float) * len) : small_array;
407+
408+ /* Copy the data. */
409+ for(i = 0; i < len; i++){
410+ array[i] = MR_word_to_float(T->elements[i]);
411+ }
412+#endif
413+
414+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
415+ Type,
416+ sizeof(MR_Float) * len,
417+ array,
418+ GL_STATIC_DRAW);
419+
420+#ifndef MR_UNBOXED_FLOAT
421+ if(do_alloc)
422+ MR_free(array);
423+#endif
424+ IOo = IOi;
425+ ").
426+
427+%-----------------------------------------------------------------------------%
428+
429+:- pragma foreign_proc("C",
430+ buffer_data_int_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
431+ [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
432+ may_duplicate, does_not_affect_liveness],
433+ "
434+ /* MR_Integer is guaranteed to be unboxed. */
435+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
436+ Type,
437+ sizeof(MR_Integer) * T->size,
438+ T->elements,
439+ GL_STATIC_DRAW);
440+ IOo = IOi;
441+ ").
442+
443+%-----------------------------------------------------------------------------%
444+% TODO: This should work, and is optimal when we have unboxed floats, but
445+% we should eventually implement a better C version for when we have boxed
446+% floats.
447+buffer_data_float_list(Ctx, Type, List, !IO) :-
448+ buffer_data_float_array(Ctx, Type, array.from_list(List), !IO).
449+
450+%-----------------------------------------------------------------------------%
451+% As integers are always unboxed, this actually is optimal.
452+buffer_data_int_list(Ctx, Type, List, !IO) :-
453+ buffer_data_int_array(Ctx, Type, array.from_list(List), !IO).
454+
455+%-----------------------------------------------------------------------------%
456+
457+:- pragma foreign_proc("C",
458+ buffer_data_vertex2d_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
459+ [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
460+ may_duplicate],
461+ "
462+ MR_Word X, Y, U, V;
463+ const MR_Integer len = T->size;
464+ const MR_Integer buffer_size = len * sizeof(MR_Float) * 4;
465+ MR_Float *const buffer = MR_malloc(buffer_size);
466+ MR_Integer i;
467+
468+ for(i = 0; i < len; i++){
469+ SaffronGeometry_GetVertex2D(&X, &Y, &U, &V, T->elements[i]);
470+ buffer[(i * 4) + 0] = MR_word_to_float(X);
471+ buffer[(i * 4) + 1] = MR_word_to_float(Y);
472+ buffer[(i * 4) + 2] = MR_word_to_float(U);
473+ buffer[(i * 4) + 3] = MR_word_to_float(V);
474+ }
475+
476+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
477+ Type,
478+ buffer_size,
479+ buffer,
480+ GL_STATIC_DRAW);
481+ MR_free(buffer);
482+ IOo = IOi;
483+ ").
484+
485+:- pragma foreign_proc("C",
486+ buffer_data_vertex2d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
487+ [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
488+ may_duplicate],
489+ "
490+ MR_Word X, Y, U, V;
491+ MR_Integer i = 0, alloc_size = 32;
492+ MR_Float *buffer = MR_malloc(alloc_size * sizeof(MR_Float));
493+
494+ while(!MR_list_is_empty(T)){
495+ SaffronGeometry_GetVertex2D(&X, &Y, &U, &V, MR_list_head(T));
496+ T = MR_list_tail(T);
497+ if(i + 5 >= alloc_size){
498+ alloc_size <<= 1;
499+ buffer = MR_realloc(buffer, alloc_size * sizeof(MR_Float));
500+ }
501+ buffer[i++] = MR_word_to_float(X);
502+ buffer[i++] = MR_word_to_float(Y);
503+ buffer[i++] = MR_word_to_float(U);
504+ buffer[i++] = MR_word_to_float(V);
505+
506+ }
507+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
508+ Type,
509+ i * sizeof(MR_Float),
510+ buffer,
511+ GL_STATIC_DRAW);
512+ MR_free(buffer);
513+ IOo = IOi;
514+ ").
515+
516+%-----------------------------------------------------------------------------%
517+
518+:- pragma foreign_proc("C",
519+ buffer_data_vertex3d_array(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
520+ [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
521+ may_duplicate],
522+ "
523+ MR_Word X, Y, Z, U, V;
524+ const MR_Integer len = T->size;
525+ const MR_Integer buffer_size = len * sizeof(MR_Float) * 5;
526+ MR_Float *const buffer = MR_malloc(buffer_size);
527+ MR_Integer i;
528+
529+ for(i = 0; i < len; i++){
530+ SaffronGeometry_GetVertex3D(&X, &Y, &Z, &U, &V, T->elements[i]);
531+ buffer[(i * 5) + 0] = MR_word_to_float(X);
532+ buffer[(i * 5) + 1] = MR_word_to_float(Y);
533+ buffer[(i * 5) + 2] = MR_word_to_float(Z);
534+ buffer[(i * 5) + 3] = MR_word_to_float(U);
535+ buffer[(i * 5) + 4] = MR_word_to_float(V);
536+ }
537+
538+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
539+ Type,
540+ buffer_size,
541+ buffer,
542+ GL_STATIC_DRAW);
543+ MR_free(buffer);
544+ IOo = IOi;
545+ ").
546+
547+:- pragma foreign_proc("C",
548+ buffer_data_vertex3d_list(Ctx::in, Type::in, T::in, IOi::di, IOo::uo),
549+ [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception,
550+ may_duplicate],
551+ "
552+ MR_Word X, Y, Z, U, V;
553+ MR_Integer i = 0, alloc_size = 32;
554+ MR_Float *buffer = MR_malloc(alloc_size * sizeof(MR_Float));
555+
556+ while(!MR_list_is_empty(T)){
557+ SaffronGeometry_GetVertex3D(&X, &Y, &Z, &U, &V, MR_list_head(T));
558+ T = MR_list_tail(T);
559+ if(i + 5 >= alloc_size){
560+ alloc_size <<= 1;
561+ buffer = MR_realloc(buffer, alloc_size * sizeof(MR_Float));
562+ }
563+ buffer[i++] = MR_word_to_float(X);
564+ buffer[i++] = MR_word_to_float(Y);
565+ buffer[i++] = MR_word_to_float(Z);
566+ buffer[i++] = MR_word_to_float(U);
567+ buffer[i++] = MR_word_to_float(V);
568+
569+ }
570+ SAFFRON_GL_BUFFER_FUNC(Ctx, BufferData)(
571+ Type,
572+ i * sizeof(MR_Float),
573+ buffer,
574+ GL_STATIC_DRAW);
575+ MR_free(buffer);
576+ IOo = IOi;
577+ ").
286578