void *ThreadMain(void *arg) { printf("Thread started. You should see the WebGL canvas fade from black to red.\n"); EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); attr.explicitSwapControl = EM_TRUE; ctx = emscripten_webgl_create_context(0, &attr); emscripten_webgl_make_context_current(ctx); double color = 0; for(int i = 0; i < 100; ++i) { color += 0.01; glClearColor(color, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); EMSCRIPTEN_RESULT r = emscripten_webgl_commit_frame(); assert(r == EMSCRIPTEN_RESULT_SUCCESS); double now = emscripten_get_now(); while(emscripten_get_now() - now < 16) /*no-op*/; } emscripten_webgl_make_context_current(0); emscripten_webgl_destroy_context(ctx); emscripten_atomic_store_u32(&threadRunning, 0); printf("Thread quit\n"); pthread_exit(0); }
void EmRenderWindow::initContext() { printf("Setting Emscripten Canvas size\n"); emscripten_set_canvas_size(m_width, m_height); EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); attrs.depth = 1; attrs.stencil = 1; attrs.antialias = 1; attrs.majorVersion = 2; attrs.minorVersion = 0; assert(emscripten_webgl_get_current_context() == 0); printf("Creating Emscripten WebGL context\n"); m_window = emscripten_webgl_create_context("canvas", &attrs); printf("Created Emscripten WebGL context %i\n", m_window); emscripten_webgl_make_context_current(m_window); #if defined TOY_PLATFORM_LINUX || defined TOY_PLATFORM_BSD m_nativeHandle = (void*)(uintptr_t)glfwGetX11Window(_window); #elif defined TOY_PLATFORM_OSX m_nativeHandle = glfwGetCocoaWindow(_window); #elif defined TOY_PLATFORM_WINDOWS m_nativeHandle = glfwGetWin32Window(m_glWindow); #endif }
static void init_webgl_attribs_from_framebuffer_config(EmscriptenWebGLContextAttributes *attribs, cg_framebuffer_config_t *config) { emscripten_webgl_init_context_attributes(attribs); attribs->antialias = config->samples_per_pixel ? true : false; attribs->alpha = config->has_alpha ? true : false; attribs->stencil = config->need_stencil ? true : false; }
int main() { EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(0, &attrs); assert(context > 0); // Must have received a valid context. EMSCRIPTEN_RESULT res = emscripten_webgl_make_context_current(context); assert(res == EMSCRIPTEN_RESULT_SUCCESS); assert(emscripten_webgl_get_current_context() == context); #ifdef REPORT_RESULT REPORT_RESULT(0); #endif }
void PollThreadExit(void *) { if (!emscripten_atomic_load_u32(&threadRunning)) { EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); #ifdef TEST_MAIN_THREAD_EXPLICIT_COMMIT attr.explicitSwapControl = EM_TRUE; #endif ctx = emscripten_webgl_create_context(0, &attr); emscripten_webgl_make_context_current(ctx); printf("Main thread rendering. You should see the WebGL canvas fade from black to green.\n"); emscripten_set_main_loop(MainThreadRender, 0, 0); } else { emscripten_async_call(PollThreadExit, 0, 1000); } }
static void* thread(void* data) { EmscriptenWebGLContextAttributes attributes; emscripten_webgl_init_context_attributes(&attributes); int context = emscripten_webgl_create_context(0, &attributes); emscripten_webgl_make_context_current(context); int i = 0; for(;;) { i = (i + 1) % 256; glClearColor(i / 255.0f, i / 255.0f, i / 255.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); emscripten_webgl_commit_context(context); usleep((useconds_t)(1000000.0f / 60.0f)); } return 0; }
void application::init_context() { auto attrs = EmscriptenWebGLContextAttributes{}; attrs.stencil = EM_TRUE; attrs.enableExtensionsByDefault = EM_FALSE; emscripten_webgl_init_context_attributes(&attrs); const auto ctx = emscripten_webgl_create_context(canvas_target, &attrs); emscripten_webgl_make_context_current(ctx); glctx = ctx; emscripten_webgl_enable_extension(glctx, "ANGLE_instanced_arrays"); emscripten_set_mousedown_callback( canvas_target, this, false, &enable_drag_handler); emscripten_set_touchstart_callback( canvas_target, this, false, &enable_drag_handler); emscripten_set_mouseup_callback( canvas_target, this, false, &disable_drag_handler); emscripten_set_mouseleave_callback( canvas_target, this, false, &disable_drag_handler); emscripten_set_mouseout_callback( canvas_target, this, false, &disable_drag_handler); emscripten_set_touchend_callback( canvas_target, this, false, &disable_drag_handler); emscripten_set_touchcancel_callback( canvas_target, this, false, &disable_drag_handler); emscripten_set_mousemove_callback( canvas_target, this, false, &mouse_move_handler); emscripten_set_touchmove_callback( canvas_target, this, false, &mouse_move_handler); };
int main() { emscripten_set_canvas_size( 100, 100 ); EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); attrs.enableExtensionsByDefault = 1; attrs.majorVersion = 2; attrs.minorVersion = 0; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context( 0, &attrs ); if (!context) { attrs.majorVersion = 1; context = emscripten_webgl_create_context( 0, &attrs ); if (context) printf("Skipping test: WebGL 2.0 is not available.\n"); else printf("Test failed: WebGL is not available!\n"); #ifdef REPORT_RESULT // We did not have WebGL 2, but were able to init WebGL 1? In that case, gracefully skip this test with the current browser not supporting this one. int result = context ? 0 : 12365; REPORT_RESULT(); #endif return 0; } emscripten_webgl_make_context_current(context); // Textures // int mips = 10; int sizeO = 512; unsigned short* data = new unsigned short[ 512 * 512 * 4 ]; //memset( data, 0, 512 * 512 * 4 ); // Create texture 1 GLuint tex1; GL_CALL( glGenTextures( 1, &tex1 ) ); GL_CALL( glBindTexture( GL_TEXTURE_CUBE_MAP, tex1 ) ); for( int i=0; i<6; ++i ) { GL_CALL( glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA16F, sizeO, sizeO, 0, GL_RGBA, GL_HALF_FLOAT, NULL ) ); } GL_CALL( glGenerateMipmap( GL_TEXTURE_CUBE_MAP ) ); for( int i=0; i<6; ++i ) GL_CALL( glTexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, 0, 0, sizeO, sizeO, GL_RGBA, GL_HALF_FLOAT, data ) ); delete [] data; // Create texture 2 GLuint tex2; GL_CALL( glGenTextures( 1, &tex2 ) ); GL_CALL( glBindTexture( GL_TEXTURE_CUBE_MAP, tex2 ) ); for( int i=0; i<6; ++i ) { GL_CALL( glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA16F, sizeO, sizeO, 0, GL_RGBA, GL_HALF_FLOAT, NULL ) ); } GL_CALL( glGenerateMipmap( GL_TEXTURE_CUBE_MAP ) ); // FBOs // // Create FBO 1 GLuint fbo1; GL_CALL( glGenFramebuffers( 1, &fbo1 ) ); GL_CALL( glBindFramebuffer( GL_FRAMEBUFFER, fbo1 ) ); for( int level=0; level<mips; ++level ) { for( int i=0; i<6; ++i ) { GL_CALL( glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex1, level ) ); } } IsFramebufferValid( GL_FRAMEBUFFER ); // Create FBO 2 GLuint fbo2; GL_CALL( glGenFramebuffers( 1, &fbo2 ) ); GL_CALL( glBindFramebuffer( GL_FRAMEBUFFER, fbo2 ) ); for( int level=0; level<mips; ++level ) { for( int i=0; i<6; ++i ) { GL_CALL( glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex2, level ) ); glViewport( 0, 0, sizeO, sizeO ); } } IsFramebufferValid( GL_FRAMEBUFFER ); // Copy FBO 1 to 2 int nw = sizeO; GL_CALL( glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo1 ) ); GL_CALL( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fbo2 ) ); for( int level=0; level<mips; ++level ) { for( int i=0; i<6; ++i ) { GL_CALL( glFramebufferTexture2D( GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex1, level ) ); GL_CALL( glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex2, level ) ); glViewport( 0, 0, nw, nw ); GL_CALL( glBlitFramebuffer( 0, 0, nw, nw, 0, 0, nw, nw, GL_COLOR_BUFFER_BIT, GL_NEAREST ) ); } nw /= 2; } GL_CALL( glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ) ); GL_CALL( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) ); #ifdef REPORT_RESULT int result = 0; REPORT_RESULT(); #endif return 0; }
int main() { EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); attrs.enableExtensionsByDefault = 1; attrs.majorVersion = 2; attrs.minorVersion = 0; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context( 0, &attrs ); if (!context) { printf("Skipped: WebGL 2 is not supported.\n"); #ifdef REPORT_RESULT REPORT_RESULT(); #endif return 0; } emscripten_webgl_make_context_current(context); const char *vertexShader = "#version 300 es\n" "uniform Block1a {\n" " uniform mat4 var1;\n" " uniform vec4 variable2;\n" "} block1bb;\n" "uniform Block2ccc {\n" " uniform mat4 var1;\n" " uniform vec4 variable2;\n" "} block2dddd;\n" "void main() {\n" " gl_Position = block1bb.var1*block1bb.variable2 + block2dddd.var1*block2dddd.variable2;\n" "}\n"; const char *fragmentShader = "#version 300 es\n" "precision lowp float;\n" " uniform Block3eeeee {\n" " uniform vec4 var1;\n" " uniform vec4 variable2;\n" "} block3ffffff;\n" // Append characters of different lengths to test name string lengths. "out vec4 outColor;\n" "void main() {\n" " outColor = block3ffffff.var1 + block3ffffff.variable2;\n" "}\n"; GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, &vertexShader, NULL); glCompileShader(vs); int ok = 0; glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); if (!ok) { printf("Shader compilation error with vertex\n"); GLint infoLen = 0; glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); glGetShaderInfoLog(vs, infoLen, NULL, infoLog); printf("Error compiling shader:\n%s\n", infoLog); } } GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, &fragmentShader, NULL); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); if (!ok) { printf("Shader compilation error with fragment\n"); GLint infoLen = 0; glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); glGetShaderInfoLog(vs, infoLen, NULL, infoLog); printf("Error compiling shader:\n%s\n", infoLog); } } GLuint program = glCreateProgram(); glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &ok); assert(ok); int maxLength = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength); printf("GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: %d\n", maxLength); assert(maxLength == 12); GLint numActiveUniformBlocks = -1; glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveUniformBlocks); assert(numActiveUniformBlocks == 3); // Dump all active uniform buffer blocks of the current program. for(int i = 0; i < numActiveUniformBlocks; ++i) { char str[256] = {}; GLsizei length = -1; glGetActiveUniformBlockName(program, i, 255, &length, str); assert(length > 0); printf("Active uniform block at index %d: %s\n", i, str); GLint param = -1; #define DUMPUNIFORMBLOCKSTATUS(stat) glGetActiveUniformBlockiv(program, i, stat, ¶m); printf("%s: %d\n", #stat, param); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_BINDING); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_DATA_SIZE); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_NAME_LENGTH); DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS); GLint indices[16] = {}; glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices); for(size_t i = 0; i < param; ++i) printf("offset for index %d: %d\n", i, indices[i]); } #ifdef REPORT_RESULT REPORT_RESULT(); #endif return 0; }
int main() { EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); attrs.enableExtensionsByDefault = true; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(0, &attrs); emscripten_webgl_make_context_current(context); // Test what the return values of GL_IMPLEMENTATION_COLOR_READ_TYPE and GL_IMPLEMENTATION_COLOR_READ_FORMAT are. GLint type = -1, format = -1; glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type); printf("GL_IMPLEMENTATION_COLOR_READ_TYPE for FBO 0: 0x%x\n", type); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format); printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT for FBO 0: 0x%x\n", format); // Try glReadPixels() in that format. unsigned char data[16]; glReadPixels(0, 0, 1, 1, format, type, &data); assert(glGetError() == 0 && "glReadPixels of FBO 0 in implementation defined format failed"); // Try glReadPixels() in the format that is mandated to work by the spec. glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data); assert(glGetError() == 0 && "glReadPixels of FBO 0 in GL_RGBA+GL_UNSIGNED_BYTE format failed"); // Test the same with a floating point render target bound. GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint rb; glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 512, 512); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type); printf("GL_IMPLEMENTATION_COLOR_READ_TYPE for FBO with float renderbuffer: 0x%x\n", type); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format); printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT for FBO with float renderbuffer: 0x%x\n", format); // Try glReadPixels() in that format. if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { printf("Oops, WebGL implementation returns an implementation defined color type(==GL_UNSIGNED_BYTE) & format(==GL_RGBA) that should " "not be possible to be used to sample WebGL floating point color renderbuffer according to WEBGL_color_buffer_float.\n"); } while (glGetError() != 0); glReadPixels(0, 0, 1, 1, format, type, &data); if (glGetError() != 0) printf("glReadPixels of FBO with floating point color renderbuffer in implementation defined format failed"); // Try glReadPixels() in the format that is mandated to work by the spec. WEBGL_color_buffer_float says // that GL_RGBA and GL_UNSIGNED_BYTE no longer work but instead GL_RGBA and GL_FLOAT must be used. glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, &data); assert(glGetError() == 0 && "glReadPixels of FBO with floating point color renderbuffer in GL_RGBA+GL_FLOAT format failed"); #ifdef REPORT_RESULT int result = 0; REPORT_RESULT(); #endif }