• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

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

javac++androidlinuxc#windowsobjective-cqtcocoa誰得pythonphprubygameguibathyscaphec翻訳計画中(planning stage)omegatframeworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

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


コミットメタ情報

リビジョン8a215ba90197900dd702c858e19a9984ed357516 (tree)
日時2022-04-27 10:28:29
作者AlaskanEmily <emily@alas...>
コミッターAlaskanEmily

ログメッセージ

Generate OpenGL extension and post-1.1 bindings automatically

変更サマリ

差分

--- a/makefile
+++ b/makefile
@@ -11,6 +11,7 @@ PARALLEL_OPT=`if test ! -z '$(PARALLEL)' ; then echo ' -j $(PARALLEL)' ; fi`
1111 SAFFRON_MMC_OPTS=$(MMC_OPTS) $(GRADE_OPT) $(PARALLEL_OPT)
1212 SHARED_MMC_FLAGS=--linkage shared --lib-linkage shared
1313 STATIC_MMC_FLAGS=--linkage static --lib-linkage static
14+AWK?=awk
1415
1516 ALL=build_saffron
1617 all: $(ALL)
@@ -32,11 +33,20 @@ SAFFRON_TGA_LINK_FLAGS=--search-lib-files-dir "$$ROOT/util/tga" --init-file "$$R
3233 SAFFRON_GLOW_LINK_FLAGS=--search-lib-files-dir "$$ROOT/util/glow" --init-file "$$ROOT/util/glow/saffron_glow.init" $(GLOW_INCLUDE_FLAGS)
3334 SAFFRON_WINDOW_LINK_FLAGS=--search-lib-files-dir "$$ROOT/util/window" --init-file "$$ROOT/util/window/saffron_window.init"
3435
36+# Generated source.
37+saffron.gl.buffer.inc: saffron.gl_gen.awk saffron.gl.buffer.csv
38+ $(AWK) -F, -f saffron.gl_gen.awk < saffron.gl.buffer.csv > '$@'
39+ @touch saffron.gl.buffer.m # Force the Mercury compiler to rebuild this...
40+
41+saffron.gl.shader.inc: saffron.gl_gen.awk saffron.gl.shader.csv
42+ $(AWK) -F, -f saffron.gl_gen.awk < saffron.gl.shader.csv > '$@'
43+ @touch saffron.gl.shader.m # Force the Mercury compiler to rebuild this...
44+
3545 # Primary libraries.
3646 # Each is preceded by the shared object they create (if any, some like the TGA reader is only built static).
3747 # This is used to copy the shared objects to target directories.
3848 libsaffron.$(SO): build_saffron
39-build_saffron: build_mmath
49+build_saffron: build_mmath saffron.gl.buffer.inc saffron.gl.shader.inc
4050 ROOT=`pwd` && $(MMC) $(SAFFRON_MMC_OPTS) $(MMATH_LINK_FLAGS) --make libsaffron $(STATIC_MMC_FLAGS)
4151 ROOT=`pwd` && $(MMC) $(SAFFRON_MMC_OPTS) $(MMATH_LINK_FLAGS) --make libsaffron $(SHARED_MMC_FLAGS) -L "$$ROOT/mmath" -lmmath -lGL -lX11
4252 install libsaffron.$(SO) demo/
--- /dev/null
+++ b/saffron.gl.buffer.csv
@@ -0,0 +1,22 @@
1+func,GenBuffers,GLsizei,GLuint*
2+func,DeleteBuffers,GLsizei,const GLuint*
3+func,BindBuffer,GLenum,GLuint
4+func,BufferData,GLenum,SaffronGLsizeiptr,const void*,GLenum
5+func,MapBuffer,GLenum,GLenum,=void*
6+func,UnmapBuffer,GLenum,=GLboolean
7+
8+struct,Buffer,GenBuffers,DeleteBuffers,BindBuffer,BufferData,MapBuffer,UnmapBuffer
9+
10+load,Buffer,core 2.0,ext GL_ARB_vertex_buffer_object ARB
11+
12+const,GL_ARRAY_BUFFER,0x8892
13+const,GL_ELEMENT_ARRAY_BUFFER,0x8893
14+const,GL_STREAM_DRAW,0x88E0
15+const,GL_STREAM_READ,0x88E1
16+const,GL_STREAM_COPY,0x88E2
17+const,GL_STATIC_DRAW,0x88E4
18+const,GL_STATIC_READ,0x88E5
19+const,GL_STATIC_COPY,0x88E6
20+const,GL_DYNAMIC_DRAW,0x88E8
21+const,GL_DYNAMIC_READ,0x88E9
22+const,GL_DYNAMIC_COPY,0x88EA
--- /dev/null
+++ b/saffron.gl.buffer.inc
@@ -0,0 +1,124 @@
1+#ifndef SAFFRON_GL_FUNC_VAR
2+#define SAFFRON_GL_FUNC_VAR(X) SaffronGL_ ## X ## _PROC X;
3+#endif
4+#ifndef SAFFRON_GL_FUNC_LOAD
5+#define SAFFRON_GL_FUNC_LOAD(X, EXT) \
6+ SaffronGL_LoadFunction(gl_ctx, (char*)("gl" #X EXT), &maybe_func); \
7+ if(!Saffron_GetCtxFunctionOK(maybe_func, &func)) break; \
8+ (ctx->X) = (SaffronGL_ ## X ## _PROC)func;
9+
10+#define SAFFRON_GL_LOAD_FUNC_CORE(X) SAFFRON_GL_FUNC_LOAD(X, "")
11+#endif
12+
13+#ifndef SAFFRON_GL_IMPL
14+typedef void(APIENTRY*SaffronGL_GenBuffers_PROC)(
15+ GLsizei,
16+ GLuint*);
17+#endif
18+#ifndef SAFFRON_GL_IMPL
19+typedef void(APIENTRY*SaffronGL_DeleteBuffers_PROC)(
20+ GLsizei,
21+ const GLuint*);
22+#endif
23+#ifndef SAFFRON_GL_IMPL
24+typedef void(APIENTRY*SaffronGL_BindBuffer_PROC)(
25+ GLenum,
26+ GLuint);
27+#endif
28+#ifndef SAFFRON_GL_IMPL
29+typedef void(APIENTRY*SaffronGL_BufferData_PROC)(
30+ GLenum,
31+ SaffronGLsizeiptr,
32+ const void*,
33+ GLenum);
34+#endif
35+#ifndef SAFFRON_GL_IMPL
36+typedef void*(APIENTRY*SaffronGL_MapBuffer_PROC)(
37+ GLenum,
38+ GLenum);
39+#endif
40+#ifndef SAFFRON_GL_IMPL
41+typedef GLboolean(APIENTRY*SaffronGL_UnmapBuffer_PROC)(
42+ GLenum);
43+#endif
44+#ifndef SAFFRON_GL_IMPL
45+#define SAFFRON_GL_BUFFER_FUNCS(X) \
46+ X(GenBuffers) \
47+ X(DeleteBuffers) \
48+ X(BindBuffer) \
49+ X(BufferData) \
50+ X(MapBuffer) \
51+ X(UnmapBuffer) \
52+/* */
53+struct SaffronGL_BufferCtx{
54+ SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_FUNC_VAR)
55+};
56+#endif
57+#ifndef SAFFRON_GL_IMPL
58+#ifdef SAFFRON_GL_EXPECT_BUFFER
59+#define SAFFRON_GL_BUFFER_FUNC(CTX, X) (gl ## X)
60+#define SAFFRON_GL_BUFFER_CTX MR_Word
61+#define SAFFRON_GL_ALLOC_BUFFER_CTX() 0
62+#define SAFFRON_GL_LOAD_BUFFER_CTX(GLCTX, CTX) (*(CTX) = 0)
63+#else
64+#define SAFFRON_GL_BUFFER_FUNC(CTX, X) ((CTX)->X)
65+#define SAFFRON_GL_BUFFER_CTX struct SaffronGL_BufferCtx
66+int SaffronGL_LoadBufferCtx(MR_Word gl_ctx, struct SaffronGL_BufferCtx **ctx_ptr);
67+#define SAFFRON_GL_LOAD_BUFFER_CTX SaffronGL_LoadBufferCtx
68+#endif
69+#else
70+#ifndef SAFFRON_GL_EXPECT_BUFFER
71+int SaffronGL_LoadBufferCtx(MR_Word gl_ctx, struct SaffronGL_BufferCtx **ctx_ptr){
72+ struct SaffronGL_BufferCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_BufferCtx));
73+ MR_Word maybe_func, func;
74+ MR_String err = NULL;
75+ MR_Integer major, minor;
76+ SaffronGL_Version(gl_ctx, &major, &minor);
77+ if(major > 2 || (major == 2 && minor >= 0)) do{
78+ SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_LOAD_FUNC_CORE)
79+ *ctx_ptr = ctx;
80+ return 0;
81+ }while(0);
82+#define SAFFRON_GL_LOAD_FUNC_BUFFER_ARB(X) SAFFRON_GL_FUNC_LOAD(X, "ARB")
83+ if(SaffronGL_SupportsExtension("GL_ARB_vertex_buffer_object")) do{
84+ SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_LOAD_FUNC_BUFFER_ARB)
85+ *ctx_ptr = ctx;
86+ return 0;
87+ }while(0);
88+ return 1;
89+}
90+#endif
91+#endif
92+#ifndef GL_ARRAY_BUFFER
93+#define GL_ARRAY_BUFFER 0x8892
94+#endif
95+#ifndef GL_ELEMENT_ARRAY_BUFFER
96+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
97+#endif
98+#ifndef GL_STREAM_DRAW
99+#define GL_STREAM_DRAW 0x88E0
100+#endif
101+#ifndef GL_STREAM_READ
102+#define GL_STREAM_READ 0x88E1
103+#endif
104+#ifndef GL_STREAM_COPY
105+#define GL_STREAM_COPY 0x88E2
106+#endif
107+#ifndef GL_STATIC_DRAW
108+#define GL_STATIC_DRAW 0x88E4
109+#endif
110+#ifndef GL_STATIC_READ
111+#define GL_STATIC_READ 0x88E5
112+#endif
113+#ifndef GL_STATIC_COPY
114+#define GL_STATIC_COPY 0x88E6
115+#endif
116+#ifndef GL_DYNAMIC_DRAW
117+#define GL_DYNAMIC_DRAW 0x88E8
118+#endif
119+#ifndef GL_DYNAMIC_READ
120+#define GL_DYNAMIC_READ 0x88E9
121+#endif
122+#ifndef GL_DYNAMIC_COPY
123+#define GL_DYNAMIC_COPY 0x88EA
124+#endif
--- a/saffron.gl.buffer.m
+++ b/saffron.gl.buffer.m
@@ -110,112 +110,19 @@
110110 :- pragma foreign_import_module("C", saffron.gl).
111111 :- pragma foreign_import_module("C", saffron.geometry).
112112
113+%-----------------------------------------------------------------------------%
113114 % Define the native prototypes to handle buffers.
114115 :- pragma foreign_decl("C", "
116+#include ""saffron.gl.buffer.inc""
117+ ").
115118
116-#define SAFFRON_GL_BUFFER_FUNCS(X) \\
117- X(GenBuffers) \\
118- X(DeleteBuffers) \\
119- X(BindBuffer) \\
120- X(BufferData) \\
121- X(MapBuffer) \\
122- X(UnmapBuffer)
123-
124-typedef void(APIENTRY*SaffronGL_GenBuffers_PROC)(GLsizei, GLuint*);
125-
126-typedef void(APIENTRY*SaffronGL_DeleteBuffers_PROC)(GLsizei, const GLuint*);
127-
128-typedef void(APIENTRY*SaffronGL_BindBuffer_PROC)(GLenum, GLuint);
129-
130-typedef void(APIENTRY*SaffronGL_BufferData_PROC)(
131- GLenum,
132- SaffronGLsizeiptr,
133- const void *,
134- GLenum);
135-
136-typedef void*(APIENTRY*SaffronGL_MapBuffer_PROC)(GLenum, GLenum);
137-
138-typedef void(*APIENTRY*SaffronGL_UnmapBuffer_PROC)(GLenum);
139-
140-#ifdef SAFFRON_GL_EXPECT_BUFFERS
141-
142-/* TODO: Maybe we should be caching some info here? */
143-# define SAFFRON_GL_BUFFER_CTX MR_Word
144-# define SAFFRON_GL_BUFFER_FUNC(CTX, FN) gl ## FN
145-
146-#else
147-
148-# define SAFFRON_GL_BUFFER_FUNC_VAR(X) \\
149- SaffronGL_ ## X ## _PROC X;
150-
151-struct SaffronGL_BufferCtx{
152- SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_BUFFER_FUNC_VAR)
153-};
154-
155-# undef SAFFRON_GL_BUFFER_FUNC_VAR
156-
157-# define SAFFRON_GL_BUFFER_CTX struct SaffronGL_BufferCtx*
158-# define SAFFRON_GL_BUFFER_FUNC(CTX, FN) ((CTX)->FN)
159-
160-#endif
161-
162-#ifndef GL_ARRAY_BUFFER
163-# define GL_ARRAY_BUFFER 0x8892
164-#endif
165-
166-#ifndef GL_ELEMENT_ARRAY_BUFFER
167-# define GL_ELEMENT_ARRAY_BUFFER 0x8893
168-#endif
169-
170-#ifndef GL_STREAM_DRAW
171-# define GL_STREAM_DRAW 0x88E0
172-#endif
173-
174-#ifndef GL_STREAM_READ
175-# define GL_STREAM_READ 0x88E1
176-#endif
177-
178-#ifndef GL_STREAM_COPY
179-# define GL_STREAM_COPY 0x88E2
180-#endif
181-
182-#ifndef GL_STATIC_DRAW
183-# define GL_STATIC_DRAW 0x88E4
184-#endif
185-
186-#ifndef GL_STATIC_READ
187-# define GL_STATIC_READ 0x88E5
188-#endif
189-
190-#ifndef GL_STATIC_COPY
191-# define GL_STATIC_COPY 0x88E6
192-#endif
193-
194-#ifndef GL_DYNAMIC_DRAW
195-# define GL_DYNAMIC_DRAW 0x88E8
196-#endif
197-
198-#ifndef GL_DYNAMIC_READ
199-# define GL_DYNAMIC_READ 0x88E9
200-#endif
201-
202-#ifndef GL_DYNAMIC_COPY
203-# define GL_DYNAMIC_COPY 0x88EA
204-#endif
205-
206-#ifndef GL_READ_ONLY
207-# define GL_READ_ONLY 0x88B8
208-#endif
209-
210-#ifndef GL_WRITE_ONLY
211-# define GL_WRITE_ONLY 0x88B9
212-#endif
213-
214-#ifndef GL_READ_WRITE
215-# define GL_READ_WRITE 0x88BA
216-#endif
119+%-----------------------------------------------------------------------------%
217120
218-").
121+:- pragma foreign_code("C", "
122+#define SAFFRON_GL_IMPL
123+#include ""saffron.gl.buffer.inc""
124+#undef SAFFRON_GL_IMPL
125+ ").
219126
220127 %-----------------------------------------------------------------------------%
221128
@@ -252,89 +159,25 @@ create_buffer_ctx_error(E) = maybe.error(E).
252159
253160 :- pred create_buffer_ctx_internal(
254161 gl_load_func_ctx,
255- bool.bool,
256162 maybe.maybe_error(buffer_ctx),
257163 io.io, io.io).
258164 :- mode create_buffer_ctx_internal(
259165 in,
260- in,
261166 out,
262167 di, uo) is det.
263168
264169 :- pragma foreign_proc("C",
265- create_buffer_ctx_internal(Ctx::in, Old::in, MaybeBufferCtx::out, IOi::di, IOo::uo),
170+ create_buffer_ctx_internal(Ctx::in, MaybeBufferCtx::out, IOi::di, IOo::uo),
266171 [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception],
267172 "
268-
269-#ifndef SAFFRON_GL_EXPECT_BUFFERS
270- MR_Bool New = !Old;
271-
272- MR_Word maybe_func, func;
273- MR_String err = NULL;
274- struct SaffronGL_BufferCtx *buffer_ctx;
275- buffer_ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_BufferCtx));
276-
277-#ifdef _WIN32
278- Old = MR_TRUE;
279-#endif
280-
281-# define SAFFRON_GL_BUFFER_FUNC_LOAD(ERR, X, NAME) { \\
282- SaffronGL_LoadFunction(Ctx, (char*)(NAME), &maybe_func); \\
283- err = NULL; \\
284- if(Saffron_GetCtxFunctionOK(maybe_func, &func)) \\
285- buffer_ctx->X = (SaffronGL_ ## X ## _PROC)func; \\
286- else if(Saffron_GetCtxFunctionError(maybe_func, &err)) \\
287- goto ERR; \\
288- else \\
289- MR_assert(0); \\
290-}
291-
292-# define SAFFRON_GL_BUFFER_FUNC_LOAD_ARB(X) \\
293- SAFFRON_GL_BUFFER_FUNC_LOAD( \\
294- saffron_gl_create_buffer_ctx_internal_no_arb, \\
295- X, \\
296- ""gl"" #X ""ARB"")
297-
298-# define SAFFRON_GL_BUFFER_FUNC_LOAD_NEW(X) \\
299- SAFFRON_GL_BUFFER_FUNC_LOAD( \\
300- saffron_gl_create_buffer_ctx_internal, \\
301- X, \\
302- ""gl"" #X)
303-
304- /* For OpenGL versions before 2.1, only use the ARB version. */
305- if(Old){
306- /* Yes, this is slightly incorrect... */
307- if(strstr(
308- (char*)glGetString(GL_EXTENSIONS),
309- ""GL_ARB_vertex_buffer_object"") != NULL){
310-
311- SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_BUFFER_FUNC_LOAD_ARB)
312-
313- /* If we made it this far, just go to the end. */
314- goto saffron_gl_create_buffer_ctx_internal;
315- }
316- }
317-saffron_gl_create_buffer_ctx_internal_no_arb:
318- if(New){
319- SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_BUFFER_FUNC_LOAD_NEW)
320- }
321-saffron_gl_create_buffer_ctx_internal:
322-
323-#undef SAFFRON_GL_BUFFER_FUNC_LOAD_NEW
324-#undef SAFFRON_GL_BUFFER_FUNC_LOAD_ARB
325-#undef SAFFRON_GL_BUFFER_FUNC_LOAD
326-
327- if(err == NULL){
328- MaybeBufferCtx = SaffronGL_CreateBufferCtxOK(buffer_ctx);
173+ SAFFRON_GL_BUFFER_CTX ctx;
174+ if(SAFFRON_GL_LOAD_BUFFER_CTX(Ctx, &ctx) == 0){
175+ MaybeBufferCtx = SaffronGL_CreateBufferCtxOK(ctx);
329176 }
330177 else{
331- MR_GC_free(buffer_ctx);
332- MaybeBufferCtx = SaffronGL_CreateBufferCtxError(err);
178+ MaybeBufferCtx = SaffronGL_CreateBufferCtxError(
179+ (MR_String)""Could not create context"");
333180 }
334-#else
335- MaybeBufferCtx = SaffronGL_CreateBufferCtxOK(0);
336-#endif
337-
338181 IOo = IOi;
339182 ").
340183
@@ -342,27 +185,8 @@ saffron_gl_create_buffer_ctx_internal:
342185
343186 create_buffer_ctx(Ctx, MaybeBufferCtx, !IO) :-
344187 saffron.make_current(Ctx, !IO),
345- saffron.gl.opengl_version(Ctx, MaybeSemVer, !IO),
346- (
347- MaybeSemVer = maybe.ok(SemVer),
348- ( if
349- saffron.sem_ver_compare((<), SemVer, saffron.sem_ver(2, 1))
350- then
351- Old = bool.yes
352- else
353- Old = bool.no
354- )
355- ;
356- MaybeSemVer = maybe.error(Err),
357- trace [io(!XIO)] (
358- io.write_string("Error reading OpenGL version: ", !XIO),
359- io.write_string(Err, !XIO),
360- io.nl(!XIO)
361- ),
362- Old = bool.yes
363- ),
364188 LoadFuncCtx = 'new gl_load_func_ctx'(Ctx),
365- create_buffer_ctx_internal(LoadFuncCtx, Old, MaybeBufferCtx, !IO).
189+ create_buffer_ctx_internal(LoadFuncCtx, MaybeBufferCtx, !IO).
366190
367191 %-----------------------------------------------------------------------------%
368192
--- a/saffron.gl.m
+++ b/saffron.gl.m
@@ -129,16 +129,20 @@ typedef char SaffronGLchar;
129129 *
130130 * See: http://support.apple.com/kb/TA22513
131131 */
132-# define SAFFRON_GL_EXPECT_BUFFERS
132+# define SAFFRON_GL_EXPECT_BUFFER
133133 # define GL_GLEXT_PROTOTYPES
134134 # include <OpenGL/gl.h>
135135 # include <OpenGL/glext.h>
136136
137+# ifndef APIENTRY
138+# define APIENTRY
139+# endif
140+
137141 #else
138142
139143 # if (defined __linux__) || (defined __OpenBSD__) || (defined __FreeBSD__)
140-# define SAFFRON_GL_EXPECT_BUFFERS
141-# define SAFFRON_GL_EXPECT_SHADERS
144+# define SAFFRON_GL_EXPECT_BUFFER
145+# define SAFFRON_GL_EXPECT_SHADER
142146 # define GL_GLEXT_PROTOTYPES
143147 # endif
144148
@@ -165,16 +169,6 @@ typedef void(APIENTRY*SaffronGL_DrawTextureNV_PROC)(
165169 GLfloat,
166170 GLfloat);
167171
168-struct SaffronGL_DrawTextureNV_ext{
169- SaffronGL_DrawTextureNV_PROC draw_texture_nv;
170-};
171-
172-# define SAFFRON_GL_DRAW_TEXTURE_NV_EXT ""GL_NV_draw_texture""
173-
174-# define SAFFRON_GL_DRAW_TEXTURE_NV_INIT(TO, LOAD) do{ \\
175- (TO)->draw_texture_nv = (LOAD(""glDrawTextureNV"")); \\
176-}while(0)
177-
178172 #ifndef GL_SHADING_LANGUAGE_VERSION
179173 # define GL_SHADING_LANGUAGE_VERSION 0x8B8C
180174 #endif
--- /dev/null
+++ b/saffron.gl.shader.csv
@@ -0,0 +1,26 @@
1+func,CreateShader,GLenum,=GLuint
2+func,DeleteShader,GLuint
3+func,ShaderSource,GLuint,GLsizei,const SaffronGLchar**,const GLint
4+func,CompileShader,GLuint
5+func,GetShaderiv,GLuint,GLenum,GLint*
6+func,GetShaderInfoLog,GLuint,GLsizei,GLsizei*,SaffronGLchar*
7+func,CreateProgram,void,=GLuint
8+func,DeleteProgram,GLuint
9+func,LinkProgram,GLuint
10+func,AttachShader,GLuint,GLuint
11+func,UseProgram,GLuint
12+func,GetProgramiv,GLuint,GLenum,GLint*
13+
14+struct,Shader,CreateShader,DeleteShader,ShaderSource,CompileShader,GetShaderiv,GetShaderInfoLog,CreateProgram,DeleteProgram,LinkProgram,AttachShader,UseProgram,GetProgramiv
15+
16+load,Shader,core 2.0
17+
18+const,GL_SHADING_LANGUAGE_VERSION,0x8B8C
19+const,GL_VERTEX_SHADER,0x8B31
20+const,GL_FRAGMENT_SHADER,0x8B30
21+const,GL_GEOMETRY_SHADER,0x8DD9
22+const,GL_COMPILE_STATUS,0x8B81
23+const,GL_LINK_STATUS,0x8B82
24+const,GL_VALIDATE_STATUS,0x8B83
25+const,GL_INFO_LOG_LENGTH,0x8B84
26+
--- /dev/null
+++ b/saffron.gl.shader.inc
@@ -0,0 +1,143 @@
1+#ifndef SAFFRON_GL_FUNC_VAR
2+#define SAFFRON_GL_FUNC_VAR(X) SaffronGL_ ## X ## _PROC X;
3+#endif
4+#ifndef SAFFRON_GL_FUNC_LOAD
5+#define SAFFRON_GL_FUNC_LOAD(X, EXT) \
6+ SaffronGL_LoadFunction(gl_ctx, (char*)("gl" #X EXT), &maybe_func); \
7+ if(!Saffron_GetCtxFunctionOK(maybe_func, &func)) break; \
8+ (ctx->X) = (SaffronGL_ ## X ## _PROC)func;
9+
10+#define SAFFRON_GL_LOAD_FUNC_CORE(X) SAFFRON_GL_FUNC_LOAD(X, "")
11+#endif
12+
13+#ifndef SAFFRON_GL_IMPL
14+typedef GLuint(APIENTRY*SaffronGL_CreateShader_PROC)(
15+ GLenum);
16+#endif
17+#ifndef SAFFRON_GL_IMPL
18+typedef void(APIENTRY*SaffronGL_DeleteShader_PROC)(
19+ GLuint);
20+#endif
21+#ifndef SAFFRON_GL_IMPL
22+typedef void(APIENTRY*SaffronGL_ShaderSource_PROC)(
23+ GLuint,
24+ GLsizei,
25+ const SaffronGLchar**,
26+ const GLint);
27+#endif
28+#ifndef SAFFRON_GL_IMPL
29+typedef void(APIENTRY*SaffronGL_CompileShader_PROC)(
30+ GLuint);
31+#endif
32+#ifndef SAFFRON_GL_IMPL
33+typedef void(APIENTRY*SaffronGL_GetShaderiv_PROC)(
34+ GLuint,
35+ GLenum,
36+ GLint*);
37+#endif
38+#ifndef SAFFRON_GL_IMPL
39+typedef void(APIENTRY*SaffronGL_GetShaderInfoLog_PROC)(
40+ GLuint,
41+ GLsizei,
42+ GLsizei*,
43+ SaffronGLchar*);
44+#endif
45+#ifndef SAFFRON_GL_IMPL
46+typedef GLuint(APIENTRY*SaffronGL_CreateProgram_PROC)(
47+ void);
48+#endif
49+#ifndef SAFFRON_GL_IMPL
50+typedef void(APIENTRY*SaffronGL_DeleteProgram_PROC)(
51+ GLuint);
52+#endif
53+#ifndef SAFFRON_GL_IMPL
54+typedef void(APIENTRY*SaffronGL_LinkProgram_PROC)(
55+ GLuint);
56+#endif
57+#ifndef SAFFRON_GL_IMPL
58+typedef void(APIENTRY*SaffronGL_AttachShader_PROC)(
59+ GLuint,
60+ GLuint);
61+#endif
62+#ifndef SAFFRON_GL_IMPL
63+typedef void(APIENTRY*SaffronGL_UseProgram_PROC)(
64+ GLuint);
65+#endif
66+#ifndef SAFFRON_GL_IMPL
67+typedef void(APIENTRY*SaffronGL_GetProgramiv_PROC)(
68+ GLuint,
69+ GLenum,
70+ GLint*);
71+#endif
72+#ifndef SAFFRON_GL_IMPL
73+#define SAFFRON_GL_SHADER_FUNCS(X) \
74+ X(CreateShader) \
75+ X(DeleteShader) \
76+ X(ShaderSource) \
77+ X(CompileShader) \
78+ X(GetShaderiv) \
79+ X(GetShaderInfoLog) \
80+ X(CreateProgram) \
81+ X(DeleteProgram) \
82+ X(LinkProgram) \
83+ X(AttachShader) \
84+ X(UseProgram) \
85+ X(GetProgramiv) \
86+/* */
87+struct SaffronGL_ShaderCtx{
88+ SAFFRON_GL_SHADER_FUNCS(SAFFRON_GL_FUNC_VAR)
89+};
90+#endif
91+#ifndef SAFFRON_GL_IMPL
92+#ifdef SAFFRON_GL_EXPECT_SHADER
93+#define SAFFRON_GL_SHADER_FUNC(CTX, X) (gl ## X)
94+#define SAFFRON_GL_SHADER_CTX MR_Word
95+#define SAFFRON_GL_ALLOC_SHADER_CTX() 0
96+#define SAFFRON_GL_LOAD_SHADER_CTX(GLCTX, CTX) (*(CTX) = 0)
97+#else
98+#define SAFFRON_GL_SHADER_FUNC(CTX, X) ((CTX)->X)
99+#define SAFFRON_GL_SHADER_CTX struct SaffronGL_ShaderCtx
100+int SaffronGL_LoadShaderCtx(MR_Word gl_ctx, struct SaffronGL_ShaderCtx **ctx_ptr);
101+#define SAFFRON_GL_LOAD_SHADER_CTX SaffronGL_LoadShaderCtx
102+#endif
103+#else
104+#ifndef SAFFRON_GL_EXPECT_SHADER
105+int SaffronGL_LoadShaderCtx(MR_Word gl_ctx, struct SaffronGL_ShaderCtx **ctx_ptr){
106+ struct SaffronGL_ShaderCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_ShaderCtx));
107+ MR_Word maybe_func, func;
108+ MR_String err = NULL;
109+ MR_Integer major, minor;
110+ SaffronGL_Version(gl_ctx, &major, &minor);
111+ if(major > 2 || (major == 2 && minor >= 0)) do{
112+ SAFFRON_GL_SHADER_FUNCS(SAFFRON_GL_LOAD_FUNC_CORE)
113+ *ctx_ptr = ctx;
114+ return 0;
115+ }while(0);
116+ return 1;
117+}
118+#endif
119+#endif
120+#ifndef GL_SHADING_LANGUAGE_VERSION
121+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
122+#endif
123+#ifndef GL_VERTEX_SHADER
124+#define GL_VERTEX_SHADER 0x8B31
125+#endif
126+#ifndef GL_FRAGMENT_SHADER
127+#define GL_FRAGMENT_SHADER 0x8B30
128+#endif
129+#ifndef GL_GEOMETRY_SHADER
130+#define GL_GEOMETRY_SHADER 0x8DD9
131+#endif
132+#ifndef GL_COMPILE_STATUS
133+#define GL_COMPILE_STATUS 0x8B81
134+#endif
135+#ifndef GL_LINK_STATUS
136+#define GL_LINK_STATUS 0x8B82
137+#endif
138+#ifndef GL_VALIDATE_STATUS
139+#define GL_VALIDATE_STATUS 0x8B83
140+#endif
141+#ifndef GL_INFO_LOG_LENGTH
142+#define GL_INFO_LOG_LENGTH 0x8B84
143+#endif
--- a/saffron.gl.shader.m
+++ b/saffron.gl.shader.m
@@ -82,115 +82,13 @@
8282
8383 % Define the native prototypes to handle shaders.
8484 :- pragma foreign_decl("C", "
85+#include ""saffron.gl.shader.inc""
86+").
8587
86-#define SAFFRON_GL_SHADER_FUNCS(X) \\
87- X(CreateShader) \\
88- X(DeleteShader) \\
89- X(ShaderSource) \\
90- X(CompileShader) \\
91- X(GetShaderiv) \\
92- X(GetShaderInfoLog) \\
93- X(CreateProgram) \\
94- X(DeleteProgram) \\
95- X(AttachShader) \\
96- X(LinkProgram) \\
97- X(UseProgram) \\
98- X(GetProgramiv)
99-
100-/* Shader function types */
101-typedef GLuint(APIENTRY*SaffronGL_CreateShader_PROC)(GLenum);
102-
103-typedef void(APIENTRY*SaffronGL_DeleteShader_PROC)(GLuint);
104-
105-typedef void(APIENTRY*SaffronGL_ShaderSource_PROC)(
106- GLuint,
107- GLsizei,
108- const SaffronGLchar**,
109- const GLint*);
110-
111-typedef void(APIENTRY*SaffronGL_CompileShader_PROC)(GLuint);
112-
113-typedef void(APIENTRY*SaffronGL_GetShaderiv_PROC)(GLuint, GLenum, GLint*);
114-
115-typedef void(APIENTRY*SaffronGL_GetShaderInfoLog_PROC)(
116- GLuint,
117- GLsizei,
118- GLsizei*,
119- SaffronGLchar*);
120-
121-typedef GLuint(APIENTRY*SaffronGL_CreateProgram_PROC)(void);
122-
123-typedef void(APIENTRY*SaffronGL_DeleteProgram_PROC)(GLuint);
124-
125-typedef void(APIENTRY*SaffronGL_LinkProgram_PROC)(GLuint);
126-
127-typedef void(APIENTRY*SaffronGL_AttachShader_PROC)(GLuint, GLuint);
128-
129-typedef void(APIENTRY*SaffronGL_UseProgram_PROC)(GLuint);
130-
131-typedef void(APIENTRY*SaffronGL_GetProgramiv_PROC)(GLuint, GLenum, GLint*);
132-
133-#ifdef SAFFRON_GL_EXPECT_SHADERS
134-
135-/* TODO: Maybe we should be caching some info here? */
136-# define SAFFRON_GL_SHADER_CTX MR_Word
137-# define SAFFRON_GL_SHADER_FUNC(CTX, FN) gl ## FN
138-
139-#else
140-
141-# define SAFFRON_GL_SHADER_FUNC_VAR(X) \\
142- SaffronGL_ ## X ## _PROC X;
143-
144-struct SaffronGL_ShaderCtx{
145- SAFFRON_GL_SHADER_FUNCS(SAFFRON_GL_SHADER_FUNC_VAR)
146-};
147-
148-# undef SAFFRON_GL_SHADER_FUNC_VAR
149-
150-# define SAFFRON_GL_SHADER_CTX struct SaffronGL_ShaderCtx*
151-# define SAFFRON_GL_SHADER_FUNC(CTX, FN) ((CTX)->FN)
152-
153-#endif
154-
155-/* OpenGL constants for use with shaders */
156-#ifndef GL_SHADING_LANGUAGE_VERSION
157-# define GL_SHADING_LANGUAGE_VERSION 0x8B8C
158-#endif
159-
160-#ifndef GL_VERTEX_SHADER
161-# define GL_VERTEX_SHADER 0x8B31
162-#endif
163-
164-#ifndef GL_FRAGMENT_SHADER
165-# define GL_FRAGMENT_SHADER 0x8B30
166-#endif
167-
168-#ifndef GL_GEOMETRY_SHADER
169-# define GL_GEOMETRY_SHADER 0x8DD9
170-#endif
171-
172-#ifndef GL_COMPILE_STATUS
173-# define GL_COMPILE_STATUS 0x8B81
174-#endif
175-
176-#ifndef GL_LINK_STATUS
177-# define GL_LINK_STATUS 0x8B82
178-#endif
179-
180-#ifndef GL_VALIDATE_STATUS
181-# define GL_VALIDATE_STATUS 0x8B83
182-#endif
183-
184-#ifndef GL_INFO_LOG_LENGTH
185-# define GL_INFO_LOG_LENGTH 0x8B84
186-#endif
187-
188-#ifdef MR_USE_SINGLE_PREC_FLOAT
189-# define SAFFRON_GL_FLOAT_FUNC(NAME) NAME ## f
190-#else
191-# define SAFFRON_GL_FLOAT_FUNC(NAME) NAME ## d
192-#endif
193-
88+:- pragma foreign_decl("C", "
89+#define SAFFRON_GL_IMPL
90+#include ""saffron.gl.shader.inc""
91+#undef SAFFRON_GL_IMPL
19492 ").
19593
19694 %-----------------------------------------------------------------------------%
@@ -244,38 +142,14 @@ create_shader_ctx_error(E) = maybe.error(E).
244142 create_shader_ctx_internal(Ctx::in, MaybeShaderCtx::out, IOi::di, IOo::uo),
245143 [may_call_mercury, promise_pure, thread_safe, will_not_throw_exception],
246144 "
247-#ifndef SAFFRON_GL_EXPECT_SHADERS
248- MR_Word maybe_func, func;
249- MR_String err = NULL;
250- struct SaffronGL_ShaderCtx *shader_ctx;
251- shader_ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_ShaderCtx));
252-
253-# define SAFFRON_GL_SHADER_FUNC_LOAD(X) { \\
254- SaffronGL_LoadFunction(Ctx, (char*)(""gl"" #X), &maybe_func); \\
255- err = NULL; \\
256- if(Saffron_GetCtxFunctionOK(maybe_func, &func)) \\
257- shader_ctx->X = (SaffronGL_ ## X ## _PROC)func; \\
258- else if(Saffron_GetCtxFunctionError(maybe_func, &err)) \\
259- goto create_shader_ctx_internal_error; \\
260- else \\
261- MR_assert(0); \\
262-}
263-
264- SAFFRON_GL_SHADER_FUNCS(SAFFRON_GL_SHADER_FUNC_LOAD)
265-
266-# undef SAFFRON_GL_SHADER_FUNC_LOAD
267-
268-create_shader_ctx_internal_error:
269- if(err == NULL){
270- MaybeShaderCtx = SaffronGL_CreateShaderCtxOK(shader_ctx);
145+ SAFFRON_GL_SHADER_CTX ctx;
146+ if(SAFFRON_GL_LOAD_SHADER_CTX(Ctx, &ctx) == 0){
147+ MaybeShaderCtx = SaffronGL_CreateShaderCtxOK(ctx);
271148 }
272149 else{
273- MR_GC_free(shader_ctx);
274- MaybeShaderCtx = SaffronGL_CreateShaderCtxError(err);
150+ MaybeShaderCtx = SaffronGL_CreateShaderCtxError(
151+ (MR_String)""Could not create context"");
275152 }
276-#else
277- MaybeShaderCtx = SaffronGL_CreateShaderCtxOK(0);
278-#endif
279153 IOo = IOi;
280154 ").
281155
--- /dev/null
+++ b/saffron.gl_gen.awk
@@ -0,0 +1,146 @@
1+BEGIN{
2+ print("\
3+#ifndef SAFFRON_GL_FUNC_VAR\n\
4+#define SAFFRON_GL_FUNC_VAR(X) SaffronGL_ ## X ## _PROC X;\n\
5+#endif\n\
6+#ifndef SAFFRON_GL_FUNC_LOAD\n\
7+#define SAFFRON_GL_FUNC_LOAD(X, EXT) \\\n\
8+ SaffronGL_LoadFunction(gl_ctx, (char*)(\"gl\" #X EXT), &maybe_func); \\\n\
9+ if(!Saffron_GetCtxFunctionOK(maybe_func, &func)) break; \\\n\
10+ (ctx->X) = (SaffronGL_ ## X ## _PROC)func; \n\
11+\n\
12+#define SAFFRON_GL_LOAD_FUNC_CORE(X) SAFFRON_GL_FUNC_LOAD(X, \"\")\n\
13+#endif\n\
14+");
15+
16+}
17+
18+$1 == "const" {
19+ print("\
20+#ifndef " $2 "\n\
21+#define " $2 " " $3 "\n\
22+#endif");
23+ next;
24+}
25+
26+$1 !~ /#/ && $0 != "" {
27+ print("#ifndef SAFFRON_GL_IMPL");
28+ upper2 = toupper($2);
29+}
30+
31+$1 == "struct" || $1 == "load"{
32+ struct = "struct SaffronGL_" $2 "Ctx";
33+}
34+
35+$1 == "func" {
36+ if($NF ~ /^=/){
37+ last = NF - 1;
38+ ret = substr($NF, 2);
39+ }
40+ else{
41+ last = NF;
42+ ret = "void";
43+ }
44+ sig = "typedef " ret "(APIENTRY*SaffronGL_" $2 "_PROC)(";
45+ if(last < 3){
46+ print(sig "void);");
47+ }
48+ else{
49+ print(sig);
50+ for(i = 3; i < last; i++)
51+ print(" " $i ",");
52+ print(" " $last ");");
53+ }
54+}
55+
56+$1 == "struct" {
57+ print("#define SAFFRON_GL_" upper2 "_FUNCS(X) \\");
58+ for(i = 3; i <= NF; i++){
59+ print(" X(" $i ") \\");
60+ }
61+ print("/* */");
62+ print(struct "{");
63+ print(" SAFFRON_GL_" upper2 "_FUNCS(SAFFRON_GL_FUNC_VAR)");
64+ print("};");
65+}
66+
67+$1 == "load" {
68+ # Check for "core" spec, and if we find it we should generate an 'expect'
69+ # C preprocessor check to avoid unnecessary indirection.
70+ core = 0;
71+ for(i = 3; i <= NF; i++){
72+ if($i ~ /^core [0-9]\.[0-9]$/){
73+ core = i;
74+ break;
75+ }
76+ }
77+ if(core != 0){
78+ print("\
79+#ifdef SAFFRON_GL_EXPECT_" upper2 "\n\
80+#define SAFFRON_GL_" upper2 "_FUNC(CTX, X) (gl ## X)\n\
81+#define SAFFRON_GL_" upper2 "_CTX MR_Word\n\
82+#define SAFFRON_GL_ALLOC_" upper2 "_CTX() 0\n\
83+#define SAFFRON_GL_LOAD_" upper2 "_CTX(GLCTX, CTX) (*(CTX) = 0)\n\
84+#else");
85+ }
86+ # Write the default, loader implementation.
87+ sig = "int SaffronGL_Load" $2 "Ctx(MR_Word gl_ctx, " struct " **ctx_ptr)";
88+ print("\
89+#define SAFFRON_GL_" upper2 "_FUNC(CTX, X) ((CTX)->X)\n\
90+#define SAFFRON_GL_" upper2 "_CTX " struct "\n\
91+" sig ";\n\
92+#define SAFFRON_GL_LOAD_" upper2 "_CTX SaffronGL_Load" $2 "Ctx");
93+ if(core != ""){
94+ print("#endif");
95+ }
96+
97+ # Write the impl (we are in an #ifdef for the interface)
98+ print("#else");
99+ print("#ifndef SAFFRON_GL_EXPECT_" upper2);
100+
101+ # Write the loader function
102+ print(sig "{\n\
103+ " struct " *ctx = MR_GC_malloc_atomic(sizeof(" struct "));\n\
104+ MR_Word maybe_func, func;\n\
105+ MR_String err = NULL;");
106+ if(core != 0){
107+ print("\
108+ MR_Integer major, minor;\n\
109+ SaffronGL_Version(gl_ctx, &major, &minor);");
110+ }
111+ for(i = 3; i <= NF; i++){
112+ # Core has special handling.
113+ if($i ~ /^core [0-9]\.[0-9]$/){
114+ major = substr($i, 6, 1);
115+ minor = substr($i, 8, 1);
116+ print("\
117+ if(major > " major " || (major == " major " && minor >= " minor ")) do{\n\
118+ SAFFRON_GL_" upper2 "_FUNCS(SAFFRON_GL_LOAD_FUNC_CORE)\n\
119+ *ctx_ptr = ctx;\n\
120+ return 0;\n\
121+ }while(0);");
122+ }
123+ else if($i ~ /^ext GL_[A-Za-z0-9_]+ [A-Za-z0-9_]+$/){
124+ ext_i = match($i, / GL_/) + 1;
125+ sfx_i = match($i, / [A-Za-z0-9_]+$/) + 1;
126+ ext = substr($i, ext_i, sfx_i - ext_i - 1);
127+ sfx = substr($i, sfx_i);
128+ macro = "SAFFRON_GL_LOAD_FUNC_" upper2 "_" sfx;
129+ print("\
130+#define " macro "(X) SAFFRON_GL_FUNC_LOAD(X, \"" sfx "\")\n\
131+ if(SaffronGL_SupportsExtension(\"" ext "\")) do{ \n\
132+ SAFFRON_GL_" upper2 "_FUNCS(" macro ")\n\
133+ *ctx_ptr = ctx;\n\
134+ return 0;\n\
135+ }while(0);");
136+ }
137+ }
138+ print(" return 1;\n}");
139+ print("#endif"); # SAFFRON_GL_EXPECT_
140+}
141+
142+$1 !~ /#/ && $0 != "" {
143+ print("#endif");
144+}
145+
146+