Path: blob/main/test/canvas_animate_resize.c
4128 views
#include <stdbool.h>1#include <stdio.h>2#include <string.h>3#include <pthread.h>4#include <GLES2/gl2.h>5#include <math.h>6#include <assert.h>7#include <emscripten/emscripten.h>8#include <emscripten/html5.h>9#include <emscripten/threading.h>10#include <bits/errno.h>11#include <stdlib.h>12#include <unistd.h>1314//#define TEST_EXPLICIT_CONTEXT_SWAP15// - If set, test WebGL context creation .explicitSwapControl=true and call emscripten_webgl_commit_frame() to swap. Otherwise utilize implicit swapping.16//#define TEST_EMSCRIPTEN_SET_MAIN_LOOP17// - If set, test emscripten_set_main_loop(). If unset, run our own synchronously blocking loop18//#define TEST_MANUALLY_SET_ELEMENT_CSS_SIZE19// - 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.2021#if !defined(TEST_EMSCRIPTEN_SET_MAIN_LOOP) && !defined(__EMSCRIPTEN_PTHREADS__)22#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)23#endif2425#if !defined(TEST_EMSCRIPTEN_SET_MAIN_LOOP) && !defined(TEST_EXPLICIT_CONTEXT_SWAP)26#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)27#endif2829#define NUM_FRAMES_TO_RENDER 1003031GLuint vb;32int program;33int frameNumber = 0;34EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;3536void tick() {37double sizeScale = 21.0 + 20.0 * sin(emscripten_get_now()*0.001);38double w = 18.0*sizeScale;39double h = 11.0*sizeScale;4041EMSCRIPTEN_RESULT r;4243#if TEST_MANUALLY_SET_ELEMENT_CSS_SIZE44r = emscripten_set_element_css_size("#canvas", w / emscripten_get_device_pixel_ratio(), h / emscripten_get_device_pixel_ratio());45assert(r == EMSCRIPTEN_RESULT_SUCCESS);46#endif4748r = emscripten_set_canvas_element_size("#canvas", (int)w, (int)h);49assert(r == EMSCRIPTEN_RESULT_SUCCESS);5051int verifyWidth, verifyHeight;52r = emscripten_get_canvas_element_size("#canvas", &verifyWidth, &verifyHeight);53assert(r == EMSCRIPTEN_RESULT_SUCCESS);54assert(verifyWidth == (int)w);55assert(verifyHeight == (int)h);5657glViewport(0, 0, (int)w, (int)h);58glUseProgram(program);59glBindBuffer(GL_ARRAY_BUFFER, vb);60glDisable(GL_DEPTH_TEST);61int posLoc = glGetAttribLocation(program, "pos");62glVertexAttribPointer(posLoc, 2, GL_FLOAT, false, 0, 0);63glEnableVertexAttribArray(posLoc);64glUniform1f(glGetUniformLocation(program, "t"), emscripten_get_now()*0.0001f);65glClearColor(0,1,0,1); // Clear to green color which should never be visible66glClear(GL_COLOR_BUFFER_BIT);67glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);6869#if TEST_EXPLICIT_CONTEXT_SWAP70r = emscripten_webgl_commit_frame();71assert(r == EMSCRIPTEN_RESULT_SUCCESS);72#endif7374++frameNumber;75if (frameNumber >= NUM_FRAMES_TO_RENDER) {76#if TEST_EMSCRIPTEN_SET_MAIN_LOOP77emscripten_cancel_main_loop();78#endif79emscripten_webgl_make_context_current(0);80emscripten_webgl_destroy_context(ctx);81printf("quit\n");82exit(0);83}84}8586void init() {87printf("init\n");88glGenBuffers(1, &vb);89glBindBuffer(GL_ARRAY_BUFFER, vb);90float vertices[] = { -1, -1, -1, 1, 1, -1, 1, 1 };91glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);9293const char *vsCode =94"attribute vec2 pos;"95"varying lowp vec2 tex;"96"void main() { tex = pos * 0.5 + vec2(0.5,0.5); gl_Position = vec4(pos, 0.0, 1.0); }";97int vs = glCreateShader(GL_VERTEX_SHADER);98glShaderSource(vs, 1, &vsCode, NULL);99glCompileShader(vs);100101const char *fsCode =102"varying lowp vec2 tex;"103"uniform highp float t;"104"uniform sampler2D sampler;"105"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;"106"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)); }";107int fs = glCreateShader(GL_FRAGMENT_SHADER);108glShaderSource(fs, 1, &fsCode, NULL);109glCompileShader(fs);110program = glCreateProgram();111glAttachShader(program, vs);112glAttachShader(program, fs);113glLinkProgram(program);114}115116int main() {117EmscriptenWebGLContextAttributes attr;118emscripten_webgl_init_context_attributes(&attr);119#if TEST_EXPLICIT_CONTEXT_SWAP120attr.explicitSwapControl = true;121#endif122ctx = emscripten_webgl_create_context("#canvas", &attr);123printf("Created context with handle %#lx\n", ctx);124assert(ctx);125emscripten_webgl_make_context_current(ctx);126127init();128129printf("You should see the flag of Finland.\n");130#if TEST_EMSCRIPTEN_SET_MAIN_LOOP131emscripten_set_main_loop(tick, 0, 0);132#else133for (int i = 0; i < NUM_FRAMES_TO_RENDER; ++i) {134tick();135emscripten_current_thread_process_queued_calls();136usleep(16*1000);137}138#endif139return 99;140}141142143