diff options
author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 |
commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/srcgl |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srcgl')
-rwxr-xr-x | iup/srcgl/Makefile | 6 | ||||
-rwxr-xr-x | iup/srcgl/config.mak | 20 | ||||
-rwxr-xr-x | iup/srcgl/iup_glcanvas_win.c | 411 | ||||
-rwxr-xr-x | iup/srcgl/iup_glcanvas_x.c | 448 | ||||
-rwxr-xr-x | iup/srcgl/iupgl.def | 9 | ||||
-rw-r--r-- | iup/srcgl/iupgl.dep | 5 | ||||
-rwxr-xr-x | iup/srcgl/make_uname | 3 | ||||
-rwxr-xr-x | iup/srcgl/make_uname.bat | 4 |
8 files changed, 906 insertions, 0 deletions
diff --git a/iup/srcgl/Makefile b/iup/srcgl/Makefile new file mode 100755 index 0000000..882d0d2 --- /dev/null +++ b/iup/srcgl/Makefile @@ -0,0 +1,6 @@ + +.PHONY: do_all iupgl +do_all: iupgl + +iupgl: + @$(MAKE) --no-print-directory -f ../tecmake_compact.mak diff --git a/iup/srcgl/config.mak b/iup/srcgl/config.mak new file mode 100755 index 0000000..49599a5 --- /dev/null +++ b/iup/srcgl/config.mak @@ -0,0 +1,20 @@ +PROJNAME = iup +LIBNAME = iupgl +OPT = YES + +ifdef DBG + DEFINES += IUP_ASSERT +endif + +INCLUDES = ../include ../src +LDIR = ../lib/$(TEC_UNAME) +LIBS = iup + +USE_OPENGL = Yes + +ifneq ($(findstring Win, $(TEC_SYSNAME)), ) + SRC = iup_glcanvas_win.c +else + SRC = iup_glcanvas_x.c + USE_X11 = Yes +endif diff --git a/iup/srcgl/iup_glcanvas_win.c b/iup/srcgl/iup_glcanvas_win.c new file mode 100755 index 0000000..06cb66b --- /dev/null +++ b/iup/srcgl/iup_glcanvas_win.c @@ -0,0 +1,411 @@ +/** \file + * \brief iupgl control for Windows + * + * See Copyright Notice in "iup.h" + */ + +#include <windows.h> +#include <GL/gl.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <memory.h> + +#include "iup.h" +#include "iupcbs.h" +#include "iupgl.h" + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_stdcontrols.h" +#include "iup_assert.h" +#include "iup_register.h" + + +struct _IcontrolData +{ + iupCanvas canvas; /* from IupCanvas (must reserve it) */ + HWND window; + HDC device; + HGLRC context; + HPALETTE palette; + int is_owned_dc; +}; + +static int wGLCanvasDefaultResize_CB(Ihandle *ih, int width, int height) +{ + IupGLMakeCurrent(ih); + glViewport(0,0,width,height); + return IUP_DEFAULT; +} + +static int wGLCanvasCreateMethod(Ihandle* ih, void** params) +{ + (void)params; + free(ih->data); /* allocated by the iCanvasCreateMethod of IupCanvas */ + ih->data = iupALLOCCTRLDATA(); + IupSetCallback(ih, "RESIZE_CB", (Icallback)wGLCanvasDefaultResize_CB); + return IUP_NOERROR; +} + +static int wGLCreateContext(Ihandle* ih) +{ + Ihandle* ih_shared; + int number; + int isIndex = 0; + int pixelFormat; + PIXELFORMATDESCRIPTOR test_pfd; + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ + 1, /* version number */ + PFD_DRAW_TO_WINDOW | /* support window */ + PFD_SUPPORT_OPENGL, /* support OpenGL */ + PFD_TYPE_RGBA, /* RGBA type */ + 24, /* 24-bit color depth */ + 0, 0, 0, 0, 0, 0, /* color bits ignored */ + 0, /* no alpha buffer */ + 0, /* shift bit ignored */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits ignored */ + 16, /* 32-bit z-buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffer */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0 /* layer masks ignored */ + }; + + /* the IupCanvas is already mapped, just initialize the OpenGL context */ + + /* double or single buffer */ + if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE")) + pfd.dwFlags |= PFD_DOUBLEBUFFER; + + /* stereo */ + if (iupAttribGetBoolean(ih,"STEREO")) + pfd.dwFlags |= PFD_STEREO; + + /* rgba or index */ + if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX")) + { + isIndex = 1; + pfd.iPixelType = PFD_TYPE_COLORINDEX; + pfd.cColorBits = 8; /* assume 8 bits when indexed */ + number = iupAttribGetInt(ih,"BUFFER_SIZE"); + if (number > 0) pfd.cColorBits = (BYTE)number; + } + + /* red, green, blue bits */ + number = iupAttribGetInt(ih,"RED_SIZE"); + if (number > 0) pfd.cRedBits = (BYTE)number; + pfd.cRedShift = 0; + + number = iupAttribGetInt(ih,"GREEN_SIZE"); + if (number > 0) pfd.cGreenBits = (BYTE)number; + pfd.cGreenShift = pfd.cRedBits; + + number = iupAttribGetInt(ih,"BLUE_SIZE"); + if (number > 0) pfd.cBlueBits = (BYTE)number; + pfd.cBlueShift = pfd.cRedBits + pfd.cGreenBits; + + number = iupAttribGetInt(ih,"ALPHA_SIZE"); + if (number > 0) pfd.cAlphaBits = (BYTE)number; + pfd.cAlphaShift = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits; + + /* depth and stencil size */ + number = iupAttribGetInt(ih,"DEPTH_SIZE"); + if (number > 0) pfd.cDepthBits = (BYTE)number; + + /* stencil */ + number = iupAttribGetInt(ih,"STENCIL_SIZE"); + if (number > 0) pfd.cStencilBits = (BYTE)number; + + /* red, green, blue accumulation bits */ + number = iupAttribGetInt(ih,"ACCUM_RED_SIZE"); + if (number > 0) pfd.cAccumRedBits = (BYTE)number; + + number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE"); + if (number > 0) pfd.cAccumGreenBits = (BYTE)number; + + number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE"); + if (number > 0) pfd.cAccumBlueBits = (BYTE)number; + + number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE"); + if (number > 0) pfd.cAccumAlphaBits = (BYTE)number; + + pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits; + + /* get a device context */ + { + LONG style = GetClassLong(ih->data->window, GCL_STYLE); + ih->data->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC)); + } + + ih->data->device = GetDC(ih->data->window); + iupAttribSetStr(ih, "VISUAL", (char*)ih->data->device); + + /* choose pixel format */ + pixelFormat = ChoosePixelFormat(ih->data->device, &pfd); + if (pixelFormat == 0) + { + iupAttribSetStr(ih, "ERROR", "No appropriate pixel format."); + return IUP_NOERROR; + } + SetPixelFormat(ih->data->device,pixelFormat,&pfd); + + /* create rendering context */ + ih->data->context = wglCreateContext(ih->data->device); + if (!ih->data->context) + { + iupAttribSetStr(ih, "ERROR", "Could not create a rendering context."); + return IUP_NOERROR; + } + iupAttribSetStr(ih, "CONTEXT", (char*)ih->data->context); + + ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT"); + if (ih_shared && iupStrEqual(ih_shared->iclass->name, "glcanvas")) /* must be an IupGLCanvas */ + wglShareLists(ih_shared->data->context, ih->data->context); + + DescribePixelFormat(ih->data->device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &test_pfd); + if ((pfd.dwFlags & PFD_STEREO) && !(test_pfd.dwFlags & PFD_STEREO)) + { + iupAttribSetStr(ih, "ERROR", "Stereo not available."); + return IUP_NOERROR; + } + + /* create colormap for index mode */ + if (isIndex) + { + if (!ih->data->palette) + { + LOGPALETTE lp = {0x300,1,{255,255,255,PC_NOCOLLAPSE}}; /* set first color as white */ + ih->data->palette = CreatePalette(&lp); + ResizePalette(ih->data->palette,1<<pfd.cColorBits); + iupAttribSetStr(ih, "COLORMAP", (char*)ih->data->palette); + } + + SelectPalette(ih->data->device,ih->data->palette,FALSE); + RealizePalette(ih->data->device); + } + + return IUP_NOERROR; +} + +static int wGLCanvasMapMethod(Ihandle* ih) +{ + /* get a device context */ + ih->data->window = (HWND)iupAttribGet(ih, "HWND"); /* check first in the hash table, can be defined by the IupFileDlg */ + if (!ih->data->window) + ih->data->window = (HWND)IupGetAttribute(ih, "HWND"); /* works for Win32 and GTK, only after mapping the IupCanvas */ + if (!ih->data->window) + return IUP_NOERROR; + + { + LONG style = GetClassLong(ih->data->window, GCL_STYLE); + ih->data->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC)); + } + + return wGLCreateContext(ih); +} + +static void wGLCanvasUnMapMethod(Ihandle* ih) +{ + if (ih->data->context) + { + if (ih->data->context == wglGetCurrentContext()) + wglMakeCurrent(NULL, NULL); + + wglDeleteContext(ih->data->context); + } + + if (ih->data->palette) + DeleteObject((HGDIOBJ)ih->data->palette); + + if (ih->data->device) + ReleaseDC(ih->data->window, ih->data->device); +} + +static int wGLCanvasSetRefreshContextAttrib(Ihandle* ih, const char* value) +{ + if (!ih->data->is_owned_dc) + { + if (ih->data->context) + { + if (ih->data->context == wglGetCurrentContext()) + wglMakeCurrent(NULL, NULL); + + wglDeleteContext(ih->data->context); + } + + if (ih->data->device) + ReleaseDC(ih->data->window, ih->data->device); + + wGLCreateContext(ih); + } + + (void)value; + return 0; +} + +static Iclass* wGlCanvasGetClass(void) +{ + Iclass* ic = iupClassNew(iupCanvasGetClass()); + + ic->name = "glcanvas"; + ic->format = "A"; /* one optional callback name */ + ic->nativetype = IUP_TYPECANVAS; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 1; + + ic->Create = wGLCanvasCreateMethod; + ic->Map = wGLCanvasMapMethod; + ic->UnMap = wGLCanvasUnMapMethod; + + iupClassRegisterAttribute(ic, "BUFFER", NULL, NULL, IUPAF_SAMEASSYSTEM, "SINGLE", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "COLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "RGBA", IUPAF_DEFAULT); + + iupClassRegisterAttribute(ic, "CONTEXT", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING); + iupClassRegisterAttribute(ic, "VISUAL", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING); + iupClassRegisterAttribute(ic, "COLORMAP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING); + + iupClassRegisterAttribute(ic, "REFRESHCONTEXT", NULL, wGLCanvasSetRefreshContextAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); + + return ic; +} + +/******************************************* Exported functions */ + +void IupGLCanvasOpen(void) +{ + if (!IupGetGlobal("_IUP_GLCANVAS_OPEN")) + { + iupRegisterClass(wGlCanvasGetClass()); + IupSetGlobal("_IUP_GLCANVAS_OPEN", "1"); + } +} + +Ihandle* IupGLCanvas(const char *action) +{ + void *params[2]; + params[0] = (void*)action; + params[1] = NULL; + return IupCreatev("glcanvas", params); +} + +int IupGLIsCurrent(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return 0; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return 0; + + /* must be mapped */ + if (!ih->data->window) + return 0; + + if (ih->data->context == wglGetCurrentContext()) + return 1; + + return 0; +} + +void IupGLMakeCurrent(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + wglMakeCurrent(ih->data->device, ih->data->context); +} + +void IupGLSwapBuffers(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + SwapBuffers(ih->data->device); +} + +void IupGLPalette(Ihandle* ih, int index, float r, float g, float b) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + /* must have a palette */ + if (ih->data->palette) + { + PALETTEENTRY entry; + entry.peRed = (BYTE)(r*255); + entry.peGreen = (BYTE)(g*255); + entry.peBlue = (BYTE)(b*255); + entry.peFlags = PC_NOCOLLAPSE; + SetPaletteEntries(ih->data->palette,index,1,&entry); + UnrealizeObject(ih->data->device); + SelectPalette(ih->data->device,ih->data->palette,FALSE); + RealizePalette(ih->data->device); + } +} + +void IupGLUseFont(Ihandle* ih, int first, int count, int list_base) +{ + HFONT old_font, font; + + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + font = (HFONT)IupGetAttribute(ih, "HFONT"); + if (font) + { + old_font = SelectObject(ih->data->device, font); + wglUseFontBitmaps(ih->data->device, first, count, list_base); + SelectObject(ih->data->device, old_font); + } +} + +void IupGLWait(int gl) +{ + if (gl) + glFinish(); + else + GdiFlush(); +} diff --git a/iup/srcgl/iup_glcanvas_x.c b/iup/srcgl/iup_glcanvas_x.c new file mode 100755 index 0000000..adddeb1 --- /dev/null +++ b/iup/srcgl/iup_glcanvas_x.c @@ -0,0 +1,448 @@ +/** \file + * \brief iupgl control for X11 + * + * See Copyright Notice in "iup.h" + */ + +#include <X11/Xlib.h> +#include <GL/glx.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include "iup.h" +#include "iupcbs.h" +#include "iupgl.h" + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_stdcontrols.h" +#include "iup_assert.h" +#include "iup_register.h" + + +struct _IcontrolData +{ + iupCanvas canvas; /* from IupCanvas (must reserve it) */ + + Display* display; + Drawable window; + + Colormap colormap; + XVisualInfo *vinfo; + GLXContext context; +}; + +static int xGLCanvasDefaultResize(Ihandle *ih, int width, int height) +{ + IupGLMakeCurrent(ih); + glViewport(0,0,width,height); + return IUP_DEFAULT; +} + +static int xGLCanvasCreateMethod(Ihandle* ih, void** params) +{ + (void)params; + free(ih->data); /* allocated by the iCanvasCreateMethod of IupCanvas */ + ih->data = iupALLOCCTRLDATA(); + IupSetCallback(ih, "RESIZE_CB", (Icallback)xGLCanvasDefaultResize); + return IUP_NOERROR; +} + +static void xGLCanvasGetVisual(Ihandle* ih) +{ + int erb, evb, number; + int n = 0; + int alist[40]; + + if (!ih->data->display) + ih->data->display = (Display*)IupGetGlobal("XDISPLAY"); /* works for Motif and GTK, can be called before mapped */ + if (!ih->data->display) + return; + + /* double or single buffer */ + if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE")) + { + alist[n++] = GLX_DOUBLEBUFFER; + } + + /* stereo */ + if (iupAttribGetBoolean(ih,"STEREO")) + { + alist[n++] = GLX_STEREO; + } + + /* rgba or index */ + if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX")) + { + /* buffer size (for index mode) */ + number = iupAttribGetInt(ih,"BUFFER_SIZE"); + if (number > 0) + { + alist[n++] = GLX_BUFFER_SIZE; + alist[n++] = number; + } + } + else + { + alist[n++] = GLX_RGBA; /* assume rgba as default */ + } + + /* red, green, blue bits */ + number = iupAttribGetInt(ih,"RED_SIZE"); + if (number > 0) + { + alist[n++] = GLX_RED_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"GREEN_SIZE"); + if (number > 0) + { + alist[n++] = GLX_GREEN_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"BLUE_SIZE"); + if (number > 0) + { + alist[n++] = GLX_BLUE_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"ALPHA_SIZE"); + if (number > 0) + { + alist[n++] = GLX_ALPHA_SIZE; + alist[n++] = number; + } + + /* depth and stencil size */ + number = iupAttribGetInt(ih,"DEPTH_SIZE"); + if (number > 0) + { + alist[n++] = GLX_DEPTH_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"STENCIL_SIZE"); + if (number > 0) + { + alist[n++] = GLX_STENCIL_SIZE; + alist[n++] = number; + } + + /* red, green, blue accumulation bits */ + number = iupAttribGetInt(ih,"ACCUM_RED_SIZE"); + if (number > 0) + { + alist[n++] = GLX_ACCUM_RED_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE"); + if (number > 0) + { + alist[n++] = GLX_ACCUM_GREEN_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE"); + if (number > 0) + { + alist[n++] = GLX_ACCUM_BLUE_SIZE; + alist[n++] = number; + } + + number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE"); + if (number > 0) + { + alist[n++] = GLX_ACCUM_ALPHA_SIZE; + alist[n++] = number; + } + alist[n++] = None; + + /* check out X extension */ + if (!glXQueryExtension(ih->data->display, &erb, &evb)) + { + iupAttribSetStr(ih, "ERROR", "X server has no OpenGL GLX extension"); + return; + } + + /* choose visual */ + ih->data->vinfo = glXChooseVisual(ih->data->display, DefaultScreen(ih->data->display), alist); + if (!ih->data->vinfo) + iupAttribSetStr(ih, "ERROR", "No appropriate visual"); +} + +static char* xGLCanvasGetVisualAttrib(Ihandle *ih) +{ + /* This must be available before mapping, because IupCanvas uses it during map in GTK and Motif. */ + if (ih->data->vinfo) + return (char*)ih->data->vinfo->visual; + + xGLCanvasGetVisual(ih); + + if (ih->data->vinfo) + return (char*)ih->data->vinfo->visual; + + return NULL; +} + +static int xGLCanvasMapMethod(Ihandle* ih) +{ + GLXContext shared_context = NULL; + Ihandle* ih_shared; + + /* the IupCanvas is already mapped, just initialize the OpenGL context */ + + if (!xGLCanvasGetVisualAttrib(ih)) + return IUP_NOERROR; /* do not abort mapping */ + + ih->data->window = (XID)iupAttribGet(ih, "XWINDOW"); /* check first in the hash table, can be defined by the IupFileDlg */ + if (!ih->data->window) + ih->data->window = (XID)IupGetAttribute(ih, "XWINDOW"); /* works for Motif and GTK, only after mapping the IupCanvas */ + if (!ih->data->window) + return IUP_NOERROR; + + ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT"); + if (ih_shared && iupStrEqual(ih_shared->iclass->name, "glcanvas")) /* must be an IupGLCanvas */ + shared_context = ih_shared->data->context; + + /* create rendering context */ + ih->data->context = glXCreateContext(ih->data->display, ih->data->vinfo, shared_context, GL_TRUE); + if (!ih->data->context) + { + iupAttribSetStr(ih, "ERROR", "Could not create a rendering context"); + return IUP_NOERROR; + } + iupAttribSetStr(ih, "CONTEXT", (char*)ih->data->context); + + /* create colormap for index mode */ + if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX") && + ih->data->vinfo->class != StaticColor && ih->data->vinfo->class != StaticGray) + { + ih->data->colormap = XCreateColormap(ih->data->display, RootWindow(ih->data->display, DefaultScreen(ih->data->display)), ih->data->vinfo->visual, AllocAll); + iupAttribSetStr(ih, "COLORMAP", (char*)ih->data->colormap); + } + + if (ih->data->colormap != None) + IupGLPalette(ih,0,1,1,1); /* set first color as white */ + + return IUP_NOERROR; +} + +static void xGLCanvasUnMapMethod(Ihandle* ih) +{ + if (ih->data->context) + { + if (ih->data->context == glXGetCurrentContext()) + glXMakeCurrent(ih->data->display, None, NULL); + + glXDestroyContext(ih->data->display, ih->data->context); + } + + if (ih->data->colormap != None) + XFreeColormap(ih->data->display, ih->data->colormap); + + if (ih->data->vinfo) + XFree(ih->data->vinfo); +} + +static Iclass* xGlCanvasGetClass(void) +{ + Iclass* ic = iupClassNew(iupCanvasGetClass()); + + ic->name = "glcanvas"; + ic->format = "A"; /* one optional callback name */ + ic->nativetype = IUP_TYPECANVAS; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 1; + + ic->Create = xGLCanvasCreateMethod; + ic->Map = xGLCanvasMapMethod; + ic->UnMap = xGLCanvasUnMapMethod; + + iupClassRegisterAttribute(ic, "BUFFER", NULL, NULL, IUPAF_SAMEASSYSTEM, "SINGLE", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "COLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "RGBA", IUPAF_DEFAULT); + + iupClassRegisterAttribute(ic, "CONTEXT", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING); + iupClassRegisterAttribute(ic, "VISUAL", xGLCanvasGetVisualAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING|IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "COLORMAP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING); + + return ic; +} + + +/******************************************* Exported functions */ + +void IupGLCanvasOpen(void) +{ + if (!IupGetGlobal("_IUP_GLCANVAS_OPEN")) + { + iupRegisterClass(xGlCanvasGetClass()); + IupSetGlobal("_IUP_GLCANVAS_OPEN", "1"); + } +} + +Ihandle* IupGLCanvas(const char *action) +{ + void *params[2]; + params[0] = (void*)action; + params[1] = NULL; + return IupCreatev("glcanvas", params); +} + +int IupGLIsCurrent(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return 0; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return 0; + + /* must be mapped */ + if (!ih->data->window) + return 0; + + if (ih->data->context == glXGetCurrentContext()) + return 1; + + return 0; +} + +void IupGLMakeCurrent(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + glXMakeCurrent(ih->data->display, ih->data->window, ih->data->context); + glXWaitX(); +} + +void IupGLSwapBuffers(Ihandle* ih) +{ + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + glXSwapBuffers(ih->data->display, ih->data->window); +} + +static int xGLCanvasIgnoreError(Display *param1, XErrorEvent *param2) +{ + (void)param1; + (void)param2; + return 0; +} + +void IupGLPalette(Ihandle* ih, int index, float r, float g, float b) +{ + XColor color; + int rShift, gShift, bShift; + XVisualInfo *vinfo; + XErrorHandler old_handler; + + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + /* must have a colormap */ + if (ih->data->colormap == None) + return; + + /* code fragment based on the toolkit library provided with OpenGL */ + old_handler = XSetErrorHandler(xGLCanvasIgnoreError); + + vinfo = ih->data->vinfo; + switch (vinfo->class) + { + case DirectColor: + rShift = ffs((unsigned int)vinfo->red_mask) - 1; + gShift = ffs((unsigned int)vinfo->green_mask) - 1; + bShift = ffs((unsigned int)vinfo->blue_mask) - 1; + color.pixel = ((index << rShift) & vinfo->red_mask) | + ((index << gShift) & vinfo->green_mask) | + ((index << bShift) & vinfo->blue_mask); + color.red = (unsigned short)(r * 65535.0 + 0.5); + color.green = (unsigned short)(g * 65535.0 + 0.5); + color.blue = (unsigned short)(b * 65535.0 + 0.5); + color.flags = DoRed | DoGreen | DoBlue; + XStoreColor(ih->data->display, ih->data->colormap, &color); + break; + case GrayScale: + case PseudoColor: + if (index < vinfo->colormap_size) + { + color.pixel = index; + color.red = (unsigned short)(r * 65535.0 + 0.5); + color.green = (unsigned short)(g * 65535.0 + 0.5); + color.blue = (unsigned short)(b * 65535.0 + 0.5); + color.flags = DoRed | DoGreen | DoBlue; + XStoreColor(ih->data->display, ih->data->colormap, &color); + } + break; + } + + XSync(ih->data->display, 0); + XSetErrorHandler(old_handler); +} + +void IupGLUseFont(Ihandle* ih, int first, int count, int list_base) +{ + Font font; + + iupASSERT(iupObjectCheck(ih)); + if (!iupObjectCheck(ih)) + return; + + /* must be an IupGLCanvas */ + if (!iupStrEqual(ih->iclass->name, "glcanvas")) + return; + + /* must be mapped */ + if (!ih->data->window) + return; + + font = (Font)IupGetAttribute(ih, "XFONTID"); + if (font) + glXUseXFont(font, first, count, list_base); +} + +void IupGLWait(int gl) +{ + if (gl) + glXWaitGL(); + else + glXWaitX(); +} diff --git a/iup/srcgl/iupgl.def b/iup/srcgl/iupgl.def new file mode 100755 index 0000000..d82a1b1 --- /dev/null +++ b/iup/srcgl/iupgl.def @@ -0,0 +1,9 @@ +EXPORTS +IupGLCanvasOpen +IupGLCanvas +IupGLMakeCurrent +IupGLSwapBuffers +IupGLPalette +IupGLIsCurrent +IupGLUseFont +IupGLWait diff --git a/iup/srcgl/iupgl.dep b/iup/srcgl/iupgl.dep new file mode 100644 index 0000000..52fbcfa --- /dev/null +++ b/iup/srcgl/iupgl.dep @@ -0,0 +1,5 @@ +$(OBJDIR)/iup_glcanvas_x.o: iup_glcanvas_x.c ../include/iup.h ../include/iupkey.h \ + ../include/iupdef.h ../include/iupcbs.h ../include/iupgl.h \ + ../src/iup_object.h ../src/iup_class.h ../src/iup_table.h \ + ../src/iup_classbase.h ../src/iup_attrib.h ../src/iup_str.h \ + ../src/iup_stdcontrols.h ../src/iup_assert.h ../src/iup_register.h diff --git a/iup/srcgl/make_uname b/iup/srcgl/make_uname new file mode 100755 index 0000000..cc4b881 --- /dev/null +++ b/iup/srcgl/make_uname @@ -0,0 +1,3 @@ +#This builds all the libraries of the folder for 1 uname + +tecmake $1 $2 $3 $4 $5 $6 $7 diff --git a/iup/srcgl/make_uname.bat b/iup/srcgl/make_uname.bat new file mode 100755 index 0000000..f0a0722 --- /dev/null +++ b/iup/srcgl/make_uname.bat @@ -0,0 +1,4 @@ +@echo off +REM This builds all the libraries of the folder for 1 uname + +call tecmake %1 %2 %3 %4 %5 %6 |