void eecs467_default_display_started (vx_application_t *app, vx_display_t *disp) { eecs467_default_implementation_t *impl = app->impl; vx_layer_t *layer = vx_layer_create (impl->world); vx_layer_set_background_color (layer, vx_black); vx_layer_set_display (layer, disp); pthread_mutex_lock (&impl->mutex); // store a reference to the world and layer that we associate with each vx_display_t zhash_put (impl->layers, &disp, &layer, NULL, NULL); pthread_mutex_unlock (&impl->mutex); if (impl->vxeh != NULL) vx_layer_add_event_handler (layer, impl->vxeh); vx_layer_camera_op (layer, OP_PROJ_PERSPECTIVE); float eye[3] = { 0, 0, 1 }; float lookat[3] = { 0, 0, 0 }; float up[3] = { 0, 1, 0 }; vx_layer_camera_lookat (layer, eye, lookat, up, 1); vx_code_output_stream_t *couts = vx_code_output_stream_create (128); couts->write_uint32 (couts, OP_LAYER_CAMERA); couts->write_uint32 (couts, vx_layer_id (layer)); couts->write_uint32 (couts, OP_INTERFACE_MODE); couts->write_float (couts, 2.5f); disp->send_codes (disp, couts->data, couts->pos); vx_code_output_stream_destroy (couts); }
vx_buffer_t * vx_world_get_buffer(vx_world_t * world, const char * name) { vx_buffer_t * buffer = NULL; pthread_mutex_lock(&world->buffer_mutex); zhash_get(world->buffer_map, &name, &buffer); if (buffer == NULL) { buffer = calloc(1, sizeof(vx_buffer_t)); buffer->name = strdup(name); buffer->world = world; buffer->draw_order = 0; buffer->back_objs = zarray_create(sizeof(vx_object_t*)); buffer->pending_objs = zarray_create(sizeof(vx_object_t*)); buffer->front_objs = zarray_create(sizeof(vx_object_t*)); buffer->front_resc = zhash_create(sizeof(uint64_t), sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals); buffer->front_codes = vx_code_output_stream_create(128); pthread_mutex_init(&buffer->mutex, NULL); vx_buffer_t * oldBuffer= NULL; zhash_put(buffer->world->buffer_map, &buffer->name, &buffer, NULL, &oldBuffer); assert(oldBuffer == NULL); } pthread_mutex_unlock(&world->buffer_mutex); return buffer; }
void buffer_checkbox_changed(GtkWidget * widget, gpointer userdata) { buffer_info_t * buffer = userdata; int enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); vx_code_output_stream_t * outs = vx_code_output_stream_create(128); outs->write_uint32 (outs, OP_BUFFER_ENABLED); outs->write_uint32 (outs, buffer->layer_id); outs->write_str (outs, buffer->name); outs->write_uint8 (outs, enabled? 1 : 0); // convert to byte buffer->man->disp->send_codes(buffer->man->disp, outs->data, outs->pos); vx_code_output_stream_destroy(outs); }
static vx_code_output_stream_t * make_buffer_resource_codes(vx_buffer_t * buffer, zhash_t * resources) { vx_code_output_stream_t * couts = vx_code_output_stream_create(256); couts->write_uint32(couts, OP_BUFFER_RESOURCES); // tell the display which resources are currently in use couts->write_uint32(couts, buffer->world->worldID); couts->write_str(couts, buffer->name); couts->write_uint32(couts, zhash_size(resources)); zhash_iterator_t itr; zhash_iterator_init(resources, &itr); uint64_t guid = -1; vx_resc_t *resc = NULL; while (zhash_iterator_next(&itr, &guid, &resc)) couts->write_uint64(couts, guid); return couts; }
// Pass in a codes describing which resources are no longer in use. Decrement user counts, // and return a list of all resources whos counts have reached zero, which therefore // should be deleted from the display using a OP_DEALLOC_RESOURCES opcode void vx_resc_manager_buffer_resources(vx_resc_manager_t * mgr, const uint8_t * data, int datalen) { if (0) print_manager(mgr); vx_code_input_stream_t * cins = vx_code_input_stream_create(data, datalen); int code = cins->read_uint32(cins); assert(code == OP_BUFFER_RESOURCES); int worldID = cins->read_uint32(cins); char * name = strdup(cins->read_str(cins)); //freed when cur_resources is eventually removed from the buffer map int count = cins->read_uint32(cins); zhash_t * cur_resources = zhash_create(sizeof(uint64_t), sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals); vx_resc_t * vr = NULL; for (int i = 0; i < count; i++) { uint64_t id = cins->read_uint64(cins); zhash_put(cur_resources, &id, &vr, NULL, NULL); } assert(cins->pos == cins->len); // we've emptied the stream vx_code_input_stream_destroy(cins); // 1 Update our records zhash_t * worldBuffers = NULL; zhash_get(mgr->allLiveSets, &worldID, &worldBuffers); if (worldBuffers == NULL) { worldBuffers = zhash_create(sizeof(char*), sizeof(zhash_t*), zhash_str_hash, zhash_str_equals); zhash_put(mgr->allLiveSets, &worldID, &worldBuffers, NULL, NULL); } zhash_t * old_resources = NULL; char * old_name = NULL; zhash_put(worldBuffers, &name, &cur_resources, &old_name, &old_resources); free(old_name); // 2 Figure out which resources have become unused: if(old_resources != NULL) { removeAll(old_resources, cur_resources); zarray_t * dealloc = zarray_create(sizeof(uint64_t)); // now 'old_resources' contains only the resources that are no longer referenced // iterate through each one, and see if there is a buffer somewhere that references it zhash_iterator_t prev_itr; zhash_iterator_init(old_resources, &prev_itr); uint64_t id = -1; vx_resc_t * vr = NULL; while(zhash_iterator_next(&prev_itr, &id, &vr)) { // Check all worlds zhash_iterator_t world_itr;// gives us all worlds zhash_iterator_init(mgr->allLiveSets, &world_itr); uint32_t wIDl = -1; zhash_t * buffer_map = NULL; while(zhash_iterator_next(&world_itr, &wIDl, &buffer_map)) { zhash_iterator_t buffer_itr; // gives us all buffers zhash_iterator_init(buffer_map, &buffer_itr); char * bName = NULL; zhash_t * resc_map = NULL; while(zhash_iterator_next(&buffer_itr, &bName, &resc_map)) { if (zhash_contains(resc_map, &id)) { goto continue_outer_loop; } } } // If none of the worlds have this resource, we need to flag removal zarray_add(dealloc, &id); continue_outer_loop: ; } // 3 Issue dealloc commands if (zarray_size(dealloc) > 0) { vx_code_output_stream_t * couts = vx_code_output_stream_create(512); couts->write_uint32(couts, OP_DEALLOC_RESOURCES); couts->write_uint32(couts, zarray_size(dealloc)); for (int i = 0; i < zarray_size(dealloc); i++) { uint64_t id = 0; zarray_get(dealloc, i, &id); couts->write_uint64(couts, id); } mgr->disp->send_codes(mgr->disp, couts->data, couts->pos); vx_code_output_stream_destroy(couts); // Also remove the resources we deallocated from remoteResc for (int i = 0; i < zarray_size(dealloc); i++) { uint64_t id = 0; zarray_get(dealloc, i, &id); assert(zhash_contains(mgr->remoteResc, &id)); zhash_remove(mgr->remoteResc, &id, NULL, NULL); } } zarray_destroy(dealloc); zhash_destroy(old_resources); } if (0) { print_manager(mgr); printf("\n\n"); } }
static void menu_action(GtkWidget * menuitem, char * shortname, gpointer userdata) { state_t * state = userdata; if (state->popup_layer_id == 0) return; vx_code_output_stream_t * couts = vx_code_output_stream_create(128); if (verbose) printf("DBG menu: Label %s shortname %s\n", gtk_menu_item_get_label(GTK_MENU_ITEM(menuitem)), shortname); if (!strcmp(shortname,"reset_camera")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_DEFAULTS); } else if (!strcmp(shortname,"ortho")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_PROJ_ORTHO); } else if (!strcmp(shortname,"perspective")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_PROJ_PERSPECTIVE); } else if (!strcmp(shortname,"iface2.0D")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_INTERFACE_MODE); couts->write_float(couts, 2.0f); } else if (!strcmp(shortname,"iface2.5D")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_INTERFACE_MODE); couts->write_float(couts, 2.5f); } else if (!strcmp(shortname,"iface3.0D")) { couts->write_uint32(couts, OP_LAYER_CAMERA); couts->write_uint32(couts, state->popup_layer_id); couts->write_uint32(couts, OP_INTERFACE_MODE); couts->write_float(couts, 3.0f); } else if (!strcmp(shortname,"buffer_manager")) { vx_gtk_buffer_manager_show(state->buffer_manager, 1); } else if (!strcmp(shortname,"scene")) { couts->write_uint32(couts, OP_WINDOW_SCENE); // optional, filled in automatically couts->write_str(couts, "test.vxs"); } else if (!strcmp(shortname,"screen_shot")) { couts->write_uint32(couts, OP_WINDOW_SCREENSHOT); // optional, filled in automatically couts->write_str(couts, "test.png"); } else if (!strcmp(shortname,"record_movie")) { couts->write_uint32(couts, OP_WINDOW_MOVIE_RECORD); // optional, filled in automatically couts->write_str(couts, "test.ppms.gz"); } else if (!strcmp(shortname,"stop_movie")) { couts->write_uint32(couts, OP_WINDOW_MOVIE_STOP); } if (couts->pos != 0) { state->super->send_codes(state->super, couts->data, couts->pos); } /* pthread_mutex_lock(&state->mutex); */ /* pthread_mutex_unlock(&state->mutex); */ vx_code_output_stream_destroy(couts); }
static void display_started(vx_application_t * app, vx_display_t * disp) { state_t * state = app->impl; { vx_layer_t * layer = vx_layer_create(state->world); vx_layer_set_display(layer, disp); //vx_layer_camera_op(layer, OP_PROJ_ORTHO); if (1) { float view_rel[] = {0.0, 0.0, 1.0, 1.0}; vx_layer_set_viewport_rel(layer, view_rel); } if (1) { float eye3[] = {CAM_RADIUS,0,45.0f}; float lookat3[] = {CAM_RADIUS,0,0.0f}; float up3[] = {0,1,0}; vx_layer_camera_lookat(layer, eye3, lookat3, up3, 0); } if (1) { float xy0[] = {-10,-10}; float xy1[] = {10,10}; vx_layer_camera_fit2D(layer, xy0, xy1, 0); } pthread_mutex_lock(&state->mutex); // store a reference to the world and layer that we associate with each vx_display_t zhash_put(state->layers, &disp, &layer, NULL, NULL); pthread_mutex_unlock(&state->mutex); // must redraw after each new display connects draw(state, state->world); } { vx_layer_t * layer = vx_layer_create(state->world2); vx_layer_set_display(layer, disp); vx_layer_camera_op(layer, OP_PROJ_ORTHO); { vx_layer_set_viewport_abs(layer, OP_ANCHOR_TOP_RIGHT, 100, 100); } { float eye3[] = {10.0f,10.0f,100.0f}; float lookat3[] = {10.0f,10.0f,0.0f}; float up3[] = {0,1,0}; vx_layer_camera_lookat(layer, eye3, lookat3, up3, 0); } { float xy0[] = {-10,-10}; float xy1[] = {10,10}; vx_layer_camera_fit2D(layer, xy0, xy1, 0); } vx_layer_add_event_handler(layer, &state->veh); vx_layer_add_camera_listener(layer, &state->cl); /* pthread_mutex_lock(&state->mutex); // store a reference to the world and layer that we associate with each vx_display_t zhash_put(state->layers, &disp, &layer, NULL, NULL); pthread_mutex_unlock(&state->mutex); */ // must redraw after each new display connects draw(state, state->world2); } if (0) { vx_layer_t * layer = vx_layer_create(state->world3); vx_layer_set_display(layer, disp); vx_layer_set_background_color(layer, vx_green); // Manually send the codes for animating a layer (not in // vx_layer_api yet): { float viewport[] = {0, 0.5, 0.5, 0.5}; vx_code_output_stream_t * couts = vx_code_output_stream_create(128); couts->write_uint32(couts, OP_LAYER_VIEWPORT_REL); couts->write_uint32(couts, vx_layer_id(layer)); for (int i = 0; i < 4; i++) couts->write_float(couts, viewport[i]); couts->write_uint32(couts, 2000); // animate over 2 seconds disp->send_codes(disp, couts->data, couts->pos); vx_code_output_stream_destroy(couts); } draw(state, state->world3); // XXX Why is this required to get // the layer to show up? } }