OpenGL과 SDL을 사용하려고 시도 중입니다. SDL_ttf를 사용하여 텍스트를 텍스처로 렌더링하려고하지만 코드가 쓰레기를 렌더링 중입니다. 텍스처에 쓰레기를 렌더링하는 SDL_TTF
내 "질감 코드 렌더링"GLuint textToTexture(std::string & text, TTF_Font* font, glm::vec4 textColour, glm::vec4 bgColour)
{
if (!TTF_WasInit())
{
if (TTF_Init() == -1)
exit(6);
}
SDL_Color colour = { (Uint8)(textColour.r*255), (Uint8)(textColour.g*255), (Uint8)(textColour.b*255), (Uint8)(textColour.a*255) };
SDL_Color bg = { (Uint8)(bgColour.r*255), (Uint8)(bgColour.g*255), (Uint8)(bgColour.b*255), (Uint8)(bgColour.a*255) };
SDL_Surface *stringImage = NULL;
stringImage = TTF_RenderText_Blended(font, text.c_str(), colour);
if (stringImage == NULL)
{
exit(5);
}
GLuint trueH = powerofTwo(stringImage->h);
GLuint trueW = powerofTwo(stringImage->w);
unsigned char* pixels = NULL;
GLuint w = stringImage->w;
GLuint h = stringImage->h;
GLuint colours = stringImage->format->BytesPerPixel;
pixels = padTexture((unsigned char*)stringImage->pixels, w, h, pixels, trueW, trueH, colours);
GLuint format, internalFormat;
if (colours == 4) {
if (stringImage->format->Rmask == 0x000000ff)
format = GL_RGBA;
else
format = GL_BGRA;
}
else {
// no alpha
if (stringImage->format->Rmask == 0x000000ff)
format = GL_RGB;
else
format = GL_BGR;
}
internalFormat = (colours == 4) ? GL_RGBA : GL_RGB;
GLuint texId = 0;
//GLuint texture;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, trueW, trueH, 0,format, GL_UNSIGNED_BYTE, pixels);
// SDL surface was used to generate the texture but is no longer
// required. Release it to free memory
SDL_FreeSurface(stringImage);
free(pixels)
return texId;
}
패딩에 대한 정확한 크기를 계산하기위한 코드 :
int powerofTwo(int num)
{
if (num != 0)
{
num--;
num |= num >> 1; // Divide by 2^k for consecutive doublings of k up to 32,
num |= num >> 2; // and then or the results.
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
num++;
}
return num;
}
과 마지막 코드 것을의 질감 복사 바이트 ! [왜곡 질감] [1 : 정확한 치수 : 다음
unsigned char* padTexture(unsigned char * src, int srcW, int srcH, unsigned char * dest, int width, int height, int bpp)
{
dest = (unsigned char*)calloc(1, width*height*bpp);
for (int i = 0; i < srcH; i++)
{
memcpy(dest + (width*i*bpp),src + (srcW*i*bpp), srcW*bpp);
}
return dest;
}
이 코드의 결과는 ]] [1]
SDL_TTF가 코드베이스의 다른 곳에서 제대로 초기화되었고 글꼴도로드되고 있는지 확인하고 오류를 확인했습니다. 동일한 결과를 가진 세 가지 다른 ttf 글꼴로 테스트했습니다. I 다른 TTF_rendering 기능 (음영 솔리드 등)을 사용하는 경우에도
, 고체 쿼드 렌더링되고 textToTexture 함수의 "색상"변수도 추가 1.
로 끝낸다 :
MavenPro - 일반, 내가 인터넷을 발견 HelveticaNeueLTStd - 목다른 : 나는 이전에 언급 한 바와 같이
, 나는 세 TTF 폰트 테스트. "Select Scenario"문자열을 렌더링하려고했습니다.
미리 패딩 된 이미지 크기는 138x25 픽셀입니다.
채워진 이미지 크기는 256x32 픽셀입니다.
업데이트 1 : 다음과 같이
BPP 문제를 해결 한 후 새로운 질감은 다음과 같습니다
이 이미지는 내가 프로그램을 실행할 때마다 변경됩니다.
업데이트 2 : 나는 TTF_RenderText_Shaded
를 사용할 때 이미지를 패딩, 나는 내가 할 모든 검은 쿼드이며, TTF_RenderText_Blended
를 사용하는 경우, 텍스처 자체에 픽셀 데이터를 설정하여 추가 발견 된 오류를 수정 한 후 내가 얻을 :
업데이트 3 :
내가 immedietly GL의 코드를 호출하기 전에 및 SDL_RenderText_Blended
를 호출 한 후 SDL_SaveBMP
를 사용, 결과는 (이 텍스트 색상 지정) 완전히 흰색 이미지였다.
TTF_RenderText_Solid
을 사용하여 동일한 작업을 수행 할 때 저장된 이미지는 그대로 유지되지만 위의 이미지처럼 OpenGL에 의해 렌더링됩니다.
SDL_TTF를 초기화하면 오류없이 글꼴이로드되고 텍스트 렌더링이 오류를 반환하지 않으므로 다음에 수행 할 작업을 생각할 수 없습니다.
업데이트 4 : (현대 OpenGL은 그것에 대해 상관하지 않는 한) 내가 있기 때문에 하나의 함수로 모든 TTF 코드를 리팩토링과 패딩 코드를 제거한
. 그러나 모든 프로젝트 설정과 코드가 동일한 하드웨어에서 작동하는 것으로 알려진 테스트 프로젝트와 동일하지만이 문제는 계속 발생합니다.
GLuint textToTexture(const char * text, const char * font, glm::vec4 textColour, glm::vec4 bgColour, unsigned int & texID)
{
if (!TTF_WasInit()) {
if (TTF_Init() == -1)
exit(6);
}
SDL_Color colour = { (Uint8)(textColour.r * 255), (Uint8)(textColour.g * 255), (Uint8)(textColour.b * 255),(Uint8)(textColour.a * 255) };
SDL_Color bg = { (Uint8)(bgColour.r * 255), (Uint8)(bgColour.g * 255), (Uint8)(bgColour.b * 255),255 };
TTF_Font* fontObj = TTF_OpenFont(font, 24);
if (!fontObj)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Texture Error",
"Cannot load font to create texture.",
NULL);
return 0;
}
SDL_Surface *image = NULL;
image = TTF_RenderText_Blended(fontObj, text, colour);
if (image == NULL)
{
exit(5);
//exitFatalError("String surface not created.");
std::cout << "String surface not created." << std::endl;
}
unsigned char* pixels = NULL;
GLuint w = image->w;
GLuint h = image->h;
GLuint colours = image->format->BytesPerPixel;
GLuint externalFormat, internalFormat;
SDL_PixelFormat *format = image->format;
if (colours == 4) {
if (image->format->Rmask == 0x000000ff)
externalFormat = GL_RGBA;
else
externalFormat = GL_BGRA;
}
else {
// no alpha
if (image->format->Rmask == 0x000000ff)
externalFormat = GL_RGB;
else
externalFormat = GL_BGR;
}
internalFormat = (colours == 4) ? GL_RGBA : GL_RGB;
GLuint texId = 0;
//GLuint texture;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, externalFormat, GL_UNSIGNED_BYTE, image->pixels);
//glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, trueW, trueH, 0, externalFormat, GL_UNSIGNED_BYTE, pixels);
glGenerateMipmap(GL_TEXTURE_2D);
//// SDL surface was used to generate the texture but is no longer
//// required. Release it to free memory
SDL_FreeSurface(image);
TTF_CloseFont(fontObj);
return texID;
}
난 후, BMP에 이미지를 저장을 다시로드와 텍스처를 생성하는 해결 방법을 가지고,하지만 난 TTF_RenderText_Shaded
만을 사용하는 경우. TTF_RenderText_Blended
을 사용하면 텍스트 색상에 해당하는 단일 색상 이미지를 얻습니다.
'SRC + (srcW * I)'- 당신이 (동일 DST 간다) 너무 BPP를 곱해야합니다. 또한 픽셀 버퍼를 결코 확보 할 수 없지만 현재 문제와 관련이 없습니다. – keltar
그래, 그 오류 (멋지게 발견 btw),하지만 그것은 결과 질감에 아무런 개선, 그래서 거기에 다른 문제가 있습니까? –
기술적으로 행을 정렬해야하지만 bpp = 4는 이미 있습니다. 귀하가 변경 한 내용과 결과를 귀하가 받고있는 상태로 업데이트하십시오. 원래 표면의 너비와 높이, 사용 된 글꼴 및 렌더링되는 텍스트의 실제 값을 아는 것도 도움이 될 수 있습니다. – keltar