#include "../gfxdevice.h"
#include "../gfxtools.h"
+#include "../MD5.h"
+#include "../types.h"
#include <math.h>
#include <time.h>
#include <stdarg.h>
//#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;
if(!verbose)
return;
va_start(arglist, format);
- vsprintf(buf, format, arglist);
+ vsnprintf(buf, sizeof(buf)-1, format, arglist);
va_end(arglist);
l = strlen(buf);
while(l && buf[l-1]=='\n') {
{
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)
{
- glEnd();
+ glEnd();
}
void CALLBACK vertexCallback(GLvoid *vertex)
{
}
void CALLBACK combineCallbackTex(GLdouble coords[3], GLdouble *data[4], GLfloat w[4], GLdouble **out)
{
- GLdouble *vertex, *texCoord;
+ GLdouble *vertex;
vertex = (GLdouble *) malloc(5 * sizeof(GLdouble));
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
- texCoord = &vertex[3];
- vertex[3] = w[0]*data[0][3] + w[1]*data[1][3] + w[2]*data[2][3] + w[3]*data[3][3];
- vertex[4] = w[0]*data[0][4] + w[1]*data[1][4] + w[2]*data[2][4] + w[3]*data[3][4];
+ if(data[2] && data[3]) {
+ vertex[3] = w[0]*data[0][3] + w[1]*data[1][3] + w[2]*data[2][3] + w[3]*data[3][3];
+ vertex[4] = w[0]*data[0][4] + w[1]*data[1][4] + w[2]*data[2][4] + w[3]*data[3][4];
+ } else {
+ vertex[3] = w[0]*data[0][3] + w[1]*data[1][3];
+ vertex[4] = w[0]*data[0][4] + w[1]*data[1][4];
+ }
*out = vertex;
}
glLineWidth(1.0);
}
+#define SPLINE_SUBDIVISION 2
+
void tesselatePolygon(GLUtesselator*tesselator, double z, gfxline_t*line)
{
int len = 0;
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;
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);
void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
{
double z;
- dbg("fill");
+ dbg("fill %02x%02x%02x%02x", color->a, color->r, color->g, color->b);
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 ++;
//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;
+ unsigned char*data;
+ struct _imgopengl*next;
+} imgopengl_t;
+
+static imgopengl_t*img2texid = 0;
+
+static 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;
+}
+
+static void delTextures()
+{
+ imgopengl_t*i = img2texid;
+ while(i) {
+ imgopengl_t*next = i->next;
+ if(i->data) {
+ glDeleteTextures(1, &i->texID);
+ free(i->data);
+ }
+ memset(i, 0, sizeof(imgopengl_t));
+ free(i);
+ i = next;
+ }
+}
+static 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_bits < img->width)
int newwidth = 1<<width_bits;
int newheight = 1<<height_bits;
+ while(i) {
+ if(gfxhash_compare(&hash, &i->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);
+ i->data = data;
int x,y;
for(y=0;y<img->height;y++) {
for(x=0;x<img->width;x++) {
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.7,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;
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
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;
}
}
-void opengl_drawlink(struct _gfxdevice*dev, gfxline_t*line, char*action)
+void opengl_drawlink(struct _gfxdevice*dev, gfxline_t*line, const char*action)
{
dbg("link");
}
dbg("endpage");
}
-int opengl_result_save(struct _gfxresult*gfx, char*filename)
+int opengl_result_save(struct _gfxresult*gfx, const char*filename)
{
dbg("result:save");
return 0;
}
-void* opengl_result_get(struct _gfxresult*gfx, char*name)
+void* opengl_result_get(struct _gfxresult*gfx, const char*name)
{
dbg("result:get");
return 0;
{
dbg("result:destroy");
free(gfx);
+ delTextures();
}
gfxresult_t*opengl_finish(struct _gfxdevice*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);