X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fdevices%2Fopengl.c;h=c8efc053b12c71fe2a28c3a70efe4024c4a3ad8f;hb=b93de056e0b79f57c8f8fe22985b166c7d2c3dc3;hp=a789f542b3d5392ad5528332ada5c1550c909e60;hpb=48eadb4ee02aa85b77b8b232b1019eae468b3f81;p=swftools.git diff --git a/lib/devices/opengl.c b/lib/devices/opengl.c index a789f54..c8efc05 100644 --- a/lib/devices/opengl.c +++ b/lib/devices/opengl.c @@ -5,6 +5,8 @@ #include "../gfxdevice.h" #include "../gfxtools.h" +#include "../MD5.h" +#include "../types.h" #include #include @@ -14,7 +16,8 @@ #include //#define ZSTEP (1/65536.0) -#define ZSTEP (1/8.0) +#define ZSTEP (1/32.0) +//#define ZSTEP (1/4.0) typedef struct _fontlist { gfxfont_t*font; @@ -65,12 +68,12 @@ void CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); - dbg("Tessellation Error: %s\n", estring); + printf("Tessellation Error: %s\n", estring); exit(0); } void CALLBACK beginCallback(GLenum which) { - glBegin(which); + glBegin(which); } void CALLBACK endCallback(void) { @@ -179,6 +182,8 @@ void opengl_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t width, gfxc glLineWidth(1.0); } +#define SPLINE_SUBDIVISION 2 + void tesselatePolygon(GLUtesselator*tesselator, double z, gfxline_t*line) { int len = 0; @@ -191,7 +196,7 @@ void tesselatePolygon(GLUtesselator*tesselator, double z, gfxline_t*line) len = 0; while(l) { if(l->type == gfx_splineTo) { - double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))/2; + double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))*SPLINE_SUBDIVISION; int steps = (int)c; if(steps<1) steps = 1; len += steps; @@ -218,7 +223,7 @@ void tesselatePolygon(GLUtesselator*tesselator, double z, gfxline_t*line) if(l->type == gfx_splineTo) { int j; - double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))/2; + double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))*SPLINE_SUBDIVISION; int steps = (int)c; if(steps<1) steps = 1; //printf("c=%f d1=%f (%f/%f) d2=%f (%f/%f)\n", c,d1,l->x-l->sx,l->y-l->sy,d2,lastx-l->sx,lasty-l->sy); @@ -259,7 +264,8 @@ void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color) double z; dbg("fill"); internal_t*i = (internal_t*)dev->internal; - + + glDisable(GL_TEXTURE_2D); glColor4f(color->r/255.0, color->g/255.0, color->b/255.0, color->a/255.0); i->currentz ++; @@ -269,21 +275,41 @@ void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color) //tesselatePolygon(i->tesselator_line, z, line); } -void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform) +typedef struct _gfxhash { - dbg("fillbitmap"); - internal_t*i = (internal_t*)dev->internal; - char running = 0; - int len = 0; - double*xyz=0; - gfxline_t*l=0; - glColor4f(1.0,0,0,1.0); - - i->currentz ++; - - GLuint texIDs[1]; - glGenTextures(1, texIDs); + unsigned char d[16]; +} gfxhash_t; + +char gfxhash_compare(gfxhash_t*h1, gfxhash_t*h2) +{ + return !memcmp(h1->d, h2->d, 16); +} + +typedef struct _imgopengl +{ + gfxhash_t hash; + GLuint texID; + int width, height; + struct _imgopengl*next; +} imgopengl_t; + +imgopengl_t*img2texid = 0; +gfxhash_t gfximage_hash(gfximage_t*img) +{ + int t; + int size = img->width*img->height*4; + U8*data = (U8*)img->data; + gfxhash_t hash; + hash_md5(data, size, hash.d); + return hash; +} + +imgopengl_t*addTexture(gfximage_t*img) +{ + gfxhash_t hash = gfximage_hash(img); + imgopengl_t*i = img2texid; + int width_bits = 0; int height_bits = 0; while(1<width) @@ -293,6 +319,25 @@ void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gf int newwidth = 1<hash) && newwidth==i->width && newheight==i->height) { + return i; + } + i = i->next; + } + + GLuint texIDs[1]; + glGenTextures(1, texIDs); + + i = malloc(sizeof(imgopengl_t)); + i->hash = hash; + i->texID = texIDs[0]; + i->next = img2texid; + img2texid = i; + + i->width = newwidth; + i->height = newheight; + unsigned char*data = malloc(newwidth*newheight*4); int x,y; for(y=0;yheight;y++) { @@ -319,28 +364,45 @@ void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gf data[(y*newwidth+x)*4+3] = img->data[lasty*img->width+x].a; } } + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, i->texID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i->width, i->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + return i; +}; + +void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform) +{ + dbg("fillbitmap"); + internal_t*i = (internal_t*)dev->internal; + char running = 0; + int len = 0; + double*xyz=0; + gfxline_t*l=0; + glColor4f(1.0,0,0,1.0); + + i->currentz ++; + + imgopengl_t* txt = addTexture(img); gfxmatrix_t m2; gfxmatrix_invert(matrix, &m2); - m2.m00 /= newwidth; - m2.m10 /= newwidth; - m2.tx /= newwidth; - m2.m01 /= newheight; - m2.m11 /= newheight; - m2.ty /= newheight; + m2.m00 /= txt->width; + m2.m10 /= txt->width; + m2.tx /= txt->width; + m2.m01 /= txt->height; + m2.m11 /= txt->height; + m2.ty /= txt->height; glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texIDs[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newwidth, newheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, txt->texID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - gluTessBeginPolygon(i->tesselator_tex, NULL); l = line; len = 0; @@ -416,6 +478,8 @@ void opengl_addfont(gfxdevice_t*dev, gfxfont_t*font) void opengl_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix) { internal_t*i = (internal_t*)dev->internal; + if(!font) + return; if(i->font && i->font->id && !strcmp(font->id, i->font->id)) { // current font is correct @@ -430,8 +494,10 @@ void opengl_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*co l = l->next; } if(i->font == 0) { - fprintf(stderr, "Unknown font id: %s", font->id); - return; + opengl_addfont(dev, font); + i->font = font; + //fprintf(stderr, "Unknown font id: %s", font->id); + //return; } } @@ -518,7 +584,7 @@ void gfxdevice_opengl_init(gfxdevice_t*dev) gluTessCallback(i->tesselator, GLU_TESS_VERTEX, (callbackfunction_t)vertexCallback); gluTessCallback(i->tesselator, GLU_TESS_BEGIN, (callbackfunction_t)beginCallback); gluTessCallback(i->tesselator, GLU_TESS_END, (callbackfunction_t)endCallback); - //gluTessCallback(i->tesselator, GLU_TESS_COMBINE, (callbackfunction_t)combineCallback); + gluTessCallback(i->tesselator, GLU_TESS_COMBINE, (callbackfunction_t)combineCallback); i->tesselator_line = gluNewTess(); gluTessCallback(i->tesselator_line, GLU_TESS_ERROR, (callbackfunction_t)errorCallback);