我正在尝试使用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 *纹理(字体)R等)所以它会是黑色的。
如果我将纹理环境设置为DECAL,则文本呈现黑色,文本后面的框会呈现我尝试渲染文本的颜色。
我想我只是不知道这样做的正确方法。任何人都有SDL_ttf和openGL纹理环境的经验,可以给出一些想法吗?
编辑:
我已经对函数进行了一些重写并测试了表面,并最终找到了一些东西。如果我使用GL_DECAL,文本呈现正确的颜色,并且表面上的像素值值为0,它不是我尝试渲染的红色(渲染值为255,这很奇怪,因为红色是它应该的第一个通道至少我预计会有255 ^ 3(或以十六进制FF0000计)。使用DECAL时,alpha空间(文本周围的白色空间,对于像素值为0)显示当前glColor()调用的颜色。如果我使用Blended,alpha区域会消失,但我的文本也会渲染为混合(当然),因此它会与底层背景纹理混合。
我想更合适的问题是如何只混合空格而不是文本?我的猜测是我可以调用一个新的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
,但这也没有效果。
答案 0 :(得分:1)
为了处理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;
}