/** * @brief Draws a circle in a rectangle. * * @param cx X position of the center in screen coordinates.. * @param cy Y position of the center in screen coordinates. * @param r Radius of the circle. * @param rx X position of the rectangle limiting the circle in screen coords. * @param ry Y position of the rectangle limiting the circle in screen coords. * @param rw Width of the limiting rectangle. * @param rh Height of the limiting rectangle. * @param c Colour to use. */ void gl_drawCircleInRect( const double cx, const double cy, const double r, const double rx, const double ry, const double rw, const double rh, const glColour *c, int filled ) { int i, j; double rxw,ryh, x,y,p, w,h, tx,ty, tw,th, r2; GLfloat vertex[2*OPENGL_RENDER_VBO_SIZE], col[4*OPENGL_RENDER_VBO_SIZE]; rxw = rx+rw; ryh = ry+rh; /* is offscreen? */ if ((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh)) return; /* can be drawn normally? */ else if ((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) { gl_drawCircle( cx, cy, r, c, filled ); return; } /* Case if filled. */ if (filled) { r2 = 2.*r; /* Clamp bottom left. */ x = CLAMP( rx, rxw, cx-r ); y = CLAMP( ry, ryh, cy-r ); /* Clamp width. */ w = CLAMP( rx, rxw, cx+r ) - x; h = CLAMP( ry, ryh, cy+r ) - y; /* Calculate texture bottom left. */ tx = x - (cx-r); tx *= gl_circle->srw / r2; /* Transform to unitary coordinates. */ ty = y - (cy-r); ty *= gl_circle->srh / r2; /* Calculate dimensions of texture. */ tw = w/r2 * gl_circle->srw; th = h/r2 * gl_circle->srh; /* Render. */ gl_blitTexture( gl_circle, x, y, w, h, tx, ty, tw, th, c ); return; } /* Starting parameters. */ i = 0; x = 0; y = r; p = (5. - (r*4.)) / 4.; PIXEL( cx, cy+y ); PIXEL( cx, cy-y ); PIXEL( cx+y, cy ); PIXEL( cx-y, cy ); while (x<y) { x++; if (p < 0) p += 2*(double)(x)+1; else p += 2*(double)(x-(--y))+1; if (x==0) { PIXEL( cx, cy+y ); PIXEL( cx, cy-y ); PIXEL( cx+y, cy ); PIXEL( cx-y, cy ); } else if (x==y) { PIXEL( cx+x, cy+y ); PIXEL( cx-x, cy+y ); PIXEL( cx+x, cy-y ); PIXEL( cx-x, cy-y ); } else if (x<y) { PIXEL( cx+x, cy+y ); PIXEL( cx-x, cy+y ); PIXEL( cx+x, cy-y ); PIXEL( cx-x, cy-y ); PIXEL( cx+y, cy+x ); PIXEL( cx-y, cy+x ); PIXEL( cx+y, cy-x ); PIXEL( cx-y, cy-x ); } } gl_vboSubData( gl_renderVBO, 0, i*2*sizeof(GLfloat), vertex ); gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); /* Set up the colour. */ for (j=0; j<i; j++) { col[4*j+0] = c->r; col[4*j+1] = c->g; col[4*j+2] = c->b; col[4*j+3] = c->a; } gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset, i*4*sizeof(GLfloat), col ); gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY, gl_renderVBOcolOffset, 4, GL_FLOAT, 0 ); /* Draw. */ glDrawArrays( GL_POINTS, 0, i ); /* Clear state. */ gl_vboDeactivate(); }
/** * @brief Draws a circle in a rectangle. * * @param cx X position of the center in screen coordinates.. * @param cy Y position of the center in screen coordinates. * @param r Radius of the circle. * @param rx X position of the rectangle limiting the circle in screen coords. * @param ry Y position of the rectangle limiting the circle in screen coords. * @param rw Width of the limiting rectangle. * @param rh Height of the limiting rectangle. * @param c Colour to use. */ void gl_drawCircleInRect( const double cx, const double cy, const double r, const double rx, const double ry, const double rw, const double rh, const glColour *c, int filled ) { int i, j; double rxw,ryh, x,y,p, w,h; GLfloat vertex[2*OPENGL_RENDER_VBO_SIZE], col[4*OPENGL_RENDER_VBO_SIZE]; rxw = rx+rw; ryh = ry+rh; /* is offscreen? */ if ((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh)) return; /* can be drawn normally? */ else if ((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) { gl_drawCircle( cx, cy, r, c, filled ); return; } /* Case if filled. */ if (filled) { x = CLAMP( rx, rxw, cx-r ); y = CLAMP( ry, ryh, cy-r ); w = CLAMP( 0., rxw-x, 2.*r ); h = CLAMP( 0., ryh-y, 2.*r ); gl_blitTexture( gl_circle, x, y, w, h, (x-(cx-r))/(2.*r) * gl_circle->srw, (y-(cy-r))/(2.*r) * gl_circle->srh, (w/(2.*r)) * gl_circle->srw, (h/(2.*r)) * gl_circle->srh, c ); return; } /* Starting parameters. */ i = 0; x = 0; y = r; p = (5. - (r*4.)) / 4.; PIXEL( cx, cy+y ); PIXEL( cx, cy-y ); PIXEL( cx+y, cy ); PIXEL( cx-y, cy ); while (x<y) { x++; if (p < 0) p += 2*(double)(x)+1; else p += 2*(double)(x-(--y))+1; if (x==0) { PIXEL( cx, cy+y ); PIXEL( cx, cy-y ); PIXEL( cx+y, cy ); PIXEL( cx-y, cy ); } else if (x==y) { PIXEL( cx+x, cy+y ); PIXEL( cx-x, cy+y ); PIXEL( cx+x, cy-y ); PIXEL( cx-x, cy-y ); } else if (x<y) { PIXEL( cx+x, cy+y ); PIXEL( cx-x, cy+y ); PIXEL( cx+x, cy-y ); PIXEL( cx-x, cy-y ); PIXEL( cx+y, cy+x ); PIXEL( cx-y, cy+x ); PIXEL( cx+y, cy-x ); PIXEL( cx-y, cy-x ); } } gl_vboSubData( gl_renderVBO, 0, i*2*sizeof(GLfloat), vertex ); gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); /* Set up the colour. */ for (j=0; j<i; j++) { col[4*j+0] = c->r; col[4*j+1] = c->g; col[4*j+2] = c->b; col[4*j+3] = c->a; } gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset, i*4*sizeof(GLfloat), col ); gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY, gl_renderVBOcolOffset, 4, GL_FLOAT, 0 ); /* Draw. */ glDrawArrays( GL_POINTS, 0, i ); /* Clear state. */ gl_vboDeactivate(); }