C++ TTF_渲染F8_混合渲染彩色文本
我正在尝试使用SDL_ttf和openGL渲染文本 我打开字体并将文本渲染到SDL_曲面,然后将该曲面附加到纹理并绑定到openGL进行渲染 我在谷歌上搜索了一大堆这个问题,没有得到多少点击率,这会让我相信我了解一些东西 这是唯一两个重要的函数,因为我已经制作了一个临时变量来解决这个问题。它们是:C++ TTF_渲染F8_混合渲染彩色文本,c++,opengl,sdl,textures,sdl-ttf,C++,Opengl,Sdl,Textures,Sdl Ttf,我正在尝试使用SDL_ttf和openGL渲染文本 我打开字体并将文本渲染到SDL_曲面,然后将该曲面附加到纹理并绑定到openGL进行渲染 我在谷歌上搜索了一大堆这个问题,没有得到多少点击率,这会让我相信我了解一些东西 这是唯一两个重要的函数,因为我已经制作了一个临时变量来解决这个问题。它们是: SDL_Surface* CFont::BlendedUTF8Surface() { SDL_Surface* Surf_Text; SDL_Color Blah; Blah.
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_文本表面。你可以看到我已经把蓝色通道设置到最大。我一会儿再谈这个。这里是渲染
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?)
如果我在rendering函数中删除glColor4f
调用,则文本将完全拒绝呈现彩色。始终为黑色(我习惯性地在每次渲染时将颜色设置回(0,0,0),因为模式为调制(R=0*纹理(字体)R等),所以可能为黑色。这是有意义的
如果我将纹理环境设置为“贴花”,则文本渲染为黑色,文本后面的框渲染我尝试渲染文本的颜色
我想我只是不知道正确的方法。有没有人有过SDL_ttf和openGL纹理环境的经验,可以提供一些想法
编辑:
我重新编写了一些函数并测试了曲面,最终解决了一些问题。如果我使用GL_贴花,文本将呈现正确的颜色,并且曲面上的所有像素值均为0,而不是我尝试渲染的红色(渲染值为255,这很奇怪,因为红色是第一个通道,至少我认为它应该是255^3(或十六进制FF0000)。对于贴花,alpha空间(文本周围的空白区域,像素值为0)显示当前glColor()的颜色如果我使用混合,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
,但也没有效果。为了处理BGR
和RGB
更改,您可以尝试使用此代码从SDL\u曲面创建纹理
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;
}
int createTextureFromSurface(SDL_表面*表面)
{
内部纹理;
//获取SDL曲面中的通道数
闪烁色=表面->格式->字节/像素;
骨盂结构形态=0;
开关(nbOfColors){
案例1:
纹理形式=GL_α;
打破
案例3://无阿尔法通道
如果(曲面->格式->Rmask==0x000000ff)
纹理格式=GL_RGB;
其他的
纹理格式=GL_BGR;
打破
案例4://包含一个alpha通道
如果(曲面->格式->Rmask==0x000000ff)
纹理格式=GL_RGBA;
其他的
纹理格式=GL_BGRA;
打破
违约:
qDebug()我将尝试一下。我的纹理渲染功能的唯一区别(减去检查遮罩)我在min和mag过滤器中使用GL_LINEAR。我明白你的意思,这是一个比我原来只切换r和b值更好的计划。让我感到困扰的是,我遵循SDL_ttf文档,使用SDL_颜色类型并设置.r值。该颜色类型是字体到曲面渲染功能的参数。没有无论我假设的是RGB还是BGR,曲面都应该返回错误的遮罩。事实上,我不是TTF大师,但我知道我可以信任每个SDL_曲面王的此功能(来自JPG、BMP、PNG、TTF)我不知道你的代码有什么问题……我的openGL版本不支持GL_BGR和GL_BGRA,因为我在windows上使用openGL 1.1()然而,我在BGR格式中设置了一个出口,果然-字体是BGRA格式。哇。谢谢!我尝试了将format=0xE080;和0xE081;设置为BGR和BGRA的GLenum值。有趣的是,字体现在只呈现了一个实心框。我现在要尝试并弄清楚这是怎么回事。等我拿到wo时,我会的rk对;)哈哈哈,你现在得到了积极的评价。哈哈