Probleme beim Kopieren der Freetype-Bitmap in die OpenGL-Textur

Ich versuche, alle Bitmaps für Zeichen aus zu generieren' ' zu'~' und füge sie zu einer langen Textur hinzu. Ich beabsichtige, sie in einer Textur mit fester Breite zu positionieren, wollte aber vorerst nur sicherstellen, dass das Konzept funktioniert.

Aber ich habe Probleme. Anstatt die erwartete Textur zu erhalten, erhalte ich für eine 16px-Schriftart nur die folgende:

Es sieht für mich so aus, als würde ich es falsch kopieren, aber egal was ich zu tun scheine, ich bekomme immer die gleiche Ausgabe.

Zum Schluss der Code:

Font.h

#ifndef _FONT_H_
#define _FONT_H_

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <GL/gl.h>

#include <ft2build.h>
#include FT_FREETYPE_H

#include "vector2.h"
#include "math_helper.h"

class Font {
public:
  Font(const std::string font_path, int size);
  ~Font();

  int get_texture() const { return texture_; }

private:
  unsigned int width_, height_, texture_;

  static FT_Library LIBRARY;
  static const char START_CHAR = ' ';
  static const char END_CHAR   = '~';

  static void initialize_library();
};

#endif

Font.cpp

#include "font.h"

FT_Library Font::LIBRARY = NULL;        

Font::Font(const std::string font_path, int size)
  : width_(64), height_(2), texture_(0) {
  initialize_library();

  FT_Face face = NULL;
  int error = FT_New_Face(Font::LIBRARY, font_path.c_str(), 0, &face);

  if(error == FT_Err_Unknown_File_Format) {
    std::cout << "Error: Unknown file format for font \"" << font_path << "\"" << std::endl;
  } else if(error) {
    std::cout << "Error: Could not open font \"" << font_path << "\"" << std::endl;
  }

  error = FT_Set_Pixel_Sizes(face, 0, size);
  if(error) {
    std::cout << "Error: Could not set pixel size for font \"" << font_path << "\"" << std::endl;
  }

  int num_chars = (END_CHAR - START_CHAR);
  width_ = to_nearest_pow2(num_chars * size);
  height_ = to_nearest_pow2(size);
  std::vector<unsigned char> buffer(width_ * height_, 0);
  Vector2 pen;

  for(char c = START_CHAR; c <= END_CHAR; ++c) {
    error = FT_Load_Char(face, c, FT_LOAD_RENDER);

    if(error) {
      std::cout << "Error: Could not load char \"" << c << "\"" << std::endl;
      continue;
    }

    FT_Bitmap bmp = face->glyph->bitmap;
    int advance = (face->glyph->advance.x >> 6);
    int bitmapWidth = bmp.width; //I have tried pitch, same problem
    int bitmapHeight = bmp.rows;

    for(int h = 0; h < bitmapHeight; ++h) {
      for(int w = 0; w < bitmapWidth; ++w) {
        int index = h * bitmapWidth + pen.x;

        buffer[index + w] = bmp.buffer[w + bitmapWidth * h];
      }
    }

    pen.x += advance;
  }

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glGenTextures(1, &texture_);
  glBindTexture(GL_TEXTURE_2D, texture_);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width_, height_, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &buffer[0]);

  FT_Done_Face(face);
}

Font::~Font() {
  if(texture_ != 0) {
    glDeleteTextures(1, &texture_);
  }
}

void Font::initialize_library() {
  if(Font::LIBRARY == NULL) {
    if(FT_Init_FreeType(&Font::LIBRARY) != 0) {
      std::cout << "Error: Unable to initialize FreeType Library" << std::endl;
      return;
    }
  }
}

Vector2 ist nur eine einfache Struktur mit einem x- und einem y-Feld, die bei der Konstruktion auf 0 initialisiert werden.

to_nearest_pow2 ist definiert als:

template<typename T>
T to_nearest_pow2(const T num) {
  T nearest = 2;

  while((nearest <<= 1) < num);

  return nearest;
}

Oh, und so zeichne ich es auf die Leinwand (ich verwende orthographische Projektion)

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, test->get_texture());
  glBegin(GL_QUADS);
  glTexCoord2i(0, 0); glVertex2i(0, 0);
  glTexCoord2i(1, 0); glVertex2i(400, 0);
  glTexCoord2i(1, 1); glVertex2i(400, 400);
  glTexCoord2i(0, 1); glVertex2i(0, 400);
  glEnd();

Bearbeiten

ich habe mich verändertindex zu dem, was von @shouston vorgeschlagen wurde und jetzt bekomme ich diese Ausgabe

Antworten auf die Frage(2)

Ihre Antwort auf die Frage