void a3d_widget_scrollbar(a3d_widget_t* self, a3d_vec4f_t* color_scroll0, a3d_vec4f_t* color_scroll1) { assert(self); assert(color_scroll0); assert(color_scroll1); self->scroll_bar = 1; a3d_vec4f_copy(color_scroll0, &self->color_scroll0); a3d_vec4f_copy(color_scroll1, &self->color_scroll1); }
void a3d_widget_twoTone(a3d_widget_t* self, a3d_vec4f_t* color_fill2) { assert(self); assert(color_fill2); a3d_vec4f_copy(color_fill2, &self->color_fill2); }
void a3d_mat4f_mulv(const a3d_mat4f_t* self, a3d_vec4f_t* v) { assert(self); assert(v); LOGD("debug"); a3d_vec4f_t copy; a3d_mat4f_mulv_copy(self, v, ©); a3d_vec4f_copy(©, v); }
gear_t* gear_new(const a3d_vec4f_t* color, float inner_radius, float outer_radius, float width, int teeth, float tooth_depth) { LOGD("debug r=%f, g=%f, b=%f, a=%f", color->x, color->y, color->z, color->w); LOGD("debug inner_radius=%f, outer_radius=%f, width=%f", inner_radius, outer_radius, width); LOGD("debug teeth=%i, tooth_depth=%f", teeth, tooth_depth); gear_t* self = (gear_t*) malloc(sizeof(gear_t)); if(self == NULL) { LOGE("malloc failed"); return NULL; } // initialize gear a3d_vec4f_copy(color, &self->color); glGenBuffers(1, &self->front_vid); glGenBuffers(1, &self->front_teeth_vid); glGenBuffers(1, &self->back_vid); glGenBuffers(1, &self->back_teeth_vid); glGenBuffers(1, &self->outward_vid); glGenBuffers(1, &self->outward_nid); glGenBuffers(1, &self->cylinder_vid); glGenBuffers(1, &self->cylinder_nid); if(gear_generate(self, inner_radius, outer_radius, width, teeth, tooth_depth) == 0) { LOGE("gear_generate failed"); goto fail_gear_generate; } // initialize shader state if(gear_load_shaders(self) == 0) goto fail_shader; // success return self; // failure fail_shader: // gear_generate only fills in buffers fail_gear_generate: glDeleteBuffers(1, &self->cylinder_nid); glDeleteBuffers(1, &self->cylinder_vid); glDeleteBuffers(1, &self->outward_nid); glDeleteBuffers(1, &self->outward_vid); glDeleteBuffers(1, &self->back_teeth_vid); glDeleteBuffers(1, &self->back_vid); glDeleteBuffers(1, &self->front_teeth_vid); glDeleteBuffers(1, &self->front_vid); free(self); return NULL; }
a3d_textbox_t* a3d_textbox_new(a3d_screen_t* screen, int wsize, int orientation, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, int text_anchor, int text_wrapx, int text_style_border, int text_style_line, int text_style_text, a3d_vec4f_t* text_color_fill, a3d_vec4f_t* text_color_line, a3d_vec4f_t* text_color_text, int text_max_len) { assert(screen); assert(color_fill); assert(color_line); assert(text_color_fill); assert(text_color_line); assert(text_color_text); LOGD("debug wsize=%i, orientation=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, orientation, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); LOGD("text_anchor=%i, text_style_border=%i, text_style_line=%i, text_style_text=%i", text_anchor, text_style_border, text_style_line, text_style_text); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); LOGD("debug color_text: r=%f, g=%f, b=%f, a=%f", color_text->r, color_text->g, color_text->b, color_text->a); LOGD("debug text_max_len=%i", text_max_len); if(wsize == 0) { wsize = sizeof(a3d_textbox_t); } a3d_widget_reflow_fn reflow_fn = a3d_textbox_reflow; if(wrapx == A3D_WIDGET_WRAP_SHRINK) { reflow_fn = NULL; } a3d_textbox_t* self; self = (a3d_textbox_t*) a3d_listbox_new(screen, wsize, orientation, anchor, wrapx, wrapy, stretch_mode, stretch_factor, style_border, style_line, color_fill, color_line, reflow_fn, NULL); if(self == NULL) { return NULL; } self->strings = a3d_list_new(); if(self->strings == NULL) { goto fail_strings; } self->dirty = 1; self->last_w = 0.0f; self->last_h = 0.0f; self->anchor = text_anchor; self->text_wrapx = text_wrapx; self->style_border = text_style_border; self->style_line = text_style_line; self->style_text = text_style_text; self->max_len = text_max_len; a3d_vec4f_copy(text_color_fill, &self->color_fill); a3d_vec4f_copy(text_color_line, &self->color_line); a3d_vec4f_copy(text_color_text, &self->color_text); // success return self; // failure fail_strings: a3d_listbox_delete((a3d_listbox_t**) &self); return NULL; }
static void a3d_hline_draw(a3d_widget_t* widget) { assert(widget); a3d_hline_t* self = (a3d_hline_t*) widget; // clip separator to border a3d_rect4f_t rect_border_clip; if(a3d_rect4f_intersect(&widget->rect_border, &widget->rect_clip, &rect_border_clip) == 0) { return; } // clip separator float top = widget->rect_clip.t; float h2 = widget->rect_clip.h/2.0f; a3d_rect4f_t line = { .t = top + h2, .l = rect_border_clip.l, .w = rect_border_clip.w, .h = 0.0f }; // draw the separator a3d_screen_t* screen = widget->screen; a3d_vec4f_t* c = &self->color; float alpha = widget->fade*c->a; if(alpha > 0.0f) { glDisable(GL_SCISSOR_TEST); if(alpha < 1.0f) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glUseProgram(screen->prog); glEnableVertexAttribArray(screen->attr_coords); int line_style = A3D_WIDGET_LINE_MEDIUM; if(self->style == A3D_HLINE_STYLE_SMALL) { line_style = A3D_WIDGET_LINE_SMALL; } else if(self->style == A3D_HLINE_STYLE_LARGE) { line_style = A3D_WIDGET_LINE_LARGE; } float lw = a3d_screen_layoutLine(screen, line_style); glLineWidth(lw); a3d_rect4f_t* r = &line; glBindBuffer(GL_ARRAY_BUFFER, screen->id_coords2); glVertexAttribPointer(screen->attr_coords, 2, GL_FLOAT, GL_FALSE, 0, 0); a3d_mat4f_t mvp; a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f); glUniformMatrix4fv(screen->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); glUniform4f(screen->unif_rect, r->t, r->l, r->w, r->h); glUniform4f(screen->unif_color, c->r, c->g, c->b, alpha); glDrawArrays(GL_LINES, 0, 2); glLineWidth(1.0f); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(screen->attr_coords); glUseProgram(0); if(alpha < 1.0f) { glDisable(GL_BLEND); } glEnable(GL_SCISSOR_TEST); } } /*********************************************************** * public * ***********************************************************/ a3d_hline_t* a3d_hline_new(a3d_screen_t* screen, int wsize, int anchor, int style_line, a3d_vec4f_t* color_line, int max_len) { assert(screen); assert(color_line); a3d_vec4f_t clear = { .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 0.0f }; if(wsize == 0) { wsize = sizeof(a3d_hline_t); } a3d_hline_t* self = (a3d_hline_t*) a3d_widget_new(screen, wsize, anchor, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_STRETCH_NA, 1.0f, A3D_WIDGET_BORDER_NONE, A3D_WIDGET_LINE_NONE, &clear, &clear, NULL, a3d_hline_size, NULL, NULL, NULL, a3d_hline_draw, NULL, NULL); if(self == NULL) { return NULL; } self->wrapx = A3D_HLINE_WRAP_SHRINK; self->max_len = max_len; self->style = style_line; a3d_vec4f_copy(color_line, &self->color); return self; } void a3d_hline_delete(a3d_hline_t** _self) { assert(_self); a3d_hline_t* self = *_self; if(self) { a3d_widget_delete((a3d_widget_t**) _self); } }
a3d_widget_t* a3d_widget_new(struct a3d_screen_s* screen, int wsize, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_line, a3d_vec4f_t* color_fill, a3d_widget_reflow_fn reflow_fn, a3d_widget_size_fn size_fn, a3d_widget_click_fn click_fn, a3d_widget_layout_fn layout_fn, a3d_widget_drag_fn drag_fn, a3d_widget_draw_fn draw_fn, a3d_widget_fade_fn fade_fn, a3d_widget_refresh_fn refresh_fn) { // reflow_fn, size_fn, click_fn, layout_fn, refresh_fn and draw_fn may be NULL assert(screen); assert(color_line); assert(color_fill); LOGD("debug wsize=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); if(wsize == 0) { wsize = sizeof(a3d_widget_t); } a3d_widget_t* self = (a3d_widget_t*) malloc(wsize); if(self == NULL) { LOGE("malloc failed"); return NULL; } self->screen = screen; self->priv = NULL; self->drag_dx = 0.0f; self->drag_dy = 0.0f; self->anchor = anchor; self->wrapx = wrapx; self->wrapy = wrapy; self->stretch_mode = stretch_mode; self->stretch_factor = stretch_factor; self->style_border = style_border; self->style_line = style_line; self->scroll_bar = 0; self->reflow_fn = reflow_fn; self->size_fn = size_fn; self->click_fn = click_fn; self->keyPress_fn = NULL; self->layout_fn = layout_fn; self->drag_fn = drag_fn; self->refresh_fn = refresh_fn; self->draw_fn = draw_fn; self->fade_fn = fade_fn; self->fade = 0.0f; self->sound_fx = 1; a3d_rect4f_init(&self->rect_draw, 0.0f, 0.0f, 0.0f, 0.0f); a3d_rect4f_init(&self->rect_clip, 0.0f, 0.0f, 0.0f, 0.0f); a3d_rect4f_init(&self->rect_border, 0.0f, 0.0f, 0.0f, 0.0f); a3d_vec4f_copy(color_line, &self->color_line); a3d_vec4f_copy(color_fill, &self->color_fill); a3d_vec4f_load(&self->color_fill2, 0.0f, 0.0f, 0.0f, 0.0f); a3d_vec4f_load(&self->color_scroll0, 0.0f, 0.0f, 0.0f, 0.0f); a3d_vec4f_load(&self->color_scroll1, 0.0f, 0.0f, 0.0f, 0.0f); self->tone_y2 = 0.0f; glGenBuffers(1, &self->id_vtx_rect); glGenBuffers(1, &self->id_vtx_line); glGenBuffers(1, &self->scroll_id_vtx_rect); if(a3d_widget_shaders(self) == 0) { goto fail_shaders; } // success return self; // failure fail_shaders: free(self); return NULL; }
a3d_sprite_t* a3d_sprite_new(a3d_screen_t* screen, int wsize, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, a3d_vec4f_t* color_sprite, a3d_widget_click_fn click_fn, a3d_widget_refresh_fn refresh_fn, int count) { // click_fn and refresh_fn may be NULL assert(screen); assert(color_fill); assert(color_line); assert(color_sprite); LOGD("debug wsize=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); LOGD("debug color_sprite: r=%f, g=%f, b=%f, a=%f", color_sprite->r, color_sprite->g, color_sprite->b, color_sprite->a); LOGD("debug count=%i", count); if(count <= 0) { LOGE("invalid count=%i", count); return NULL; } if((wrapx == A3D_WIDGET_WRAP_SHRINK) || (wrapy == A3D_WIDGET_WRAP_SHRINK)) { LOGE("invalid wrapx=%i, wrapy=%i", wrapx, wrapy); return NULL; } if(wsize == 0) { wsize = sizeof(a3d_sprite_t); } a3d_sprite_t* self = (a3d_sprite_t*) a3d_widget_new(screen, wsize, anchor, wrapx, wrapy, stretch_mode, stretch_factor, style_border, style_line, color_line, color_fill, NULL, NULL, click_fn, NULL, NULL, a3d_sprite_draw, NULL, refresh_fn); if(self == NULL) { return NULL; } self->id_tex = (GLuint*) calloc(count, sizeof(GLuint)); if(self->id_tex == NULL) { LOGE("malloc failed"); goto fail_tex; } self->index = 0; self->count = count; self->theta = 0.0f; a3d_vec4f_copy(color_sprite, &self->color); glGenBuffers(1, &self->id_vertex); glGenBuffers(1, &self->id_coords); int vertex_size = 24; // 2*3*xyzw int coords_size = 12; // 2*3*uv glBindBuffer(GL_ARRAY_BUFFER, self->id_vertex); glBufferData(GL_ARRAY_BUFFER, vertex_size*sizeof(GLfloat), VERTEX, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, self->id_coords); glBufferData(GL_ARRAY_BUFFER, coords_size*sizeof(GLfloat), COORDS, GL_STATIC_DRAW); // success return self; // failure fail_tex: a3d_widget_delete((a3d_widget_t**) &self); return NULL; }