예제 #1
0
/* This is the main entry point for Matlab or Octave. It gets called by
   Matlab or Octave, handles first-time initialization, error handling
   and subfunction dispatching.
*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Start of dispatcher:
    int i;
    GLenum err;

    // see whether there's a string command
    if(nrhs<1 || !mxIsChar(prhs[0])) mogl_usageerr();
    
    // get string command
    mxGetString(prhs[0],cmd,CMDLEN);

    // Special case. If we're called with the special command "PREINIT", then
    // we return immediately. moglcore('PREINIT') is called by ptbmoglinit.m
    // on M$-Windows in order to preload the moglcore Mex-file into Matlab while
    // the current working directory is set to ..MOGL/core/ . This way, the dynamic
    // linker can find our own local version of glut32.dll and link it against moglcore.
    // Without this trick, we would need to install glut32.dll into the Windows system
    // folder which requires admin privileges and makes installation of Psychtoolbox
    // more complicated on M$-Windows...
    if (strcmp(cmd, "PREINIT")==0) {
        glBeginLevel=0;
        goto moglreturn;
    }
    
    if (strcmp(cmd, "DUMMYMODE")==0) {
        if (nrhs<2 || mxGetScalar(prhs[1])<0) {
            mexErrMsgTxt("MOGL-ERROR: No dummy mode level or invalid level (<0) given for subcommand DUMMYMODE!");
        }
        dummymode = (int) mxGetScalar(prhs[1]);
	if (dummymode>0) printf("MOGL-INFO: Switched to dummy mode level %i.\n", dummymode);
        goto moglreturn;
    }

    // Special command to set MOGL debug level:
    // debuglevel = 0 --> Shut up in any case, leave error-handling to higher-level code.
    // debuglevel > 0 --> Check for OpenGL error conditions.
    // debuglevel > 0 --> Output glError()'s in clear-text and abort. Output GLSL errors and abort.
    // debuglevel > 1 --> Output GLSL diagnostic messages as well.
    // debuglevel > 2 --> Be very verbose!
    if (strcmp(cmd, "DEBUGLEVEL")==0) {
        if (nrhs<2 || mxGetScalar(prhs[1])<0) {
            mexErrMsgTxt("MOGL-ERROR: No debuglevel or invalid debuglevel (<0) given for subcommand DEBUGLEVEL!");
        }

        debuglevel = (int) mxGetScalar(prhs[1]);
        goto moglreturn;
    }
    
    // Special cleanup subcommand needed for GNU/Octave: See explanation below in firstTime init.
    if (strcmp(cmd, "JettisonModuleHelper")==0) {
      goto moglreturn;
    }

    // Abort here if dummymode >= 10: Input arg. processing run, but no real
    // command parsing and processing;
    if (dummymode >= 10) {
      printf("MOGL-INFO: Dummy call to %s() - Ignored in dummy mode %i ...\n", cmd, dummymode);
      goto moglreturn;
    }

    #ifdef BUILD_GLM
    // GLM module is included and supported in moglcore: This is necessary if
    // one wants to use MOGL independent from Psychtoolbox. GLM is only supported
    // on MacOS-X, not on Linux or Windows...
    
    // We execute glm-commands without performing GLEW first-time initialization,
    // because to execute glewinit() we need a valid OpenGL context. This context is
    // either created by Psychtoolbox or by glm. Therefore glm-commands must be able
    // to execute before glewinit() happened.
    
    // look for command in glm command map
    if( (i=binsearch(glm_map,glm_map_count,cmd))>=0 ) {
        glm_map[i].cmdfn(nlhs,plhs,nrhs-1,prhs+1);
        goto moglreturn;
    }

    #endif

    // Is this the first invocation of moglcore?
    if (firsttime) {
        // Yes. Initialize GLEW, the GL Extension Wrangler Library. This will
        // auto-detect and dynamically link/bind all core OpenGL functionality
        // as well as all possible OpenGL extensions on OS-X, Linux and Windows.
        err = glewInit();
        if (GLEW_OK != err) {
            // Failed! Something is seriously wrong - We have to abort :(
            printf("MOGL: Failed to initialize! Probably you called an OpenGL command *before* opening an onscreen window?!?\n");
            printf("GLEW reported the following error: %s\n", glewGetErrorString(err)); fflush(NULL);
            goto moglreturn;
        }
        // Success. Ready to go...
		if (debuglevel > 1) {
			printf("MOGL - OpenGL for Matlab & GNU/Octave initialized. MOGL is (c) 2006-2011 Richard F. Murray & Mario Kleiner, licensed to you under MIT license.\n");
			printf("Some additional restrictions apply to redistribution of binary MEX files for Matlab due to the terms of the Mathworks Matlab license.\n");
			printf("See file 'License.txt' in the Psychtoolbox root folder for the exact licensing conditions.\n");
		}
        fflush(NULL);
        
        // Perform dynamic rebinding of ARB extensions to core functions, if necessary:
        mogl_rebindARBExtensionsToCore();
        
		#ifdef FREEGLUT
		// FreeGlut must be initialized, otherwise it will emergency abort the whole application!
		int noargs = 1;
		char dummyarg[] = "ptbmoglcore";
		char *dummyargp = &dummyarg[0];
		glutInit( &noargs, &dummyargp);
		#endif
		
		// Register exit-handler: When flushing the mex-file, we free all allocated buffer memory:
		mexAtExit(&mexExitFunction);
		
        // Done with first time initialization:
        firsttime = 0;
    }   
	
    // If glBeginLevel >  1 then most probably the script was aborted after execution of glBegin() but
    // before execution of glEnd(). In that case, we reset the level to zero.
    if (glBeginLevel > 1) glBeginLevel = 0;

    // Reset OpenGL error state so we can be sure that any of our error queries really
    // relate to errors caused by us:
    if (glBeginLevel == 0 && debuglevel > 0 && (strstr(cmd, "glGetError")==NULL)) glGetError();
        
    // look for command in manual command map
    if( (i=binsearch(gl_manual_map,gl_manual_map_count,cmd))>=0 ) {
        gl_manual_map[i].cmdfn(nlhs,plhs,nrhs-1,(const mxArray**) prhs+1);
        if (debuglevel > 0) mogl_checkerrors(cmd, prhs);
        goto moglreturn;
    }
    
    // look for command in auto command map
    if( (i=binsearch(gl_auto_map,gl_auto_map_count,cmd))>=0 ) {
        gl_auto_map[i].cmdfn(nlhs,plhs,nrhs-1,(const mxArray**) prhs+1);
        if (debuglevel > 0) mogl_checkerrors(cmd, prhs);
        goto moglreturn;
    }
    
    // no match
    mogl_usageerr();
    
    // moglreturn: Is the exit path of mogl. All execution ends at this point.
 moglreturn:
    return;
}
예제 #2
0
/* This is the main entry point for Matlab or Octave. It gets called by
   Matlab or Octave, handles first-time initialization, error handling
   and subfunction dispatching.
*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Start of dispatcher:
    int i;
    GLenum err;
    
    // FreeGlut must be initialized, otherwise it will emergency abort the whole application.
    // These variables are needed for it:
    int noargs = 1;
    char dummyarg[] = "ptbmoglcore";
    char *dummyargp = &dummyarg[0];

    // see whether there's a string command
    if(nrhs<1 || !mxIsChar(prhs[0])) mogl_usageerr();
    
    // get string command
    mxGetString(prhs[0],cmd,CMDLEN);

    // Special case. If we're called with the special command "PREINIT", then
    // we return immediately. moglcore('PREINIT') is called by ptbmoglinit.m
    // on M$-Windows in order to preload the moglcore Mex-file into Matlab while
    // the current working directory is set to ..MOGL/core/ . This way, the dynamic
    // linker can find our own local version of glut32.dll and link it against moglcore.
    // Without this trick, we would need to install glut32.dll into the Windows system
    // folder which requires admin privileges and makes installation of Psychtoolbox
    // more complicated on M$-Windows...
    if (strcmp(cmd, "PREINIT")==0) {
        glBeginLevel=0;
        goto moglreturn;
    }
    
    if (strcmp(cmd, "DUMMYMODE")==0) {
        if (nrhs<2 || mxGetScalar(prhs[1])<0) {
            mexErrMsgTxt("MOGL-ERROR: No dummy mode level or invalid level (<0) given for subcommand DUMMYMODE!");
        }
        dummymode = (int) mxGetScalar(prhs[1]);
	if (dummymode>0) printf("MOGL-INFO: Switched to dummy mode level %i.\n", dummymode);
        goto moglreturn;
    }

    // Special command to set MOGL debug level:
    // debuglevel = 0 --> Shut up in any case, leave error-handling to higher-level code.
    // debuglevel > 0 --> Check for OpenGL error conditions.
    // debuglevel > 0 --> Output glError()'s in clear-text and abort. Output GLSL errors and abort.
    // debuglevel > 1 --> Output GLSL diagnostic messages as well.
    // debuglevel > 2 --> Be very verbose!
    if (strcmp(cmd, "DEBUGLEVEL")==0) {
        if (nrhs<2 || mxGetScalar(prhs[1])<0) {
            mexErrMsgTxt("MOGL-ERROR: No debuglevel or invalid debuglevel (<0) given for subcommand DEBUGLEVEL!");
        }

        debuglevel = (int) mxGetScalar(prhs[1]);
        goto moglreturn;
    }
    
    // Special cleanup subcommand needed for GNU/Octave: See explanation below in firstTime init.
    if (strcmp(cmd, "JettisonModuleHelper")==0) {
      goto moglreturn;
    }

    // Abort here if dummymode >= 10: Input arg. processing run, but no real
    // command parsing and processing;
    if (dummymode >= 10) {
      printf("MOGL-INFO: Dummy call to %s() - Ignored in dummy mode %i ...\n", cmd, dummymode);
      goto moglreturn;
    }

    #ifdef BUILD_GLM
    // GLM module is included and supported in moglcore: This is necessary if
    // one wants to use MOGL independent from Psychtoolbox. GLM is only supported
    // on MacOS-X, not on Linux or Windows...
    
    // We execute glm-commands without performing GLEW first-time initialization,
    // because to execute glewinit() we need a valid OpenGL context. This context is
    // either created by Psychtoolbox or by glm. Therefore glm-commands must be able
    // to execute before glewinit() happened.
    
    // look for command in glm command map
    if( (i=binsearch(glm_map,glm_map_count,cmd))>=0 ) {
        glm_map[i].cmdfn(nlhs,plhs,nrhs-1,prhs+1);
        goto moglreturn;
    }

    #endif

    // Is this the first invocation of moglcore?
    if (firsttime) {
        // Yes. Initialize GLEW, the GL Extension Wrangler Library. This will
        // auto-detect and dynamically link/bind all core OpenGL functionality
        // as well as all possible OpenGL extensions on OS-X, Linux and Windows.
        err = GLEW_OK;
        #ifdef PTB_USE_WAFFLE
        // Linux is special: If we use the Waffle backend for display system binding, then our display backend
        // may be something else than GLX (e.g., X11/EGL, Wayland/EGL, GBM/EGL, ANDROID/EGL etc.), in which case
        // glewInit() would not work and would crash hard. Detect if we're on classic Linux or Linux with X11/GLX.
        // If so, execute glewInit(), otherwise call glewContextInit() - a routine which skips GLX specific setup,
        // therefore only initializes the non-GLX parts. We need a hacked glew.c for this function to be available,
        // as original upstream GLEW makes that function private (static):
        if (!getenv("PSYCH_USE_DISPLAY_BACKEND") || strstr(getenv("PSYCH_USE_DISPLAY_BACKEND"), "glx")) {
            // Classic backend or GLX backend: The full show.
            err = glewInit();
        }
        else {
            // Non-GLX backend, probably EGL: Reduced show.
            err = glewContextInit();
        }
        #else
            // Other os'es, or Linux without Waffle backend: Always init GLEW:
            err = glewInit();
        #endif

        if (GLEW_OK != err) {
            // Failed! Something is seriously wrong - We have to abort :(
            printf("MOGL: Failed to initialize! Probably you called an OpenGL command *before* opening an onscreen window?!?\n");
            printf("GLEW reported the following error: %s\n", glewGetErrorString(err)); fflush(NULL);
            goto moglreturn;
        }

        // Success. Ready to go...
		if (debuglevel > 1) {
			printf("MOGL - OpenGL for Matlab & GNU/Octave initialized. MOGL is (c) 2006-2013 Richard F. Murray & Mario Kleiner, licensed to you under MIT license.\n");
            #ifdef WINDOWS
			printf("On MS-Windows, we make use of the freeglut library, which is Copyright (c) 1999-2000 Pawel W. Olszta, licensed under compatible MIT/X11 license.\n");
            printf("The precompiled Windows binary DLL's have been kindly provided by http://www.transmissionzero.co.uk/software/freeglut-devel/ -- Thanks!\n");
            #endif
			printf("See file 'License.txt' in the Psychtoolbox root folder for the exact licensing conditions.\n");
		}
        fflush(NULL);
        
        // Perform dynamic rebinding of ARB extensions to core functions, if necessary:
        mogl_rebindARBExtensionsToCore();
        
		#ifdef FREEGLUT
		// FreeGlut must be initialized, otherwise it will emergency abort the whole application.
		// However, we skip init if we're on a setup without GLX display backend, as this would
		// abort us due to lack of GLX. On non-GLX we simply can't use FreeGlut at all.
		if (!getenv("PSYCH_USE_DISPLAY_BACKEND") || strstr(getenv("PSYCH_USE_DISPLAY_BACKEND"), "glx")) {
			// GLX display backend - Init and use FreeGlut:
			glutInit( &noargs, &dummyargp);
		}
		#endif

        // Running on a OpenGL-ES rendering api under Linux?
        if (getenv("PSYCH_USE_GFX_BACKEND") && strstr(getenv("PSYCH_USE_GFX_BACKEND"), "gles")) {
            // Yes. We emulate some immediate mode rendering commands, which aren't available
            // in OpenGL Embedded Subset at all, via "our" own emulation code. This code emulates
            // immediate mode on top of client vertex arrays and batch submission.
            if (debuglevel > 1) {
                printf("OpenGL-ES rendering API active: Emulating immediate mode rendering via David Petrie's ftglesGlue emulation code.\n");
            }
        }

		// Register exit-handler: When flushing the mex-file, we free all allocated buffer memory:
		mexAtExit(&mexExitFunction);
		
        // Done with first time initialization:
        firsttime = 0;
    }   
	
    // If glBeginLevel >  1 then most probably the script was aborted after execution of glBegin() but
    // before execution of glEnd(). In that case, we reset the level to zero.
    if (glBeginLevel > 1) glBeginLevel = 0;

    // Reset OpenGL error state so we can be sure that any of our error queries really
    // relate to errors caused by us:
    if (glBeginLevel == 0 && debuglevel > 0 && (strstr(cmd, "glGetError")==NULL)) glGetError();
        
    // look for command in manual command map
    if( (i=binsearch(gl_manual_map,gl_manual_map_count,cmd))>=0 ) {
        gl_manual_map[i].cmdfn(nlhs,plhs,nrhs-1,(const mxArray**) prhs+1);
        if (debuglevel > 0) mogl_checkerrors(cmd, prhs);
        goto moglreturn;
    }
    
    // look for command in auto command map
    if( (i=binsearch(gl_auto_map,gl_auto_map_count,cmd))>=0 ) {
        gl_auto_map[i].cmdfn(nlhs,plhs,nrhs-1,(const mxArray**) prhs+1);
        if (debuglevel > 0) mogl_checkerrors(cmd, prhs);
        goto moglreturn;
    }
    
    // no match
    mogl_usageerr();
    
    // moglreturn: Is the exit path of mogl. All execution ends at this point.
 moglreturn:
    return;
}