Re: OpenGL overwrite example?

New Message Reply Date view Thread view Subject view Author view

Simon Hui (shui++at++kid.asd.sgi.com)
Wed, 19 Jun 96 14:44:46 -0700


> From: Jan Barglowski <jan++at++archimedes.vislab.navy.mil>
> Subject: OpenGL overwrite example?
>
> Problem is, I've found a few GL ways of doing this, but it
> doesn't seem to work with OpenGL at all. Here's my code:
>
> /* Open GL commands. */
> gluOrtho2D(-640.0, 640.0, -512.0, 512.0);
> glMatrixMode(GL_MODELVIEW);
> pfPushIdentMatrix();

Unlike ortho2() in IrisGL, gluOrtho2D() does not assume that the matrix
you want to change is the projection matrix. (For that matter, none of the
OpenGL matrix calls assume a particular matrix). It computes a matrix P,
and replaces the current matrix M with M*P.

So before calling gluOrtho2D(), you need to:

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D();

> Any pointers or (correct) code examples would be appreciated! Also, any
> way to display text in OpenGL? My OpenGL book has no examples of this :-(

Here's one.

Simon

-----------------------------------------------------------------------------

/*
 * Copyright (c) 1994, 1995, 1996 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee,
 * provided that (i) the above copyright notices and this permission
 * notice appear in all copies of the software and related documentation,
 * and (ii) the name of Silicon Graphics may not be used in any
 * advertising or publicity relating to the software without the specific,
 * prior written permission of Silicon Graphics.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
 * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */
/*
 * font.c
 *
 * Drawing fonts using OpenGL/GLX.
 *
 * Simon Hui, Silicon Graphics Inc., 1993
 *
 * compile: cc font.c -lGL -lXext -lX11 -lm -o font
 *
 * $Revision: 1.4 $
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <X11/keysym.h>

/* run xlsfonts to see other fonts supported by your X server */
#define FANCYFONT \
"-adobe-itc avant garde gothic-demi-o-normal--25-180-100-100-p-139-iso8859-1"
#define BASICFONT "10x20"

/* the base index for display list of entire font */
#define FONTBASE 0x1000
/* The base index for display list of just the alphabet */
#define ALPHABETBASE 0x8000

#define WHOLEFONT 1
#define ALPHABET 2
#define RAINBOW 3
   
long width = 600, height = 600;
Display *dpy;
XFontStruct *fontstruct;
   
char *string = "OpenGL";
char *fontname;

int mode = RAINBOW;
int glyphs, rows, cols, first, last;
int firstrow, lastrow;

init(void) {
    fontstruct = XLoadQueryFont(dpy, FANCYFONT);
    if (!fontstruct) {
        /* if the avant-garde font is not avail, try the simpler 10x20 font */
        fontstruct = XLoadQueryFont(dpy, BASICFONT);
        if (!fontstruct) {
            fprintf(stderr, "font %s not found\n", BASICFONT);
            exit(1);
        }
    }
    firstrow = fontstruct->min_byte1;
    lastrow = fontstruct->max_byte1;
    rows = lastrow - firstrow + 1;
    if (rows > 5) {
        printf ("only using first 5 rows of this multi-row font\n");
        rows = 5;
        lastrow = firstrow + rows - 1;
    }
    first = fontstruct->min_char_or_byte2;
    last = fontstruct->max_char_or_byte2;
    cols = last - first + 1;
    glyphs = cols;
     
    /*
    ** Define bitmaps for entire font.
    */
    glXUseXFont(fontstruct->fid, firstrow << 8, rows*256, FONTBASE);

    /*
    ** Define bitmaps for just the alphabet.
    */
    glXUseXFont(fontstruct->fid, 'A', 26, ALPHABETBASE);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-0.1, 1.1, -0.1, 1.1, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(1.0, 0.0, 1.0, 0.0);
}

drawAll(void) {
    int r;
    int i, j, c;
    int nrow, ncol=16;
    char buf[20];

    glColor3f(0.0, 0.0, 1.0);
    for (r=0; r < rows; r++) {
        glClear( GL_COLOR_BUFFER_BIT );
        c = FONTBASE + (r<<8);
        for (j=15; j > -1; j--) {
            for (i=0; i < 16; i++) {
                glRasterPos2f((float)i/16.0, (float)j/16.0);
                glCallList(c);
                c++;
            }
        }
        glFlush();
        if (rows > 1) {
            printf( "hit return to see next row of font>" );
            gets(buf);
        }
    }
}

drawAlphabet(void) {
    int i, j, c;
    int nrow=16, ncol=16;

    glColor3f(1.0, 0.0, 0.0);
    for (j=0; j < nrow; j++) {
        for (i=0; i < ncol; i++) {
            glRasterPos2f((float)i/ncol, (float)j/nrow);
            c = (j*ncol + i) % 26;
            glCallList(ALPHABETBASE + c);
        }
    }
}

static float colors[][3] = {
    {1, 0, 0},
    {1, 1, 0},
    {0, 1, 1},
    {1, 0, 1},
    {0, 0, 1},
};

drawRainbow(void) {
    int i, ncolors, nrows, h;
    float *this, *next;
    float r, g, b;
    float x, y, dx, dy;

    h = fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent;
    ncolors = sizeof(colors) / sizeof(colors[0]);
    nrows = 10;
    dx = 1.0 / ncolors;
    dy = 1.0 / nrows;

    glListBase(FONTBASE);
    x = 0;
    for (i=0; i < ncolors; i++) {
        for (y=0; y < 1; y+=dy) {
            this = colors[i];
            next = colors[(i+1)%ncolors];
            r = (y*next[0]) + (1-y)*this[0];
            g = (y*next[1]) + (1-y)*this[1];
            b = (y*next[2]) + (1-y)*this[2];
            glColor3f(r, g, b);
            glRasterPos2f(x, y);
            glCallLists(strlen(string), GL_BYTE, (GLubyte *)string);
        }
        x += dx;
    }
}

void draw(void) {
    glClearColor(.5, .5, .5, 1);
    glClear(GL_COLOR_BUFFER_BIT);
     
    switch(mode) {
      case WHOLEFONT:
        drawAll();
        break;
      case ALPHABET:
        drawAlphabet();
        break;
      case RAINBOW:
        drawRainbow();
        break;
    }
    glFlush();
}

static void usage(void)
{
    printf("Usage: tfont [-f fontname] [-s string] [-e]\n");
    exit(-1);
}

int main(int argc, char **argv)
{
    XEvent event;
    int i;

    for (i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            switch(argv[i][1]) {
              case 'f':
                fontname = argv[++i];
                break;
              case 's':
                string = argv[++i];
                break;
              default:
                usage();
                break;
            }
        } else {
            usage();
        }
    }
    makeWindow();
    init();
    for (;;) {
        do {
            XNextEvent(dpy, &event);
            switch (event.type) {
              case Expose:
                draw();
                break;
              case KeyPress:
                {
                    char buf[100];
                    int rv;
                    KeySym ks;

                    rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
                    switch (ks) {
                      case XK_a:
                        mode = WHOLEFONT;
                        draw();
                        break;
                      case XK_b:
                        mode = ALPHABET;
                        draw();
                        break;
                      case XK_r:
                        mode = RAINBOW;
                        draw();
                        break;
                      case XK_Escape:
                        exit(0);
                        break;
                    }
                }
                break;
            }
        } while (XPending(dpy) != 0);
    }
}

int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, None };

waitForMap(Display *d, XEvent *e, char *arg) {
    return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
}

fatal(const char *msg) {
    fprintf(stderr, "%s\n", msg);
    exit(EXIT_FAILURE);
}

makeWindow() {
    XEvent event;
    XSetWindowAttributes swa;
    XVisualInfo *vi;
    Window win;
    GLXContext cx;

    dpy = XOpenDisplay(0);
    if (!dpy) fatal("can't open display");
    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
    if (!vi) fatal("no suitable visual");
    cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
    swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
                                   vi->visual, AllocNone);
    swa.border_pixel = 0;
    swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height,
                        0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
    XStoreName(dpy, win, "videotex");
    XMapWindow(dpy, win);
    XIfEvent(dpy, &event, waitForMap, (char*)win);
    glXMakeCurrent(dpy, win, cx);
}

=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer.html
            Submissions: info-performer++at++sgi.com
        Admin. requests: info-performer-request++at++sgi.com


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:53:02 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.