1

OpenGLでテキストをレンダリングするためにSDL_ttfを使用しています。ただし、テキストの端に厄介なアーティファクトが発生しています。

アーティファクト

コードは次のとおりです。

#include <string>
#include "SDL.h"
#include "SDL_opengl.h"
#include <SDL_ttf.h>

using namespace std;

#define WINDOW_WIDTH 1280
#define WINDOW_HEIGHT 1024

struct Color
{
    unsigned char R, G, B, A;

    Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) : 
        R(r), G(g), B(b), A(a)
    {}
};


void DrawRectangle(int left, int right, int top, int bottom, Color c, GLuint Texture);
void DrawTextGL(int left, int top, TTF_Font* font, string text);
GLuint SDLSurfaceToTexture(SDL_Surface* surface);

int main(int argc, char** argv)
{
    SDL_Init(SDL_INIT_VIDEO);   
    SDL_Surface* screen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_OPENGL);
    TTF_Init();

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
    glEnable(GL_TEXTURE_2D);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 0.0f, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Enabling transparency
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

    SDL_Surface* temp = SDL_LoadBMP("New Bitmap Image.bmp");
    GLuint WhiteTexture = SDLSurfaceToTexture(temp);

    TTF_Font* Font;
    Font = TTF_OpenFont("FreeSerif.ttf", 36);
    DrawRectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Color(0, 0, 0, 255), WhiteTexture);
    SDL_GL_SwapBuffers();
    DrawTextGL(300, 300, Font, "graveyard");
    DrawTextGL(600, 600, Font, "graveyard");

    SDL_GL_SwapBuffers();
    system("pause");
    SDL_Quit();
    return 0;
}

void DrawRectangle(int left, int right, int top, int bottom, Color c, GLuint Texture)
{
    glBindTexture(GL_TEXTURE_2D, Texture);

    glColor4f(c.R/255.0f, c.G/255.0f, c.B/255.0f, c.A/255.0f);

    glBegin(GL_QUADS);

    //Top-left vertex (corner) 
    glTexCoord2i(0, 0);
    glVertex2f(GLfloat(left), GLfloat(top));

    //Top-right vertex (corner)
    glTexCoord2i(1, 0);
    glVertex2f(GLfloat(right), GLfloat(top));

    //Bottom-right vertex (corner)
    glTexCoord2i(1, 1);
    glVertex2f(GLfloat(right), GLfloat(bottom));

    //Bottom-left vertex (corner)
    glTexCoord2i(0, 1);
    glVertex2f(GLfloat(left), GLfloat(bottom));

    glEnd();
}

void DrawTextGL(int left, int top, TTF_Font* font, string text)
{
    SDL_Color color = {255, 255, 255, 255};
    SDL_Surface* textSurface;
    textSurface = TTF_RenderText_Blended(font, text.c_str(), color);
    GLuint Texture = SDLSurfaceToTexture(textSurface);

    DrawRectangle(left, left + 260, top, top + 80, Color(255, 255, 255, 255), Texture);

    SDL_FreeSurface(textSurface);
    glDeleteTextures(1, &Texture);
}

GLuint SDLSurfaceToTexture(SDL_Surface* surface)
{
    GLuint texture;
    GLint nOfColors;
    GLenum texture_format;

    // get the number of channels in the SDL surface
    nOfColors = surface->format->BytesPerPixel;

    if (nOfColors == 4)     // contains an alpha channel
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGBA;
        else
            texture_format = GL_BGRA;
    } 
    else if (nOfColors == 3)
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGB;
        else
            texture_format = GL_BGR;
    }
    else
    {
        printf("Picture with less than 24-bit color depth detected.\n");
        return 0;
    }

    // Have OpenGL generate a texture object handle for us
    glGenTextures(1, &texture);

    // Bind the texture object
    glBindTexture(GL_TEXTURE_2D, texture); 

    // Set the texture's stretching properties
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
    texture_format, GL_UNSIGNED_BYTE, surface->pixels);

    // Bind the texture to which subsequent calls refer to
    glBindTexture(GL_TEXTURE_2D, texture);

    return texture;
}

「New Bitmap Image.bmp」は、白いピクセルが 1 つ入った単なるビットマップです。「FreeSerif.ttf」はこちらから取ったフォントです。

4

0 に答える 0