void menu_item_widget::paint_non_client(graphics_context& aGraphicsContext) const { if (iMenu.has_selected_item() && iMenu.selected_item() == (iMenu.find_item(iMenuItem))) { bool openSubMenu = (iMenuItem.type() == i_menu_item::SubMenu && iMenuItem.sub_menu().is_open()); colour background; if (openSubMenu && iMenu.type() == i_menu::MenuBar) { background = app::instance().current_style().colour().dark() ? app::instance().current_style().colour().darker(0x40) : app::instance().current_style().colour().lighter(0x40); if (background.similar_intensity(app::instance().current_style().colour(), 0.05)) { background = app::instance().current_style().selection_colour(); background.set_alpha(0x80); } } else { background = background_colour().light() ? background_colour().darker(0x40) : background_colour().lighter(0x40); background.set_alpha(0x80); } aGraphicsContext.fill_rect(client_rect(), background); } }
void slider_impl::paint(graphics_context& aGraphicsContext) const { scoped_units su(*this, UnitsPixels); rect rectBarBox = bar_box(); colour ink = background_colour().light(0x80) ? background_colour().darker(0x80) : background_colour().lighter(0x80); aGraphicsContext.fill_rounded_rect(rectBarBox, 2.0, ink); rectBarBox.deflate(size{1.0, 1.0}); aGraphicsContext.fill_rounded_rect(rectBarBox, 2.0, ink.mid(background_colour())); rect rectValue = rectBarBox; rectValue.cx = rectValue.width() * normalized_value(); if (normalized_value() > 0.0) aGraphicsContext.fill_rounded_rect(rectValue, 2.0, app::instance().current_style().selection_colour()); rect rectIndicator = indicator_box(); colour indicatorColour = foreground_colour(); if (iDragOffset != boost::none) { if (indicatorColour.light(0x40)) indicatorColour.darken(0x40); else indicatorColour.lighten(0x40); } colour indicatorBorderColour = indicatorColour.darker(0x40); indicatorColour.lighten(0x40); aGraphicsContext.fill_circle(rectIndicator.centre(), rectIndicator.width() / 2.0, indicatorBorderColour); aGraphicsContext.fill_circle(rectIndicator.centre(), rectIndicator.width() / 2.0 - 1.0, indicatorColour); }
void TriangleMeshViewerDisplay::initializeGL() { if (_verbose) { std::cerr << "Double buffering " << (doubleBuffer() ? "ON" : "OFF") << "\n"; std::cerr << "Auto Buffer Swap " << (autoBufferSwap() ? "ON" : "OFF") << "\n"; std::cerr << "Multisampling " << (format().sampleBuffers() ? "ON" : "OFF") << "\n"; } const FloatRGBA bg=background_colour(); glClearColor(bg.r,bg.g,bg.b,1.0f); // Switch depth-buffering on glEnable(GL_DEPTH_TEST); // Basic lighting stuff (set ambient globally rather than in light) GLfloat black_light[]={0.0,0.0,0.0,1.0}; glLightfv(GL_LIGHT0,GL_AMBIENT,black_light); glLightfv(GL_LIGHT0,GL_SPECULAR,black_light); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); // Do smooth shading 'cos colours are specified at vertices glShadeModel(GL_SMOOTH); // Use arrays of data glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); }
//-------------------------------------------------------------- void mainApp::setup(){ // Load data from the specified load_emotions(this->data_path); load_expressions(this->data_path); // Set the window properties ofSetWindowTitle("upload"); ofSetFrameRate(60); ofSetFullscreen(true); ofHideCursor(); // Set the background colour ofColor col; background_colour(col); ofBackground(col.r, col.g, col.b); // Start the twitter search thread to drive the emotion state start_twitter_search(); }
void menu_item_widget::paint(graphics_context& aGraphicsContext) const { if (iMenuItem.type() != i_menu_item::Action || !iMenuItem.action().is_separator()) { widget::paint(aGraphicsContext); if (iMenuItem.type() == i_menu_item::SubMenu && iMenu.type() == i_menu::Popup) { bool openSubMenu = (iMenuItem.type() == i_menu_item::SubMenu && iMenuItem.sub_menu().is_open()); colour ink = openSubMenu ? app::instance().current_style().selection_colour() : background_colour().light() ? background_colour().darker(0x80) : background_colour().lighter(0x80); if (iSubMenuArrow == boost::none || iSubMenuArrow->first != ink) { const uint8_t sArrowImagePattern[9][6] { { 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 1, 1, 1, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, }; iSubMenuArrow = std::make_pair(ink, image{ "neogfx::menu_item_widget::" + ink.to_string(), sArrowImagePattern, { { 0, colour{} },{ 1, ink } } }); } rect rect = client_rect(false); aGraphicsContext.draw_texture( point{ rect.right() - iGap + std::floor((iGap - iSubMenuArrow->second.extents().cx) / 2.0), std::floor((rect.height() - iSubMenuArrow->second.extents().cy) / 2.0) }, iSubMenuArrow->second); } } else { scoped_units su(*this, aGraphicsContext, UnitsPixels); rect line = client_rect(false); ++line.y; line.cy = 1.0; line.x += (iIconSize + iGap * 2.0); line.cx -= (iIconSize + iGap * 3.0); colour ink = background_colour().light() ? background_colour().darker(0x60) : background_colour().lighter(0x60); ink.set_alpha(0x80); aGraphicsContext.fill_rect(line, ink); } }
void TriangleMeshViewerDisplay::paintGL() { assert(isValid()); const FloatRGBA bg=background_colour(); glClearColor(bg.r,bg.g,bg.b,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const float a=parameters->ambient; GLfloat global_ambient[]={a,a,a,1.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT,global_ambient); GLfloat light_diffuse[]={1.0f-a,1.0f-a,1.0f-a,1.0}; glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( camera_position.x,camera_position.y,camera_position.z, camera_lookat.x ,camera_lookat.y ,camera_lookat.z, camera_up.x ,camera_up.y ,camera_up.z ); const XYZ light_direction(parameters->illumination_direction()); GLfloat light_position[]= { light_direction.x, light_direction.y, light_direction.z, 0.0f // w=0 implies directional light }; glLightfv(GL_LIGHT0,GL_POSITION,light_position); glRotatef((180.0/M_PI)*object_tilt,1.0,0.0,0.0); glRotatef((180.0/M_PI)*object_rotation,0.0,0.0,1.0); glPolygonMode(GL_FRONT_AND_BACK,(parameters->wireframe ? GL_LINE : GL_FILL)); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); if (parameters->display_list && gl_display_list_index!=0) { glCallList(gl_display_list_index); } else { bool building_display_list=(parameters->display_list && gl_display_list_index==0); if (building_display_list) { gl_display_list_index=glGenLists(1); assert(gl_display_list_index!=0); glNewList(gl_display_list_index,GL_COMPILE_AND_EXECUTE); if (_verbose) std::cerr << "Building display list..."; } GLfloat default_material_white[3]={1.0f,1.0f,1.0f}; GLfloat default_material_black[3]={0.0f,0.0f,0.0f}; glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,default_material_white); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,default_material_black); for (uint m=0;m<mesh.size();m++) { const TriangleMesh*const it=mesh[m]; if (it==0) continue; // Meshes after the first are rendered twice: first the backfacing polys then the front facing. // This solves the problem of either clouds disappearing when we're under them (with backface culling) // or weird stuff around the periphery when culling is on. // It's quite an expensive solution! const uint passes=(m==0 ? 1 : 2); for (uint pass=0;pass<passes;pass++) { if (passes==2 && pass==0) { glCullFace(GL_FRONT); } else { glCullFace(GL_BACK); } if (it->emissive()==0.0f) { if (m) // Switch blending on for non-emissive meshes after the first { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } // Use "Color Material" mode 'cos everything is the same material.... just change the colour glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); // Point GL at arrays of data glVertexPointer(3,GL_FLOAT,sizeof(Vertex),&(it->vertex(0).position().x)); glNormalPointer(GL_FLOAT,sizeof(Vertex),&(it->vertex(0).normal().x)); // For a second mesh, use alpha (actually could use it for the first mesh but maybe it's more efficient not to). glColorPointer((m==0 ? 3 : 4),GL_UNSIGNED_BYTE,sizeof(Vertex),&(it->vertex(0).colour(0).r)); // Builds on some platforms (ie Ubuntu) seem to get in a mess if you render >1k primitives // (3k vertices). NB This is a problem in the client; not the xserver. // Debian (Sarge or Etch) has no problems with unlimited batches. // Note it's simply the batch size; there doesn't seem to be any problem with the 10Ks of vertices. // Since the limited batch size doesn't seem to hurt working implementations we just use it everywhere. const uint batch_size=1000; // Draw the colour-zero triangles for (uint t=0;t<it->triangles_of_colour0();t+=batch_size) { glDrawRangeElements ( GL_TRIANGLES, 0, it->vertices()-1, 3*std::min(batch_size,static_cast<uint>(it->triangles_of_colour0()-t)), GL_UNSIGNED_INT, &(it->triangle(t).vertex(0)) ); if (_verbose && building_display_list) { std::cerr << "."; } } // Switch to alternate colour and draw the colour-one triangles glColorPointer(3,GL_UNSIGNED_BYTE,sizeof(Vertex),&(it->vertex(0).colour(1).r)); for (uint t=it->triangles_of_colour0();t<it->triangles();t+=batch_size) { glDrawRangeElements ( GL_TRIANGLES, 0, it->vertices()-1, 3*std::min(batch_size,static_cast<uint>(it->triangles()-t)), GL_UNSIGNED_INT, &(it->triangle(t).vertex(0)) ); if (_verbose && building_display_list) { std::cerr << "."; } } glDisable(GL_COLOR_MATERIAL); } else // implies mesh[m]->emissive()>0.0 { // We abuse alpha for emission, so no blending glDisable(GL_BLEND); // If there could be emissive vertices, we need to do things the hard way // using immediate mode. Maybe the display list capture will help. const float k=1.0f/255.0f; const float em=k*( it->emissive()); const float ad=k*(1.0f-it->emissive()); glBegin(GL_TRIANGLES); for (unsigned int t=0;t<it->triangles();t++) { if (_verbose && building_display_list && (t&0x3ff) == 0) { std::cerr << "."; } const uint c=(t<it->triangles_of_colour0() ? 0 : 1); for (uint i=0;i<3;i++) { const uint vn=it->triangle(t).vertex(i); const Vertex& v=it->vertex(vn); GLfloat c_ad[3]; GLfloat c_em[3]; if (v.colour(c).a==0) // Zero alpha used to imply emissive vertex colour { c_ad[0]=v.colour(c).r*ad; c_ad[1]=v.colour(c).g*ad; c_ad[2]=v.colour(c).b*ad; c_em[0]=v.colour(c).r*em; c_em[1]=v.colour(c).g*em; c_em[2]=v.colour(c).b*em; } else { c_ad[0]=v.colour(c).r*k; c_ad[1]=v.colour(c).g*k; c_ad[2]=v.colour(c).b*k; c_em[0]=0.0f; c_em[1]=0.0f; c_em[2]=0.0f; } glNormal3fv(&(v.normal().x)); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,c_ad); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,c_em); glVertex3fv(&(v.position().x)); } } glEnd(); } } } if (building_display_list) { glEndList(); if (_verbose) { std::cerr << "\n...built display list\n"; } } } if (_verbose) check_for_gl_errors(__PRETTY_FUNCTION__); // Get time taken since last frame const uint dt=frame_time.restart(); // Save it in the queue frame_times.push_back(dt); // Keep last 30 frame times while (frame_times.size()>30) frame_times.pop_front(); // Only update frame time a couple of times a second to reduce flashing if (frame_time_reported.elapsed()>500) { //! \todo Frame time calculation is wrong... need -1 correction to number of frames const float average_time=std::accumulate ( frame_times.begin(), frame_times.end(), 0 )/static_cast<float>(frame_times.size()); const float fps=1000.0/average_time; std::ostringstream report; report.setf(std::ios::fixed); report.precision(1); uint n_triangles=0; uint n_vertices=0; for (uint m=0;m<mesh.size();m++) { if (mesh[m]) { n_triangles+=mesh[m]->triangles(); n_vertices+=mesh[m]->vertices(); } } report << "Triangles: " << n_triangles << ", " << "Vertices: " << n_vertices << ", " << "FPS: " << fps << "\n"; _notify.notify(report.str()); frame_time_reported.restart(); } }