Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/canvas_animate_resize.c
4128 views
1
#include <stdbool.h>
2
#include <stdio.h>
3
#include <string.h>
4
#include <pthread.h>
5
#include <GLES2/gl2.h>
6
#include <math.h>
7
#include <assert.h>
8
#include <emscripten/emscripten.h>
9
#include <emscripten/html5.h>
10
#include <emscripten/threading.h>
11
#include <bits/errno.h>
12
#include <stdlib.h>
13
#include <unistd.h>
14
15
//#define TEST_EXPLICIT_CONTEXT_SWAP
16
// - If set, test WebGL context creation .explicitSwapControl=true and call emscripten_webgl_commit_frame() to swap. Otherwise utilize implicit swapping.
17
//#define TEST_EMSCRIPTEN_SET_MAIN_LOOP
18
// - If set, test emscripten_set_main_loop(). If unset, run our own synchronously blocking loop
19
//#define TEST_MANUALLY_SET_ELEMENT_CSS_SIZE
20
// - If set, manually update CSS pixel size of the canvas. If unset, leave the CSS size to auto and expect the browser to resize the canvas size.
21
22
#if !defined(TEST_EMSCRIPTEN_SET_MAIN_LOOP) && !defined(__EMSCRIPTEN_PTHREADS__)
23
#error TEST_EMSCRIPTEN_SET_MAIN_LOOP=false, but blocking main loops require using -sPROXY_TO_PTHREADS= and multithreading (build with -sPROXY_TO_PTHREAD and -pthread)
24
#endif
25
26
#if !defined(TEST_EMSCRIPTEN_SET_MAIN_LOOP) && !defined(TEST_EXPLICIT_CONTEXT_SWAP)
27
#error If using own main loop, must use explicit context swapping (explicitSwapControl=true) (build with either -DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1 or -DTEST_EXPLICIT_CONTEXT_SWAP=1)
28
#endif
29
30
#define NUM_FRAMES_TO_RENDER 100
31
32
GLuint vb;
33
int program;
34
int frameNumber = 0;
35
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;
36
37
void tick() {
38
double sizeScale = 21.0 + 20.0 * sin(emscripten_get_now()*0.001);
39
double w = 18.0*sizeScale;
40
double h = 11.0*sizeScale;
41
42
EMSCRIPTEN_RESULT r;
43
44
#if TEST_MANUALLY_SET_ELEMENT_CSS_SIZE
45
r = emscripten_set_element_css_size("#canvas", w / emscripten_get_device_pixel_ratio(), h / emscripten_get_device_pixel_ratio());
46
assert(r == EMSCRIPTEN_RESULT_SUCCESS);
47
#endif
48
49
r = emscripten_set_canvas_element_size("#canvas", (int)w, (int)h);
50
assert(r == EMSCRIPTEN_RESULT_SUCCESS);
51
52
int verifyWidth, verifyHeight;
53
r = emscripten_get_canvas_element_size("#canvas", &verifyWidth, &verifyHeight);
54
assert(r == EMSCRIPTEN_RESULT_SUCCESS);
55
assert(verifyWidth == (int)w);
56
assert(verifyHeight == (int)h);
57
58
glViewport(0, 0, (int)w, (int)h);
59
glUseProgram(program);
60
glBindBuffer(GL_ARRAY_BUFFER, vb);
61
glDisable(GL_DEPTH_TEST);
62
int posLoc = glGetAttribLocation(program, "pos");
63
glVertexAttribPointer(posLoc, 2, GL_FLOAT, false, 0, 0);
64
glEnableVertexAttribArray(posLoc);
65
glUniform1f(glGetUniformLocation(program, "t"), emscripten_get_now()*0.0001f);
66
glClearColor(0,1,0,1); // Clear to green color which should never be visible
67
glClear(GL_COLOR_BUFFER_BIT);
68
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
69
70
#if TEST_EXPLICIT_CONTEXT_SWAP
71
r = emscripten_webgl_commit_frame();
72
assert(r == EMSCRIPTEN_RESULT_SUCCESS);
73
#endif
74
75
++frameNumber;
76
if (frameNumber >= NUM_FRAMES_TO_RENDER) {
77
#if TEST_EMSCRIPTEN_SET_MAIN_LOOP
78
emscripten_cancel_main_loop();
79
#endif
80
emscripten_webgl_make_context_current(0);
81
emscripten_webgl_destroy_context(ctx);
82
printf("quit\n");
83
exit(0);
84
}
85
}
86
87
void init() {
88
printf("init\n");
89
glGenBuffers(1, &vb);
90
glBindBuffer(GL_ARRAY_BUFFER, vb);
91
float vertices[] = { -1, -1, -1, 1, 1, -1, 1, 1 };
92
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
93
94
const char *vsCode =
95
"attribute vec2 pos;"
96
"varying lowp vec2 tex;"
97
"void main() { tex = pos * 0.5 + vec2(0.5,0.5); gl_Position = vec4(pos, 0.0, 1.0); }";
98
int vs = glCreateShader(GL_VERTEX_SHADER);
99
glShaderSource(vs, 1, &vsCode, NULL);
100
glCompileShader(vs);
101
102
const char *fsCode =
103
"varying lowp vec2 tex;"
104
"uniform highp float t;"
105
"uniform sampler2D sampler;"
106
"void main() { highp float x = tex.x + sin((t + tex.y)*10.0)*0.005; highp float y = tex.y + sin((t + tex.x)*10.0)*0.02; x = x*1.3 - 0.1; y = y * 1.3 - 0.23;"
107
"gl_FragColor = (tex.x > 0.05 && tex.x < 0.09) ? vec4(0,0,0,1) : ((x >= 0.0 && x <= 1.0 && y >= 0.0 && y <= 1.0) ? (((x >= 5.0/18.0 && x <= 8.0/18.0) || (x >= 0.0 && x <= 1.0 && y >= 4.0/11.0 && y <= 7.0/11.0)) ? vec4(0,0,1,1) : vec4(1,1,1,1)) : vec4(0.75,0.75,0.75,1)); }";
108
int fs = glCreateShader(GL_FRAGMENT_SHADER);
109
glShaderSource(fs, 1, &fsCode, NULL);
110
glCompileShader(fs);
111
program = glCreateProgram();
112
glAttachShader(program, vs);
113
glAttachShader(program, fs);
114
glLinkProgram(program);
115
}
116
117
int main() {
118
EmscriptenWebGLContextAttributes attr;
119
emscripten_webgl_init_context_attributes(&attr);
120
#if TEST_EXPLICIT_CONTEXT_SWAP
121
attr.explicitSwapControl = true;
122
#endif
123
ctx = emscripten_webgl_create_context("#canvas", &attr);
124
printf("Created context with handle %#lx\n", ctx);
125
assert(ctx);
126
emscripten_webgl_make_context_current(ctx);
127
128
init();
129
130
printf("You should see the flag of Finland.\n");
131
#if TEST_EMSCRIPTEN_SET_MAIN_LOOP
132
emscripten_set_main_loop(tick, 0, 0);
133
#else
134
for (int i = 0; i < NUM_FRAMES_TO_RENDER; ++i) {
135
tick();
136
emscripten_current_thread_process_queued_calls();
137
usleep(16*1000);
138
}
139
#endif
140
return 99;
141
}
142
143