From 3b21507274aa4f98644382903ae529c1fc2c7bd4 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 20 Aug 2014 01:36:33 +1000 Subject: GL3D GWIN window + demo --- 3rdparty/tinygl-0.4-ugfx/src/glx.c | 413 +++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 3rdparty/tinygl-0.4-ugfx/src/glx.c (limited to '3rdparty/tinygl-0.4-ugfx/src/glx.c') diff --git a/3rdparty/tinygl-0.4-ugfx/src/glx.c b/3rdparty/tinygl-0.4-ugfx/src/glx.c new file mode 100644 index 00000000..2c018128 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/glx.c @@ -0,0 +1,413 @@ +/* simple glx driver for TinyGL */ +#include +#include +#include +#include +#include "zgl.h" + +typedef struct { + GLContext *gl_context; + Display *display; + XVisualInfo visual_info; + int xsize,ysize; + XImage *ximage; + GC gc; + Colormap cmap; + Drawable drawable; + int do_convert; /* true if must do convertion to X11 format */ + /* shared memory */ + int shm_use; + XShmSegmentInfo *shm_info; + int CompletionType; +} TinyGLXContext; + +Bool glXQueryExtension( Display *dpy, int *errorb, int *event ) +{ + return True; +} + + +XVisualInfo* glXChooseVisual( Display *dpy, int screen, + int *attribList ) +{ + XVisualInfo vinfo; + int n; + + /* the attribList is ignored : we consider only RGBA rendering (no + direct color) */ + + if (XMatchVisualInfo (dpy, screen, 16, TrueColor, &vinfo)) { + /* 16 bit visual (fastest with TinyGL) */ + } else if (XMatchVisualInfo (dpy, screen, 24, TrueColor, &vinfo)) { + /* 24 bit visual */ + } else if (XMatchVisualInfo (dpy, screen, 32, TrueColor, &vinfo)) { + /* 32 bit visual */ + } else if (XMatchVisualInfo (dpy, screen, 8, PseudoColor, &vinfo)) { + /* 8 bit visual */ + } else { + /* no suitable visual */ + return NULL; + } + + return XGetVisualInfo(dpy,VisualAllMask,&vinfo,&n); +} + + + +GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, + GLXContext shareList, Bool direct ) +{ + TinyGLXContext *ctx; + + if (shareList != NULL) { + gl_fatal_error("No sharing available in TinyGL"); + } + ctx=gl_malloc(sizeof(TinyGLXContext)); + ctx->gl_context=NULL; + ctx->visual_info=*vis; + return (GLXContext) ctx; +} + + +void glXDestroyContext( Display *dpy, GLXContext ctx1 ) +{ + TinyGLXContext *ctx = (TinyGLXContext *) ctx1; + if (ctx->gl_context != NULL) { + glClose(); + } + gl_free(ctx); +} + + +static int glxXErrorFlag=0; + +static int glxHandleXError(Display *dpy,XErrorEvent *event) +{ + glxXErrorFlag=1; + return 0; +} + +static int bits_per_pixel(Display *dpy, XVisualInfo *visinfo) +{ + XImage *img; + int bpp; + char *data; + + data = gl_malloc(8); + if (data == NULL) + return visinfo->depth; + + img = XCreateImage(dpy, visinfo->visual, visinfo->depth, + ZPixmap, 0, data, 1, 1, 32, 0); + if (img == NULL) { + gl_free(data); + return visinfo->depth; + } + bpp = img->bits_per_pixel; + gl_free(data); + img->data = NULL; + XDestroyImage(img); + return bpp; +} + +static int create_ximage(TinyGLXContext *ctx, + int xsize,int ysize,int depth) +{ + int major,minor; + Bool pixmaps; + unsigned char *framebuffer; + int (*old_handler)(Display *,XErrorEvent *); + + if (XShmQueryVersion(ctx->display,&major,&minor,&pixmaps)) + ctx->shm_use=1; + else + ctx->shm_use=0; + + if (!ctx->shm_use) goto no_shm; + + ctx->shm_info=gl_malloc(sizeof(XShmSegmentInfo)); + ctx->ximage=XShmCreateImage(ctx->display,None,depth,ZPixmap,NULL, + ctx->shm_info,xsize,ysize); + if (ctx->ximage == NULL) { + fprintf(stderr,"XShm: error: XShmCreateImage\n"); + ctx->shm_use=0; + gl_free(ctx->shm_info); + goto no_shm; + } + ctx->shm_info->shmid=shmget(IPC_PRIVATE, + ctx->ysize*ctx->ximage->bytes_per_line, + IPC_CREAT | 0777); + if (ctx->shm_info->shmid < 0) { + fprintf(stderr,"XShm: error: shmget\n"); + no_shm1: + ctx->shm_use=0; + XDestroyImage(ctx->ximage); + goto no_shm; + } + ctx->ximage->data=shmat(ctx->shm_info->shmid,0,0); + if (ctx->ximage->data == (char *) -1) { + fprintf(stderr,"XShm: error: shmat\n"); + no_shm2: + shmctl(ctx->shm_info->shmid,IPC_RMID,0); + goto no_shm1; + } + ctx->shm_info->shmaddr=ctx->ximage->data; + + ctx->shm_info->readOnly=False; + + /* attach & test X errors */ + + glxXErrorFlag=0; + old_handler=XSetErrorHandler(glxHandleXError); + XShmAttach(ctx->display,ctx->shm_info); + XSync(ctx->display, False); + + if (glxXErrorFlag) { + XFlush(ctx->display); + shmdt(ctx->shm_info->shmaddr); + XSetErrorHandler(old_handler); + goto no_shm2; + } + + /* the shared memory will be automatically deleted */ + shmctl(ctx->shm_info->shmid,IPC_RMID,0); + + /* test with a dummy XShmPutImage */ + XShmPutImage(ctx->display,ctx->drawable,ctx->gc, + ctx->ximage,0,0,0,0,1,1, + False); + + XSync(ctx->display, False); + XSetErrorHandler(old_handler); + + if (glxXErrorFlag) { + fprintf(stderr,"XShm: error: XShmPutImage\n"); + XFlush(ctx->display); + shmdt(ctx->shm_info->shmaddr); + goto no_shm2; + } + + ctx->CompletionType=XShmGetEventBase(ctx->display) + ShmCompletion; + /* shared memory is OK !! */ + + return 0; + + no_shm: + ctx->ximage=XCreateImage(ctx->display, None, depth, ZPixmap, 0, + NULL,xsize,ysize, 8, 0); + framebuffer=gl_malloc(ysize * ctx->ximage->bytes_per_line); + ctx->ximage->data = framebuffer; + return 0; +} + +static void free_ximage(TinyGLXContext *ctx) +{ + if (ctx->shm_use) + { + XShmDetach(ctx->display, ctx->shm_info); + XDestroyImage(ctx->ximage); + shmdt(ctx->shm_info->shmaddr); + gl_free(ctx->shm_info); + } else { + gl_free(ctx->ximage->data); + XDestroyImage(ctx->ximage); + } +} + +/* resize the glx viewport : we try to use the xsize and ysize + given. We return the effective size which is guaranted to be smaller */ + +int glX_resize_viewport(GLContext *c,int *xsize_ptr,int *ysize_ptr) +{ + TinyGLXContext *ctx; + int xsize,ysize; + + ctx=(TinyGLXContext *)c->opaque; + + xsize=*xsize_ptr; + ysize=*ysize_ptr; + + /* we ensure that xsize and ysize are multiples of 2 for the zbuffer. + TODO: find a better solution */ + xsize&=~3; + ysize&=~3; + + if (xsize == 0 || ysize == 0) return -1; + + *xsize_ptr=xsize; + *ysize_ptr=ysize; + + if (ctx->ximage != NULL) free_ximage(ctx); + + ctx->xsize=xsize; + ctx->ysize=ysize; + + if (create_ximage(ctx,ctx->xsize,ctx->ysize,ctx->visual_info.depth) != 0) + return -1; + + /* resize the Z buffer */ + if (ctx->do_convert) { + ZB_resize(c->zb,NULL,xsize,ysize); + } else { + ZB_resize(c->zb,ctx->ximage->data,xsize,ysize); + } + return 0; +} + +/* we assume here that drawable is a window */ +Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, + GLXContext ctx1) +{ + TinyGLXContext *ctx = (TinyGLXContext *) ctx1; + XWindowAttributes attr; + int i,xsize,ysize; + unsigned int palette[ZB_NB_COLORS]; + unsigned char color_indexes[ZB_NB_COLORS]; + ZBuffer *zb; + XColor xcolor; + unsigned long pixel[ZB_NB_COLORS],tmp_plane; + + if (ctx->gl_context == NULL) { + /* create the TinyGL context */ + + ctx->display=dpy; + ctx->drawable=drawable; + + XGetWindowAttributes(ctx->display,drawable,&attr); + + xsize=attr.width; + ysize=attr.height; + + if (attr.depth != ctx->visual_info.depth) return False; + + /* ximage structure */ + ctx->ximage=NULL; + ctx->shm_use=1; /* use shm */ + + if (attr.depth == 8) { + /* get the colormap from the window */ + ctx->cmap = attr.colormap; + + if ( XAllocColorCells(ctx->display,ctx->cmap,True,&tmp_plane,0, + pixel,ZB_NB_COLORS) == 0) { + /* private cmap */ + ctx->cmap = XCreateColormap(ctx->display, drawable, + ctx->visual_info.visual, AllocAll); + XSetWindowColormap(ctx->display, drawable, ctx->cmap); + for(i=0;i>8) & 0xFF00; + xcolor.green = (palette[i] & 0xFF00); + xcolor.blue = (palette[i] << 8) & 0xFF00; + xcolor.pixel = pixel[i]; + XStoreColor(ctx->display,ctx->cmap,&xcolor); + } + ctx->do_convert = 1; + } else { + int mode,bpp; + /* RGB 16/24/32 */ + bpp = bits_per_pixel(ctx->display,&ctx->visual_info); + switch(bpp) { + case 24: + mode = ZB_MODE_RGB24; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + case 32: + mode = ZB_MODE_RGBA; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + default: + mode = ZB_MODE_5R6G5B; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + } + zb=ZB_open(xsize,ysize,mode,0,NULL,NULL,NULL); + if (zb == NULL) { + fprintf(stderr, "Error while initializing Z buffer\n"); + exit(1); + } + } + + /* create a gc */ + ctx->gc = XCreateGC(ctx->display, drawable, 0, 0); + + /* initialisation of the TinyGL interpreter */ + glInit(zb); + ctx->gl_context=gl_get_context(); + ctx->gl_context->opaque=(void *) ctx; + ctx->gl_context->gl_resize_viewport=glX_resize_viewport; + + /* set the viewport : we force a call to glX_resize_viewport */ + ctx->gl_context->viewport.xsize=-1; + ctx->gl_context->viewport.ysize=-1; + + glViewport(0, 0, xsize, ysize); + } + + return True; +} + +static Bool WaitForShmCompletion(Display *dpy, XEvent *event, char *arg) +{ + TinyGLXContext *ctx=(TinyGLXContext *) arg; + + return (event->type == ctx->CompletionType) && + ( ((XShmCompletionEvent *)event)->drawable == (Window)ctx->drawable); +} + +void glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + GLContext *gl_context; + TinyGLXContext *ctx; + + /* retrieve the current GLXContext */ + gl_context=gl_get_context(); + ctx=(TinyGLXContext *)gl_context->opaque; + + /* for non 16 bits visuals, a conversion is required */ + + + if (ctx->do_convert) { + ZB_copyFrameBuffer(ctx->gl_context->zb, + ctx->ximage->data, + ctx->ximage->bytes_per_line); + + } + + /* draw the ximage */ + if (ctx->shm_use) { + XEvent event; + + XShmPutImage(dpy,drawable,ctx->gc, + ctx->ximage,0,0,0,0,ctx->ximage->width, ctx->ximage->height, + True); + XIfEvent(dpy, &event, WaitForShmCompletion, (char*)ctx); + } else { + XPutImage(dpy, drawable, ctx->gc, + ctx->ximage, 0, 0, 0, 0, ctx->ximage->width, ctx->ximage->height); + } + XFlush(dpy); +} + + +void glXWaitGL( void ) +{ +} + +void glXWaitX( void ) +{ +} -- cgit v1.2.3