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; } }
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); }
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 (); }
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; }
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"); }
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); }
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"); }
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"); }
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; }
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); }
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"); }
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; }
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; }