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.
-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
}
{
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
{
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);
GLfloat world_width = right - left;
GLfloat pixels_needed = (char_pix_per_world_unit * world_width);
draw_annotations(left, right);
}
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 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;
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);
glBegin(GL_QUADS);
glVertex3f(left, top, z);
glVertex3f(left, bottom, z);
-void GlSequence::draw_track(GLfloat , GLfloat ) const
+void GlSequence::draw_track(GLfloat left, GLfloat right) const
{
glColor3fv(drawColor.get());
// draw main sequence track
{
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
- GLfloat annotation_z = seq_z + 1.0;
+ GLfloat annotation_z = seq_z + 10.0;
const std::list<annot>& annots = seq.annotations();
const std::list<motif>& motifs = seq.motifs();
for (std::list<annot>::const_iterator annot_itor = annots.begin();
annot_itor != annots.end();
const std::list<annot>& annots = seq.annotations();
const std::list<motif>& motifs = seq.motifs();
for (std::list<annot>::const_iterator annot_itor = annots.begin();
annot_itor != annots.end();
- ++annot_itor, ++annotation_z)
- 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<motif>::const_iterator motifs_itor = motifs.begin();
motifs_itor != motifs.end();
seq_height, annotation_z);
}
// if motifs?
for (std::list<motif>::const_iterator motifs_itor = motifs.begin();
motifs_itor != motifs.end();
- ++motifs_itor, ++annotation_z)
{
glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get());
{
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);
}
seq_height, annotation_z);
}
void setColor(Color &);
Color color();
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
//! 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
* coordinates
* \param[in] pixel_width allow setting the current viewport pixel width
*/
* 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);
friend bool operator==(const GlSequence &left, const GlSequence &right);
const GLfloat char_pix_per_world_unit;
//! Return the pixel width of the opengl viewport.
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
//! 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;
//! draw sequence as a bar
void draw_track(GLfloat, GLfloat) const;
void draw_annotations(GLfloat, GLfloat) const;
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
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_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 )
}
BOOST_AUTO_TEST_CASE( glsequence_sequence )