1 #include "alg/glsequence.hpp"
9 GlSequence::GlSequence(const Sequence &s)
15 drawColor(0.0, 0.0, 0.0),
16 char_pix_per_world_unit(5.0)
20 GlSequence::GlSequence(const GlSequence &s)
25 seq_height(s.seq_height),
26 drawColor(s.drawColor),
27 char_pix_per_world_unit(s.char_pix_per_world_unit)
31 GlSequence &GlSequence::operator=(const GlSequence & s)
34 const_cast<Sequence &>(seq) = s.seq;
38 seq_height = s.seq_height;
39 drawColor = s.drawColor;
40 assert(char_pix_per_world_unit == s.char_pix_per_world_unit);
45 const Sequence& GlSequence::sequence() const
50 void GlSequence::setX(GLfloat value)
55 GLfloat GlSequence::x() const
60 void GlSequence::setY(GLfloat value)
65 GLfloat GlSequence::y() const
70 GLfloat GlSequence::length() const
75 Sequence::size_type GlSequence::leftbase(GLfloat left) const
82 return (Sequence::size_type)left;
85 Sequence::size_type GlSequence::rightbase(GLfloat right) const
89 if (right > seq.size())
92 return (Sequence::size_type)right;
95 Sequence::const_iterator GlSequence::sequence_begin() const
100 Sequence::const_iterator GlSequence::sequence_end() const
105 Sequence::const_iterator
106 GlSequence::sequence_begin(GLfloat left, GLfloat right) const
108 // the following code will be wrong when sequences can be slid around
109 // so make sure we break.
112 if ( leftbase(left) > seq.size() or left > right )
115 return seq.begin() + leftbase(left);
118 Sequence::const_iterator
119 GlSequence::sequence_end(GLfloat left, GLfloat right) const
121 // the following code will be wrong when sequences can be slid around
122 // so make sure we break.
125 if ( rightbase(right) > seq.size() or left > right )
128 return seq.begin() + rightbase(right);
132 //! set default track draw color
133 void GlSequence::setColor(Color &c)
138 //! get default track draw color
139 Color GlSequence::color()
145 int GlSequence::get_viewport_pixel_width()
148 glGetIntegerv(GL_VIEWPORT, viewport);
149 return viewport[3]; // grab the viewport width
152 bool GlSequence::is_sequence_renderable(GLfloat left,
154 int viewport_width) const
156 // if called with default argument, go get the viewable width
157 if (viewport_width == -1) {
158 viewport_width = get_viewport_pixel_width();
160 GLfloat world_width = right - left;
161 GLfloat pixels_needed = (char_pix_per_world_unit * world_width);
163 // if the number of pixels taken up by rendering the characters
164 // that'd show up in the current ortho width is less than the window
165 // width we can actually draw something
166 return pixels_needed < viewport_width;
170 void GlSequence::draw(GLfloat left, GLfloat right) const
172 if ( not is_sequence_renderable(left, right) ) {
173 draw_track(left, right);
175 draw_sequence(left, right);
177 draw_annotations(left, right);
180 void GlSequence::draw_box(GLfloat left, GLfloat right,
181 GLfloat height, GLfloat z) const
183 GLfloat offset = height/2.0;
184 GLfloat top = seq_y + offset;
185 GLfloat bottom = seq_y - offset;
188 glVertex3f(left, top, z);
189 glVertex3f(left, bottom, z);
190 glVertex3f(right, bottom, z);
191 glVertex3f(right, top, z);
194 void GlSequence::draw_track(GLfloat left, GLfloat right) const
196 glColor3fv(drawColor.get());
197 // draw main sequence track
198 draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0);
201 void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
204 glLineWidth(seq_height);
205 GLfloat annotation_z = seq_z + 1.0;
206 std::list<annot> annots = seq.annotations();
207 for (std::list<annot>::const_iterator annot_itor = annots.begin();
208 annot_itor != annots.end();
209 ++annot_itor, ++annotation_z)
211 glColor3f(0.0, 0.5, 0.0);
212 draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end,
213 seq_height, annotation_z);
218 const int STROKE = 2;
221 typedef struct charpoint {
227 {0, -5, PT}, {2.5, 5, PT}, {5, -5, STROKE},
228 {0.75, -2, PT}, {4.25, -2, END}
232 {2.5, -5, PT}, {2.5,5, STROKE}, {0, 5, PT}, {5, 5, END}
236 {5, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT},
237 {2, -5, PT}, {3, -5, PT}, {5, -3, STROKE},
238 {2.5, -1, PT}, {5, -1,PT}, {5, -5, END}
242 {4.9, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT},
243 {2, -5, PT}, {3, -5, PT}, {5, -3, END}
246 CP Xdata[] = {{ 0, 5, PT}, {5, -5,STROKE},{0,-5,PT},{5, 5, END}};
247 CP Ndata[] = {{ 0, -5, PT}, {0, 5, PT}, {5, -5, PT}, {5, 5, END}};
249 static void drawLetter(CP *l, GLfloat z)
251 glBegin(GL_LINE_STRIP);
255 glVertex3f(l->x, l->y, z);
258 glVertex3f(l->x, l->y, z);
260 glBegin(GL_LINE_STRIP);
263 glVertex3f(l->x, l->y, z);
268 throw runtime_error("data structure failure");
274 void GlSequence::draw_sequence(GLfloat left, GLfloat right) const
276 // FIXME: basically this needs to be greater than the number of annotations
277 const GLfloat z = 30;
279 glColor3fv(drawColor.get());
281 Sequence::const_iterator seq_itor = sequence_begin(left, right);
282 Sequence::const_iterator seq_end = sequence_end(left, right);
283 Sequence::size_type basepair = 0;
285 assert(seq_end - seq_itor >= 0);
286 while(seq_itor != seq_end)
288 assert ( basepair < seq.size() );
290 glTranslatef( leftbase(left) + basepair, seq_y, 1.0 );
291 glScalef(0.1, 1.0, 1.0);
294 drawLetter(Adata, z);
297 drawLetter(Tdata, z);
300 drawLetter(Gdata, z);
303 drawLetter(Cdata, z);
306 drawLetter(Ndata, z);
309 drawLetter(Xdata, z);
318 bool operator==(const GlSequence &left, const GlSequence &right)
320 return ( (left.seq_x == right.seq_x) and
321 (left.seq_y == right.seq_y) and
322 (left.seq_z == right.seq_z) and
323 (left.seq_height == right.seq_height) and
324 (left.drawColor == right.drawColor));