• 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.


コミットメタ情報

リビジョン4e6c5240a2e1bc4f3cdfa265efc31e302364d2a9 (tree)
日時2022-04-01 11:53:57
作者AlaskanEmily <emily@alas...>
コミッターAlaskanEmily

ログメッセージ

Handle Glow failures

変更サマリ

差分

--- a/demo/saffron_cube_demo.m
+++ b/demo/saffron_cube_demo.m
@@ -238,81 +238,98 @@ cube_geometry = [
238238 main(!IO) :-
239239 % Load the demo image
240240 saffron_tga.load_path("res/crate.tga", ImageResult, !IO),
241+
242+ % The Mercury compiler is smart enough to see that the error branch will
243+ % throw, and will unify the result outside that disjunction.
241244 (
242245 ImageResult = io.error(Err),
243246 exception.throw(exception.software_error(io.error_message(Err)))
244247 ;
245- ImageResult = io.ok({BMP, TexW, TexH}),
246-
247- W = 640,
248- H = 480,
249- Title = "Saffron Cube Demo",
250-
251- % Create the window and OpenGL context
252- saffron_glow.viewport_size(W, H, WinW, WinH),
253- saffron_glow.create_window(WinW, WinH, Title, Win, !IO),
254- saffron_glow.create_context(Win, 1, 3, GlowCtx, !IO),
255-
256- % Show the window.
257- % Depending on the Glow backend, this *might* need to happen after
258- % creating the OpenGL context.
259- saffron_glow.show_window(Win, !IO),
260-
261- % Using the backend-specific type is what determines what backend we
262- % will use.
263- saffron.gl2.init(GlowCtx, Ctx, !IO),
264-
265- saffron.gl.shader_model_version_string(Ctx, VersionString, !IO),
266- io.write_string("GLSL Version: ", !IO),
267- io.write_string(VersionString, !IO),
268- io.nl(!IO),
269-
270- % Set the ortho mode
271- AR = float(W) / float(H),
272-
273- Matrix = matrix.ortho(-AR, AR, 1.0, -1.0, -1000.0, 1000.0),
274- saffron.draw.set_matrix(Ctx, Matrix, !IO),
275-
276- saffron.draw.transform(Ctx, matrix.scale(0.4, 0.4, 0.4), !IO),
277-
278- % foo(!IO),
279-
280- % Upload the image to create a texture.
281- saffron.gl.create_texture_from_bitmap(Ctx, BMP, TexW, TexH, Texture, !IO),
282- Faces = cube_geometry,
283-
284- % Upload geometry to buffers.
285- % Most programs would probably want to use index buffers for a shape
286- % like this with mostly shared geometry.
287- list.map_foldl(
288- saffron.geometry.create_buffer_list(Ctx),
289- % list.map(list.reverse, Faces), FaceBuffers,
290- Faces, FaceBuffers,
291- !IO),
292-
293- % Construct the faces.
294- % This *could* be done as one large, wound shape, but a majority of
295- % programs will be loading meshes that will contain individual hulls/
296- % faces that will need to be constructed in this way.
297- list.map_foldl(
298- saffron.geometry.create_shape2(Ctx, saffron.geometry.triangle_strip, Texture),
299- FaceBuffers, Shapes,
300- !IO),
301-
302- % Construct the shape.
303- saffron.draw.create_group_list(Ctx, Shapes, Group, !IO),
304-
305- % Run the engine.
306- run(Ctx, Win, Group, !IO),
307-
308- % Cleanup
309- saffron.destroy(Ctx, Group, !IO),
310- list.foldl(saffron.destroy(Ctx), Shapes, !IO),
311- list.foldl(saffron.destroy(Ctx), FaceBuffers, !IO),
312- saffron.destroy(Ctx, Texture, !IO),
313-
314- % The window and context will be garbage-collected?
315- % I wrote the bindings years ago, I don't remember the intention :(
316- saffron_glow.hide_window(Win, !IO)
317- ).
248+ ImageResult = io.ok({BMP, TexW, TexH})
249+ ),
250+ W = 640,
251+ H = 480,
252+ Title = "Saffron Cube Demo",
253+
254+ % Create the window and OpenGL context
255+ saffron_glow.viewport_size(W, H, WinW, WinH),
256+ saffron_glow.create_window(WinW, WinH, Title, WinRes, !IO),
257+ (
258+ WinRes = io.error(Err),
259+ exception.throw(exception.software_error(io.error_message(Err)))
260+ ;
261+ WinRes = io.ok(Win)
262+ ),
263+ saffron_glow.create_context(Win, 1, 3, GlowCtxRes, !IO),
264+ (
265+ GlowCtxRes = io.error(Err),
266+ exception.throw(exception.software_error(io.error_message(Err)))
267+ ;
268+ GlowCtxRes = io.ok(GlowCtx)
269+ ),
270+
271+ % Show the window.
272+ % Depending on the Glow backend, this *might* need to happen after creating
273+ % the OpenGL context, but not necessarily.
274+ saffron_glow.show_window(Win, !IO),
275+
276+ % Using the backend-specific type is what determines what backend Glow is
277+ % using.
278+ saffron.gl2.init(GlowCtx, Ctx, !IO),
279+
280+ saffron.gl.opengl_version_string(Ctx, GLVersion, !IO),
281+ io.write_string("OpenGL Version: ", !IO),
282+ io.write_string(GLVersion, !IO),
283+ io.nl(!IO),
284+
285+ saffron.gl.shader_model_version_string(Ctx, GLSLVersion, !IO),
286+ io.write_string("GLSL Version: ", !IO),
287+ io.write_string(GLSLVersion, !IO),
288+ io.nl(!IO),
289+
290+ % Set the ortho mode
291+ AR = float(W) / float(H),
292+
293+ Matrix = matrix.ortho(-AR, AR, 1.0, -1.0, -1000.0, 1000.0),
294+ saffron.draw.set_matrix(Ctx, Matrix, !IO),
295+
296+ saffron.draw.transform(Ctx, matrix.scale(0.4, 0.4, 0.4), !IO),
297+
298+ % Upload the image to create a texture.
299+ saffron.gl.create_texture_from_bitmap(Ctx, BMP, TexW, TexH, Texture, !IO),
300+ Faces = cube_geometry,
301+
302+ % Upload geometry to buffers.
303+ % Most programs would probably want to use index buffers for a shape like
304+ % this with mostly shared geometry.
305+ list.map_foldl(
306+ saffron.geometry.create_buffer_list(Ctx),
307+ Faces, FaceBuffers,
308+ !IO),
309+
310+ % Construct the faces.
311+ % This *could* be done as one large, wound shape, but the majority of
312+ % programs will be loading meshes that will contain individual hulls/faces
313+ % that will need to be constructed in this way.
314+ list.map_foldl(
315+ saffron.geometry.create_shape2(Ctx, saffron.geometry.triangle_strip, Texture),
316+ FaceBuffers,
317+ Shapes,
318+ !IO),
319+
320+ % Construct the shape.
321+ saffron.draw.create_group_list(Ctx, Shapes, Group, !IO),
322+
323+ % Run the engine.
324+ run(Ctx, Win, Group, !IO),
325+
326+ % Cleanup
327+ saffron.destroy(Ctx, Group, !IO),
328+ list.foldl(saffron.destroy(Ctx), Shapes, !IO),
329+ list.foldl(saffron.destroy(Ctx), FaceBuffers, !IO),
330+ saffron.destroy(Ctx, Texture, !IO),
331+
332+ % The window and context will be garbage-collected?
333+ % I wrote the bindings years ago, I don't remember the intention :(
334+ saffron_glow.hide_window(Win, !IO).
318335
--- a/glow
+++ b/glow
@@ -1 +1 @@
1-Subproject commit 95e81a9a328299d5c8193ec1cd5180bc4e2a015d
1+Subproject commit e4dad582e2f58b9ae1e55247257c97c25a9f12bb
--- a/util/glow/saffron_glow.m
+++ b/util/glow/saffron_glow.m
@@ -21,6 +21,11 @@
2121
2222 %-----------------------------------------------------------------------------%
2323
24+:- inst io_res_uniq == unique(io.ok(unique) ; io.error(ground)).
25+:- mode io_res_uo == (free >> io_res_uniq).
26+
27+%-----------------------------------------------------------------------------%
28+
2429 :- type window.
2530
2631 %-----------------------------------------------------------------------------%
@@ -32,9 +37,9 @@
3237 :- pred viewport_size(int::in, int::in, int::uo, int::uo) is det.
3338
3439 %-----------------------------------------------------------------------------%
35-% create_window(Width, Height, Title, Win, !IO)
36-:- pred create_window(int, int, string, window, io.io, io.io).
37-:- mode create_window(in, in, in, uo, di, uo) is det.
40+% create_window(Width, Height, Title, WinRes, !IO)
41+:- pred create_window(int, int, string, io.res(window), io.io, io.io).
42+:- mode create_window(in, in, in, io_res_uo, di, uo) is det.
3843
3944 %-----------------------------------------------------------------------------%
4045
@@ -52,9 +57,9 @@
5257 :- mode get_window_event(in, uo, di, uo) is det.
5358
5459 %-----------------------------------------------------------------------------%
55-% create_context(Win, GLMajor, GLMinor, Ctx, !IO)
56-:- pred create_context(window, int, int, context, io.io, io.io).
57-:- mode create_context(in, in, in, uo, di, uo) is det.
60+% create_context(Win, GLMajor, GLMinor, CtxRes, !IO)
61+:- pred create_context(window, int, int, io.res(context), io.io, io.io).
62+:- mode create_context(in, in, in, io_res_uo, di, uo) is det.
5863
5964 %-----------------------------------------------------------------------------%
6065
@@ -197,13 +202,35 @@ SAFFRON_GLOW_SPECIAL_KEY_CASE_EX(GLOW_ ## NAME, SAFFRON_KEY_ ## NAME)
197202
198203 %-----------------------------------------------------------------------------%
199204
205+:- func create_window_ok(window::di) = (io.res(window)::uo) is det.
206+create_window_ok(Win) = io.ok(Win).
207+:- pragma foreign_export("C",
208+ create_window_ok(di) = (uo),
209+ "SaffronGlow_CreateWindowOK").
210+
211+%-----------------------------------------------------------------------------%
212+
213+:- func create_window_error = (io.res(window)::io_res_uo) is det.
214+create_window_error = io.error(io.make_io_error("Could not create Glow window")).
215+:- pragma foreign_export("C",
216+ create_window_error = (io_res_uo),
217+ "SaffronGlow_CreateWindowError").
218+
219+%-----------------------------------------------------------------------------%
220+
200221 :- pragma foreign_proc("C",
201- create_window(W::in, H::in, Title::in, Win::uo, IOi::di, IOo::uo),
222+ create_window(W::in, H::in, Title::in, WinRes::io_res_uo, IOi::di, IOo::uo),
202223 [promise_pure, will_not_call_mercury, will_not_throw_exception, thread_safe,
203224 tabled_for_io, may_duplicate],
204225 "
205- Win = MR_GC_malloc_atomic(Glow_WindowStructSize());
206- Glow_CreateWindow(Win, W, H, Title, 0);
226+ struct Glow_Window *win = MR_GC_malloc_atomic(Glow_WindowStructSize());
227+ if(Glow_CreateWindow(win, W, H, Title, 0) == 0){
228+ WinRes = SaffronGlow_CreateWindowOK(win);
229+ }
230+ else{
231+ MR_GC_free(win);
232+ WinRes = SaffronGlow_CreateWindowError();
233+ }
207234 IOo = IOi;
208235 ").
209236
@@ -326,13 +353,37 @@ SAFFRON_GLOW_SPECIAL_KEY_CASE_EX(GLOW_ ## NAME, SAFFRON_KEY_ ## NAME)
326353
327354 %-----------------------------------------------------------------------------%
328355
356+:- func create_context_ok(context::di) = (io.res(context)::uo) is det.
357+create_context_ok(Ctx) = io.ok(Ctx).
358+:- pragma foreign_export("C",
359+ create_context_ok(di) = (uo),
360+ "SaffronGlow_CreateContextOK").
361+
362+%-----------------------------------------------------------------------------%
363+
364+:- func create_context_error = (io.res(context)::io_res_uo) is det.
365+create_context_error = io.error(io.make_io_error("Could not create Glow context")).
366+:- pragma foreign_export("C",
367+ create_context_error = (io_res_uo),
368+ "SaffronGlow_CreateContextError").
369+
370+%-----------------------------------------------------------------------------%
371+
329372 :- pragma foreign_proc("C",
330- create_context(Win::in, Major::in, Minor::in, Ctx::uo, IOi::di, IOo::uo),
373+ create_context(Win::in, Major::in, Minor::in, CtxRes::io_res_uo, IOi::di, IOo::uo),
331374 [promise_pure, will_not_call_mercury, will_not_throw_exception, thread_safe,
332375 tabled_for_io, may_duplicate],
333376 "
334- Ctx = MR_GC_malloc_atomic(Glow_ContextStructSize());
335- Glow_CreateContext(Win, NULL, Major, Minor, Ctx);
377+ struct Glow_Context *ctx =
378+ MR_GC_malloc_atomic(Glow_ContextStructSize());
379+ if(Glow_CreateContext(Win, NULL, Major, Minor, ctx) == 0){
380+ CtxRes = SaffronGlow_CreateContextOK(ctx);
381+ }
382+ else{
383+ MR_GC_free(ctx);
384+ CtxRes = SaffronGlow_CreateContextError();
385+ }
386+
336387 IOo = IOi;
337388 ").
338389