Ejemplo n.º 1
0
static void
handle_event(Data *data, SDL_Event *event)
{
    switch (event->type) {
    case SDL_WINDOWEVENT:
        switch (event->window.event) {
        case SDL_WINDOWEVENT_CLOSE:
            data->quit = true;
            break;
        }
        break;

    case SDL_MOUSEMOTION: {
        int width = cg_framebuffer_get_width(data->fb);
        int height = cg_framebuffer_get_height(data->fb);

        data->center_x = event->motion.x * 2.0f / width - 1.0f;
        data->center_y = event->motion.y * 2.0f / height - 1.0f;

        data->redraw_queued = true;
    } break;

    case SDL_QUIT:
        data->quit = true;
        break;
    }
}
Ejemplo n.º 2
0
static void
_cg_winsys_onscreen_set_resizable(cg_onscreen_t *onscreen,
                                  bool resizable)
{
    cg_framebuffer_t *framebuffer = CG_FRAMEBUFFER(onscreen);
    cg_device_t *dev = framebuffer->dev;
    cg_xlib_renderer_t *xlib_renderer =
        _cg_xlib_renderer_get_data(dev->display->renderer);
    cg_onscreen_egl_t *egl_onscreen = onscreen->winsys;
    cg_onscreen_xlib_t *xlib_onscreen = egl_onscreen->platform;

    XSizeHints *size_hints = XAllocSizeHints();

    if (resizable) {
        /* TODO: Add cg_onscreen_request_minimum_size () */
        size_hints->min_width = 1;
        size_hints->min_height = 1;

        size_hints->max_width = INT_MAX;
        size_hints->max_height = INT_MAX;
    } else {
        int width = cg_framebuffer_get_width(framebuffer);
        int height = cg_framebuffer_get_height(framebuffer);

        size_hints->min_width = width;
        size_hints->min_height = height;

        size_hints->max_width = width;
        size_hints->max_height = height;
    }

    XSetWMNormalHints(xlib_renderer->xdpy, xlib_onscreen->xwin, size_hints);

    XFree(size_hints);
}
Ejemplo n.º 3
0
void
test_blend (void)
{
  cg_framebuffer_orthographic (test_fb, 0, 0,
                                 cg_framebuffer_get_width (test_fb),
                                 cg_framebuffer_get_height (test_fb),
                                 -1,
                                 100);

  paint ();
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
    cg_onscreen_t *onscreen;
    cg_error_t *error = NULL;
    struct demo demo;
    float fovy, aspect, z_near, z_2d, z_far;
    uv_loop_t *loop = uv_default_loop();

    demo.dev = cg_device_new ();
    if (!demo.dev || error != NULL)
        c_error("Failed to create Cogl context\n");

    onscreen = cg_onscreen_new(demo.dev, WIDTH, HEIGHT);

    demo.fb = onscreen;
    demo.width = cg_framebuffer_get_width(demo.fb);
    demo.height = cg_framebuffer_get_height(demo.fb);

    cg_onscreen_show(onscreen);
    cg_framebuffer_set_viewport(demo.fb, 0, 0, demo.width, demo.height);

    fovy = 45;
    aspect = (float)demo.width / (float)demo.height;
    z_near = 0.1;
    z_2d = 1000;
    z_far = 2000;

    cg_framebuffer_perspective(demo.fb, fovy, aspect, z_near, z_far);
    c_matrix_init_identity(&demo.view);
    c_matrix_view_2d_in_perspective(&demo.view, fovy, aspect, z_near, z_2d,
                                     demo.width, demo.height);
    cg_framebuffer_set_modelview_matrix(demo.fb, &demo.view);
    demo.swap_ready = true;

    cg_onscreen_add_frame_callback(demo.fb, frame_event_cb, &demo, NULL);

    init_particle_emitters(&demo);

    demo.timer = c_timer_new();
    demo.spin_rate = 0;
    demo.angle_between_emitters = 2 * M_PI / C_N_ELEMENTS(demo.emitter);

    uv_idle_init(loop, &demo.idle);
    demo.idle.data = &demo;
    uv_idle_start(&demo.idle, paint_cb);

    cg_uv_set_mainloop(demo.dev, loop);
    uv_run(loop, UV_RUN_DEFAULT);

    return 0;
}
Ejemplo n.º 5
0
void
test_depth_test (void)
{
  TestState state;

  cg_framebuffer_orthographic (test_fb, 0, 0,
                                 cg_framebuffer_get_width (test_fb),
                                 cg_framebuffer_get_height (test_fb),
                                 -1,
                                 100);

  paint (&state);

  if (test_verbose ())
    c_print ("OK\n");
}
Ejemplo n.º 6
0
static void
paint (void)
{
  cg_pipeline_t *pipeline = cg_pipeline_new (test_dev);
  int width = cg_framebuffer_get_width (test_fb);
  int half_width = width / 2;
  int height = cg_framebuffer_get_height (test_fb);
  cg_vertex_p2_t tri0_vertices[] = {
        { 0, 0 },
        { 0, height },
        { half_width, height },
  };
  cg_vertex_p2c4_t tri1_vertices[] = {
        { half_width, 0, 0x80, 0x80, 0x80, 0x80 },
        { half_width, height, 0x80, 0x80, 0x80, 0x80 },
        { width, height, 0x80, 0x80, 0x80, 0x80 },
  };
  cg_primitive_t *tri0;
  cg_primitive_t *tri1;

  cg_framebuffer_clear4f (test_fb, CG_BUFFER_BIT_COLOR, 0, 0, 0, 0);

  tri0 = cg_primitive_new_p2 (test_dev, CG_VERTICES_MODE_TRIANGLES,
                                3, tri0_vertices);
  tri1 = cg_primitive_new_p2c4 (test_dev, CG_VERTICES_MODE_TRIANGLES,
                                  3, tri1_vertices);

  /* Check that cogl correctly handles the case where we draw
   * different primitives same pipeline and switch from using the
   * opaque color associated with the pipeline and using a colour
   * attribute with an alpha component which implies blending is
   * required.
   *
   * If Cogl gets this wrong then then in all likelyhood the second
   * primitive will be drawn with blending still disabled.
   */

  cg_primitive_draw (tri0, test_fb, pipeline);
  cg_primitive_draw (tri1, test_fb, pipeline);

  test_cg_check_pixel_and_alpha (test_fb,
                                    half_width + 5,
                                    height - 5,
                                    0x80808080);
}
Ejemplo n.º 7
0
void
test_snippets(void)
{
    TestState state;

    state.fb_width = cg_framebuffer_get_width(test_fb);
    state.fb_height = cg_framebuffer_get_height(test_fb);

    cg_framebuffer_orthographic(test_fb,
                                0, 0,
                                state.fb_width,
                                state.fb_height,
                                -1,
                                100);

    run_tests(&state);

    if(test_verbose())
        c_print("OK\n");
}
Ejemplo n.º 8
0
void
test_texture_mipmap_get_set (void)
{
  cg_texture_t *texture = make_texture ();

  cg_framebuffer_orthographic (test_fb,
                                 0, 0,
                                 cg_framebuffer_get_width (test_fb),
                                 cg_framebuffer_get_height (test_fb),
                                 -1,
                                 100);

  update_mipmap_levels (texture);
  paint (texture);

  validate_results ();

  if (test_verbose ())
    c_print ("OK\n");
}
Ejemplo n.º 9
0
static bool
_cg_winsys_onscreen_init(cg_onscreen_t *onscreen,
                         cg_error_t **error)
{
    cg_framebuffer_t *framebuffer = CG_FRAMEBUFFER(onscreen);
    cg_onscreen_webgl_t *webgl_onscreen;
    cg_device_t *dev = framebuffer->dev;
    cg_display_t *display = dev->display;
    cg_webgl_display_t *webgl_display = display->winsys;
    int width, height;

    width = cg_framebuffer_get_width(framebuffer);
    height = cg_framebuffer_get_height(framebuffer);

    CGlib_Emscripten_SetWindowSize(webgl_display->window, width, height);

    onscreen->winsys = c_slice_new(cg_onscreen_webgl_t);
    webgl_onscreen = onscreen->winsys;
    webgl_onscreen->window = webgl_display->window;

    return true;
}
Ejemplo n.º 10
0
static void
setup_orthographic_modelview (void)
{
  c_matrix_t matrix;
  int fb_width = cg_framebuffer_get_width (test_fb);
  int fb_height = cg_framebuffer_get_height (test_fb);

  /* Set up a non-identity modelview matrix. When the journal is
   * flushed it will usually flush the identity matrix. Using the
   * non-default matrix ensures that we test that Cogl restores the
   * matrix we asked for. The matrix sets up an orthographic transform
   * in the modelview matrix */

  c_matrix_init_identity (&matrix);
  c_matrix_orthographic (&matrix,
                            0.0f, 0.0f, /* x_1 y_1 */
                            fb_width,
                            fb_height,
                            -1.0f, /* nearval */
                            1.0f /* farval */);
  cg_framebuffer_set_modelview_matrix (test_fb, &matrix);
}
Ejemplo n.º 11
0
static void
_cg_winsys_onscreen_swap_region(cg_onscreen_t *onscreen,
                                const int *user_rectangles,
                                int n_rectangles)
{
    cg_device_t *dev = CG_FRAMEBUFFER(onscreen)->dev;
    cg_renderer_t *renderer = dev->display->renderer;
    cg_renderer_egl_t *egl_renderer = renderer->winsys;
    cg_onscreen_egl_t *egl_onscreen = onscreen->winsys;
    cg_framebuffer_t *framebuffer = CG_FRAMEBUFFER(onscreen);
    int framebuffer_height = cg_framebuffer_get_height(framebuffer);
    int *rectangles = c_alloca(sizeof(int) * n_rectangles * 4);
    int i;

    /* eglSwapBuffersRegion expects rectangles relative to the
     * bottom left corner but we are given rectangles relative to
     * the top left so we need to flip them... */
    memcpy(rectangles, user_rectangles, sizeof(int) * n_rectangles * 4);
    for (i = 0; i < n_rectangles; i++) {
        int *rect = &rectangles[4 * i];
        rect[1] = framebuffer_height - rect[1] - rect[3];
    }

    /* At least for eglSwapBuffers the EGL spec says that the surface to
       swap must be bound to the current context. It looks like Mesa
       also validates that this is the case for eglSwapBuffersRegion so
       we must bind here too */
    _cg_framebuffer_flush_state(CG_FRAMEBUFFER(onscreen),
                                CG_FRAMEBUFFER(onscreen),
                                CG_FRAMEBUFFER_STATE_BIND);

    if (!egl_renderer->pf_eglSwapBuffersRegion(egl_renderer->edpy,
                                               egl_onscreen->egl_surface,
                                               n_rectangles,
                                               rectangles))
        c_warning("Error reported by eglSwapBuffersRegion");
}
Ejemplo n.º 12
0
void
test_npot_texture (void)
{
  if (test_verbose ())
    {
      if (cg_has_feature (test_dev, CG_FEATURE_ID_TEXTURE_NPOT))
        c_print ("NPOT textures are supported\n");
      else
        c_print ("NPOT textures are not supported\n");
    }

  cg_framebuffer_orthographic (test_fb,
                                 0, 0,
                                 cg_framebuffer_get_width (test_fb),
                                 cg_framebuffer_get_height (test_fb),
                                 -1,
                                 100);

  paint ();
  validate_result ();

  if (test_verbose ())
    c_print ("OK\n");
}
Ejemplo n.º 13
0
static bool
_cg_winsys_onscreen_init(cg_onscreen_t *onscreen,
                         cg_error_t **error)
{
    cg_framebuffer_t *framebuffer = CG_FRAMEBUFFER(onscreen);
    cg_onscreen_sdl2_t *sdl_onscreen;
    SDL_Window *window;
    int width, height;
    SDL_WindowFlags flags;

#ifdef __ANDROID__
    {
        cg_display_t *display = framebuffer->dev->display;
        cg_display_sdl2_t *sdl_display = display->winsys;
        int win_width, win_height;

        if (sdl_display->have_onscreen) {
            _cg_set_error(error,
                          CG_WINSYS_ERROR,
                          CG_WINSYS_ERROR_CREATE_ONSCREEN,
                          "Android platform only supports a single "
                          "onscreen window");
            return false;
        }

        window = sdl_display->dummy_window;

        SDL_GetWindowSize(window, &win_width, &win_height);

        _cg_framebuffer_winsys_update_size(framebuffer, win_width, win_height);

        sdl_display->have_onscreen = true;
    }

#else /* __ANDROID__ */

    width = cg_framebuffer_get_width(framebuffer);
    height = cg_framebuffer_get_height(framebuffer);

    flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;

    /* The resizable property on SDL window apparently can only be set
     * on creation */
    if (onscreen->resizable)
        flags |= SDL_WINDOW_RESIZABLE;

    window = SDL_CreateWindow("" /* title */,
                              0,
                              0, /* x/y */
                              width,
                              height,
                              flags);
    if (window == NULL) {
        _cg_set_error(error,
                      CG_WINSYS_ERROR,
                      CG_WINSYS_ERROR_CREATE_ONSCREEN,
                      "SDL_CreateWindow failed: %s",
                      SDL_GetError());
        return false;
    }

#endif /* __ANDROID__ */

    SDL_SetWindowData(window, CG_SDL_WINDOW_DATA_KEY, onscreen);

    onscreen->winsys = c_slice_new(cg_onscreen_sdl2_t);
    sdl_onscreen = onscreen->winsys;
    sdl_onscreen->window = window;

    return true;
}
Ejemplo n.º 14
0
static bool
_cg_winsys_egl_onscreen_init(cg_onscreen_t *onscreen,
                             EGLConfig egl_config,
                             cg_error_t **error)
{
    cg_framebuffer_t *framebuffer = CG_FRAMEBUFFER(onscreen);
    cg_device_t *dev = framebuffer->dev;
    cg_display_t *display = dev->display;
    cg_renderer_t *renderer = display->renderer;
    cg_renderer_egl_t *egl_renderer = renderer->winsys;
    cg_xlib_renderer_t *xlib_renderer = _cg_xlib_renderer_get_data(renderer);
    cg_onscreen_xlib_t *xlib_onscreen;
    cg_onscreen_egl_t *egl_onscreen = onscreen->winsys;
    Window xwin;

    /* FIXME: We need to explicitly Select for ConfigureNotify events.
     * For foreign windows we need to be careful not to mess up any
     * existing event mask.
     * We need to document that for windows we create then toolkits
     * must be careful not to clear event mask bits that we select.
     */

    /* XXX: Note we ignore the user's original width/height when
     * given a foreign X window. */
    if (onscreen->foreign_xid) {
        Status status;
        cg_xlib_trap_state_t state;
        XWindowAttributes attr;
        int xerror;

        xwin = onscreen->foreign_xid;

        _cg_xlib_renderer_trap_errors(display->renderer, &state);

        status = XGetWindowAttributes(xlib_renderer->xdpy, xwin, &attr);
        xerror = _cg_xlib_renderer_untrap_errors(display->renderer, &state);
        if (status == 0 || xerror) {
            char message[1000];
            XGetErrorText(
                xlib_renderer->xdpy, xerror, message, sizeof(message));
            _cg_set_error(error,
                          CG_WINSYS_ERROR,
                          CG_WINSYS_ERROR_CREATE_ONSCREEN,
                          "Unable to query geometry of foreign "
                          "xid 0x%08lX: %s",
                          xwin,
                          message);
            return false;
        }

        _cg_framebuffer_winsys_update_size(
            framebuffer, attr.width, attr.height);

        /* Make sure the app selects for the events we require... */
        onscreen->foreign_update_mask_callback(
            onscreen,
            CG_ONSCREEN_X11_EVENT_MASK,
            onscreen->foreign_update_mask_data);
    } else {
        int width;
        int height;
        cg_xlib_trap_state_t state;
        XVisualInfo *xvisinfo;
        XSetWindowAttributes xattr;
        unsigned long mask;
        int xerror;

        width = cg_framebuffer_get_width(framebuffer);
        height = cg_framebuffer_get_height(framebuffer);

        _cg_xlib_renderer_trap_errors(display->renderer, &state);

        xvisinfo = get_visual_info(display, egl_config);
        if (xvisinfo == NULL) {
            _cg_set_error(error,
                          CG_WINSYS_ERROR,
                          CG_WINSYS_ERROR_CREATE_ONSCREEN,
                          "Unable to retrieve the X11 visual of context's "
                          "fbconfig");
            return false;
        }

        /* window attributes */
        xattr.background_pixel =
            WhitePixel(xlib_renderer->xdpy, DefaultScreen(xlib_renderer->xdpy));
        xattr.border_pixel = 0;
        /* XXX: is this an X resource that we are leaking‽... */
        xattr.colormap = XCreateColormap(xlib_renderer->xdpy,
                                         DefaultRootWindow(xlib_renderer->xdpy),
                                         xvisinfo->visual,
                                         AllocNone);
        xattr.event_mask = CG_ONSCREEN_X11_EVENT_MASK;

        mask = CWBorderPixel | CWColormap | CWEventMask;

        xwin = XCreateWindow(xlib_renderer->xdpy,
                             DefaultRootWindow(xlib_renderer->xdpy),
                             0,
                             0,
                             width,
                             height,
                             0,
                             xvisinfo->depth,
                             InputOutput,
                             xvisinfo->visual,
                             mask,
                             &xattr);

        XFree(xvisinfo);

        XSync(xlib_renderer->xdpy, False);
        xerror = _cg_xlib_renderer_untrap_errors(display->renderer, &state);
        if (xerror) {
            char message[1000];
            XGetErrorText(
                xlib_renderer->xdpy, xerror, message, sizeof(message));
            _cg_set_error(error,
                          CG_WINSYS_ERROR,
                          CG_WINSYS_ERROR_CREATE_ONSCREEN,
                          "X error while creating Window for cg_onscreen_t: %s",
                          message);
            return false;
        }
    }

    xlib_onscreen = c_slice_new(cg_onscreen_xlib_t);
    egl_onscreen->platform = xlib_onscreen;

    xlib_onscreen->xwin = xwin;
    xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? true : false;

    egl_onscreen->egl_surface =
        eglCreateWindowSurface(egl_renderer->edpy,
                               egl_config,
                               (NativeWindowType)xlib_onscreen->xwin,
                               NULL);

    return true;
}