void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { long nnod, nnod_reg, reg; double *inreg; double *source; double *nodes_reg; double D; size_t elt_size; mxArray *q; if(nrhs != 7) mexErrMsgTxt("7 inputs required\n"); if(nlhs != 1) mexErrMsgTxt("1 output required\n"); nnod = (long) *(mxGetPr(prhs[0])); elt_size = mxGetElementSize(prhs[1]); assert(elt_size != 0); nnod_reg = mxGetM(prhs[1]); nodes_reg = mxGetPr(prhs[1]); if(mxGetN(prhs[2]) != 1) mexErrMsgTxt("Need row vector for inreg\n "); inreg = mxGetPr(prhs[2]); mxArray *omega = mxCreateDoubleMatrix(1,1,mxCOMPLEX); *(mxGetPr(omega)) = *(mxGetPr(prhs[3])); if (mxIsComplex(prhs[3])) *(mxGetPi(omega)) = *(mxGetPi(prhs[3])); else *(mxGetPi(omega)) = 0.; D = *(mxGetPr(prhs[4])); elt_size = mxGetElementSize(prhs[5]), assert(elt_size != 0); source = mxGetPr(prhs[5]); reg = (long) *mxGetPr(prhs[6]); q = mxCreateDoubleMatrix(nnod, 1, mxCOMPLEX); build_source(nodes_reg, inreg, nnod, nnod_reg, omega, D, source, reg, q); plhs[0] = q; mxDestroyArray(omega); }
GLProgram *GLCompiler::make( ) { bool errors= false; bool shaders= false; for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(sources[i].source.empty()) continue; // construit le source shaders= true; sources[i].build= build_source(i); // cree le program if(program == GLProgram::null()) program= (new GLProgram(program_label))->create(); // cree le shader GLuint shader= program->shaders[i]; if(shader == 0) { shader= glCreateShader(GLProgram::types[i]); glAttachShader(program->name, shader); program->shaders[i]= shader; } // compile le shader const char *text[]= { sources[i].build.c_str() }; glShaderSource(shader, 1, text, NULL); glCompileShader(shader); GLint status= 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) { errors= true; GLint length= 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); if(length > 0) { char *log= new char[length +1]; glGetShaderInfoLog(shader, length, NULL, log); ERROR("error compiling %s shader:\n", GLProgram::labels[i]); printErrors(log, sources[i]); ERROR("shader defines:\n%s\n", sources[i].definitions.c_str()); delete [] log; } else MESSAGE("error compiling %s shader: no log. failed.\n", GLProgram::labels[i]); } #if 0 { GLint length= 0; glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); if(length > 0) { char log[4096]; glGetShaderSource(shader, sizeof(log), NULL, log); DEBUGLOG("shader:\n%s\n", log); } } #endif } if(shaders == false || program == GLProgram::null()) { ERROR("no shader. failed.\n"); return program; } if(errors == true) { program->resources(); program->errors= true; return program; } // link GLint status= 0; glLinkProgram(program->name); glGetProgramiv(program->name, GL_LINK_STATUS, &status); if(status == GL_FALSE) { GLint length= 0; glGetProgramiv(program->name, GL_INFO_LOG_LENGTH, &length); if(length > 0) { char *log= new char[length +1]; glGetProgramInfoLog(program->name, length, NULL, log); MESSAGE("error linking program:\n%s\nfailed.\n", log); delete [] log; } else MESSAGE("error linking program: no log. failed.\n"); program->errors= true; return program; } //~ #ifdef GK_OPENGL4 #if 0 { // interface matching // introspection opengl >= 4.3 // recompile chaque shader dans un program separe et recupere les varyings avec queryinterface(program_inputs / program_outputs)... std::vector<parameter> stage_inputs[GLProgram::SHADERTYPE_LAST]; std::vector<parameter> stage_outputs[GLProgram::SHADERTYPE_LAST]; for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(program->shaders[i] == 0) continue; // recupere le source du shader GLint stage_length= 0; glGetShaderiv(program->shaders[i], GL_SHADER_SOURCE_LENGTH, &stage_length); std::vector<GLchar> stage_source(stage_length +1); glGetShaderSource(program->shaders[i], stage_source.size(), NULL, &stage_source.front()); // construit un program pipeline avec uniquement ce shader const GLchar *sources[]= { &stage_source.front() }; GLuint stage= glCreateShader(GLProgram::types[i]); glShaderSource(stage, 1, sources, NULL); glCompileShader(stage); GLuint pipeline= glCreateProgram(); glProgramParameteri(pipeline, GL_PROGRAM_SEPARABLE, GL_TRUE); glAttachShader(pipeline, stage); glLinkProgram(pipeline); glValidateProgram(pipeline); // recupere les varyings in / out GLint inputs; glGetProgramInterfaceiv(pipeline, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &inputs); for(int k= 0; k < inputs; k++) { GLenum properties[3]= { GL_TYPE, GL_LOCATION, GL_LOCATION_COMPONENT }; GLint values[3]= { 0, -1, -1 }; glGetProgramResourceiv(pipeline, GL_PROGRAM_INPUT, k, 3, properties, 3, NULL, values); GLchar name[4096]= { 0 }; glGetProgramResourceName(pipeline, GL_PROGRAM_INPUT, k, sizeof(name), NULL, name); stage_inputs[i].push_back( parameter(name, k, values[0], values[1], -1, values[2]) ); } std::stable_sort(stage_inputs[i].begin(), stage_inputs[i].end()); GLint outputs; glGetProgramInterfaceiv(pipeline, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &outputs); for(int k= 0; k < outputs; k++) { GLenum properties[4]= { GL_TYPE, GL_LOCATION, GL_LOCATION_INDEX, GL_LOCATION_COMPONENT }; GLint values[4]= { 0, -1, -1, -1 }; glGetProgramResourceiv(pipeline, GL_PROGRAM_OUTPUT, k, 4, properties, 4, NULL, values); GLchar name[4096]= { 0 }; glGetProgramResourceName(pipeline, GL_PROGRAM_OUTPUT, k, sizeof(name), NULL, name); stage_outputs[i].push_back( parameter(name, k, values[0], values[1], values[2], values[3]) ); } std::stable_sort(stage_outputs[i].begin(), stage_outputs[i].end()); // nettoyage glDeleteShader(stage); glDeleteProgram(pipeline); } // affichage : les sorties d'un shader doivent correspondre aux entrees du shader suivant dans le pipeline printf("program interfaces...\n"); for(unsigned int i= 0; i < GLProgram::SHADERTYPE_LAST; i++) { if(stage_inputs[i].size()) { printf(" %s shader inputs:\n", GLProgram::labels[i]); for(unsigned int k= 0; k < stage_inputs[i].size(); k++) { const char *type= glsl::type_string(stage_inputs[i][k].type); if(type) printf(" %02d/-1: '%s', type '%s'\n", stage_inputs[i][k].location, stage_inputs[i][k].name.c_str(), type); else printf(" %02d/-1: '%s', type 0x%x\n", stage_inputs[i][k].location, stage_inputs[i][k].name.c_str(), stage_inputs[i][k].type); } } if(stage_outputs[i].size()) { printf(" %s shader outputs:\n", GLProgram::labels[i]); for(unsigned int k= 0; k < stage_outputs[i].size(); k++) { const char *type= glsl::type_string(stage_outputs[i][k].type); if(type) printf(" %02d/%02d: '%s', type '%s'\n", stage_outputs[i][k].location, stage_outputs[i][k].location_index, stage_outputs[i][k].name.c_str(), type); else printf(" %02d/%02d: '%s', type 0x%x\n", stage_outputs[i][k].location, stage_outputs[i][k].location_index, stage_outputs[i][k].name.c_str(), stage_outputs[i][k].type); } } //! \todo verification des interfaces } } #endif program->resources(); program->errors= false; MESSAGE("done.\n"); return program; }