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;
}
Beispiel #2
0
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;
}