Author: manolo
Date: 2010-04-10 06:04:26 -0700 (Sat, 10 Apr 2010)
New Revision: 7477
Log:
gl_draw.cxx: implemented a fifo of pre-computed textures for GL text display
(Mac only)
Modified:
branches/branch-1.3-Fl_Printer/FL/gl.h
branches/branch-1.3-Fl_Printer/src/gl_draw.cxx
Modified: branches/branch-1.3-Fl_Printer/FL/gl.h
===================================================================
--- branches/branch-1.3-Fl_Printer/FL/gl.h 2010-04-09 22:18:05 UTC (rev
7476)
+++ branches/branch-1.3-Fl_Printer/FL/gl.h 2010-04-10 13:04:26 UTC (rev
7477)
@@ -98,6 +98,10 @@
FL_EXPORT void gl_draw(const char*, int n, float x, float y);
FL_EXPORT void gl_draw(const char*, int x, int y, int w, int h, Fl_Align);
FL_EXPORT void gl_measure(const char*, int& x, int& y);
+#ifdef __APPLE__
+extern FL_EXPORT void gl_texture_pile_height(int max);
+extern FL_EXPORT int gl_texture_pile_height();
+#endif
FL_EXPORT void gl_draw_image(const uchar *, int x,int y,int w,int h, int d=3,
int ld=0);
Modified: branches/branch-1.3-Fl_Printer/src/gl_draw.cxx
===================================================================
--- branches/branch-1.3-Fl_Printer/src/gl_draw.cxx 2010-04-09 22:18:05 UTC
(rev 7476)
+++ branches/branch-1.3-Fl_Printer/src/gl_draw.cxx 2010-04-10 13:04:26 UTC
(rev 7477)
@@ -29,7 +29,7 @@
// See also Fl_Gl_Window and gl_start.cxx
#include "flstring.h"
-#if HAVE_GL
+#if HAVE_GL || defined(FL_DOXYGEN)
#include <FL/Fl.H>
#include <FL/gl.h>
@@ -189,7 +189,7 @@
past->next = f->next;
}
- // It would be nice if this next line was in a desctructor somewhere
+ // It would be nice if this next line was in a destructor somewhere
glDeleteLists(f->listbase, 256);
Fl_Font_Descriptor* tmp = f;
@@ -360,20 +360,55 @@
glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
}
-#ifdef __APPLE__
+#if defined( __APPLE__) || defined(FL_DOXYGEN)
#include <FL/glu.h>
-static int texture_count = 0;
-static const int texture_total = 50;
-static GLuint texName[texture_total];
-static char *string_table[texture_total];
-static int length_table[texture_total];
-static int width_table[texture_total];
-static int height_table[texture_total];
+// manages a fifo pile of pre-computed string textures
+class gl_texture_fifo {
+ friend void gl_draw_cocoa(const char *, int);
+private:
+ typedef struct { // information for a pre-computed texture
+ GLuint texName; // its name
+ char *utf8; //its text
+ Fl_Font_Descriptor *fdesc; // its font
+ int width; // its width
+ int height; // its height
+ } data;
+ data *fifo; // array of pile elements
+ int size_; // pile height
+ int current; // the oldest texture to have entered the pile
+ int last; // pile top
+ int textures_generated; // true iff glGenTextures has been called
+ void display_texture(int rank);
+ int compute_texture(const char* str, int n);
+ int already_known(const char *str, int n);
+public:
+ gl_texture_fifo(int max = 100); // 100 = default height of texture pile
+ inline int size(void) {return size_; };
+ ~gl_texture_fifo(void);
+};
-static void display_texture(int rank)
+gl_texture_fifo::gl_texture_fifo(int max)
{
+ size_ = max;
+ last = current = -1;
+ textures_generated = 0;
+ fifo = (data*)calloc(size_, sizeof(data));
+}
+
+gl_texture_fifo::~gl_texture_fifo()
+{
+ for (int i = 0; i < size_; i++) {
+ if (fifo[i].utf8) free(fifo[i].utf8);
+ if (textures_generated) glDeleteTextures(1, &fifo[i].texName);
+ }
+ free(fifo);
+}
+
+// displays a pre-computed texture on the GL scene
+void gl_texture_fifo::display_texture(int rank)
+{
//setup matrices
GLint matrixMode;
glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
@@ -390,7 +425,7 @@
//write the texture on screen
GLfloat pos[4];
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
- CGRect bounds = CGRectMake (pos[0], pos[1] - fl_descent(),
width_table[rank], height_table[rank]);
+ CGRect bounds = CGRectMake (pos[0], pos[1] - fl_descent(), fifo[rank].width,
fifo[rank].height);
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); //
GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer
test.
@@ -398,18 +433,18 @@
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
glEnable (GL_TEXTURE_RECTANGLE_EXT);
- glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName[rank]);
+ glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[rank].texName);
glBegin (GL_QUADS);
glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates
glVertex2f (bounds.origin.x, bounds.origin.y);
- glTexCoord2f (0.0f, height_table[rank]); // draw upper left in world
coordinates
+ glTexCoord2f (0.0f, fifo[rank].height); // draw upper left in world
coordinates
glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
- glTexCoord2f (width_table[rank], height_table[rank]); // draw upper right in
world coordinates
+ glTexCoord2f (fifo[rank].width, fifo[rank].height); // draw upper right in
world coordinates
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y +
bounds.size.height);
- glTexCoord2f (width_table[rank], 0.0f); // draw lower right in world
coordinates
+ glTexCoord2f (fifo[rank].width, 0.0f); // draw lower right in world
coordinates
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
glEnd ();
@@ -421,7 +456,7 @@
glMatrixMode (matrixMode);
//set the raster position to end of string
- pos[0] += width_table[rank];
+ pos[0] += fifo[rank].width;
GLdouble modelmat[16];
glGetDoublev (GL_MODELVIEW_MATRIX, modelmat);
GLdouble projmat[16];
@@ -432,71 +467,97 @@
gluUnProject(pos[0], pos[1], pos[2], modelmat, projmat, viewport, &objX,
&objY, &objZ);
glRasterPos2d(objX, objY);
}
-
-int compute_texture(const char* str, int n)
+
+// pre-computes a string texture
+int gl_texture_fifo::compute_texture(const char* str, int n)
{
- int rank;
- if (texture_count == texture_total) {
- glDeleteTextures(1, texName);
- free(string_table[0]);
- memmove(texName, texName + 1, (texture_total-1)*sizeof(GLuint));
- memmove(length_table, length_table + 1, (texture_total-1)*sizeof(int));
- memmove(string_table, string_table + 1, (texture_total-1)*sizeof(char *));
- rank = texture_count - 1;
- }
- else {
- rank = texture_count++;
- }
-//write str to a bitmap just big enough
- width_table[rank] = 0, height_table[rank] = 0;
- fl_measure(str, width_table[rank], height_table[rank], 0);
+ current = (current + 1) % size_;
+ if (current > last) last = current;
+ //write str to a bitmap just big enough
+ fifo[current].width = 0, fifo[current].height = 0;
+ fl_measure(str, fifo[current].width, fifo[current].height, 0);
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
- void *base = calloc(4*width_table[rank], height_table[rank]);
- if(base == NULL) return -1;
- fl_gc = CGBitmapContextCreate(base, width_table[rank], height_table[rank],
8, width_table[rank]*4, lut, kCGImageAlphaPremultipliedLast);
+ void *base = calloc(4*fifo[current].width, fifo[current].height);
+ if (base == NULL) return -1;
+ fl_gc = CGBitmapContextCreate(base, fifo[current].width,
fifo[current].height, 8, fifo[current].width*4, lut,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(lut);
fl_fontsize = gl_fontsize;
- fl_draw(str, 0, height_table[rank] - fl_descent());
-//put this bitmap in a texture
+ fl_draw(str, 0, fifo[current].height - fl_descent());
+ //put this bitmap in a texture
glPushAttrib(GL_TEXTURE_BIT);
- glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName[rank]);
+ glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[current].texName);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width_table[rank],
height_table[rank], 0, GL_RGBA, GL_UNSIGNED_BYTE, base);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, fifo[current].width,
fifo[current].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, base);
glPopAttrib();
CGContextRelease(fl_gc);
fl_gc = NULL;
free(base);
- string_table[rank] = (char *)malloc(n);
- memcpy(string_table[rank], str, n);
- length_table[rank] = n;
- return rank;
+ if ( fifo[current].utf8 ) free(fifo[current].utf8);
+ fifo[current].utf8 = (char *)malloc(n + 1);
+ memcpy(fifo[current].utf8, str, n);
+ fifo[current].utf8[n] = 0;
+ fifo[current].fdesc = gl_fontsize;
+ return current;
}
-static int already_known(const char *str, int n)
+// returns rank of pre-computed texture for a string if it exists
+int gl_texture_fifo::already_known(const char *str, int n)
{
int rank;
- for ( rank = 0; rank < texture_count; rank++) {
- if(n == length_table[rank] && memcmp(str, string_table[rank], n) == 0)
return rank;
- }
+ for ( rank = 0; rank <= last; rank++) {
+ if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 &&
+ fifo[rank].fdesc == gl_fontsize) return rank;
+ }
return -1;
}
+static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class
instance
+
+// draws a utf8 string using pre-computed texture if available
static void gl_draw_cocoa(const char* str, int n)
{
- static int first = true;
- if(first) {
- first = false;
- glGenTextures (texture_total, texName);
- texture_count = 0;
+ if (! gl_fifo) gl_fifo = new gl_texture_fifo();
+ if (!gl_fifo->textures_generated) {
+ for (int i = 0; i < gl_fifo->size_; i++) glGenTextures (1,
&(gl_fifo->fifo[i].texName));
+ gl_fifo->textures_generated = 1;
}
- int rank = already_known(str, n);
- if(rank == -1) {
- rank = compute_texture(str, n);
+ int rank = gl_fifo->already_known(str, n);
+ if (rank == -1) {
+ rank = gl_fifo->compute_texture(str, n);
}
- display_texture(rank);
+ gl_fifo->display_texture(rank);
}
+/** \addtogroup group_macosx
+ @{ */
+
+/**
+ \brief Returns the current height of the pile of pre-computed string textures
+ *
+ The default value is 100.
+ */
+int gl_texture_pile_height(void)
+{
+ if (! gl_fifo) gl_fifo = new gl_texture_fifo();
+ return gl_fifo->size();
+}
+
+/**
+ \brief Changes the height of the pile of pre-computed string textures
+ *
+ Strings that are often re-displayed can be processed much faster if
+ this pile is set high enough to hold all of them.
+ \param max Height of the texture pile
+ */
+void gl_texture_pile_height(int max)
+{
+ if (gl_fifo) delete gl_fifo;
+ gl_fifo = new gl_texture_fifo(max);
+}
+
+/** @} */
+
#endif // __APPLE__
#endif // HAVE_GL
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit