Pergunta

Eu estive a tentar compor o texto em uma janela openGL usando SDL e a SDL_TTF biblioteca no windows XP, VS2010.
Versões:
SDL versão 1.2.14
SDL TTF devel 1.2.10
openGL (versão é de pelo menos 2-3 anos de idade).

Eu tenho criado com êxito, uma janela openGL usando SDL / SDL_image e pode render de linhas e polígonos para ele sem problemas.

No entanto, de mover-se no texto, parece que há alguma falha no meu programa atual, eu estou obtendo o seguinte resultado ao tentar este código aqui

enter image description here

para aqueles que não estão dispostos a pastebin aqui estão apenas a crutial segmentos de código:

void drawText(char * text) {
    glLoadIdentity();
    SDL_Color clrFg = {0,0,255,0}; // set colour to blue (or 'red' for BGRA)
    SDL_Surface *sText = TTF_RenderUTF8_Blended( fntCourier, text, clrFg );
    GLuint * texture = create_texture(sText);
    glBindTexture(GL_TEXTURE_2D, *texture);
    // draw a polygon and map the texture to it, may be the source of error
    glBegin(GL_QUADS); {
        glTexCoord2i(0, 0); glVertex3f(0, 0, 0);
        glTexCoord2i(1, 0); glVertex3f(0 + sText->w, 0, 0);
        glTexCoord2i(1, 1); glVertex3f(0 + sText->w, 0 + sText->h, 0);
        glTexCoord2i(0, 1); glVertex3f(0, 0 + sText->h, 0);
    } glEnd();
    // free the surface and texture, removing this code has no effect
    SDL_FreeSurface( sText );
    glDeleteTextures( 1, texture );
}

segmento 2:

// create GLTexture out of SDL_Surface
GLuint * create_texture(SDL_Surface *surface) {
    GLuint texture = 0;

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    // The SDL_Surface appears to have BGR_A formatting, however this ends up with a 
    // white rectangle no matter which colour i set in the previous code.
    int Mode = GL_RGB;

    if(surface->format->BytesPerPixel == 4) {
        Mode = GL_RGBA;
    }

    glTexImage2D(GL_TEXTURE_2D, 0, Mode, surface->w, surface->h, 0, Mode, 
                 GL_UNSIGNED_BYTE, surface->pixels);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return &texture;
}

Há um óbvio bits de código que eu estou ausente?
Obrigado por qualquer ajuda sobre este assunto.
Eu venho tentando aprender openGL e SDL por 3 dias agora, por favor, perdoe qualquer desinformação da minha parte.


EDITAR:

Eu notar que usando
TTF_RenderUTF8_Shaded
TTF_RenderUTF8_Solid

Lançar uma exceção de ponteiro nulo, o que significa que há um erro na real o processamento de texto de função (suspeito), eu não sei como isso significa TTF_RenderUTF8_Blended retorna um quadrado vermelho, mas eu suspeito que todos os problemas da dobradiça sobre isso.

Foi útil?

Solução

Acho que o problema está nas funções glEnable(GL_TEXTURE_2D) e glDisable(GL_TEXTURE_2D) que devem ser chamadas toda vez que o texto é pintado na tela. E talvez também a conversão de cores entre a superfície SDL e GL não esteja correta. Combinei create_texture e drawText em uma única função que exibe o texto corretamente.Este é o código:

void drawText(char * text, TTF_Font* tmpfont) {
SDL_Rect area;
SDL_Color clrFg = {0,0,255,0};
SDL_Surface *sText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended( tmpfont, text, clrFg ));
area.x = 0;area.y = 0;area.w = sText->w;area.h = sText->h;
SDL_Surface* temp = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA,sText->w,sText->h,32,0x000000ff,0x0000ff00,0x00ff0000,0x000000ff);
SDL_BlitSurface(sText, &area, temp, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sText->w, sText->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp->pixels);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); {
    glTexCoord2d(0, 0); glVertex3f(0, 0, 0);
    glTexCoord2d(1, 0); glVertex3f(0 + sText->w, 0, 0);
    glTexCoord2d(1, 1); glVertex3f(0 + sText->w, 0 + sText->h, 0);
    glTexCoord2d(0, 1); glVertex3f(0, 0 + sText->h, 0); 
} glEnd();
glDisable(GL_TEXTURE_2D);
SDL_FreeSurface( sText );
SDL_FreeSurface( temp );
} 

captura de tela

Estou inicializando o OpenGL da seguinte maneira:

int Init(){
glClearColor( 0.1, 0.2, 0.2, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, 600, 300, 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if( glGetError() != GL_NO_ERROR ){
    return false;
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);
} 

Outras dicas

Eu acho que você deve apenas adicionar glEnable (GL_BLEND), porque o código para a superfície do texto diz TTF_RenderUTF8_Blended (fntCourier, text, clrFg) e você deve habilitar as habilidades de mistura do opengl.

EDITAR

Ok, eu finalmente aproveitou o momento para colocar o seu código através de um compilador.O mais importante, o compilador com -Werror para que o aviso se transformar em erros

GLuint * create_texture(SDL_Surface *surface) {
    GLuint texture = 0;

    /*...*/

    return &texture;
}

Eu não vê-lo primeiro, porque é algo como C coder 101 e é bastante inesperado: Você não deve retornar ponteiros para variáveis locais!.Uma vez que as funções sai de escopo, o ponteiro retornado irá apontar para disparate só.Por que você retornar um ponteiro para todos?Apenas retornar um número inteiro:

GLuint create_texture(SDL_Surface *surface) {
    GLuint texture = 0;

    /*...*/

    return texture;
}

Devido a isso, você também não vai apagar a textura depois.Você faz o upload para o OpenGL, mas, em seguida, solta a referência para ele.


O código perde uma glEnable(GL_TEXTURE_2D) é por isso que você não pode ver os efeitos de textura. No entanto, o uso de texturas é de qualidade inferior.Da forma como você fez isso, você recriar uma nova textura cada vez que você for desenhar texto.Se isso acontece em uma animação em loop, você vai

  1. executado fora da memória de textura, ao invés de em breve
  2. diminuir significativamente

(1) podem ser resolvidos por não gerar uma nova textura nome de cada redesenho de

(2) pode ser endereços carregando uma nova textura de dados apenas quando as alterações de texto e não utilizando glTexImage2D, mas glTexSubImage2D (claro, se as dimensões da textura mudança, ela deve ser glTexImage2D).


EDITAR, encontrei um outro possível problema, mas primeiro corrigir o seu problema com o ponteiro.

Você deve se certificar de que você está usando GL_REPLACE ou GL_MODULATE textura ambiente de modo.Se utilizar GL_DECAL ou GL_BLEND você acabar com texto vermelho em vermelho quad.

Havia vazamento de memória da função em meu post anterior e o programa estava travando após algum tempo ... Eu melhorei isso separando o carregamento e a exibição da textura:

A primeira função deve ser chamada antes do loop SDL. Ela carrega a string de texto na memória:

Cada string carregada deve ter um parâmetro txtNum diferente

GLuint texture[100];
SDL_Rect area[100]; 
void Load_string(char * text, SDL_Color clr, int txtNum, const char* file, int ptsize){
    TTF_Font* tmpfont;
    tmpfont = TTF_OpenFont(file, ptsize); 
    SDL_Surface *sText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Solid( tmpfont, text, clr ));
    area[txtNum].x = 0;area[txtNum].y = 0;area[txtNum].w = sText->w;area[txtNum].h = sText->h;
    glGenTextures(1, &texture[txtNum]);
    glBindTexture(GL_TEXTURE_2D, texture[txtNum]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, sText->w, sText->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, sText->pixels);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    SDL_FreeSurface( sText );
    TTF_CloseFont(tmpfont);
 }

O segundo exibe a string, deve ser chamado no loop SDL:

void drawText(float coords[3], int txtNum) {
     glBindTexture(GL_TEXTURE_2D, texture[txtNum]);
     glEnable(GL_TEXTURE_2D);
     glBegin(GL_QUADS); {
     glTexCoord2f(0, 0); glVertex3f(coords[0], coords[1], coords[2]);
     glTexCoord2f(1, 0); glVertex3f(coords[0] + area[txtNum].w, coords[1], coords[2]);
     glTexCoord2f(1, 1); glVertex3f(coords[0] + area[txtNum].w, coords[1] + area[txtNum].h, coords[2]);
     glTexCoord2f(0, 1); glVertex3f(coords[0], coords[1] + area[txtNum].h, coords[2]); 
     } glEnd();
     glDisable(GL_TEXTURE_2D);
}

insira a descrição da imagem aqui

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top