Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/browser/html5_webgl.c
7085 views
1
#include <emscripten/html5_webgl.h>
2
#include <emscripten/html5.h>
3
#include <webgl/webgl2.h>
4
#include <stdlib.h>
5
#include <assert.h>
6
#include <stdio.h>
7
#include <string.h>
8
9
GLuint compile_shader(GLenum shaderType, const char *src) {
10
GLuint shader = glCreateShader(shaderType);
11
glShaderSource(shader, 1, &src, NULL);
12
glCompileShader(shader);
13
return shader;
14
}
15
16
GLuint create_program(GLuint vertexShader, GLuint fragmentShader) {
17
GLuint program = glCreateProgram();
18
glAttachShader(program, vertexShader);
19
glAttachShader(program, fragmentShader);
20
glBindAttribLocation(program, 0, "apos");
21
glBindAttribLocation(program, 1, "acolor");
22
glLinkProgram(program);
23
return program;
24
}
25
26
int main() {
27
EmscriptenWebGLContextAttributes attrs;
28
emscripten_webgl_init_context_attributes(&attrs);
29
attrs.majorVersion = 2;
30
attrs.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK;
31
attrs.renderViaOffscreenBackBuffer = true;
32
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#canvas", &attrs);
33
emscripten_webgl_make_context_current(context);
34
35
// Test emscripten_webgl_get_supported_extensions() API
36
char *extensions = emscripten_webgl_get_supported_extensions();
37
assert(extensions);
38
assert(strlen(extensions) > 0);
39
assert(strstr(extensions, "WEBGL") != 0);
40
free(extensions);
41
42
// Test emscripten_webgl_get_parameter_d() API
43
assert(emscripten_webgl_get_parameter_d(GL_BLUE_BITS) == 8);
44
45
// Test emscripten_webgl_get_parameter_o() API
46
GLuint buf;
47
glGenBuffers(1, &buf);
48
assert(buf != 0);
49
glBindBuffer(GL_ARRAY_BUFFER, buf);
50
assert(emscripten_webgl_get_parameter_o(GL_ARRAY_BUFFER_BINDING) == buf);
51
52
// Test emscripten_webgl_get_parameter_utf8() API
53
char *version = emscripten_webgl_get_parameter_utf8(GL_VERSION);
54
assert(version);
55
assert(strstr(version, "WebGL") != 0);
56
free(version);
57
58
// Test emscripten_webgl_get_parameter_i64v API
59
int64_t components = 0;
60
emscripten_webgl_get_parameter_i64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, &components);
61
assert(components > 0);
62
63
// Test emscripten_webgl_get_parameter_v API with truncated read length
64
glViewport(1, 2, 3, 4);
65
int viewport[4] = { 0, 0, 0, 0 };
66
int numElements = emscripten_webgl_get_parameter_v(GL_VIEWPORT, viewport, 3, EMSCRIPTEN_WEBGL_PARAM_TYPE_INT);
67
assert(numElements == 4);
68
assert(viewport[0] == 1);
69
assert(viewport[1] == 2);
70
assert(viewport[2] == 3);
71
assert(viewport[3] == 0);
72
73
// Test emscripten_webgl_get_parameter_v API with full read length
74
numElements = emscripten_webgl_get_parameter_v(GL_VIEWPORT, viewport, 4, EMSCRIPTEN_WEBGL_PARAM_TYPE_INT);
75
assert(numElements == 4);
76
assert(viewport[0] == 1);
77
assert(viewport[1] == 2);
78
assert(viewport[2] == 3);
79
assert(viewport[3] == 4);
80
81
// Test emscripten_webgl_get_vertex_attrib_d() API
82
glEnableVertexAttribArray(0);
83
double enabled = emscripten_webgl_get_vertex_attrib_d(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED);
84
assert(enabled == 1.0);
85
86
// Test emscripten_webgl_get_vertex_attrib_v() API with truncated read length
87
glVertexAttrib4f(0, 0.2f, 0.4f, 0.6f, 0.8f);
88
float data[4] = { 0, 0, 0, 0 };
89
numElements = emscripten_webgl_get_vertex_attrib_v(0, GL_CURRENT_VERTEX_ATTRIB, data, 2, EMSCRIPTEN_WEBGL_PARAM_TYPE_FLOAT);
90
assert(numElements == 4);
91
assert(data[0] == 0.2f);
92
assert(data[1] == 0.4f);
93
assert(data[2] == 0.0f);
94
assert(data[3] == 0.0f);
95
96
// Test emscripten_webgl_get_vertex_attrib_v() API with full read length
97
numElements = emscripten_webgl_get_vertex_attrib_v(0, GL_CURRENT_VERTEX_ATTRIB, data, 4, EMSCRIPTEN_WEBGL_PARAM_TYPE_FLOAT);
98
assert(numElements == 4);
99
assert(data[0] == 0.2f);
100
assert(data[1] == 0.4f);
101
assert(data[2] == 0.6f);
102
assert(data[3] == 0.8f);
103
104
// Test emscripten_webgl_get_vertex_attrib_o() API
105
glBufferData(GL_ARRAY_BUFFER, 4, data, GL_STATIC_DRAW);
106
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, 0);
107
assert(emscripten_webgl_get_vertex_attrib_o(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) == buf);
108
109
static const char vertex_shader[] =
110
"#version 100\n"
111
"attribute vec4 apos;"
112
"attribute vec4 acolor;"
113
"uniform float vsUniformFloat;"
114
"varying vec4 color;"
115
"void main() {"
116
"color = acolor * vsUniformFloat;"
117
"gl_Position = apos;"
118
"}";
119
GLuint vs = compile_shader(GL_VERTEX_SHADER, vertex_shader);
120
121
// Test emscripten_webgl_get_shader_parameter_d() API
122
assert(emscripten_webgl_get_shader_parameter_d(vs, GL_DELETE_STATUS) == 0);
123
assert(emscripten_webgl_get_shader_parameter_d(vs, GL_COMPILE_STATUS) == 1);
124
assert(emscripten_webgl_get_shader_parameter_d(vs, GL_SHADER_TYPE) == GL_VERTEX_SHADER);
125
126
// Test emscripten_webgl_get_shader_source_utf8() API
127
char *src = emscripten_webgl_get_shader_source_utf8(vs);
128
assert(src);
129
assert(strstr(src, "attribute") != 0);
130
free(src);
131
132
static const char failing_shader[] =
133
"#version 100\n"
134
"attribute vec4 apos;"
135
"attr_error_ibute vec4 acolor;"
136
"varying vec4 color;"
137
"void main() {"
138
"color = acolor;"
139
"gl_Position = apos;"
140
"}";
141
GLuint vs2 = compile_shader(GL_VERTEX_SHADER, failing_shader);
142
143
// Test emscripten_webgl_get_shader_info_log_utf8() API
144
src = emscripten_webgl_get_shader_info_log_utf8(vs2);
145
assert(src);
146
assert(strstr(src, "attr_error_ibute") != 0);
147
free(src);
148
149
static const char fragment_shader[] =
150
"#version 100\n"
151
"precision lowp float;"
152
"varying vec4 color;"
153
"uniform vec4 psUniformVec;"
154
"void main() {"
155
"gl_FragColor = color + psUniformVec;"
156
"}";
157
GLuint fs = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);
158
159
// Test emscripten_webgl_get_shader_parameter_d() API
160
assert(emscripten_webgl_get_shader_parameter_d(fs, GL_DELETE_STATUS) == 0);
161
assert(emscripten_webgl_get_shader_parameter_d(fs, GL_COMPILE_STATUS) == 1);
162
assert(emscripten_webgl_get_shader_parameter_d(fs, GL_SHADER_TYPE) == GL_FRAGMENT_SHADER);
163
164
// Test emscripten_webgl_get_shader_source_utf8() API
165
src = emscripten_webgl_get_shader_source_utf8(fs);
166
assert(src);
167
assert(strstr(src, "varying") != 0);
168
free(src);
169
170
GLuint program = create_program(vs, fs);
171
172
// Test emscripten_webgl_get_program_parameter_d() API
173
assert(emscripten_webgl_get_program_parameter_d(program, GL_ACTIVE_ATTRIBUTES) == 2);
174
175
// Test emscripten_webgl_get_program_info_log_utf8() API
176
GLuint program2 = create_program(vs2, fs);
177
char *programLog = emscripten_webgl_get_program_info_log_utf8(program2);
178
assert(programLog);
179
// Firefox says "Must have a compiled vertex shader attached."
180
// Chrome says "invalid shaders"
181
// -> test that word "shader" is present
182
assert(strstr(programLog, "shader") != 0);
183
free(programLog);
184
185
glUseProgram(program);
186
glUniform1f(glGetUniformLocation(program, "vsUniformFloat"), 2.f);
187
glUniform4f(glGetUniformLocation(program, "psUniformVec"), 1.f, 2.f, 3.f, 4.f);
188
189
// Test emscripten_webgl_get_uniform_d() API
190
double vsUniformFloat = emscripten_webgl_get_uniform_d(program, glGetUniformLocation(program, "vsUniformFloat"));
191
assert(vsUniformFloat == 2.f);
192
193
float psUniformVec[4] = { 0, 0, 0, 0 };
194
195
// Test emscripten_webgl_get_uniform_v() API truncated read
196
numElements = emscripten_webgl_get_uniform_v(program, glGetUniformLocation(program, "psUniformVec"), psUniformVec, 3, EMSCRIPTEN_WEBGL_PARAM_TYPE_FLOAT);
197
assert(numElements == 4);
198
assert(psUniformVec[0] == 1.0f);
199
assert(psUniformVec[1] == 2.0f);
200
assert(psUniformVec[2] == 3.0f);
201
assert(psUniformVec[3] == 0.0f);
202
203
// Test emscripten_webgl_get_uniform_v() API full read
204
numElements = emscripten_webgl_get_uniform_v(program, glGetUniformLocation(program, "psUniformVec"), psUniformVec, 4, EMSCRIPTEN_WEBGL_PARAM_TYPE_FLOAT);
205
assert(numElements == 4);
206
assert(psUniformVec[0] == 1.0f);
207
assert(psUniformVec[1] == 2.0f);
208
assert(psUniformVec[2] == 3.0f);
209
assert(psUniformVec[3] == 4.0f);
210
211
return 0;
212
}
213
214