XdrawString+double buffer

dragoran dragoran at feuerpokemon.de
Mon Jul 31 09:29:30 PDT 2006


Brian Paul wrote:
> dragoran wrote:
>> Brian Paul wrote:
>>
>>> dragoran wrote:
>>>
>>>> Hello
>>>> I am working on a wrapper around glxSwapbuffers. I want to display 
>>>> text in openglapps.
>>>> I have tryed many different things like textures,gldrawpixels, etc. 
>>>> but none of the works in all apps.
>>>> ut2004 does not even like the gldrawpixel version.
>>>> so I tryed using Xdrawstring which works in all of this apps but it 
>>>> flackers because of double buffering.
>>>> how can I avoid this?
>>>> here is my code, it simply displays "test" on the appwindow...
>>>>
>>>> void glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
>>>> #ifdef DEBUG
>>>>    fprintf(stderr,"about to draw hud ;)\n");
>>>> #endif
>>>>    Colormap cmap;
>>>>    XColor c0, c1;
>>>>    cmap = DefaultColormap(dpy, 0);
>>>>    XAllocNamedColor(dpy, cmap, "red", &c1, &c0);
>>>>    XGCValues values;
>>>>    GC maingc=XCreateGC(dpy, drawable, 0 ,&values);
>>>>    XSetForeground(dpy, maingc, c1.pixel);     
>>>> XDrawString(dpy,drawable, maingc, 20, 50, "test",4);
>>>>    pglXSwapBuffers(dpy, drawable); }
>>>
>>>
>>> It might work better to put the XDrawString() call after the 
>>> SwapBuffers().
>>>
>>> Also, you may need a glXWaitGL() call between them.
>>>
>>> -Brian
>>>
>>>
>> hello
>> now I have tryed with
>> pglXSwapBuffers(dpy, drawable);
>>    glXWaitGL();
>>    XDrawString(dpy,drawable, maingc, 20, 50, "test",4);
>> the only thing that this causes are lower framerates but teh 
>> flickering isn't gone
>
> I guess the only flicker-free solution is to draw the text with OpenGL 
> commands prior to SwapBuffers().  Have you tried glWindowPos/glBitmap()?
>
first I did this:
void glEnable2D()
{
    int vPort[4];
 
    glGetIntegerv(GL_VIEWPORT, vPort);
 
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
 
    glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
}

void glDisable2D()
{
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();  
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();   
}

void SDL_GL_RenderText(char *text, TTF_Font *font, SDL_Color color, 
SDL_Rect *location) {
    SDL_Surface *initial;
    SDL_Surface *intermediary;
    SDL_Rect rect;
    int w,h;
    int texture;
   
    /* Use SDL_TTF to render our text */
    initial = TTF_RenderText_Blended(font, text, color);
   
    /* Convert the rendered text to a known format */
    w = nextpoweroftwo(initial->w);
    h = nextpoweroftwo(initial->h);
   
    intermediary = SDL_CreateRGBSurface(0, w, h, 32,
            0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

    SDL_BlitSurface(initial, 0, intermediary, 0);
   
    /* Tell GL about our new texture */
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA,
            GL_UNSIGNED_BYTE, intermediary->pixels );
   
    /* GL_NEAREST looks horrible, if scaled... */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   

    /* prepare to render our texture */
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glColor3f(1.0f, 1.0f, 1.0f);
   
    /* Draw a quad at location */
    glBegin(GL_QUADS);
        /* Recall that the origin is in the lower-left corner
           That is why the TexCoords specify different corners
           than the Vertex coors seem to. */
        glTexCoord2f(0.0f, 1.0f);
            glVertex2f(location->x    , location->y);
        glTexCoord2f(1.0f, 1.0f);
            glVertex2f(location->x + w, location->y);
        glTexCoord2f(1.0f, 0.0f);
            glVertex2f(location->x + w, location->y + h);
        glTexCoord2f(0.0f, 0.0f);
            glVertex2f(location->x    , location->y + h);
    glEnd();
   
    /* Bad things happen if we delete the texture before it finishes */
    glFinish();
   
    /* return the deltas in the unused w,h part of the rect */
    location->w = initial->w;
    location->h = initial->h;
   
    /* Clean up */
    SDL_FreeSurface(initial);
    SDL_FreeSurface(intermediary);
    glDeleteTextures(1, &texture);
}


void show_hud() {   
    static TTF_Font* font;
    static SDL_Color color;
    SDL_Rect position;
    if(init_done==0) {
        TTF_Init();
        if(!(font = TTF_OpenFont(fontpath, 20))) {
            fprintf(stderr,"Error loading font: %s", TTF_GetError());
            exit(1);
        }
        init_done=1;
    }
    /* Go in HUD-drawing mode */
    glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | 
GL_LINE_BIT | GL_TRANSFORM_BIT);
    glEnable2D();
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);
    glDisable(GL_FOG);
    glDisable(GL_LINE_STIPPLE);
    glDisable(GL_ALPHA_TEST);
    glDepthMask(0);
    color.r = 255;
    color.g = 255;
    color.b = 255;
    position.x=0;
    position.y=0;
    SDL_GL_RenderText("Test ;)", font, color, &position);
    glRasterPos2i(20,20);
    /*int raster[4];
    glGetFloatv(GL_CURRENT_RASTER_POSITION,&raster);
    fprintf(stderr,"rasterposition: 
x=%.1f,y=%.1f,z=%.1f\n",raster[0],raster[1],raster[2]);
    unsigned char pixels[100][100];
    glDrawPixels(100,100,GL_RED,GL_UNSIGNED_BYTE,&pixels);*/
    /* Come out of HUD mode */
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_ALPHA_TEST);
    glEnable(GL_LINE_STIPPLE);
    glEnable(GL_BLEND);
    glEnable(GL_FOG);
    glEnable(GL_LIGHTING);
    glDepthMask(1);
    glDisable2D();
    glPopAttrib();
#ifdef DEBUG
    /*const GLubyte *errString;
    GLuint errCode;
    if ((errCode = glGetError()) != GL_NO_ERROR) {
        errString = gluErrorString(errCode);
       fprintf (stderr, "OpenGL Error: %s\n", errString);
    }*/
#endif

}

and called showhud() before swapbuffers the problem was that it worked 
fine in glxgears and ogre based games but not in 
quake4/doom3/ut2004/nexiuz-glx/nexuiz-sdl
before this I have tryed to use bitmap fonts used rasteroperations but 
the problem was that it didn't even work in glxgears.
the commented out stuff was the test using glxdrawpixels with did not 
work in ut2004... glDrawpixels is slow too.
the main problem that I have is that I really don't know what the app 
does my code is called in a wrapper before SwapBuffers()
> -Brian
>
>




More information about the xorg mailing list