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);
}
Esempio n. 2
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
	}
Esempio n. 3
0
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;
}
Esempio n. 7
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, &param); 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
}