-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathadditions.c
More file actions
218 lines (164 loc) · 6.14 KB
/
additions.c
File metadata and controls
218 lines (164 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/**
* Manual routines to add to the generated code.
*/
#include <GLUT/glut.h>
#include "quickjs/quickjs.h"
#ifdef WEBGL_DEBUG
#include <stdio.h>
static void debug_check_error(JSContext *ctx, const char *func, int argc, JSValueConst *argv) {
GLenum err = glGetError();
if (err != GL_NO_ERROR || WEBGL_DEBUG > 1) {
fprintf(stderr, "%s(", func);
for (int i = 0; i < argc; i++) {
const char *s = JS_ToCString(ctx, argv[i]);
fprintf(stderr, "%s%s", s ? s : "<value>", i == argc - 1 ? "" : ", ");
if (s) JS_FreeCString(ctx, s);
}
fprintf(stderr, ") -> %s (%d)\n", gluErrorString(err), err);
}
}
#define DEBUG_GL_CHECK(ctx, name, argc, argv) debug_check_error(ctx, name, argc, argv)
#define DEBUG_GL_CHECK_RAW(name, fmt, ...) \
do { \
GLenum err = glGetError(); \
if (err != GL_NO_ERROR || WEBGL_DEBUG > 1) { \
fprintf(stderr, name "(" fmt ") -> %s (%d)\n", \
##__VA_ARGS__, gluErrorString(err), err); \
} \
} while (0)
#else
#define DEBUG_GL_CHECK(ctx, name, argc, argv)
#define DEBUG_GL_CHECK_RAW(name, fmt, ...)
#endif
#define window_width 640
#define window_height 480
int contextGot = 0;
JSValue func = JS_UNDEFINED;
JSContext *ctx;
void renderLoop () {
if (!JS_IsFunction(ctx, func)) {
return;
}
JSValue args = JS_UNDEFINED;
JS_Call(ctx, func, JS_UNDEFINED, 0, &args);
glutSwapBuffers();
DEBUG_GL_CHECK_RAW("glutSwapBuffers", "");
}
/**
* This function initializes the OpenGL context and returns 0 if successful.
*/
static JSValue js_getContext()
{
if (contextGot) {
return JS_UNDEFINED;
}
int argc = 0;
char *argv[1] = {""};
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
glutCreateWindow("QuickJS WebGL");
DEBUG_GL_CHECK_RAW("glutCreateWindow", "\"%s\"", "QuickJS WebGL");
glutDisplayFunc(renderLoop);
DEBUG_GL_CHECK_RAW("glutDisplayFunc", "%p", renderLoop);
glutIdleFunc(renderLoop);
DEBUG_GL_CHECK_RAW("glutIdleFunc", "%p", renderLoop);
contextGot = 1;
return JS_UNDEFINED;
}
static JSValue js_start(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
glutMainLoop();
DEBUG_GL_CHECK_RAW("glutMainLoop", "");
return JS_UNDEFINED;
}
static JSValue js_glShaderSource(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
unsigned int a0; // shader
if (JS_ToUint32(ctx, &a0, argv[0])) return JS_EXCEPTION;
const char *a1; // source
a1 = JS_ToCString(ctx, argv[1]); if (!a1) return JS_EXCEPTION;
int slen = strlen(a1);
glShaderSource(a0, 1, &a1, &slen);
DEBUG_GL_CHECK(ctx, "glShaderSource", argc, argv);
return JS_UNDEFINED;
}
static JSValue js_glGetVertexAttribPointerv(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
// glGetVertexAttribPointerv(a0,a1,a2);
return JS_UNDEFINED;
}
static JSValue js_glVertexAttribPointer(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
unsigned int a0; // indx
if (JS_ToUint32(ctx, &a0, argv[0])) return JS_EXCEPTION;
int a1; // size
if (JS_ToInt32(ctx, &a1, argv[1])) return JS_EXCEPTION;
unsigned int a2; // type
if (JS_ToUint32(ctx, &a2, argv[2])) return JS_EXCEPTION;
unsigned int a3; // normalized
a3 = JS_ToBool(ctx, argv[3]);
const khronos_ssize_t a4; // stride
if (JS_ToInt32(ctx, &a4, argv[4])) return JS_EXCEPTION;
unsigned int a5; // offset
if (JS_ToUint32(ctx, &a5, argv[5])) return JS_EXCEPTION;
glVertexAttribPointer(a0,a1,a2,a3,a4,a5);
#ifdef WEBGL_DEBUG
DEBUG_GL_CHECK(ctx, "glVertexAttribPointer", argc, argv);
#endif
return JS_UNDEFINED;
}
static JSValue js_createBuffer(JSContext *ctx) {
GLuint res;
glGenBuffers(1, &res);
DEBUG_GL_CHECK(ctx, "glGenBuffers", 0, NULL);
return JS_NewInt32(ctx, res);
}
static JSValue js_requestAnimationFrame(JSContext *_ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
if (!JS_IsFunction(ctx, argv[0])) {
return JS_ThrowTypeError(ctx, "Argument must be a function");
}
func = argv[0];
ctx = _ctx;
return JS_UNDEFINED;
}
static JSValue js_errorString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
unsigned int error;
if (JS_ToUint32(ctx, &error, argv[0])) return JS_EXCEPTION;
const char *str = (const char *)gluErrorString(error);
return JS_NewString(ctx, str);
}
#define LOG_BUFF_SIZE 4096
static char log_buff[LOG_BUFF_SIZE];
static JSValue js_glGetShaderInfoLog(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
unsigned int a0; // shader
if (JS_ToUint32(ctx, &a0, argv[0])) return JS_EXCEPTION;
unsigned int length;
glGetShaderInfoLog(a0, LOG_BUFF_SIZE, &length, log_buff);
DEBUG_GL_CHECK(ctx, "glGetShaderInfoLog", argc, argv);
return JS_NewString(ctx, log_buff);
}
static JSValue js_glGetProgramInfoLog(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
unsigned int a0; // program
if (JS_ToUint32(ctx, &a0, argv[0])) return JS_EXCEPTION;
unsigned int length = LOG_BUFF_SIZE;
glGetProgramInfoLog(a0, LOG_BUFF_SIZE, &length, log_buff);
DEBUG_GL_CHECK(ctx, "glGetProgramInfoLog", argc, argv);
return JS_NewString(ctx, log_buff);
}
static JSValue js_glDrawElements(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
unsigned int a0; // mode
if (JS_ToUint32(ctx, &a0, argv[0])) return JS_EXCEPTION;
unsigned int a1; // count
if (JS_ToInt32(ctx, &a1, argv[1])) return JS_EXCEPTION;
unsigned int a2; // type
if (JS_ToUint32(ctx, &a2, argv[2])) return JS_EXCEPTION;
unsigned int a3; // offset
if (JS_ToUint32(ctx, &a3, argv[3])) return JS_EXCEPTION;
glDrawElements(a0, a1, a2, (GLvoid*)0);
DEBUG_GL_CHECK(ctx, "glDrawElements", argc, argv);
return JS_UNDEFINED;
}