示例#1
0
文件: font.c 项目: nenau/naev
/**
 * @brief Starts the rendering engine.
 */
static void gl_fontRenderStart( const glFontStash* font, double x, double y, const glColour *c )
{
   double a;

   /* Enable textures. */
   glEnable(GL_TEXTURE_2D);

   /* Set up matrix. */
   gl_matrixMode(GL_MODELVIEW);
   gl_matrixPush();
      gl_matrixTranslate( round(x), round(y) );

   /* Handle colour. */
   if (font_restoreLast) {
      a   = (c==NULL) ? 1. : c->a;
      ACOLOUR(*font_lastCol,a);
   }
   else {
      if (c==NULL)
         glColor4d( 1., 1., 1., 1. );
      else
         COLOUR(*c);
   }
   font_restoreLast = 0;

   /* Activate the appropriate VBOs. */
   gl_vboActivateOffset( font->vbo_tex,  GL_TEXTURE_COORD_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( font->vbo_vert, GL_VERTEX_ARRAY, 0, 2, GL_SHORT, 0 );
}
示例#2
0
/**
 * @brief Renders a rectangle.
 *
 *    @param x X position to render rectangle at.
 *    @param y Y position to render rectangle at.
 *    @param w Rectangle width.
 *    @param h Rectangle height.
 *    @param c Rectangle colour.
 */
void gl_renderRectEmpty( double x, double y, double w, double h, const glColour *c )
{
   GLfloat vx, vy, vxw, vyh;
   GLfloat vertex[5*2], col[5*4];

   /* Helper variables. */
   vx  = (GLfloat) x;
   vy  = (GLfloat) y;
   vxw = vx + (GLfloat) w;
   vyh = vy + (GLfloat) h;

   /* Set the vertex. */
   vertex[0] = vx;
   vertex[1] = vy;
   vertex[2] = vxw;
   vertex[3] = vy;
   vertex[4] = vxw;
   vertex[5] = vyh;
   vertex[6] = vx;
   vertex[7] = vyh;
   vertex[8] = vx;
   vertex[9] = vy;
   gl_vboSubData( gl_renderVBO, 0, sizeof(vertex), vertex );
   gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );

   /* 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];
   col[16] = col[0];
   col[17] = col[1];
   col[18] = col[2];
   col[19] = col[3];
   gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset, sizeof(col), col );
   gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY,
         gl_renderVBOcolOffset, 4, GL_FLOAT, 0 );

   /* Draw. */
   glDrawArrays( GL_LINE_STRIP, 0, 5 );

   /* Clear state. */
   gl_vboDeactivate();

   /* Check errors. */
   gl_checkErr();
}
示例#3
0
文件: map.c 项目: isfos/naev
/**
 * @brief Draws a mission marker on the map.
 *
 * @param x X position to draw at.
 * @param y Y position to draw at.
 * @param r Radius of system.
 * @param num Total number of markers.
 * @param cur Current marker to draw.
 * @param type Type to draw.
 */
static void map_drawMarker( double x, double y, double r,
                            int num, int cur, int type )
{
    const double beta = M_PI / 9;
    static const glColour* colours[] = {
        &cGreen, &cBlue, &cRed, &cOrange
    };

    int i;
    double alpha, cos_alpha, sin_alpha;
    GLfloat vertex[3*(2+4)];


    /* Calculate the angle. */
    if ((num == 1) || (num == 2) || (num == 4))
        alpha = M_PI/4.;
    else if (num == 3)
        alpha = M_PI/6.;
    else if (num == 5)
        alpha = M_PI/10.;
    else
        alpha = M_PI/2.;

    alpha += M_PI*2. * (double)cur/(double)num;
    cos_alpha = r * cos(alpha);
    sin_alpha = r * sin(alpha);
    r = 3 * r;

    /* Draw the marking triangle. */
    vertex[0] = x + cos_alpha;
    vertex[1] = y + sin_alpha;
    vertex[2] = x + cos_alpha + r * cos(beta + alpha);
    vertex[3] = y + sin_alpha + r * sin(beta + alpha);
    vertex[4] = x + cos_alpha + r * cos(beta - alpha);
    vertex[5] = y + sin_alpha - r * sin(beta - alpha);

    for (i=0; i<3; i++) {
        vertex[6 + 4*i + 0] = colours[type]->r;
        vertex[6 + 4*i + 1] = colours[type]->g;
        vertex[6 + 4*i + 2] = colours[type]->b;
        vertex[6 + 4*i + 3] = colours[type]->a;
    }

    glEnable(GL_POLYGON_SMOOTH);
    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_TRIANGLES, 0, 3 );
    gl_vboDeactivate();
    glDisable(GL_POLYGON_SMOOTH);
}
示例#4
0
/**
 * @brief Renders a rectangle.
 *
 *    @param x X position to render rectangle at.
 *    @param y Y position to render rectangle at.
 *    @param w Rectangle width.
 *    @param h Rectangle height.
 *    @param c Rectangle colour.
 */
void gl_renderRect( double x, double y, double w, double h, const glColour *c )
{
   GLfloat vertex[4*2], col[4*4];

   /* Set the vertex. */
   /*   1--2
    *   |  |
    *   3--4
    */
   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 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 );

   /* Draw. */
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );

   /* Clear state. */
   gl_vboDeactivate();

   /* Check errors. */
   gl_checkErr();
}
示例#5
0
文件: toolkit.c 项目: Delll/naev
/**
 * @brief Draws an outline.
 *
 * If lc is NULL, colour will be flat.
 *
 *    @param x X position to draw at.
 *    @param y Y position to draw at.
 *    @param w Width.
 *    @param h Height.
 *    @param b Border width.
 *    @param c Colour.
 *    @param lc Light colour.
 */
void toolkit_drawOutline( int x, int y, int w, int h, int b,
                          glColour* c, glColour* lc )
{
   GLint lines[4][2];
   glColour colours[4];

   /* Set shade model. */
   glShadeModel( (lc==NULL) ? GL_FLAT : GL_SMOOTH );

   x -= b, w += 2 * b;
   y -= b, h += 2 * b;
   lc = lc ? lc : c;

   /* Lines. */
   lines[0][0]   = x;      /* left-up */
   lines[0][1]   = y;
   colours[0]    = *lc;

   lines[1][0]   = x;      /* left-down */
   lines[1][1]   = y + h;
   colours[1]    = *c;

   lines[2][0]   = x + w;  /* right-down */
   lines[2][1]   = y + h;
   colours[2]    = *c;

   lines[3][0]   = x + w;  /* right-up */
   lines[3][1]   = y;
   colours[3]    = *lc;

   /* Upload to the VBO. */
   gl_vboSubData( toolkit_vbo, 0, sizeof(lines), lines );
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset, sizeof(colours), colours );

   /* Set up the VBO. */
   gl_vboActivateOffset( toolkit_vbo, GL_VERTEX_ARRAY, 0, 2, GL_INT, 0 );
   gl_vboActivateOffset( toolkit_vbo, GL_COLOR_ARRAY, 
                         toolkit_vboColourOffset, 4, GL_FLOAT, 0 );

   /* Draw the VBO. */
   glDrawArrays( GL_LINE_LOOP, 0, 4 );

   /* Deactivate VBO. */
   gl_vboDeactivate();
}
示例#6
0
文件: toolkit.c 项目: Delll/naev
/**
 * @brief Draws a rectangle.
 *
 * If lc is NULL, colour will be flat.
 *
 *    @param x X position to draw at.
 *    @param y Y position to draw at.
 *    @param w Width.
 *    @param h Height.
 *    @param c Colour.
 *    @param lc Light colour.
 */
void toolkit_drawRect( int x, int y, int w, int h,
                       glColour* c, glColour* lc )
{
   GLint vertex[4][2];
   glColour colours[4];

   /* Set shade model. */
   glShadeModel( (lc) ? GL_SMOOTH : GL_FLAT );

   lc = lc == NULL ? c : lc;

   /* Set up vertices and colours. */
   vertex[0][0] = x;        /* left-up */
   vertex[0][1] = y;
   colours[0]   = *c;

   vertex[1][0] = x;        /* left-down */
   vertex[1][1] = y + h;
   colours[1]   = *lc;

   vertex[2][0] = x + w;    /* right-up */
   vertex[2][1] = y;
   colours[2]   = *c;

   vertex[3][0] = x + w;    /* right-down */
   vertex[3][1] = y + h;
   colours[3]   = *lc;

   /* Upload to the VBO. */
   gl_vboSubData( toolkit_vbo, 0, sizeof(vertex), vertex );
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset, sizeof(colours), colours );

   /* Set up the VBO. */
   gl_vboActivateOffset( toolkit_vbo, GL_VERTEX_ARRAY,
                         0, 2, GL_INT, 0 );
   gl_vboActivateOffset( toolkit_vbo, GL_COLOR_ARRAY,
                         toolkit_vboColourOffset, 4, GL_FLOAT, 0 );

   /* Draw the VBO. */
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );

   /* Deactivate VBO. */
   gl_vboDeactivate();
}
示例#7
0
/**
 * @brief Renders a cross at a given position.
 *
 *    @param x X position to center at.
 *    @param y Y position to center at.
 *    @param r Radius of cross.
 *    @param c Colour to use.
 */
void gl_renderCross( double x, double y, double r, const glColour *c )
{
   int i;
   GLfloat vertex[2*4], colours[4*4];
   GLfloat vx,vy, vr;

   /* Set up stuff. */
   vx = x;
   vy = y;
   vr = r;

   /* the + sign in the middle of the radar representing the player */
   for (i=0; i<4; i++) {
      colours[4*i + 0] = c->r;
      colours[4*i + 1] = c->g;
      colours[4*i + 2] = c->b;
      colours[4*i + 3] = c->a;
   }
   gl_vboSubData( gl_renderVBO, gl_renderVBOcolOffset,
         sizeof(GLfloat) * 4*4, colours );
   /* Set up vertex. */
   vertex[0] = vx+0.;
   vertex[1] = vy-vr;
   vertex[2] = vx+0.;
   vertex[3] = vy+vr;
   vertex[4] = vx-vr;
   vertex[5] = vy+0.;
   vertex[6] = vx+vr;
   vertex[7] = vy+0.;
   gl_vboSubData( gl_renderVBO, 0, sizeof(GLfloat) * 4*2, vertex );
   /* Draw tho VBO. */
   gl_vboActivateOffset( gl_renderVBO, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( gl_renderVBO, GL_COLOR_ARRAY,
         gl_renderVBOcolOffset, 4, GL_FLOAT, 0 );
   glDrawArrays( GL_LINES, 0, 4 );
   gl_vboDeactivate();
}
示例#8
0
文件: toolkit.c 项目: Delll/naev
/**
 * @brief Renders a window border.
 *
 *    @param w Window to render
 */
static void window_renderBorder( Window* w )
{
   int i;
   GLint cx, cy;
   double x, y;
   glColour *lc, *c, *dc, *oc;
   GLint vertex[31*4];
   GLfloat colours[31*4];

   /* position */
   x = w->x - (double)SCREEN_W/2.;
   y = w->y - (double)SCREEN_H/2.;

   /* colours */
   lc = &cGrey90;
   c = &cGrey70;
   dc = &cGrey50;
   oc = &cGrey30;

   /*
    * Case fullscreen.
    */
   if (window_isFlag( w, WINDOW_FULLSCREEN )) {
      /* Background. */
      toolkit_drawRect( x, y,          w->w, 0.6*w->h, dc, c );
      toolkit_drawRect( x, y+0.6*w->h, w->w, 0.4*w->h, c, NULL );
      /* Name. */
      gl_printMidRaw( &gl_defFont, w->w,
            x + (double)SCREEN_W/2.,
            y + w->h - 20. + (double)SCREEN_H/2.,
            &cBlack, w->name );
      return;
   }

   /*
    * window shaded bg
    */
   /* main body */
   toolkit_drawRect( x+21, y,          w->w-42., 0.6*w->h, dc, c );
   toolkit_drawRect( x+21, y+0.6*w->h, w->w-42., 0.4*w->h, c, NULL );

   glShadeModel(GL_SMOOTH);
   /* Both sides. */
   gl_vboActivateOffset( toolkit_vbo, GL_COLOR_ARRAY,
         toolkit_vboColourOffset, 4, GL_FLOAT, 0 );
   gl_vboActivateOffset( toolkit_vbo, GL_VERTEX_ARRAY, 0, 2, GL_INT, 0 );
   /* Colour is shared. */
   colours[0] = c->r;
   colours[1] = c->g;
   colours[2] = c->r;
   colours[3] = c->a;
   for (i=0; i<7; i++) {
      colours[4 + 4*i + 0] = dc->r;
      colours[4 + 4*i + 1] = dc->g;
      colours[4 + 4*i + 2] = dc->r;
      colours[4 + 4*i + 3] = dc->a;
   }
   for (i=0; i<8; i++) {
      colours[32 + 4*i + 0] = c->r;
      colours[32 + 4*i + 1] = c->g;
      colours[32 + 4*i + 2] = c->r;
      colours[32 + 4*i + 3] = c->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*16, colours );
   /* Left side vertex. */
   cx = x;
   cy = y;
   vertex[0]  = cx + 21;
   vertex[1]  = cy + 0.6*w->h;
   vertex[2]  = cx + 21;
   vertex[3]  = cy;
   vertex[4]  = cx + 15;
   vertex[5]  = cy + 1;
   vertex[6]  = cx + 10;
   vertex[7]  = cy + 3;
   vertex[8]  = cx + 6;
   vertex[9]  = cy + 6;
   vertex[10] = cx + 3;
   vertex[11] = cy + 10;
   vertex[12] = cx + 1;
   vertex[13] = cy + 15;
   vertex[14] = cx;
   vertex[15] = cy + 21;
   vertex[16] = cx;
   vertex[17] = cy + 0.6*w->h;
   vertex[18] = cx;
   cy = y + w->h;
   vertex[19] = cy - 21;
   vertex[20] = cx + 1;
   vertex[21] = cy - 15;
   vertex[22] = cx + 3;
   vertex[23] = cy - 10;
   vertex[24] = cx + 6;
   vertex[25] = cy - 6;
   vertex[26] = cx + 10;
   vertex[27] = cy - 3;
   vertex[28] = cx + 15;
   vertex[29] = cy - 1;
   vertex[30] = cx + 21;
   vertex[31] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex );
   glDrawArrays( GL_POLYGON, 0, 16 );
   /* Right side vertex. */
   cx = x + w->w;
   cy = y;
   vertex[0]  = cx - 21;
   vertex[1]  = cy + 0.6*w->h;
   vertex[2]  = cx - 21;
   vertex[3]  = cy;
   vertex[4]  = cx - 15;
   vertex[5]  = cy + 1;
   vertex[6]  = cx - 10;
   vertex[7]  = cy + 3;
   vertex[8]  = cx - 6;
   vertex[9]  = cy + 6;
   vertex[10] = cx - 3;
   vertex[11] = cy + 10;
   vertex[12] = cx - 1;
   vertex[13] = cy + 15;
   vertex[14] = cx;
   vertex[15] = cy + 21;
   vertex[16] = cx;
   vertex[17] = cy + 0.6*w->h;
   vertex[18] = cx;
   cy = y + w->h;
   vertex[19] = cy - 21;
   vertex[20] = cx - 1;
   vertex[21] = cy - 15;
   vertex[22] = cx - 3;
   vertex[23] = cy - 10;
   vertex[24] = cx - 6;
   vertex[25] = cy - 6;
   vertex[26] = cx - 10;
   vertex[27] = cy - 3;
   vertex[28] = cx - 15;
   vertex[29] = cy - 1;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex );
   glDrawArrays( GL_POLYGON, 0, 16 );


   /* 
    * inner outline
    */
   /* Colour. */
   for (i=0; i<7; i++) {
      colours[4*i + 0] = c->r;
      colours[4*i + 1] = c->g;
      colours[4*i + 2] = c->b;
      colours[4*i + 3] = c->a;
   }
   for (; i<7+16; i++) {
      colours[4*i + 0] = lc->r;
      colours[4*i + 1] = lc->g;
      colours[4*i + 2] = lc->b;
      colours[4*i + 3] = lc->a;
   }
   for (; i<7+16+8; i++) {
      colours[4*i + 0] = c->r;
      colours[4*i + 1] = c->g;
      colours[4*i + 2] = c->b;
      colours[4*i + 3] = c->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*31, colours );
   /* Vertex. */
   /* Left side. */
   cx = x + 1;
   cy = y + 1;
   vertex[0]  = cx + 21;
   vertex[1]  = cy;
   vertex[2]  = cx + 15;
   vertex[3]  = cy + 1;
   vertex[4]  = cx + 10;
   vertex[5]  = cy + 3;
   vertex[6]  = cx + 6;
   vertex[7]  = cy + 6;
   vertex[8]  = cx + 3;
   vertex[9]  = cy + 10;
   vertex[10] = cx + 1;
   vertex[11] = cy + 15;
   vertex[12] = cx;
   vertex[13] = cy + 21;
   vertex[14] = cx;
   vertex[15] = cy + 0.6*w->h - 1;
   cy = y + w->h - 1;
   vertex[16] = cx;
   vertex[17] = cy - 21;
   vertex[18] = cx + 1;
   vertex[19] = cy - 15;
   vertex[20] = cx + 3;
   vertex[21] = cy - 10;
   vertex[22] = cx + 6;
   vertex[23] = cy - 6;
   vertex[24] = cx + 10;
   vertex[25] = cy - 3;
   vertex[26] = cx + 15;
   vertex[27] = cy - 1;
   vertex[28] = cx + 21;
   vertex[29] = cy;
   /* Right side via top. */
   cx = x + w->w - 1;
   cy = y + w->h - 1;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   vertex[32] = cx - 15;
   vertex[33] = cy - 1;
   vertex[34] = cx - 10;
   vertex[35] = cy - 3;
   vertex[36] = cx - 6;
   vertex[37] = cy - 6;
   vertex[38] = cx - 3;
   vertex[39] = cy - 10;
   vertex[40] = cx - 1;
   vertex[41] = cy - 15;
   vertex[42] = cx;
   vertex[43] = cy - 21;
   cy = y + 1;
   vertex[44] = cx;
   vertex[45] = cy + 0.6*w->h - 1;
   vertex[46] = cx;
   vertex[47] = cy + 21;
   vertex[48] = cx - 1;
   vertex[49] = cy + 15;
   vertex[50] = cx - 3;
   vertex[51] = cy + 10;
   vertex[52] = cx - 6;
   vertex[53] = cy + 6;
   vertex[54] = cx - 10;
   vertex[55] = cy + 3;
   vertex[56] = cx - 15;
   vertex[57] = cy + 1;
   vertex[58] = cx - 21;
   vertex[59] = cy;
   cx = x + 1;
   cy = y + 1;
   vertex[60] = cx + 21;
   vertex[61] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex );
   glDrawArrays( GL_LINE_LOOP, 0, 31 );


   /*
    * outter outline
    */
   glShadeModel(GL_FLAT);
   /* Colour. */
   for (i=0; i<31; i++) {
      colours[4*i + 0] = oc->r;
      colours[4*i + 1] = oc->g;
      colours[4*i + 2] = oc->b;
      colours[4*i + 3] = oc->a;
   }
   gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset,
         sizeof(GLfloat) * 4*31, colours );
   /* Vertex. */
   /* Left side. */
   cx = x;
   cy = y;
   vertex[0]  = cx + 21;
   vertex[1]  = cy;
   vertex[2]  = cx + 15;
   vertex[3]  = cy + 1;
   vertex[4]  = cx + 10;
   vertex[5]  = cy + 3;
   vertex[6]  = cx + 6;
   vertex[7]  = cy + 6;
   vertex[8]  = cx + 3;
   vertex[9]  = cy + 10;
   vertex[10] = cx + 1;
   vertex[11] = cy + 15;
   vertex[12] = cx;
   vertex[13] = cy + 21;
   vertex[14] = cx;
   vertex[15] = cy + 0.6*w->h;
   cy = y + w->h;
   vertex[16] = cx;
   vertex[17] = cy - 21;
   vertex[18] = cx + 1;
   vertex[19] = cy - 15;
   vertex[20] = cx + 3;
   vertex[21] = cy - 10;
   vertex[22] = cx + 6;
   vertex[23] = cy - 6;
   vertex[24] = cx + 10;
   vertex[25] = cy - 3;
   vertex[26] = cx + 15;
   vertex[27] = cy - 1;
   vertex[28] = cx + 21;
   vertex[29] = cy;
   /* Right side via top. */
   cx = x + w->w;
   cy = y + w->h;
   vertex[30] = cx - 21;
   vertex[31] = cy;
   vertex[32] = cx - 15;
   vertex[33] = cy - 1;
   vertex[34] = cx - 10;
   vertex[35] = cy - 3;
   vertex[36] = cx - 6;
   vertex[37] = cy - 6;
   vertex[38] = cx - 3;
   vertex[39] = cy - 10;
   vertex[40] = cx - 1;
   vertex[41] = cy - 15;
   vertex[42] = cx;
   vertex[43] = cy - 21;
   cy = y;
   vertex[44] = cx;
   vertex[45] = cy + 0.6*w->h;
   vertex[46] = cx;
   vertex[47] = cy + 21;
   vertex[48] = cx - 1;
   vertex[49] = cy + 15;
   vertex[50] = cx - 3;
   vertex[51] = cy + 10;
   vertex[52] = cx - 6;
   vertex[53] = cy + 6;
   vertex[54] = cx - 10;
   vertex[55] = cy + 3;
   vertex[56] = cx - 15;
   vertex[57] = cy + 1;
   vertex[58] = cx - 21;
   vertex[59] = cy;
   cx = x;
   cy = y;
   vertex[60] = cx + 21;
   vertex[61] = cy;
   gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex );
   glDrawArrays( GL_LINE_LOOP, 0, 31 );

   /* Clean up. */
   gl_vboDeactivate();

   /*
    * render window name
    */
   gl_printMidRaw( &gl_defFont, w->w,
         x + (double)SCREEN_W/2.,
         y + w->h - 20. + (double)SCREEN_H/2.,
         &cBlack, w->name );
}
示例#9
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, 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();
}
示例#10
0
static void gl_drawCircleEmpty( const double cx, const double cy,
      const double r, const glColour *c )
{
   int i, j;
   double x,y,p;
   GLfloat vertex[2*OPENGL_RENDER_VBO_SIZE], col[4*OPENGL_RENDER_VBO_SIZE];

   /* 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, j*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();
}
示例#11
0
/**
 * @brief Texture blitting backend.
 *
 *    @param texture Texture to blit.
 *    @param x X position of the texture on the screen. (units pixels)
 *    @param y Y position of the texture on the screen. (units pixels)
 *    @param w Width on the screen. (units pixels)
 *    @param h Height on the screen. (units pixels)
 *    @param tx X position within the texture. [0:1]
 *    @param ty Y position within the texture. [0:1]
 *    @param tw Texture width. [0:1]
 *    @param th Texture height. [0:1]
 *    @param c Colour to use (modifies texture colour).
 */
void gl_blitTexture(  const glTexture* texture,
      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];

   /* Bind the texture. */
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, texture->texture);

   /* Must have colour for now. */
   if (c == NULL)
      c = &cWhite;

   /* 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_TEXTURE_COORD_ARRAY,
         gl_renderVBOtexOffset, 2, GL_FLOAT, 0 );

   /* 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 );

   /* Draw. */
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );

   /* Clear state. */
   gl_vboDeactivate();
   glDisable(GL_TEXTURE_2D);

   /* anything failed? */
   gl_checkErr();
}
示例#12
0
文件: map.c 项目: isfos/naev
/**
 * @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 );
}
示例#13
0
文件: weapon.c 项目: zid/naev
/**
 * @brief Draws the minimap weapons (used in player.c).
 *
 *    @param res Minimap resolution.
 *    @param w Width of minimap.
 *    @param h Height of minimap.
 *    @param shape Shape of the minimap.
 *    @param alpha Alpha to draw points at.
 */
void weapon_minimap( const double res, const double w,
      const double h, const RadarShape shape, double alpha )
{
   int i, rc, p;
   double x, y;
   Weapon *wp;
   glColour *c;
   GLsizei offset;

   /* Get offset. */
   p = 0;
   offset = weapon_vboSize;

   if (shape==RADAR_CIRCLE)
      rc = (int)(w*w);

   /* Draw the points for weapons on all layers. */
   for (i=0; i<nwbackLayer; i++) {
      wp = wbackLayer[i];

      /* Make sure is in range. */
      if (!pilot_inRange( player, wp->solid->pos.x, wp->solid->pos.y ))
         continue;

      /* Get radar position. */
      x = (wp->solid->pos.x - player->solid->pos.x) / res;
      y = (wp->solid->pos.y - player->solid->pos.y) / res;

      /* Make sure in range. */
      if (shape==RADAR_RECT && (ABS(x)>w/2. || ABS(y)>h/2.))
         continue;
      if (shape==RADAR_CIRCLE && (((x)*(x)+(y)*(y)) > rc))
         continue;

      /* Choose colour based on if it'll hit player. */
      if (outfit_isSeeker(wp->outfit) && (wp->target != PLAYER_ID))
         c = &cNeutral;
      else if ((wp->target == PLAYER_ID) || !areAllies(FACTION_PLAYER, wp->faction))
         c = &cHostile;
      else
         c = &cNeutral;

      /* Set the colour. */
      weapon_vboData[ offset + 4*p + 0 ] = c->r;
      weapon_vboData[ offset + 4*p + 1 ] = c->g;
      weapon_vboData[ offset + 4*p + 2 ] = c->b;
      weapon_vboData[ offset + 4*p + 3 ] = alpha;

      /* Put the pixel. */
      weapon_vboData[ 2*p + 0 ] = x;
      weapon_vboData[ 2*p + 1 ] = y;

      /* "Add" pixel. */
      p++;
   }
   for (i=0; i<nwfrontLayer; i++) {
      wp = wfrontLayer[i];

      /* Make sure is in range. */
      if (!pilot_inRange( player, wp->solid->pos.x, wp->solid->pos.y ))
         continue;

      /* Get radar position. */
      x = (wp->solid->pos.x - player->solid->pos.x) / res;
      y = (wp->solid->pos.y - player->solid->pos.y) / res;

      /* Make sure in range. */
      if (shape==RADAR_RECT && (ABS(x)>w/2. || ABS(y)>h/2.))
         continue;
      if (shape==RADAR_CIRCLE && (((x)*(x)+(y)*(y)) > rc))
         continue;

      /* Choose colour based on if it'll hit player. */
      if (outfit_isSeeker(wp->outfit) && (wp->target != PLAYER_ID))
         c = &cNeutral;
      else if ((wp->target == PLAYER_ID) || !areAllies(FACTION_PLAYER, wp->faction))
         c = &cHostile;
      else
         c = &cNeutral;

      /* Set the colour. */
      weapon_vboData[ offset + 4*p + 0 ] = c->r;
      weapon_vboData[ offset + 4*p + 1 ] = c->g;
      weapon_vboData[ offset + 4*p + 2 ] = c->b;
      weapon_vboData[ offset + 4*p + 3 ] = alpha;

      /* Put the pixel. */
      weapon_vboData[ 2*p + 0 ] = x;
      weapon_vboData[ 2*p + 1 ] = y;

      /* "Add" pixel. */
      p++;
   }

   /* Only render with something to draw. */
   if (p > 0) {
      /* Upload data changes. */
      gl_vboSubData( weapon_vbo, 0, sizeof(GLfloat) * 2*p, weapon_vboData );
      gl_vboSubData( weapon_vbo, offset * sizeof(GLfloat),
            sizeof(GLfloat) * 4*p, &weapon_vboData[offset] );

      /* Activate VBO. */
      gl_vboActivateOffset( weapon_vbo, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );
      gl_vboActivateOffset( weapon_vbo, GL_COLOR_ARRAY, offset * sizeof(GLfloat),
            4, GL_FLOAT, 0 );

      /* Render VBO. */
      glDrawArrays( GL_POINTS, 0, p );

      /* Disable VBO. */
      gl_vboDeactivate();
   }
}
示例#14
0
文件: opengl_render.c 项目: zid/naev
/**
 * @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();
}
示例#15
0
/**
 * @brief Renders the nebula using the multitexture approach.
 *
 *    @param dt Current delta tick.
 */
static void nebu_renderMultitexture( const double dt )
{
   GLfloat col[4];
   int temp;
   double sx, sy;

   /* calculate frame to draw */
   nebu_timer -= dt;
   if (nebu_timer < 0.) { /* Time to change. */
      temp         = cur_nebu[0] - cur_nebu[1];
      cur_nebu[1]  = cur_nebu[0];
      cur_nebu[0] += temp;

      if (cur_nebu[0] >= NEBULA_Z)
         cur_nebu[0] = cur_nebu[1] - 1;
      else if (cur_nebu[0] < 0)
         cur_nebu[0] = cur_nebu[1] + 1;

      /* Change timer. */
      nebu_timer += nebu_dt;

      /* Case it hasn't rendered in a while so it doesn't go crazy. */
      if (nebu_timer < 0)
         nebu_timer = nebu_dt;
   }

   /* Set the colour */
   col[0] = cBlue.r;
   col[1] = cBlue.g;
   col[2] = cBlue.b;
   col[3] = (nebu_dt - nebu_timer) / nebu_dt;

   /* Set up the targets */
   /* Texture 0 */
   nglActiveTexture( GL_TEXTURE0 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, nebu_textures[cur_nebu[1]]);
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
   /* Texture 1 */
   nglActiveTexture( GL_TEXTURE1 );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, nebu_textures[cur_nebu[0]]);

   /* Prepare it */
   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_REPLACE );
   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_INTERPOLATE );
   /* Colour */
   glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col );

   /* Arguments */
   /* Arg0 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB,    GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB,   GL_SRC_COLOR );
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,  GL_TEXTURE );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
   /* Arg1 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,  GL_PREVIOUS );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
   /* Arg2 */
   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,  GL_CONSTANT );
   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA );

   /* Compensate possible rumble */
   spfx_getShake( &sx, &sy );
   gl_matrixPush();
      gl_matrixTranslate( -sx, -sy );

   /* Now render! */
   gl_vboActivateOffset( nebu_vboBG, GL_VERTEX_ARRAY,
         sizeof(GL_FLOAT) * 0*2*4, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboBG, GL_TEXTURE0,
         sizeof(GL_FLOAT) * 1*2*4, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboBG, GL_TEXTURE1,
         sizeof(GL_FLOAT) * 2*2*4, 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
   gl_vboDeactivate();

   gl_matrixPop();

   /* Set values to defaults */
   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();
}
示例#16
0
/**
 * @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();
}
示例#17
0
/**
 * @brief Renders the nebula overlay (hides what player can't see).
 *
 *    @param dt Current delta tick.
 */
void nebu_renderOverlay( const double dt )
{
   (void) dt;
   double gx, gy;
   double ox, oy;
   double z;
   double sx, sy;

   /* Get GUI offsets. */
   gui_getOffset( &gx, &gy );

   /* Get zoom. */
   z = cam_getZoom();

   /*
    * Renders the puffs
    */
   nebu_renderPuffs( 0 );

   /* Prepare the matrix */
   ox = gx;
   oy = gy;
   spfx_getShake( &sx, &sy );
   ox += sx;
   oy += sy;
   gl_matrixPush();
      gl_matrixTranslate( SCREEN_W/2.+ox, SCREEN_H/2.+oy );
      gl_matrixScale( z, z );

   /*
    * Mask for area player can still see (partially)
    */
   glShadeModel(GL_SMOOTH);
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY,
         sizeof(GLfloat)*2*18, 4, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 18 );


   /*
    * Solid nebula for areas the player can't see
    */
   glShadeModel(GL_FLAT);
   /* Colour is shared. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 2*28), 4, GL_FLOAT, 0 );
   /* Top left. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 0*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Top right. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 1*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Bottom right. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 2*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );
   /* Bottom left. */
   gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY,
         sizeof(GLfloat)*((2+4)*18 + 3*2*7), 2, GL_FLOAT, 0 );
   glDrawArrays( GL_TRIANGLE_FAN, 0, 7 );

   gl_vboDeactivate();
   gl_matrixPop();

   /* Reset puff movement. */
   puff_x = 0.;
   puff_y = 0.;

   gl_checkErr();
}
示例#18
0
文件: font.c 项目: nenau/naev
/**
 * @brief Adds a font glyph to the texture stash.
 */
static int gl_fontAddGlyphTex( glFontStash *stsh, font_char_t *ch, glFontGlyph *glyph )
{
   int i, j, n;
   GLubyte *data;
   glFontRow *r, *gr;
   glFontTex *tex;
   GLfloat *vbo_tex;
   GLshort *vbo_vert;
   GLfloat tx, ty, txw, tyh;
   GLfloat fw, fh;
   GLshort vx, vy, vw, vh;

   /* Find free row. */
   gr = NULL;
   for (i=0; i<array_size( stsh->tex ); i++) {
      for (j=0; j<MAX_ROWS; j++) {
         r = &stsh->tex->rows[j];
         /* Fits in current row, so use that. */
         if ((r->h == ch->h) && (r->x+ch->w < stsh->tw)) {
            tex = &stsh->tex[i];
            gr = r;
            break;
         }
         /* If not empty row, skip. */
         if (r->h != 0)
            continue;
         /* See if height fits. */
         if ((j==0) || (stsh->tex->rows[j-1].y+stsh->tex->rows[j-1].h+ch->h < stsh->th)) {
            r->h = ch->h;
            if (j>0)
               r->y = stsh->tex->rows[j-1].y + stsh->tex->rows[j-1].h;
            tex = &stsh->tex[i];
            gr = r;
            break;
         }
      }
   }

   /* Allocate new texture. */
   if (gr == NULL) {
      tex = &array_grow( &stsh->tex );
      memset( stsh->tex, 0, sizeof(glFontTex) );

      glGenTextures( 1, &tex->id );
      glBindTexture( GL_TEXTURE_2D, tex->id );

      /* Shouldn't ever scale - we'll generate appropriate size font. */
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

      /* Clamp texture .*/
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

      /* Initialize size. */
      data = calloc( 2*stsh->tw*stsh->th, sizeof(GLubyte) );
      glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, stsh->tw, stsh->th, 0,
            GL_ALPHA, GL_UNSIGNED_BYTE, data );
      free(data);

      /* Check for errors. */
      gl_checkErr();

      gr = &tex->rows[0];
      gr->h = ch->h;
   }

   /* Upload data. */
   glBindTexture( GL_TEXTURE_2D, tex->id );
   glPixelStorei(GL_UNPACK_ALIGNMENT,1);
   glTexSubImage2D( GL_TEXTURE_2D, 0, gr->x, gr->y, ch->w, ch->h,
         GL_ALPHA, GL_UNSIGNED_BYTE, ch->data );

   /* Check for error. */
   gl_checkErr();

   /* Update VBOs. */
   stsh->nvbo++;
   if (stsh->nvbo > stsh->mvbo) {
      stsh->mvbo *= 2;
      stsh->vbo_tex_data  = realloc( stsh->vbo_tex_data,  8*stsh->mvbo*sizeof(GLfloat) );
      stsh->vbo_vert_data = realloc( stsh->vbo_vert_data, 8*stsh->mvbo*sizeof(GLshort) );
   }
   n = 8*stsh->nvbo;
   vbo_tex  = &stsh->vbo_tex_data[n-8];
   vbo_vert = &stsh->vbo_vert_data[n-8];
   /* We do something like the following for vertex coordinates.
      *
      *
      *  +----------------- top reference   \  <------- font->h
      *  |                                  |
      *  |                                  | --- off_y
      *  +----------------- glyph top       /
      *  |
      *  |
      *  +----------------- glyph bottom
      *  |
      *  v   y
      *
      *
      *  +----+------------->  x
      *  |    |
      *  |    glyph start
      *  |
      *  side reference
      *
      *  \----/
      *   off_x
      */
   /* Temporary variables. */
   fw  = (GLfloat) stsh->tw;
   fh  = (GLfloat) stsh->th;
   tx  = (GLfloat) gr->x / fw;
   ty  = (GLfloat) gr->y / fh;
   txw = (GLfloat) (gr->x + ch->w) / fw;
   tyh = (GLfloat) (gr->y + ch->h) / fh;
   vx  = ch->off_x;
   vy  = ch->off_y - ch->h;
   vw  = ch->w;
   vh  = ch->h;
   /* Texture coords. */
   vbo_tex[ 0 ] = tx;  /* Top left. */
   vbo_tex[ 1 ] = ty;
   vbo_tex[ 2 ] = txw; /* Top right. */
   vbo_tex[ 3 ] = ty;
   vbo_tex[ 4 ] = txw; /* Bottom right. */
   vbo_tex[ 5 ] = tyh;
   vbo_tex[ 6 ] = tx;  /* Bottom left. */
   vbo_tex[ 7 ] = tyh;
   /* Vertex coords. */
   vbo_vert[ 0 ] = vx;    /* Top left. */
   vbo_vert[ 1 ] = vy+vh;
   vbo_vert[ 2 ] = vx+vw; /* Top right. */
   vbo_vert[ 3 ] = vy+vh;
   vbo_vert[ 4 ] = vx+vw; /* Bottom right. */
   vbo_vert[ 5 ] = vy;
   vbo_vert[ 6 ] = vx;    /* Bottom left. */
   vbo_vert[ 7 ] = vy;
   /* Update vbos. */
   gl_vboData( stsh->vbo_tex,  sizeof(GLfloat)*n,  stsh->vbo_tex_data );
   gl_vboData( stsh->vbo_vert, sizeof(GLshort)*n, stsh->vbo_vert_data );

   /* Add space for the new character. */
   gr->x += ch->w;

   /* Save glyph data. */
   glyph->vbo_id = (n-8)/2;
   glyph->tex = tex;

   /* Since the VBOs have possibly changed, we have to reset the data. */
   gl_vboActivateOffset( stsh->vbo_tex,  GL_TEXTURE_COORD_ARRAY, 0, 2, GL_FLOAT, 0 );
   gl_vboActivateOffset( stsh->vbo_vert, GL_VERTEX_ARRAY, 0, 2, GL_SHORT, 0 );

   return 0;
}