我在使用OpenGL和SDL2.0绘制TTF字体时遇到了麻烦。
我记得在SDL版本2之前我没有遇到任何问题,但似乎缺乏关于这个主题的文档,可能是由于新标准。
我已经包含以下代码,以显示我正在做的事情。
这段代码非常低效,因为我每帧重新创建纹理,如果复制+粘贴则考虑到这一点:)
void main_render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Set our color back to white (Full texture color)
glColor3f(1.0f, 1.0f, 1.0f);
mainCamera->perspective();
mainCamera->translate();
//Load the font
TTF_Font *font = TTF_OpenFont("../resource/font.ttf", 10);
if (font == nullptr) {
std::cout << "TTF_OpenFont error: " << std::endl;
return;
}
//Render font to a SDL_Surface
SDL_Color color = {0,0,255,80};
SDL_Surface *surface = TTF_RenderText_Blended(font, "Hi!", color);
if (surface == nullptr) {
TTF_CloseFont(font);
std::cout << "TTF_RenderText error: " << std::endl;
return;
}
//Create a SDL_Texture * from the surface
SDL_Texture * text = SDL_CreateTextureFromSurface(fontRender, surface);
if (text == nullptr){
std::cout << "SDL_CreateTextureFromSurface error: " << std::endl;
return;
}
//Bind the SDL_Texture in OpenGL
SDL_GL_BindTexture(text, NULL, NULL);
//Draw the SDL_Texture * as a Quad
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); {
glTexCoord2d(0, 0); glVertex3f(0, 0, 0);
glTexCoord2d(1, 0); glVertex3f(0 + surface->w, 0, 0);
glTexCoord2d(1, 1); glVertex3f(0 + surface->w, 0 + surface->h, 0);
glTexCoord2d(0, 1); glVertex3f(0, 0 + surface->h, 0);
} glEnd();
glDisable(GL_TEXTURE_2D);
//Cleanup
TTF_CloseFont(font);
SDL_DestroyTexture(text);
SDL_FreeSurface(surface);
//Swap the buffers to refresh the window
mainWindow->swap_buffers();
}
答案 0 :(得分:1)
所以OpenGL要求所有纹理在我的系统上都有Base2的尺寸(2,4,16,32,64 ......)
我通过增量搜索最接近原始维度2的幂来解决这个问题:
unsigned int power_two_floor(unsigned int val) {
unsigned int power = 2, nextVal = power*2;
while((nextVal *= 2) <= val)
power*=2;
return power*2;
}
然后我遇到了障碍:纹理是正确的颜色,但像素是乱码。通过使用调整后的OpenGL尺寸将图像复制到RGB SDL_Surface来修复此问题。
//Find the first power of two for OpenGL image
int w = power_two_floor(surface->w)*2;
int h = power_two_floor(surface->h)*2;
//Create a surface to the correct size in RGB format, and copy the old image
SDL_Surface * s = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000);
SDL_BlitSurface(surface, NULL, s, NULL);
需要添加过滤器信息才能使用mipmap修正OpenGL:
//Avoid mipmap filtering
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
以下是我的回答:
unsigned int power_two_floor(unsigned int val) {
unsigned int power = 2, nextVal = power*2;
while((nextVal *= 2) <= val)
power*=2;
return power*2;
}
void main_render() {
//Load the font
TTF_Font *font = TTF_OpenFont("../resource/font.ttf", 10);
if (font == nullptr) {
std::cout << "TTF_OpenFont error: " << std::endl;
return;
}
SDL_Color colorFg = {0,0,255};
SDL_Surface *surface;
//Render font to a SDL_Surface
if ((surface = TTF_RenderText_Blended(font, "Hi!", colorFg)) == nullptr) {
TTF_CloseFont(font);
std::cout << "TTF_RenderText error: " << std::endl;
return;
}
GLuint texId;
//Generate OpenGL texture
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
//Avoid mipmap filtering
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//Find the first power of two for OpenGL image
int w = power_two_floor(surface->w)*2;
int h = power_two_floor(surface->h)*2;
//Create a surface to the correct size in RGB format, and copy the old image
SDL_Surface * s = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000);
SDL_BlitSurface(surface, NULL, s, NULL);
//Copy the created image into OpenGL format
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
//Draw the OpenGL texture as a Quad
glBegin(GL_QUADS); {
glTexCoord2d(0, 1); glVertex3f(0, 0, 0);
glTexCoord2d(1, 1); glVertex3f(0 + surface->w, 0, 0);
glTexCoord2d(1, 0); glVertex3f(0 + surface->w, 0 + surface->h, 0);
glTexCoord2d(0, 0); glVertex3f(0, 0 + surface->h, 0);
} glEnd();
glDisable(GL_TEXTURE_2D);
//Cleanup
TTF_CloseFont(font);
SDL_FreeSurface(s);
SDL_FreeSurface(surface);
glDeleteTextures(1, &texId);
}