static void a3d_sprite_draw(a3d_widget_t* widget) { assert(widget); LOGD("debug"); a3d_sprite_t* self = (a3d_sprite_t*) widget; a3d_screen_t* screen = widget->screen; a3d_mat4f_t mvp; // draw sprite a3d_vec4f_t* c = &self->color; float alpha = widget->fade*c->a; if(alpha > 0.0f) { float w = 0.0f; float h = 0.0f; float x = widget->rect_draw.l; float y = widget->rect_draw.t; float ww = widget->rect_draw.w; float hh = widget->rect_draw.h; a3d_screen_sizef(screen, &w, &h); a3d_mat4f_ortho(&mvp, 1, 0.0f, w, h, 0.0f, 0.0f, 2.0f); a3d_mat4f_translate(&mvp, 0, x + ww/2.0f, y + hh/2.0f, -1.0f); a3d_mat4f_scale(&mvp, 0, ww, hh, 1.0f); a3d_mat4f_rotate(&mvp, 0, self->theta, 0.0f, 0.0f, 1.0f); a3d_spriteShader_t* shader = a3d_screen_spriteShader(screen); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(shader->prog); glEnableVertexAttribArray(shader->attr_vertex); glEnableVertexAttribArray(shader->attr_coords); glBindTexture(GL_TEXTURE_2D, self->id_tex[self->index]); glBindBuffer(GL_ARRAY_BUFFER, self->id_vertex); glVertexAttribPointer(shader->attr_vertex, 4, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, self->id_coords); glVertexAttribPointer(shader->attr_coords, 2, GL_FLOAT, GL_FALSE, 0, 0); glUniform4f(shader->unif_color, c->r, c->g, c->b, alpha); glUniformMatrix4fv(shader->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); glUniform1i(shader->unif_sampler, 0); glDrawArrays(GL_TRIANGLES, 0, 6); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(shader->attr_coords); glDisableVertexAttribArray(shader->attr_vertex); glUseProgram(0); glDisable(GL_BLEND); } }
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); } }
void a3d_widget_draw(a3d_widget_t* self) { assert(self); LOGD("debug"); if(self->fade == 0.0f) { return; } a3d_rect4f_t rect_border_clip; if(a3d_rect4f_intersect(&self->rect_border, &self->rect_clip, &rect_border_clip) == 0) { return; } // draw the fill a3d_screen_t* screen = self->screen; a3d_vec4f_t* c = &self->color_fill; float alpha = self->fade*c->a; if(alpha > 0.0f) { a3d_screen_scissor(screen, &rect_border_clip); if(alpha < 1.0f) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } a3d_mat4f_t mvp; glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_rect); a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f); if(self->tone_y2 == 0.0f) { glEnableVertexAttribArray(self->attr_vertex); glVertexAttribPointer(self->attr_vertex, 2, GL_FLOAT, GL_FALSE, 0, 0); glUseProgram(self->prog); glUniform4f(self->unif_color, c->r, c->g, c->b, alpha); glUniformMatrix4fv(self->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); } else { a3d_vec4f_t* c2 = &self->color_fill2; float alpha2 = self->fade*c2->a; glEnableVertexAttribArray(self->attr_vertex2); glVertexAttribPointer(self->attr_vertex2, 2, GL_FLOAT, GL_FALSE, 0, 0); glUseProgram(self->prog2); glUniform4f(self->unif_color2a, c->r, c->g, c->b, alpha); glUniform4f(self->unif_color2b, c2->r, c2->g, c2->b, alpha2); glUniform1f(self->unif_y2, self->tone_y2); glUniformMatrix4fv(self->unif_mvp2, 1, GL_FALSE, (GLfloat*) &mvp); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4*A3D_WIDGET_BEZEL); glBindBuffer(GL_ARRAY_BUFFER, 0); if(self->tone_y2 == 0.0f) { glDisableVertexAttribArray(self->attr_vertex); } else { glDisableVertexAttribArray(self->attr_vertex2); } glUseProgram(0); if(alpha < 1.0f) { glDisable(GL_BLEND); } } // draw the contents a3d_rect4f_t rect_draw_clip; if(a3d_rect4f_intersect(&self->rect_draw, &self->rect_clip, &rect_draw_clip)) { a3d_widget_draw_fn draw_fn = self->draw_fn; if(draw_fn) { a3d_screen_scissor(screen, &rect_draw_clip); (*draw_fn)(self); } // draw the scroll bar float s = rect_draw_clip.h/self->rect_draw.h; if(self->scroll_bar && (s < 1.0f)) { // clamp the start/end points float a = -self->drag_dy/self->rect_draw.h; float b = a + s; if(a < 0.0f) { a = 0.0f; } else if(a > 1.0f) { a = 1.0f; } if(b < 0.0f) { b = 0.0f; } else if(b > 1.0f) { b = 1.0f; } a3d_vec4f_t* c0 = &self->color_scroll0; a3d_vec4f_t* c1 = &self->color_scroll1; a3d_screen_scissor(screen, &rect_border_clip); if((c0->a < 1.0f) || (c1->a < 1.0f)) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } a3d_mat4f_t mvp; glBindBuffer(GL_ARRAY_BUFFER, self->scroll_id_vtx_rect); a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f); glEnableVertexAttribArray(self->scroll_attr_vertex); glVertexAttribPointer(self->scroll_attr_vertex, 4, GL_FLOAT, GL_FALSE, 0, 0); glUseProgram(self->scroll_prog); glUniform4f(self->scroll_unif_color0, c0->r, c0->g, c0->b, c0->a); glUniform4f(self->scroll_unif_color1, c1->r, c1->g, c1->b, c1->a); glUniform1f(self->scroll_unif_a, a); glUniform1f(self->scroll_unif_b, b); glUniformMatrix4fv(self->scroll_unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(self->scroll_attr_vertex); glUseProgram(0); if((c0->a < 1.0f) || (c1->a < 1.0f)) { glDisable(GL_BLEND); } } } // draw the border c = &self->color_line; alpha = self->fade*c->a; if((alpha > 0.0f) && (self->style_line != A3D_WIDGET_LINE_NONE)) { glDisable(GL_SCISSOR_TEST); if(alpha < 1.0f) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glUseProgram(self->prog); glEnableVertexAttribArray(self->attr_vertex); // draw rounded line glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_line); glVertexAttribPointer(self->attr_vertex, 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(self->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); glUniform4f(self->unif_color, c->r, c->g, c->b, alpha); glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*(4*A3D_WIDGET_BEZEL + 1)); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(self->attr_vertex); glUseProgram(0); if(alpha < 1.0f) { glDisable(GL_BLEND); } glEnable(GL_SCISSOR_TEST); } }