title: what's wrong with my shader using texture by through glUniform1i
body: <p>in my texturing with GLSL program,just one texture bind to texture unit 0.such as following:</p>
  
  <pre><code>.......................
          glActiveTexture(GL_TEXTURE0);
          GLuint tid;
          glGenTextures(1, &amp;tid);
          glBindTexture(GL_TEXTURE_2D, tid);
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width, img.height, 0,
                       img.format, GL_UNSIGNED_BYTE, img.data);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  </code></pre>
  
  <p>and then inform to frag shader through a uniform variable(as setUniform does),here's name is "texture0" corresponding  to my frag shader:</p>
  
  <pre><code>void CShader::setUniform( const char *name, int val )
      {
          int loc = getUniformLocation(name);
          glAssert();  //note!,my own assertion wrapping around glGetError.
                if( loc &gt;= 0 )
          {
              glUniform1i(loc, val);
  
          } else {
              printf("Uniform: %s not found.\n",name);
          }
                glAssert();   //note!,my own assertion wrapping around glGetError.
  
      }
  </code></pre>
  
  <p>it is out of my expectation, it assert failed at last <code>glAssert()</code> line,and giving me <code>GL_INVALID_OPERATION</code> .what was wrong,doesn't my display card is supported for this operation?,it can't be,my <code>OpenGL</code> version is 3.x.  after few hours struggle, did a try commented the last <code>glAssert()</code>,but another assertion failed  at my gldrawelements call. obviously, i absolutely think that cause <code>gldrawelements</code> failed is <code>glUniform1i</code> failed. can someone give me suggestion. </p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>from datenwolf  suggestion,here 's code for glAssert, it's very simple,just call glGetError once.</p>
  
  <pre><code>void _glAssert(const char * info, int line){
   char const* sz_GL_INVALID_ENUM="GL_INVALID_ENUM";
   char const* sz_GL_INVALID_VALUE="GL_INVALID_VALUE";
   char const* sz_GL_INVALID_OPERATION="GL_INVALID_OPERATION";
   char const* sz_GL_OUT_OF_MEMORY ="GL_OUT_OF_MEMORY";
  GLenum result;
      if((result=glGetError()) != GL_NO_ERROR )
      {
          const char *  sz_result=NULL;
          switch(result)
          {
          case GL_INVALID_ENUM:
              sz_result = sz_GL_INVALID_ENUM;
          break;
          case GL_INVALID_VALUE:
              sz_result = sz_GL_INVALID_VALUE;
          break;
          case GL_INVALID_OPERATION:
              sz_result = sz_GL_INVALID_OPERATION;
          break;
          case GL_OUT_OF_MEMORY:
              sz_result = sz_GL_OUT_OF_MEMORY;
          break;
          }
  
          _assert(sz_result,info,line);
      }
  }
  
  #define glAssert() \
      _glAssert(__FILE__, __LINE__);
  </code></pre>
  
  <p>BTW，before i use glUniform1i call,everything works fine with my shader</p>
  
  <pre><code>attribute vec3 VertexPosition;
  varying vec3 Color;
  void main()
  {
  Color = vec3(0.5,0,0);
  gl_TexCoord[0]  = gl_MultiTexCoord0;
  gl_Position = gl_ModelViewProjectionMatrix * vec4( VertexPosition, 1.0 );
  }
  
  
  uniform sampler2D texture0;
  
  varying vec3 Color;
  void main() {
  
   vec4 texColor = texture2D( texture0, gl_TexCoord[0].st);
  gl_FragColor= vec4(Color, 1.0)*texColor;
  }
  </code></pre>
  
  <p>i have stripped out many code in shader to simplify the problem .</p>
  
  <p>i'm Sorry that I don't describe this in detail. actually,my wrapper around opengl is very simple,no complex things with it, no multiple threads.</p>
  
  <p>this is constructor used for loading texture and shader script into GPU,memory separately, then call "compileandlink" method to compile the shader script , and call setUniform immediately.</p>
  
  <pre><code>IEntity(const char * szvs,const char * szfs): m_shader(new CShader(szvs,szfs)){
           ...........................
  }
  
  CCube::CCube():IEntity("v_simple.glsl","f_simple.glsl") {
      ...................
  
          IMAGE img;
          img.Load("texture.bmp");
          img.ExpandPalette();
  
          glActiveTexture(GL_TEXTURE0);
          GLuint tid;
          glGenTextures(1, &amp;tid);
          glBindTexture(GL_TEXTURE_2D, tid);
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width, img.height, 0,
                       img.format, GL_UNSIGNED_BYTE, img.data);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  
          m_shader-&gt;compileandlink();
          m_shader-&gt;setUniform("texture0", 0);
  }
  </code></pre>
  
  <p><strong>CShader::compileandlink method</strong></p>
  
  <pre><code>bool CShader::compileandlink(){
              if(m_vsscript == NULL || m_fsscript == NULL)
                  return false;
  
              if(strlen(m_vsscript) &lt;= 0  || strlen(m_fsscript) &lt;= 0)
                  return false;
  
              glShaderSource(m_vs, 1, (const GLchar **) &amp;m_vsscript, NULL);
              glCompileShader(m_vs);
  
              glShaderSource(m_fs, 1, (const GLchar **) &amp;m_fsscript, NULL);
              glCompileShader(m_fs);
  
              glAttachShader(m_program, m_vs);
              glAttachShader(m_program, m_fs);
              //glBindFragDataLocation(m_program, 0, "FragColor");
              glLinkProgram(m_program);
              glAssert();
  
  
              GLint status;
              glGetProgramiv( m_program, GL_LINK_STATUS, &amp;status );
              if( GL_FALSE == status ) {
              fprintf( stderr, "Failed to link shader program!\n" );
              GLint logLen;
              glGetProgramiv(m_program, GL_INFO_LOG_LENGTH,
              &amp;logLen);
  
              if( logLen &gt; 0 )
                  {
                  char * log = (char *)malloc(logLen);
                  GLsizei written;
                  glGetProgramInfoLog(m_program, logLen,
                      &amp;written, log);
                  printf("Program log: \n%s", log);
                  free(log);
                  }
              }
  
  
              return true;
  
      }
  </code></pre>
  
  <p><strong>CShader::setUniform method</strong>, as i say before,it have  GL_INVALID_OPERATION result of "glGetError" after glGetUniformiv returned inside this method.</p>
  
  <pre><code>void CShader::setUniform( const char *name, int val )
      {
          int loc = getUniformLocation(name);
          glAssert();
          if( loc &gt;= 0 )
          {
              GLint outval=-1;
  
              glUniform1i(loc, val);
              /*int tmploc =glGetUniformLocation(m_program, name);
              glGetUniformiv(m_program,
                              tmploc,
                             &amp;outval);
              printf("Value is %d\n", outval);*/
  
          } else {
              printf("Uniform: %s not found.\n",name);
          }
          glAssert();
      }
  </code></pre>