Я пытаюсь визуализировать текст, используя SDL_ttf и openGL.
Я открываю шрифт и отрисовываю текст на SDL_Surface, а затем прикрепляю эту поверхность к текстуре и связываю ее для openGL для ее рендеринга.
Я погуглил этот вопрос и не получил много хитов, которые заставили бы меня поверить, что я что-то понимаю.
Единственные две функции, которые имеют значение, так как я сделал временную переменную, чтобы решить эту проблему. Они есть:
SDL_Surface* CFont::BlendedUTF8Surface() {
SDL_Surface* Surf_Text;
SDL_Color Blah;
Blah.r = 0;
Blah.b = 255;
Blah.g = 0;
if(!(Surf_Text = TTF_RenderUTF8_Blended(pFont,TxtMsg,Blah))) {
char str[256];
sprintf_s(str, "? %s \n", TTF_GetError());
OutputDebugString(str);
}
return Surf_Text;
}
Это использует SDL_ttf для рендеринга текста на поверхность Surf_Text. Вы можете видеть, что я превысил синий канал. Я расскажу об этом через минуту. Вот рендеринг
void CLabel::OnRender(int xOff,int yOff) {
if(Visible) {
glColor4f(1.0,1.0,1.0,1.0);
Font.Color(FontColors.r, FontColors.g, FontColors.b); //useless I overwrote the variable with Blah to test this
SDL_Surface* Surf_Text;
Surf_Text = Font.BlendedUTF8Surface();
Text_Font.OnLoad(Surf_Text);
Text_Font.RenderQuad(_X+xOff,_Y+yOff);
SDL_FreeSurface(Surf_Text);
glColor4f(0.0,0.0,0.0,1.0);
}
}
Хорошо, насколько я могу судить, проблема, возможно, связана с текущим состоянием цвета и режимом текстурной среды.
Когда я визуализирую текст таким образом, текст будет менять цвета, но это похоже на сужение каналов R и B. Если я сделаю красный 255, текст будет синим, а если я сделаю синий 255 — красным. Зеленый остается зеленым (RGB против BGR?).
Если я удалю glColor4f
вызов в функции рендеринга, текст вообще отказался отображать цветной. Всегда черный (я обычно устанавливаю цвет обратно (0,0,0) каждый раз, когда что-то рендеринг, так что это возможно, поскольку режим является модулированным (R = 0 * Texture (Font) R и т. Д.), Поэтому он будет черным. Имеет смысл ,
Если я установлю для среды Texture значение DECAL, текст станет черным, а поле за текстом — цветом, который я пытаюсь отобразить.
Я думаю, что просто не знаю правильный способ сделать это. У кого-нибудь есть опыт работы с текстурными средами SDL_ttf и openGL, которые могут дать некоторые идеи?
Редактировать:
Я сделал несколько переписываний функций и протестировал поверхность и наконец понял несколько вещей. Если я использую GL_DECAL, текст отрисовывает правильный цвет, и значение пиксельных значений равно 0 везде на поверхности, где это не красный цвет, который я пытался отрисовать (который отрисовывается со значением 255, что странно, так как красный — первый канал, который должен было 255 ^ 3 (или с точки зрения шестнадцатеричного FF0000) по крайней мере, я бы ожидал). С DECAL, альфа-пространство (пробел вокруг текста, который имеет 0 для значения в пикселях) отображает цвет текущего вызова glColor (). Если я использую Blended, альфа-зона исчезает, но мой текст также отображается как Blended (конечно), так что он смешивается с базовой текстурой фона.
Я думаю, что более уместный вопрос — как смешать только пробел, а не текст? Я предполагаю, что я мог бы вызвать новый glBlendFunc (); но я проверил параметры и я как ребенок в лесу. Понятия не имею, как получить желаемый результат.
Решение не полностью проверено, но формат поверхности действительно BGRA, но я не могу осуществить это исправление. Я собираюсь попытаться создать функцию замены цвета для этого, я думаю.
Это исправление не сработало. Вместо настройки BGR я подумал просто создать новую поверхность RGB:
if (Surface->format->Rmask == 0x00ff0000) {
Surface = SDL_CreateRGBSurfaceFrom(Surface->pixels, Surface->w, Surface->h, 32, Surface->pitch, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask, Surface->format->Amask);
}
После того, как это не сработало, я попытался обменяться Surface->format->Bmask
а также Surface->format->Rmask
но это тоже не имело никакого эффекта.
Для того, чтобы справиться BGR
а также RGB
изменения, вы можете попробовать этот код, чтобы создать текстуру из SDL_Surface
int createTextureFromSurface(SDL_Surface *surface)
{
int texture;
// get the number of channels in the SDL surface
GLint nbOfColors = surface->format->BytesPerPixel;
GLenum textureFormat = 0;
switch (nbOfColors) {
case 1:
textureFormat = GL_ALPHA;
break;
case 3: // no alpha channel
if (surface->format->Rmask == 0x000000ff)
textureFormat = GL_RGB;
else
textureFormat = GL_BGR;
break;
case 4: // contains an alpha channel
if (surface->format->Rmask == 0x000000ff)
textureFormat = GL_RGBA;
else
textureFormat = GL_BGRA;
break;
default:
qDebug() << "Warning: the image is not truecolor...";
break;
}
glEnable( GL_TEXTURE_2D );
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nbOfColors, surface->w, surface->h, 0,
textureFormat, GL_UNSIGNED_BYTE, surface->pixels );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return texture;
}
Других решений пока нет …