Пример #1
0
/**
 * Callback called from _mesa_HashWalk()
 */
static void
count_tex_size(GLuint key, void *data, void *userData)
{
   const struct gl_texture_object *texObj =
      (const struct gl_texture_object *) data;
   GLuint *total = (GLuint *) userData;

   *total = *total + texture_size(texObj);
}
Пример #2
0
/**
 * Compute total size (in bytes) of all textures for the given context.
 * For debugging purposes.
 */
GLuint
_mesa_total_texture_memory(struct gl_context *ctx)
{
   GLuint tgt, total = 0;

   _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total);

   /* plus, the default texture objects */
   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
      total += texture_size(ctx->Shared->DefaultTex[tgt]);
   }

   return total;
}
Пример #3
0
/** Render a glyph for a character into bitmap and save it into the glyph page.
 *  \param c The character to be loaded.
 *  \param c \ref GlyphInfo for the character.
 */
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
{
    assert(gi.glyph_index > 0);
    assert(gi.font_number < m_face_ttf->getTotalFaces());
    FT_Face cur_face = m_face_ttf->getFace(gi.font_number);
    FT_GlyphSlot slot = cur_face->glyph;

    // Same face may be shared across the different FontWithFace,
    // so reset dpi each time
    font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()),
        "setting DPI");

    font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index,
        FT_LOAD_DEFAULT), "loading a glyph");

    font_manager->checkFTError(shapeOutline(&(slot->outline)),
        "shaping outline");

    font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL),
        "rendering a glyph to bitmap");

    // Convert to an anti-aliased bitmap
    FT_Bitmap* bits = &(slot->bitmap);
    core::dimension2du texture_size(bits->width + 1, bits->rows + 1);
    if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
        m_used_height + m_current_height + texture_size.Height >
        getGlyphPageSize())                                     ||
        m_used_height + texture_size.Height > getGlyphPageSize())
    {
        // Add a new glyph page if current one is full
        createNewGlyphPage();
    }

    // Determine the linebreak location
    if (m_used_width + texture_size.Width > getGlyphPageSize())
    {
        m_used_width  = 0;
        m_used_height += m_current_height;
        m_current_height = 0;
    }

    const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
#ifndef SERVER_ONLY
    video::ITexture* tex = m_spritebank->getTexture(cur_tex);
    glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
    assert(bits->pixel_mode == FT_PIXEL_MODE_GRAY);
    if (CVS->isARBTextureSwizzleUsable())
    {
        glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
            bits->width, bits->rows, GL_RED, GL_UNSIGNED_BYTE, bits->buffer);
    }
    else
    {
        const unsigned int size = bits->width * bits->rows;
        uint8_t* image_data = new uint8_t[size * 4];
        memset(image_data, 255, size * 4);
        for (unsigned int i = 0; i < size; i++)
            image_data[4 * i + 3] = bits->buffer[i];
        glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
            bits->width, bits->rows, GL_BGRA, GL_UNSIGNED_BYTE, image_data);
        delete[] image_data;
    }
    if (tex->hasMipMaps())
        glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);
#endif

    // Store the rectangle of current glyph
    gui::SGUISpriteFrame f;
    gui::SGUISprite s;
    core::rect<s32> rectangle(m_used_width, m_used_height,
        m_used_width + bits->width, m_used_height + bits->rows);
    f.rectNumber = m_spritebank->getPositions().size();
    f.textureNumber = cur_tex;

    // Add frame to sprite
    s.Frames.push_back(f);
    s.frameTime = 0;
    m_spritebank->getPositions().push_back(rectangle);
    m_spritebank->getSprites().push_back(s);

    // Save glyph metrics
    FontArea a;
    a.advance_x = cur_face->glyph->advance.x / BEARING;
    a.bearing_x = cur_face->glyph->metrics.horiBearingX / BEARING;
    const int cur_height = (cur_face->glyph->metrics.height / BEARING);
    const int cur_offset_y = cur_height -
        (cur_face->glyph->metrics.horiBearingY / BEARING);
    a.offset_y = m_glyph_max_height - cur_height + cur_offset_y;
    a.offset_y_bt = -cur_offset_y;
    a.spriteno = f.rectNumber;
    m_character_area_map[c] = a;

    // Store used area
    m_used_width += texture_size.Width;
    if (m_current_height < texture_size.Height)
        m_current_height = texture_size.Height;
}   // insertGlyph