static int _evas_gl_common_shader_program_source_init(Evas_GL_Program *p, Evas_GL_Program_Source *vert, Evas_GL_Program_Source *frag, const char *name) { GLint ok; p->vert = glCreateShader(GL_VERTEX_SHADER); p->frag = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(p->vert, 1, (const char **)&(vert->src), NULL); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glCompileShader(p->vert); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); ok = 0; glGetShaderiv(p->vert, GL_COMPILE_STATUS, &ok); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); if (!ok) { gl_compile_link_error(p->vert, "compile vertex shader"); ERR("Abort compile of shader vert (%s): %s", name, vert->src); return 0; } glShaderSource(p->frag, 1, (const char **)&(frag->src), NULL); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glCompileShader(p->frag); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); ok = 0; glGetShaderiv(p->frag, GL_COMPILE_STATUS, &ok); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); if (!ok) { gl_compile_link_error(p->frag, "compile fragment shader"); ERR("Abort compile of shader frag (%s): %s", name, frag->src); return 0; } p->prog = glCreateProgram(); #ifdef GL_GLES #else if ((glsym_glGetProgramBinary) && (glsym_glProgramParameteri)) glsym_glProgramParameteri(p->prog, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); #endif glAttachShader(p->prog, p->vert); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glAttachShader(p->prog, p->frag); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_VERTEX, "vertex"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_COLOR, "color"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_TEXUV, "tex_coord"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_TEXUV2, "tex_coord2"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_TEXUV3, "tex_coord3"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glBindAttribLocation(p->prog, SHAD_TEXM, "tex_coordm"); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glLinkProgram(p->prog); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); ok = 0; glGetProgramiv(p->prog, GL_LINK_STATUS, &ok); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); if (!ok) { gl_compile_link_error(p->prog, "link fragment and vertex shaders"); ERR("Abort compile of shader frag (%s): %s", name, frag->src); ERR("Abort compile of shader vert (%s): %s", name, vert->src); return 0; } return 1; }
static Evas_GL_Program * evas_gl_common_shader_compile(unsigned int flags, const char *vertex, const char *fragment) { Evas_GL_Program *p; GLuint vtx, frg, prg; GLint ok = 0; compiler_released = EINA_FALSE; vtx = glCreateShader(GL_VERTEX_SHADER); frg = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vtx, 1, &vertex, NULL); glCompileShader(vtx); glGetShaderiv(vtx, GL_COMPILE_STATUS, &ok); if (!ok) { gl_compile_link_error(vtx, "compile vertex shader", EINA_TRUE); ERR("Abort compile of vertex shader:\n%s", vertex); glDeleteShader(vtx); return NULL; } ok = 0; glShaderSource(frg, 1, &fragment, NULL); glCompileShader(frg); glGetShaderiv(frg, GL_COMPILE_STATUS, &ok); if (!ok) { gl_compile_link_error(frg, "compile fragment shader", EINA_TRUE); ERR("Abort compile of fragment shader:\n%s", fragment); glDeleteShader(vtx); glDeleteShader(frg); return NULL; } ok = 0; prg = glCreateProgram(); #ifndef GL_GLES if ((glsym_glGetProgramBinary) && (glsym_glProgramParameteri)) glsym_glProgramParameteri(prg, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); #endif glAttachShader(prg, vtx); glAttachShader(prg, frg); _attributes_bind(prg); glLinkProgram(prg); glGetProgramiv(prg, GL_LINK_STATUS, &ok); if (!ok) { gl_compile_link_error(prg, "link fragment and vertex shaders", EINA_FALSE); ERR("Abort compile of shader (flags: %08x)", flags); glDeleteShader(vtx); glDeleteShader(frg); glDeleteProgram(prg); return 0; } p = calloc(1, sizeof(*p)); p->flags = flags; p->prog = prg; p->reset = EINA_TRUE; glDeleteShader(vtx); glDeleteShader(frg); return p; }
static int _evas_gl_common_shader_program_binary_init(Evas_GL_Program *p, const char *pname, Eet_File *ef) { int res = 0, num = 0, length = 0; int *formats = NULL; void *data = NULL; GLint ok = 0; if (!ef) return res; data = eet_read(ef, pname, &length); if ((!data) || (length <= 0)) goto finish; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num); if (num <= 0) goto finish; formats = calloc(num, sizeof(int)); if (!formats) goto finish; glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, formats); if (!formats[0]) goto finish; p->prog = glCreateProgram(); #if 1 // TODO: invalid rendering error occurs when attempting to use a // glProgramBinary. in order to render correctly we should create a dummy // vertex shader. p->vert = glCreateShader(GL_VERTEX_SHADER); glAttachShader(p->prog, p->vert); p->frag = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(p->prog, p->frag); #endif glsym_glProgramBinary(p->prog, formats[0], data, length); glBindAttribLocation(p->prog, SHAD_VERTEX, "vertex"); glBindAttribLocation(p->prog, SHAD_COLOR, "color"); glBindAttribLocation(p->prog, SHAD_TEXUV, "tex_coord"); glBindAttribLocation(p->prog, SHAD_TEXUV2, "tex_coord2"); glBindAttribLocation(p->prog, SHAD_TEXUV3, "tex_coord3"); glBindAttribLocation(p->prog, SHAD_TEXM, "tex_coordm"); glGetProgramiv(p->prog, GL_LINK_STATUS, &ok); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); if (!ok) { gl_compile_link_error(p->prog, "load a program object"); ERR("Abort load of program (%s)", pname); goto finish; } res = 1; finish: if (formats) free(formats); if (data) free(data); if ((!res) && (p->prog)) { glDeleteProgram(p->prog); p->prog = 0; } return res; }
static Evas_GL_Program * _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags) { int num = 0, length = 0; int *formats = NULL; void *data = NULL; char pname[32]; GLint ok = 0, prg, vtx = GL_NONE, frg = GL_NONE; Evas_GL_Program *p = NULL; Eina_Bool direct = 1; if (!ef || !glsym_glProgramBinary) return NULL; sprintf(pname, SHADER_PROG_NAME_FMT, flags); data = (void *) eet_read_direct(ef, pname, &length); if (!data) { data = eet_read(ef, pname, &length); direct = 0; } if ((!data) || (length <= 0)) goto finish; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num); if (num <= 0) goto finish; formats = calloc(num, sizeof(int)); if (!formats) goto finish; glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, formats); if (!formats[0]) goto finish; prg = glCreateProgram(); #if 1 // TODO: invalid rendering error occurs when attempting to use a // glProgramBinary. in order to render correctly we should create a dummy // vertex shader. vtx = glCreateShader(GL_VERTEX_SHADER); glAttachShader(prg, vtx); frg = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(prg, frg); #endif glsym_glProgramBinary(prg, formats[0], data, length); _attributes_bind(prg); glGetProgramiv(prg, GL_LINK_STATUS, &ok); if (!ok) { gl_compile_link_error(prg, "load a program object", EINA_FALSE); ERR("Abort load of program (%s)", pname); glDeleteProgram(prg); goto finish; } p = calloc(1, sizeof(*p)); p->flags = flags; p->prog = prg; p->reset = EINA_TRUE; p->bin_saved = EINA_TRUE; p->uniform.mvp = glGetUniformLocation(prg, "mvp"); p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id"); evas_gl_common_shader_textures_bind(p); finish: if (vtx) glDeleteShader(vtx); if (frg) glDeleteShader(frg); free(formats); if (!direct) free(data); return p; }