Beispiel #1
0
void RenderChain::bind_tracker(Pass &pass, unsigned pass_index)
{
   if (!tracker)
      return;

   if (pass_index == 1)
      uniform_cnt = state_get_uniform(tracker, uniform_info, MAX_VARIABLES, frame_count);

   for (unsigned i = 0; i < uniform_cnt; i++)
   {
      set_cg_param(pass.fPrg, uniform_info[i].id, uniform_info[i].value);
      set_cg_param(pass.vPrg, uniform_info[i].id, uniform_info[i].value);
   }
}
Beispiel #2
0
void gl_glsl_set_params(unsigned width, unsigned height, 
      unsigned tex_width, unsigned tex_height, 
      unsigned out_width, unsigned out_height,
      unsigned frame_count,
      const struct gl_tex_info *info, 
      const struct gl_tex_info *prev_info, 
      const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt)
{
   // We enforce a certain layout for our various texture types in the texunits.
   // - Regular frame (rubyTexture) (always bound).
   // - LUT textures (always bound).
   // - Original texture (always bound if meaningful).
   // - FBO textures (always bound if available).
   // - Previous textures.

   if (!glsl_enable || (gl_program[active_index] == 0))
      return;

   const struct shader_uniforms *uni = &gl_uniforms[active_index];

   float input_size[2] = {(float)width, (float)height};
   float output_size[2] = {(float)out_width, (float)out_height};
   float texture_size[2] = {(float)tex_width, (float)tex_height};

   if (uni->input_size >= 0)
      pglUniform2fv(uni->input_size, 1, input_size);

   if (uni->output_size >= 0)
      pglUniform2fv(uni->output_size, 1, output_size);

   if (uni->texture_size >= 0)
      pglUniform2fv(uni->texture_size, 1, texture_size);

   if (uni->frame_count >= 0)
      pglUniform1i(uni->frame_count, frame_count);

   if (uni->frame_direction >= 0)
      pglUniform1i(uni->frame_direction, g_extern.frame_is_reverse ? -1 : 1);

   for (unsigned i = 0; i < gl_teximage_cnt; i++)
   {
      if (uni->lut_texture[i] >= 0)
         pglUniform1i(uni->lut_texture[i], i + 1);
   }

   unsigned texunit = gl_teximage_cnt + 1;

   // Set original texture unless we're in first pass (pointless).
   if (active_index > 1)
   {
      if (uni->orig.texture >= 0)
      {
         // Bind original texture.
         pglActiveTexture(GL_TEXTURE0 + texunit);
         pglUniform1i(uni->orig.texture, texunit);
         glBindTexture(GL_TEXTURE_2D, info->tex);
      }

      texunit++;

      if (uni->orig.texture_size >= 0)
         pglUniform2fv(uni->orig.texture_size, 1, info->tex_size);

      if (uni->orig.input_size >= 0)
         pglUniform2fv(uni->orig.input_size, 1, info->input_size);

      // Pass texture coordinates.
      if (uni->orig.tex_coord >= 0)
      {
         int loc = uni->orig.tex_coord;
         pglEnableVertexAttribArray(loc);
         pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, info->coord);
         gl_attribs[gl_attrib_index++] = loc;
      }

      // Bind new texture in the chain.
      if (fbo_info_cnt > 0)
      {
         pglActiveTexture(GL_TEXTURE0 + texunit + fbo_info_cnt - 1);
         glBindTexture(GL_TEXTURE_2D, fbo_info[fbo_info_cnt - 1].tex);
      }

      // Bind FBO textures.
      for (unsigned i = 0; i < fbo_info_cnt; i++)
      {
         if (uni->pass[i].texture)
            pglUniform1i(uni->pass[i].texture, texunit);

         texunit++;

         if (uni->pass[i].texture_size >= 0)
            pglUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size);

         if (uni->pass[i].input_size >= 0)
            pglUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size);

         if (uni->pass[i].tex_coord >= 0)
         {
            int loc = uni->pass[i].tex_coord;
            pglEnableVertexAttribArray(loc);
            pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, fbo_info[i].coord);
            gl_attribs[gl_attrib_index++] = loc;
         }
      }
   }
   else
   {
      // First pass, so unbind everything to avoid collitions.
      // Unbind ORIG.
      pglActiveTexture(GL_TEXTURE0 + texunit);
      glBindTexture(GL_TEXTURE_2D, 0);

      GLuint base_tex = texunit + 1;
      // Unbind any lurking FBO passes.
      // Rendering to a texture that is bound to a texture unit
      // sounds very shaky ... ;)
      for (unsigned i = 0; i < gl_num_programs; i++)
      {
         pglActiveTexture(GL_TEXTURE0 + base_tex + i);
         glBindTexture(GL_TEXTURE_2D, 0);
      }
   }

   // Set previous textures. Only bind if they're actually used.
   for (unsigned i = 0; i < PREV_TEXTURES; i++)
   {
      if (uni->prev[i].texture >= 0)
      {
         pglActiveTexture(GL_TEXTURE0 + texunit);
         glBindTexture(GL_TEXTURE_2D, prev_info[i].tex);
         pglUniform1i(uni->prev[i].texture, texunit++);
      }

      texunit++;

      if (uni->prev[i].texture_size >= 0)
         pglUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size);

      if (uni->prev[i].input_size >= 0)
         pglUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size);

      // Pass texture coordinates.
      if (uni->prev[i].tex_coord >= 0)
      {
         int loc = uni->prev[i].tex_coord;
         pglEnableVertexAttribArray(loc);
         pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, prev_info[i].coord);
         gl_attribs[gl_attrib_index++] = loc; 
      }
   }

   pglActiveTexture(GL_TEXTURE0);

   if (gl_state_tracker)
   {
      static struct state_tracker_uniform info[MAX_VARIABLES];
      static unsigned cnt = 0;

      if (active_index == 1)
         cnt = state_get_uniform(gl_state_tracker, info, MAX_VARIABLES, frame_count);

      for (unsigned i = 0; i < cnt; i++)
      {
         int location = pglGetUniformLocation(gl_program[active_index], info[i].id);
         pglUniform1f(location, info[i].value);
      }
   }
}
Beispiel #3
0
void gl_glsl_set_params(unsigned width, unsigned height, 
      unsigned tex_width, unsigned tex_height, 
      unsigned out_width, unsigned out_height,
      unsigned frame_count,
      const struct gl_tex_info *info, 
      const struct gl_tex_info *prev_info, 
      const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt)
{
   // We enforce a certain layout for our various texture types in the texunits.
   // - Regular SNES frame (rubyTexture) (always bound).
   // - LUT textures (always bound).
   // - Original texture (always bound if meaningful).
   // - FBO textures (always bound if available).
   // - Previous textures.

   if (!glsl_enable || (gl_program[active_index] == 0))
      return;

   GLint location;

   float inputSize[2] = {(float)width, (float)height};
   location = pglGetUniformLocation(gl_program[active_index], "rubyInputSize");
   pglUniform2fv(location, 1, inputSize);

   float outputSize[2] = {(float)out_width, (float)out_height};
   location = pglGetUniformLocation(gl_program[active_index], "rubyOutputSize");
   pglUniform2fv(location, 1, outputSize);

   float textureSize[2] = {(float)tex_width, (float)tex_height};
   location = pglGetUniformLocation(gl_program[active_index], "rubyTextureSize");
   pglUniform2fv(location, 1, textureSize);

   location = pglGetUniformLocation(gl_program[active_index], "rubyFrameCount");
   pglUniform1i(location, frame_count);

   location = pglGetUniformLocation(gl_program[active_index], "rubyFrameDirection");
   pglUniform1i(location, g_extern.frame_is_reverse ? -1 : 1);

   for (unsigned i = 0; i < gl_teximage_cnt; i++)
   {
      location = pglGetUniformLocation(gl_program[active_index], gl_teximage_uniforms[i]);
      pglUniform1i(location, i + 1);
   }

   unsigned texunit = gl_teximage_cnt + 1;

   // Set original texture unless we're in first pass (pointless).
   if (active_index > 1)
   {
      // Bind original texture.
      pglActiveTexture(GL_TEXTURE0 + texunit);

      location = pglGetUniformLocation(gl_program[active_index], "rubyOrigTexture");
      pglUniform1i(location, texunit++);
      glBindTexture(GL_TEXTURE_2D, info->tex);

      location = pglGetUniformLocation(gl_program[active_index], "rubyOrigTextureSize");
      pglUniform2fv(location, 1, info->tex_size);
      location = pglGetUniformLocation(gl_program[active_index], "rubyOrigInputSize");
      pglUniform2fv(location, 1, info->input_size);

      // Pass texture coordinates.
      location = pglGetAttribLocation(gl_program[active_index], "rubyOrigTexCoord");
      if (location >= 0)
      {
         pglEnableVertexAttribArray(location);
         pglVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 0, info->coord);
         gl_attribs[gl_attrib_index++] = location;
      }

      // Bind new texture in the chain.
      if (fbo_info_cnt > 0)
      {
         pglActiveTexture(GL_TEXTURE0 + texunit + fbo_info_cnt - 1);
         glBindTexture(GL_TEXTURE_2D, fbo_info[fbo_info_cnt - 1].tex);
      }

      // Bind FBO textures.
      for (unsigned i = 0; i < fbo_info_cnt; i++)
      {
         char attrib_buf[64];

         snprintf(attrib_buf, sizeof(attrib_buf), "rubyPass%uTexture", i + 1);
         location = pglGetUniformLocation(gl_program[active_index], attrib_buf);
         pglUniform1i(location, texunit++);

         snprintf(attrib_buf, sizeof(attrib_buf), "rubyPass%uTextureSize", i + 1);
         location = pglGetUniformLocation(gl_program[active_index], attrib_buf);
         pglUniform2fv(location, 1, fbo_info[i].tex_size);

         snprintf(attrib_buf, sizeof(attrib_buf), "rubyPass%uInputSize", i + 1);
         location = pglGetUniformLocation(gl_program[active_index], attrib_buf);
         pglUniform2fv(location, 1, fbo_info[i].input_size);

         snprintf(attrib_buf, sizeof(attrib_buf), "rubyPass%uTexCoord", i + 1);
         location = pglGetAttribLocation(gl_program[active_index], attrib_buf);
         if (location >= 0)
         {
            pglEnableVertexAttribArray(location);
            pglVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 0, fbo_info[i].coord);
            gl_attribs[gl_attrib_index++] = location;
         }
      }
   }
   else
   {
      // First pass, so unbind everything to avoid collitions.
      // Unbind ORIG.
      pglActiveTexture(GL_TEXTURE0 + texunit);
      glBindTexture(GL_TEXTURE_2D, 0);

      GLuint base_tex = texunit + 1;
      // Unbind any lurking FBO passes.
      // Rendering to a texture that is bound to a texture unit
      // sounds very shaky ... ;)
      for (unsigned i = 0; i < gl_num_programs; i++)
      {
         pglActiveTexture(GL_TEXTURE0 + base_tex + i);
         glBindTexture(GL_TEXTURE_2D, 0);
      }
   }

   // Set previous textures. Only bind if they're actually used.
   for (unsigned i = 0; i < PREV_TEXTURES; i++)
   {
      char attr_buf_tex[64];
      char attr_buf_tex_size[64];
      char attr_buf_input_size[64];
      char attr_buf_coord[64];
      static const char *prev_names[PREV_TEXTURES] = {
         "Prev",
         "Prev1",
         "Prev2",
         "Prev3",
         "Prev4",
         "Prev5",
         "Prev6",
      };

      snprintf(attr_buf_tex,        sizeof(attr_buf_tex),        "ruby%sTexture",     prev_names[i]);
      snprintf(attr_buf_tex_size,   sizeof(attr_buf_tex_size),   "ruby%sTextureSize", prev_names[i]);
      snprintf(attr_buf_input_size, sizeof(attr_buf_input_size), "ruby%sInputSize",   prev_names[i]);
      snprintf(attr_buf_coord,      sizeof(attr_buf_coord),      "ruby%sTexCoord",    prev_names[i]);

      location = pglGetUniformLocation(gl_program[active_index], attr_buf_tex);
      if (location >= 0)
      {
         pglActiveTexture(GL_TEXTURE0 + texunit);
         glBindTexture(GL_TEXTURE_2D, prev_info[i].tex);
         pglUniform1i(location, texunit++);
      }

      location = pglGetUniformLocation(gl_program[active_index], attr_buf_tex_size);
      pglUniform2fv(location, 1, prev_info[i].tex_size);
      location = pglGetUniformLocation(gl_program[active_index], attr_buf_input_size);
      pglUniform2fv(location, 1, prev_info[i].input_size);

      // Pass texture coordinates.
      location = pglGetAttribLocation(gl_program[active_index], attr_buf_coord);
      if (location >= 0)
      {
         pglEnableVertexAttribArray(location);
         pglVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 0, prev_info[i].coord);
         gl_attribs[gl_attrib_index++] = location;
      }
   }

   pglActiveTexture(GL_TEXTURE0);

   if (gl_state_tracker)
   {
      static struct state_tracker_uniform info[MAX_VARIABLES];
      static unsigned cnt = 0;

      if (active_index == 1)
         cnt = state_get_uniform(gl_state_tracker, info, MAX_VARIABLES, frame_count);

      for (unsigned i = 0; i < cnt; i++)
      {
         location = pglGetUniformLocation(gl_program[active_index], info[i].id);
         pglUniform1f(location, info[i].value);
      }
   }
}
Beispiel #4
0
static void gl_cg_set_params(unsigned width, unsigned height, 
      unsigned tex_width, unsigned tex_height,
      unsigned out_width, unsigned out_height,
      unsigned frame_count,
      const struct gl_tex_info *info,
      const struct gl_tex_info *prev_info,
      const struct gl_tex_info *fbo_info,
      unsigned fbo_info_cnt)
{
   unsigned i;
   if (!cg_active || (active_index == 0) || (active_index == GL_SHADER_STOCK_BLEND))
      return;

   // Set frame.
   set_param_2f(prg[active_index].vid_size_f, width, height);
   set_param_2f(prg[active_index].tex_size_f, tex_width, tex_height);
   set_param_2f(prg[active_index].out_size_f, out_width, out_height);
   set_param_1f(prg[active_index].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0);

   set_param_2f(prg[active_index].vid_size_v, width, height);
   set_param_2f(prg[active_index].tex_size_v, tex_width, tex_height);
   set_param_2f(prg[active_index].out_size_v, out_width, out_height);
   set_param_1f(prg[active_index].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0);

   if (prg[active_index].frame_cnt_f || prg[active_index].frame_cnt_v)
   {
      unsigned modulo = cg_shader->pass[active_index - 1].frame_count_mod;
      if (modulo)
         frame_count %= modulo;

      set_param_1f(prg[active_index].frame_cnt_f, (float)frame_count);
      set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count);
   }

   // Set orig texture.
   CGparameter param = prg[active_index].orig.tex;
   if (param)
   {
      cgGLSetTextureParameter(param, info->tex);
      cgGLEnableTextureParameter(param);
   }

   set_param_2f(prg[active_index].orig.vid_size_v, info->input_size[0], info->input_size[1]);
   set_param_2f(prg[active_index].orig.vid_size_f, info->input_size[0], info->input_size[1]);
   set_param_2f(prg[active_index].orig.tex_size_v, info->tex_size[0],   info->tex_size[1]);
   set_param_2f(prg[active_index].orig.tex_size_f, info->tex_size[0],   info->tex_size[1]);
   if (prg[active_index].orig.coord)
   {
      cgGLSetParameterPointer(prg[active_index].orig.coord, 2, GL_FLOAT, 0, info->coord);
      cgGLEnableClientState(prg[active_index].orig.coord);
      cg_attribs[cg_attrib_index++] = prg[active_index].orig.coord;
   }

   // Set prev textures.
   for (i = 0; i < PREV_TEXTURES; i++)
   {
      param = prg[active_index].prev[i].tex;
      if (param)
      {
         cgGLSetTextureParameter(param, prev_info[i].tex);
         cgGLEnableTextureParameter(param);
      }

      set_param_2f(prg[active_index].prev[i].vid_size_v, prev_info[i].input_size[0], prev_info[i].input_size[1]);
      set_param_2f(prg[active_index].prev[i].vid_size_f, prev_info[i].input_size[0], prev_info[i].input_size[1]);
      set_param_2f(prg[active_index].prev[i].tex_size_v, prev_info[i].tex_size[0],   prev_info[i].tex_size[1]);
      set_param_2f(prg[active_index].prev[i].tex_size_f, prev_info[i].tex_size[0],   prev_info[i].tex_size[1]);

      if (prg[active_index].prev[i].coord)
      {
         cgGLSetParameterPointer(prg[active_index].prev[i].coord, 2, GL_FLOAT, 0, prev_info[i].coord);
         cgGLEnableClientState(prg[active_index].prev[i].coord);
         cg_attribs[cg_attrib_index++] = prg[active_index].prev[i].coord;
      }
   }

   // Set lookup textures.
   for (i = 0; i < cg_shader->luts; i++)
   {
      CGparameter fparam = cgGetNamedParameter(prg[active_index].fprg, cg_shader->lut[i].id);
      if (fparam)
      {
         cgGLSetTextureParameter(fparam, lut_textures[i]);
         cgGLEnableTextureParameter(fparam);
      }

      CGparameter vparam = cgGetNamedParameter(prg[active_index].vprg, cg_shader->lut[i].id);
      if (vparam)
      {
         cgGLSetTextureParameter(vparam, lut_textures[i]);
         cgGLEnableTextureParameter(vparam);
      }
   }

   // Set FBO textures.
   if (active_index > 2)
   {
      for (i = 0; i < fbo_info_cnt; i++)
      {
         if (prg[active_index].fbo[i].tex)
         {
            cgGLSetTextureParameter(prg[active_index].fbo[i].tex, fbo_info[i].tex);
            cgGLEnableTextureParameter(prg[active_index].fbo[i].tex);
         }

         set_param_2f(prg[active_index].fbo[i].vid_size_v, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
         set_param_2f(prg[active_index].fbo[i].vid_size_f, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);

         set_param_2f(prg[active_index].fbo[i].tex_size_v, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
         set_param_2f(prg[active_index].fbo[i].tex_size_f, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);

         if (prg[active_index].fbo[i].coord)
         {
            cgGLSetParameterPointer(prg[active_index].fbo[i].coord, 2, GL_FLOAT, 0, fbo_info[i].coord);
            cgGLEnableClientState(prg[active_index].fbo[i].coord);
            cg_attribs[cg_attrib_index++] = prg[active_index].fbo[i].coord;
         }
      }
   }

   // Set state parameters
   if (state_tracker)
   {
      // Only query uniforms in first pass.
      static struct state_tracker_uniform info[MAX_VARIABLES];
      static unsigned cnt = 0;

      if (active_index == 1)
         cnt = state_get_uniform(state_tracker, info, MAX_VARIABLES, frame_count);

      for (i = 0; i < cnt; i++)
      {
         CGparameter param_v = cgGetNamedParameter(prg[active_index].vprg, info[i].id);
         CGparameter param_f = cgGetNamedParameter(prg[active_index].fprg, info[i].id);
         set_param_1f(param_v, info[i].value);
         set_param_1f(param_f, info[i].value);
      }
   }
}
Beispiel #5
0
static void gl_glsl_set_params(void *data, unsigned width, unsigned height, 
      unsigned tex_width, unsigned tex_height, 
      unsigned out_width, unsigned out_height,
      unsigned frame_count,
      const struct gl_tex_info *info, 
      const struct gl_tex_info *prev_info, 
      const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt)
{
   (void)data;
   // We enforce a certain layout for our various texture types in the texunits.
   // - Regular frame (Texture) (always bound).
   // - LUT textures (always bound).
   // - Original texture (always bound if meaningful).
   // - FBO textures (always bound if available).
   // - Previous textures.

   if (!glsl_enable || (gl_program[active_index] == 0))
      return;

   GLfloat buffer[128];
   unsigned i;
   size_t size = 0;
   struct glsl_attrib attribs[32];
   size_t attribs_size = 0;
   struct glsl_attrib *attr = attribs;

   const struct shader_uniforms *uni = &gl_uniforms[active_index];

   float input_size[2] = {(float)width, (float)height};
   float output_size[2] = {(float)out_width, (float)out_height};
   float texture_size[2] = {(float)tex_width, (float)tex_height};

   if (uni->input_size >= 0)
      glUniform2fv(uni->input_size, 1, input_size);

   if (uni->output_size >= 0)
      glUniform2fv(uni->output_size, 1, output_size);

   if (uni->texture_size >= 0)
      glUniform2fv(uni->texture_size, 1, texture_size);

   if (uni->frame_count >= 0 && active_index)
   {
      unsigned modulo = glsl_shader->pass[active_index - 1].frame_count_mod;
      if (modulo)
         frame_count %= modulo;
      glUniform1i(uni->frame_count, frame_count);
   }

   if (uni->frame_direction >= 0)
      glUniform1i(uni->frame_direction, g_extern.frame_is_reverse ? -1 : 1);

   for (i = 0; i < glsl_shader->luts; i++)
   {
      if (uni->lut_texture[i] >= 0)
      {
         // Have to rebind as HW render could override this.
         glActiveTexture(GL_TEXTURE0 + i + 1);
         glBindTexture(GL_TEXTURE_2D, gl_teximage[i]);
         glUniform1i(uni->lut_texture[i], i + 1);
      }
   }

   unsigned texunit = glsl_shader->luts + 1;

   // Set original texture unless we're in first pass (pointless).
   if (active_index > 1)
   {
      if (uni->orig.texture >= 0)
      {
         // Bind original texture.
         glActiveTexture(GL_TEXTURE0 + texunit);
         glUniform1i(uni->orig.texture, texunit);
         glBindTexture(GL_TEXTURE_2D, info->tex);
      }

      texunit++;

      if (uni->orig.texture_size >= 0)
         glUniform2fv(uni->orig.texture_size, 1, info->tex_size);

      if (uni->orig.input_size >= 0)
         glUniform2fv(uni->orig.input_size, 1, info->input_size);

      // Pass texture coordinates.
      if (uni->orig.tex_coord >= 0)
      {
         attr->loc = uni->orig.tex_coord;
         attr->size = 2;
         attr->offset = size * sizeof(GLfloat);
         attribs_size++;
         attr++;

         memcpy(buffer + size, info->coord, 8 * sizeof(GLfloat));
         size += 8;
      }

      // Bind new texture in the chain.
      if (fbo_info_cnt > 0)
      {
         glActiveTexture(GL_TEXTURE0 + texunit + fbo_info_cnt - 1);
         glBindTexture(GL_TEXTURE_2D, fbo_info[fbo_info_cnt - 1].tex);
      }

      // Bind FBO textures.
      for (i = 0; i < fbo_info_cnt; i++)
      {
         if (uni->pass[i].texture)
            glUniform1i(uni->pass[i].texture, texunit);

         texunit++;

         if (uni->pass[i].texture_size >= 0)
            glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size);

         if (uni->pass[i].input_size >= 0)
            glUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size);

         if (uni->pass[i].tex_coord >= 0)
         {
            attr->loc = uni->pass[i].tex_coord;
            attr->size = 2;
            attr->offset = size * sizeof(GLfloat);
            attribs_size++;
            attr++;

            memcpy(buffer + size, fbo_info[i].coord, 8 * sizeof(GLfloat));
            size += 8;
         }
      }
   }
   else
   {
      // First pass, so unbind everything to avoid collitions.
      // Unbind ORIG.
      glActiveTexture(GL_TEXTURE0 + texunit);
      glBindTexture(GL_TEXTURE_2D, 0);

      GLuint base_tex = texunit + 1;
      // Unbind any lurking FBO passes.
      // Rendering to a texture that is bound to a texture unit
      // sounds very shaky ... ;)
      for (i = 0; i < glsl_shader->passes; i++)
      {
         glActiveTexture(GL_TEXTURE0 + base_tex + i);
         glBindTexture(GL_TEXTURE_2D, 0);
      }
   }

   // Set previous textures. Only bind if they're actually used.
   for (i = 0; i < PREV_TEXTURES; i++)
   {
      if (uni->prev[i].texture >= 0)
      {
         glActiveTexture(GL_TEXTURE0 + texunit);
         glBindTexture(GL_TEXTURE_2D, prev_info[i].tex);
         glUniform1i(uni->prev[i].texture, texunit++);
      }

      texunit++;

      if (uni->prev[i].texture_size >= 0)
         glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size);

      if (uni->prev[i].input_size >= 0)
         glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size);

      // Pass texture coordinates.
      if (uni->prev[i].tex_coord >= 0)
      {
         attr->loc = uni->prev[i].tex_coord;
         attr->size = 2;
         attr->offset = size * sizeof(GLfloat);
         attribs_size++;
         attr++;

         memcpy(buffer + size, prev_info[i].coord, 8 * sizeof(GLfloat));
         size += 8;
      }
   }

   if (size)
   {
      gl_glsl_set_attribs(glsl_vbo[active_index].vbo_secondary,
            glsl_vbo[active_index].buffer_secondary,
            &glsl_vbo[active_index].size_secondary,
            buffer, size, attribs, attribs_size);
   }

   glActiveTexture(GL_TEXTURE0);

   if (gl_state_tracker)
   {
      static struct state_tracker_uniform info[GFX_MAX_VARIABLES];
      static unsigned cnt = 0;

      if (active_index == 1)
         cnt = state_get_uniform(gl_state_tracker, info, GFX_MAX_VARIABLES, frame_count);

      for (i = 0; i < cnt; i++)
      {
         int location = glGetUniformLocation(gl_program[active_index], info[i].id);
         glUniform1f(location, info[i].value);
      }
   }
}
Beispiel #6
0
static void gl_cg_set_params(void *data, unsigned width, unsigned height, 
      unsigned tex_width, unsigned tex_height,
      unsigned out_width, unsigned out_height,
      unsigned frame_count,
      const void *_info,
      const void *_prev_info,
      const void *_fbo_info,
      unsigned fbo_info_cnt)
{
   unsigned i;
   const struct gl_tex_info *info = (const struct gl_tex_info*)_info;
   const struct gl_tex_info *prev_info = (const struct gl_tex_info*)_prev_info;
   const struct gl_tex_info *fbo_info = (const struct gl_tex_info*)_fbo_info;
   cg_shader_data_t *cg = (cg_shader_data_t*)driver.video_shader_data;

   (void)data;
   if (!cg || (cg->active_idx == 0) ||
         (cg->active_idx == GL_SHADER_STOCK_BLEND))
      return;

   /* Set frame. */
   set_param_2f(cg->prg[cg->active_idx].vid_size_f, width, height);
   set_param_2f(cg->prg[cg->active_idx].tex_size_f, tex_width, tex_height);
   set_param_2f(cg->prg[cg->active_idx].out_size_f, out_width, out_height);
   set_param_1f(cg->prg[cg->active_idx].frame_dir_f,
         g_extern.frame_is_reverse ? -1.0 : 1.0);

   set_param_2f(cg->prg[cg->active_idx].vid_size_v, width, height);
   set_param_2f(cg->prg[cg->active_idx].tex_size_v, tex_width, tex_height);
   set_param_2f(cg->prg[cg->active_idx].out_size_v, out_width, out_height);
   set_param_1f(cg->prg[cg->active_idx].frame_dir_v,
         g_extern.frame_is_reverse ? -1.0 : 1.0);

   if (cg->prg[cg->active_idx].frame_cnt_f || cg->prg[cg->active_idx].frame_cnt_v)
   {
      unsigned modulo = cg->cg_shader->pass[cg->active_idx - 1].frame_count_mod;
      if (modulo)
         frame_count %= modulo;

      set_param_1f(cg->prg[cg->active_idx].frame_cnt_f, (float)frame_count);
      set_param_1f(cg->prg[cg->active_idx].frame_cnt_v, (float)frame_count);
   }

   /* Set orig texture. */
   CGparameter param = cg->prg[cg->active_idx].orig.tex;
   if (param)
   {
      cgGLSetTextureParameter(param, info->tex);
      cgGLEnableTextureParameter(param);
   }

   set_param_2f(cg->prg[cg->active_idx].orig.vid_size_v,
         info->input_size[0], info->input_size[1]);
   set_param_2f(cg->prg[cg->active_idx].orig.vid_size_f,
         info->input_size[0], info->input_size[1]);
   set_param_2f(cg->prg[cg->active_idx].orig.tex_size_v,
         info->tex_size[0],   info->tex_size[1]);
   set_param_2f(cg->prg[cg->active_idx].orig.tex_size_f,
         info->tex_size[0],   info->tex_size[1]);

   if (cg->prg[cg->active_idx].orig.coord)
   {
      cgGLSetParameterPointer(cg->prg[cg->active_idx].orig.coord, 2,
            GL_FLOAT, 0, info->coord);
      cgGLEnableClientState(cg->prg[cg->active_idx].orig.coord);
      cg->cg_attribs[cg->cg_attrib_idx++] = cg->prg[cg->active_idx].orig.coord;
   }

   /* Set prev textures. */
   for (i = 0; i < PREV_TEXTURES; i++)
   {
      param = cg->prg[cg->active_idx].prev[i].tex;
      if (param)
      {
         cgGLSetTextureParameter(param, prev_info[i].tex);
         cgGLEnableTextureParameter(param);
      }

      set_param_2f(cg->prg[cg->active_idx].prev[i].vid_size_v,
            prev_info[i].input_size[0], prev_info[i].input_size[1]);
      set_param_2f(cg->prg[cg->active_idx].prev[i].vid_size_f,
            prev_info[i].input_size[0], prev_info[i].input_size[1]);
      set_param_2f(cg->prg[cg->active_idx].prev[i].tex_size_v,
            prev_info[i].tex_size[0],   prev_info[i].tex_size[1]);
      set_param_2f(cg->prg[cg->active_idx].prev[i].tex_size_f,
            prev_info[i].tex_size[0],   prev_info[i].tex_size[1]);

      if (cg->prg[cg->active_idx].prev[i].coord)
      {
         cgGLSetParameterPointer(cg->prg[cg->active_idx].prev[i].coord, 
               2, GL_FLOAT, 0, prev_info[i].coord);
         cgGLEnableClientState(cg->prg[cg->active_idx].prev[i].coord);
         cg->cg_attribs[cg->cg_attrib_idx++] = cg->prg[cg->active_idx].prev[i].coord;
      }
   }

   /* Set lookup textures. */
   for (i = 0; i < cg->cg_shader->luts; i++)
   {
      CGparameter fparam = cgGetNamedParameter(
            cg->prg[cg->active_idx].fprg, cg->cg_shader->lut[i].id);

      if (fparam)
      {
         cgGLSetTextureParameter(fparam, cg->lut_textures[i]);
         cgGLEnableTextureParameter(fparam);
      }

      CGparameter vparam = cgGetNamedParameter(
            cg->prg[cg->active_idx].vprg, cg->cg_shader->lut[i].id);
      if (vparam)
      {
         cgGLSetTextureParameter(vparam, cg->lut_textures[i]);
         cgGLEnableTextureParameter(vparam);
      }
   }

   /* Set FBO textures. */
   if (cg->active_idx)
   {
      for (i = 0; i < fbo_info_cnt; i++)
      {
         if (cg->prg[cg->active_idx].fbo[i].tex)
         {
            cgGLSetTextureParameter(
                  cg->prg[cg->active_idx].fbo[i].tex, fbo_info[i].tex);
            cgGLEnableTextureParameter(cg->prg[cg->active_idx].fbo[i].tex);
         }

         set_param_2f(cg->prg[cg->active_idx].fbo[i].vid_size_v,
               fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
         set_param_2f(cg->prg[cg->active_idx].fbo[i].vid_size_f,
               fbo_info[i].input_size[0], fbo_info[i].input_size[1]);

         set_param_2f(cg->prg[cg->active_idx].fbo[i].tex_size_v,
               fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
         set_param_2f(cg->prg[cg->active_idx].fbo[i].tex_size_f,
               fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);

         if (cg->prg[cg->active_idx].fbo[i].coord)
         {
            cgGLSetParameterPointer(cg->prg[cg->active_idx].fbo[i].coord,
                  2, GL_FLOAT, 0, fbo_info[i].coord);
            cgGLEnableClientState(cg->prg[cg->active_idx].fbo[i].coord);
            cg->cg_attribs[cg->cg_attrib_idx++] = cg->prg[cg->active_idx].fbo[i].coord;
         }
      }
   }

   /* #pragma parameters. */
   for (i = 0; i < cg->cg_shader->num_parameters; i++)
   {
      CGparameter param_v = cgGetNamedParameter(
            cg->prg[cg->active_idx].vprg, cg->cg_shader->parameters[i].id);
      CGparameter param_f = cgGetNamedParameter(
            cg->prg[cg->active_idx].fprg, cg->cg_shader->parameters[i].id);
      set_param_1f(param_v, cg->cg_shader->parameters[i].current);
      set_param_1f(param_f, cg->cg_shader->parameters[i].current);
   }

   /* Set state parameters. */
   if (cg->state_tracker)
   {
      /* Only query uniforms in first pass. */
      static struct state_tracker_uniform tracker_info[MAX_VARIABLES];
      static unsigned cnt = 0;

      if (cg->active_idx == 1)
         cnt = state_get_uniform(cg->state_tracker, tracker_info,
               MAX_VARIABLES, frame_count);

      for (i = 0; i < cnt; i++)
      {
         CGparameter param_v = cgGetNamedParameter(
               cg->prg[cg->active_idx].vprg, tracker_info[i].id);
         CGparameter param_f = cgGetNamedParameter(
               cg->prg[cg->active_idx].fprg, tracker_info[i].id);
         set_param_1f(param_v, tracker_info[i].value);
         set_param_1f(param_f, tracker_info[i].value);
      }
   }
}