/** * @brief Initializes the nebula VBO. */ void nebu_vbo_init (void) { GLfloat vertex[4*3*2]; GLfloat tw, th; /* Free the VBO if it exists. */ if (nebu_vboBG != NULL) { gl_vboDestroy( nebu_vboBG ); nebu_vboBG = NULL; } /* Vertex. */ vertex[0] = 0; vertex[1] = 0; vertex[2] = 0; vertex[3] = SCREEN_H; vertex[4] = SCREEN_W; vertex[5] = 0; vertex[6] = SCREEN_W; vertex[7] = SCREEN_H; /* Texture 0. */ tw = (double)nebu_w / (double)nebu_pw; th = (double)nebu_h / (double)nebu_ph; vertex[8] = 0.; vertex[9] = 0.; vertex[10] = tw; vertex[11] = 0.; vertex[12] = 0.; vertex[13] = th; vertex[14] = tw; vertex[15] = th; /* Texture 1. */ vertex[16] = 0.; vertex[17] = 0.; vertex[18] = tw; vertex[19] = 0.; vertex[20] = 0.; vertex[21] = th; vertex[22] = tw; vertex[23] = th; nebu_vboBG = gl_vboCreateStatic( sizeof(GLfloat) * (4*2*3), vertex ); }
/** * @brief Regenerates the overlay. */ void nebu_genOverlay (void) { int i; GLfloat *data; double a; double gx, gy; double z; /* Get GUI offsets. */ gui_getOffset( &gx, &gy ); /* Here we calculate outer corners. It should actually be /2. because we * are centered around 0,0. However, we treat this extra space as a buffer * for when it's shaking. */ z = 1./conf.zoom_far; /* See if need to generate overlay. */ if (nebu_vboOverlay == NULL) { nebu_vboOverlay = gl_vboCreateStatic( sizeof(GLfloat) * ((2+4)*18 + 2*28 + 4*7), NULL ); /* Set colors, those will be pure static. */ data = gl_vboMap( nebu_vboOverlay ); /* Alpha overlay. */ for (i=0; i<18; i++) { data[2*18 + 4*i + 0] = cDarkBlue.r; data[2*18 + 4*i + 1] = cDarkBlue.g; data[2*18 + 4*i + 2] = cDarkBlue.b; data[2*18 + 4*i + 3] = cDarkBlue.a; } data[2*18 + 3] = 0.; /* Origin is transparent. */ /* Solid overlay. */ for (i=0; i<7; i++) { data[(2+4)*18 + 2*28 + 4*i + 0] = cDarkBlue.r; data[(2+4)*18 + 2*28 + 4*i + 1] = cDarkBlue.g; data[(2+4)*18 + 2*28 + 4*i + 2] = cDarkBlue.b; data[(2+4)*18 + 2*28 + 4*i + 3] = cDarkBlue.a; } gl_vboUnmap( nebu_vboOverlay ); } /* Generate the main chunk. */ data = gl_vboMap( nebu_vboOverlay ); /* Main chunk. */ data[0] = 0.; data[1] = 0.; for (i=0; i<17; i++) { a = M_PI*2./16. * (double)i; data[2*(i+1) + 0] = nebu_view * cos(a); data[2*(i+1) + 1] = nebu_view * sin(a); } /* Top Left */ data[(2+4)*18+0] = -SCREEN_W*z-gx; data[(2+4)*18+1] = SCREEN_H*z-gy; data[(2+4)*18+2] = -nebu_view; data[(2+4)*18+3] = 0.; data[(2+4)*18+4] = -nebu_view*COS225; data[(2+4)*18+5] = nebu_view*SIN225; data[(2+4)*18+6] = -nebu_view*ANG45; data[(2+4)*18+7] = nebu_view*ANG45; data[(2+4)*18+8] = -nebu_view*SIN225; data[(2+4)*18+9] = nebu_view*COS225; data[(2+4)*18+10] = 0.; data[(2+4)*18+11] = nebu_view; data[(2+4)*18+12] = SCREEN_W*z-gx; data[(2+4)*18+13] = SCREEN_H*z-gy; /* Top Right */ data[(2+4)*18+14] = SCREEN_W*z-gx; data[(2+4)*18+15] = SCREEN_H*z-gy; data[(2+4)*18+16] = 0.; data[(2+4)*18+17] = nebu_view; data[(2+4)*18+18] = nebu_view*SIN225; data[(2+4)*18+19] = nebu_view*COS225; data[(2+4)*18+20] = nebu_view*ANG45; data[(2+4)*18+21] = nebu_view*ANG45; data[(2+4)*18+22] = nebu_view*COS225; data[(2+4)*18+23] = nebu_view*SIN225; data[(2+4)*18+24] = nebu_view; data[(2+4)*18+25] = 0.; data[(2+4)*18+26] = SCREEN_W*z-gx; data[(2+4)*18+27] = -SCREEN_H*z-gy; /* Bottom Right */ data[(2+4)*18+28] = SCREEN_W*z-gx; data[(2+4)*18+29] = -SCREEN_H*z-gy; data[(2+4)*18+30] = nebu_view; data[(2+4)*18+31] = 0.; data[(2+4)*18+32] = nebu_view*COS225; data[(2+4)*18+33] = -nebu_view*SIN225; data[(2+4)*18+34] = nebu_view*ANG45; data[(2+4)*18+35] = -nebu_view*ANG45; data[(2+4)*18+36] = nebu_view*SIN225; data[(2+4)*18+37] = -nebu_view*COS225; data[(2+4)*18+38] = 0.; data[(2+4)*18+39] = -nebu_view; data[(2+4)*18+40] = -SCREEN_W*z-gx; data[(2+4)*18+41] = -SCREEN_H*z-gy; /* Bottom left */ data[(2+4)*18+42] = -SCREEN_W*z-gx; data[(2+4)*18+43] = -SCREEN_H*z-gy; data[(2+4)*18+44] = 0.; data[(2+4)*18+45] = -nebu_view; data[(2+4)*18+46] = -nebu_view*SIN225; data[(2+4)*18+47] = -nebu_view*COS225; data[(2+4)*18+48] = -nebu_view*ANG45; data[(2+4)*18+49] = -nebu_view*ANG45; data[(2+4)*18+50] = -nebu_view*COS225; data[(2+4)*18+51] = -nebu_view*SIN225; data[(2+4)*18+52] = -nebu_view; data[(2+4)*18+53] = 0.; data[(2+4)*18+54] = -SCREEN_W*z-gx; data[(2+4)*18+55] = SCREEN_H*z-gy; gl_vboUnmap( nebu_vboOverlay ); }
/** * @brief Initilaizes background stars. * * @param n Number of stars to add (stars per 800x640 screen). */ void background_initStars( int n ) { unsigned int i; GLfloat w, h, hw, hh; double size; /* Calculate size. */ size = SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF; size /= pow2(conf.zoom_far); /* Calculate star buffer. */ w = (SCREEN_W + 2.*STAR_BUF); w += conf.zoom_stars * (w / conf.zoom_far - 1.); h = (SCREEN_H + 2.*STAR_BUF); h += conf.zoom_stars * (h / conf.zoom_far - 1.); hw = w / 2.; hh = h / 2.; /* Calculate stars. */ size *= n; nstars = (unsigned int)(size/(800.*600.)); if (mstars < nstars) { /* Create data. */ star_vertex = realloc( star_vertex, nstars * sizeof(GLfloat) * 4 ); star_colour = realloc( star_colour, nstars * sizeof(GLfloat) * 8 ); mstars = nstars; } for (i=0; i < nstars; i++) { /* Set the position. */ star_vertex[4*i+0] = RNGF()*w - hw; star_vertex[4*i+1] = RNGF()*h - hh; star_vertex[4*i+2] = 0.; star_vertex[4*i+3] = 0.; /* Set the colour. */ star_colour[8*i+0] = 1.; star_colour[8*i+1] = 1.; star_colour[8*i+2] = 1.; star_colour[8*i+3] = RNGF()*0.6 + 0.2; star_colour[8*i+4] = 1.; star_colour[8*i+5] = 1.; star_colour[8*i+6] = 1.; star_colour[8*i+7] = 0.; } /* Destroy old VBO. */ if (star_vertexVBO != NULL) { gl_vboDestroy( star_vertexVBO ); star_vertexVBO = NULL; } if (star_colourVBO != NULL) { gl_vboDestroy( star_colourVBO ); star_colourVBO = NULL; } /* Create now VBO. */ star_vertexVBO = gl_vboCreateStream( nstars * sizeof(GLfloat) * 4, star_vertex ); star_colourVBO = gl_vboCreateStatic( nstars * sizeof(GLfloat) * 8, star_colour ); }
/** * @brief Initializes a font. * * @param font Font to load (NULL defaults to gl_defFont). * @param fname Name of the font (from inside packfile, NULL defaults to default font). * @param h Height of the font to generate. * @return 0 on success. */ int gl_fontInit( glFont* font, const char *fname, const char *fallback, const unsigned int h ) { FT_Library library; FT_Face face; size_t bufsize; FT_Byte* buf; int i; glFontStash *stsh; char *used_font; /* See if we should override fonts. */ used_font = NULL; if ((strcmp( fallback, FONT_DEFAULT_PATH )==0) && (conf.font_name_default!=NULL)) { used_font = strdup( conf.font_name_default ); } else if ((strcmp( fallback, FONT_MONOSPACE_PATH )==0) && (conf.font_name_monospace!=NULL)) { used_font = strdup( conf.font_name_monospace ); } if (used_font) { buf = (FT_Byte*)nfile_readFile( &bufsize, used_font ); if (buf==NULL) { free(used_font); used_font = NULL; } } /* Try to use system font. */ if (used_font==NULL) { used_font = gl_fontFind( fname ); if (used_font) { buf = (FT_Byte*)nfile_readFile( &bufsize, used_font ); if (buf==NULL) { free(used_font); used_font = NULL; } } } /* Fallback to packaged font. */ if (used_font==NULL) { buf = ndata_read( (fallback!=NULL) ? fallback : FONT_DEFAULT_PATH, &bufsize ); if (buf == NULL) { WARN(_("Unable to read font: %s"), (fallback!=NULL) ? fallback : FONT_DEFAULT_PATH); return -1; } used_font = strdup( fallback ); } /* Get default font if not set. */ if (font == NULL) { font = &gl_defFont; DEBUG( _("Using default font '%s'"), used_font ); } /* Get font stash. */ if (avail_fonts==NULL) avail_fonts = array_create( glFontStash ); stsh = &array_grow( &avail_fonts ); memset( stsh, 0, sizeof(glFontStash) ); font->id = stsh - avail_fonts; font->h = (int)floor((double)h); /* Default sizes. */ stsh->tw = DEFAULT_TEXTURE_SIZE; stsh->th = DEFAULT_TEXTURE_SIZE; stsh->h = font->h; /* Create a FreeType font library. */ if (FT_Init_FreeType(&library)) { WARN(_("FT_Init_FreeType failed with font %s."), (used_font!=NULL) ? used_font : FONT_DEFAULT_PATH ); return -1; } /* Object which freetype uses to store font info. */ if (FT_New_Memory_Face( library, buf, bufsize, 0, &face )) { WARN(_("FT_New_Face failed loading library from %s"), (used_font!=NULL) ? used_font : FONT_DEFAULT_PATH ); return -1; } /* Try to resize. */ if (FT_IS_SCALABLE(face)) { if (FT_Set_Char_Size( face, 0, /* Same as width. */ h << 6, /* In 1/64th of a pixel. */ 96, /* Create at 96 DPI */ 96)) /* Create at 96 DPI */ WARN(_("FT_Set_Char_Size failed.")); } else WARN(_("Font isn't resizable!")); /* Select the character map. */ if (FT_Select_Charmap( face, FT_ENCODING_UNICODE )) WARN(_("FT_Select_Charmap failed to change character mapping.")); /* Initialize the unicode support. */ for (i=0; i<HASH_LUT_SIZE; i++) stsh->lut[i] = -1; stsh->glyphs = array_create( glFontGlyph ); stsh->tex = array_create( glFontTex ); /* Set up font stuff for next glyphs. */ stsh->fontname = strdup( (used_font!=NULL) ? used_font : FONT_DEFAULT_PATH ); stsh->face = face; stsh->library = library; stsh->fontdata = buf; /* Set up VBOs. */ stsh->mvbo = 256; stsh->vbo_tex_data = calloc( 8*stsh->mvbo, sizeof(GLfloat) ); stsh->vbo_vert_data = calloc( 8*stsh->mvbo, sizeof(GLshort) ); stsh->vbo_tex = gl_vboCreateStatic( sizeof(GLfloat)*8*stsh->mvbo, stsh->vbo_tex_data ); stsh->vbo_vert = gl_vboCreateStatic( sizeof(GLshort)*8*stsh->mvbo, stsh->vbo_vert_data ); /* Initializes ASCII. */ for (i=0; i<128; i++) gl_fontGetGlyph( stsh, i ); #if 0 /* We can now free the face and library */ FT_Done_Face(face); FT_Done_FreeType(library); /* Free read buffer. */ free(buf); #endif return 0; }