Domanda

Ho cercato di rendere un testo su una finestra openGL usa SDL e la SDL_TTF libreria su windows XP, VS2010.
Versioni:
Versione SDL 1.2.14
SDL TTF devel 1.2.10
openGL (versione è di almeno 2-3 anni).

Ho creato una finestra openGL usa SDL / SDL_image e possibile eseguire il rendering di linee e poligoni su di esso senza problemi.

Tuttavia, lo spostamento sul testo sembra che c'è qualche falla nel mio programma attuale, sto ottenendo il seguente risultato quando cercando questo codice qui

enter image description here

per chi non è disposto a pastebin, qui ci sono solo le crutial segmenti di codice:

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;
}

C'è un evidente po ' di codice mi manca?
Grazie per qualsiasi aiuto su questo argomento.
Sto cercando di imparare openGL e SDL per 3 giorni, così si prega di perdonare la mancata informazione da parte mia.


EDIT:

Ho notato che utilizzando
TTF_RenderUTF8_Shaded
TTF_RenderUTF8_Solid

Passi un puntatore null eccezione, nel senso che c'è un errore nel testo reale funzione di rendering (ho il sospetto), non so come, questo significa TTF_RenderUTF8_Blended restituisce un quadrato rosso, ma ho il sospetto che tutti i problemi cardine su questo.

È stato utile?

Soluzione

Penso che il problema sia nelle funzioni glEnable(GL_TEXTURE_2D) e glDisable(GL_TEXTURE_2D) che devono essere chiamate ogni volta che il testo viene dipinto sullo schermo e forse anche la conversione del colore tra la superficie SDL e GL non è corretta. Ho combinato create_texture e drawText in un'unica funzione che visualizza correttamente il testo.Questo è il codice:

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 );
} 

screenshot

Sto inizializzando OpenGL come segue:

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);
} 

Altri suggerimenti

Penso che dovresti semplicemente aggiungere glEnable (GL_BLEND), perché il codice per la superficie del testo dice TTF_RenderUTF8_Blended (fntCourier, text, clrFg) e devi abilitare le capacità di fusione di opengl.

MODIFICA

Ok, ho finalmente avuto il tempo di mettere il vostro codice tramite un compilatore.Ancora più importante, con il compilatore -Werror in modo che l'attenzione si trasformano in errori

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

    /*...*/

    return &texture;
}

Io non l'ho visto prima, perché è qualcosa di simile a C coder 101 ed è del tutto inaspettato: Non si deve restituire i puntatori a variabili locali!.Una volta che le funzioni in ambito il puntatore restituito punto di sciocchezze solo.Perché si ritorna un puntatore a tutti?Appena di ritorno da un numero intero:

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

    /*...*/

    return texture;
}

Perché di questo si sta, inoltre, non ha intenzione di eliminare la texture in seguito.La carichi su OpenGL, ma poi si perde il riferimento ad essa.


Il tuo codice manca un glEnable(GL_TEXTURE_2D) ecco perché non è possibile vedere gli effetti di texture. Tuttavia l'uso di texture non è ottimale.Nel modo in cui lo ha fatto, si ricrea una nuova texture ogni volta che si sta per disegnare il testo.Se ciò accade in un animazione in loop, ti

  1. il run-out di memoria texture piuttosto presto
  2. rallentare in modo significativo

(1) può essere affrontato da non generare una nuova texture nome di ogni ridisegnare

(2) possono essere indirizzi caricando nuove texture dati solo quando le modifiche del testo e non utilizzando glTexImage2D, ma glTexSubImage2D (naturalmente, se le dimensioni della texture cambiare, deve essere glTexImage2D).


EDIT, trovato un altro possibile problema, ma prima di fissare il puntatore problema.

È necessario assicurarsi che si sta utilizzando GL_REPLACE o GL_MODULATE texture modalità di ambiente.Se si utilizza GL_DECAL o GL_BLEND si finisce con il testo rosso su rosso quad.

Si è verificata una perdita di memoria della funzione nel mio post precedente e il programma si è bloccato dopo un po 'di tempo ... L'ho migliorato separando il caricamento della trama e la visualizzazione:

La prima funzione deve essere chiamata prima del ciclo SDL. Carica la stringa di testo in memoria:

Ogni stringa caricata deve avere un parametro txtNum diverso

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);
 }

Il secondo mostra la stringa, deve essere chiamato nel ciclo 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);
}

inserisci qui la descrizione dell'immagine

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top