void am_billboard_node::render(am_render_state *rstate) { am_program_param_value *param = &rstate->param_name_map[name].value; if (param->type == AM_PROGRAM_PARAM_CLIENT_TYPE_MAT4) { glm::mat4 *m = (glm::mat4*)¶m->value.m4[0]; glm::mat4 old = *m; float s = 1.0f; if (preserve_uniform_scaling) { s = glm::length(glm::vec3((*m)[0][0], (*m)[1][0], (*m)[2][0])); } (*m)[0][0] = s; (*m)[0][1] = 0.0f; (*m)[0][2] = 0.0f; (*m)[1][0] = 0.0f; (*m)[1][1] = s; (*m)[1][2] = 0.0f; (*m)[2][0] = 0.0f; (*m)[2][1] = 0.0f; (*m)[2][2] = s; render_children(rstate); *m = old; } else { log_ignored_transform(rstate, name, "billboard"); render_children(rstate); } }
void am_rotate_node::render(am_render_state *rstate) { am_program_param_value *param = &rstate->param_name_map[name].value; if (param->type == AM_PROGRAM_PARAM_CLIENT_TYPE_MAT4) { glm::mat4 *m = (glm::mat4*)¶m->value.m4[0]; glm::mat4 old = *m; *m *= glm::mat4_cast(rotation); render_children(rstate); *m = old; } else { log_ignored_transform(rstate, name, "rotate"); render_children(rstate); } }
void am_translate_node::render(am_render_state *rstate) { am_program_param_value *param = &rstate->param_name_map[name].value; if (param->type == AM_PROGRAM_PARAM_CLIENT_TYPE_MAT4) { glm::mat4 *m = (glm::mat4*)¶m->value.m4[0]; glm::vec4 old_column = (*m)[3]; (*m)[3] = (*m)[0] * v[0] + (*m)[1] * v[1] + (*m)[2] * v[2] + (*m)[3]; render_children(rstate); (*m)[3] = old_column; } else { log_ignored_transform(rstate, name, "translate"); render_children(rstate); } }
void Timeline::render(gui::Compositor* compositor, gui::Renderer* renderer, gui::render::CommandList& render_commands) { // TODO: should get this from the style const gemini::Color frame_color = gemini::Color::from_rgba(96, 96, 96, 255); // draw the background render_commands.add_rectangle(geometry[0], geometry[1], geometry[2], geometry[3], gui::render::WhiteTexture, gemini::Color::from_rgba(64, 64, 64, 255)); // add a top rule line to separate this panel render_commands.add_line(geometry[0], geometry[3], gemini::Color::from_rgba(0, 0, 0, 255), 1.0f); // center the individual frames Rect block; block.set(left_margin + 2.0f, 1.0, (frame_width_pixels - 4.0f), size.height - 2.0f); for (size_t index = 0; index < total_frames; ++index) { // draw frame ticks until we reach the end of the panel if (block.origin.x + block.size.width >= (origin.x + size.width)) { break; } Point points[4]; points[0] = transform_point(local_transform, block.origin); points[1] = transform_point(local_transform, Point(block.origin.x, block.origin.y + block.size.height)); points[2] = transform_point(local_transform, Point(block.origin.x + block.size.width, block.origin.y + block.size.height)); points[3] = transform_point(local_transform, Point(block.origin.x + block.size.width, block.origin.y)); render_commands.add_rectangle(points[0], points[1], points[2], points[3], gui::render::WhiteTexture, frame_color); block.origin.x += frame_width_pixels; } render_children(compositor, renderer, render_commands); } // render
void am_lookat_node::render(am_render_state *rstate) { am_program_param_value *param = &rstate->param_name_map[name].value; am_program_param_value old_val = *param; param->type = AM_PROGRAM_PARAM_CLIENT_TYPE_MAT4; memcpy(¶m->value.m4[0], glm::value_ptr(glm::lookAt(eye, center, up)), 16 * sizeof(float)); render_children(rstate); *param = old_val; }
void Label::render(Compositor* compositor, Renderer* renderer, gui::render::CommandList& render_commands) { render_commands.add_rectangle( geometry[0], geometry[1], geometry[2], geometry[3], render::WhiteTexture, background_color ); if (text.empty()) return; const int32_t upper_bound = (LABEL_TOP_MARGIN - font_height); const int32_t lower_bound = (LABEL_TOP_MARGIN + size.height + font_height); // draw cache items float item_offset = 0.0f; for (const font_cache_entry& item : font_cache) { Rect current_rect; current_rect.origin = item.origin - scroll_offset; current_rect.size = size; // Don't draw text above the panel. This shouldn't overlap // by more than a single line -- clipping will take care of it. if (current_rect.origin.y < upper_bound) continue; // Don't draw text below the panel. This shouldn't overlap // by more than a single line -- clipping will take care of it. if ((current_rect.origin.y+item.height) > (lower_bound + item.height)) break; current_rect.origin = transform_point(get_transform(0), current_rect.origin); render_commands.add_font(font_handle, &text[item.start], item.length, current_rect, foreground_color); } //const bool content_larger_than_bounds = content_bounds.height() > size.height; //if (content_larger_than_bounds) //{ // Point start(origin.x, origin.y + content_bounds.height()); // Point end(origin.x + size.width, origin.y + content_bounds.height()); // render_commands.add_line(start, end, gemini::Color::from_rgba(0, 255, 0, 255)); //} render_children(compositor, renderer, render_commands); }
void am_color_mask_node::render(am_render_state *rstate) { am_color_mask_state old = rstate->active_color_mask_state; rstate->active_color_mask_state.set(r, g, b, a); render_children(rstate); rstate->active_color_mask_state.restore(&old); }
void am_viewport_node::render(am_render_state *rstate) { am_viewport_state old = rstate->active_viewport_state; rstate->active_viewport_state.set(x, y, w, h); render_children(rstate); rstate->active_viewport_state.restore(&old); }
void render_child(component *c) { if (!c) return; render_child(c->next); render_gui(c); render_children(c); }