Acme-MITHALDU-BleedingOpenGL

 view release on metacpan or  search on metacpan

pogl_gl_top.xs  view on Meta::CPAN

/*  Last saved: Sat 10 Jul 2010 12:57:04 PM*/

/*  Copyright (c) 1998 Kenneth Albanowski. All rights reserved.
 *  Copyright (c) 2007 Bob Free. All rights reserved.
 *  Copyright (c) 2009 Chris Marshall. All rights reserved.
 *  This program is free software; you can redistribute it and/or
 *  modify it under the same terms as Perl itself.
 */

/* OpenGL GLX bindings */
#define IN_POGL_GLX_XS

#include <stdio.h>

#include "pgopogl.h"

#ifdef HAVE_GL
#include "gl_util.h"

/* Note: this is caching procs once for all contexts */
/* !!! This should instead cache per context */
#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_W32API))
#define loadProc(proc,name) \
{ \
  if (!proc) \
  { \
    proc = (void *)wglGetProcAddress(name); \
    if (!proc) croak(name " is not supported by this renderer"); \
  } \
}
#define testProc(proc,name) ((proc) ? 1 : !!(proc = (void *)wglGetProcAddress(name)))
#else /* not using WGL */
#define loadProc(proc,name)
#define testProc(proc,name) 1
#endif /* not defined _WIN32, __CYGWIN__, and HAVE_W32API */
#endif /* defined HAVE_GL */

#ifdef HAVE_GLX
#include "glx_util.h"
#endif /* defined HAVE_GLX */

#ifdef HAVE_GLU
#include "glu_util.h"
#endif /* defined HAVE_GLU */



#ifdef IN_POGL_GLX_XS
#ifdef HAVE_GLX
#  define HAVE_GLpc			/* Perl interface */
#  define nativeWindowId(d, w)	(w)
static Bool WaitForNotify(Display *d, XEvent *e, char *arg) {
    return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
}
#  define glpResizeWindow(s1,s2,w,d)	XResizeWindow(d,w,s1,s2)
#  define glpMoveWindow(s1,s2,w,d)		XMoveWindow(d,w,s1,s2)
#  define glpMoveResizeWindow(s1,s2,s3,s4,w,d)	XMoveResizeWindow(d,w,s1,s2,s3,s4)
#endif	/* defined HAVE_GLX */ 



static int debug = 0;

#ifdef HAVE_GLpc

#  define NUM_ARG 7			/* Number of mandatory args to glpcOpenWindow */

Display *dpy;
int dpy_open;
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
Window win;
GLXContext ctx;

static int default_attributes[] = { GLX_DOUBLEBUFFER, GLX_RGBA, None };

#endif	/* defined HAVE_GLpc */ 

static int DBUFFER_HACK = 0;
#define __had_dbuffer_hack() (DBUFFER_HACK)

#endif /* End IN_POGL_GLX_XS */



/********************/
/* GPGPU Utils      */
/********************/

GLint FBO_MAX = -1;

/* Get max GPGPU data size */
int gpgpu_size(void)
{
#if defined(GL_ARB_texture_rectangle) && defined(GL_ARB_texture_float) && \
  defined(GL_ARB_fragment_program) && defined(GL_EXT_framebuffer_object)
  if (FBO_MAX == -1)
  {
    if (testProc(glProgramStringARB,"glProgramStringARB") &&
      testProc(glGenProgramsARB,"glGenProgramsARB") &&
      testProc(glBindProgramARB,"glBindProgramARB") &&
      testProc(glIsProgramARB,"glIsProgramARB") &&
      testProc(glProgramLocalParameter4fvARB,"glProgramLocalParameter4fvARB") &&
      testProc(glDeleteProgramsARB,"glDeleteProgramsARB") &&
      testProc(glGenFramebuffersEXT,"glGenFramebuffersEXT") &&
      testProc(glGenRenderbuffersEXT,"glGenRenderbuffersEXT") &&
      testProc(glBindFramebufferEXT,"glBindFramebufferEXT") &&
      testProc(glFramebufferTexture2DEXT,"glFramebufferTexture2DEXT") &&
      testProc(glBindRenderbufferEXT,"glBindRenderbufferEXT") &&
      testProc(glRenderbufferStorageEXT,"glRenderbufferStorageEXT") &&
      testProc(glFramebufferRenderbufferEXT,"glFramebufferRenderbufferEXT") &&
      testProc(glCheckFramebufferStatusEXT,"glCheckFramebufferStatusEXT") &&
      testProc(glDeleteRenderbuffersEXT,"glDeleteRenderbuffersEXT") &&
      testProc(glDeleteFramebuffersEXT,"glDeleteFramebuffersEXT"))
    {
      glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT,&FBO_MAX);
    }
    else
    {
      FBO_MAX = 0;
    }
  }
  return(FBO_MAX);
#else
  return(0);
#endif
}

/* Get max square array width for a given GPGPU data size */
int gpgpu_width(int len)

pogl_gl_top.xs  view on Meta::CPAN


    RETVAL = newHV(); /* Create hash to return GL Object info */

    if(items > NUM_ARG){
        int i;
        a_buf = (int *) malloc((items-NUM_ARG+2) * sizeof(int));
        a_buf[0] = GLX_DOUBLEBUFFER; /* Preallocate */
        attributes = a_buf + 1;
        for (i=NUM_ARG; i<items; i++) {
            attributes[i-NUM_ARG] = SvIV(ST(i));
        }
        attributes[items-NUM_ARG] = None;
    }
    if (debug) {
        int i;	
        for (i=0; attributes[i] != None; i++) {
            printf("att=%d %d\n", i, attributes[i]);
        }
    }
    /* get a connection */
    if (!dpy_open) {
        dpy = XOpenDisplay(NULL);
        dpy_open = 1;
    }
    if (!dpy) {
        croak("ERROR: failed to get an X connection");
    } else if (debug) {
        printf("Display open %x\n", dpy);
    }		

    /* get an appropriate visual */
    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
    if (!vi) { /* Might have happened that one does not
                * *need* DOUBLEBUFFER, but the display does
                * not provide SINGLEBUFFER; and the semantic
                * of GLX_DOUBLEBUFFER is that if it misses,
                * only SINGLEBUFFER visuals are selected.  */
        attributes--; /* GLX_DOUBLEBUFFER preallocated there */
        vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes); /* Retry */
        if (vi)
            DBUFFER_HACK = 1;
    }
    if (a_buf)
        free(a_buf);
    if(!vi) {
        croak("ERROR: failed to get an X visual\n");
    } else if (debug) {
        printf("Visual open %x\n", vi);
    }		

    /* A blank line here will confuse xsubpp ;-) */
#ifdef HAVE_GLX
    /* create a GLX context */
    ctx = glXCreateContext(dpy, vi, 0, GL_TRUE);
    if (!ctx) {
        croak("ERROR: failed to get an X Context");
    } else if (debug) {
        printf("Context Created %x\n", ctx);
    }

    /* create a color map */
    cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
            vi->visual, AllocNone);

    /* create a window */
    swa.colormap = cmap;
    swa.border_pixel = 0;
    swa.event_mask = event_mask;
#endif	/* defined HAVE_GLX */

    if (!pwin) {
        pwin = RootWindow(dpy, vi->screen);
        if (debug) printf("Using root as parent window 0x%x\n", pwin);
    }
    if (steal) {
        win = nativeWindowId(dpy, pwin); /* What about depth/visual */
    } else {
        win = XCreateWindow(dpy, pwin, 
                x, y, w, h,
                0, vi->depth, InputOutput, vi->visual,
                CWBorderPixel|CWColormap|CWEventMask, &swa);
        /* NOTE: PDL code had CWBackPixel above */
    }
    if (!win) {
        croak("No Window");
    } else {
        if (debug) printf("win = 0x%x\n", win);
    }
    XMapWindow(dpy, win);
#ifndef HAVE_GLX  /* For OS/2 GLX emulation stuff -chm 2009.09.14 */
    /* On OS/2: cannot create a context before mapping something... */
    /* create a GLX context */
    ctx = glXCreateContext(dpy, vi, 0, GL_TRUE);
    if (!ctx)
        croak("No context!\n");

    LastEventMask = event_mask;
#else	/* HAVE_GLX, this is the default branch */
    if ( (event_mask & StructureNotifyMask) && !steal ) {
        XIfEvent(dpy, &event, WaitForNotify, (char*)win);
    }
#endif	/* not defined HAVE_GLX */

    /* connect the context to the window */
    if (!glXMakeCurrent(dpy, win, ctx))
        croak("Non current");

    if (debug)
        printf("Display=0x%x Window=0x%x Context=0x%x\n",dpy, win, ctx);

    /* Create the GL object hash information */
    hv_store(RETVAL, "Display", strlen("Display"), newSViv(PTR2IV(dpy)), 0);
    hv_store(RETVAL, "Window", strlen("Window"),   newSViv(  (IV) win ), 0);
    hv_store(RETVAL, "Context", strlen("Context"), newSViv(PTR2IV(ctx)), 0);

    hv_store(RETVAL, "GL_Version",strlen("GL_Version"), 
            newSVpv((char *) glGetString(GL_VERSION),0),0);
    hv_store(RETVAL, "GL_Vendor",strlen("GL_Vendor"), 
            newSVpv((char *) glGetString(GL_VENDOR),0),0);
    hv_store(RETVAL, "GL_Renderer",strlen("GL_Renderer"), 
            newSVpv((char *) glGetString(GL_RENDERER),0),0);

    /* clear the buffer */
    glClearColor(0,0,0,1);
    while ( (err = glGetError()) != GL_NO_ERROR ) {
        printf("ERROR issued in GL %s\n", gluErrorString(err));
    }
}
OUTPUT:
RETVAL

#// glpRasterFont(name,base,number,d)
int
glpRasterFont(name,base,number,d)
        char *name
        int base
        int number
        Display *d
        CODE:
        {
                XFontStruct *fi;
                int lb;
                fi = XLoadQueryFont(d,name);
                if(fi == NULL) {
                        die("No font %s found",name);
                }
                lb = glGenLists(number);
                if(lb == 0) {
                        die("No display lists left for font %s (need %d)",name,number);
                }
                glXUseXFont(fi->fid, base, number, lb);



( run in 0.819 second using v1.01-cache-2.11-cpan-6aa56a78535 )