From: Diane Trout Date: Wed, 29 Mar 2006 08:24:11 +0000 (+0000) Subject: make annotations big enough to show up X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=0bc5dcb7c0d698d21c0ea7c74e55d5df8fbf52c0 make annotations big enough to show up fixes ticket:69 (or at least improves it) Annotations could disapper if the width of the annotation was less than one pixel. This patch forces it to be at least one pixel. However it appears that the scrollbar is moving things in non-integral pixel sizes so the annotations end up flashing as they render over different fractions of two pixels. --- diff --git a/alg/glsequence.cpp b/alg/glsequence.cpp index e38da9d..893e6fc 100644 --- a/alg/glsequence.cpp +++ b/alg/glsequence.cpp @@ -149,21 +149,33 @@ Color GlSequence::color() } -int GlSequence::get_viewport_pixel_width() +int GlSequence::get_viewport_width_in_pixels() { GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); return viewport[3]; // grab the viewport width } +GLfloat GlSequence::get_pixel_width(GLfloat left, GLfloat right) const +{ + return get_pixel_width(left, right, get_viewport_width_in_pixels()); +} + +GLfloat +GlSequence::get_pixel_width(GLfloat left, GLfloat right, int vp_width) const +{ + return round((right-left)/vp_width); +} + +bool GlSequence::is_sequence_renderable(GLfloat left, GLfloat right) const +{ + return is_sequence_renderable(left, right, get_viewport_width_in_pixels()); +} + bool GlSequence::is_sequence_renderable(GLfloat left, GLfloat right, int viewport_width) const { - // if called with default argument, go get the viewable width - if (viewport_width == -1) { - viewport_width = get_viewport_pixel_width(); - } GLfloat world_width = right - left; GLfloat pixels_needed = (char_pix_per_world_unit * world_width); @@ -184,13 +196,19 @@ void GlSequence::draw(GLfloat left, GLfloat right) const draw_annotations(left, right); } -void GlSequence::draw_box(GLfloat left, GLfloat right, +void GlSequence::draw_box(GLfloat world_left, GLfloat world_right, + GLfloat left, GLfloat right, GLfloat height, GLfloat z) const { + GLfloat pixel_width = get_pixel_width(world_left, world_right); GLfloat offset = height/2.0; GLfloat top = seq_y + offset; GLfloat bottom = seq_y - offset; - + + // make our box be at least 1 pixel + if ((right-left) < pixel_width) { + right = left + pixel_width; + } glBegin(GL_QUADS); glVertex3f(left, top, z); glVertex3f(left, bottom, z); @@ -199,34 +217,34 @@ void GlSequence::draw_box(GLfloat left, GLfloat right, glEnd(); } -void GlSequence::draw_track(GLfloat , GLfloat ) const +void GlSequence::draw_track(GLfloat left, GLfloat right) const { glColor3fv(drawColor.get()); // draw main sequence track - draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0); + draw_box(left, right, seq_x, seq_x+seq.size(), seq_height, 0.0); } -void GlSequence::draw_annotations(GLfloat , GLfloat ) const +void GlSequence::draw_annotations(GLfloat left, GLfloat right) const { // draw annotations - GLfloat annotation_z = seq_z + 1.0; + GLfloat annotation_z = seq_z + 10.0; const std::list& annots = seq.annotations(); const std::list& motifs = seq.motifs(); for (std::list::const_iterator annot_itor = annots.begin(); annot_itor != annots.end(); - ++annot_itor, ++annotation_z) + ++annot_itor) { - glColor3f(0.0, 0.5, 0.0); - draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end, + glColor3f(0.0, 0.8, 0.0); + draw_box(left, right, seq_x+annot_itor->start, seq_x+annot_itor->end, seq_height, annotation_z); } // if motifs? for (std::list::const_iterator motifs_itor = motifs.begin(); motifs_itor != motifs.end(); - ++motifs_itor, ++annotation_z) + ++motifs_itor) { glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get()); - draw_box(seq_x+motifs_itor->start, seq_x+motifs_itor->end, + draw_box(left, right, seq_x+motifs_itor->start, seq_x+motifs_itor->end, seq_height, annotation_z); } diff --git a/alg/glsequence.hpp b/alg/glsequence.hpp index 0133230..b9a84f9 100644 --- a/alg/glsequence.hpp +++ b/alg/glsequence.hpp @@ -57,6 +57,13 @@ public: void setColor(Color &); Color color(); + //! how big is a pixel in world coordinats + GLfloat get_pixel_width(GLfloat, GLfloat) const; + //! how big is a pixel in world coordinats (specifying viewport size) + GLfloat get_pixel_width(GLfloat, GLfloat, int) const; + + //! are we close enough that it would make sense to view the base pairs? + bool is_sequence_renderable(GLfloat left, GLfloat right) const; //! are we close enough that it would make sense to view the base pairs? /*! though we don't actually check to see if there's sequence in our * view, just that there's enough pixels to render something if @@ -66,9 +73,7 @@ public: * coordinates * \param[in] pixel_width allow setting the current viewport pixel width */ - bool is_sequence_renderable(GLfloat left, - GLfloat right, - int pixel_width=-1) const; + bool is_sequence_renderable(GLfloat, GLfloat, int) const; friend bool operator==(const GlSequence &left, const GlSequence &right); @@ -83,9 +88,9 @@ protected: const GLfloat char_pix_per_world_unit; //! Return the pixel width of the opengl viewport. - static int get_viewport_pixel_width(); + static int get_viewport_width_in_pixels(); //! draw a from left to right +/- height/2 - void draw_box(GLfloat left, GLfloat right, GLfloat height, GLfloat z) const; + void draw_box(GLfloat world_left, GLfloat world_right, GLfloat left, GLfloat right, GLfloat height, GLfloat z) const; //! draw sequence as a bar void draw_track(GLfloat, GLfloat) const; void draw_annotations(GLfloat, GLfloat) const; diff --git a/alg/test/test_glsequence.cpp b/alg/test/test_glsequence.cpp index 9c78530..bb0cb49 100644 --- a/alg/test/test_glsequence.cpp +++ b/alg/test/test_glsequence.cpp @@ -1,4 +1,5 @@ #include +#include #include @@ -53,6 +54,9 @@ BOOST_AUTO_TEST_CASE( glsequence_renderable ) BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false ); // way fewer basepairs than viewport pixel width BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true); + + BOOST_CHECK_CLOSE((double)s.get_pixel_width(0, 100, 100), 1.0, 1e-6); + BOOST_CHECK_CLOSE((double)s.get_pixel_width(0, 1000, 100), 10.0, 1e-6); } BOOST_AUTO_TEST_CASE( glsequence_sequence )