/** * @brief Blits a sprite, position is in absolute screen coordinates. * * @param sprite Sprite to blit. * @param bx X position of the texture in screen coordinates. * @param by Y position of the texture in screen coordinates. * @param sx X position of the sprite to use. * @param sy Y position of the sprite to use. * @param c Colour to use (modifies texture colour). */ void gl_blitStaticSprite( const glTexture* sprite, const double bx, const double by, const int sx, const int sy, const glColour* c ) { double x,y, tx,ty; x = bx; y = by; /* texture coords */ tx = sprite->sw*(double)(sx)/sprite->rw; ty = sprite->sh*(sprite->sy-(double)sy-1)/sprite->rh; /* actual blitting */ gl_blitTexture( sprite, x, y, sprite->sw, sprite->sh, tx, ty, sprite->srw, sprite->srh, c ); }
/** * @brief Renders a texture using the core render function. * * This function is far more complex than renderTex, however it allows much * more fine grained control over the entire render process and puts you * closer to the actual OpenGL calls. * * @usage gfx.renderTexRaw( tex, 0., 0., 100., 100., 1, 1, 0., 0., 0.5, 0.5 ) -- Renders the bottom quarter of the sprite 1,1 of the image. * * @luaparam tex Texture to render. * @luaparam pos_x X position to render texture at. * @luaparam pos_y Y position to render texture at. * @luaparam pos_w Width of the image on screen. * @luaparam pos_h Height of the image on screen. * @luaparam sprite_x X sprite to render. * @luaparam sprite_y Y sprite to render. * @luaparam tex_x X sprite texture offset as [0.:1.]. * @luaparam tex_y Y sprite texture offset as [0.:1.]. * @luaparam tex_w Sprite width to display as [-1.:1.]. Note if negative, it will flip the image horizontally. * @luaparam tex_h Sprite height to display as [-1.:1.] Note if negative, it will flip the image vertically. * @luaparam colour [OPTIONAL] Colour to use when rendering. * @luafunc renderTexRaw( tex, pos_x, pos_y, pos_w, pos_h, sprite_x, sprite_y, tex_x, tex_y, tex_w, tex_h, colour ) */ static int gfxL_renderTexRaw( lua_State *L ) { glTexture *t; glColour *col; double px,py, pw,ph, tx,ty, tw,th; int sx, sy; /* Parameters. */ col = NULL; t = luaL_checktex( L, 1 ); px = luaL_checknumber( L, 2 ); py = luaL_checknumber( L, 3 ); pw = luaL_checknumber( L, 4 ); ph = luaL_checknumber( L, 5 ); sx = luaL_checkinteger( L, 6 ) - 1; sy = luaL_checkinteger( L, 7 ) - 1; tx = luaL_checknumber( L, 8 ); ty = luaL_checknumber( L, 9 ); tw = luaL_checknumber( L, 10 ); th = luaL_checknumber( L, 11 ); if (lua_iscolour( L, 12 )) col = lua_tocolour( L, 12 ); /* Some sanity checking. */ #if DEBUGGING if (sx >= t->sx) NLUA_ERROR( L, "Texture '%s' trying to render out of bounds (X position) sprite: %d > %d.", t->name, sx+1, t->sx ); if (sx >= t->sx) NLUA_ERROR( L, "Texture '%s' trying to render out of bounds (Y position) sprite: %d > %d.", t->name, sy+1, t->sy ); #endif /* DEBUGGING */ /* Translate as needed. */ tx = (tx * t->sw + t->sw * (double)(sx)) / t->rw; tw = tw * t->srw; if (tw < 0) tx -= tw; ty = (ty * t->sh + t->sh * (t->sy - (double)sy-1)) / t->rh; th = th * t->srh; if (th < 0) ty -= th; /* Render. */ gl_blitTexture( t, px, py, pw, ph, tx, ty, tw, th, col ); return 0; }
/** * @brief Blits a texture scaling it. * * @param texture Texture to blit. * @param bx X position of the texture in screen coordinates. * @param by Y position of the texture in screen coordinates. * @param bw Width to scale to. * @param bh Height to scale to. * @param c Colour to use (modifies texture colour). */ void gl_blitScale( const glTexture* texture, const double bx, const double by, const double bw, const double bh, const glColour* c ) { double x,y; double tx,ty; /* here we use absolute coords */ x = bx; y = by; /* texture dimensions */ tx = ty = 0.; /* Actual blitting. */ gl_blitTexture( texture, x, y, bw, bh, tx, ty, texture->srw, texture->srh, c ); }
/** * @brief Blits a scaled sprite, position is in absolute screen coordinates. * * @param sprite Sprite to blit. * @param bx X position of the texture in screen coordinates. * @param by Y position of the texture in screen coordinates. * @param sx X position of the sprite to use. * @param sy Y position of the sprite to use. * @param bw Width of sprite to render at. * @param bh Height of sprite to render at. * @param c Colour to use (modifies texture colour). */ void gl_blitScaleSprite( const glTexture* sprite, const double bx, const double by, const int sx, const int sy, const double bw, const double bh, const glColour* c ) { double x,y, tx,ty; x = bx - (double)SCREEN_W/2.; y = by - (double)SCREEN_H/2.; /* texture coords */ tx = sprite->sw*(double)(sx)/sprite->rw; ty = sprite->sh*(sprite->sy-(double)sy-1)/sprite->rh; /* actual blitting */ gl_blitTexture( sprite, x, y, bw, bh, tx, ty, sprite->srw, sprite->srh, c ); }
/** * @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 Texture blitting backend for interpolated texture. * * Value blitted is ta*inter + tb*(1.-inter). * * @param ta Texture A to blit. * @param tb Texture B to blit. * @param inter Amount of interpolation to do. * @param x X position of the texture on the screen. * @param y Y position of the texture on the screen. * @param tx X position within the texture. * @param ty Y position within the texture. * @param tw Texture width. * @param th Texture height. * @param c Colour to use (modifies texture colour). */ static void gl_blitTextureInterpolate( const glTexture* ta, const glTexture* tb, const double inter, const double x, const double y, const double w, const double h, const double tx, const double ty, const double tw, const double th, const glColour *c ) { GLfloat vertex[4*2], tex[4*2], col[4*4]; GLfloat mcol[4] = { 0., 0., 0. }; /* No interpolation. */ if (!conf.interpolate || (tb == NULL)) { gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c ); return; } /* Corner cases. */ if (inter == 1.) { gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c ); return; } else if (inter == 0.) { gl_blitTexture( tb, x, y, w, h, tx, ty, tw, th, c ); return; } /* No multitexture. */ if (nglActiveTexture == NULL) { if (inter > 0.5) gl_blitTexture( ta, x, y, w, h, tx, ty, tw, th, c ); else gl_blitTexture( tb, x, y, w, h, tx, ty, tw, th, c ); } /* Set default colour. */ if (c == NULL) c = &cWhite; /* Bind the textures. */ /* Texture 0. */ nglActiveTexture( GL_TEXTURE0 ); glEnable(GL_TEXTURE_2D); glBindTexture( GL_TEXTURE_2D, ta->texture); /* Set the mode. */ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); /* Interpolate texture and alpha. */ glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE ); mcol[3] = inter; glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mcol ); /* Arguments. */ /* Arg0. */ glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0 ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0 ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); /* Arg1. */ glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1 ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE1 ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA ); /* Arg2. */ glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA ); /* Texture 1. */ nglActiveTexture( GL_TEXTURE1 ); glEnable(GL_TEXTURE_2D); glBindTexture( GL_TEXTURE_2D, tb->texture); /* Set the mode. */ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); /* Interpolate texture and alpha. */ glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE ); /* Arguments. */ /* Arg0. */ glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); /* Arg1. */ glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA ); /* Set the colour. */ col[0] = c->r; col[1] = c->g; col[2] = c->b; col[3] = c->a; col[4] = col[0]; col[5] = col[1]; col[6] = col[2]; col[7] = col[3]; col[8] = col[0]; col[9] = col[1]; col[10] = col[2]; col[11] = col[3]; col[12] = col[0]; col[13] = col[1]; col[14] = col[2]; col[15] = col[3]; gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset, 4*4*sizeof(GLfloat), col ); gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY, gl_renderVBOcolOffset, 4, GL_FLOAT, 0 ); /* Set the vertex. */ vertex[0] = (GLfloat)x; vertex[4] = vertex[0]; vertex[2] = vertex[0] + (GLfloat)w; vertex[6] = vertex[2]; vertex[1] = (GLfloat)y; vertex[3] = vertex[1]; vertex[5] = vertex[1] + (GLfloat)h; vertex[7] = vertex[5]; gl_vboSubData( gl_renderVBO, 0, 4*2*sizeof(GLfloat), vertex ); gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); /* Set the texture. */ tex[0] = (GLfloat)tx; tex[4] = tex[0]; tex[2] = tex[0] + (GLfloat)tw; tex[6] = tex[2]; tex[1] = (GLfloat)ty; tex[3] = tex[1]; tex[5] = tex[1] + (GLfloat)th; tex[7] = tex[5]; gl_vboSubData( gl_renderVBO, gl_renderVBOtexOffset, 4*2*sizeof(GLfloat), tex ); gl_vboActivateOffset( gl_renderVBO, GL_TEXTURE0, gl_renderVBOtexOffset, 2, GL_FLOAT, 0 ); gl_vboActivateOffset( gl_renderVBO, GL_TEXTURE1, gl_renderVBOtexOffset, 2, GL_FLOAT, 0 ); /* Draw. */ glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); /* Clear state. */ gl_vboDeactivate(); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glDisable(GL_TEXTURE_2D); nglActiveTexture( GL_TEXTURE0 ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glDisable(GL_TEXTURE_2D); /* anything failed? */ gl_checkErr(); }
/** * @brief Renders the custom map widget. * * @param bx Base X position to render at. * @param by Base Y position to render at. * @param w Width of the widget. * @param h Height of the widget. */ static void map_render( double bx, double by, double w, double h, void *data ) { (void) data; int i,j, n,m; double x,y,r, tx,ty, fuel; StarSystem *sys, *jsys, *hsys, *lsys; glColour *col, c; GLfloat vertex[8*(2+4)]; int sw, sh; /* Parameters. */ r = round(CLAMP(5., 15., 6.*map_zoom)); x = round((bx - map_xpos + w/2) * 1.); y = round((by - map_ypos + h/2) * 1.); /* background */ gl_renderRect( bx, by, w, h, &cBlack ); /* * First pass renders everything almost (except names and markers). */ for (i=0; i<systems_nstack; i++) { sys = system_getIndex( i ); /* check to make sure system is known or adjacent to known (or marked) */ if (!sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED) && !space_sysReachable(sys)) continue; tx = x + sys->pos.x*map_zoom; ty = y + sys->pos.y*map_zoom; /* draws the disk representing the faction */ if (sys_isKnown(sys) && (sys->faction != -1)) { sw = gl_faction_disk->sw; sh = gl_faction_disk->sw; col = faction_colour(sys->faction); c.r = col->r; c.g = col->g; c.b = col->b; c.a = 0.7; gl_blitTexture( gl_faction_disk, tx - sw/2, ty - sh/2, sw, sh, 0., 0., gl_faction_disk->srw, gl_faction_disk->srw, &c ); } /* Draw the system. */ if (!sys_isKnown(sys) || (sys->nfleets==0)) col = &cInert; else if (sys->security >= 1.) col = &cGreen; else if (sys->security >= 0.6) col = &cOrange; else if (sys->security >= 0.3) col = &cRed; else col = &cDarkRed; gl_drawCircleInRect( tx, ty, r, bx, by, w, h, col, 0 ); /* If system is known fill it. */ if (sys_isKnown(sys) && (sys->nplanets > 0)) { /* Planet colours */ if (!sys_isKnown(sys)) col = &cInert; else if (sys->nplanets==0) col = &cInert; else col = faction_getColour( sys->faction); /* Radius slightly shorter. */ gl_drawCircleInRect( tx, ty, 0.5*r, bx, by, w, h, col, 1 ); } if (!sys_isKnown(sys)) continue; /* we don't draw hyperspace lines */ /* draw the hyperspace paths */ glShadeModel(GL_SMOOTH); col = &cDarkBlue; /* first we draw all of the paths. */ for (j=0; j<sys->njumps; j++) { jsys = system_getIndex( sys->jumps[j] ); if (hyperspace_target != -1) hsys = system_getIndex( cur_system->jumps[hyperspace_target] ); /* Draw the lines. */ vertex[0] = x + sys->pos.x * map_zoom; vertex[1] = y + sys->pos.y * map_zoom; vertex[2] = vertex[0] + (jsys->pos.x - sys->pos.x)/2. * map_zoom; vertex[3] = vertex[1] + (jsys->pos.y - sys->pos.y)/2. * map_zoom; vertex[4] = x + jsys->pos.x * map_zoom; vertex[5] = y + jsys->pos.y * map_zoom; vertex[6] = col->r; vertex[7] = col->g; vertex[8] = col->b; vertex[9] = 0.; vertex[10] = col->r; vertex[11] = col->g; vertex[12] = col->b; vertex[13] = col->a; vertex[14] = col->r; vertex[15] = col->g; vertex[16] = col->b; vertex[17] = 0.; gl_vboSubData( map_vbo, 0, sizeof(GLfloat) * 3*(2+4), vertex ); gl_vboActivateOffset( map_vbo, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); gl_vboActivateOffset( map_vbo, GL_COLOR_ARRAY, sizeof(GLfloat) * 2*3, 4, GL_FLOAT, 0 ); glDrawArrays( GL_LINE_STRIP, 0, 3 ); gl_vboDeactivate(); } glShadeModel( GL_FLAT ); } /* Now we'll draw over the lines with the new pathways. */ if (map_path != NULL) { lsys = cur_system; glShadeModel(GL_SMOOTH); col = &cGreen; fuel = player->fuel; for (j=0; j<map_npath; j++) { jsys = map_path[j]; if (fuel == player->fuel) col = &cGreen; else if (fuel < 100.) col = &cRed; else col = &cYellow; fuel -= 100; /* Draw the lines. */ vertex[0] = x + lsys->pos.x * map_zoom; vertex[1] = y + lsys->pos.y * map_zoom; vertex[2] = vertex[0] + (jsys->pos.x - lsys->pos.x)/2. * map_zoom; vertex[3] = vertex[1] + (jsys->pos.y - lsys->pos.y)/2. * map_zoom; vertex[4] = x + jsys->pos.x * map_zoom; vertex[5] = y + jsys->pos.y * map_zoom; vertex[6] = col->r; vertex[7] = col->g; vertex[8] = col->b; vertex[9] = 0.; vertex[10] = col->r; vertex[11] = col->g; vertex[12] = col->b; vertex[13] = col->a; vertex[14] = col->r; vertex[15] = col->g; vertex[16] = col->b; vertex[17] = 0.; gl_vboSubData( map_vbo, 0, sizeof(GLfloat) * 3*(2+4), vertex ); gl_vboActivateOffset( map_vbo, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); gl_vboActivateOffset( map_vbo, GL_COLOR_ARRAY, sizeof(GLfloat) * 2*3, 4, GL_FLOAT, 0 ); glDrawArrays( GL_LINE_STRIP, 0, 3 ); gl_vboDeactivate(); lsys = jsys; } glShadeModel( GL_FLAT ); } /* * Second pass - System names */ for (i=0; i<systems_nstack; i++) { sys = system_getIndex( i ); /* Skip system. */ if (!sys_isKnown(sys) || (map_zoom <= 0.5 )) continue; tx = x + (sys->pos.x+11.) * map_zoom; ty = y + (sys->pos.y-5.) * map_zoom; gl_print( &gl_smallFont, tx + SCREEN_W/2., ty + SCREEN_H/2., &cWhite, sys->name ); } /* * Third pass - system markers */ for (i=0; i<systems_nstack; i++) { sys = system_getIndex( i ); /* We only care about marked now. */ if (!sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)) continue; /* Get the position. */ tx = x + sys->pos.x*map_zoom; ty = y + sys->pos.y*map_zoom; /* Count markers. */ n = (sys_isFlag(sys, SYSTEM_CMARKED)) ? 1 : 0; n += sys->markers_misc; n += sys->markers_cargo; n += sys->markers_rush; /* Draw the markers. */ j = 0; if (sys_isFlag(sys, SYSTEM_CMARKED)) { map_drawMarker( tx, ty, r, n, j, 0 ); j++; } for (m=0; m<sys->markers_misc; m++) { map_drawMarker( tx, ty, r, n, j, 1 ); j++; } for (m=0; m<sys->markers_rush; m++) { map_drawMarker( tx, ty, r, n, j, 2 ); j++; } for (m=0; m<sys->markers_cargo; m++) { map_drawMarker( tx, ty, r, n, j, 3 ); j++; } } /* Selected planet. */ if (map_selected != -1) { sys = system_getIndex( map_selected ); gl_drawCircleInRect( x + sys->pos.x * map_zoom, y + sys->pos.y * map_zoom, 1.5*r, bx, by, w, h, &cRed, 0 ); } /* Current planet. */ gl_drawCircleInRect( x + cur_system->pos.x * map_zoom, y + cur_system->pos.y * map_zoom, 1.5*r, bx, by, w, h, &cRadar_tPlanet, 0 ); }
/** * @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(); }