Exemplo n.º 1
0
static void gl_glsl_deinit(void)
{
   if (glsl_enable)
   {
      pglUseProgram(0);
      for (unsigned i = 0; i < GFX_MAX_SHADERS; i++)
      {
         if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0]))
            continue;

         gl_glsl_delete_shader(gl_program[i]);
      }

      if (glsl_shader)
         glDeleteTextures(glsl_shader->luts, gl_teximage);
   }

   memset(gl_program, 0, sizeof(gl_program));
   glsl_enable  = false;
   active_index = 0;

   gl_glsl_free_shader();

   if (gl_state_tracker)
      state_tracker_free(gl_state_tracker);
   gl_state_tracker = NULL;

   gl_glsl_reset_attrib();
}
Exemplo n.º 2
0
static void gl_glsl_deinit(void)
{
   unsigned i;
   glUseProgram(0);
   for (i = 0; i < GFX_MAX_SHADERS; i++)
   {
      if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0]))
         continue;

      glDeleteProgram(gl_program[i]);
   }

   if (glsl_shader && glsl_shader->luts)
      glDeleteTextures(glsl_shader->luts, gl_teximage);

   memset(gl_program, 0, sizeof(gl_program));
   memset(gl_uniforms, 0, sizeof(gl_uniforms));
   glsl_enable  = false;
   active_index = 0;

   gl_glsl_free_shader();

   if (gl_state_tracker)
      state_tracker_free(gl_state_tracker);
   gl_state_tracker = NULL;

   gl_glsl_reset_attrib();

   for (i = 0; i < GFX_MAX_SHADERS; i++)
   {
      if (glsl_vbo[i].vbo_primary)
         glDeleteBuffers(1, &glsl_vbo[i].vbo_primary);
      if (glsl_vbo[i].vbo_secondary)
         glDeleteBuffers(1, &glsl_vbo[i].vbo_secondary);
   }
   memset(&glsl_vbo, 0, sizeof(glsl_vbo));
}
Exemplo n.º 3
0
static bool gl_glsl_init(const char *path)
{
#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__)
   // Load shader functions.
   LOAD_GL_SYM(CreateProgram);
   LOAD_GL_SYM(UseProgram);
   LOAD_GL_SYM(CreateShader);
   LOAD_GL_SYM(DeleteShader);
   LOAD_GL_SYM(ShaderSource);
   LOAD_GL_SYM(CompileShader);
   LOAD_GL_SYM(AttachShader);
   LOAD_GL_SYM(DetachShader);
   LOAD_GL_SYM(LinkProgram);
   LOAD_GL_SYM(GetUniformLocation);
   LOAD_GL_SYM(Uniform1i);
   LOAD_GL_SYM(Uniform1f);
   LOAD_GL_SYM(Uniform2fv);
   LOAD_GL_SYM(Uniform4fv);
   LOAD_GL_SYM(UniformMatrix4fv);
   LOAD_GL_SYM(GetShaderiv);
   LOAD_GL_SYM(GetShaderInfoLog);
   LOAD_GL_SYM(GetProgramiv);
   LOAD_GL_SYM(GetProgramInfoLog);
   LOAD_GL_SYM(DeleteProgram);
   LOAD_GL_SYM(GetAttachedShaders);
   LOAD_GL_SYM(GetAttribLocation);
   LOAD_GL_SYM(EnableVertexAttribArray);
   LOAD_GL_SYM(DisableVertexAttribArray);
   LOAD_GL_SYM(VertexAttribPointer);

   RARCH_LOG("Checking GLSL shader support ...\n");
   bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader
      && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader
      && pglDetachShader && pglLinkProgram && pglGetUniformLocation
      && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv
      && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog 
      && pglDeleteProgram && pglGetAttachedShaders
      && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray
      && pglVertexAttribPointer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      return false;
   }
#endif

   glsl_shader = (struct gfx_shader*)calloc(1, sizeof(*glsl_shader));
   if (!glsl_shader)
      return false;

   if (path)
   {
      bool ret;
      if (strcmp(path_get_extension(path), "glsl") == 0)
      {
         strlcpy(glsl_shader->pass[0].source.cg, path, sizeof(glsl_shader->pass[0].source.cg));
         glsl_shader->passes = 1;
         glsl_shader->modern = true;
         ret = true;
      }
      else if (strcmp(path_get_extension(path), "glslp") == 0)
      {
         config_file_t *conf = config_file_new(path);
         if (conf)
         {
            ret = gfx_shader_read_conf_cgp(conf, glsl_shader);
            glsl_shader->modern = true;
            config_file_free(conf);
         }
         else
            ret = false;
      }
      else
         ret = gfx_shader_read_xml(path, glsl_shader);

      if (!ret)
      {
         RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
         return false;
      }
   }
   else
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      glsl_shader->passes = 1;
      glsl_shader->pass[0].source.xml.vertex   = strdup(stock_vertex_modern);
      glsl_shader->pass[0].source.xml.fragment = strdup(stock_fragment_modern);
      glsl_shader->modern = true;
   }

   gfx_shader_resolve_relative(glsl_shader, path);

#ifdef HAVE_OPENGLES2
   if (!glsl_shader->modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      return false;
   }
#endif

   const char *stock_vertex = glsl_shader->modern ?
      stock_vertex_modern : stock_vertex_legacy;
   const char *stock_fragment = glsl_shader->modern ?
      stock_fragment_modern : stock_fragment_legacy;

   if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0)))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      gl_glsl_free_shader();
      return false;
   }

   if (!compile_programs(&gl_program[1]))
   {
      gl_glsl_free_shader();
      return false;
   }

   if (!load_luts())
   {
      RARCH_ERR("[GL]: Failed to load LUTs.\n");
      gl_glsl_free_shader();
      return false;
   }

   for (unsigned i = 0; i <= glsl_shader->passes; i++)
      find_uniforms(gl_program[i], &gl_uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error())
      RARCH_WARN("Detected GL error in GLSL.\n");
#endif

   if (glsl_shader->variables)
   {
      struct state_tracker_info info = {0};
      info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
      info.info      = glsl_shader->variable;
      info.info_elem = glsl_shader->variables;

#ifdef HAVE_PYTHON
      info.script = glsl_shader->script;
      info.script_class = *glsl_shader->script_class ?
         glsl_shader->script_class : NULL;
#endif

      gl_state_tracker = state_tracker_init(&info);
      if (!gl_state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }
   
   glsl_enable = true;
   gl_program[glsl_shader->passes  + 1] = gl_program[0];
   gl_uniforms[glsl_shader->passes + 1] = gl_uniforms[0];

   if (glsl_shader->modern)
   {
      gl_program[GL_SHADER_STOCK_BLEND] = compile_program(stock_vertex_modern_blend,
            stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);

      find_uniforms(gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
   }
   else
   {
      gl_program[GL_SHADER_STOCK_BLEND] = gl_program[0];
      gl_uniforms[GL_SHADER_STOCK_BLEND] = gl_uniforms[0];
   }

   gl_glsl_reset_attrib();

   return true;
}